r63094 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r63093‎ | r63094 | r63095 >
Date:21:01, 28 February 2010
Author:catrope
Status:deferred (Comments)
Tags:
Comment:
UsabilityInitiative: Make sure templates are wrapped/unwrapped when they become collapsible/non-collapsible
* Refactor most of stylize() into wrapTemplate()
* Add afterWrap, onSkip and beforeUnwrap handlers that call wrapTemplate() and unwrapTemplate()
* Change CSS so non-collapsed templates don't get styled as such
* Fix highlighter for cases where the text it was trying to wrap was exactly equal to the contents of the encompassing node
Modified paths:
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.highlight.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.html (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.templateEditor.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -74,19 +74,19 @@
7575 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 7 ),
7676 array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 27 ),
7777 array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 157 ),
78 - array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 35 ),
 78+ array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 36 ),
7979 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 52 ),
8080 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 19 ),
8181 array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 95 ),
8282 array( 'src' => 'js/plugins/jquery.wikiEditor.preview.js', 'version' => 11 ),
83 - array( 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js', 'version' => 26 ),
 83+ array( 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js', 'version' => 27 ),
8484 array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 3 ),
8585 ),
8686 'combined' => array(
87 - array( 'src' => 'js/plugins.combined.js', 'version' => 293 ),
 87+ array( 'src' => 'js/plugins.combined.js', 'version' => 294 ),
8888 ),
8989 'minified' => array(
90 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 293 ),
 90+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 294 ),
