src/cm/media/js/lib/yui/yui3-3.15.0/build/exec-command/exec-command-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('exec-command', function (Y, NAME) {
       
     2 
       
     3 
       
     4     /**
       
     5      * Plugin for the frame module to handle execCommands for Editor
       
     6      * @class Plugin.ExecCommand
       
     7      * @extends Base
       
     8      * @constructor
       
     9      * @module editor
       
    10      * @submodule exec-command
       
    11      */
       
    12         var ExecCommand = function() {
       
    13             ExecCommand.superclass.constructor.apply(this, arguments);
       
    14         },
       
    15         /**
       
    16         * This method is meant to normalize IE's in ability to exec the proper command on elements with CSS styling.
       
    17         * @method fixIETags
       
    18         * @protected
       
    19         * @param {String} cmd The command to execute
       
    20         * @param {String} tag The tag to create
       
    21         * @param {String} rule The rule that we are looking for.
       
    22         */
       
    23         fixIETags = function(cmd, tag, rule) {
       
    24             var inst = this.getInstance(),
       
    25                 doc = inst.config.doc,
       
    26                 sel = doc.selection.createRange(),
       
    27                 o = doc.queryCommandValue(cmd),
       
    28                 html, reg, m, p, d, s, c;
       
    29 
       
    30             if (o) {
       
    31                 html = sel.htmlText;
       
    32                 reg = new RegExp(rule, 'g');
       
    33                 m = html.match(reg);
       
    34 
       
    35                 if (m) {
       
    36                     html = html.replace(rule + ';', '').replace(rule, '');
       
    37 
       
    38                     sel.pasteHTML('<var id="yui-ie-bs">');
       
    39 
       
    40                     p = doc.getElementById('yui-ie-bs');
       
    41                     d = doc.createElement('div');
       
    42                     s = doc.createElement(tag);
       
    43 
       
    44                     d.innerHTML = html;
       
    45                     if (p.parentNode !== inst.config.doc.body) {
       
    46                         p = p.parentNode;
       
    47                     }
       
    48 
       
    49                     c = d.childNodes;
       
    50 
       
    51                     p.parentNode.replaceChild(s, p);
       
    52 
       
    53                     Y.each(c, function(f) {
       
    54                         s.appendChild(f);
       
    55                     });
       
    56                     sel.collapse();
       
    57                     if (sel.moveToElementText) {
       
    58                         sel.moveToElementText(s);
       
    59                     }
       
    60                     sel.select();
       
    61                 }
       
    62             }
       
    63             this._command(cmd);
       
    64         };
       
    65 
       
    66         Y.extend(ExecCommand, Y.Base, {
       
    67             /**
       
    68             * An internal reference to the keyCode of the last key that was pressed.
       
    69             * @private
       
    70             * @property _lastKey
       
    71             */
       
    72             _lastKey: null,
       
    73             /**
       
    74             * An internal reference to the instance of the frame plugged into.
       
    75             * @private
       
    76             * @property _inst
       
    77             */
       
    78             _inst: null,
       
    79             /**
       
    80             * Execute a command on the frame's document.
       
    81             * @method command
       
    82             * @param {String} action The action to perform (bold, italic, fontname)
       
    83             * @param {String} value The optional value (helvetica)
       
    84             * @return {Node/NodeList} Should return the Node/Nodelist affected
       
    85             */
       
    86             command: function(action, value) {
       
    87                 var fn = ExecCommand.COMMANDS[action];
       
    88 
       
    89                 Y.log('execCommand(' + action + '): "' + value + '"', 'info', 'exec-command');
       
    90                 if (fn) {
       
    91                     Y.log('OVERIDE execCommand(' + action + '): "' + value + '"', 'info', 'exec-command');
       
    92                     return fn.call(this, action, value);
       
    93                 } else {
       
    94                     return this._command(action, value);
       
    95                 }
       
    96             },
       
    97             /**
       
    98             * The private version of execCommand that doesn't filter for overrides.
       
    99             * @private
       
   100             * @method _command
       
   101             * @param {String} action The action to perform (bold, italic, fontname)
       
   102             * @param {String} value The optional value (helvetica)
       
   103             */
       
   104             _command: function(action, value) {
       
   105                 var inst = this.getInstance();
       
   106                 try {
       
   107                     try {
       
   108                         inst.config.doc.execCommand('styleWithCSS', null, 1);
       
   109                     } catch (e1) {
       
   110                         try {
       
   111                             inst.config.doc.execCommand('useCSS', null, 0);
       
   112                         } catch (e2) {
       
   113                         }
       
   114                     }
       
   115                     Y.log('Using default browser execCommand(' + action + '): "' + value + '"', 'info', 'exec-command');
       
   116                     inst.config.doc.execCommand(action, null, value);
       
   117                 } catch (e) {
       
   118                     Y.log(e.message, 'warn', 'exec-command');
       
   119                 }
       
   120             },
       
   121             /**
       
   122             * Get's the instance of YUI bound to the parent frame
       
   123             * @method getInstance
       
   124             * @return {YUI} The YUI instance bound to the parent frame
       
   125             */
       
   126             getInstance: function() {
       
   127                 if (!this._inst) {
       
   128                     this._inst = this.get('host').getInstance();
       
   129                 }
       
   130                 return this._inst;
       
   131             },
       
   132             initializer: function() {
       
   133                 Y.mix(this.get('host'), {
       
   134                     execCommand: function(action, value) {
       
   135                         return this.exec.command(action, value);
       
   136                     },
       
   137                     _execCommand: function(action, value) {
       
   138                         return this.exec._command(action, value);
       
   139                     }
       
   140                 });
       
   141 
       
   142                 this.get('host').on('dom:keypress', Y.bind(function(e) {
       
   143                     this._lastKey = e.keyCode;
       
   144                 }, this));
       
   145             },
       
   146             _wrapContent: function(str, override) {
       
   147                 var useP = (this.getInstance().host.editorPara && !override ? true : false);
       
   148 
       
   149                 if (useP) {
       
   150                     str = '<p>' + str + '</p>';
       
   151                 } else {
       
   152                     str = str + '<br>';
       
   153                 }
       
   154                 return str;
       
   155             }
       
   156         }, {
       
   157             /**
       
   158             * execCommand
       
   159             * @property NAME
       
   160             * @static
       
   161             */
       
   162             NAME: 'execCommand',
       
   163             /**
       
   164             * exec
       
   165             * @property NS
       
   166             * @static
       
   167             */
       
   168             NS: 'exec',
       
   169             ATTRS: {
       
   170                 host: {
       
   171                     value: false
       
   172                 }
       
   173             },
       
   174             /**
       
   175             * Static object literal of execCommand overrides
       
   176             * @class Plugin.ExecCommand.COMMANDS
       
   177             * @static
       
   178             */
       
   179             COMMANDS: {
       
   180                 /**
       
   181                 * Wraps the content with a new element of type (tag)
       
   182                 * @method wrap
       
   183                 * @static
       
   184                 * @param {String} cmd The command executed: wrap
       
   185                 * @param {String} tag The tag to wrap the selection with
       
   186                 * @return {NodeList} NodeList of the items touched by this command.
       
   187                 */
       
   188                 wrap: function(cmd, tag) {
       
   189                     var inst = this.getInstance();
       
   190                     return (new inst.EditorSelection()).wrapContent(tag);
       
   191                 },
       
   192                 /**
       
   193                 * Inserts the provided HTML at the cursor, should be a single element.
       
   194                 * @method inserthtml
       
   195                 * @static
       
   196                 * @param {String} cmd The command executed: inserthtml
       
   197                 * @param {String} html The html to insert
       
   198                 * @return {Node} Node instance of the item touched by this command.
       
   199                 */
       
   200                 inserthtml: function(cmd, html) {
       
   201                     var inst = this.getInstance();
       
   202                     if (inst.EditorSelection.hasCursor() || Y.UA.ie) {
       
   203                         return (new inst.EditorSelection()).insertContent(html);
       
   204                     } else {
       
   205                         this._command('inserthtml', html);
       
   206                     }
       
   207                 },
       
   208                 /**
       
   209                 * Inserts the provided HTML at the cursor, and focuses the cursor afterwards.
       
   210                 * @method insertandfocus
       
   211                 * @static
       
   212                 * @param {String} cmd The command executed: insertandfocus
       
   213                 * @param {String} html The html to insert
       
   214                 * @return {Node} Node instance of the item touched by this command.
       
   215                 */
       
   216                 insertandfocus: function(cmd, html) {
       
   217                     var inst = this.getInstance(), out, sel;
       
   218                     if (inst.EditorSelection.hasCursor()) {
       
   219                         html += inst.EditorSelection.CURSOR;
       
   220                         out = this.command('inserthtml', html);
       
   221                         sel = new inst.EditorSelection();
       
   222                         sel.focusCursor(true, true);
       
   223                     } else {
       
   224                         this.command('inserthtml', html);
       
   225                     }
       
   226                     return out;
       
   227                 },
       
   228                 /**
       
   229                 * Inserts a BR at the current cursor position
       
   230                 * @method insertbr
       
   231                 * @static
       
   232                 * @param {String} cmd The command executed: insertbr
       
   233                 */
       
   234                 insertbr: function() {
       
   235                     var inst = this.getInstance(),
       
   236                         sel = new inst.EditorSelection(),
       
   237                         html = '<var>|</var>', last = null,
       
   238                         root = inst.EditorSelection.ROOT,
       
   239                         q = (Y.UA.webkit) ? 'span.Apple-style-span,var' : 'var',
       
   240                         insert = function(n) {
       
   241                             var c = inst.Node.create('<br>');
       
   242                             n.insert(c, 'before');
       
   243                             return c;
       
   244                         };
       
   245 
       
   246                     if (sel._selection.pasteHTML) {
       
   247                         sel._selection.pasteHTML(html);
       
   248                     } else {
       
   249                         this._command('inserthtml', html);
       
   250                     }
       
   251 
       
   252 
       
   253                     root.all(q).each(function(n) {
       
   254                         var g = true, s;
       
   255                         if (Y.UA.webkit) {
       
   256                             g = false;
       
   257                             if (n.get('innerHTML') === '|') {
       
   258                                 g = true;
       
   259                             }
       
   260                         }
       
   261                         if (g) {
       
   262                             last = insert(n);
       
   263                             if ((!last.previous() || !last.previous().test('br')) && Y.UA.gecko) {
       
   264                                 s = last.cloneNode();
       
   265                                 last.insert(s, 'after');
       
   266                                 last = s;
       
   267                             }
       
   268                             n.remove();
       
   269                         }
       
   270                     });
       
   271                     if (Y.UA.webkit && last) {
       
   272                         insert(last);
       
   273                         sel.selectNode(last);
       
   274                     }
       
   275                 },
       
   276                 /**
       
   277                 * Inserts an image at the cursor position
       
   278                 * @method insertimage
       
   279                 * @static
       
   280                 * @param {String} cmd The command executed: insertimage
       
   281                 * @param {String} img The url of the image to be inserted
       
   282                 * @return {Node} Node instance of the item touched by this command.
       
   283                 */
       
   284                 insertimage: function(cmd, img) {
       
   285                     return this.command('inserthtml', '<img src="' + img + '">');
       
   286                 },
       
   287                 /**
       
   288                 * Add a class to all of the elements in the selection
       
   289                 * @method addclass
       
   290                 * @static
       
   291                 * @param {String} cmd The command executed: addclass
       
   292                 * @param {String} cls The className to add
       
   293                 * @return {NodeList} NodeList of the items touched by this command.
       
   294                 */
       
   295                 addclass: function(cmd, cls) {
       
   296                     var inst = this.getInstance();
       
   297                     return (new inst.EditorSelection()).getSelected().addClass(cls);
       
   298                 },
       
   299                 /**
       
   300                 * Remove a class from all of the elements in the selection
       
   301                 * @method removeclass
       
   302                 * @static
       
   303                 * @param {String} cmd The command executed: removeclass
       
   304                 * @param {String} cls The className to remove
       
   305                 * @return {NodeList} NodeList of the items touched by this command.
       
   306                 */
       
   307                 removeclass: function(cmd, cls) {
       
   308                     var inst = this.getInstance();
       
   309                     return (new inst.EditorSelection()).getSelected().removeClass(cls);
       
   310                 },
       
   311                 /**
       
   312                 * Adds a forecolor to the current selection, or creates a new element and applies it
       
   313                 * @method forecolor
       
   314                 * @static
       
   315                 * @param {String} cmd The command executed: forecolor
       
   316                 * @param {String} val The color value to apply
       
   317                 * @return {NodeList} NodeList of the items touched by this command.
       
   318                 */
       
   319                 forecolor: function(cmd, val) {
       
   320                     var inst = this.getInstance(),
       
   321                         sel = new inst.EditorSelection(), n;
       
   322 
       
   323                     if (!Y.UA.ie) {
       
   324                         this._command('useCSS', false);
       
   325                     }
       
   326                     if (inst.EditorSelection.hasCursor()) {
       
   327                         if (sel.isCollapsed) {
       
   328                             if (sel.anchorNode && (sel.anchorNode.get('innerHTML') === '&nbsp;')) {
       
   329                                 sel.anchorNode.setStyle('color', val);
       
   330                                 n = sel.anchorNode;
       
   331                             } else {
       
   332                                 n = this.command('inserthtml', '<span style="color: ' + val + '">' + inst.EditorSelection.CURSOR + '</span>');
       
   333                                 sel.focusCursor(true, true);
       
   334                             }
       
   335                             return n;
       
   336                         } else {
       
   337                             return this._command(cmd, val);
       
   338                         }
       
   339                     } else {
       
   340                         this._command(cmd, val);
       
   341                     }
       
   342                 },
       
   343                 /**
       
   344                 * Adds a background color to the current selection, or creates a new element and applies it
       
   345                 * @method backcolor
       
   346                 * @static
       
   347                 * @param {String} cmd The command executed: backcolor
       
   348                 * @param {String} val The color value to apply
       
   349                 * @return {NodeList} NodeList of the items touched by this command.
       
   350                 */
       
   351                 backcolor: function(cmd, val) {
       
   352                     var inst = this.getInstance(),
       
   353                         sel = new inst.EditorSelection(), n;
       
   354 
       
   355                     if (Y.UA.gecko || Y.UA.opera) {
       
   356                         cmd = 'hilitecolor';
       
   357                     }
       
   358                     if (!Y.UA.ie) {
       
   359                         this._command('useCSS', false);
       
   360                     }
       
   361                     if (inst.EditorSelection.hasCursor()) {
       
   362                         if (sel.isCollapsed) {
       
   363                             if (sel.anchorNode && (sel.anchorNode.get('innerHTML') === '&nbsp;')) {
       
   364                                 sel.anchorNode.setStyle('backgroundColor', val);
       
   365                                 n = sel.anchorNode;
       
   366                             } else {
       
   367                                 n = this.command('inserthtml',
       
   368                                     '<span style="background-color: ' + val + '">' + inst.EditorSelection.CURSOR + '</span>');
       
   369                                 sel.focusCursor(true, true);
       
   370                             }
       
   371                             return n;
       
   372                         } else {
       
   373                             return this._command(cmd, val);
       
   374                         }
       
   375                     } else {
       
   376                         this._command(cmd, val);
       
   377                     }
       
   378                 },
       
   379                 /**
       
   380                 * Sugar method, calles backcolor
       
   381                 * @method hilitecolor
       
   382                 * @static
       
   383                 * @param {String} cmd The command executed: backcolor
       
   384                 * @param {String} val The color value to apply
       
   385                 * @return {NodeList} NodeList of the items touched by this command.
       
   386                 */
       
   387                 hilitecolor: function() {
       
   388                     return ExecCommand.COMMANDS.backcolor.apply(this, arguments);
       
   389                 },
       
   390                 /**
       
   391                 * Adds a font name to the current selection, or creates a new element and applies it
       
   392                 * @method fontname2
       
   393                 * @deprecated
       
   394                 * @static
       
   395                 * @param {String} cmd The command executed: fontname
       
   396                 * @param {String} val The font name to apply
       
   397                 * @return {NodeList} NodeList of the items touched by this command.
       
   398                 */
       
   399                 fontname2: function(cmd, val) {
       
   400                     this._command('fontname', val);
       
   401                     var inst = this.getInstance(),
       
   402                         sel = new inst.EditorSelection();
       
   403 
       
   404                     if (sel.isCollapsed && (this._lastKey !== 32)) {
       
   405                         if (sel.anchorNode.test('font')) {
       
   406                             sel.anchorNode.set('face', val);
       
   407                         }
       
   408                     }
       
   409                 },
       
   410                 /**
       
   411                 * Adds a fontsize to the current selection, or creates a new element and applies it
       
   412                 * @method fontsize2
       
   413                 * @deprecated
       
   414                 * @static
       
   415                 * @param {String} cmd The command executed: fontsize
       
   416                 * @param {String} val The font size to apply
       
   417                 * @return {NodeList} NodeList of the items touched by this command.
       
   418                 */
       
   419                 fontsize2: function(cmd, val) {
       
   420                     this._command('fontsize', val);
       
   421 
       
   422                     var inst = this.getInstance(),
       
   423                         sel = new inst.EditorSelection(), p;
       
   424 
       
   425                     if (sel.isCollapsed && sel.anchorNode && (this._lastKey !== 32)) {
       
   426                         if (Y.UA.webkit) {
       
   427                             if (sel.anchorNode.getStyle('lineHeight')) {
       
   428                                 sel.anchorNode.setStyle('lineHeight', '');
       
   429                             }
       
   430                         }
       
   431                         if (sel.anchorNode.test('font')) {
       
   432                             sel.anchorNode.set('size', val);
       
   433                         } else if (Y.UA.gecko) {
       
   434                             p = sel.anchorNode.ancestor(inst.EditorSelection.DEFAULT_BLOCK_TAG);
       
   435                             if (p) {
       
   436                                 p.setStyle('fontSize', '');
       
   437                             }
       
   438                         }
       
   439                     }
       
   440                 },
       
   441                 /**
       
   442                 * Overload for list
       
   443                 * @method insertorderedlist
       
   444                 * @static
       
   445                 * @param {String} cmd The command executed: list, ul
       
   446                 */
       
   447                 insertunorderedlist: function() {
       
   448                     this.command('list', 'ul');
       
   449                 },
       
   450                 /**
       
   451                 * Overload for list
       
   452                 * @method insertunorderedlist
       
   453                 * @static
       
   454                 * @param {String} cmd The command executed: list, ol
       
   455                 */
       
   456                 insertorderedlist: function() {
       
   457                     this.command('list', 'ol');
       
   458                 },
       
   459                 /**
       
   460                 * Noramlizes lists creation/destruction for IE. All others pass through to native calls
       
   461                 * @method list
       
   462                 * @static
       
   463                 * @param {String} cmd The command executed: list (not used)
       
   464                 * @param {String} tag The tag to deal with
       
   465                 */
       
   466                 list: function(cmd, tag) {
       
   467                     var inst = this.getInstance(), html, self = this,
       
   468                         /*
       
   469                         The yui3- class name below is not a skinnable class,
       
   470                         it's a utility class used internally by editor and
       
   471                         stripped when completed, calling getClassName on this
       
   472                         is a waste of resources.
       
   473                         */
       
   474                         DIR = 'dir', cls = 'yui3-touched',
       
   475                         dir, range, div, elm, n, str, s, par, list, lis,
       
   476                         useP = (inst.host.editorPara ? true : false), tmp,
       
   477                         sdir, hasPParent, fc,
       
   478                         root = inst.EditorSelection.ROOT,
       
   479                         sel = new inst.EditorSelection();
       
   480 
       
   481                     cmd = 'insert' + ((tag === 'ul') ? 'un' : '') + 'orderedlist';
       
   482 
       
   483                     if (Y.UA.ie && Y.UA.ie < 11 && !sel.isCollapsed) {
       
   484                         range = sel._selection;
       
   485                         html = range.htmlText;
       
   486                         div = inst.Node.create(html) || root;
       
   487 
       
   488                         if (div.test('li') || div.one('li')) {
       
   489                             this._command(cmd, null);
       
   490                             return;
       
   491                         }
       
   492                         if (div.test(tag)) {
       
   493                             elm = range.item ? range.item(0) : range.parentElement();
       
   494                             n = inst.one(elm);
       
   495                             lis = n.all('li');
       
   496 
       
   497                             str = '<div>';
       
   498                             lis.each(function(l) {
       
   499                                 str = self._wrapContent(l.get('innerHTML'));
       
   500                             });
       
   501                             str += '</div>';
       
   502                             s = inst.Node.create(str);
       
   503                             if (n.get('parentNode').test('div')) {
       
   504                                 n = n.get('parentNode');
       
   505                             }
       
   506                             if (n && n.hasAttribute(DIR)) {
       
   507                                 if (useP) {
       
   508                                     s.all('p').setAttribute(DIR, n.getAttribute(DIR));
       
   509                                 } else {
       
   510                                     s.setAttribute(DIR, n.getAttribute(DIR));
       
   511                                 }
       
   512                             }
       
   513                             if (useP) {
       
   514                                 n.replace(s.get('innerHTML'));
       
   515                             } else {
       
   516                                 n.replace(s);
       
   517                             }
       
   518                             if (range.moveToElementText) {
       
   519                                 range.moveToElementText(s._node);
       
   520                             }
       
   521                             range.select();
       
   522                         } else {
       
   523                             par = Y.one(range.parentElement());
       
   524                             if (!par.test(inst.EditorSelection.BLOCKS)) {
       
   525                                 par = par.ancestor(inst.EditorSelection.BLOCKS);
       
   526                             }
       
   527                             if (par) {
       
   528                                 if (par.hasAttribute(DIR)) {
       
   529                                     dir = par.getAttribute(DIR);
       
   530                                 }
       
   531                             }
       
   532                             if (html.indexOf('<br>') > -1) {
       
   533                                 html = html.split(/<br>/i);
       
   534                             } else {
       
   535                                 tmp = inst.Node.create(html);
       
   536                                 ps = tmp ? tmp.all('p') : null;
       
   537 
       
   538                                 if (ps && ps.size()) {
       
   539                                     html = [];
       
   540                                     ps.each(function(n) {
       
   541                                         html.push(n.get('innerHTML'));
       
   542                                     });
       
   543                                 } else {
       
   544                                     html = [html];
       
   545                                 }
       
   546                             }
       
   547                             list = '<' + tag + ' id="ie-list">';
       
   548                             Y.each(html, function(v) {
       
   549                                 var a = inst.Node.create(v);
       
   550                                 if (a && a.test('p')) {
       
   551                                     if (a.hasAttribute(DIR)) {
       
   552                                         dir = a.getAttribute(DIR);
       
   553                                     }
       
   554                                     v = a.get('innerHTML');
       
   555                                 }
       
   556                                 list += '<li>' + v + '</li>';
       
   557                             });
       
   558                             list += '</' + tag + '>';
       
   559                             range.pasteHTML(list);
       
   560                             elm = inst.config.doc.getElementById('ie-list');
       
   561                             elm.id = '';
       
   562                             if (dir) {
       
   563                                 elm.setAttribute(DIR, dir);
       
   564                             }
       
   565                             if (range.moveToElementText) {
       
   566                                 range.moveToElementText(elm);
       
   567                             }
       
   568                             range.select();
       
   569                         }
       
   570                     } else if (Y.UA.ie && Y.UA.ie < 11) {
       
   571                         par = inst.one(sel._selection.parentElement());
       
   572                         if (par.test('p')) {
       
   573                             if (par && par.hasAttribute(DIR)) {
       
   574                                 dir = par.getAttribute(DIR);
       
   575                             }
       
   576                             html = Y.EditorSelection.getText(par);
       
   577                             if (html === '') {
       
   578                                 sdir = '';
       
   579                                 if (dir) {
       
   580                                     sdir = ' dir="' + dir + '"';
       
   581                                 }
       
   582                                 list = inst.Node.create(Y.Lang.sub('<{tag}{dir}><li></li></{tag}>', { tag: tag, dir: sdir }));
       
   583                                 par.replace(list);
       
   584                                 sel.selectNode(list.one('li'));
       
   585                             } else {
       
   586                                 this._command(cmd, null);
       
   587                             }
       
   588                         } else {
       
   589                             this._command(cmd, null);
       
   590                         }
       
   591                     } else {
       
   592                         root.all(tag).addClass(cls);
       
   593                         if (sel.anchorNode.test(inst.EditorSelection.BLOCKS)) {
       
   594                             par = sel.anchorNode;
       
   595                         } else {
       
   596                             par = sel.anchorNode.ancestor(inst.EditorSelection.BLOCKS);
       
   597                         }
       
   598                         if (!par) { //No parent, find the first block under the anchorNode
       
   599                             par = sel.anchorNode.one(inst.EditorSelection.BLOCKS);
       
   600                         }
       
   601 
       
   602                         if (par && par.hasAttribute(DIR)) {
       
   603                             dir = par.getAttribute(DIR);
       
   604                         }
       
   605                         if (par && par.test(tag)) {
       
   606                             hasPParent = par.ancestor('p');
       
   607                             html = inst.Node.create('<div/>');
       
   608                             elm = par.all('li');
       
   609                             elm.each(function(h) {
       
   610                                 html.append(self._wrapContent(h.get('innerHTML'), hasPParent));
       
   611                             });
       
   612                             if (dir) {
       
   613                                 if (useP) {
       
   614                                     html.all('p').setAttribute(DIR, dir);
       
   615                                 } else {
       
   616                                     html.setAttribute(DIR, dir);
       
   617                                 }
       
   618                             }
       
   619                             if (useP) {
       
   620                                 html = inst.Node.create(html.get('innerHTML'));
       
   621                             }
       
   622                             fc = html.get('firstChild');
       
   623                             par.replace(html);
       
   624                             sel.selectNode(fc);
       
   625                         } else {
       
   626                             this._command(cmd, null);
       
   627                         }
       
   628                         list = root.all(tag);
       
   629                         if (dir) {
       
   630                             if (list.size()) {
       
   631                                 //Changed to a List
       
   632                                 list.each(function(n) {
       
   633                                     if (!n.hasClass(cls)) {
       
   634                                         n.setAttribute(DIR, dir);
       
   635                                     }
       
   636                                 });
       
   637                             }
       
   638                         }
       
   639 
       
   640                         list.removeClass(cls);
       
   641                     }
       
   642                 },
       
   643                 /**
       
   644                 * Noramlizes alignment for Webkit Browsers
       
   645                 * @method justify
       
   646                 * @static
       
   647                 * @param {String} cmd The command executed: justify (not used)
       
   648                 * @param {String} val The actual command from the justify{center,all,left,right} stubs
       
   649                 */
       
   650                 justify: function(cmd, val) {
       
   651                     if (Y.UA.webkit) {
       
   652                         var inst = this.getInstance(),
       
   653                             sel = new inst.EditorSelection(),
       
   654                             aNode = sel.anchorNode, html,
       
   655                             bgColor = aNode.getStyle('backgroundColor');
       
   656 
       
   657                             this._command(val);
       
   658                             sel = new inst.EditorSelection();
       
   659                             if (sel.anchorNode.test('div')) {
       
   660                                 html = '<span>' + sel.anchorNode.get('innerHTML') + '</span>';
       
   661                                 sel.anchorNode.set('innerHTML', html);
       
   662                                 sel.anchorNode.one('span').setStyle('backgroundColor', bgColor);
       
   663                                 sel.selectNode(sel.anchorNode.one('span'));
       
   664                             }
       
   665                     } else {
       
   666                         this._command(val);
       
   667                     }
       
   668                 },
       
   669                 /**
       
   670                 * Override method for justify
       
   671                 * @method justifycenter
       
   672                 * @static
       
   673                 */
       
   674                 justifycenter: function() {
       
   675                     this.command('justify', 'justifycenter');
       
   676                 },
       
   677                 /**
       
   678                 * Override method for justify
       
   679                 * @method justifyleft
       
   680                 * @static
       
   681                 */
       
   682                 justifyleft: function() {
       
   683                     this.command('justify', 'justifyleft');
       
   684                 },
       
   685                 /**
       
   686                 * Override method for justify
       
   687                 * @method justifyright
       
   688                 * @static
       
   689                 */
       
   690                 justifyright: function() {
       
   691                     this.command('justify', 'justifyright');
       
   692                 },
       
   693                 /**
       
   694                 * Override method for justify
       
   695                 * @method justifyfull
       
   696                 * @static
       
   697                 */
       
   698                 justifyfull: function() {
       
   699                     this.command('justify', 'justifyfull');
       
   700                 }
       
   701             }
       
   702         });
       
   703 
       
   704         if (Y.UA.ie && Y.UA.ie < 11) {
       
   705             ExecCommand.COMMANDS.bold = function() {
       
   706                 fixIETags.call(this, 'bold', 'b', 'FONT-WEIGHT: bold');
       
   707             };
       
   708             ExecCommand.COMMANDS.italic = function() {
       
   709                 fixIETags.call(this, 'italic', 'i', 'FONT-STYLE: italic');
       
   710             };
       
   711             ExecCommand.COMMANDS.underline = function() {
       
   712                 fixIETags.call(this, 'underline', 'u', 'TEXT-DECORATION: underline');
       
   713             };
       
   714         }
       
   715 
       
   716         Y.namespace('Plugin');
       
   717         Y.Plugin.ExecCommand = ExecCommand;
       
   718 
       
   719 
       
   720 
       
   721 }, '@VERSION@', {"requires": ["frame"]});