web/wp-includes/js/tinymce/plugins/wpview/editor_plugin_src.js
changeset 204 09a1c134465b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/wp-includes/js/tinymce/plugins/wpview/editor_plugin_src.js	Wed Dec 19 17:46:52 2012 -0800
@@ -0,0 +1,188 @@
+/**
+ * WordPress View plugin.
+ */
+
+(function() {
+	var VK = tinymce.VK,
+		TreeWalker = tinymce.dom.TreeWalker,
+		selected;
+
+	tinymce.create('tinymce.plugins.wpView', {
+		init : function( editor, url ) {
+			var wpView = this;
+
+			// Check if the `wp.mce` API exists.
+			if ( typeof wp === 'undefined' || ! wp.mce )
+				return;
+
+			editor.onPreInit.add( function( editor ) {
+				// Add elements so we can set `contenteditable` to false.
+				editor.schema.addValidElements('div[*],span[*]');
+			});
+
+			// When the editor's content changes, scan the new content for
+			// matching view patterns, and transform the matches into
+			// view wrappers. Since the editor's DOM is outdated at this point,
+			// we'll wait to render the views.
+			editor.onBeforeSetContent.add( function( editor, o ) {
+				if ( ! o.content )
+					return;
+
+				o.content = wp.mce.view.toViews( o.content );
+			});
+
+			// When the editor's content has been updated and the DOM has been
+			// processed, render the views in the document.
+			editor.onSetContent.add( function( editor, o ) {
+				wp.mce.view.render( editor.getDoc() );
+			});
+
+			editor.onInit.add( function( editor ) {
+
+				// When a view is selected, ensure content that is being pasted
+				// or inserted is added to a text node (instead of the view).
+				editor.selection.onBeforeSetContent.add( function( selection, o ) {
+					var view = wpView.getParentView( selection.getNode() ),
+						walker, target;
+
+					// If the selection is not within a view, bail.
+					if ( ! view )
+						return;
+
+					// If there are no additional nodes or the next node is a
+					// view, create a text node after the current view.
+					if ( ! view.nextSibling || wpView.isView( view.nextSibling ) ) {
+						target = editor.getDoc().createTextNode('');
+						editor.dom.insertAfter( target, view );
+
+					// Otherwise, find the next text node.
+					} else {
+						walker = new TreeWalker( view.nextSibling, view.nextSibling );
+						target = walker.next();
+					}
+
+					// Select the `target` text node.
+					selection.select( target );
+					selection.collapse( true );
+				});
+
+				// When the selection's content changes, scan any new content
+				// for matching views and immediately render them.
+				//
+				// Runs on paste and on inserting nodes/html.
+				editor.selection.onSetContent.add( function( selection, o ) {
+					if ( ! o.context )
+						return;
+
+					var node = selection.getNode();
+
+					if ( ! node.innerHTML )
+						return;
+
+					node.innerHTML = wp.mce.view.toViews( node.innerHTML );
+					wp.mce.view.render( node );
+				});
+			});
+
+			// When the editor's contents are being accessed as a string,
+			// transform any views back to their text representations.
+			editor.onPostProcess.add( function( editor, o ) {
+				if ( ( ! o.get && ! o.save ) || ! o.content )
+					return;
+
+				o.content = wp.mce.view.toText( o.content );
+			});
+
+			// Triggers when the selection is changed.
+			// Add the event handler to the top of the stack.
+			editor.onNodeChange.addToTop( function( editor, controlManager, node, collapsed, o ) {
+				var view = wpView.getParentView( node );
+
+				// Update the selected view.
+				if ( view ) {
+					wpView.select( view );
+
+					// Prevent the selection from propagating to other plugins.
+					return false;
+
+				// If we've clicked off of the selected view, deselect it.
+				} else {
+					wpView.deselect();
+				}
+			});
+
+			editor.onKeyDown.addToTop( function( editor, event ) {
+				var keyCode = event.keyCode,
+					view, instance;
+
+				// If a view isn't selected, let the event go on its merry way.
+				if ( ! selected )
+					return;
+
+				// If the caret is not within the selected view, deselect the
+				// view and bail.
+				view = wpView.getParentView( editor.selection.getNode() );
+				if ( view !== selected ) {
+					wpView.deselect();
+					return;
+				}
+
+				// If delete or backspace is pressed, delete the view.
+				if ( keyCode === VK.DELETE || keyCode === VK.BACKSPACE ) {
+					if ( (instance = wp.mce.view.instance( selected )) ) {
+						instance.remove();
+						wpView.deselect();
+					}
+				}
+
+				// Let keypresses that involve the command or control keys through.
+				// Also, let any of the F# keys through.
+				if ( event.metaKey || event.ctrlKey || ( keyCode >= 112 && keyCode <= 123 ) )
+					return;
+
+				event.preventDefault();
+			});
+		},
+
+		getParentView : function( node ) {
+			while ( node ) {
+				if ( this.isView( node ) )
+					return node;
+
+				node = node.parentNode;
+			}
+		},
+
+		isView : function( node ) {
+			return (/(?:^|\s)wp-view-wrap(?:\s|$)/).test( node.className );
+		},
+
+		select : function( view ) {
+			if ( view === selected )
+				return;
+
+			this.deselect();
+			selected = view;
+			wp.mce.view.select( selected );
+		},
+
+		deselect : function() {
+			if ( selected )
+				wp.mce.view.deselect( selected );
+			selected = null;
+		},
+
+		getInfo : function() {
+			return {
+				longname  : 'WordPress Views',
+				author    : 'WordPress',
+				authorurl : 'http://wordpress.org',
+				infourl   : 'http://wordpress.org',
+				version   : '1.0'
+			};
+		}
+	});
+
+	// Register plugin
+	tinymce.PluginManager.add( 'wpview', tinymce.plugins.wpView );
+})();
\ No newline at end of file