r66453 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r66452‎ | r66453 | r66454 >
Date:22:54, 14 May 2010
Author:pdhanda
Status:ok (Comments)
Tags:
Comment:
Cleaned up paste code. IE still needs work
Modified paths:
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -85,6 +85,7 @@
8686 'isSupported': function( module ) {
8787 // Fallback to the wikiEditor browser map if no special map is provided in the module
8888 var mod = module && 'browsers' in module ? module : $.wikiEditor;
 89+ return mod.supported = true;
8990 // Check for and make use of cached value and early opportunities to bail
9091 if ( typeof mod.supported !== 'undefined' ) {
9192 // Cache hit
@@ -418,8 +419,12 @@
419420 'paste': function( event ) {
420421 // Save the cursor position to restore it after all this voodoo
421422 var cursorPos = context.fn.getCaretPosition();
422 - var oldLength = context.fn.getContents().length - ( cursorPos[1] - cursorPos[0] );
423 - context.$content.find( ':not(.wikiEditor)' ).addClass( 'wikiEditor' );
 423+ if ( !context.$content.text() ) {
 424+ context.$content.empty();
 425+ }
 426+ var oldLength = context.fn.getContents().length;
 427+
 428+ context.$content.find( '*' ).addClass( 'wikiEditor' );
424429 if ( $.layout.name !== 'webkit' ) {
425430 context.$content.addClass( 'pasting' );
426431 }
@@ -439,58 +444,82 @@
440445 var outerParent = $(this).parent();
441446 outerParent.replaceWith( outerParent.childNodes );
442447 } );
 448+
443449 // Unwrap the span found in webkit copies (Apple Richtext)
444 - context.$content.find( 'span.Apple-style-span' ).each( function() {
445 - $(this).replaceWith( this.childNodes );
446 - } );
 450+ if ( ! $.browser.msie ) {
 451+ context.$content.find( 'span.Apple-style-span' ).each( function() {
 452+ $(this).replaceWith( this.childNodes );
 453+ } );
 454+ }
447455
448 - // If the pasted content is plain text then wrap it in a <p> and adjust the <br> accordingly
449 - var pasteContent = context.fn.getOffset( cursorPos[0] ).node;
450 - var removeNextBR = false;
451 - while ( pasteContent != null && !$( pasteContent ).hasClass( 'wikiEditor' ) ) {
452 - var currentNode = pasteContent;
453 - pasteContent = pasteContent.nextSibling;
454 - if ( currentNode.nodeName == '#text' && currentNode.nodeValue == currentNode.wholeText ) {
455 - var pWrapper = $( '<p />' ).addClass( 'wikiEditor' );
456 - $( currentNode ).wrap( pWrapper );
457 - $( currentNode ).addClass( 'wikiEditor' );
458 - removeNextBR = true;
459 - } else if ( currentNode.nodeName == 'BR' && removeNextBR ) {
460 - $( currentNode ).remove();
461 - removeNextBR = false;
462 - } else {
463 - removeNextBR = false;
464 - }
465 - }
466456 var $selection = context.$content.find( ':not(.wikiEditor)' );
 457+ var $previousElement;
467458 while ( $selection.length && $selection.length > 0 ) {
468459 var $currentElement = $selection.eq( 0 );
 460+
 461+ //go up till we find the first pasted element
469462 while ( !$currentElement.parent().is( 'body' ) && !$currentElement.parent().is( '.wikiEditor' ) ) {
470463 $currentElement = $currentElement.parent();
471464 }
 465+ //go to the previous element till we find the first pasted element
 466+ while ( $currentElement[0] != null &&
 467+ $currentElement[0].previousSibling != null &&
 468+ !$( $currentElement[0].previousSibling ).hasClass( 'wikiEditor' ) ) {
 469+ $currentElement = $( $currentElement[0].previousSibling );
 470+ }
472471
 472+ //each pasted element is always wrapped in a <p>
473473 var $newElement;
474 - if ( $currentElement.is( 'p' ) || $currentElement.is( 'div' ) || $currentElement.is( 'pre' ) ) {
475 - //Convert all <div>, <p> and <pre> that was pasted into a <p> element
476 - $newElement = $( '<p />' );
 474+ var textNode = false;
 475+ if ( $currentElement[0].nodeName == '#text' ) {
 476+ $newElement = $( '<p></p>' );
 477+ textNode = true;
 478+ } else if ( $currentElement.is( 'p' ) || $currentElement.is( 'pre' ) || $currentElement.is( 'br' ) ) {
 479+ $newElement = $( '<p></p>' );
477480 } else {
478 - // everything else becomes a <span>
479 - $newElement = $( '<span />' ).addClass( 'wikiEditor' );
 481+ $newElement = $( '<span></span>' );
480482 }
 483+ var newElementHTML = '';
 484+ var currentHTML = '';
481485
482 - // If the pasted content was html, just convert it into text and <br>
483 - var pieces = $.trim( $currentElement.text() ).split( '\n' );
484 - var newElementHTML = '';
 486+
 487+ if ( $currentElement[0].nodeName == '#text' ) {
 488+ //if it is a text node then just append it
 489+ currentHTML = $currentElement[0].nodeValue;
 490+ } else {
 491+ currentHTML = $currentElement.html();
 492+ //replace all forms of <p> tags with a \n. All other tags get removed.
 493+ currentHTML = currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)/gi, '\n');
 494+ currentHTML = currentHTML.replace(/(<[^>]*>)|(<[^\>]*\>)/gi, '');
 495+
 496+ }
 497+
 498+ //wrap each piece in a <p> with a <br> in between.
 499+ var pieces = currentHTML.split( '\n' );
485500 for ( var i = 0; i < pieces.length; i++ ) {
486501 if ( pieces[i] ) {
487 - newElementHTML += $.trim( pieces[i] );
488 - } else {
489 - newElementHTML += '<span><br class="wikiEditor" /></span>';
 502+ if ( textNode || ! $newElement.is( 'p' ) ) {
 503+ newElementHTML += '<p class="wikiEditor">' + pieces[i] + '</p>';
 504+ } else {
 505+ newElementHTML += pieces[i];
 506+ }
 507+ } else if ( textNode || ! $newElement.is( 'p' ) ) {
 508+ newElementHTML += '<br class="wikiEditor" >';
490509 }
 510+
 511+ if ( !textNode ) {
 512+ newElementHTML += '<br class="wikiEditor" >';
 513+ }
491514 }
492 - $newElement.html( newElementHTML )
493 - .addClass( 'wikiEditor' )
494 - .insertAfter( $currentElement );
 515+
 516+ $newElement.html( newElementHTML ).addClass( 'wikiEditor' );
 517+
 518+ //remove extra <br>s
 519+ if ( $newElement.is( 'p' ) && $currentElement[0].nextSibling != null && $( $currentElement[0].nextSibling ).is( 'br' ) ) {
 520+ $( $currentElement[0].nextSibling ).remove();
 521+ }
 522+ //swap out the original content with with newly sanitized one
 523+ $newElement.insertAfter( $currentElement );
495524 $currentElement.remove();
496525
497526 $selection = context.$content.find( ':not(.wikiEditor)' );
@@ -501,10 +530,14 @@
502531 context.$content.removeClass( 'pasting' );
503532 }
504533
 534+
