editor-lists.js revision d2a5a45ff58ab15a8ee0339edcd03f0243373d59
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam MooreYUI.add('editor-lists', function(Y) {
b39897a381c2203466da5568bfd2862a54a81311Adam Moore
b39897a381c2203466da5568bfd2862a54a81311Adam Moore /**
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * 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.
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore * @module editor
2c5ce90c334a2d0f18474e85c93b424b6ec9daaaAdam Moore * @submodule editor-lists
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore /**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * 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.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @class Plugin.EditorLists
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @constructor
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @extends Base
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove var EditorLists = function() {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove EditorLists.superclass.constructor.apply(this, arguments);
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove }, LI = 'li', OL = 'ol', UL = 'ul', HOST = 'host';
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove Y.extend(EditorLists, Y.Base, {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove /**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * Listener for host's nodeChange event and captures the tabkey interaction only when inside a list node.
8e3356edb73b10f6622c26b9186418d70fcde68bRyan Grove * @private
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @method _onNodeChange
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @param {Event} e The Event facade passed from the host.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore _onNodeChange: function(e) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove var inst = this.get(HOST).getInstance(), sel, li,
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove newLi, newList, sTab, par, moved = false, tag, focusEnd = false;
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove if (Y.UA.ie && e.changedType === 'enter') {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove if (e.changedNode.test(LI + ', ' + LI + ' *')) {
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore e.changedEvent.halt();
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove e.preventDefault();
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove li = e.changedNode;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore newLi = inst.Node.create('<' + LI + '>' + EditorLists.NON + '</' + LI + '>');
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove if (!li.test(LI)) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove li = li.ancestor(LI);
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove }
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove li.insert(newLi, 'after');
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove sel = new inst.Selection();
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove sel.selectNode(newLi.get('firstChild'), true, false);
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove }
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove }
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove if (e.changedType === 'tab') {
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore if (e.changedNode.test(LI + ', ' + LI + ' *')) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove e.changedEvent.halt();
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove e.preventDefault();
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove li = e.changedNode;
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove sTab = e.changedEvent.shiftKey;
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove par = li.ancestor(OL + ',' + UL);
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove tag = UL;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
67e8ed2937abc262dbe7537695d632143294269fRyan Grove
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (par.get('tagName').toLowerCase() === OL) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove tag = OL;
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (!li.test(LI)) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove li = li.ancestor(LI);
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (sTab) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (li.ancestor(LI)) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove li.ancestor(LI).insert(li, 'after');
67e8ed2937abc262dbe7537695d632143294269fRyan Grove moved = true;
67e8ed2937abc262dbe7537695d632143294269fRyan Grove focusEnd = true;
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove } else {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove //li.setStyle('border', '1px solid red');
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (li.previous(LI)) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove newList = inst.Node.create('<' + tag + '></' + tag + '>');
67e8ed2937abc262dbe7537695d632143294269fRyan Grove li.previous(LI).append(newList);
67e8ed2937abc262dbe7537695d632143294269fRyan Grove newList.append(li);
67e8ed2937abc262dbe7537695d632143294269fRyan Grove moved = true;
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (moved) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (!li.test(LI)) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove li = li.ancestor(LI);
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove li.all(EditorLists.REMOVE).remove();
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove if (Y.UA.ie) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove li = li.append(EditorLists.NON).one(EditorLists.NON_SEL);
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove //Selection here..
67e8ed2937abc262dbe7537695d632143294269fRyan Grove (new inst.Selection()).selectNode(li, true, focusEnd);
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove }
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove },
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove initializer: function() {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove this.get(HOST).on('nodeChange', Y.bind(this._onNodeChange, this));
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove }
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove }, {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove /**
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * The non element placeholder, used for positioning the cursor and filling empty items
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @property REMOVE
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @static
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove */
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove NON: '<span class="yui-non">&nbsp;</span>',
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove /**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * The selector query to get all non elements
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @property NONSEL
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @static
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove */
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove NON_SEL: 'span.yui-non',
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove /**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * The items to removed from a list when a list item is moved, currently removes BR nodes
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @property REMOVE
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @static
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove */
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove REMOVE: 'br',
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove /**
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore * editorLists
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @property NAME
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @static
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove */
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove NAME: 'editorLists',
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove /**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * lists
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @property NS
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @static
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove */
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove NS: 'lists',
9fb523cf517ad4d6a53ae9f461d672cba63835d2Adam Moore ATTRS: {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore host: {
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove value: false
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove }
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove }
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove });
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove Y.namespace('Plugin');
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove Y.Plugin.EditorLists = EditorLists;
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove Y.mix(Y.Plugin.ExecCommand.COMMANDS, {
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove /**
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * Override for the insertunorderedlist method from the <a href="Plugin.EditorLists.html">EditorLists</a> plugin.
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * @for ExecCommand
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * @method COMMANDS.insertunorderedlist
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @static
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * @param {String} cmd The command executed: insertunorderedlist
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * @return {Node} Node instance of the item touched by this command.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore insertunorderedlist: function(cmd) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove var inst = this.get('host').getInstance(), out;
67e8ed2937abc262dbe7537695d632143294269fRyan Grove this.get('host')._execCommand(cmd, '');
67e8ed2937abc262dbe7537695d632143294269fRyan Grove },
67e8ed2937abc262dbe7537695d632143294269fRyan Grove /**
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * Override for the insertorderedlist method from the <a href="Plugin.EditorLists.html">EditorLists</a> plugin.
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @for ExecCommand
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @method COMMANDS.insertorderedlist
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @static
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @param {String} cmd The command executed: insertorderedlist
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @return {Node} Node instance of the item touched by this command.
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove */
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove insertorderedlist: function(cmd) {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove var inst = this.get('host').getInstance(), out;
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove this.get('host')._execCommand(cmd, '');
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove }
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove });
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
67e8ed2937abc262dbe7537695d632143294269fRyan Grove}, '@VERSION@' ,{skinnable:false, requires:['editor-base']});
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore