editor-base.js revision feeca215b500b5ee5872ac047835500b4828f38c
4f15171c562757e8d3e2b8882e04d6b5a2291732Matt Sweeney * Base class for Editor. Handles the business logic of Editor, no GUI involved only utility methods and events.
4f15171c562757e8d3e2b8882e04d6b5a2291732Matt Sweeney * @module editor
8d1240fc6300f6769711557511f6882f0a3d3139Matt Sweeney * @submodule editor-base
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * Base class for Editor. Handles the business logic of Editor, no GUI involved only utility methods and events.
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @class EditorBase
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @for EditorBase
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @extends Base
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @constructor
7bd6c48178788dd4f19fa028e0294192ee2c7278Matt Sweeney var EditorBase = function() {
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney EditorBase.superclass.constructor.apply(this, arguments);
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * Internal reference to the Y.Frame instance
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @property frame
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney frame.after('ready', Y.bind(this._afterFrameReady, this));
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * Copy certain styles from one node instance to another (used for new paragraph creation mainly)
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @method copyStyles
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @param {Node} from The Node instance to copy the styles from
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @param {Node} to The Node instance to copy the styles to
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney //Don't carry the A styles
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney var styles = ['color', 'fontSize', 'fontFamily', 'backgroundColor', 'fontStyle' ],
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * Holder for the selection bookmark in IE.
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @property _lastBookmark
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * The default handler for the nodeChange event.
6244b09179e0efbecc704ba75b5323ee0f5b38d3Matt Sweeney * @method _defNodeChangeFn
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * @param {Event} e The event
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney //Y.log('Default nodeChange function: ' + e.changedType, 'info', 'editor');
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * This whole method needs to be fixed and made more dynamic.
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * Maybe static functions for the e.changeType and an object bag
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney * to walk through and filter to pass off the event to before firing..
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney case 'keydown':
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney case 'enter':
d59c625bc91380e7d3458db5e7e9a581d670684aMatt Sweeney //Webkit doesn't support shift+enter as a BR, this fixes that.
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney if (!e.changedNode.test('li, li *') && !e.changedEvent.shiftKey) {
8906dd44d6aa2a5092388e0c2e80d8dc9aae397cMatt Sweeney Y.log('Overriding TAB key to insert HTML: HALTING', 'info', 'editor');
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney case 'enter-up':
1e4299e83b45ff5cf2fc6b545f0186ecf831ec87Matt Sweeney var para = ((this._lastPara) ? this._lastPara : e.changedNode),
if (para2) {
para2 = null;
if (prev) {
while (!found) {
if (lc) {
if (lc2) {
found = true;
found = true;
if (lc) {
this._lastPara = p;
if (e.commands) {
if (cmd) {
if (family2) {
if (family) {
if (!e.fontFamily) {
if (!e.fontSize) {
if (!e.fontColor) {
if (!e.backgroundColor) {
while (domNode !== null) {
if ((domNode === inst.config.doc.documentElement) || (domNode === inst.config.doc) || !domNode.tagName) {
domNode = null;
domNode = null;
domNode = null;
if (nodeList) {
_afterFrameReady: function() {
_onFrameActivate: function() {
if (this._lastBookmark) {
this._lastBookmark = null;
_onFrameMouseUp: function(e) {
this.fire('nodeChange', { changedNode: e.frameTarget, changedType: 'mouseup', changedEvent: e.frameEvent });
_onFrameMouseDown: function(e) {
this.fire('nodeChange', { changedNode: e.frameTarget, changedType: 'mousedown', changedEvent: e.frameEvent });
_currentSelection: null,
_currentSelectionTimer: null,
_currentSelectionClear: null,
_onFrameKeyDown: function(e) {
if (!this._currentSelection) {
if (this._currentSelectionTimer) {
this._currentSelectionClear = true;
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: 'keydown', changedEvent: e.frameEvent });
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: EditorBase.NC_KEYS[e.keyCode], changedEvent: e.frameEvent });
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: EditorBase.NC_KEYS[e.keyCode] + '-down', changedEvent: e.frameEvent });
_onFrameKeyPress: function(e) {
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: 'keypress', changedEvent: e.frameEvent });
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: EditorBase.NC_KEYS[e.keyCode] + '-press', changedEvent: e.frameEvent });
_onFrameKeyUp: function(e) {
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: 'keyup', selection: sel, changedEvent: e.frameEvent });
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: EditorBase.NC_KEYS[e.keyCode] + '-up', selection: sel, changedEvent: e.frameEvent });
if (this._currentSelectionClear) {
* @return {Node/NodeList} The Node or Nodelist affected by the command. Only returns on override commands, not browser defined commands.
switch (cmd) {
return ret;
getInstance: function() {
* @param {Selector/HTMLElement/Node} node The node to append the Editor to
show: function() {
hide: function() {
getContent: function() {
return html;
* @description Converts an RGB color string to a hex color, example: rgb(0, 255, 0) converts to #00ff00
var exp = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
return css;
TAG2CMD: {
NC_KEYS: {
STRINGS: {
ATTRS: {
content: {
getter: function() {
dir: {
writeOnce: true,
linkedcss: {
value: false,
if (this.frame) {
return css;
extracss: {
value: false,
if (this.frame) {
return css;
* <dt>changedType</dt><dd>The type of change: mousedown, mouseup, right, left, backspace, tab, enter, etc..</dd>
* <dt>commands</dt><dd>The list of execCommands that belong to this change and the dompath that's associated with the changedNode</dd>
* <dt>classNames</dt><dd>An array of classNames that are applied to the changedNode and all of it's parents</dd>