editor-debug.js revision 56fa0b5ce00608c58c7c82cc5341c5fbf8898719
/**
* Creates a wrapper around an iframe. It loads the content either from a local
* file or from script and creates a local YUI instance bound to that new window and document.
* @module editor
* @submodule frame
*/
/**
* Creates a wrapper around an iframe. It loads the content either from a local
* file or from script and creates a local YUI instance bound to that new window and document.
* @class Frame
* @extends Base
* @constructor
*/
var Frame = function() {
};
/**
* @private
* @property _ready
* @description Internal reference set when the content is ready.
* @type Boolean
*/
_ready: null,
/**
* @private
* @property _rendered
* @description Internal reference set when render is called.
* @type Boolean
*/
_rendered: null,
/**
* @private
* @property _iframe
* @description Internal Node reference to the iFrame or the window
* @type Node
*/
_iframe: null,
/**
* @private
* @property _instance
* @description Internal reference to the YUI instance bound to the iFrame or window
* @type YUI
*/
_instance: null,
/**
* @private
* @method _create
* @description Create the iframe or Window and get references to the Document & Window
* @return {Object} Hash table containing references to the new Document & Window
*/
_create: function() {
res = this._resolveWinDoc();
return {
};
},
/**
* @private
* @method _resolveWinDoc
* @description Resolves the document and window from an iframe or window instance
* @param {Object} c The YUI Config to add the window and document to
* @return {Object} Object hash of window and document references, if a YUI config was passed, it is returned.
*/
_resolveWinDoc: function(c) {
var config = (c) ? c : {};
return config;
},
/**
* @private
* @method _onDomEvent
* @description Generic handler for all DOM events fired by the iframe or window. This handler
* takes the current EventFacade and augments it to fire on the Frame host. It adds two new properties
* to the EventFacade called frameX and frameY which adds the scroll and xy position of the iframe
* to the original pageX and pageY of the event so external nodes can be positioned over the frame.
* @param {Event.Facade} e
*/
_onDomEvent: function(e) {
//Y.log('onDOMEvent: ' + e.type, 'info', 'frame');
e.frameTarget = e.target;
e.frameCurrentTarget = e.currentTarget;
e.frameEvent = e;
//TODO: Not sure why this stopped working!!!
emitFacade: true,
}, this, e),
ev.preventDefault();
}, this, e)
});
},
initializer: function() {
this.publish('ready', {
emitFacade: true,
defaultFn: this._defReadyFn
});
},
/**
* @private
* @method _defReadyFn
* @description Binds DOM events, sets the iframe to visible and fires the ready event
*/
_defReadyFn: function() {
var inst = this.getInstance(),
if (v === 1) {
}
});
},
/**
* @method use
* @description This is a scoped version of the normal YUI.use method & is bound to this frame/window.
* At setup, the inst.use method is mapped to this method.
*/
use: function() {
var inst = this.getInstance(),
cb = false;
}
if (cb) {
});
}
},
/**
* @private
* @method _onContentReady
* @description Called once the content is available in the frame/window and calls the final use call
* on the internal instance so that the modules are loaded properly.
*/
_onContentReady: function(e) {
if (!this._ready) {
this._ready = true;
var inst = this.getInstance(),
this.fire('contentready');
if (e) {
}
//TODO Circle around and deal with CSS loading...
this.fire('ready');
}, this));
}
},
/**
* @private
* @method _instanceLoaded
* @description Called from the first YUI instance that sets up the internal instance.
*/
_instanceLoaded: function(inst) {
var html = '',
extra_css = ((this.get('extracss')) ? '<style id="extra_css">' + this.get('extracss') + '</style>' : ''),
});
} else {
}
if (this.get('designMode')) {
try {
//Force other browsers into non CSS styling
} catch (e) {}
}
}
},
/**
* @method delegate
* @description A delegate method passed to the instance's delegate method
* @param {String} type The type of event to listen for
* @param {Function} fn The method to attach
* @param {String} cont The container to act as a delegate, if no "sel" passed, the body is assumed as the container.
* @param {String} sel The selector to match in the event (optional)
* @return {EventHandle} The Event handle returned from Y.delegate
*/
var inst = this.getInstance();
if (!inst) {
Y.log('Delegate events can not be attached until after the ready event has fired.', 'error', 'iframe');
return false;
}
if (!sel) {
cont = 'body';
}
},
/**
* @method getInstance
* @description Get a reference to the internal YUI instance.
* @return {YUI} The internal YUI instance
*/
getInstance: function() {
return this._instance;
},
/**
* @method render
* @description Render the iframe into the container config option or open the window.
* @param {String/HTMLElement/Node} node The node to render to
* @return {Y.Frame}
* @chainable
*/
if (this._rendered) {
return this;
}
this._rendered = true;
if (node) {
}
var inst,
this._instanceLoaded(i);
}, this),
config = {
debug: false,
bootstrap: false,
},
}, this);
return this;
},
/**
* @private
* @method _resolveBaseHref
* @description Resolves the basehref of the page the frame is created on. Only applies to dynamic content.
* @param {String} href The new value to use, if empty it will be resolved from the current url.
* @return {String}
*/
_resolveBaseHref: function(href) {
}
}
return href;
},
/**
* @private
* @method _getHTML
* @description Get the content from the iframe
* @param {String} html The raw HTML from the body of the iframe.
* @return {String}
*/
if (this._ready) {
var inst = this.getInstance();
}
return html;
},
/**
* @private
* @method _setHTML
* @description Set the content of the iframe
* @param {String} html The raw HTML to set the body of the iframe to.
* @return {String}
*/
if (this._ready) {
var inst = this.getInstance();
} else {
//This needs to be wrapped in a contentready callback for the !_ready state
var inst = this.getInstance();
}, this, html));
}
return html;
},
/**
* @method focus
* @description Set the focus to the iframe
*/
focus: function() {
return this;
},
_setExtraCSS: function(css) {
if (this._ready) {
var inst = this.getInstance(),
}
return css;
}
}, {
DEFAULT_CSS: 'html { height: 95%; } body { padding: 7px; background-color: #fff; font: 13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a, a:visited, a:hover { color: blue !important; text-decoration: underline !important; cursor: text !important; } img { cursor: pointer !important; border: none; }',
/**
* @static
* @property HTML
* @description The template string used to create the iframe
* @type String
*/
HTML: '<iframe border="0" frameBorder="0" marginWidth="0" marginHeight="0" leftMargin="0" topMargin="0" allowTransparency="true" width="100%" height="100%"></iframe>',
/**
* @static
* @property PAGE_HTML
* @description The template used to create the page when created dynamically.
* @type String
*/
PAGE_HTML: '<html dir="{DIR}" lang="{LANG}"><head><title>{TITLE}</title>{META}<base href="{BASE_HREF}"/><style id="editor_css">{DEFAULT_CSS}</style>{EXTRA_CSS}</head><body>{CONTENT}</body></html>',
/**
* @static
* @property DOC_TYPE
* @description The DOCTYPE to prepend to the new document when created. Should match the one on the page being served.
* @type String
*/
DOC_TYPE: '<!DOCTYPE HTML PUBLIC "-/'+'/W3C/'+'/DTD HTML 4.01/'+'/EN" "http:/'+'/www.w3.org/TR/html4/strict.dtd">',
/**
* @static
* @property META
* @description The meta-tag for Content-Type to add to the dynamic document
* @type String
*/
/**
* @static
* @property NAME
* @description The name of the class (frame)
* @type String
*/
NAME: 'frame',
ATTRS: {
/**
* @attribute title
* @description The title to give the blank page.
* @type String
*/
title: {
value: 'Blank Page'
},
/**
* @attribute dir
* @description The default text direction for this new frame. Default: ltr
* @type String
*/
dir: {
value: 'ltr'
},
/**
* @attribute lang
* @description The default language. Default: en-US
* @type String
*/
lang: {
value: 'en-US'
},
/**
* @attribute src
* @type String
*/
src: {
//Hackish, IE needs the false in the Javascript URL
},
/**
* @attribute designMode
* @description Should designMode be turned on after creation.
* @writeonce
* @type Boolean
*/
designMode: {
writeOnce: true,
value: false
},
/**
* @attribute content
* @type String
*/
content: {
value: '<br>',
setter: '_setHTML',
getter: '_getHTML'
},
/**
* @attribute basehref
* @description The base href to use in the iframe.
* @type String
*/
basehref: {
value: false,
getter: '_resolveBaseHref'
},
/**
* @attribute use
* @description Array of modules to include in the scoped YUI instance at render time. Default: ['none', 'selector-css2']
* @writeonce
* @type Array
*/
use: {
writeOnce: true,
},
/**
* @attribute container
* @description The container to append the iFrame to on render.
* @type String/HTMLElement/Node
*/
container: {
value: 'body',
setter: function(n) {
return Y.one(n);
}
},
/**
* @attribute id
* @description Set the id of the new Node. (optional)
* @type String
* @writeonce
*/
id: {
writeOnce: true,
if (!id) {
}
return id;
}
},
/**
* @attribute extracss
* @description A string of CSS to add to the Head of the Editor
* @type String
*/
extracss: {
value: '',
setter: '_setExtraCSS'
},
/**
* @attribute host
* @description A reference to the Editor instance
* @type Object
*/
host: {
value: false
}
}
});
/**
* @module editor
* @submodule selection
*/
/**
* @class Selection
* @constructor
*/
//TODO This shouldn't be there, Y.Node doesn't normalize getting textnode content.
var textContent = 'textContent',
INNER_HTML = 'innerHTML',
FONT_FAMILY = 'fontFamily';
Y.Selection = function() {
}
this._selection = sel;
textContent = 'nodeValue';
if (this.isCollapsed) {
}
}
if (ieNode) {
if (ieNode.firstChild) {
}
}
this.anchorOffset = this.focusOffset = (this.anchorNode.nodeValue) ? this.anchorNode.nodeValue.length : 0 ;
}
}
//var self = this;
//debugger;
} else {
}
} else {
}
};
/**
* Performs a prefilter on all nodes in the editor. Looks for nodes with a style: fontFamily or font face
* It then creates a dynamic class assigns it and removed the property. This is so that we don't lose
* the fontFamily when selecting nodes.
* @static
* @method filter
*/
ls;
if (n.getStyle(FONT_FAMILY)) {
});
n.removeAttribute('face');
n.removeAttribute('style');
}
//This is for IE
n.removeAttribute('style');
}
}
});
//Not sure about this one?
newTag = 'i';
if (t === 'strong') {
newTag = 'b';
}
});
v.remove();
}
});
Y.Selection.filterBlocks();
};
/**
* Method attempts to replace all "orphined" text nodes in the main body by wrapping them with a <p>. Called from filter.
* @static
* @method filterBlocks
*/
Y.Selection.filterBlocks = function() {
var childs = Y.config.doc.body.childNodes, i, node, wrapped = false, doit = true, newChild, firstChild;
if (childs) {
doit = true;
doit = false;
}
}
if (doit) {
if (!wrapped) {
wrapped = [];
}
}
} else {
if (wrapped) {
}
wrapped = false;
}
}
}
}
};
/**
* Undoes what filter does enough to return the HTML from the Editor, then re-applies the filter.
* @static
* @method unfilter
* @return {String} The filtered HTML
*/
//One of ours
n.removeClass(n._yuid);
n.removeAttribute('class');
}
}
});
n.remove();
} else {
n.removeClass('yui-non');
}
});
n.removeAttribute('id');
n.removeAttribute('_yuid');
}
});
n.removeAttribute('style');
}
});
return html;
};
/**
* Resolve a node from the selection object and return a Node instance
* @static
* @method resolve
* @param {HTMLElement} n The HTMLElement to resolve. Might be a TextNode, gives parentNode.
* @return {Node} The Resolved node
*/
if (n && n.nodeType === 3) {
n = n.parentNode;
}
return Y.one(n);
};
/**
* The selector to use when looking for Nodes to cache the value of: [style],font[face]
* @static
* @property ALL
*/
/**
* The selector to use when looking for block level items.
* @static
* @property BLOCKS
*/
/**
* The temporary fontname applied to a selection to retrieve their values: yui-tmp
* @static
* @property TMP
*/
/**
* The default tag to use when creating elements: span
* @static
* @property DEFAULT_TAG
*/
/**
* Range text value
* @property text
* @type String
*/
text: null,
/**
* Flag to show if the range is collapsed or not
* @property isCollapsed
* @type Boolean
*/
isCollapsed: null,
/**
* A Node instance of the parentNode of the anchorNode of the range
* @property anchorNode
* @type Node
*/
anchorNode: null,
/**
* The offset from the range object
* @property anchorOffset
* @type Number
*/
anchorOffset: null,
/**
* A Node instance of the actual textNode of the range.
* @property anchorTextNode
* @type Node
*/
anchorTextNode: null,
/**
* A Node instance of the parentNode of the focusNode of the range
* @property focusNode
* @type Node
*/
focusNode: null,
/**
* The offset from the range object
* @property focusOffset
* @type Number
*/
focusOffset: null,
/**
* A Node instance of the actual textNode of the range.
* @property focusTextNode
* @type Node
*/
focusTextNode: null,
/**
* @property _selection
* @private
*/
_selection: null,
/**
* Wrap an element, with another element
* @private
* @method _wrap
* @param {HTMLElement} n The node to wrap
* @param {String} tag The tag to use when creating the new element.
* @return {HTMLElement} The wrapped node
*/
},
/**
* Swap an element, with another element
* @private
* @method _swap
* @param {HTMLElement} n The node to swap
* @param {String} tag The tag to use when creating the new element.
* @return {HTMLElement} The new node
*/
},
/**
* Get all the nodes in the current selection. This method will actually perform a filter first.
* Then it calls doc.execCommand('fontname', null, 'yui-tmp') to touch all nodes in the selection.
* The it compiles a list of all nodes affected by the execCommand and builds a NodeList to return.
* @method getSelected
* @return {NodeList} A NodeList of all items in the selection.
*/
getSelected: function() {
items = [];
n.removeAttribute('face');
n.removeAttribute('style');
}
}
});
},
/**
* Insert HTML at the current cursor position and return a Node instance of the newly inserted element.
* @method insertContent
* @param {String} html The HTML to insert.
* @return {Node} The inserted Node.
*/
insertContent: function(html) {
},
/**
* Insert HTML at the current cursor position, this method gives you control over the text node to insert into and the offset where to put it.
* @method insertAtCursor
* @param {String} html The HTML to insert.
* @param {Node} node The text node to break when inserting.
* @param {Number} offset The left offset of the text node to break and insert the new content.
* @param {Boolean} collapse Should the range be collapsed after insertion. default: false
* @return {Node} The inserted Node.
*/
var cur = Y.Node.create('<' + Y.Selection.DEFAULT_TAG + ' class="yui-non"></' + Y.Selection.DEFAULT_TAG + '>'),
return newNode;
} else {
//TODO using Y.Node.create here throws warnings & strips first white space character
//txt = Y.one(Y.Node.create(inHTML.substr(0, offset)));
//txt2 = Y.one(Y.Node.create(inHTML.substr(offset)));
}
return newNode;
},
/**
* Get all elements inside a selection and wrap them with a new element and return a NodeList of all elements touched.
* @method wrapContent
* @param {String} tag The tag to wrap all selected items with.
* @return {NodeList} A NodeList of all items in the selection.
*/
wrapContent: function(tag) {
if (!this.isCollapsed) {
var items = this.getSelected(),
if (t === 'font') {
} else {
}
}, this);
range = this.createRange();
if (this._selection.removeAllRanges) {
this._selection.removeAllRanges();
} else {
range2 = this.createRange();
}
return changed;
} else {
return Y.all([]);
}
},
/**
* Find and replace a string inside a text node and replace it with HTML focusing the node after
* to allow you to continue to type.
* @method replace
* @param {String} se The string to search for.
* @param {String} re The string of HTML to replace it with.
* @return {Node} The node inserted.
*/
if (range.getBookmark) {
} else {
node = this.anchorTextNode;
}
return newNode;
},
/**
* Destroy the range.
* @method remove
* @chainable
* @return {Y.Selection}
*/
remove: function() {
this._selection.removeAllRanges();
return this;
},
/**
* Wrapper for the different range creation methods.
* @method createRange
* @return {RangeObject}
*/
createRange: function() {
} else {
}
},
/**
* Select a Node (hilighting it).
* @method selectNode
* @param {Node} node The node to select
* @param {Boolean} collapse Should the range be collapsed after insertion. default: false
* @chainable
* @return {Y.Selection}
*/
var range = this.createRange();
if (range.selectNode) {
this._selection.removeAllRanges();
if (collapse) {
try {
} catch (e) {
}
}
} else {
if (collapse) {
}
}
return this;
},
/**
* Put a placeholder in the DOM at the current cursor position.
* @method setCursor
* @return {Node}
*/
setCursor: function() {
},
/**
* Get the placeholder in the DOM at the current cursor position.
* @method getCursor
* @return {Node}
*/
getCursor: function() {
},
/**
* Gets a stored cursor and focuses it for editing, must be called sometime after setCursor
* @method focusCursor
* @return {Node}
*/
focusCursor: function() {
if (cur) {
this.selectNode(cur);
}
},
/**
* Generic toString for logging.
* @method toString
* @return {String}
*/
toString: function() {
return 'Selection Object';
}
};
/**
* Plugin for the frame module to handle execCommands for Editor
* @module editor
* @submodule exec-command
*/
/**
* Plugin for the frame module to handle execCommands for Editor
* @class ExecCommand
* @extends Base
* @constructor
* @namespace Plugin
*/
var ExecCommand = function() {
};
/**
* An internal reference to the instance of the frame plugged into.
* @private
* @property _inst
*/
_inst: null,
/**
* Execute a command on the frame's document.
* @method command
* @param {String} action The action to perform (bold, italic, fontname)
* @param {String} value The optional value (helvetica)
*/
if (fn) {
} else {
}
},
/**
* The private version of execCommand that doesn't filter for overrides.
* @private
* @method _command
* @param {String} action The action to perform (bold, italic, fontname)
* @param {String} value The optional value (helvetica)
*/
var inst = this.getInstance();
try {
} catch (e) {
}
},
/**
* Get's the instance of YUI bound to the parent frame
* @method getInstance
* @return {YUI} The YUI instance bound to the parent frame
*/
getInstance: function() {
if (!this._inst) {
}
return this._inst;
},
initializer: function() {
},
}
});
}
}, {
/**
* execCommand
* @property NAME
* @static
*/
NAME: 'execCommand',
/**
* exec
* @property NS
* @static
*/
NS: 'exec',
ATTRS: {
host: {
value: false
}
},
/**
* Static object literal of execCommand overrides
* @property COMMANDS
* @static
*/
COMMANDS: {
/**
* Wraps the content with a new element of type (tag)
* @method COMMANDS.wrap
* @static
* @param {String} cmd The command executed: wrap
* @param {String} tag The tag to wrap the selection with
* @return {NodeList} NodeList of the items touched by this command.
*/
var inst = this.getInstance();
},
/**
* Inserts the provided HTML at the cursor, should be a single element.
* @method COMMANDS.inserthtml
* @static
* @param {String} cmd The command executed: inserthtml
* @param {String} html The html to insert
* @return {Node} Node instance of the item touched by this command.
*/
var inst = this.getInstance();
},
/**
* Inserts an image at the cursor position
* @method COMMANDS.insertimage
* @static
* @param {String} cmd The command executed: insertimage
* @param {String} img The url of the image to be inserted
* @return {Node} Node instance of the item touched by this command.
*/
},
/**
* Add a class to all of the elements in the selection
* @method COMMANDS.addclass
* @static
* @param {String} cmd The command executed: addclass
* @param {String} cls The className to add
* @return {NodeList} NodeList of the items touched by this command.
*/
var inst = this.getInstance();
},
/**
* Remove a class from all of the elements in the selection
* @method COMMANDS.removeclass
* @static
* @param {String} cmd The command executed: removeclass
* @param {String} cls The className to remove
* @return {NodeList} NodeList of the items touched by this command.
*/
var inst = this.getInstance();
},
bidi: function() {
var inst = this.getInstance(),
if (sel.anchorNode) {
}
if (dir === '') {
}
if (dir === 'rtl') {
dir = 'ltr';
} else {
dir = 'rtl';
}
}
return blockItem;
},
cmd = 'hilitecolor';
}
}
this._command('styleWithCSS', false);
}
},
hilitecolor: function() {
}
}
});
Y.namespace('Plugin');
/**
* @module editor
* @submodule editor-tab
*/
/**
* @class EditorTab
* @constructor
* @extends Base
* @namespace Plugin
*/
var EditorTab = function() {
}, HOST = 'host';
/**
* Listener for host's nodeChange event and captures the tabkey interaction.
* @private
* @method _onNodeChange
* @param {Event} e The Event facade passed from the host.
*/
_onNodeChange: function(e) {
var action = 'indent';
if (e.changedType === 'tab') {
e.changedEvent.halt();
e.preventDefault();
if (e.changedEvent.shiftKey) {
action = 'outdent';
}
}
}
},
initializer: function() {
}
}, {
/**
* editorTab
* @property NAME
* @static
*/
NAME: 'editorTab',
/**
* tab
* @property NS
* @static
*/
NS: 'tab',
ATTRS: {
host: {
value: false
}
}
});
Y.namespace('Plugin');
/**
* Adds prompt style link creation. Adds an override for the <a href="Plugin.ExecCommand.html#method_COMMANDS.createlink">createlink execCommand</a>.
* @module editor
* @submodule createlink-base
*/
/**
* Adds prompt style link creation. Adds an override for the <a href="Plugin.ExecCommand.html#method_COMMANDS.createlink">createlink execCommand</a>.
* @class CreateLinkBase
* @static
* @namespace Plugin
*/
var CreateLinkBase = {};
/**
* Strings used by the plugin
* @property STRINGS
* @static
*/
/**
* String used for the Prompt
* @property PROMPT
* @static
*/
PROMPT: 'Please enter the URL for the link to point to:',
/**
* String used as the default value of the Prompt
* @property DEFAULT
* @static
*/
DEFAULT: 'http://'
};
Y.namespace('Plugin');
/**
* Override for the createlink method from the <a href="Plugin.CreateLinkBase.html">CreateLinkBase</a> plugin.
* @for ExecCommand
* @method COMMANDS.createlink
* @static
* @param {String} cmd The command executed: createlink
* @return {Node} Node instance of the item touched by this command.
*/
createlink: function(cmd) {
if (url) {
//We have a selection
} else {
//No selection, insert a new node..
}
}
return a;
}
});
/**
* Base class for Editor. Handles the business logic of Editor, no GUI involved only utility methods and events.
* @module editor
* @submodule editor-base
*/
/**
* Base class for Editor. Handles the business logic of Editor, no GUI involved only utility methods and events.
* @class EditorBase
* @extends Base
* @constructor
*/
var EditorBase = function() {
};
/**
* Internal reference to the Y.Frame instance
* @property frame
*/
frame: null,
initializer: function() {
designMode: true,
host: this
this.publish('nodeChange', {
emitFacade: true,
bubbles: true,
defaultFn: this._defNodeChangeFn
});
},
/**
* The default handler for the nodeChange event.
* @method _defNodeChangeFn
* @param {Event} e The event
* @private
*/
_defNodeChangeFn: function(e) {
switch (e.changedType) {
case 'enter':
//Enter key goes here..
break;
case 'tab':
e.changedEvent.halt();
}
break;
}
if (e.commands) {
}
if (cmd) {
}
//Bold and Italic styles
}
}
}
}
if (family2) {
}
}
});
if (bColor2 !== 'transparent') {
}
});
e.classNames = classes;
//TODO Dont' like this, not dynamic enough..
if (!e.fontFamily) {
e.fontFamily = family;
}
if (!e.fontSize) {
}
if (!e.fontColor) {
}
if (!e.backgroundColor) {
e.backgroundColor = bColor;
}
},
/**
* Walk the dom tree from this node up to body, returning a reversed array of parents.
* @method getDomPath
* @param {Node} node The Node to start from
*/
getDomPath: function(node) {
var domPath = [],
while (node !== null) {
node = null;
break;
}
//Check to see if we get el.nodeName and nodeType
}
node = null;
break;
}
}
}
},
/**
* After frame ready, bind mousedown & keyup listeners
* @method _afterFrameReady
* @private
*/
_afterFrameReady: function() {
},
/**
* Fires nodeChange event
* @method _onFrameMouseDown
* @private
*/
_onFrameMouseDown: function(e) {
},
/**
* Fires nodeChange event for keyup on specific keys
* @method _onFrameKeyUp
* @private
*/
_onFrameKeyUp: function(e) {
if (sel.anchorNode) {
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: 'keyup', selection: sel, changedEvent: e });
}
}
},
/**
* Fires nodeChange event
* @method _onFrameKeyDown
* @private
*/
_onFrameKeyDown: function(e) {
this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: EditorBase.NC_KEYS[e.keyCode], changedEvent: e });
}
},
/**
* Pass through to the frame.execCommand method
* @method execCommand
* @param {String} cmd The command to pass: inserthtml, insertimage, bold
* @param {String} val The optional value of the command: Helvetica
* @return {Node/NodeList} The Node or Nodelist affected by the command. Only returns on override commands, not browser defined commands.
*/
switch (cmd) {
case 'forecolor':
break;
case 'backcolor':
e.backgroundColor = val;
break;
case 'fontsize':
break;
case 'fontname':
e.fontFamily = val;
break;
}
this.fire('nodeChange', e);
return ret;
},
/**
* Get the YUI instance of the frame
* @method getInstance
* @return {YUI} The YUI instance bound to the frame.
*/
getInstance: function() {
return this.frame.getInstance();
},
destructor: function() {
},
/**
* Renders the Y.Frame to the passed node.
* @method render
* @param {Selector/HTMLElement/Node} node The node to append the Editor to
* @return {EditorBase}
* @chainable
*/
return this;
},
/**
* Focus the contentWindow of the iframe
* @method focus
* @return {EditorBase}
* @chainable
*/
focus: function() {
return this;
},
/**
* (Un)Filters the content of the Editor, cleaning YUI related code. //TODO better filtering
* @method getContent
* @return {String} The filtered content of the Editor
*/
getContent: function() {
//Removing the _yuid from the objects in IE
return html;
}
}, {
/**
* @method filter_rgb
* @param String css The CSS string containing rgb(#,#,#);
* @description Converts an RGB color string to a hex color, example: rgb(0, 255, 0) converts to #00ff00
* @return String
*/
FILTER_RGB: function(css) {
var exp = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
css = "#" + r + g + b;
}
}
return css;
},
TAG2CMD: {
'b': 'bold',
'strong': 'bold',
'i': 'italic',
'em': 'italic',
'u': 'underline',
'sup': 'superscript',
'sub': 'subscript',
'img': 'insertimage',
'a' : 'createlink',
'ul' : 'insertunorderedlist',
'ol' : 'insertorderedlist'
},
/**
* Hash table of keys to fire a nodeChange event for.
* @static
* @property NC_KEYS
* @type Object
*/
NC_KEYS: {
8: 'backspace',
9: 'tab',
13: 'enter',
32: 'space',
33: 'pageup',
34: 'pagedown',
35: 'end',
36: 'home',
37: 'left',
38: 'up',
39: 'right',
40: 'down',
46: 'delete'
},
/**
* The default modules to use inside the Frame
* @static
* @property USE
* @type Array
*/
/**
* The Class Name: editorBase
* @static
* @property NAME
*/
NAME: 'editorBase',
/**
* Editor Strings
* @static
* @property STRINGS
*/
STRINGS: {
/**
* Title of frame document: Rich Text Editor
* @static
* @property STRINGS.title
*/
title: 'Rich Text Editor'
},
ATTRS: {
/**
* The content to load into the Editor Frame
* @attribute content
*/
content: {
value: '<br>',
}
},
getter: function() {
}
},
/**
* The value of the dir attribute on the HTML element of the frame. Default: ltr
* @attribute dir
*/
dir: {
writeOnce: true,
value: 'ltr'
},
/**
* @attribute extracss
* @description A string of CSS to add to the Head of the Editor
* @type String
*/
extracss: {
value: false,
if (this.frame) {
}
return css;
}
}
}
});
Y.EditorBase = EditorBase;
/**
* @event nodeChange
* @description Fired from mouseup & keyup.
* @param {Event.Facade} event An Event Facade object with the following specific property added:
* <dl><dt>node</dt><dd>The node currently being interacted with</dd></dl>
* @type {Event.Custom}
*/
/**
* Handles list manipulation inside the Editor. Adds keyboard manipulation and execCommand support. Adds overrides for the <a href="Plugin.ExecCommand.html#method_COMMANDS.insertorderedlist">insertorderedlist</a> and <a href="Plugin.ExecCommand.html#method_COMMANDS.insertunorderedlist">insertunorderedlist</a> execCommands.
* @module editor
* @submodule editor-lists
*/
/**
* Handles list manipulation inside the Editor. Adds keyboard manipulation and execCommand support. Adds overrides for the <a href="Plugin.ExecCommand.html#method_COMMANDS.insertorderedlist">insertorderedlist</a> and <a href="Plugin.ExecCommand.html#method_COMMANDS.insertunorderedlist">insertunorderedlist</a> execCommands.
* @class EditorLists
* @constructor
* @extends Base
* @namespace Plugin
*/
var EditorLists = function() {
/**
* Listener for host's nodeChange event and captures the tabkey interaction only when inside a list node.
* @private
* @method _onNodeChange
* @param {Event} e The Event facade passed from the host.
*/
_onNodeChange: function(e) {
e.changedEvent.halt();
e.preventDefault();
li = e.changedNode;
}
}
}
if (e.changedType === 'tab') {
e.changedEvent.halt();
e.preventDefault();
li = e.changedNode;
}
}
if (sTab) {
moved = true;
}
} else {
//li.setStyle('border', '1px solid red');
moved = true;
}
}
}
if (moved) {
}
//Selection here..
}
}
},
initializer: function() {
}
}, {
NON: '<span class="yui-non"> </span>',
NON_SEL: 'span.yui-non',
/**
* The items to removed from a list when a list item is moved, currently removes BR nodes
* @property REMOVE
* @static
*/
REMOVE: 'br',
/**
* editorLists
* @property NAME
* @static
*/
NAME: 'editorLists',
/**
* lists
* @property NS
* @static
*/
NS: 'lists',
ATTRS: {
host: {
value: false
}
}
});
Y.namespace('Plugin');
/**
* Override for the insertunorderedlist method from the <a href="Plugin.EditorLists.html">EditorLists</a> plugin.
* @for ExecCommand
* @method COMMANDS.insertunorderedlist
* @static
* @param {String} cmd The command executed: insertunorderedlist
* @return {Node} Node instance of the item touched by this command.
*/
insertunorderedlist: function(cmd) {
return out;
},
/**
* Override for the insertorderedlist method from the <a href="Plugin.EditorLists.html">EditorLists</a> plugin.
* @for ExecCommand
* @method COMMANDS.insertorderedlist
* @static
* @param {String} cmd The command executed: insertorderedlist
* @return {Node} Node instance of the item touched by this command.
*/
insertorderedlist: function(cmd) {
return out;
}
});
YUI.add('editor', function(Y){}, '@VERSION@' ,{use:['frame', 'selection', 'exec-command', 'editor-base'], skinnable:false});