[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/editor-base/ -> editor-base-debug.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('editor-base', function (Y, NAME) {
   9  
  10  
  11      /**
  12       * Base class for Editor. Handles the business logic of Editor, no GUI involved only utility methods and events.
  13       *
  14       *      var editor = new Y.EditorBase({
  15       *          content: 'Foo'
  16       *      });
  17       *      editor.render('#demo');
  18       *
  19       * @class EditorBase
  20       * @extends Base
  21       * @module editor
  22       * @main editor
  23       * @submodule editor-base
  24       * @constructor
  25       */
  26  
  27      var Lang = Y.Lang,
  28  
  29      EditorBase = function() {
  30          EditorBase.superclass.constructor.apply(this, arguments);
  31      }, LAST_CHILD = ':last-child';
  32  
  33      Y.extend(EditorBase, Y.Base, {
  34          /**
  35          * Internal reference to the Y.ContentEditable instance
  36          * @property frame
  37          */
  38          frame: null,
  39  
  40          initializer: function() {
  41              this.publish('nodeChange', {
  42                  emitFacade: true,
  43                  bubbles: true,
  44                  defaultFn: this._defNodeChangeFn
  45              });
  46  
  47              //this.plug(Y.Plugin.EditorPara);
  48          },
  49          destructor: function() {
  50              this.detachAll();
  51          },
  52          /**
  53          * Copy certain styles from one node instance to another (used for new paragraph creation mainly)
  54          * @method copyStyles
  55          * @param {Node} from The Node instance to copy the styles from
  56          * @param {Node} to The Node instance to copy the styles to
  57          */
  58          copyStyles: function(from, to) {
  59              if (from.test('a')) {
  60                  //Don't carry the A styles
  61                  return;
  62              }
  63              var styles = ['color', 'fontSize', 'fontFamily', 'backgroundColor', 'fontStyle' ],
  64                  newStyles = {};
  65  
  66              Y.each(styles, function(v) {
  67                  newStyles[v] = from.getStyle(v);
  68              });
  69              if (from.ancestor('b,strong')) {
  70                  newStyles.fontWeight = 'bold';
  71              }
  72              if (from.ancestor('u')) {
  73                  if (!newStyles.textDecoration) {
  74                      newStyles.textDecoration = 'underline';
  75                  }
  76              }
  77              to.setStyles(newStyles);
  78          },
  79          /**
  80          * Holder for the selection bookmark in IE.
  81          * @property _lastBookmark
  82          * @private
  83          */
  84          _lastBookmark: null,
  85          /**
  86          * Resolves the e.changedNode in the nodeChange event if it comes from the document. If
  87          * the event came from the document, it will get the last child of the last child of the document
  88          * and return that instead.
  89          * @method _resolveChangedNode
  90          * @param {Node} n The node to resolve
  91          * @private
  92          */
  93          _resolveChangedNode: function(n) {
  94              var inst = this.getInstance(), lc, lc2, found, root = this._getRoot(), sel;
  95  
  96              if (n && n.compareTo(root)) {
  97                  sel = new inst.EditorSelection();
  98                  if (sel && sel.anchorNode) {
  99                      n = sel.anchorNode;
 100                  }
 101              }
 102              if (inst && n && n.test('html')) {
 103                  lc = root.one(LAST_CHILD);
 104                  while (!found) {
 105                      if (lc) {
 106                          lc2 = lc.one(LAST_CHILD);
 107                          if (lc2) {
 108                              lc = lc2;
 109                          } else {
 110                              found = true;
 111                          }
 112                      } else {
 113                          found = true;
 114                      }
 115                  }
 116                  if (lc) {
 117                      if (lc.test('br')) {
 118                          if (lc.previous()) {
 119                              lc = lc.previous();
 120                          } else {
 121                              lc = lc.get('parentNode');
 122                          }
 123                      }
 124                      if (lc) {
 125                          n = lc;
 126                      }
 127                  }
 128              }
 129              if (!n) {
 130                  //Fallback to make sure a node is attached to the event
 131                  n = root;
 132              }
 133              return n;
 134          },
 135          /**
 136          * Resolves the ROOT editor element.
 137          * @method _getRoot
 138          * @private
 139          */
 140          _getRoot: function() {
 141              return this.getInstance().EditorSelection.ROOT;
 142          },
 143          /**
 144          * The default handler for the nodeChange event.
 145          * @method _defNodeChangeFn
 146          * @param {Event} e The event
 147          * @private
 148          */
 149          _defNodeChangeFn: function(e) {
 150              var startTime = (new Date()).getTime(),
 151                  inst = this.getInstance(), sel,
 152                  changed, endTime,
 153                  cmds = {}, family, fsize, classes = [],
 154                  fColor = '', bColor = '', bq,
 155                  normal = false,
 156                  root = this._getRoot();
 157  
 158              if (Y.UA.ie && Y.UA.ie < 11) {
 159                  try {
 160                      sel = inst.config.doc.selection.createRange();
 161                      if (sel.getBookmark) {
 162                          this._lastBookmark = sel.getBookmark();
 163                      }
 164                  } catch (ie) {}
 165              }
 166  
 167              e.changedNode = this._resolveChangedNode(e.changedNode);
 168  
 169  
 170              /*
 171              * @TODO
 172              * This whole method needs to be fixed and made more dynamic.
 173              * Maybe static functions for the e.changeType and an object bag
 174              * to walk through and filter to pass off the event to before firing..
 175              */
 176  
 177              switch (e.changedType) {
 178                  case 'tab':
 179                      if (!e.changedNode.test('li, li *') && !e.changedEvent.shiftKey) {
 180                          e.changedEvent.frameEvent.preventDefault();
 181                          Y.log('Overriding TAB key to insert HTML: HALTING', 'info', 'editor');
 182                          if (Y.UA.webkit) {
 183                              this.execCommand('inserttext', '\t');
 184                          } else if (Y.UA.gecko) {
 185                              this.frame.exec._command('inserthtml', EditorBase.TABKEY);
 186                          } else if (Y.UA.ie) {
 187                              this.execCommand('inserthtml', EditorBase.TABKEY);
 188                          }
 189                      }
 190                      break;
 191                  case 'backspace-up':
 192                      // Fixes #2531090 - Joins text node strings so they become one for bidi
 193                      if (Y.UA.webkit && e.changedNode) {
 194                          e.changedNode.set('innerHTML', e.changedNode.get('innerHTML'));
 195                      }
 196                      break;
 197              }
 198              if (Y.UA.webkit && e.commands && (e.commands.indent || e.commands.outdent)) {
 199                  /*
 200                  * When executing execCommand 'indent or 'outdent' Webkit applies
 201                  * a class to the BLOCKQUOTE that adds left/right margin to it
 202                  * This strips that style so it is just a normal BLOCKQUOTE
 203                  */
 204                  bq = root.all('.webkit-indent-blockquote, blockquote');
 205                  if (bq.size()) {
 206                      bq.setStyle('margin', '');
 207                  }
 208              }
 209  
 210              changed = this.getDomPath(e.changedNode, false);
 211  
 212              if (e.commands) {
 213                  cmds = e.commands;
 214              }
 215  
 216  
 217              Y.each(changed, function(el) {
 218                  var tag = el.tagName.toLowerCase(),
 219                      cmd = EditorBase.TAG2CMD[tag], s,
 220                      n, family2, cls, bColor2;
 221  
 222                  if (cmd) {
 223                      cmds[cmd] = 1;
 224                  }
 225  
 226                  //Bold and Italic styles
 227                  s = el.currentStyle || el.style;
 228  
 229                  if ((''+s.fontWeight) === 'normal') {
 230                      normal = true;
 231                  }
 232                  if ((''+s.fontWeight) === 'bold') { //Cast this to a string
 233                      cmds.bold = 1;
 234                  }
 235                  if (Y.UA.ie) {
 236                      if (s.fontWeight > 400) {
 237                          cmds.bold = 1;
 238                      }
 239                  }
 240                  if (s.fontStyle === 'italic') {
 241                      cmds.italic = 1;
 242                  }
 243  
 244                  if (s.textDecoration.indexOf('underline') > -1) {
 245                      cmds.underline = 1;
 246                  }
 247                  if (s.textDecoration.indexOf('line-through') > -1) {
 248                      cmds.strikethrough = 1;
 249                  }
 250  
 251                  n = inst.one(el);
 252                  if (n.getStyle('fontFamily')) {
 253                      family2 = n.getStyle('fontFamily').split(',')[0].toLowerCase();
 254                      if (family2) {
 255                          family = family2;
 256                      }
 257                      if (family) {
 258                          family = family.replace(/'/g, '').replace(/"/g, '');
 259                      }
 260                  }
 261  
 262                  fsize = EditorBase.NORMALIZE_FONTSIZE(n);
 263  
 264  
 265                  cls = el.className.split(' ');
 266                  Y.each(cls, function(v) {
 267                      if (v !== '' && (v.substr(0, 4) !== 'yui_')) {
 268                          classes.push(v);
 269                      }
 270                  });
 271  
 272                  fColor = EditorBase.FILTER_RGB(n.getStyle('color'));
 273                  bColor2 = EditorBase.FILTER_RGB(s.backgroundColor);
 274                  if (bColor2 !== 'transparent') {
 275                      if (bColor2 !== '') {
 276                          bColor = bColor2;
 277                      }
 278                  }
 279  
 280              });
 281  
 282              if (normal) {
 283                  delete cmds.bold;
 284                  delete cmds.italic;
 285              }
 286  
 287              e.dompath = inst.all(changed);
 288              e.classNames = classes;
 289              e.commands = cmds;
 290  
 291              //TODO Dont' like this, not dynamic enough..
 292              if (!e.fontFamily) {
 293                  e.fontFamily = family;
 294              }
 295              if (!e.fontSize) {
 296                  e.fontSize = fsize;
 297              }
 298              if (!e.fontColor) {
 299                  e.fontColor = fColor;
 300              }
 301              if (!e.backgroundColor) {
 302                  e.backgroundColor = bColor;
 303              }
 304  
 305              endTime = (new Date()).getTime();
 306              Y.log('_defNodeChangeTimer 2: ' + (endTime - startTime) + 'ms', 'info', 'selection');
 307          },
 308          /**
 309          * Walk the dom tree from this node up to body, returning a reversed array of parents.
 310          * @method getDomPath
 311          * @param {Node} node The Node to start from
 312          */
 313          getDomPath: function(node, nodeList) {
 314              var domPath = [], domNode, rootNode,
 315                  root = this._getRoot(),
 316                  inst = this.frame.getInstance();
 317  
 318              domNode = inst.Node.getDOMNode(node);
 319              rootNode = inst.Node.getDOMNode(root);
 320              //return inst.all(domNode);
 321  
 322              while (domNode !== null) {
 323  
 324                  if ((domNode === inst.config.doc.documentElement) || (domNode === inst.config.doc) || !domNode.tagName) {
 325                      domNode = null;
 326                      break;
 327                  }
 328  
 329                  if (!inst.DOM.inDoc(domNode)) {
 330                      domNode = null;
 331                      break;
 332                  }
 333  
 334                  //Check to see if we get el.nodeName and nodeType
 335                  if (domNode.nodeName && domNode.nodeType && (domNode.nodeType === 1)) {
 336                      domPath.push(domNode);
 337                  }
 338  
 339                  if (domNode === rootNode) {
 340                      domNode = null;
 341                      break;
 342                  }
 343  
 344                  domNode = domNode.parentNode;
 345              }
 346  
 347              /*{{{ Using Node
 348              while (node !== null) {
 349                  if (node.test('html') || node.test('doc') || !node.get('tagName')) {
 350                      node = null;
 351                      break;
 352                  }
 353                  if (!node.inDoc()) {
 354                      node = null;
 355                      break;
 356                  }
 357                  //Check to see if we get el.nodeName and nodeType
 358                  if (node.get('nodeName') && node.get('nodeType') && (node.get('nodeType') == 1)) {
 359                      domPath.push(inst.Node.getDOMNode(node));
 360                  }
 361  
 362                  if (node.test('body')) {
 363                      node = null;
 364                      break;
 365                  }
 366  
 367                  node = node.get('parentNode');
 368              }
 369              }}}*/
 370  
 371              if (domPath.length === 0) {
 372                  domPath[0] = inst.config.doc.body;
 373              }
 374  
 375              if (nodeList) {
 376                  return inst.all(domPath.reverse());
 377              } else {
 378                  return domPath.reverse();
 379              }
 380  
 381          },
 382          /**
 383          * After frame ready, bind mousedown & keyup listeners
 384          * @method _afterFrameReady
 385          * @private
 386          */
 387          _afterFrameReady: function() {
 388              var inst = this.frame.getInstance();
 389  
 390              this.frame.on('dom:mouseup', Y.bind(this._onFrameMouseUp, this));
 391              this.frame.on('dom:mousedown', Y.bind(this._onFrameMouseDown, this));
 392              this.frame.on('dom:keydown', Y.bind(this._onFrameKeyDown, this));
 393  
 394              if (Y.UA.ie && Y.UA.ie < 11) {
 395                  this.frame.on('dom:activate', Y.bind(this._onFrameActivate, this));
 396                  this.frame.on('dom:beforedeactivate', Y.bind(this._beforeFrameDeactivate, this));
 397              }
 398              this.frame.on('dom:keyup', Y.bind(this._onFrameKeyUp, this));
 399              this.frame.on('dom:keypress', Y.bind(this._onFrameKeyPress, this));
 400              this.frame.on('dom:paste', Y.bind(this._onPaste, this));
 401  
 402              inst.EditorSelection.filter();
 403              this.fire('ready');
 404          },
 405          /**
 406          * Caches the current cursor position in IE.
 407          * @method _beforeFrameDeactivate
 408          * @private
 409          */
 410          _beforeFrameDeactivate: function(e) {
 411              if (e.frameTarget.test('html')) { //Means it came from a scrollbar
 412                  return;
 413              }
 414              var inst = this.getInstance(),
 415                  sel = inst.config.doc.selection.createRange();
 416  
 417              if (sel.compareEndPoints && !sel.compareEndPoints('StartToEnd', sel)) {
 418                  sel.pasteHTML('<var id="yui-ie-cursor">');
 419              }
 420          },
 421          /**
 422          * Moves the cached selection bookmark back so IE can place the cursor in the right place.
 423          * @method _onFrameActivate
 424          * @private
 425          */
 426          _onFrameActivate: function(e) {
 427              if (e.frameTarget.test('html')) { //Means it came from a scrollbar
 428                  return;
 429              }
 430              var inst = this.getInstance(),
 431                  sel = new inst.EditorSelection(),
 432                  range = sel.createRange(),
 433                  root = this._getRoot(),
 434                  cur = root.all('#yui-ie-cursor');
 435  
 436              if (cur.size()) {
 437                  cur.each(function(n) {
 438                      n.set('id', '');
 439                      if (range.moveToElementText) {
 440                          try {
 441                              range.moveToElementText(n._node);
 442                              var moved = range.move('character', -1);
 443                              if (moved === -1) { //Only move up if we actually moved back.
 444                                  range.move('character', 1);
 445                              }
 446                              range.select();
 447                              range.text = '';
 448                          } catch (e) {}
 449                      }
 450                      n.remove();
 451                  });
 452              }
 453          },
 454          /**
 455          * Fires nodeChange event
 456          * @method _onPaste
 457          * @private
 458          */
 459          _onPaste: function(e) {
 460              this.fire('nodeChange', { changedNode: e.frameTarget, changedType: 'paste', changedEvent: e.frameEvent });
 461          },
 462          /**
 463          * Fires nodeChange event
 464          * @method _onFrameMouseUp
 465          * @private
 466          */
 467          _onFrameMouseUp: function(e) {
 468              this.fire('nodeChange', { changedNode: e.frameTarget, changedType: 'mouseup', changedEvent: e.frameEvent  });
 469          },
 470          /**
 471          * Fires nodeChange event
 472          * @method _onFrameMouseDown
 473          * @private
 474          */
 475          _onFrameMouseDown: function(e) {
 476              this.fire('nodeChange', { changedNode: e.frameTarget, changedType: 'mousedown', changedEvent: e.frameEvent  });
 477          },
 478          /**
 479          * Caches a copy of the selection for key events. Only creating the selection on keydown
 480          * @property _currentSelection
 481          * @private
 482          */
 483          _currentSelection: null,
 484          /**
 485          * Holds the timer for selection clearing
 486          * @property _currentSelectionTimer
 487          * @private
 488          */
 489          _currentSelectionTimer: null,
 490          /**
 491          * Flag to determine if we can clear the selection or not.
 492          * @property _currentSelectionClear
 493          * @private
 494          */
 495          _currentSelectionClear: null,
 496          /**
 497          * Fires nodeChange event
 498          * @method _onFrameKeyDown
 499          * @private
 500          */
 501          _onFrameKeyDown: function(e) {
 502              var inst, sel;
 503              if (!this._currentSelection) {
 504                  if (this._currentSelectionTimer) {
 505                      this._currentSelectionTimer.cancel();
 506                  }
 507                  this._currentSelectionTimer = Y.later(850, this, function() {
 508                      this._currentSelectionClear = true;
 509                  });
 510  
 511                  inst = this.frame.getInstance();
 512                  sel = new inst.EditorSelection(e);
 513  
 514                  this._currentSelection = sel;
 515              } else {
 516                  sel = this._currentSelection;
 517              }
 518  
 519              inst = this.frame.getInstance();
 520              sel = new inst.EditorSelection();
 521  
 522              this._currentSelection = sel;
 523  
 524              if (sel && sel.anchorNode) {
 525                  this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: 'keydown', changedEvent: e.frameEvent });
 526                  if (EditorBase.NC_KEYS[e.keyCode]) {
 527                      this.fire('nodeChange', {
 528                          changedNode: sel.anchorNode,
 529                          changedType: EditorBase.NC_KEYS[e.keyCode],
 530                          changedEvent: e.frameEvent
 531                      });
 532                      this.fire('nodeChange', {
 533                          changedNode: sel.anchorNode,
 534                          changedType: EditorBase.NC_KEYS[e.keyCode] + '-down',
 535                          changedEvent: e.frameEvent
 536                      });
 537                  }
 538              }
 539          },
 540          /**
 541          * Fires nodeChange event
 542          * @method _onFrameKeyPress
 543          * @private
 544          */
 545          _onFrameKeyPress: function(e) {
 546              var sel = this._currentSelection;
 547  
 548              if (sel && sel.anchorNode) {
 549                  this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: 'keypress', changedEvent: e.frameEvent });
 550                  if (EditorBase.NC_KEYS[e.keyCode]) {
 551                      this.fire('nodeChange', {
 552                          changedNode: sel.anchorNode,
 553                          changedType: EditorBase.NC_KEYS[e.keyCode] + '-press',
 554                          changedEvent: e.frameEvent
 555                      });
 556                  }
 557              }
 558          },
 559          /**
 560          * Fires nodeChange event for keyup on specific keys
 561          * @method _onFrameKeyUp
 562          * @private
 563          */
 564          _onFrameKeyUp: function(e) {
 565              var inst = this.frame.getInstance(),
 566                  sel = new inst.EditorSelection(e);
 567  
 568              if (sel && sel.anchorNode) {
 569                  this.fire('nodeChange', { changedNode: sel.anchorNode, changedType: 'keyup', selection: sel, changedEvent: e.frameEvent  });
 570                  if (EditorBase.NC_KEYS[e.keyCode]) {
 571                      this.fire('nodeChange', {
 572                          changedNode: sel.anchorNode,
 573                          changedType: EditorBase.NC_KEYS[e.keyCode] + '-up',
 574                          selection: sel,
 575                          changedEvent: e.frameEvent
 576                      });
 577                  }
 578              }
 579              if (this._currentSelectionClear) {
 580                  this._currentSelectionClear = this._currentSelection = null;
 581              }
 582          },
 583          /**
 584          * Validates linkedcss property
 585          *
 586          * @method _validateLinkedCSS
 587          * @private
 588          */
 589          _validateLinkedCSS: function(value) {
 590              return Lang.isString(value) || Lang.isArray(value);
 591          },
 592          /**
 593          * Pass through to the frame.execCommand method
 594          * @method execCommand
 595          * @param {String} cmd The command to pass: inserthtml, insertimage, bold
 596          * @param {String} val The optional value of the command: Helvetica
 597          * @return {Node/NodeList} The Node or Nodelist affected by the command. Only returns on override commands, not browser defined commands.
 598          */
 599          execCommand: function(cmd, val) {
 600              var ret = this.frame.execCommand(cmd, val),
 601                  inst = this.frame.getInstance(),
 602                  sel = new inst.EditorSelection(), cmds = {},
 603                  e = { changedNode: sel.anchorNode, changedType: 'execcommand', nodes: ret };
 604  
 605              switch (cmd) {
 606                  case 'forecolor':
 607                      e.fontColor = val;
 608                      break;
 609                  case 'backcolor':
 610                      e.backgroundColor = val;
 611                      break;
 612                  case 'fontsize':
 613                      e.fontSize = val;
 614                      break;
 615                  case 'fontname':
 616                      e.fontFamily = val;
 617                      break;
 618              }
 619  
 620              cmds[cmd] = 1;
 621              e.commands = cmds;
 622  
 623              this.fire('nodeChange', e);
 624  
 625              return ret;
 626          },
 627          /**
 628          * Get the YUI instance of the frame
 629          * @method getInstance
 630          * @return {YUI} The YUI instance bound to the frame.
 631          */
 632          getInstance: function() {
 633              return this.frame.getInstance();
 634          },
 635          /**
 636          * Renders the Y.ContentEditable to the passed node.
 637          * @method render
 638          * @param {Selector/HTMLElement/Node} node The node to append the Editor to
 639          * @return {EditorBase}
 640          * @chainable
 641          */
 642          render: function(node) {
 643              var frame = this.frame;
 644  
 645              if (!frame) {
 646                  this.plug(Y.Plugin.Frame, {
 647                      designMode: true,
 648                      title: EditorBase.STRINGS.title,
 649                      use: EditorBase.USE,
 650                      dir: this.get('dir'),
 651                      extracss: this.get('extracss'),
 652                      linkedcss: this.get('linkedcss'),
 653                      defaultblock: this.get('defaultblock')
 654                  });
 655  
 656                  frame = this.frame;
 657              }
 658  
 659              if (!frame.hasPlugin('exec')) {
 660                  frame.plug(Y.Plugin.ExecCommand);
 661              }
 662  
 663              frame.after('ready', Y.bind(this._afterFrameReady, this));
 664  
 665              frame.addTarget(this);
 666  
 667              frame.set('content', this.get('content'));
 668  
 669              frame.render(node);
 670  
 671              return this;
 672          },
 673          /**
 674          * Focus the contentWindow of the iframe
 675          * @method focus
 676          * @param {Function} fn Callback function to execute after focus happens
 677          * @return {EditorBase}
 678          * @chainable
 679          */
 680          focus: function(fn) {
 681              this.frame.focus(fn);
 682              return this;
 683          },
 684          /**
 685          * Handles the showing of the Editor instance. Currently only handles the iframe
 686          * @method show
 687          * @return {EditorBase}
 688          * @chainable
 689          */
 690          show: function() {
 691              this.frame.show();
 692              return this;
 693          },
 694          /**
 695          * Handles the hiding of the Editor instance. Currently only handles the iframe
 696          * @method hide
 697          * @return {EditorBase}
 698          * @chainable
 699          */
 700          hide: function() {
 701              this.frame.hide();
 702              return this;
 703          },
 704          /**
 705          * (Un)Filters the content of the Editor, cleaning YUI related code. //TODO better filtering
 706          * @method getContent
 707          * @return {String} The filtered content of the Editor
 708          */
 709          getContent: function() {
 710              var html = '', inst = this.getInstance();
 711              if (inst && inst.EditorSelection) {
 712                  html = inst.EditorSelection.unfilter();
 713              }
 714              //Removing the _yuid from the objects in IE
 715              html = html.replace(/ _yuid="([^>]*)"/g, '');
 716              return html;
 717          }
 718      }, {
 719          /**
 720          * @static
 721          * @method NORMALIZE_FONTSIZE
 722          * @description Pulls the fontSize from a node, then checks for string values (x-large, x-small)
 723          * and converts them to pixel sizes. If the parsed size is different from the original, it calls
 724          * node.setStyle to update the node with a pixel size for normalization.
 725          */
 726          NORMALIZE_FONTSIZE: function(n) {
 727              var size = n.getStyle('fontSize'), oSize = size;
 728  
 729              switch (size) {
 730                  case '-webkit-xxx-large':
 731                      size = '48px';
 732                      break;
 733                  case 'xx-large':
 734                      size = '32px';
 735                      break;
 736                  case 'x-large':
 737                      size = '24px';
 738                      break;
 739                  case 'large':
 740                      size = '18px';
 741                      break;
 742                  case 'medium':
 743                      size = '16px';
 744                      break;
 745                  case 'small':
 746                      size = '13px';
 747                      break;
 748                  case 'x-small':
 749                      size = '10px';
 750                      break;
 751              }
 752              if (oSize !== size) {
 753                  n.setStyle('fontSize', size);
 754              }
 755              return size;
 756          },
 757          /**
 758          * @static
 759          * @property TABKEY
 760          * @description The HTML markup to use for the tabkey
 761          */
 762          TABKEY: '<span class="tab">&nbsp;&nbsp;&nbsp;&nbsp;</span>',
 763          /**
 764          * @static
 765          * @method FILTER_RGB
 766          * @param String css The CSS string containing rgb(#,#,#);
 767          * @description Converts an RGB color string to a hex color, example: rgb(0, 255, 0) converts to #00ff00
 768          * @return String
 769          */
 770          FILTER_RGB: function(css) {
 771              if (css.toLowerCase().indexOf('rgb') !== -1) {
 772                  var exp = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi"),
 773                      rgb = css.replace(exp, "$1,$2,$3,$4,$5").split(','),
 774                      r, g, b;
 775  
 776                  if (rgb.length === 5) {
 777                      r = parseInt(rgb[1], 10).toString(16);
 778                      g = parseInt(rgb[2], 10).toString(16);
 779                      b = parseInt(rgb[3], 10).toString(16);
 780  
 781                      r = r.length === 1 ? '0' + r : r;
 782                      g = g.length === 1 ? '0' + g : g;
 783                      b = b.length === 1 ? '0' + b : b;
 784  
 785                      css = "#" + r + g + b;
 786                  }
 787              }
 788              return css;
 789          },
 790          /**
 791          * @static
 792          * @property TAG2CMD
 793          * @description A hash table of tags to their execcomand's
 794          */
 795          TAG2CMD: {
 796              'b': 'bold',
 797              'strong': 'bold',
 798              'i': 'italic',
 799              'em': 'italic',
 800              'u': 'underline',
 801              'sup': 'superscript',
 802              'sub': 'subscript',
 803              'img': 'insertimage',
 804              'a' : 'createlink',
 805              'ul' : 'insertunorderedlist',
 806              'ol' : 'insertorderedlist'
 807          },
 808          /**
 809          * Hash table of keys to fire a nodeChange event for.
 810          * @static
 811          * @property NC_KEYS
 812          * @type Object
 813          */
 814          NC_KEYS: {
 815              8: 'backspace',
 816              9: 'tab',
 817              13: 'enter',
 818              32: 'space',
 819              33: 'pageup',
 820              34: 'pagedown',
 821              35: 'end',
 822              36: 'home',
 823              37: 'left',
 824              38: 'up',
 825              39: 'right',
 826              40: 'down',
 827              46: 'delete'
 828          },
 829          /**
 830          * The default modules to use inside the Frame
 831          * @static
 832          * @property USE
 833          * @type Array
 834          */
 835          USE: ['node', 'selector-css3', 'editor-selection', 'stylesheet'],
 836          /**
 837          * The Class Name: editorBase
 838          * @static
 839          * @property NAME
 840          */
 841          NAME: 'editorBase',
 842          /**
 843          * Editor Strings.  By default contains only the `title` property for the
 844          * Title of frame document (default "Rich Text Editor").
 845          *
 846          * @static
 847          * @property STRINGS
 848          */
 849          STRINGS: {
 850              title: 'Rich Text Editor'
 851          },
 852          ATTRS: {
 853              /**
 854              * The content to load into the Editor Frame
 855              * @attribute content
 856              */
 857              content: {
 858                  validator: Lang.isString,
 859                  value: '<br class="yui-cursor">',
 860                  setter: function(str) {
 861                      if (str.substr(0, 1) === "\n") {
 862                          Y.log('Stripping first carriage return from content before injecting', 'warn', 'editor');
 863                          str = str.substr(1);
 864                      }
 865                      if (str === '') {
 866                          str = '<br class="yui-cursor">';
 867                      }
 868                      if (str === ' ') {
 869                          if (Y.UA.gecko) {
 870                              str = '<br class="yui-cursor">';
 871                          }
 872                      }
 873                      return this.frame.set('content', str);
 874                  },
 875                  getter: function() {
 876                      return this.frame.get('content');
 877                  }
 878              },
 879              /**
 880              * The value of the dir attribute on the HTML element of the frame. Default: ltr
 881              * @attribute dir
 882              */
 883              dir: {
 884                  validator: Lang.isString,
 885                  writeOnce: true,
 886                  value: 'ltr'
 887              },
 888              /**
 889              * @attribute linkedcss
 890              * @description An array of url's to external linked style sheets
 891              * @type String|Array
 892              */
 893              linkedcss: {
 894                  validator: '_validateLinkedCSS',
 895                  value: '',
 896                  setter: function(css) {
 897                      if (this.frame) {
 898                          this.frame.set('linkedcss', css);
 899                      }
 900                      return css;
 901                  }
 902              },
 903              /**
 904              * @attribute extracss
 905              * @description A string of CSS to add to the Head of the Editor
 906              * @type String
 907              */
 908              extracss: {
 909                  validator: Lang.isString,
 910                  value: '',
 911                  setter: function(css) {
 912                      if (this.frame) {
 913                          this.frame.set('extracss', css);
 914                      }
 915                      return css;
 916                  }
 917              },
 918              /**
 919              * @attribute defaultblock
 920              * @description The default tag to use for block level items, defaults to: p
 921              * @type String
 922              */
 923              defaultblock: {
 924                  validator: Lang.isString,
 925                  value: 'p'
 926              }
 927          }
 928      });
 929  
 930      Y.EditorBase = EditorBase;
 931  
 932      /**
 933      * @event nodeChange
 934      * @description Fired from several mouse/key/paste event points.
 935      * @param {EventFacade} event An Event Facade object with the following specific properties added:
 936      * <dl>
 937      *   <dt>changedEvent</dt><dd>The event that caused the nodeChange</dd>
 938      *   <dt>changedNode</dt><dd>The node that was interacted with</dd>
 939      *   <dt>changedType</dt><dd>The type of change: mousedown, mouseup, right, left, backspace, tab, enter, etc..</dd>
 940      *   <dt>commands</dt><dd>The list of execCommands that belong to this change and the dompath that's associated with the changedNode</dd>
 941      *   <dt>classNames</dt><dd>An array of classNames that are applied to the changedNode and all of it's parents</dd>
 942      *   <dt>dompath</dt><dd>A sorted array of node instances that make up the DOM path from the changedNode to body.</dd>
 943      *   <dt>backgroundColor</dt><dd>The cascaded backgroundColor of the changedNode</dd>
 944      *   <dt>fontColor</dt><dd>The cascaded fontColor of the changedNode</dd>
 945      *   <dt>fontFamily</dt><dd>The cascaded fontFamily of the changedNode</dd>
 946      *   <dt>fontSize</dt><dd>The cascaded fontSize of the changedNode</dd>
 947      * </dl>
 948      */
 949  
 950      /**
 951      * @event ready
 952      * @description Fired after the frame is ready.
 953      * @param {EventFacade} event An Event Facade object.
 954      */
 955  
 956  
 957  
 958  
 959  
 960  }, '3.17.2', {"requires": ["base", "frame", "node", "exec-command", "editor-selection"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1