src/cm/media/js/lib/yui/yui3-3.15.0/build/content-editable/content-editable.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('content-editable', function (Y, NAME) {
       
     2 
       
     3     /*jshint maxlen: 500 */
       
     4     /**
       
     5     * Creates a component to work with an elemment.
       
     6     * @class ContentEditable
       
     7     * @for ContentEditable
       
     8     * @extends Y.Plugin.Base
       
     9     * @constructor
       
    10     * @module editor
       
    11     * @submodule content-editable
       
    12     */
       
    13 
       
    14     var Lang = Y.Lang,
       
    15         YNode = Y.Node,
       
    16 
       
    17         EVENT_CONTENT_READY = 'contentready',
       
    18         EVENT_READY = 'ready',
       
    19 
       
    20         TAG_PARAGRAPH = 'p',
       
    21 
       
    22         BLUR = 'blur',
       
    23         CONTAINER = 'container',
       
    24         CONTENT_EDITABLE = 'contentEditable',
       
    25         EMPTY = '',
       
    26         FOCUS = 'focus',
       
    27         HOST = 'host',
       
    28         INNER_HTML = 'innerHTML',
       
    29         KEY = 'key',
       
    30         PARENT_NODE = 'parentNode',
       
    31         PASTE = 'paste',
       
    32         TEXT = 'Text',
       
    33         USE = 'use',
       
    34 
       
    35     ContentEditable = function() {
       
    36         ContentEditable.superclass.constructor.apply(this, arguments);
       
    37     };
       
    38 
       
    39     Y.extend(ContentEditable, Y.Plugin.Base, {
       
    40 
       
    41         /**
       
    42         * Internal reference set when render is called.
       
    43         * @private
       
    44         * @property _rendered
       
    45         * @type Boolean
       
    46         */
       
    47         _rendered: null,
       
    48 
       
    49         /**
       
    50         * Internal reference to the YUI instance bound to the element
       
    51         * @private
       
    52         * @property _instance
       
    53         * @type YUI
       
    54         */
       
    55         _instance: null,
       
    56 
       
    57         /**
       
    58         * Initializes the ContentEditable instance
       
    59         * @protected
       
    60         * @method initializer
       
    61         */
       
    62         initializer: function() {
       
    63             var host = this.get(HOST);
       
    64 
       
    65             if (host) {
       
    66                 host.frame = this;
       
    67             }
       
    68 
       
    69             this._eventHandles = [];
       
    70 
       
    71             this.publish(EVENT_READY, {
       
    72                 emitFacade: true,
       
    73                 defaultFn: this._defReadyFn
       
    74             });
       
    75         },
       
    76 
       
    77         /**
       
    78         * Destroys the instance.
       
    79         * @protected
       
    80         * @method destructor
       
    81         */
       
    82         destructor: function() {
       
    83             new Y.EventHandle(this._eventHandles).detach();
       
    84 
       
    85             this._container.removeAttribute(CONTENT_EDITABLE);
       
    86         },
       
    87 
       
    88         /**
       
    89         * Generic handler for all DOM events fired by the Editor container. This handler
       
    90         * takes the current EventFacade and augments it to fire on the ContentEditable host. It adds two new properties
       
    91         * to the EventFacade called frameX and frameY which adds the scroll and xy position of the ContentEditable element
       
    92         * to the original pageX and pageY of the event so external nodes can be positioned over the element.
       
    93         * In case of ContentEditable element these will be equal to pageX and pageY of the container.
       
    94         * @private
       
    95         * @method _onDomEvent
       
    96         * @param {EventFacade} e
       
    97         */
       
    98         _onDomEvent: function(e) {
       
    99             var xy;
       
   100 
       
   101             e.frameX = e.frameY = 0;
       
   102 
       
   103             if (e.pageX > 0 || e.pageY > 0) {
       
   104                 if (e.type.substring(0, 3) !== KEY) {
       
   105                     xy = this._container.getXY();
       
   106 
       
   107                     e.frameX = xy[0];
       
   108                     e.frameY = xy[1];
       
   109                 }
       
   110             }
       
   111 
       
   112             e.frameTarget = e.target;
       
   113             e.frameCurrentTarget = e.currentTarget;
       
   114             e.frameEvent = e;
       
   115 
       
   116             this.fire('dom:' + e.type, e);
       
   117         },
       
   118 
       
   119         /**
       
   120         * Simple pass thru handler for the paste event so we can do content cleanup
       
   121         * @private
       
   122         * @method _DOMPaste
       
   123         * @param {EventFacade} e
       
   124         */
       
   125         _DOMPaste: function(e) {
       
   126             var inst = this.getInstance(),
       
   127                 data = EMPTY, win = inst.config.win;
       
   128 
       
   129             if (e._event.originalTarget) {
       
   130                 data = e._event.originalTarget;
       
   131             }
       
   132 
       
   133             if (e._event.clipboardData) {
       
   134                 data = e._event.clipboardData.getData(TEXT);
       
   135             }
       
   136 
       
   137             if (win.clipboardData) {
       
   138                 data = win.clipboardData.getData(TEXT);
       
   139 
       
   140                 if (data === EMPTY) { // Could be empty, or failed
       
   141                     // Verify failure
       
   142                     if (!win.clipboardData.setData(TEXT, data)) {
       
   143                         data = null;
       
   144                     }
       
   145                 }
       
   146             }
       
   147 
       
   148             e.frameTarget = e.target;
       
   149             e.frameCurrentTarget = e.currentTarget;
       
   150             e.frameEvent = e;
       
   151 
       
   152             if (data) {
       
   153                 e.clipboardData = {
       
   154                     data: data,
       
   155                     getData: function() {
       
   156                         return data;
       
   157                     }
       
   158                 };
       
   159             } else {
       
   160 
       
   161                 e.clipboardData = null;
       
   162             }
       
   163 
       
   164             this.fire('dom:paste', e);
       
   165         },
       
   166 
       
   167         /**
       
   168         * Binds DOM events and fires the ready event
       
   169         * @private
       
   170         * @method _defReadyFn
       
   171         */
       
   172         _defReadyFn: function() {
       
   173             var inst = this.getInstance(),
       
   174                 container = this.get(CONTAINER);
       
   175 
       
   176             Y.each(
       
   177                 ContentEditable.DOM_EVENTS,
       
   178                 function(value, key) {
       
   179                     var fn = Y.bind(this._onDomEvent, this),
       
   180                         kfn = ((Y.UA.ie && ContentEditable.THROTTLE_TIME > 0) ? Y.throttle(fn, ContentEditable.THROTTLE_TIME) : fn);
       
   181 
       
   182                     if (!inst.Node.DOM_EVENTS[key]) {
       
   183                         inst.Node.DOM_EVENTS[key] = 1;
       
   184                     }
       
   185 
       
   186                     if (value === 1) {
       
   187                         if (key !== FOCUS && key !== BLUR && key !== PASTE) {
       
   188                             if (key.substring(0, 3) === KEY) {
       
   189                                 //Throttle key events in IE
       
   190                                 this._eventHandles.push(container.on(key, kfn, container));
       
   191                             } else {
       
   192                                 this._eventHandles.push(container.on(key, fn, container));
       
   193                             }
       
   194                         }
       
   195                     }
       
   196                 },
       
   197                 this
       
   198             );
       
   199 
       
   200             inst.Node.DOM_EVENTS.paste = 1;
       
   201 
       
   202             this._eventHandles.push(
       
   203                 container.on(PASTE, Y.bind(this._DOMPaste, this), container),
       
   204                 container.on(FOCUS, Y.bind(this._onDomEvent, this), container),
       
   205                 container.on(BLUR, Y.bind(this._onDomEvent, this), container)
       
   206             );
       
   207 
       
   208             inst.__use = inst.use;
       
   209 
       
   210             inst.use = Y.bind(this.use, this);
       
   211         },
       
   212 
       
   213         /**
       
   214         * Called once the content is available in the ContentEditable element and calls the final use call
       
   215         * @private
       
   216         * @method _onContentReady
       
   217         * on the internal instance so that the modules are loaded properly.
       
   218         */
       
   219         _onContentReady: function(event) {
       
   220             if (!this._ready) {
       
   221                 this._ready = true;
       
   222 
       
   223                 var inst = this.getInstance(),
       
   224                     args = Y.clone(this.get(USE));
       
   225 
       
   226                 this.fire(EVENT_CONTENT_READY);
       
   227 
       
   228 
       
   229                 if (event) {
       
   230                     inst.config.doc = YNode.getDOMNode(event.target);
       
   231                 }
       
   232 
       
   233                 args.push(Y.bind(function() {
       
   234 
       
   235                     if (inst.EditorSelection) {
       
   236                         inst.EditorSelection.DEFAULT_BLOCK_TAG = this.get('defaultblock');
       
   237 
       
   238                         inst.EditorSelection.ROOT = this.get(CONTAINER);
       
   239                     }
       
   240 
       
   241                     this.fire(EVENT_READY);
       
   242                 }, this));
       
   243 
       
   244 
       
   245                 inst.use.apply(inst, args);
       
   246             }
       
   247         },
       
   248 
       
   249         /**
       
   250         * Retrieves defaultblock value from host attribute
       
   251         * @private
       
   252         * @method _getDefaultBlock
       
   253         * @return {String}
       
   254         */
       
   255         _getDefaultBlock: function() {
       
   256             return this._getHostValue('defaultblock');
       
   257         },
       
   258 
       
   259         /**
       
   260         * Retrieves dir value from host attribute
       
   261         * @private
       
   262         * @method _getDir
       
   263         * @return {String}
       
   264         */
       
   265         _getDir: function() {
       
   266             return this._getHostValue('dir');
       
   267         },
       
   268 
       
   269         /**
       
   270         * Retrieves extracss value from host attribute
       
   271         * @private
       
   272         * @method _getExtraCSS
       
   273         * @return {String}
       
   274         */
       
   275         _getExtraCSS: function() {
       
   276             return this._getHostValue('extracss');
       
   277         },
       
   278 
       
   279         /**
       
   280         * Get the content from the container
       
   281         * @private
       
   282         * @method _getHTML
       
   283         * @param {String} html The raw HTML from the container.
       
   284         * @return {String}
       
   285         */
       
   286         _getHTML: function() {
       
   287             var html, container;
       
   288 
       
   289             if (this._ready) {
       
   290                 container = this.get(CONTAINER);
       
   291 
       
   292                 html = container.get(INNER_HTML);
       
   293             }
       
   294 
       
   295             return html;
       
   296         },
       
   297 
       
   298         /**
       
   299         * Retrieves a value from host attribute
       
   300         * @private
       
   301         * @method _getHostValue
       
   302         * @param {attr} The attribute which value should be returned from the host
       
   303         * @return {String|Object}
       
   304         */
       
   305         _getHostValue: function(attr) {
       
   306             var host = this.get(HOST);
       
   307 
       
   308             if (host) {
       
   309                 return host.get(attr);
       
   310             }
       
   311         },
       
   312 
       
   313         /**
       
   314         * Set the content of the container
       
   315         * @private
       
   316         * @method _setHTML
       
   317         * @param {String} html The raw HTML to set to the container.
       
   318         * @return {String}
       
   319         */
       
   320         _setHTML: function(html) {
       
   321             if (this._ready) {
       
   322                 var container = this.get(CONTAINER);
       
   323 
       
   324                 container.set(INNER_HTML, html);
       
   325             } else {
       
   326                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   327                 this.once(EVENT_CONTENT_READY, Y.bind(this._setHTML, this, html));
       
   328             }
       
   329 
       
   330             return html;
       
   331         },
       
   332 
       
   333         /**
       
   334         * Sets the linked CSS on the instance.
       
   335         * @private
       
   336         * @method _setLinkedCSS
       
   337         * @param {String} css The linkedcss value
       
   338         * @return {String}
       
   339         */
       
   340         _setLinkedCSS: function(css) {
       
   341             if (this._ready) {
       
   342                 var inst = this.getInstance();
       
   343                 inst.Get.css(css);
       
   344             } else {
       
   345                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   346                 this.once(EVENT_CONTENT_READY, Y.bind(this._setLinkedCSS, this, css));
       
   347             }
       
   348 
       
   349             return css;
       
   350         },
       
   351 
       
   352         /**
       
   353         * Sets the dir (language direction) attribute on the container.
       
   354         * @private
       
   355         * @method _setDir
       
   356         * @param {String} value The language direction
       
   357         * @return {String}
       
   358         */
       
   359         _setDir: function(value) {
       
   360             var container;
       
   361 
       
   362             if (this._ready) {
       
   363                 container = this.get(CONTAINER);
       
   364 
       
   365                 container.setAttribute('dir', value);
       
   366             } else {
       
   367                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   368                 this.once(EVENT_CONTENT_READY, Y.bind(this._setDir, this, value));
       
   369             }
       
   370 
       
   371             return value;
       
   372         },
       
   373 
       
   374         /**
       
   375         * Set's the extra CSS on the instance.
       
   376         * @private
       
   377         * @method _setExtraCSS
       
   378         * @param {String} css The CSS style to be set as extra css
       
   379         * @return {String}
       
   380         */
       
   381         _setExtraCSS: function(css) {
       
   382             if (this._ready) {
       
   383                 if (css) {
       
   384                     var inst = this.getInstance(),
       
   385                         head = inst.one('head');
       
   386 
       
   387                     if (this._extraCSSNode) {
       
   388                         this._extraCSSNode.remove();
       
   389                     }
       
   390 
       
   391                     this._extraCSSNode = YNode.create('<style>' + css + '</style>');
       
   392 
       
   393                     head.append(this._extraCSSNode);
       
   394                 }
       
   395             } else {
       
   396                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   397                 this.once(EVENT_CONTENT_READY, Y.bind(this._setExtraCSS, this, css));
       
   398             }
       
   399 
       
   400             return css;
       
   401         },
       
   402 
       
   403         /**
       
   404         * Sets the language value on the instance.
       
   405         * @private
       
   406         * @method _setLang
       
   407         * @param {String} value The language to be set
       
   408         * @return {String}
       
   409         */
       
   410         _setLang: function(value) {
       
   411             var container;
       
   412 
       
   413             if (this._ready) {
       
   414                 container = this.get(CONTAINER);
       
   415 
       
   416                 container.setAttribute('lang', value);
       
   417             } else {
       
   418                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   419                 this.once(EVENT_CONTENT_READY, Y.bind(this._setLang, this, value));
       
   420             }
       
   421 
       
   422             return value;
       
   423         },
       
   424 
       
   425         /**
       
   426         * Called from the first YUI instance that sets up the internal instance.
       
   427         * This loads the content into the ContentEditable element and attaches the contentready event.
       
   428         * @private
       
   429         * @method _instanceLoaded
       
   430         * @param {YUI} inst The internal YUI instance bound to the ContentEditable element
       
   431         */
       
   432         _instanceLoaded: function(inst) {
       
   433             this._instance = inst;
       
   434 
       
   435             this._onContentReady();
       
   436 
       
   437             var doc = this._instance.config.doc;
       
   438 
       
   439             if (!Y.UA.ie) {
       
   440                 try {
       
   441                     //Force other browsers into non CSS styling
       
   442                     doc.execCommand('styleWithCSS', false, false);
       
   443                     doc.execCommand('insertbronreturn', false, false);
       
   444                 } catch (err) {}
       
   445             }
       
   446         },
       
   447 
       
   448 
       
   449         /**
       
   450         * Validates linkedcss property
       
   451         *
       
   452         * @method _validateLinkedCSS
       
   453         * @private
       
   454         */
       
   455         _validateLinkedCSS: function(value) {
       
   456             return Lang.isString(value) || Lang.isArray(value);
       
   457         },
       
   458 
       
   459         //BEGIN PUBLIC METHODS
       
   460         /**
       
   461         * This is a scoped version of the normal YUI.use method & is bound to the ContentEditable element
       
   462         * At setup, the inst.use method is mapped to this method.
       
   463         * @method use
       
   464         */
       
   465         use: function() {
       
   466 
       
   467             var inst = this.getInstance(),
       
   468                 args = Y.Array(arguments),
       
   469                 callback = false;
       
   470 
       
   471             if (Lang.isFunction(args[args.length - 1])) {
       
   472                 callback = args.pop();
       
   473             }
       
   474 
       
   475             if (callback) {
       
   476                 args.push(function() {
       
   477 
       
   478                     callback.apply(inst, arguments);
       
   479                 });
       
   480             }
       
   481 
       
   482             return inst.__use.apply(inst, args);
       
   483         },
       
   484 
       
   485         /**
       
   486         * A delegate method passed to the instance's delegate method
       
   487         * @method delegate
       
   488         * @param {String} type The type of event to listen for
       
   489         * @param {Function} fn The method to attach
       
   490         * @param {String, Node} cont The container to act as a delegate, if no "sel" passed, the container is assumed.
       
   491         * @param {String} sel The selector to match in the event (optional)
       
   492         * @return {EventHandle} The Event handle returned from Y.delegate
       
   493         */
       
   494         delegate: function(type, fn, cont, sel) {
       
   495             var inst = this.getInstance();
       
   496 
       
   497             if (!inst) {
       
   498 
       
   499                 return false;
       
   500             }
       
   501 
       
   502             if (!sel) {
       
   503                 sel = cont;
       
   504 
       
   505                 cont = this.get(CONTAINER);
       
   506             }
       
   507 
       
   508             return inst.delegate(type, fn, cont, sel);
       
   509         },
       
   510 
       
   511         /**
       
   512         * Get a reference to the internal YUI instance.
       
   513         * @method getInstance
       
   514         * @return {YUI} The internal YUI instance
       
   515         */
       
   516         getInstance: function() {
       
   517             return this._instance;
       
   518         },
       
   519 
       
   520         /**
       
   521         * @method render
       
   522         * @param {String/HTMLElement/Node} node The node to render to
       
   523         * @return {ContentEditable}
       
   524         * @chainable
       
   525         */
       
   526         render: function(node) {
       
   527             var args, inst, fn;
       
   528 
       
   529             if (this._rendered) {
       
   530 
       
   531                 return this;
       
   532             }
       
   533 
       
   534             if (node) {
       
   535                 this.set(CONTAINER, node);
       
   536             }
       
   537 
       
   538             container = this.get(CONTAINER);
       
   539 
       
   540             if (!container) {
       
   541                 container = YNode.create(ContentEditable.HTML);
       
   542 
       
   543                 Y.one('body').prepend(container);
       
   544 
       
   545                 this.set(CONTAINER, container);
       
   546             }
       
   547 
       
   548             this._rendered = true;
       
   549 
       
   550             this._container.setAttribute(CONTENT_EDITABLE, true);
       
   551 
       
   552             args = Y.clone(this.get(USE));
       
   553 
       
   554             fn = Y.bind(function() {
       
   555                 inst = YUI();
       
   556 
       
   557                 inst.host = this.get(HOST); //Cross reference to Editor
       
   558 
       
   559 
       
   560                 inst.use('node-base', Y.bind(this._instanceLoaded, this));
       
   561             }, this);
       
   562 
       
   563             args.push(fn);
       
   564 
       
   565             Y.use.apply(Y, args);
       
   566 
       
   567             return this;
       
   568         },
       
   569 
       
   570         /**
       
   571         * Set the focus to the container
       
   572         * @method focus
       
   573         * @param {Function} fn Callback function to execute after focus happens
       
   574         * @return {ContentEditable}
       
   575         * @chainable
       
   576         */
       
   577         focus: function() {
       
   578             this._container.focus();
       
   579 
       
   580             return this;
       
   581         },
       
   582         /**
       
   583         * Show the iframe instance
       
   584         * @method show
       
   585         * @return {ContentEditable}
       
   586         * @chainable
       
   587         */
       
   588         show: function() {
       
   589             this._container.show();
       
   590 
       
   591             this.focus();
       
   592 
       
   593             return this;
       
   594         },
       
   595 
       
   596         /**
       
   597         * Hide the iframe instance
       
   598         * @method hide
       
   599         * @return {ContentEditable}
       
   600         * @chainable
       
   601         */
       
   602         hide: function() {
       
   603             this._container.hide();
       
   604 
       
   605             return this;
       
   606         }
       
   607     },
       
   608     {
       
   609         /**
       
   610         * The throttle time for key events in IE
       
   611         * @static
       
   612         * @property THROTTLE_TIME
       
   613         * @type Number
       
   614         * @default 100
       
   615         */
       
   616         THROTTLE_TIME: 100,
       
   617 
       
   618         /**
       
   619         * The DomEvents that the frame automatically attaches and bubbles
       
   620         * @static
       
   621         * @property DOM_EVENTS
       
   622         * @type Object
       
   623         */
       
   624         DOM_EVENTS: {
       
   625             click: 1,
       
   626             dblclick: 1,
       
   627             focusin: 1,
       
   628             focusout: 1,
       
   629             keydown: 1,
       
   630             keypress: 1,
       
   631             keyup: 1,
       
   632             mousedown: 1,
       
   633             mouseup: 1,
       
   634             paste: 1
       
   635         },
       
   636 
       
   637         /**
       
   638         * The template string used to create the ContentEditable element
       
   639         * @static
       
   640         * @property HTML
       
   641         * @type String
       
   642         */
       
   643         HTML: '<div></div>',
       
   644 
       
   645         /**
       
   646         * The name of the class (contentEditable)
       
   647         * @static
       
   648         * @property NAME
       
   649         * @type String
       
   650         */
       
   651         NAME: 'contentEditable',
       
   652 
       
   653         /**
       
   654         * The namespace on which ContentEditable plugin will reside.
       
   655         *
       
   656         * @property NS
       
   657         * @type String
       
   658         * @default 'contentEditable'
       
   659         * @static
       
   660         */
       
   661         NS: CONTENT_EDITABLE,
       
   662 
       
   663         ATTRS: {
       
   664             /**
       
   665             * The default text direction for this ContentEditable element. Default: ltr
       
   666             * @attribute dir
       
   667             * @type String
       
   668             */
       
   669             dir: {
       
   670                 lazyAdd: false,
       
   671                 validator: Lang.isString,
       
   672                 setter: '_setDir',
       
   673                 valueFn: '_getDir'
       
   674             },
       
   675 
       
   676             /**
       
   677             * The container to set contentEditable=true or to create on render.
       
   678             * @attribute container
       
   679             * @type String/HTMLElement/Node
       
   680             */
       
   681             container: {
       
   682                 setter: function(n) {
       
   683                     this._container = Y.one(n);
       
   684 
       
   685                     return this._container;
       
   686                 }
       
   687             },
       
   688 
       
   689             /**
       
   690             * The string to inject as Editor content. Default '<br>'
       
   691             * @attribute content
       
   692             * @type String
       
   693             */
       
   694             content: {
       
   695                 getter: '_getHTML',
       
   696                 lazyAdd: false,
       
   697                 setter: '_setHTML',
       
   698                 validator: Lang.isString,
       
   699                 value: '<br>'
       
   700             },
       
   701 
       
   702             /**
       
   703             * The default tag to use for block level items, defaults to: p
       
   704             * @attribute defaultblock
       
   705             * @type String
       
   706             */
       
   707             defaultblock: {
       
   708                 validator: Lang.isString,
       
   709                 value: TAG_PARAGRAPH,
       
   710                 valueFn: '_getDefaultBlock'
       
   711             },
       
   712 
       
   713             /**
       
   714             * A string of CSS to add to the Head of the Editor
       
   715             * @attribute extracss
       
   716             * @type String
       
   717             */
       
   718             extracss: {
       
   719                 lazyAdd: false,
       
   720                 setter: '_setExtraCSS',
       
   721                 validator: Lang.isString,
       
   722                 valueFn: '_getExtraCSS'
       
   723             },
       
   724 
       
   725             /**
       
   726             * Set the id of the new Node. (optional)
       
   727             * @attribute id
       
   728             * @type String
       
   729             * @writeonce
       
   730             */
       
   731             id: {
       
   732                 writeOnce: true,
       
   733                 getter: function(id) {
       
   734                     if (!id) {
       
   735                         id = 'inlineedit-' + Y.guid();
       
   736                     }
       
   737 
       
   738                     return id;
       
   739                 }
       
   740             },
       
   741 
       
   742             /**
       
   743             * The default language. Default: en-US
       
   744             * @attribute lang
       
   745             * @type String
       
   746             */
       
   747             lang: {
       
   748                 validator: Lang.isString,
       
   749                 setter: '_setLang',
       
   750                 lazyAdd: false,
       
   751                 value: 'en-US'
       
   752             },
       
   753 
       
   754             /**
       
   755             * An array of url's to external linked style sheets
       
   756             * @attribute linkedcss
       
   757             * @type String|Array
       
   758             */
       
   759             linkedcss: {
       
   760                 setter: '_setLinkedCSS',
       
   761                 validator: '_validateLinkedCSS'
       
   762                 //value: ''
       
   763             },
       
   764 
       
   765             /**
       
   766             * The Node instance of the container.
       
   767             * @attribute node
       
   768             * @type Node
       
   769             */
       
   770             node: {
       
   771                 readOnly: true,
       
   772                 value: null,
       
   773                 getter: function() {
       
   774                     return this._container;
       
   775                 }
       
   776             },
       
   777 
       
   778             /**
       
   779             * Array of modules to include in the scoped YUI instance at render time. Default: ['node-base', 'editor-selection', 'stylesheet']
       
   780             * @attribute use
       
   781             * @writeonce
       
   782             * @type Array
       
   783             */
       
   784             use: {
       
   785                 validator: Lang.isArray,
       
   786                 writeOnce: true,
       
   787                 value: ['node-base', 'editor-selection', 'stylesheet']
       
   788             }
       
   789         }
       
   790     });
       
   791 
       
   792     Y.namespace('Plugin');
       
   793 
       
   794     Y.Plugin.ContentEditable = ContentEditable;
       
   795 
       
   796 }, '@VERSION@', {"requires": ["node-base", "editor-selection", "stylesheet", "plugin"]});