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