Index: /CKEditor/branches/prototype/_source/plugins/fakeobjects/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/fakeobjects/plugin.js (revision 2843)
+++ /CKEditor/branches/prototype/_source/plugins/fakeobjects/plugin.js (revision 2843)
@@ -0,0 +1,173 @@
+/*
+ * CKEditor - The text editor for Internet - http://ckeditor.com
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ */
+
+/**
+ * @fileoverview The "fakeobjects" plugin. It handles placeholder DOM nodes
+ * in WYSIWYG mode.
+ */
+
+(function()
+{
+ CKEDITOR.plugins.add( 'fakeobjects',
+ {
+ init : function( editor, pluginPath )
+ {
+ var flashExtensionRegex = /\.swf($|#|\?)/i,
+ objectTypes =
+ {
+ flash : {
+ match : function( nodeName, attributes )
+ {
+ return nodeName == 'embed' && ( attributes.type == 'application/x-shockwave-flash' || flashExtensionRegex.test( attributes.src || '' ) );
+ },
+
+ cssClass : 'flash'
+ }
+ },
+ makeTagOpenerHtml = function( tagName, attributes )
+ {
+ var attribStr = [], html = [ '<' + tagName ];
+ for ( var i in attributes )
+ attribStr.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '"');
+ if ( attribStr.length > 0 )
+ html.push( ' ', attribStr.join( ' ' ) );
+ html.push( '>' );
+ return html.join( '' );
+ },
+ protectedHtmlRegex = /]+))(?:"[^"]*"|'[^']*'|[^<])*>(?:<\/img>)?/gi,
+ protectHtmlRestore_ReplaceTags = function( htmlTag, s1 )
+ {
+ return decodeURIComponent( s1.substr( 1, s1.length - 2 ) );
+ },
+ namespace =
+ {
+ protectElement : function( element )
+ {
+ var $ = element.$.cloneNode( true ),
+ doc = $.ownerDocument,
+ temp = doc.createElement( 'div' ),
+ html;
+
+ // Get the object's HTML code.
+ temp.appendChild( $ );
+ html = temp.innerHTML;
+
+ // Get the fake element's CSS class.
+ var cssClass = 'unknown';
+ for ( var i in objectTypes )
+ {
+ if ( objectTypes[i].match( element.getName(), element.$ ) )
+ {
+ cssClass = '_cke_fakeobject' + ' ' + objectTypes[i].cssClass;
+ break;
+ }
+ }
+
+ // Make the fake element.
+ var fakeRawElement = doc.createElement( 'img' );
+ img.className = cssClass;
+ img.src = CKEDITOR.getUrl(
+ '_source/' + // TODO: Remove this in release package
+ 'skins/' + editor.config.skin + '/images/spacer.gif' );
+ img.style.cssText = $.style.cssText;
+ return new CKEDITOR.dom.element( fakeRawElement );
+ },
+
+ protectHtml : function( html )
+ {
+ var parser = new CKEDITOR.htmlParser(),
+ tagDepth = 0, processedHtml = [],
+ protectedHtml = [], inProtection = false;
+
+ parser.onTagOpen = function( tagName, attributes )
+ {
+ if ( inProtection )
+ {
+ protectedHtml.push( makeTagOpenerHtml( tagName, attributes ) );
+ return;
+ }
+
+ for ( var i in objectTypes )
+ {
+ if ( objectTypes[i].match( tagName, attributes ) )
+ {
+ inProtection = true;
+ tagDepth = 1;
+ processedHtml.push( '' ) : processedHtml.push( '' );
+ };
+
+ parser.onTagClose = function( tagName )
+ {
+ if ( inProtection )
+ {
+ tagDepth--;
+ protectedHtml.push( '' + tagName + '>' );
+ if ( tagDepth < 1 )
+ {
+ inProtection = false;
+ processedHtml.push( encodeURIComponent( protectedHtml.join( '' ) ), '" />' );
+ }
+ }
+ else
+ processedHtml.push( '' + tagName + '>' );
+ };
+
+ parser.parse( html );
+ return processedHtml.join( '' );
+ },
+
+ restoreHtml : function( html )
+ {
+ return html.replace( protectedHtmlRegex, protectHtmlRestore_ReplaceTags );
+ },
+
+ addObjectType : function( typeName, typeHandler )
+ {
+ objectTypes.typeName = typeHandler;
+ }
+ };
+
+ CKEDITOR.plugins.fakeobjects = namespace;
+ }
+ } );
+})();
Index: /CKEditor/branches/prototype/_source/plugins/find/dialogs/find.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/find/dialogs/find.js (revision 2842)
+++ /CKEditor/branches/prototype/_source/plugins/find/dialogs/find.js (revision 2843)
@@ -23,27 +23,44 @@
findDialog = function( editor, startupPage )
{
- var characterCursor = function( cursorOrTextNode, offset )
+ var characterWalker = function( cursorOrTextNode, offset )
{
if ( arguments.length < 2 )
return;
- var isCursor = ( cursorOrTextNode instanceof characterCursor );
+ var isCursor = ( cursorOrTextNode instanceof characterWalker );
CKEDITOR.tools.extend( this._ || ( this._ = {} ),
{
- 'textNode' : isCursor ? cursorOrTextNode._.textNode : cursorOrTextNode,
- 'offset' : isCursor ? cursorOrTextNode._.offset : offset,
- 'stopFlag' : false
+ textNode : isCursor ? cursorOrTextNode._.textNode : cursorOrTextNode,
+ offset : isCursor ? cursorOrTextNode._.offset : offset,
+ stopFlag : false,
+ actionEvents : null
} );
this._.walker = new CKEDITOR.dom.domWalker( this._.textNode );
CKEDITOR.event.implementOn( this );
- };
-
- CKEDITOR.tools.extend( characterCursor,
- {
+ arguments.callee.domWalkerEventBridge( this );
+ };
+
+ CKEDITOR.tools.extend( characterWalker,
+ {
+ guardDomWalkerNonEmptyTextNode : function( evt )
+ {
+ if ( evt.to && evt.to.type == CKEDITOR.NODE_TEXT && evt.to.$.length > 0 )
+ this.stop();
+ },
+
+ domWalkerEventBridge : function( me )
+ {
+ me._.walker.on( 'up', function( evt ){ me.fire( 'domUp', evt.data, evt.editor ); } );
+ me._.walker.on( 'down', function( evt ){ me.fire( 'domDown', evt.data, evt.editor ); } );
+ me._.walker.on( 'sibling', function( evt ){ me.fire( 'domSibling', evt.data, evt.editor ); } );
+ }
} );
- characterCursor.prototype = {
+ characterWalker.prototype = {
'next' : function()
{
+ // Clear any previous action events.
+ // If there are more characters in the text node, get it and raise an event.
+ // If we are at the end of the text node, use dom walker to get the next text node.
},
Index: /CKEditor/branches/prototype/_source/plugins/wysiwygarea/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/wysiwygarea/plugin.js (revision 2842)
+++ /CKEditor/branches/prototype/_source/plugins/wysiwygarea/plugin.js (revision 2843)
@@ -85,5 +85,5 @@
CKEDITOR.plugins.add( 'wysiwygarea',
{
- requires : [ 'editingblock' ],
+ requires : [ 'editingblock', 'fakeobjects' ],
init : function( editor, pluginPath )
@@ -247,4 +247,7 @@
data = protectUrls( data );
+ // Replace tags with fake elements.
+ data = CKEDITOR.plugins.fakeobjects.protectHtml( data );
+
data =
editor.config.docType +
@@ -297,4 +300,7 @@
data = protectUrlsRestore( data );
+ // Restore fake elements.
+ data = CKEDITOR.plugins.fakeobjects.restoreHtml( data );
+
return data;
},