r62329 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r62328‎ | r62329 | r62330 >
Date:21:35, 11 February 2010
Author:tparscal
Status:resolved (Comments)
Tags:
Comment:
Fixes bug #22398 which was caused by the pre-wrap CSS style being applied to the body durring pasting, and newline characters being inserted in the pasted content. We now change the class while pasting to something that overrides the white-space rule and strip out newlines on paste. We now need a cursor restore solution for pasting however since we have to replace the entire HTML contents. Alternatively, we might be able to step through text nodes in the dom and strip the newlines out on an element-by-element basis.
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.html (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.templateEditor.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -72,20 +72,20 @@
7373 array( 'src' => 'js/plugins/jquery.namespaceSelect.js', 'version' => 1 ),
7474 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 7 ),
7575 array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 27 ),
76 - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 119 ),
 76+ array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 120 ),
7777 array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 29 ),
7878 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 48 ),
7979 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 12 ),
80 - array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 81 ),
 80+ array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 82 ),
8181 array( 'src' => 'js/plugins/jquery.wikiEditor.preview.js', 'version' => 10 ),
8282 array( 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js', 'version' => 17 ),
8383 array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 2 ),
8484 ),
8585 'combined' => array(
86 - array( 'src' => 'js/plugins.combined.js', 'version' => 239 ),
 86+ array( 'src' => 'js/plugins.combined.js', 'version' => 240 ),
8787 ),
8888 'minified' => array(
89 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 239 ),
 89+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 240 ),
9090 ),
9191 ),
9292 );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.templateEditor.js
@@ -1,7 +1,25 @@
22 /* TemplateEditor module for wikiEditor */
33 ( function( $ ) { $.wikiEditor.modules.templateEditor = {
4 -
54 /**
 5+ * Compatability map
 6+ */
 7+'browsers': {
 8+ // Left-to-right languages
 9+ 'ltr': {
 10+ 'msie': [['>=', 8]],
 11+ 'firefox': [['>=', 3]],
 12+ 'opera': [['>=', 10]],
 13+ 'safari': [['>=', 4]]
 14+ },
 15+ // Right-to-left languages
 16+ 'rtl': {
 17+ 'msie': [['>=', 8]],
 18+ 'firefox': [['>=', 3]],
 19+ 'opera': [['>=', 10]],
 20+ 'safari': [['>=', 4]]
 21+ }
 22+},
 23+/**
624 * Event handlers
725 */
826 evt: {
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.html
@@ -27,6 +27,9 @@
2828 white-space: -o-pre-wrap; /* Opera 7 */
2929 word-wrap: break-word; /* Internet Explorer 5.5+ */
3030 }
 31+ body.pasting {
 32+ white-space: normal;
 33+ }
3134 p {
3235 margin: 0;
3336 padding: 0;
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -77,18 +77,21 @@
7878 * is essentially to blacklist rather than whitelist are debateable, but at this point we've decided it's the more
7979 * "open-web" way to go.
8080 */
81 - 'isSupported': function() {
 81+ 'isSupported': function( module ) {
 82+ var map = module && typeof $.wikiEditor.modules[module].browsers ?
 83+ $.wikiEditor.modules[module].browsers :
 84+ $.wikiEditor.browsers;
8285 // Check for and make use of a cached return value
8386 if ( typeof $.wikiEditor.supported != 'undefined' ) {
8487 return $.wikiEditor.supported;
8588 }
8689 // Check if we have any compatiblity information on-hand for the current browser
87 - if ( !( $.browser.name in $.wikiEditor.browsers[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'] ) ) {
 90+ if ( !( $.browser.name in map[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'] ) ) {
8891 // Assume good faith :)
8992 return $.wikiEditor.supported = true;
9093 }
9194 // Check over each browser condition to determine if we are running in a compatible client
92 - var browser = $.wikiEditor.browsers[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'][$.browser.name];
 95+ var browser = map[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'][$.browser.name];
9396 for ( var condition in browser ) {
9497 var op = browser[condition][0];
9598 var val = browser[condition][1];
@@ -369,6 +372,7 @@
370373 },
371374 'paste': function( event ) {
372375 context.$content.find( ':not(.wikiEditor)' ).addClass( 'wikiEditor' );
 376+ context.$content.addClass( 'pasting' );
373377 setTimeout( function() {
374378 var $selection = context.$content.find( ':not(.wikiEditor)' );
375379 while ( $selection.length && $selection.length > 0 ) {
@@ -387,6 +391,10 @@
388392 }
389393 $selection = context.$content.find( ':not(.wikiEditor)' );
390394 }
 395+ context.$content.find( '.wikiEditor' ).removeClass( 'wikiEditor' );
 396+ // Remove newlines from everything
 397+ context.$content.html( context.$content.html().replace( /\n/g, '' ) );
 398+ context.$content.removeClass( 'pasting' );
391399 }, 0 );
392400 return true;
393401 }
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -6510,18 +6510,21 @@
65116511 * is essentially to blacklist rather than whitelist are debateable, but at this point we've decided it's the more
65126512 * "open-web" way to go.
65136513 */
6514 - 'isSupported': function() {
 6514+ 'isSupported': function( module ) {
 6515+ var map = module && typeof $.wikiEditor.modules[module].browsers ?
 6516+ $.wikiEditor.modules[module].browsers :
 6517+ $.wikiEditor.browsers;
65156518 // Check for and make use of a cached return value
65166519 if ( typeof $.wikiEditor.supported != 'undefined' ) {
65176520 return $.wikiEditor.supported;
65186521 }
65196522 // Check if we have any compatiblity information on-hand for the current browser
6520 - if ( !( $.browser.name in $.wikiEditor.browsers[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'] ) ) {
 6523+ if ( !( $.browser.name in map[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'] ) ) {
65216524 // Assume good faith :)
65226525 return $.wikiEditor.supported = true;
65236526 }
65246527 // Check over each browser condition to determine if we are running in a compatible client
6525 - var browser = $.wikiEditor.browsers[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'][$.browser.name];
 6528+ var browser = map[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'][$.browser.name];
65266529 for ( var condition in browser ) {
65276530 var op = browser[condition][0];
65286531 var val = browser[condition][1];
@@ -6802,6 +6805,7 @@
68036806 },
68046807 'paste': function( event ) {
68056808 context.$content.find( ':not(.wikiEditor)' ).addClass( 'wikiEditor' );
 6809+ context.$content.addClass( 'pasting' );
68066810 setTimeout( function() {
68076811 var $selection = context.$content.find( ':not(.wikiEditor)' );
68086812 while ( $selection.length && $selection.length > 0 ) {
@@ -6820,6 +6824,10 @@
68216825 }
68226826 $selection = context.$content.find( ':not(.wikiEditor)' );
68236827 }
 6828+ context.$content.find( '.wikiEditor' ).removeClass( 'wikiEditor' );
 6829+ // Remove newlines from everything
 6830+ context.$content.html( context.$content.html().replace( /\n/g, '' ) );
 6831+ context.$content.removeClass( 'pasting' );
68246832 }, 0 );
68256833 return true;
68266834 }
@@ -8704,8 +8712,26 @@
87058713 }; } )( jQuery );
87068714 /* TemplateEditor module for wikiEditor */
87078715 ( function( $ ) { $.wikiEditor.modules.templateEditor = {
8708 -
87098716 /**
 8717+ * Compatability map
 8718+ */
 8719+'browsers': {
 8720+ // Left-to-right languages
 8721+ 'ltr': {
 8722+ 'msie': [['>=', 8]],
 8723+ 'firefox': [['>=', 3]],
 8724+ 'opera': [['>=', 10]],
 8725+ 'safari': [['>=', 4]]
 8726+ },
 8727+ // Right-to-left languages
 8728+ 'rtl': {
 8729+ 'msie': [['>=', 8]],
 8730+ 'firefox': [['>=', 3]],
 8731+ 'opera': [['>=', 10]],
 8732+ 'safari': [['>=', 4]]
 8733+ }
 8734+},
 8735+/**
87108736 * Event handlers
87118737 */
87128738 evt: {
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -436,9 +436,9 @@
437437 options.endContainer=options.startContainer;break;case'scrollToCaretPosition':options=$.extend({'force':false},options);break;}
438438 var context=$(this).data('wikiEditor-context');var hasIframe=context!==undefined&&context.$iframe!==undefined;var needSave=false;if(hasIframe&&context.savedSelection!==null){context.fn.restoreSelection();needSave=true;}
439439 retval=(hasIframe?context.fn:fn)[command].call(this,options);if(hasIframe&&needSave){context.fn.saveSelection();}
440 -return retval;};})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[],'browsers':{'ltr':{'msie':[['>=',7]],'firefox':[['>=',2],['!=','2.0'],['!=','2.0.0.1'],['!=','2.0.0.2'],['!=','2.0.0.3'],['!=','2.0.0.4']],'opera':[['>=',9.6]],'safari':[['>=',4]]},'rtl':{'msie':[['>=',8]],'firefox':[['>=',2],['!=','2.0'],['!=','2.0.0.1'],['!=','2.0.0.2'],['!=','2.0.0.3'],['!=','2.0.0.4']],'opera':[['>=',9.6]],'safari':[['>=',4]]}},'imgPath':wgScriptPath+'/extensions/UsabilityInitiative/images/wikiEditor/','isSupported':function(){if(typeof $.wikiEditor.supported!='undefined'){return $.wikiEditor.supported;}
441 -if(!($.browser.name in $.wikiEditor.browsers[$('body').is('.rtl')?'rtl':'ltr'])){return $.wikiEditor.supported=true;}
442 -var browser=$.wikiEditor.browsers[$('body').is('.rtl')?'rtl':'ltr'][$.browser.name];for(var condition in browser){var op=browser[condition][0];var val=browser[condition][1];if(typeof val=='string'){if(!(eval('$.browser.version'+op+'"'+val+'"'))){return $.wikiEditor.supported=false;}}else if(typeof val=='number'){if(!(eval('$.browser.versionNumber'+op+val))){return $.wikiEditor.supported=false;}}}
 440+return retval;};})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[],'browsers':{'ltr':{'msie':[['>=',7]],'firefox':[['>=',2],['!=','2.0'],['!=','2.0.0.1'],['!=','2.0.0.2'],['!=','2.0.0.3'],['!=','2.0.0.4']],'opera':[['>=',9.6]],'safari':[['>=',4]]},'rtl':{'msie':[['>=',8]],'firefox':[['>=',2],['!=','2.0'],['!=','2.0.0.1'],['!=','2.0.0.2'],['!=','2.0.0.3'],['!=','2.0.0.4']],'opera':[['>=',9.6]],'safari':[['>=',4]]}},'imgPath':wgScriptPath+'/extensions/UsabilityInitiative/images/wikiEditor/','isSupported':function(module){var map=module&&typeof $.wikiEditor.modules[module].browsers?$.wikiEditor.modules[module].browsers:$.wikiEditor.browsers;if(typeof $.wikiEditor.supported!='undefined'){return $.wikiEditor.supported;}
 441+if(!($.browser.name in map[$('body').is('.rtl')?'rtl':'ltr'])){return $.wikiEditor.supported=true;}
 442+var browser=map[$('body').is('.rtl')?'rtl':'ltr'][$.browser.name];for(var condition in browser){var op=browser[condition][0];var val=browser[condition][1];if(typeof val=='string'){if(!(eval('$.browser.version'+op+'"'+val+'"'))){return $.wikiEditor.supported=false;}}else if(typeof val=='number'){if(!(eval('$.browser.versionNumber'+op+val))){return $.wikiEditor.supported=false;}}}
443443 return $.wikiEditor.supported=true;},'autoMsg':function(object,property){if(typeof property=='object'){for(var i in property){if(property[i]in object||property[i]+'Msg'in object){property=property[i];break;}}}
444444 if(property in object){return object[property];}else if(property+'Msg'in object){if(typeof object[property+'Msg']=='object'){return mw.usability.getMsg.apply(mw.usability,object[property+'Msg']);}else{return mw.usability.getMsg(object[property+'Msg']);}}else{return'';}},'autoLang':function(object,lang){return object[lang||wgUserLanguage]||object['default']||object;},'autoIcon':function(icon,path,lang){var src=$.wikiEditor.autoLang(icon,lang);path=path||$.wikiEditor.imgPath;if(src.substr(0,7)!='http://'&&src.substr(0,8)!='https://'&&src[0]!='/'){src=path+src;}
445445 return src+'?'+wgWikiEditorIconVersion;}};$.fn.wikiEditor=function(){if(!$j.wikiEditor.isSupported()){return $(this);}
@@ -455,9 +455,10 @@
456456 switch(event.which){case 8:break;}
457457 return true;},'delayedChange':function(event){event.data.scope='division';var newHTML=context.$content.html();if(context.oldDelayedHTML!=newHTML){context.fn.purgeOffsets();context.oldDelayedHTML=newHTML;event.data.scope='realchange';if(newHTML!==context.history[context.history.length+context.historyPosition].html){context.historyPosition=-1;}
458458 context.history.push({'html':newHTML});while(context.history.length>10){context.history.shift();}}
459 -return true;},'paste':function(event){context.$content.find(':not(.wikiEditor)').addClass('wikiEditor');setTimeout(function(){var $selection=context.$content.find(':not(.wikiEditor)');while($selection.length&&$selection.length>0){var $currentElement=$selection.eq(0);while(!$currentElement.parent().is('body')&&!$currentElement.parent().is('.wikiEditor')){$currentElement=$currentElement.parent();}
 459+return true;},'paste':function(event){context.$content.find(':not(.wikiEditor)').addClass('wikiEditor');context.$content.addClass('pasting');setTimeout(function(){var $selection=context.$content.find(':not(.wikiEditor)');while($selection.length&&$selection.length>0){var $currentElement=$selection.eq(0);while(!$currentElement.parent().is('body')&&!$currentElement.parent().is('.wikiEditor')){$currentElement=$currentElement.parent();}
460460 if($currentElement.is('br')){$currentElement.addClass('wikiEditor');}else{$('<p></p>').text($currentElement.text()).addClass('wikiEditor').insertAfter($currentElement);$currentElement.remove();}
461 -$selection=context.$content.find(':not(.wikiEditor)');}},0);return true;}};context.fn={'trigger':function(name,event){if(typeof event=='undefined'){event={'type':'custom'};}
 461+$selection=context.$content.find(':not(.wikiEditor)');}
 462+context.$content.find('.wikiEditor').removeClass('wikiEditor');context.$content.html(context.$content.html().replace(/\n/g,''));context.$content.removeClass('pasting');},0);return true;}};context.fn={'trigger':function(name,event){if(typeof event=='undefined'){event={'type':'custom'};}
462463 if(typeof event.data=='undefined'){event.data={};}
463464 if(name in context.evt){if(!context.evt[name](event)){return false;}}
464465 for(var module in context.modules){if(module in $.wikiEditor.modules&&'evt'in $.wikiEditor.modules[module]&&name in $.wikiEditor.modules[module].evt){$.wikiEditor.modules[module].evt[name](context,event);}}
@@ -609,7 +610,7 @@
610611 $('#wikiEditor-'+context.instance+'-dialog-minor').hide();else if($('#wpMinoredit').is(':checked'))
611612 $('#wikiEditor-'+context.instance+'-dialog-minor').attr('checked','checked');if($('#wpWatchthis').size()==0)
612613 $('#wikiEditor-'+context.instance+'-dialog-watch').hide();else if($('#wpWatchthis').is(':checked'))
613 -$('#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={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++;}
 614+$('#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]]}},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++;}
614615 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;}}}
615616 if(endIndex!=-1){markers.push({start:tokenArray[beginIndex].offset,end:tokenArray[endIndex].offset,type:'template',anchor:'wrap',afterWrap:$.wikiEditor.modules.templateEditor.fn.stylize,beforeUnwrap:function(node){$(node).data('display').remove();},onSkip:function(){},getAnchor:function(ca1,ca2){return $(ca1.parentNode).is('div.wikiEditor-template-text')&&$(ca1.parentNode.previousSibling).is('ul.wikiEditor-template-modes')&&ca1.parentNode.nextSibling==null?ca1.parentNode:null;}});}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('model')!='undefined'){return;}
616617 var model=new $.wikiEditor.modules.templateEditor.fn.model($(this).text());if(!model.isCollapsible()){return;}

Follow-up revisions

RevisionCommit summaryAuthorDate
r62403wmf-deployment: Backport part for r62329 to make stuff workcatrope00:09, 13 February 2010

Comments

#Comment by Catrope (talk | contribs)   21:44, 11 February 2010
+		var map = module && typeof $.wikiEditor.modules[module].browsers ?
+				$.wikiEditor.modules[module].browsers :
+				$.wikiEditor.browsers;

Since typeof always returns a string, the condition is always true. You probably meant to add  != 'undefined' there. Alternatively, you can just use var map = ( module && $.wikiEditor.modules[module].browsers ) || $.wikiEditor.browsers;

+				context.$content.html( context.$content.html().replace( /\n/g, '' ) );

Apart from cursor moving issues, this also makes event handlers disappear.

Status & tagging log