505535 // Restore cursor position
506536 context.fn.purgeOffsets();
507537 var newLength = context.fn.getContents().length;
508538 var restoreTo = cursorPos[0] + newLength - oldLength;
 539+ if ( restoreTo > newLength ) {
 540+ restoreTo = newLength;
 541+ }
509542 context.fn.setSelection( { start: restoreTo, end: restoreTo } );
510543 }, 0 );
511544 return true;
@@ -1626,10 +1659,10 @@
16271660 end = e ? e.offset : null;
16281661 // Don't try to set the selection past the end of a node, causes errors
16291662 // Just put the selection at the end of the node in this case
1630 - if ( sc.nodeName == '#text' && start > sc.nodeValue.length ) {
 1663+ if ( sc != null && sc.nodeName == '#text' && start > sc.nodeValue.length ) {
16311664 start = sc.nodeValue.length - 1;
16321665 }
1633 - if ( ec.nodeName == '#text' && end > ec.nodeValue.length ) {
 1666+ if ( ec != null && ec.nodeName == '#text' && end > ec.nodeValue.length ) {
16341667 end = ec.nodeValue.length - 1;
16351668 }
16361669 }

Comments

#Comment by Catrope (talk | contribs)   18:29, 3 June 2010
+					if ( $currentElement[0].nodeName == '#text' ) {

Wouldn't if( textnode ) work here too? What did you introduce that var for otherwise?

+						currentHTML = currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)/gi, '\n');

The brackets around \s in this regex seem redundant. Also, you should be able to merge these three cases into one by using ?, among other things.

+						currentHTML = currentHTML.replace(/(<[^>]*>)|(<[^\>]*\>)/gi, '');

The second case is identical to the first, so it's redundant.

#Comment by Catrope (talk | contribs)   15:58, 9 June 2010

Never mind, all this code was taken out later.

Status & tagging log