Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.hooks.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | /* Static Functions */ |
13 | 13 | |
14 | 14 | /** |
15 | | - * EditPage::showEditForm::initial hook |
| 15 | + * EditPage::showEditForm:initial hook |
16 | 16 | * Adds the TOC to the edit form |
17 | 17 | */ |
18 | 18 | public static function addTOC( &$ep ) { |
— | — | @@ -29,10 +29,18 @@ |
30 | 30 | $popts->setTidy( true ); |
31 | 31 | $popts->enableLimitReport(); |
32 | 32 | $articleObj = new Article( $ep->mTitle ); |
33 | | - $p_result = false; |
34 | | - if ( $ep->preview && $ep->section == '' ) |
| 33 | + $p_result = $p_result2 = false; |
| 34 | + if ( $ep->preview ) { |
35 | 35 | $p_result = $ep->mParserOutput; |
36 | | - else if ( $wgEnableParserCache && !$ep->preview ) { |
| 36 | + if ( $ep->section != '' ) { |
| 37 | + // Store this result and make sure the |
| 38 | + // ParserOutput for the entire page is |
| 39 | + // grabbed as well |
| 40 | + $p_result2 = $p_result; |
| 41 | + $p_result = false; |
| 42 | + } |
| 43 | + } |
| 44 | + else if ( $wgEnableParserCache ) { |
37 | 45 | $p_result = $pcache->get( $articleObj, $popts ); |
38 | 46 | // The ParserOutput in cache could be too old to have |
39 | 47 | // byte offsets. In that case, reparse |
— | — | @@ -48,35 +56,50 @@ |
49 | 57 | } |
50 | 58 | if ( !$p_result ) { |
51 | 59 | $popts->setIsPreview( $ep->preview || $ep->section != '' ); |
52 | | - $text = $articleObj->getContent(); |
53 | | - if ( $ep->preview ) { |
54 | | - if( $ep->section == 'new' ) |
55 | | - $text .= $ep->textbox1; |
56 | | - else if ( $ep->section != '' ) |
57 | | - $text = $wgParser->replaceSection( $text, |
58 | | - $ep->section, $ep->textbox1 ); |
59 | | - else |
60 | | - $text = $ep->textbox1; |
61 | | - } |
62 | | - $p_result = $wgParser->parse( $text, $ep->mTitle, |
63 | | - $popts ); |
| 60 | + $p_result = $wgParser->parse( $articleObj->getContent(), |
| 61 | + $ep->mTitle, $popts ); |
64 | 62 | if ( $wgEnableParserCache ) |
65 | | - $pcache->save( $p_result, $articleObj, $popts ); |
| 63 | + $pcache->save( $p_result, $articleObj, |
| 64 | + $popts ); |
66 | 65 | } |
| 66 | + |
| 67 | + if( $p_result2 ) { |
| 68 | + // Merge the section trees of the original article and |
| 69 | + // the edited text; this saves us from parsing the |
| 70 | + // entire page with the edited section replaced |
| 71 | + $sectionTree = Parser::mergeSectionTrees( |
| 72 | + $p_result->getSections(), |
| 73 | + $p_result2->getSections(), |
| 74 | + $ep->section, $ep->mTitle, strlen( $ep->textbox1 ) ); |
| 75 | + $toc = $wgUser->getSkin()->generateTOC( $sectionTree ); |
| 76 | + } else { |
| 77 | + $sectionTree = $p_result->getSections(); |
| 78 | + $toc = $p_result->getTOCHTML(); |
| 79 | + } |
67 | 80 | |
68 | 81 | $js = "\$.section = '" . Xml::escapeJsString( $ep->section ) . "';"; |
69 | 82 | $js .= "\$.sectionOffsets = ["; |
70 | 83 | $targetLevel = false; |
71 | | - foreach ( $p_result->getSections() as $section ) |
| 84 | + $targetSection = false; |
| 85 | + foreach ( $sectionTree as $section ) |
72 | 86 | if ( !is_null( $section['byteoffset'] ) ) { |
73 | 87 | if ( $ep->section != '' ) { |
74 | 88 | // Only get offsets for the section |
75 | | - // being edited and its descendants |
| 89 | + // being edited and its descendants. |
| 90 | + // In preview mode, sibling sections |
| 91 | + // may have been added, so use the |
| 92 | + // number of sections in $p_result2 |
76 | 93 | if ( $section['index'] < $ep->section ) |
77 | 94 | continue; |
78 | | - else if ( $section['index'] == $ep->section ) |
79 | | - $targetLevel = $section['level']; |
80 | | - else if ( $section['level'] <= $targetLevel ) |
| 95 | + else if ( $section['index'] == $ep->section ) { |
| 96 | + if ( $ep->preview ) |
| 97 | + $targetSection = $ep->section + |
| 98 | + count( $p_result2->getSections() ); |
| 99 | + else |
| 100 | + $targetLevel = $section['level']; |
| 101 | + } |
| 102 | + else if ( ( $ep->preview && $section['index'] >= $targetSection ) || |
| 103 | + ( !$ep->preview && $section['level'] <= $targetLevel ) ) |
81 | 104 | break; |
82 | 105 | } |
83 | 106 | $js .= intval( $section['byteoffset'] ) . ','; |
— | — | @@ -87,8 +110,8 @@ |
88 | 111 | // Terrible hack to prevent two TOCs with the same ID |
89 | 112 | // from being displayed |
90 | 113 | $toc = str_replace( '<table id="toc"', |
91 | | - '<table id="navigableTOC"', $p_result->getTOCHTML() ); |
| 114 | + '<table id="navigableTOC"', $toc ); |
92 | 115 | $ep->editFormTextTop .= $toc . $jsTag; |
93 | 116 | return true; |
94 | | - } |
| 117 | + } |
95 | 118 | } |
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.js |
— | — | @@ -112,33 +112,23 @@ |
113 | 113 | .data( 'offset', $.sectionOffsets[i] ); |
114 | 114 | } else if ( $.section != 'new' && $.section != 0 ) { |
115 | 115 | // Existing section edit |
116 | | - // Unlink all irrelevant section links |
117 | | - $.section = parseInt( $.section ); |
118 | | - $( '.toc:last * li' ).not( '.tocsection-' + $.section + ' * li') |
119 | | - .not( '.tocsection-' + $.section ).each( function() { |
120 | | - link = $(this).children( 'a' ); |
121 | | - if ( link.is( ':visible' ) ) { |
122 | | - link.hide(); |
123 | | - $(this).prepend( link.html() ); |
124 | | - } |
125 | | - }); |
126 | | - |
127 | 116 | // Set adjusted offsets on the usable links |
| 117 | + $.section = parseInt( $.section ); |
128 | 118 | for ( i = 0; i < $.sectionOffsets.length; i++ ) |
129 | 119 | $( '.tocsection-' + ( i + $.section ) ).children( 'a' ) |
130 | 120 | .data( 'offset', $.sectionOffsets[i] - |
131 | 121 | $.sectionOffsets[0] ); |
132 | | - } else { |
133 | | - // New section or section 0 |
134 | | - // Unlink everything |
135 | | - $( '.toc:last * li' ).each( function() { |
136 | | - link = $(this).children( 'a' ); |
137 | | - if ( link.visible() ) { |
138 | | - link.hide(); |
139 | | - $(this).prepend( link.html() ); |
140 | | - } |
141 | | - }); |
142 | 122 | } |
| 123 | + // Unlink all section links that didn't get an offset |
| 124 | + $( '.toc:last * li' ).each( function() { |
| 125 | + link = $(this).children( 'a' ); |
| 126 | + if ( typeof link.data( 'offset') == 'undefined' && |
| 127 | + link.is( ':visible' ) ) { |
| 128 | + link.hide(); |
| 129 | + $(this).prepend( link.html() ); |
| 130 | + } |
| 131 | + }); |
| 132 | + |
143 | 133 | $( '.toc:last * li a' ).click( function(e) { |
144 | 134 | if( typeof jQuery(this).data( 'offset' ) != 'undefined' ) |
145 | 135 | jQuery( '#wpTextbox1' ).scrollToPosition( jQuery(this).data( 'offset' ) ); |
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/ISSUES |
— | — | @@ -6,13 +6,3 @@ |
7 | 7 | 7x15 (Linux), but these values should really be determined dynamically. |
8 | 8 | ** Both of these can be avoided by determining the caret position properly, |
9 | 9 | I'll ask Michael Dale about this. |
10 | | -* When previewing, two TOCs may show up (one in the preview, one navigable), |
11 | | - in which case the first TOC gets two [hide] links and the second gets none |
12 | | -* When previewing a section, both the section content and the entire page are |
13 | | - parsed, which is slow. |
14 | | -** We're parsing the entire page solely for its TOC, maybe we can take the |
15 | | - old TOC from the parser cache and blend in the edited section? |
16 | | -** Is it even desirable to show full context here? Showing the edited section |
17 | | - as top-level is less parser-intensive for section previews |
18 | | -* TOC is only shown when it'd normally appear on the page (4 sections or |
19 | | - __TOC__ and no __NOTOC__), is this desirable? |