Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php |
— | — | @@ -74,7 +74,7 @@ |
75 | 75 | array( 'src' => 'js/plugins/jquery.expandableField.js', 'version' => 15 ), |
76 | 76 | array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 19 ), |
77 | 77 | array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 33 ), |
78 | | - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 187 ), |
| 78 | + array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 188 ), |
79 | 79 | array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 53 ), |
80 | 80 | array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 62 ), |
81 | 81 | array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 24 ), |
— | — | @@ -85,10 +85,10 @@ |
86 | 86 | array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 5 ), |
87 | 87 | ), |
88 | 88 | 'combined' => array( |
89 | | - array( 'src' => 'js/plugins.combined.js', 'version' => 403 ), |
| 89 | + array( 'src' => 'js/plugins.combined.js', 'version' => 404 ), |
90 | 90 | ), |
91 | 91 | 'minified' => array( |
92 | | - array( 'src' => 'js/plugins.combined.min.js', 'version' => 403 ), |
| 92 | + array( 'src' => 'js/plugins.combined.min.js', 'version' => 404 ), |
93 | 93 | ), |
94 | 94 | ), |
95 | 95 | ); |
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js |
— | — | @@ -397,7 +397,7 @@ |
398 | 398 | // Surround by <p> if it does not already have it |
399 | 399 | var cursorPos = context.fn.getCaretPosition(); |
400 | 400 | var t = context.fn.getOffset( cursorPos[0] ); |
401 | | - if ( t && t.node.nodeName == '#text' && t.node.parentNode.nodeName.toLowerCase() == 'body' ) { |
| 401 | + if ( ! $.browser.msie && t && t.node.nodeName == '#text' && t.node.parentNode.nodeName.toLowerCase() == 'body' ) { |
402 | 402 | $( t.node ).wrap( "<p></p>" ); |
403 | 403 | context.fn.purgeOffsets(); |
404 | 404 | context.fn.setSelection( { start: cursorPos[0], end: cursorPos[1] } ); |
— | — | @@ -453,10 +453,11 @@ |
454 | 454 | } |
455 | 455 | |
456 | 456 | var $selection = context.$content.find( ':not(.wikiEditor)' ); |
457 | | - var $previousElement; |
| 457 | + var newElementHTML = '' ; |
| 458 | + var $markElement = null; |
458 | 459 | while ( $selection.length && $selection.length > 0 ) { |
459 | 460 | var $currentElement = $selection.eq( 0 ); |
460 | | - |
| 461 | + |
461 | 462 | //go up till we find the first pasted element |
462 | 463 | while ( !$currentElement.parent().is( 'body' ) && !$currentElement.parent().is( '.wikiEditor' ) ) { |
463 | 464 | $currentElement = $currentElement.parent(); |
— | — | @@ -468,63 +469,50 @@ |
469 | 470 | $currentElement = $( $currentElement[0].previousSibling ); |
470 | 471 | } |
471 | 472 | |
472 | | - //each pasted element is always wrapped in a <p> |
473 | | - var $newElement; |
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>' ); |
480 | | - } else { |
481 | | - $newElement = $( '<span></span>' ); |
482 | | - } |
483 | | - var newElementHTML = ''; |
| 473 | + // we're going to collect and sanitize all the pasted content and then insert it at $markElement |
484 | 474 | var currentHTML = ''; |
485 | | - |
486 | | - |
487 | | - if ( $currentElement[0].nodeName == '#text' ) { |
| 475 | + if ( $currentElement[0].nodeName == '#text' ) { |
488 | 476 | //if it is a text node then just append it |
489 | 477 | currentHTML = $currentElement[0].nodeValue; |
490 | 478 | } else { |
491 | 479 | currentHTML = $currentElement.html(); |
| 480 | + // First remove all new lines |
| 481 | + currentHTML = currentHTML.replace( /\r?\n/g, ''); |
492 | 482 | //replace all forms of <p> tags with a \n. All other tags get removed. |
493 | 483 | currentHTML = currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)/gi, '\n'); |
| 484 | + // Replace all forms of html tags that should end up in their own <p> |
| 485 | + currentHTML = currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)|(<[\s]*h[\d][^>]*>)|(<[\s]*h[\d][^\/>]*\/>)/gi, '\n'); |
494 | 486 | currentHTML = currentHTML.replace(/(<[^>]*>)|(<[^\>]*\>)/gi, ''); |
495 | | - |
| 487 | + currentHTML += '\n'; |
496 | 488 | } |
| 489 | + newElementHTML += currentHTML; |
497 | 490 | |
498 | | - //wrap each piece in a <p> with a <br> in between. |
499 | | - var pieces = currentHTML.split( '\n' ); |
500 | | - for ( var i = 0; i < pieces.length; i++ ) { |
501 | | - if ( pieces[i] ) { |
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" >'; |
509 | | - } |
510 | | - |
511 | | - if ( !textNode ) { |
512 | | - newElementHTML += '<br class="wikiEditor" >'; |
513 | | - } |
| 491 | + if ( $markElement == null ) { |
| 492 | + $markElement = $( '<div></div>' ).addClass( 'wikiEditor' ).insertAfter( $currentElement ); |
| 493 | + } |
| 494 | + $currentElement.remove(); |
| 495 | + $selection = context.$content.find( ':not(.wikiEditor)' ); |
| 496 | + } |
| 497 | + |
| 498 | + //now put a <p> around each line of pasted content |
| 499 | + var pieces = newElementHTML.split( '\n' ); |
| 500 | + var $newElement; |
| 501 | + for ( var i = 0; i < pieces.length; i++ ) { |
| 502 | + $newElement = $( '<p></p>' ); |
| 503 | + if ( pieces[i] ) { |
| 504 | + $newElement.text( pieces[i] ); |
| 505 | + } else { |
| 506 | + $newElement.html( '<br>' ); |
514 | 507 | } |
515 | | - |
516 | | - $newElement.html( newElementHTML ).addClass( 'wikiEditor' ); |
517 | 508 | |
518 | | - //remove extra <br>s |
519 | | - if ( $newElement.is( 'p' ) && $currentElement[0].nextSibling != null && $( $currentElement[0].nextSibling ).is( 'br' ) ) { |
520 | | - $( $currentElement[0].nextSibling ).remove(); |
| 509 | + $newElement.insertAfter( $markElement ); |
| 510 | + if (i == 0 ) { |
| 511 | + $markElement.remove(); |
521 | 512 | } |
522 | | - //swap out the original content with with newly sanitized one |
523 | | - $newElement.insertAfter( $currentElement ); |
524 | | - $currentElement.remove(); |
525 | | - |
526 | | - $selection = context.$content.find( ':not(.wikiEditor)' ); |
| 513 | + $markElement = $newElement; |
527 | 514 | } |
528 | 515 | |
| 516 | + |
529 | 517 | context.$content.find( '.wikiEditor' ).removeClass( 'wikiEditor' ); |
530 | 518 | if ( $.layout.name !== 'webkit' ) { |
531 | 519 | context.$content.removeClass( 'pasting' ); |
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js |
— | — | @@ -7069,7 +7069,7 @@ |
7070 | 7070 | // Surround by <p> if it does not already have it |
7071 | 7071 | var cursorPos = context.fn.getCaretPosition(); |
7072 | 7072 | var t = context.fn.getOffset( cursorPos[0] ); |
7073 | | - if ( t && t.node.nodeName == '#text' && t.node.parentNode.nodeName.toLowerCase() == 'body' ) { |
| 7073 | + if ( ! $.browser.msie && t && t.node.nodeName == '#text' && t.node.parentNode.nodeName.toLowerCase() == 'body' ) { |
7074 | 7074 | $( t.node ).wrap( "<p></p>" ); |
7075 | 7075 | context.fn.purgeOffsets(); |
7076 | 7076 | context.fn.setSelection( { start: cursorPos[0], end: cursorPos[1] } ); |
— | — | @@ -7125,10 +7125,11 @@ |
7126 | 7126 | } |
7127 | 7127 | |
7128 | 7128 | var $selection = context.$content.find( ':not(.wikiEditor)' ); |
7129 | | - var $previousElement; |
| 7129 | + var newElementHTML = '' ; |
| 7130 | + var $markElement = null; |
7130 | 7131 | while ( $selection.length && $selection.length > 0 ) { |
7131 | 7132 | var $currentElement = $selection.eq( 0 ); |
7132 | | - |
| 7133 | + |
7133 | 7134 | //go up till we find the first pasted element |
7134 | 7135 | while ( !$currentElement.parent().is( 'body' ) && !$currentElement.parent().is( '.wikiEditor' ) ) { |
7135 | 7136 | $currentElement = $currentElement.parent(); |
— | — | @@ -7140,63 +7141,50 @@ |
7141 | 7142 | $currentElement = $( $currentElement[0].previousSibling ); |
7142 | 7143 | } |
7143 | 7144 | |
7144 | | - //each pasted element is always wrapped in a <p> |
7145 | | - var $newElement; |
7146 | | - var textNode = false; |
7147 | | - if ( $currentElement[0].nodeName == '#text' ) { |
7148 | | - $newElement = $( '<p></p>' ); |
7149 | | - textNode = true; |
7150 | | - } else if ( $currentElement.is( 'p' ) || $currentElement.is( 'pre' ) || $currentElement.is( 'br' ) ) { |
7151 | | - $newElement = $( '<p></p>' ); |
7152 | | - } else { |
7153 | | - $newElement = $( '<span></span>' ); |
7154 | | - } |
7155 | | - var newElementHTML = ''; |
| 7145 | + // we're going to collect and sanitize all the pasted content and then insert it at $markElement |
7156 | 7146 | var currentHTML = ''; |
7157 | | - |
7158 | | - |
7159 | | - if ( $currentElement[0].nodeName == '#text' ) { |
| 7147 | + if ( $currentElement[0].nodeName == '#text' ) { |
7160 | 7148 | //if it is a text node then just append it |
7161 | 7149 | currentHTML = $currentElement[0].nodeValue; |
7162 | 7150 | } else { |
7163 | 7151 | currentHTML = $currentElement.html(); |
| 7152 | + // First remove all new lines |
| 7153 | + currentHTML = currentHTML.replace( /\r?\n/g, ''); |
7164 | 7154 | //replace all forms of <p> tags with a \n. All other tags get removed. |
7165 | 7155 | currentHTML = currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)/gi, '\n'); |
| 7156 | + // Replace all forms of html tags that should end up in their own <p> |
| 7157 | + currentHTML = currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)|(<[\s]*h[\d][^>]*>)|(<[\s]*h[\d][^\/>]*\/>)/gi, '\n'); |
7166 | 7158 | currentHTML = currentHTML.replace(/(<[^>]*>)|(<[^\>]*\>)/gi, ''); |
7167 | | - |
| 7159 | + currentHTML += '\n'; |
7168 | 7160 | } |
| 7161 | + newElementHTML += currentHTML; |
7169 | 7162 | |
7170 | | - //wrap each piece in a <p> with a <br> in between. |
7171 | | - var pieces = currentHTML.split( '\n' ); |
7172 | | - for ( var i = 0; i < pieces.length; i++ ) { |
7173 | | - if ( pieces[i] ) { |
7174 | | - if ( textNode || ! $newElement.is( 'p' ) ) { |
7175 | | - newElementHTML += '<p class="wikiEditor">' + pieces[i] + '</p>'; |
7176 | | - } else { |
7177 | | - newElementHTML += pieces[i]; |
7178 | | - } |
7179 | | - } else if ( textNode || ! $newElement.is( 'p' ) ) { |
7180 | | - newElementHTML += '<br class="wikiEditor" >'; |
7181 | | - } |
7182 | | - |
7183 | | - if ( !textNode ) { |
7184 | | - newElementHTML += '<br class="wikiEditor" >'; |
7185 | | - } |
| 7163 | + if ( $markElement == null ) { |
| 7164 | + $markElement = $( '<div></div>' ).addClass( 'wikiEditor' ).insertAfter( $currentElement ); |
| 7165 | + } |
| 7166 | + $currentElement.remove(); |
| 7167 | + $selection = context.$content.find( ':not(.wikiEditor)' ); |
| 7168 | + } |
| 7169 | + |
| 7170 | + //now put a <p> around each line of pasted content |
| 7171 | + var pieces = newElementHTML.split( '\n' ); |
| 7172 | + var $newElement; |
| 7173 | + for ( var i = 0; i < pieces.length; i++ ) { |
| 7174 | + $newElement = $( '<p></p>' ); |
| 7175 | + if ( pieces[i] ) { |
| 7176 | + $newElement.text( pieces[i] ); |
| 7177 | + } else { |
| 7178 | + $newElement.html( '<br>' ); |
7186 | 7179 | } |
7187 | | - |
7188 | | - $newElement.html( newElementHTML ).addClass( 'wikiEditor' ); |
7189 | 7180 | |
7190 | | - //remove extra <br>s |
7191 | | - if ( $newElement.is( 'p' ) && $currentElement[0].nextSibling != null && $( $currentElement[0].nextSibling ).is( 'br' ) ) { |
7192 | | - $( $currentElement[0].nextSibling ).remove(); |
| 7181 | + $newElement.insertAfter( $markElement ); |
| 7182 | + if (i == 0 ) { |
| 7183 | + $markElement.remove(); |
7193 | 7184 | } |
7194 | | - //swap out the original content with with newly sanitized one |
7195 | | - $newElement.insertAfter( $currentElement ); |
7196 | | - $currentElement.remove(); |
7197 | | - |
7198 | | - $selection = context.$content.find( ':not(.wikiEditor)' ); |
| 7185 | + $markElement = $newElement; |
7199 | 7186 | } |
7200 | 7187 | |
| 7188 | + |
7201 | 7189 | context.$content.find( '.wikiEditor' ).removeClass( 'wikiEditor' ); |
7202 | 7190 | if ( $.layout.name !== 'webkit' ) { |
7203 | 7191 | context.$content.removeClass( 'pasting' ); |
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js |
— | — | @@ -475,18 +475,18 @@ |
476 | 476 | break;} |
477 | 477 | return true;},'change':function(event){event.data.scope='division';var newHTML=context.$content.html();if(context.oldHTML!=newHTML){context.fn.purgeOffsets();context.oldHTML=newHTML;event.data.scope='realchange';} |
478 | 478 | if(context.$content.children().length==0){context.$content.append('<p></p>');} |
479 | | -return true;},'delayedChange':function(event){event.data.scope='division';var newHTML=context.$content.html();if(context.oldDelayedHTML!=newHTML){context.oldDelayedHTML=newHTML;event.data.scope='realchange';var cursorPos=context.fn.getCaretPosition();var t=context.fn.getOffset(cursorPos[0]);if(t&&t.node.nodeName=='#text'&&t.node.parentNode.nodeName.toLowerCase()=='body'){$(t.node).wrap("<p></p>");context.fn.purgeOffsets();context.fn.setSelection({start:cursorPos[0],end:cursorPos[1]});}} |
| 479 | +return true;},'delayedChange':function(event){event.data.scope='division';var newHTML=context.$content.html();if(context.oldDelayedHTML!=newHTML){context.oldDelayedHTML=newHTML;event.data.scope='realchange';var cursorPos=context.fn.getCaretPosition();var t=context.fn.getOffset(cursorPos[0]);if(!$.browser.msie&&t&&t.node.nodeName=='#text'&&t.node.parentNode.nodeName.toLowerCase()=='body'){$(t.node).wrap("<p></p>");context.fn.purgeOffsets();context.fn.setSelection({start:cursorPos[0],end:cursorPos[1]});}} |
480 | 480 | context.fn.updateHistory(event.data.scope=='realchange');return true;},'cut':function(event){setTimeout(function(){context.$content.find('br').each(function(){if($(this).parent().is('body')){$(this).wrap($('<p></p>'));}});},100);return true;},'paste':function(event){var cursorPos=context.fn.getCaretPosition();if(!context.$content.text()){context.$content.empty();} |
481 | 481 | var oldLength=context.fn.getContents().length;context.$content.find('*').addClass('wikiEditor');if($.layout.name!=='webkit'){context.$content.addClass('pasting');} |
482 | 482 | setTimeout(function(){context.$content.find('script,style,img,input,select,textarea,hr,button,link,meta').remove();context.$content.find('*').each(function(){if($(this).children().length==0&&this.childNodes.length>0){$(this).text($(this).text());}});context.$content.find('p:not(.wikiEditor) p:not(.wikiEditor)').each(function(){var outerParent=$(this).parent();outerParent.replaceWith(outerParent.childNodes);});if(!$.browser.msie){context.$content.find('span.Apple-style-span').each(function(){$(this).replaceWith(this.childNodes);});} |
483 | | -var $selection=context.$content.find(':not(.wikiEditor)');var $previousElement;while($selection.length&&$selection.length>0){var $currentElement=$selection.eq(0);while(!$currentElement.parent().is('body')&&!$currentElement.parent().is('.wikiEditor')){$currentElement=$currentElement.parent();} |
| 483 | +var $selection=context.$content.find(':not(.wikiEditor)');var newElementHTML='';var $markElement=null;while($selection.length&&$selection.length>0){var $currentElement=$selection.eq(0);while(!$currentElement.parent().is('body')&&!$currentElement.parent().is('.wikiEditor')){$currentElement=$currentElement.parent();} |
484 | 484 | while($currentElement[0]!=null&&$currentElement[0].previousSibling!=null&&!$($currentElement[0].previousSibling).hasClass('wikiEditor')){$currentElement=$($currentElement[0].previousSibling);} |
485 | | -var $newElement;var textNode=false;if($currentElement[0].nodeName=='#text'){$newElement=$('<p></p>');textNode=true;}else if($currentElement.is('p')||$currentElement.is('pre')||$currentElement.is('br')){$newElement=$('<p></p>');}else{$newElement=$('<span></span>');} |
486 | | -var newElementHTML='';var currentHTML='';if($currentElement[0].nodeName=='#text'){currentHTML=$currentElement[0].nodeValue;}else{currentHTML=$currentElement.html();currentHTML=currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)/gi,'\n');currentHTML=currentHTML.replace(/(<[^>]*>)|(<[^\>]*\>)/gi,'');} |
487 | | -var pieces=currentHTML.split('\n');for(var i=0;i<pieces.length;i++){if(pieces[i]){if(textNode||!$newElement.is('p')){newElementHTML+='<p class="wikiEditor">'+pieces[i]+'</p>';}else{newElementHTML+=pieces[i];}}else if(textNode||!$newElement.is('p')){newElementHTML+='<br class="wikiEditor" >';} |
488 | | -if(!textNode){newElementHTML+='<br class="wikiEditor" >';}} |
489 | | -$newElement.html(newElementHTML).addClass('wikiEditor');if($newElement.is('p')&&$currentElement[0].nextSibling!=null&&$($currentElement[0].nextSibling).is('br')){$($currentElement[0].nextSibling).remove();} |
490 | | -$newElement.insertAfter($currentElement);$currentElement.remove();$selection=context.$content.find(':not(.wikiEditor)');} |
| 485 | +var currentHTML='';if($currentElement[0].nodeName=='#text'){currentHTML=$currentElement[0].nodeValue;}else{currentHTML=$currentElement.html();currentHTML=currentHTML.replace(/\r?\n/g,'');currentHTML=currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)/gi,'\n');currentHTML=currentHTML.replace(/(<[\s]*p[^>]*>)|(<[\s]*\/p[^>]*>)|(<[\s]*p[^\/>]*\/>)|(<[\s]*h[\d][^>]*>)|(<[\s]*h[\d][^\/>]*\/>)/gi,'\n');currentHTML=currentHTML.replace(/(<[^>]*>)|(<[^\>]*\>)/gi,'');currentHTML+='\n';} |
| 486 | +newElementHTML+=currentHTML;if($markElement==null){$markElement=$('<div></div>').addClass('wikiEditor').insertAfter($currentElement);} |
| 487 | +$currentElement.remove();$selection=context.$content.find(':not(.wikiEditor)');} |
| 488 | +var pieces=newElementHTML.split('\n');var $newElement;for(var i=0;i<pieces.length;i++){$newElement=$('<p></p>');if(pieces[i]){$newElement.text(pieces[i]);}else{$newElement.html('<br>');} |
| 489 | +$newElement.insertAfter($markElement);if(i==0){$markElement.remove();} |
| 490 | +$markElement=$newElement;} |
491 | 491 | context.$content.find('.wikiEditor').removeClass('wikiEditor');if($.layout.name!=='webkit'){context.$content.removeClass('pasting');} |
492 | 492 | context.fn.purgeOffsets();var newLength=context.fn.getContents().length;var restoreTo=cursorPos[0]+newLength-oldLength;if(restoreTo>newLength){restoreTo=newLength;} |
493 | 493 | context.fn.setSelection({start:restoreTo,end:restoreTo});},0);return true;},'ready':function(event){context.history.push({'html':context.$content.html(),'sel':context.fn.getCaretPosition()});return true;}};context.fn={'trigger':function(name,event){if(typeof event=='undefined'){event={'type':'custom'};} |