9191 ),
9292 ),
9393 );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.templateEditor.js
@@ -58,6 +58,7 @@
5959 }//while finding template ending
6060 if ( endIndex != -1 ) {
6161 // Create a model for the template
 62+ // FIXME: This is a performance hit
6263 var model = new $.wikiEditor.modules.templateEditor.fn.model(
6364 context.fn.getContents().substring( tokenArray[beginIndex].offset,
6465 tokenArray[endIndex].offset
@@ -70,12 +71,35 @@
7172 anchor: 'wrap',
7273 //splitPs: model.isCollapsible(),
7374 splitPs: false,
74 - afterWrap: $.wikiEditor.modules.templateEditor.fn.stylize,
 75+ afterWrap: function( node ) {
 76+ // Store model so we can compare it later
 77+ $( node ).data( 'model', $( node ).data( 'marker' ).model );
 78+ if ( model.isCollapsible() ) {
 79+ $.wikiEditor.modules.templateEditor.fn.wrapTemplate( $( node ) );
 80+ } else {
 81+ $( node ).addClass( 'wikiEditor-template-text' );
 82+ }
 83+ },
7584 beforeUnwrap: function( node ) {
76 - // FIXME: $( node ).data( 'display' ) doesn't exist any more
77 - //$( node ).data( 'display' ).remove();
 85+ if ( $( node ).parent().hasClass( 'wikiEditor-template' ) ) {
 86+ $.wikiEditor.modules.templateEditor.fn.unwrapTemplate( $( node ) );
 87+ }
7888 },
79 - onSkip: function() { },
 89+ onSkip: function( node ) {
 90+ var oldModel = $( node ).data( 'model' );
 91+ var newModel = $( node ).data( 'marker' ).model;
 92+ if ( oldModel.getText() == newModel.getText() ) {
 93+ // No change
 94+ return;
 95+ }
 96+
 97+ if ( $( node ).parent().hasClass( 'wikiEditor-template' ) && !newModel.isCollapsible() ) {
 98+ $.wikiEditor.modules.templateEditor.fn.unwrapTemplate( $( node ) );
 99+ } else if ( !$( node ).parent().hasClass( 'wikiEditor-template' ) && newModel.isCollapsible() ) {
 100+ $.wikiEditor.modules.templateEditor.fn.wrapTemplate( $( node ) );
 101+ }
 102+ // TODO: Update table; not doing this yet because the table will probably die
 103+ },
80104 getAnchor: function( ca1, ca2 ) {
81105 // FIXME: Relies on the current <span> structure that is likely to die
82106 return $( ca1.parentNode ).is( 'span.wikiEditor-template-text' ) ?
@@ -117,205 +141,202 @@
118142 // Initialize module within the context
119143 context.modules.templateEditor = {};
120144 },
121 - stylize: function( wrappedTemplate ) {
122 - $( wrappedTemplate ).each( function() {
123 - if ( typeof $(this).data( 'setupDone' ) != 'undefined' ) {
124 - // We have a model, so all this init stuff has already happened
125 - return;
126 - }
127 - var model = $(this).data( 'marker' ).model;
128 - var context = $(this).data( 'marker' ).context;
 145+ /**
 146+ * Turns a simple template wrapper (really just a <span>) into a complex one
 147+ * @param $wrapper Wrapping <span>
 148+ */
 149+ wrapTemplate: function( $wrapper ) {
 150+ var model = $wrapper.data( 'marker' ).model;
 151+ var context = $wrapper.data( 'marker' ).context;
 152+
 153+ var $template = $wrapper
 154+ .wrap( '<span class="wikiEditor-template"></span>' )
 155+ .addClass( 'wikiEditor-nodisplay' )
 156+ .parent()
 157+ .addClass( 'wikiEditor-template-collapsed' )
 158+ .data( 'model', model );
 159+
 160+ var $templateName = $( '<span />' )
 161+ .addClass( 'wikiEditor-template-name wikiEditor-noinclude' )
 162+ .text( model.getName() )
 163+ .mousedown( toggleWikiTextEditor )
 164+ .prependTo( $template );
 165+
 166+ var $templateExpand = $( '<span />' )
 167+ .addClass( 'wikiEditor-template-expand wikiEditor-noinclude' )
 168+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/expand.png" width="12" height="16" />' )
 169+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/collapse.png" width="12" height="16" style="display:none;" />' )
 170+ .mousedown( toggleWikiTextEditor )
 171+ .prependTo( $template );
 172+
 173+ var $templateDialog = $( '<span />' )
 174+ .addClass( 'wikiEditor-template-dialog wikiEditor-noinclude' )
 175+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/dialog-collapsed.png" width="22" height="16" />' )
 176+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/dialog-expanded.png" width="22" height="16" style="display:none;" />' )
 177+ .mousedown( function() { createDialog( $template ); return false; } )
 178+ .insertAfter( $templateName );
 179+
 180+ function toggleWikiTextEditor() {
 181+ context.fn.refreshOffsets();
 182+ var $template = $( this ).closest( '.wikiEditor-template' );
 183+ $template
 184+ .toggleClass( 'wikiEditor-template-expanded' )
 185+ .toggleClass( 'wikiEditor-template-collapsed' )
 186+ .find( 'img' )
 187+ .each( function() {
 188+ $( this ).toggle();
 189+ } );
 190+ var $wikitext = $template.children( '.wikiEditor-template-text' );
 191+ $wikitext.toggleClass( 'wikiEditor-nodisplay' );
129192
130 - //check if model is collapsible
131 - if ( !model.isCollapsible() ) {
132 - //just treat it as normal text for now
133 - return;
 193+ //if we just collapsed this
 194+ if( $template.hasClass( 'wikiEditor-template-collapsed' ) ) {
 195+ var model = new $.wikiEditor.modules.templateEditor.fn.model(
 196+ $template.children( '.wikiEditor-template-text' ).text()
 197+ );
 198+ $template.data( 'model' , model );
 199+ $template.children( '.wikiEditor-template-name' ).text( model.getName() );
 200+ } else { //we just expanded this
 201+ $wikitext.text( $template.data( 'model' ).getText() );
134202 }
135203
136 - var $template = $( this )
137 - .wrap( '<span class="wikiEditor-template"></span>' )
138 - .addClass( 'wikiEditor-template-text wikiEditor-nodisplay' )
139 - .parent()
140 - .addClass( 'wikiEditor-template-collapsed' )
141 - .data( 'model', model );
142 -
143 - var $templateName = $( '<span />' )
144 - .addClass( 'wikiEditor-template-name wikiEditor-noinclude' )
 204+ return false;
 205+ };
 206+
 207+ // Expand
 208+ function expandTemplate( $displayDiv ) {
 209+ // Housekeeping
 210+ $displayDiv
 211+ .removeClass( 'wikiEditor-template-collapsed' )
 212+ .addClass( 'wikiEditor-template-expanded' )
 213+ // remove mousedown hander from the entire thing
 214+ .unbind( 'mousedown' );
 215+ //$displayDiv.text( model.getText() );
 216+ $keyValueTable = $( '<table />' )
 217+ .appendTo( $displayDiv );
 218+ $header_row = $( '<tr />' )
 219+ .appendTo( $keyValueTable );
 220+ $( '<th />' )
 221+ .attr( 'colspan', '2' )
145222 .text( model.getName() )
146 - .mousedown( toggleWikiTextEditor )
147 - .prependTo( $template );
148 -
149 - var $templateExpand = $( '<span />' )
150 - .addClass( 'wikiEditor-template-expand wikiEditor-noinclude' )
151 - .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/expand.png" width="12" height="16" />' )
152 - .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/collapse.png" width="12" height="16" style="display:none;" />' )
153 - .mousedown( toggleWikiTextEditor )
154 - .prependTo( $template );
155 -
156 - var $templateDialog = $( '<span />' )
157 - .addClass( 'wikiEditor-template-dialog wikiEditor-noinclude' )
158 - .append( '<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-collapsed.png" width="22" height="16" />' )
159 - .append( '<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-expanded.png" width="22" height="16" style="display:none;" />' )
160 - .mousedown( function() { createDialog( $template ); return false; } )
161 - .insertAfter( $templateName );
162 -
163 - $(this).data( 'setupDone', true );
164 -
165 - function toggleWikiTextEditor(){
166 - context.fn.refreshOffsets();
167 - var $template = $( this ).closest( '.wikiEditor-template' );
168 - $template
169 - .toggleClass( 'wikiEditor-template-expanded' )
170 - .toggleClass( 'wikiEditor-template-collapsed' )
171 - .find( 'img' )
172 - .each( function() {
173 - $( this ).toggle();
174 - } );
175 - var $wikitext = $template.children('.wikiEditor-template-text');
176 - $wikitext.toggleClass('wikiEditor-nodisplay');
 223+ .appendTo( $header_row );
 224+ for( param in model.getAllParamNames() ){
 225+ $keyVal_row = $( '<tr />' )
 226+ .appendTo( $keyValueTable );
177227
178 - //if we just collapsed this
179 - if( $template.hasClass('wikiEditor-template-collapsed') ) {
180 - var model = new $.wikiEditor.modules.templateEditor.fn.model(
181 - $template.children( '.wikiEditor-template-text' ).text()
182 - );
183 - $template.data( 'model' , model );
184 - $template.children( '.wikiEditor-template-name' ).text( model.getName() );
185 - }
186 - else{ //we just expanded this
187 - $wikitext.text($template.data('model').getText());
188 - }
189 -
190 - return false;
191 - };
 228+ $( '<td />' )
 229+ .text( param )
 230+ .appendTo( $keyVal_row );
 231+ $( '<td />' )
 232+ .text( model.getValue( param ) )
 233+ .appendTo( $keyVal_row );
 234+ }
 235+ };
 236+ // Collapse
 237+ function collapseTemplate( $displayDiv ) {
 238+ // Housekeeping
 239+ $displayDiv
 240+ .addClass( 'wikiEditor-template-collapsed' )
 241+ .removeClass( 'wikiEditor-template-expanded' )
 242+ .text( model.getName() );
 243+ };
192244
193 - // Expand
194 - function expandTemplate( $displayDiv ) {
195 - // Housekeeping
196 - $displayDiv.removeClass( 'wikiEditor-template-collapsed' );
197 - $displayDiv.addClass( 'wikiEditor-template-expanded' );
198 - // remove mousedown hander from the entire thing
199 - $displayDiv.unbind( 'mousedown' );
200 - //$displayDiv.text( model.getText() );
201 - $keyValueTable = $( '<table />' )
202 - .appendTo( $displayDiv );
203 - $header_row = $( '<tr />' )
204 - .appendTo( $keyValueTable );
205 - $( '<th />' )
206 - .attr( 'colspan', '2' )
207 - .text( model.getName() )
208 - .appendTo( $header_row );
209 - for( param in model.getAllParamNames() ){
210 - $keyVal_row = $( '<tr />' )
211 - .appendTo( $keyValueTable );
212 -
213 - $( '<td />' )
214 - .text( param )
215 - .appendTo( $keyVal_row );
216 - $( '<td />' )
217 - .text( model.getValue( param ) )
218 - .appendTo( $keyVal_row );
 245+ function createDialog( $templateDiv ) {
 246+ // Give the user some feedback on what they're doing
 247+ context.fn.highlightLine( $templateDiv );
 248+ //
 249+ var $wikitext = $templateDiv.children( '.wikiEditor-template-text' );
 250+ //TODO: check if template model has been changed
 251+ var templateModel = new $.wikiEditor.modules.templateEditor.fn.model( $wikitext.text() );
 252+ $templateDiv.data( 'model', templateModel );
 253+ var $dialog = $( '<div />' );
 254+ var $title = $(' <div />' )
 255+ .text( templateModel.getName() )
 256+ .addClass( 'wikiEditor-template-dialog-title' );
 257+ var $table = $( '<table />' )
 258+ .addClass( 'wikiEditor-template-dialog-table' )
 259+ .appendTo( $dialog );
 260+ var allInitialParams = templateModel.getAllInitialParams();
 261+ for ( var paramIndex in allInitialParams ) {
 262+ var param = allInitialParams[paramIndex];
 263+ if ( typeof param.name == 'undefined' ) {
 264+ //param 0 is the name
 265+ continue;
219266 }
220 - };
221 - // Collapse
222 - function collapseTemplate( $displayDiv ) {
223 - // Housekeeping
224 - $displayDiv.addClass( 'wikiEditor-template-collapsed' );
225 - $displayDiv.removeClass( 'wikiEditor-template-expanded' );
226 - $displayDiv.text( model.getName() );
227 - };
228 -
229 - function createDialog( $templateDiv ) {
230 - // Give the user some feedback on what they're doing
 267+ var $paramRow = $( '<tr />' )
 268+ .addClass( 'wikiEditor-template-dialog-row' );
 269+ var $paramName = $( '<td />' )
 270+ .addClass( 'wikiEditor-template-dialog-name' )
 271+ .text(
 272+ param.name.replace( /[\_\-]/g, ' ' ).replace( /^(.)|\s(.)/g, function ( first ) {
 273+ return first.toUpperCase();
 274+ } )
 275+ );
 276+ var $paramVal = $( '<td />' )
 277+ .addClass( 'wikiEditor-template-dialog-value' );
 278+ var $paramInput = $( '<input />' )
 279+ .data( 'name', param.name )
 280+ .val( templateModel.getValue( param.name ) );
 281+ $paramVal.append( $paramInput );
 282+ $paramRow.append( $paramName ).append( $paramVal );
 283+ $table.append( $paramRow );
 284+ }
 285+ //click handler for values
 286+ $( '<button />' ).click( function() {
 287+ // More user feedback
231288 context.fn.highlightLine( $templateDiv );
232289 //
233 - var $wikitext = $templateDiv.children( '.wikiEditor-template-text' );
234 - //TODO: check if template model has been changed
235 - var templateModel = new $.wikiEditor.modules.templateEditor.fn.model( $wikitext.text() );
236 - $templateDiv.data( 'model', templateModel );
237 - var $dialog = $( '<div />' );
238 - var $title = $(' <div />' )
239 - .text( templateModel.getName() )
240 - .addClass( 'wikiEditor-template-dialog-title' );
241 - var $table = $( '<table />' )
242 - .addClass( 'wikiEditor-template-dialog-table' )
243 - .appendTo( $dialog );
244 - var allInitialParams = templateModel.getAllInitialParams();
245 - for ( var paramIndex in allInitialParams ) {
246 - var param = allInitialParams[paramIndex];
247 - if ( typeof param.name == 'undefined' ) {
248 - //param 0 is the name
249 - continue;
250 - }
251 - var $paramRow = $( '<tr />' )
252 - .addClass( 'wikiEditor-template-dialog-row' );
253 - var $paramName = $( '<td />' )
254 - .addClass( 'wikiEditor-template-dialog-name' )
255 - .text(
256 - param.name.replace( /[\_\-]/g, ' ' ).replace( /^(.)|\s(.)/g, function ( first ) {
257 - return first.toUpperCase();
258 - } )
259 - );
260 - var $paramVal = $( '<td />' )
261 - .addClass( 'wikiEditor-template-dialog-value' );
262 - var $paramInput = $( '<input />' )
263 - .data( 'name', param.name )
264 - .val( templateModel.getValue( param.name ) );
265 - $paramVal.append( $paramInput );
266 - $paramRow.append( $paramName ).append( $paramVal );
267 - $table.append( $paramRow );
268 - }
269 - //click handler for values
270 - $( '<button />' ).click( function() {
271 - // More user feedback
272 - context.fn.highlightLine( $templateDiv );
273 - //
274 - $( '.wikiEditor-template-dialog-value input' ).each( function(){
275 - templateModel.setValue( $(this).data('name'), $(this).val() );
276 - });
277 - //keep text consistent
278 - $wikitext.text( templateModel.getText() );
279 -
280 - $dialog.dialog( 'close' );
281 -
282 - }).text( 'OK' ).appendTo( $dialog ); // FIXME: Internationalize 'OK'
283 - $dialog.dialog(); //opens dialog
284 - return false;
285 - };
 290+ $( '.wikiEditor-template-dialog-value input' ).each( function(){
 291+ templateModel.setValue( $(this).data( 'name' ), $(this).val() );
 292+ });
 293+ //keep text consistent
 294+ $wikitext.text( templateModel.getText() );
 295+
 296+ $dialog.dialog( 'close' );
 297+
 298+ }).text( 'OK' ).appendTo( $dialog ); // FIXME: Internationalize 'OK'
 299+ $dialog.dialog(); //opens dialog
 300+ return false;
 301+ };
 302+
 303+ function toggleWikiText() {
 304+ var $template = $( this ).closest( '.wikiEditor-template' );
 305+ $template
 306+ .toggleClass( 'wikiEditor-template-collapsed' )
 307+ .toggleClass( 'wikiEditor-template-expanded' )
 308+ .children( '.wikiEditor-template-text, .wikiEditor-template-name, .wikiEditor-template-modes' )
 309+ .toggleClass( 'wikiEditor-nodisplay' );
286310
287 - function toggleWikiText() {
288 - var $template = $( this ).closest( '.wikiEditor-template' );
289 - $template
290 - .toggleClass( 'wikiEditor-template-collapsed' )
291 - .toggleClass( 'wikiEditor-template-expanded' )
292 - .children( '.wikiEditor-template-text, .wikiEditor-template-name, .wikiEditor-template-modes' )
293 - .toggleClass( 'wikiEditor-nodisplay' );
 311+ //if we just collapsed this
 312+ if ( $template.hasClass( 'wikiEditor-template-collapsed' ) ) {
 313+ var model = new $.wikiEditor.modules.templateEditor.fn.model(
 314+ $template.children( '.wikiEditor-template-text' ).text()
 315+ );
 316+ $template.data( 'model' , model );
 317+ $template.children( '.wikiEditor-template-name' ).text( model.getName() );
 318+ } else{ //else we just expanded this
 319+ $template.children( '.wikiEditor-template-text' ).children('.wikiEditor-template-inner-text').text(
 320+ $template.data('model')
 321+ .getText()
 322+ .replace(/\{\{/, '')
 323+ .replace(/\}\}$/, '')
 324+ );
294325
295 - //if we just collapsed this
296 - if ( $template.hasClass( 'wikiEditor-template-collapsed' ) ) {
297 - var model = new $.wikiEditor.modules.templateEditor.fn.model(
298 - $template.children( '.wikiEditor-template-text' ).text()
299 - );
300 - $template.data( 'model' , model );
301 - $template.children( '.wikiEditor-template-name' ).text( model.getName() );
302 - } else{ //else we just expanded this
303 - $template.children( '.wikiEditor-template-text' ).children('.wikiEditor-template-inner-text').text(
304 - $template.data('model')
305 - .getText()
306 - .replace(/\{\{/, '')
307 - .replace(/\}\}$/, '')
308 - );
309 -
310 - }
311 - return false;
312326 }
313 -
314 - function noEdit() {
315 - return false;
316 - }
317 - });
 327+ return false;
 328+ }
318329
 330+ function noEdit() {
 331+ return false;
 332+ }
319333 },
 334+ /**
 335+ * Turn a complex template wrapper back into a simple one
 336+ * @param $wrapper Wrapping <span>
 337+ */
 338+ unwrapTemplate: function( $wrapper ) {
 339+ $wrapper.parent().replaceWith( $wrapper );
 340+ },
320341
321342 /**
322343 * Gets templateInfo node from templateInfo extension, if it exists
@@ -323,6 +344,7 @@
324345 getTemplateInfo: function ( templateName ) {
325346 var templateInfo = '';
326347 // TODO: API call here
 348+ // FIXME: This setup won't work very well with the async nature of grabbing the template info
327349 return $( templateInfo );
328350 },
329351
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.html
@@ -89,14 +89,14 @@
9090 .wikiEditor-template-expanded {
9191 display: inline;
9292 }
93 - .wikiEditor-template-text{
 93+ .wikiEditor-template .wikiEditor-template-text {
9494 background: #f3f3f3;
9595 margin-top: -4px;
9696 border: solid 1px #d9d9d9;
9797 padding-left: 4px;
9898 display: block;
9999 }
100 - .wikiEditor-template-end, .wikiEditor-template-start{
 100+ .wikiEditor-template-end, .wikiEditor-template-start {
101101 color: blue;
102102 cursor: pointer;
103103 }
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.highlight.js
@@ -219,16 +219,18 @@
220220 }
221221
222222 var end = markers[i].end;
223 - var e = context.fn.getOffset( end );
 223+ // To avoid ending up at the first char of the next node, we grab the offset for end - 1
 224+ // and add one to the offset
 225+ var e = context.fn.getOffset( end - 1 );
224226 if ( !e ) {
225227 // This shouldn't happen
226228 continue;
227229 }
228230 var endNode = e.node;
229231 var endDepth = e.depth;
230 - if ( e.offset < e.length - 1 && e.node.nodeName == '#text' ) {
 232+ if ( e.offset + 1 < e.length - 1 && e.node.nodeName == '#text' ) {
231233 // Split off the suffix. This puts the suffix in a new node and leaves the rest in endNode
232 - endNode.splitText( e.offset );
 234+ endNode.splitText( e.offset + 1 );
233235 // This also invalidates cached offset objects
234236 context.fn.purgeOffsets(); // TODO: Optimize better, get end offset object earlier
235237 }
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -8560,16 +8560,18 @@
85618561 }
85628562
85638563 var end = markers[i].end;
8564 - var e = context.fn.getOffset( end );
 8564+ // To avoid ending up at the first char of the next node, we grab the offset for end - 1
 8565+ // and add one to the offset
 8566+ var e = context.fn.getOffset( end - 1 );
85658567 if ( !e ) {
85668568 // This shouldn't happen
85678569 continue;
85688570 }
85698571 var endNode = e.node;
85708572 var endDepth = e.depth;
8571 - if ( e.offset < e.length - 1 && e.node.nodeName == '#text' ) {
 8573+ if ( e.offset + 1 < e.length - 1 && e.node.nodeName == '#text' ) {
85728574 // Split off the suffix. This puts the suffix in a new node and leaves the rest in endNode
8573 - endNode.splitText( e.offset );
 8575+ endNode.splitText( e.offset + 1 );
85748576 // This also invalidates cached offset objects
85758577 context.fn.purgeOffsets(); // TODO: Optimize better, get end offset object earlier
85768578 }
@@ -9057,6 +9059,7 @@
90589060 }//while finding template ending
90599061 if ( endIndex != -1 ) {
90609062 // Create a model for the template
 9063+ // FIXME: This is a performance hit
90619064 var model = new $.wikiEditor.modules.templateEditor.fn.model(
90629065 context.fn.getContents().substring( tokenArray[beginIndex].offset,
90639066 tokenArray[endIndex].offset
@@ -9069,12 +9072,35 @@
90709073 anchor: 'wrap',
90719074 //splitPs: model.isCollapsible(),
90729075 splitPs: false,
9073 - afterWrap: $.wikiEditor.modules.templateEditor.fn.stylize,
 9076+ afterWrap: function( node ) {
 9077+ // Store model so we can compare it later
 9078+ $( node ).data( 'model', $( node ).data( 'marker' ).model );
 9079+ if ( model.isCollapsible() ) {
 9080+ $.wikiEditor.modules.templateEditor.fn.wrapTemplate( $( node ) );
 9081+ } else {
 9082+ $( node ).addClass( 'wikiEditor-template-text' );
 9083+ }
 9084+ },
90749085 beforeUnwrap: function( node ) {
9075 - // FIXME: $( node ).data( 'display' ) doesn't exist any more
9076 - //$( node ).data( 'display' ).remove();
 9086+ if ( $( node ).parent().hasClass( 'wikiEditor-template' ) ) {
 9087+ $.wikiEditor.modules.templateEditor.fn.unwrapTemplate( $( node ) );
 9088+ }
90779089 },
9078 - onSkip: function() { },
 9090+ onSkip: function( node ) {
 9091+ var oldModel = $( node ).data( 'model' );
 9092+ var newModel = $( node ).data( 'marker' ).model;
 9093+ if ( oldModel.getText() == newModel.getText() ) {
 9094+ // No change
 9095+ return;
 9096+ }
 9097+
 9098+ if ( $( node ).parent().hasClass( 'wikiEditor-template' ) && !newModel.isCollapsible() ) {
 9099+ $.wikiEditor.modules.templateEditor.fn.unwrapTemplate( $( node ) );
 9100+ } else if ( !$( node ).parent().hasClass( 'wikiEditor-template' ) && newModel.isCollapsible() ) {
 9101+ $.wikiEditor.modules.templateEditor.fn.wrapTemplate( $( node ) );
 9102+ }
 9103+ // TODO: Update table; not doing this yet because the table will probably die
 9104+ },
90799105 getAnchor: function( ca1, ca2 ) {
90809106 // FIXME: Relies on the current <span> structure that is likely to die
90819107 return $( ca1.parentNode ).is( 'span.wikiEditor-template-text' ) ?
@@ -9116,205 +9142,202 @@
91179143 // Initialize module within the context
91189144 context.modules.templateEditor = {};
91199145 },
9120 - stylize: function( wrappedTemplate ) {
9121 - $( wrappedTemplate ).each( function() {
9122 - if ( typeof $(this).data( 'setupDone' ) != 'undefined' ) {
9123 - // We have a model, so all this init stuff has already happened
9124 - return;
9125 - }
9126 - var model = $(this).data( 'marker' ).model;
9127 - var context = $(this).data( 'marker' ).context;
 9146+ /**
 9147+ * Turns a simple template wrapper (really just a <span>) into a complex one
 9148+ * @param $wrapper Wrapping <span>
 9149+ */
 9150+ wrapTemplate: function( $wrapper ) {
 9151+ var model = $wrapper.data( 'marker' ).model;
 9152+ var context = $wrapper.data( 'marker' ).context;
 9153+
 9154+ var $template = $wrapper
 9155+ .wrap( '<span class="wikiEditor-template"></span>' )
 9156+ .addClass( 'wikiEditor-nodisplay' )
 9157+ .parent()
 9158+ .addClass( 'wikiEditor-template-collapsed' )
 9159+ .data( 'model', model );
 9160+
 9161+ var $templateName = $( '<span />' )
 9162+ .addClass( 'wikiEditor-template-name wikiEditor-noinclude' )
 9163+ .text( model.getName() )
 9164+ .mousedown( toggleWikiTextEditor )
 9165+ .prependTo( $template );
 9166+
 9167+ var $templateExpand = $( '<span />' )
 9168+ .addClass( 'wikiEditor-template-expand wikiEditor-noinclude' )
 9169+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/expand.png" width="12" height="16" />' )
 9170+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/collapse.png" width="12" height="16" style="display:none;" />' )
 9171+ .mousedown( toggleWikiTextEditor )
 9172+ .prependTo( $template );
 9173+
 9174+ var $templateDialog = $( '<span />' )
 9175+ .addClass( 'wikiEditor-template-dialog wikiEditor-noinclude' )
 9176+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/dialog-collapsed.png" width="22" height="16" />' )
 9177+ .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/dialog-expanded.png" width="22" height="16" style="display:none;" />' )
 9178+ .mousedown( function() { createDialog( $template ); return false; } )
 9179+ .insertAfter( $templateName );
 9180+
 9181+ function toggleWikiTextEditor() {
 9182+ context.fn.refreshOffsets();
 9183+ var $template = $( this ).closest( '.wikiEditor-template' );
 9184+ $template
 9185+ .toggleClass( 'wikiEditor-template-expanded' )
 9186+ .toggleClass( 'wikiEditor-template-collapsed' )
 9187+ .find( 'img' )
 9188+ .each( function() {
 9189+ $( this ).toggle();
 9190+ } );
 9191+ var $wikitext = $template.children( '.wikiEditor-template-text' );
 9192+ $wikitext.toggleClass( 'wikiEditor-nodisplay' );
91289193
9129 - //check if model is collapsible
9130 - if ( !model.isCollapsible() ) {
9131 - //just treat it as normal text for now
9132 - return;
 9194+ //if we just collapsed this
 9195+ if( $template.hasClass( 'wikiEditor-template-collapsed' ) ) {
 9196+ var model = new $.wikiEditor.modules.templateEditor.fn.model(
 9197+ $template.children( '.wikiEditor-template-text' ).text()
 9198+ );
 9199+ $template.data( 'model' , model );
 9200+ $template.children( '.wikiEditor-template-name' ).text( model.getName() );
 9201+ } else { //we just expanded this
 9202+ $wikitext.text( $template.data( 'model' ).getText() );
91339203 }
91349204
9135 - var $template = $( this )
9136 - .wrap( '<span class="wikiEditor-template"></span>' )
9137 - .addClass( 'wikiEditor-template-text wikiEditor-nodisplay' )
9138 - .parent()
9139 - .addClass( 'wikiEditor-template-collapsed' )
9140 - .data( 'model', model );
9141 -
9142 - var $templateName = $( '<span />' )
9143 - .addClass( 'wikiEditor-template-name wikiEditor-noinclude' )
 9205+ return false;
 9206+ };
 9207+
 9208+ // Expand
 9209+ function expandTemplate( $displayDiv ) {
 9210+ // Housekeeping
 9211+ $displayDiv
 9212+ .removeClass( 'wikiEditor-template-collapsed' )
 9213+ .addClass( 'wikiEditor-template-expanded' )
 9214+ // remove mousedown hander from the entire thing
 9215+ .unbind( 'mousedown' );
 9216+ //$displayDiv.text( model.getText() );
 9217+ $keyValueTable = $( '<table />' )
 9218+ .appendTo( $displayDiv );
 9219+ $header_row = $( '<tr />' )
 9220+ .appendTo( $keyValueTable );
 9221+ $( '<th />' )
 9222+ .attr( 'colspan', '2' )
91449223 .text( model.getName() )
9145 - .mousedown( toggleWikiTextEditor )
9146 - .prependTo( $template );
9147 -
9148 - var $templateExpand = $( '<span />' )
9149 - .addClass( 'wikiEditor-template-expand wikiEditor-noinclude' )
9150 - .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/expand.png" width="12" height="16" />' )
9151 - .append( '<img src="' + $.wikiEditor.imgPath + '/templateEditor/collapse.png" width="12" height="16" style="display:none;" />' )
9152 - .mousedown( toggleWikiTextEditor )
9153 - .prependTo( $template );
9154 -
9155 - var $templateDialog = $( '<span />' )
9156 - .addClass( 'wikiEditor-template-dialog wikiEditor-noinclude' )
9157 - .append( '<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-collapsed.png" width="22" height="16" />' )
9158 - .append( '<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-expanded.png" width="22" height="16" style="display:none;" />' )
9159 - .mousedown( function() { createDialog( $template ); return false; } )
9160 - .insertAfter( $templateName );
9161 -
9162 - $(this).data( 'setupDone', true );
9163 -
9164 - function toggleWikiTextEditor(){
9165 - context.fn.refreshOffsets();
9166 - var $template = $( this ).closest( '.wikiEditor-template' );
9167 - $template
9168 - .toggleClass( 'wikiEditor-template-expanded' )
9169 - .toggleClass( 'wikiEditor-template-collapsed' )
9170 - .find( 'img' )
9171 - .each( function() {
9172 - $( this ).toggle();
9173 - } );
9174 - var $wikitext = $template.children('.wikiEditor-template-text');
9175 - $wikitext.toggleClass('wikiEditor-nodisplay');
 9224+ .appendTo( $header_row );
 9225+ for( param in model.getAllParamNames() ){
 9226+ $keyVal_row = $( '<tr />' )
 9227+ .appendTo( $keyValueTable );
91769228
9177 - //if we just collapsed this
9178 - if( $template.hasClass('wikiEditor-template-collapsed') ) {
9179 - var model = new $.wikiEditor.modules.templateEditor.fn.model(
9180 - $template.children( '.wikiEditor-template-text' ).text()
9181 - );
9182 - $template.data( 'model' , model );
9183 - $template.children( '.wikiEditor-template-name' ).text( model.getName() );
9184 - }
9185 - else{ //we just expanded this
9186 - $wikitext.text($template.data('model').getText());
9187 - }
9188 -
9189 - return false;
9190 - };
 9229+ $( '<td />' )
 9230+ .text( param )
 9231+ .appendTo( $keyVal_row );
 9232+ $( '<td />' )
 9233+ .text( model.getValue( param ) )
 9234+ .appendTo( $keyVal_row );
 9235+ }
 9236+ };
 9237+ // Collapse
 9238+ function collapseTemplate( $displayDiv ) {
 9239+ // Housekeeping
 9240+ $displayDiv
 9241+ .addClass( 'wikiEditor-template-collapsed' )
 9242+ .removeClass( 'wikiEditor-template-expanded' )
 9243+ .text( model.getName() );
 9244+ };
91919245
9192 - // Expand
9193 - function expandTemplate( $displayDiv ) {
9194 - // Housekeeping
9195 - $displayDiv.removeClass( 'wikiEditor-template-collapsed' );
9196 - $displayDiv.addClass( 'wikiEditor-template-expanded' );
9197 - // remove mousedown hander from the entire thing
9198 - $displayDiv.unbind( 'mousedown' );
9199 - //$displayDiv.text( model.getText() );
9200 - $keyValueTable = $( '<table />' )
9201 - .appendTo( $displayDiv );
9202 - $header_row = $( '<tr />' )
9203 - .appendTo( $keyValueTable );
9204 - $( '<th />' )
9205 - .attr( 'colspan', '2' )
9206 - .text( model.getName() )
9207 - .appendTo( $header_row );
9208 - for( param in model.getAllParamNames() ){
9209 - $keyVal_row = $( '<tr />' )
9210 - .appendTo( $keyValueTable );
9211 -
9212 - $( '<td />' )
9213 - .text( param )
9214 - .appendTo( $keyVal_row );
9215 - $( '<td />' )
9216 - .text( model.getValue( param ) )
9217 - .appendTo( $keyVal_row );
 9246+ function createDialog( $templateDiv ) {
 9247+ // Give the user some feedback on what they're doing
 9248+ context.fn.highlightLine( $templateDiv );
 9249+ //
 9250+ var $wikitext = $templateDiv.children( '.wikiEditor-template-text' );
 9251+ //TODO: check if template model has been changed
 9252+ var templateModel = new $.wikiEditor.modules.templateEditor.fn.model( $wikitext.text() );
 9253+ $templateDiv.data( 'model', templateModel );
 9254+ var $dialog = $( '<div />' );
 9255+ var $title = $(' <div />' )
 9256+ .text( templateModel.getName() )
 9257+ .addClass( 'wikiEditor-template-dialog-title' );
 9258+ var $table = $( '<table />' )
 9259+ .addClass( 'wikiEditor-template-dialog-table' )
 9260+ .appendTo( $dialog );
 9261+ var allInitialParams = templateModel.getAllInitialParams();
 9262+ for ( var paramIndex in allInitialParams ) {
 9263+ var param = allInitialParams[paramIndex];
 9264+ if ( typeof param.name == 'undefined' ) {
 9265+ //param 0 is the name
 9266+ continue;
92189267 }
9219 - };
9220 - // Collapse
9221 - function collapseTemplate( $displayDiv ) {
9222 - // Housekeeping
9223 - $displayDiv.addClass( 'wikiEditor-template-collapsed' );
9224 - $displayDiv.removeClass( 'wikiEditor-template-expanded' );
9225 - $displayDiv.text( model.getName() );
9226 - };
9227 -
9228 - function createDialog( $templateDiv ) {
9229 - // Give the user some feedback on what they're doing
 9268+ var $paramRow = $( '<tr />' )
 9269+ .addClass( 'wikiEditor-template-dialog-row' );
 9270+ var $paramName = $( '<td />' )
 9271+ .addClass( 'wikiEditor-template-dialog-name' )
 9272+ .text(
 9273+ param.name.replace( /[\_\-]/g, ' ' ).replace( /^(.)|\s(.)/g, function ( first ) {
 9274+ return first.toUpperCase();
 9275+ } )
 9276+ );
 9277+ var $paramVal = $( '<td />' )
 9278+ .addClass( 'wikiEditor-template-dialog-value' );
 9279+ var $paramInput = $( '<input />' )
 9280+ .data( 'name', param.name )
 9281+ .val( templateModel.getValue( param.name ) );
 9282+ $paramVal.append( $paramInput );
 9283+ $paramRow.append( $paramName ).append( $paramVal );
 9284+ $table.append( $paramRow );
 9285+ }
 9286+ //click handler for values
 9287+ $( '<button />' ).click( function() {
 9288+ // More user feedback
92309289 context.fn.highlightLine( $templateDiv );
92319290 //
9232 - var $wikitext = $templateDiv.children( '.wikiEditor-template-text' );
9233 - //TODO: check if template model has been changed
9234 - var templateModel = new $.wikiEditor.modules.templateEditor.fn.model( $wikitext.text() );
9235 - $templateDiv.data( 'model', templateModel );
9236 - var $dialog = $( '<div />' );
9237 - var $title = $(' <div />' )
9238 - .text( templateModel.getName() )
9239 - .addClass( 'wikiEditor-template-dialog-title' );
9240 - var $table = $( '<table />' )
9241 - .addClass( 'wikiEditor-template-dialog-table' )
9242 - .appendTo( $dialog );
9243 - var allInitialParams = templateModel.getAllInitialParams();
9244 - for ( var paramIndex in allInitialParams ) {
9245 - var param = allInitialParams[paramIndex];
9246 - if ( typeof param.name == 'undefined' ) {
9247 - //param 0 is the name
9248 - continue;
9249 - }
9250 - var $paramRow = $( '<tr />' )
9251 - .addClass( 'wikiEditor-template-dialog-row' );
9252 - var $paramName = $( '<td />' )
9253 - .addClass( 'wikiEditor-template-dialog-name' )
9254 - .text(
9255 - param.name.replace( /[\_\-]/g, ' ' ).replace( /^(.)|\s(.)/g, function ( first ) {
9256 - return first.toUpperCase();
9257 - } )
9258 - );
9259 - var $paramVal = $( '<td />' )
9260 - .addClass( 'wikiEditor-template-dialog-value' );
9261 - var $paramInput = $( '<input />' )
9262 - .data( 'name', param.name )
9263 - .val( templateModel.getValue( param.name ) );
9264 - $paramVal.append( $paramInput );
9265 - $paramRow.append( $paramName ).append( $paramVal );
9266 - $table.append( $paramRow );
9267 - }
9268 - //click handler for values
9269 - $( '<button />' ).click( function() {
9270 - // More user feedback
9271 - context.fn.highlightLine( $templateDiv );
9272 - //
9273 - $( '.wikiEditor-template-dialog-value input' ).each( function(){
9274 - templateModel.setValue( $(this).data('name'), $(this).val() );
9275 - });
9276 - //keep text consistent
9277 - $wikitext.text( templateModel.getText() );
9278 -
9279 - $dialog.dialog( 'close' );
9280 -
9281 - }).text( 'OK' ).appendTo( $dialog ); // FIXME: Internationalize 'OK'
9282 - $dialog.dialog(); //opens dialog
9283 - return false;
9284 - };
 9291+ $( '.wikiEditor-template-dialog-value input' ).each( function(){
 9292+ templateModel.setValue( $(this).data( 'name' ), $(this).val() );
 9293+ });
 9294+ //keep text consistent
 9295+ $wikitext.text( templateModel.getText() );
 9296+
 9297+ $dialog.dialog( 'close' );
 9298+
 9299+ }).text( 'OK' ).appendTo( $dialog ); // FIXME: Internationalize 'OK'
 9300+ $dialog.dialog(); //opens dialog
 9301+ return false;
 9302+ };
 9303+
 9304+ function toggleWikiText() {
 9305+ var $template = $( this ).closest( '.wikiEditor-template' );
 9306+ $template
 9307+ .toggleClass( 'wikiEditor-template-collapsed' )
 9308+ .toggleClass( 'wikiEditor-template-expanded' )
 9309+ .children( '.wikiEditor-template-text, .wikiEditor-template-name, .wikiEditor-template-modes' )
 9310+ .toggleClass( 'wikiEditor-nodisplay' );
92859311
9286 - function toggleWikiText() {
9287 - var $template = $( this ).closest( '.wikiEditor-template' );
9288 - $template
9289 - .toggleClass( 'wikiEditor-template-collapsed' )
9290 - .toggleClass( 'wikiEditor-template-expanded' )
9291 - .children( '.wikiEditor-template-text, .wikiEditor-template-name, .wikiEditor-template-modes' )
9292 - .toggleClass( 'wikiEditor-nodisplay' );
 9312+ //if we just collapsed this
 9313+ if ( $template.hasClass( 'wikiEditor-template-collapsed' ) ) {
 9314+ var model = new $.wikiEditor.modules.templateEditor.fn.model(
 9315+ $template.children( '.wikiEditor-template-text' ).text()
 9316+ );
 9317+ $template.data( 'model' , model );
 9318+ $template.children( '.wikiEditor-template-name' ).text( model.getName() );
 9319+ } else{ //else we just expanded this
 9320+ $template.children( '.wikiEditor-template-text' ).children('.wikiEditor-template-inner-text').text(
 9321+ $template.data('model')
 9322+ .getText()
 9323+ .replace(/\{\{/, '')
 9324+ .replace(/\}\}$/, '')
 9325+ );
92939326
9294 - //if we just collapsed this
9295 - if ( $template.hasClass( 'wikiEditor-template-collapsed' ) ) {
9296 - var model = new $.wikiEditor.modules.templateEditor.fn.model(
9297 - $template.children( '.wikiEditor-template-text' ).text()
9298 - );
9299 - $template.data( 'model' , model );
9300 - $template.children( '.wikiEditor-template-name' ).text( model.getName() );
9301 - } else{ //else we just expanded this
9302 - $template.children( '.wikiEditor-template-text' ).children('.wikiEditor-template-inner-text').text(
9303 - $template.data('model')
9304 - .getText()
9305 - .replace(/\{\{/, '')
9306 - .replace(/\}\}$/, '')
9307 - );
9308 -
9309 - }
9310 - return false;
93119327 }
9312 -
9313 - function noEdit() {
9314 - return false;
9315 - }
9316 - });
 9328+ return false;
 9329+ }
93179330
 9331+ function noEdit() {
 9332+ return false;
 9333+ }
93189334 },
 9335+ /**
 9336+ * Turn a complex template wrapper back into a simple one
 9337+ * @param $wrapper Wrapping <span>
 9338+ */
 9339+ unwrapTemplate: function( $wrapper ) {
 9340+ $wrapper.parent().replaceWith( $wrapper );
 9341+ },
93199342
93209343 /**
93219344 * Gets templateInfo node from templateInfo extension, if it exists
@@ -9322,6 +9345,7 @@
93239346 getTemplateInfo: function ( templateName ) {
93249347 var templateInfo = '';
93259348 // TODO: API call here
 9349+ // FIXME: This setup won't work very well with the async nature of grabbing the template info
93269350 return $( templateInfo );
93279351 },
93289352
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -586,8 +586,8 @@
587587 if(s.offset>0&&s.node.nodeName=='#text'){startNode=startNode.splitText(s.offset<s.node.nodeValue.length?s.offset:s.node.nodeValue.length-1);context.fn.purgeOffsets();}
588588 if(markers[i].splitPs&&startNode.parentNode.nodeName=='P'){var startP=startNode.ownerDocument.createElement('p');while(startNode.parentNode.firstChild!=startNode){startP.appendChild(startNode.parentNode.firstChild);}
589589 if(startP.firstChild){startNode.parentNode.insertBefore(startP,startNode);}}
590 -var end=markers[i].end;var e=context.fn.getOffset(end);if(!e){continue;}
591 -var endNode=e.node;var endDepth=e.depth;if(e.offset<e.length-1&&e.node.nodeName=='#text'){endNode.splitText(e.offset);context.fn.purgeOffsets();}
 590+var end=markers[i].end;var e=context.fn.getOffset(end-1);if(!e){continue;}
 591+var endNode=e.node;var endDepth=e.depth;if(e.offset+1<e.length-1&&e.node.nodeName=='#text'){endNode.splitText(e.offset+1);context.fn.purgeOffsets();}
592592 if(markers[i].splitPs&&endNode.parentNode.nodeName=='P'&&endNode.parentNode.parentNode){var endP=endNode.parentNode;while(endP.firstChild!=endNode){endP.parentNode.insertBefore(endP.firstChild,endP);}
593593 endP.parentNode.insertBefore(endNode,endP);if(!endP.firstChild){endP.parentNode.removeChild(endP);}}
594594 if(endNode.nodeName=='BR'){endNode=e.lastTextNode;endDepth=e.lastTextNodeDepth;}
@@ -633,15 +633,13 @@
634634 $('#wikiEditor-'+context.instance+'-dialog-watch').hide();else if($('#wpWatchthis').is(':checked'))
635635 $('#wikiEditor-'+context.instance+'-dialog-watch').attr('checked','checked');$(this).find('form').submit(function(e){$(this).closest('.ui-dialog').find('button:first').click();e.preventDefault();});},dialog:{buttons:{'wikieditor-publish-dialog-publish':function(){var minorChecked=$('#wikiEditor-'+context.instance+'-dialog-minor').is(':checked')?'checked':'';var watchChecked=$('#wikiEditor-'+context.instance+'-dialog-watch').is(':checked')?'checked':'';$('#wpMinoredit').attr('checked',minorChecked);$('#wpWatchthis').attr('checked',watchChecked);$('#wpSummary').val($j('#wikiEditor-'+context.instance+'-dialog-summary').val());$('#editform').submit();},'wikieditor-publish-dialog-goback':function(){$(this).dialog('close');}},open:function(){$('#wikiEditor-'+context.instance+'-dialog-summary').focus();},width:500},resizeme:false}});context.fn.addButton({'captionMsg':'wikieditor-publish-button-publish','action':function(){$('#'+dialogID).dialog('open');return false;}});context.fn.addButton({'captionMsg':'wikieditor-publish-button-cancel','action':function(){}});}}};})(jQuery);(function($){$.wikiEditor.modules.templateEditor={'browsers':{'ltr':{'msie':[['>=',8]],'firefox':[['>=',3]],'opera':[['>=',10]],'safari':[['>=',4]]},'rtl':{'msie':[['>=',8]],'firefox':[['>=',3]],'opera':[['>=',10]],'safari':[['>=',4]]}},'req':['iframe'],evt:{mark:function(context,event){var markers=context.modules.highlight.markers;var tokenArray=context.modules.highlight.tokenArray;var level=0;var tokenIndex=0;while(tokenIndex<tokenArray.length){while(tokenIndex<tokenArray.length&&tokenArray[tokenIndex].label!='TEMPLATE_BEGIN'){tokenIndex++;}
636636 if(tokenIndex<tokenArray.length){var beginIndex=tokenIndex;var endIndex=-1;var openTemplates=1;var templatesMatched=false;while(tokenIndex<tokenArray.length-1&&endIndex==-1){tokenIndex++;if(tokenArray[tokenIndex].label=='TEMPLATE_BEGIN'){openTemplates++;}else if(tokenArray[tokenIndex].label=='TEMPLATE_END'){openTemplates--;if(openTemplates==0){endIndex=tokenIndex;}}}
637 -if(endIndex!=-1){var model=new $.wikiEditor.modules.templateEditor.fn.model(context.fn.getContents().substring(tokenArray[beginIndex].offset,tokenArray[endIndex].offset));markers.push({start:tokenArray[beginIndex].offset,end:tokenArray[endIndex].offset,type:'template',anchor:'wrap',splitPs:false,afterWrap:$.wikiEditor.modules.templateEditor.fn.stylize,beforeUnwrap:function(node){},onSkip:function(){},getAnchor:function(ca1,ca2){return $(ca1.parentNode).is('span.wikiEditor-template-text')?ca1.parentNode:null;},model:model,context:context});}else{tokenArray[beginIndex].label='TEMPLATE_FALSE_BEGIN';tokenIndex=beginIndex;}}}}},exp:[{'regex':/{{/,'label':"TEMPLATE_BEGIN"},{'regex':/}}/,'label':"TEMPLATE_END",'markAfter':true}],cfg:{},fn:{create:function(context,config){context.modules.templateEditor={};},stylize:function(wrappedTemplate){$(wrappedTemplate).each(function(){if(typeof $(this).data('setupDone')!='undefined'){return;}
638 -var model=$(this).data('marker').model;var context=$(this).data('marker').context;if(!model.isCollapsible()){return;}
639 -var $template=$(this).wrap('<span class="wikiEditor-template"></span>').addClass('wikiEditor-template-text wikiEditor-nodisplay').parent().addClass('wikiEditor-template-collapsed').data('model',model);var $templateName=$('<span />').addClass('wikiEditor-template-name wikiEditor-noinclude').text(model.getName()).mousedown(toggleWikiTextEditor).prependTo($template);var $templateExpand=$('<span />').addClass('wikiEditor-template-expand wikiEditor-noinclude').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/expand.png" width="12" height="16" />').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/collapse.png" width="12" height="16" style="display:none;" />').mousedown(toggleWikiTextEditor).prependTo($template);var $templateDialog=$('<span />').addClass('wikiEditor-template-dialog wikiEditor-noinclude').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-collapsed.png" width="22" height="16" />').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-expanded.png" width="22" height="16" style="display:none;" />').mousedown(function(){createDialog($template);return false;}).insertAfter($templateName);$(this).data('setupDone',true);function toggleWikiTextEditor(){context.fn.refreshOffsets();var $template=$(this).closest('.wikiEditor-template');$template.toggleClass('wikiEditor-template-expanded').toggleClass('wikiEditor-template-collapsed').find('img').each(function(){$(this).toggle();});var $wikitext=$template.children('.wikiEditor-template-text');$wikitext.toggleClass('wikiEditor-nodisplay');if($template.hasClass('wikiEditor-template-collapsed')){var model=new $.wikiEditor.modules.templateEditor.fn.model($template.children('.wikiEditor-template-text').text());$template.data('model',model);$template.children('.wikiEditor-template-name').text(model.getName());}
640 -else{$wikitext.text($template.data('model').getText());}
641 -return false;};function expandTemplate($displayDiv){$displayDiv.removeClass('wikiEditor-template-collapsed');$displayDiv.addClass('wikiEditor-template-expanded');$displayDiv.unbind('mousedown');$keyValueTable=$('<table />').appendTo($displayDiv);$header_row=$('<tr />').appendTo($keyValueTable);$('<th />').attr('colspan','2').text(model.getName()).appendTo($header_row);for(param in model.getAllParamNames()){$keyVal_row=$('<tr />').appendTo($keyValueTable);$('<td />').text(param).appendTo($keyVal_row);$('<td />').text(model.getValue(param)).appendTo($keyVal_row);}};function collapseTemplate($displayDiv){$displayDiv.addClass('wikiEditor-template-collapsed');$displayDiv.removeClass('wikiEditor-template-expanded');$displayDiv.text(model.getName());};function createDialog($templateDiv){context.fn.highlightLine($templateDiv);var $wikitext=$templateDiv.children('.wikiEditor-template-text');var templateModel=new $.wikiEditor.modules.templateEditor.fn.model($wikitext.text());$templateDiv.data('model',templateModel);var $dialog=$('<div />');var $title=$(' <div />').text(templateModel.getName()).addClass('wikiEditor-template-dialog-title');var $table=$('<table />').addClass('wikiEditor-template-dialog-table').appendTo($dialog);var allInitialParams=templateModel.getAllInitialParams();for(var paramIndex in allInitialParams){var param=allInitialParams[paramIndex];if(typeof param.name=='undefined'){continue;}
 637+if(endIndex!=-1){var model=new $.wikiEditor.modules.templateEditor.fn.model(context.fn.getContents().substring(tokenArray[beginIndex].offset,tokenArray[endIndex].offset));markers.push({start:tokenArray[beginIndex].offset,end:tokenArray[endIndex].offset,type:'template',anchor:'wrap',splitPs:false,afterWrap:function(node){$(node).data('model',$(node).data('marker').model);if(model.isCollapsible()){$.wikiEditor.modules.templateEditor.fn.wrapTemplate($(node));}else{$(node).addClass('wikiEditor-template-text');}},beforeUnwrap:function(node){if($(node).parent().hasClass('wikiEditor-template')){$.wikiEditor.modules.templateEditor.fn.unwrapTemplate($(node));}},onSkip:function(node){var oldModel=$(node).data('model');var newModel=$(node).data('marker').model;if(oldModel.getText()==newModel.getText()){return;}
 638+if($(node).parent().hasClass('wikiEditor-template')&&!newModel.isCollapsible()){$.wikiEditor.modules.templateEditor.fn.unwrapTemplate($(node));}else if(!$(node).parent().hasClass('wikiEditor-template')&&newModel.isCollapsible()){$.wikiEditor.modules.templateEditor.fn.wrapTemplate($(node));}},getAnchor:function(ca1,ca2){return $(ca1.parentNode).is('span.wikiEditor-template-text')?ca1.parentNode:null;},model:model,context:context});}else{tokenArray[beginIndex].label='TEMPLATE_FALSE_BEGIN';tokenIndex=beginIndex;}}}}},exp:[{'regex':/{{/,'label':"TEMPLATE_BEGIN"},{'regex':/}}/,'label':"TEMPLATE_END",'markAfter':true}],cfg:{},fn:{create:function(context,config){context.modules.templateEditor={};},wrapTemplate:function($wrapper){var model=$wrapper.data('marker').model;var context=$wrapper.data('marker').context;var $template=$wrapper.wrap('<span class="wikiEditor-template"></span>').addClass('wikiEditor-nodisplay').parent().addClass('wikiEditor-template-collapsed').data('model',model);var $templateName=$('<span />').addClass('wikiEditor-template-name wikiEditor-noinclude').text(model.getName()).mousedown(toggleWikiTextEditor).prependTo($template);var $templateExpand=$('<span />').addClass('wikiEditor-template-expand wikiEditor-noinclude').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/expand.png" width="12" height="16" />').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/collapse.png" width="12" height="16" style="display:none;" />').mousedown(toggleWikiTextEditor).prependTo($template);var $templateDialog=$('<span />').addClass('wikiEditor-template-dialog wikiEditor-noinclude').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-collapsed.png" width="22" height="16" />').append('<img src="'+$.wikiEditor.imgPath+'/templateEditor/dialog-expanded.png" width="22" height="16" style="display:none;" />').mousedown(function(){createDialog($template);return false;}).insertAfter($templateName);function toggleWikiTextEditor(){context.fn.refreshOffsets();var $template=$(this).closest('.wikiEditor-template');$template.toggleClass('wikiEditor-template-expanded').toggleClass('wikiEditor-template-collapsed').find('img').each(function(){$(this).toggle();});var $wikitext=$template.children('.wikiEditor-template-text');$wikitext.toggleClass('wikiEditor-nodisplay');if($template.hasClass('wikiEditor-template-collapsed')){var model=new $.wikiEditor.modules.templateEditor.fn.model($template.children('.wikiEditor-template-text').text());$template.data('model',model);$template.children('.wikiEditor-template-name').text(model.getName());}else{$wikitext.text($template.data('model').getText());}
 639+return false;};function expandTemplate($displayDiv){$displayDiv.removeClass('wikiEditor-template-collapsed').addClass('wikiEditor-template-expanded').unbind('mousedown');$keyValueTable=$('<table />').appendTo($displayDiv);$header_row=$('<tr />').appendTo($keyValueTable);$('<th />').attr('colspan','2').text(model.getName()).appendTo($header_row);for(param in model.getAllParamNames()){$keyVal_row=$('<tr />').appendTo($keyValueTable);$('<td />').text(param).appendTo($keyVal_row);$('<td />').text(model.getValue(param)).appendTo($keyVal_row);}};function collapseTemplate($displayDiv){$displayDiv.addClass('wikiEditor-template-collapsed').removeClass('wikiEditor-template-expanded').text(model.getName());};function createDialog($templateDiv){context.fn.highlightLine($templateDiv);var $wikitext=$templateDiv.children('.wikiEditor-template-text');var templateModel=new $.wikiEditor.modules.templateEditor.fn.model($wikitext.text());$templateDiv.data('model',templateModel);var $dialog=$('<div />');var $title=$(' <div />').text(templateModel.getName()).addClass('wikiEditor-template-dialog-title');var $table=$('<table />').addClass('wikiEditor-template-dialog-table').appendTo($dialog);var allInitialParams=templateModel.getAllInitialParams();for(var paramIndex in allInitialParams){var param=allInitialParams[paramIndex];if(typeof param.name=='undefined'){continue;}
642640 var $paramRow=$('<tr />').addClass('wikiEditor-template-dialog-row');var $paramName=$('<td />').addClass('wikiEditor-template-dialog-name').text(param.name.replace(/[\_\-]/g,' ').replace(/^(.)|\s(.)/g,function(first){return first.toUpperCase();}));var $paramVal=$('<td />').addClass('wikiEditor-template-dialog-value');var $paramInput=$('<input />').data('name',param.name).val(templateModel.getValue(param.name));$paramVal.append($paramInput);$paramRow.append($paramName).append($paramVal);$table.append($paramRow);}
643641 $('<button />').click(function(){context.fn.highlightLine($templateDiv);$('.wikiEditor-template-dialog-value input').each(function(){templateModel.setValue($(this).data('name'),$(this).val());});$wikitext.text(templateModel.getText());$dialog.dialog('close');}).text('OK').appendTo($dialog);$dialog.dialog();return false;};function toggleWikiText(){var $template=$(this).closest('.wikiEditor-template');$template.toggleClass('wikiEditor-template-collapsed').toggleClass('wikiEditor-template-expanded').children('.wikiEditor-template-text, .wikiEditor-template-name, .wikiEditor-template-modes').toggleClass('wikiEditor-nodisplay');if($template.hasClass('wikiEditor-template-collapsed')){var model=new $.wikiEditor.modules.templateEditor.fn.model($template.children('.wikiEditor-template-text').text());$template.data('model',model);$template.children('.wikiEditor-template-name').text(model.getName());}else{$template.children('.wikiEditor-template-text').children('.wikiEditor-template-inner-text').text($template.data('model').getText().replace(/\{\{/,'').replace(/\}\}$/,''));}
644642 return false;}
645 -function noEdit(){return false;}});},getTemplateInfo:function(templateName){var templateInfo='';return $(templateInfo);},model:function(wikitext){var collapsible=true;function Param(name,value,number,nameIndex,equalsIndex,valueIndex){this.name=name;this.value=value;this.number=number;this.nameIndex=nameIndex;this.equalsIndex=equalsIndex;this.valueIndex=valueIndex;}
 643+function noEdit(){return false;}},unwrapTemplate:function($wrapper){$wrapper.parent().replaceWith($wrapper);},getTemplateInfo:function(templateName){var templateInfo='';return $(templateInfo);},model:function(wikitext){var collapsible=true;function Param(name,value,number,nameIndex,equalsIndex,valueIndex){this.name=name;this.value=value;this.number=number;this.nameIndex=nameIndex;this.equalsIndex=equalsIndex;this.valueIndex=valueIndex;}
646644 function Range(begin,end){this.begin=begin;this.end=end;}
647645 function getSetValue(name,value,original){var valueRange;var rangeIndex;var retVal;if(isNaN(name)){if(typeof paramsByName[name]=='undefined'){return"";}
648646 rangeIndex=paramsByName[name];}else{rangeIndex=parseInt(name);}

Follow-up revisions

RevisionCommit summaryAuthorDate
r63122UsabilityInitiative: Fix r63094, r63121 per CRcatrope17:24, 1 March 2010

Comments

#Comment by Adammiller~mediawikiwiki (talk | contribs)   17:05, 1 March 2010
-				.addClass( 'wikiEditor-template-text wikiEditor-nodisplay' )
+			.addClass( 'wikiEditor-nodisplay' )

Why didn't you retain the wikiEditor-template-text class on the span containing the raw wikitext? Seems like this breaks expanding and collapsing, and maybe some other things as well.


#Comment by Catrope (talk | contribs)   17:25, 1 March 2010

Good catch. When I was working on this code this morning, I was agitated at the fact that that class had disappeared (how ironic) so I readded it in a different place in r63121. Cleaned this up in r63122.

Status & tagging log