src/cm/media/js/lib/yui/yui3-3.15.0/build/content-editable/content-editable-debug.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                 Y.log('Failed to collect clipboard data', 'warn', 'contenteditable');
       
   161 
       
   162                 e.clipboardData = null;
       
   163             }
       
   164 
       
   165             this.fire('dom:paste', e);
       
   166         },
       
   167 
       
   168         /**
       
   169         * Binds DOM events and fires the ready event
       
   170         * @private
       
   171         * @method _defReadyFn
       
   172         */
       
   173         _defReadyFn: function() {
       
   174             var inst = this.getInstance(),
       
   175                 container = this.get(CONTAINER);
       
   176 
       
   177             Y.each(
       
   178                 ContentEditable.DOM_EVENTS,
       
   179                 function(value, key) {
       
   180                     var fn = Y.bind(this._onDomEvent, this),
       
   181                         kfn = ((Y.UA.ie && ContentEditable.THROTTLE_TIME > 0) ? Y.throttle(fn, ContentEditable.THROTTLE_TIME) : fn);
       
   182 
       
   183                     if (!inst.Node.DOM_EVENTS[key]) {
       
   184                         inst.Node.DOM_EVENTS[key] = 1;
       
   185                     }
       
   186 
       
   187                     if (value === 1) {
       
   188                         if (key !== FOCUS && key !== BLUR && key !== PASTE) {
       
   189                             if (key.substring(0, 3) === KEY) {
       
   190                                 //Throttle key events in IE
       
   191                                 this._eventHandles.push(container.on(key, kfn, container));
       
   192                             } else {
       
   193                                 this._eventHandles.push(container.on(key, fn, container));
       
   194                             }
       
   195                         }
       
   196                     }
       
   197                 },
       
   198                 this
       
   199             );
       
   200 
       
   201             inst.Node.DOM_EVENTS.paste = 1;
       
   202 
       
   203             this._eventHandles.push(
       
   204                 container.on(PASTE, Y.bind(this._DOMPaste, this), container),
       
   205                 container.on(FOCUS, Y.bind(this._onDomEvent, this), container),
       
   206                 container.on(BLUR, Y.bind(this._onDomEvent, this), container)
       
   207             );
       
   208 
       
   209             inst.__use = inst.use;
       
   210 
       
   211             inst.use = Y.bind(this.use, this);
       
   212         },
       
   213 
       
   214         /**
       
   215         * Called once the content is available in the ContentEditable element and calls the final use call
       
   216         * @private
       
   217         * @method _onContentReady
       
   218         * on the internal instance so that the modules are loaded properly.
       
   219         */
       
   220         _onContentReady: function(event) {
       
   221             if (!this._ready) {
       
   222                 this._ready = true;
       
   223 
       
   224                 var inst = this.getInstance(),
       
   225                     args = Y.clone(this.get(USE));
       
   226 
       
   227                 this.fire(EVENT_CONTENT_READY);
       
   228 
       
   229                 Y.log('On content available', 'info', 'contenteditable');
       
   230 
       
   231                 if (event) {
       
   232                     inst.config.doc = YNode.getDOMNode(event.target);
       
   233                 }
       
   234 
       
   235                 args.push(Y.bind(function() {
       
   236                     Y.log('Callback from final internal use call', 'info', 'contenteditable');
       
   237 
       
   238                     if (inst.EditorSelection) {
       
   239                         inst.EditorSelection.DEFAULT_BLOCK_TAG = this.get('defaultblock');
       
   240 
       
   241                         inst.EditorSelection.ROOT = this.get(CONTAINER);
       
   242                     }
       
   243 
       
   244                     this.fire(EVENT_READY);
       
   245                 }, this));
       
   246 
       
   247                 Y.log('Calling use on internal instance: ' + args, 'info', 'contentEditable');
       
   248 
       
   249                 inst.use.apply(inst, args);
       
   250             }
       
   251         },
       
   252 
       
   253         /**
       
   254         * Retrieves defaultblock value from host attribute
       
   255         * @private
       
   256         * @method _getDefaultBlock
       
   257         * @return {String}
       
   258         */
       
   259         _getDefaultBlock: function() {
       
   260             return this._getHostValue('defaultblock');
       
   261         },
       
   262 
       
   263         /**
       
   264         * Retrieves dir value from host attribute
       
   265         * @private
       
   266         * @method _getDir
       
   267         * @return {String}
       
   268         */
       
   269         _getDir: function() {
       
   270             return this._getHostValue('dir');
       
   271         },
       
   272 
       
   273         /**
       
   274         * Retrieves extracss value from host attribute
       
   275         * @private
       
   276         * @method _getExtraCSS
       
   277         * @return {String}
       
   278         */
       
   279         _getExtraCSS: function() {
       
   280             return this._getHostValue('extracss');
       
   281         },
       
   282 
       
   283         /**
       
   284         * Get the content from the container
       
   285         * @private
       
   286         * @method _getHTML
       
   287         * @param {String} html The raw HTML from the container.
       
   288         * @return {String}
       
   289         */
       
   290         _getHTML: function() {
       
   291             var html, container;
       
   292 
       
   293             if (this._ready) {
       
   294                 container = this.get(CONTAINER);
       
   295 
       
   296                 html = container.get(INNER_HTML);
       
   297             }
       
   298 
       
   299             return html;
       
   300         },
       
   301 
       
   302         /**
       
   303         * Retrieves a value from host attribute
       
   304         * @private
       
   305         * @method _getHostValue
       
   306         * @param {attr} The attribute which value should be returned from the host
       
   307         * @return {String|Object}
       
   308         */
       
   309         _getHostValue: function(attr) {
       
   310             var host = this.get(HOST);
       
   311 
       
   312             if (host) {
       
   313                 return host.get(attr);
       
   314             }
       
   315         },
       
   316 
       
   317         /**
       
   318         * Set the content of the container
       
   319         * @private
       
   320         * @method _setHTML
       
   321         * @param {String} html The raw HTML to set to the container.
       
   322         * @return {String}
       
   323         */
       
   324         _setHTML: function(html) {
       
   325             if (this._ready) {
       
   326                 var container = this.get(CONTAINER);
       
   327 
       
   328                 container.set(INNER_HTML, html);
       
   329             } else {
       
   330                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   331                 this.once(EVENT_CONTENT_READY, Y.bind(this._setHTML, this, html));
       
   332             }
       
   333 
       
   334             return html;
       
   335         },
       
   336 
       
   337         /**
       
   338         * Sets the linked CSS on the instance.
       
   339         * @private
       
   340         * @method _setLinkedCSS
       
   341         * @param {String} css The linkedcss value
       
   342         * @return {String}
       
   343         */
       
   344         _setLinkedCSS: function(css) {
       
   345             if (this._ready) {
       
   346                 var inst = this.getInstance();
       
   347                 inst.Get.css(css);
       
   348             } else {
       
   349                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   350                 this.once(EVENT_CONTENT_READY, Y.bind(this._setLinkedCSS, this, css));
       
   351             }
       
   352 
       
   353             return css;
       
   354         },
       
   355 
       
   356         /**
       
   357         * Sets the dir (language direction) attribute on the container.
       
   358         * @private
       
   359         * @method _setDir
       
   360         * @param {String} value The language direction
       
   361         * @return {String}
       
   362         */
       
   363         _setDir: function(value) {
       
   364             var container;
       
   365 
       
   366             if (this._ready) {
       
   367                 container = this.get(CONTAINER);
       
   368 
       
   369                 container.setAttribute('dir', value);
       
   370             } else {
       
   371                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   372                 this.once(EVENT_CONTENT_READY, Y.bind(this._setDir, this, value));
       
   373             }
       
   374 
       
   375             return value;
       
   376         },
       
   377 
       
   378         /**
       
   379         * Set's the extra CSS on the instance.
       
   380         * @private
       
   381         * @method _setExtraCSS
       
   382         * @param {String} css The CSS style to be set as extra css
       
   383         * @return {String}
       
   384         */
       
   385         _setExtraCSS: function(css) {
       
   386             if (this._ready) {
       
   387                 if (css) {
       
   388                     var inst = this.getInstance(),
       
   389                         head = inst.one('head');
       
   390 
       
   391                     if (this._extraCSSNode) {
       
   392                         this._extraCSSNode.remove();
       
   393                     }
       
   394 
       
   395                     this._extraCSSNode = YNode.create('<style>' + css + '</style>');
       
   396 
       
   397                     head.append(this._extraCSSNode);
       
   398                 }
       
   399             } else {
       
   400                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   401                 this.once(EVENT_CONTENT_READY, Y.bind(this._setExtraCSS, this, css));
       
   402             }
       
   403 
       
   404             return css;
       
   405         },
       
   406 
       
   407         /**
       
   408         * Sets the language value on the instance.
       
   409         * @private
       
   410         * @method _setLang
       
   411         * @param {String} value The language to be set
       
   412         * @return {String}
       
   413         */
       
   414         _setLang: function(value) {
       
   415             var container;
       
   416 
       
   417             if (this._ready) {
       
   418                 container = this.get(CONTAINER);
       
   419 
       
   420                 container.setAttribute('lang', value);
       
   421             } else {
       
   422                 //This needs to be wrapped in a contentready callback for the !_ready state
       
   423                 this.once(EVENT_CONTENT_READY, Y.bind(this._setLang, this, value));
       
   424             }
       
   425 
       
   426             return value;
       
   427         },
       
   428 
       
   429         /**
       
   430         * Called from the first YUI instance that sets up the internal instance.
       
   431         * This loads the content into the ContentEditable element and attaches the contentready event.
       
   432         * @private
       
   433         * @method _instanceLoaded
       
   434         * @param {YUI} inst The internal YUI instance bound to the ContentEditable element
       
   435         */
       
   436         _instanceLoaded: function(inst) {
       
   437             this._instance = inst;
       
   438 
       
   439             this._onContentReady();
       
   440 
       
   441             var doc = this._instance.config.doc;
       
   442 
       
   443             if (!Y.UA.ie) {
       
   444                 try {
       
   445                     //Force other browsers into non CSS styling
       
   446                     doc.execCommand('styleWithCSS', false, false);
       
   447                     doc.execCommand('insertbronreturn', false, false);
       
   448                 } catch (err) {}
       
   449             }
       
   450         },
       
   451 
       
   452 
       
   453         /**
       
   454         * Validates linkedcss property
       
   455         *
       
   456         * @method _validateLinkedCSS
       
   457         * @private
       
   458         */
       
   459         _validateLinkedCSS: function(value) {
       
   460             return Lang.isString(value) || Lang.isArray(value);
       
   461         },
       
   462 
       
   463         //BEGIN PUBLIC METHODS
       
   464         /**
       
   465         * This is a scoped version of the normal YUI.use method & is bound to the ContentEditable element
       
   466         * At setup, the inst.use method is mapped to this method.
       
   467         * @method use
       
   468         */
       
   469         use: function() {
       
   470             Y.log('Calling augmented use after ready', 'info', 'contenteditable');
       
   471 
       
   472             var inst = this.getInstance(),
       
   473                 args = Y.Array(arguments),
       
   474                 callback = false;
       
   475 
       
   476             if (Lang.isFunction(args[args.length - 1])) {
       
   477                 callback = args.pop();
       
   478             }
       
   479 
       
   480             if (callback) {
       
   481                 args.push(function() {
       
   482                     Y.log('Internal callback from augmented use', 'info', 'contenteditable');
       
   483 
       
   484                     callback.apply(inst, arguments);
       
   485                 });
       
   486             }
       
   487 
       
   488             return inst.__use.apply(inst, args);
       
   489         },
       
   490 
       
   491         /**
       
   492         * A delegate method passed to the instance's delegate method
       
   493         * @method delegate
       
   494         * @param {String} type The type of event to listen for
       
   495         * @param {Function} fn The method to attach
       
   496         * @param {String, Node} cont The container to act as a delegate, if no "sel" passed, the container is assumed.
       
   497         * @param {String} sel The selector to match in the event (optional)
       
   498         * @return {EventHandle} The Event handle returned from Y.delegate
       
   499         */
       
   500         delegate: function(type, fn, cont, sel) {
       
   501             var inst = this.getInstance();
       
   502 
       
   503             if (!inst) {
       
   504                 Y.log('Delegate events can not be attached until after the ready event has fired.', 'error', 'contenteditable');
       
   505 
       
   506                 return false;
       
   507             }
       
   508 
       
   509             if (!sel) {
       
   510                 sel = cont;
       
   511 
       
   512                 cont = this.get(CONTAINER);
       
   513             }
       
   514 
       
   515             return inst.delegate(type, fn, cont, sel);
       
   516         },
       
   517 
       
   518         /**
       
   519         * Get a reference to the internal YUI instance.
       
   520         * @method getInstance
       
   521         * @return {YUI} The internal YUI instance
       
   522         */
       
   523         getInstance: function() {
       
   524             return this._instance;
       
   525         },
       
   526 
       
   527         /**
       
   528         * @method render
       
   529         * @param {String/HTMLElement/Node} node The node to render to
       
   530         * @return {ContentEditable}
       
   531         * @chainable
       
   532         */
       
   533         render: function(node) {
       
   534             var args, inst, fn;
       
   535 
       
   536             if (this._rendered) {
       
   537                 Y.log('Container already rendered.', 'warn', 'contentEditable');
       
   538 
       
   539                 return this;
       
   540             }
       
   541 
       
   542             if (node) {
       
   543                 this.set(CONTAINER, node);
       
   544             }
       
   545 
       
   546             container = this.get(CONTAINER);
       
   547 
       
   548             if (!container) {
       
   549                 container = YNode.create(ContentEditable.HTML);
       
   550 
       
   551                 Y.one('body').prepend(container);
       
   552 
       
   553                 this.set(CONTAINER, container);
       
   554             }
       
   555 
       
   556             this._rendered = true;
       
   557 
       
   558             this._container.setAttribute(CONTENT_EDITABLE, true);
       
   559 
       
   560             args = Y.clone(this.get(USE));
       
   561 
       
   562             fn = Y.bind(function() {
       
   563                 inst = YUI();
       
   564 
       
   565                 inst.host = this.get(HOST); //Cross reference to Editor
       
   566 
       
   567                 inst.log = Y.log; //Dump the instance logs to the parent instance.
       
   568 
       
   569                 Y.log('Creating new internal instance with node-base only', 'info', 'contenteditable');
       
   570                 inst.use('node-base', Y.bind(this._instanceLoaded, this));
       
   571             }, this);
       
   572 
       
   573             args.push(fn);
       
   574 
       
   575             Y.log('Adding new modules to main instance: ' + args, 'info', 'contenteditable');
       
   576             Y.use.apply(Y, args);
       
   577 
       
   578             return this;
       
   579         },
       
   580 
       
   581         /**
       
   582         * Set the focus to the container
       
   583         * @method focus
       
   584         * @param {Function} fn Callback function to execute after focus happens
       
   585         * @return {ContentEditable}
       
   586         * @chainable
       
   587         */
       
   588         focus: function() {
       
   589             this._container.focus();
       
   590 
       
   591             return this;
       
   592         },
       
   593         /**
       
   594         * Show the iframe instance
       
   595         * @method show
       
   596         * @return {ContentEditable}
       
   597         * @chainable
       
   598         */
       
   599         show: function() {
       
   600             this._container.show();
       
   601 
       
   602             this.focus();
       
   603 
       
   604             return this;
       
   605         },
       
   606 
       
   607         /**
       
   608         * Hide the iframe instance
       
   609         * @method hide
       
   610         * @return {ContentEditable}
       
   611         * @chainable
       
   612         */
       
   613         hide: function() {
       
   614             this._container.hide();
       
   615 
       
   616             return this;
       
   617         }
       
   618     },
       
   619     {
       
   620         /**
       
   621         * The throttle time for key events in IE
       
   622         * @static
       
   623         * @property THROTTLE_TIME
       
   624         * @type Number
       
   625         * @default 100
       
   626         */
       
   627         THROTTLE_TIME: 100,
       
   628 
       
   629         /**
       
   630         * The DomEvents that the frame automatically attaches and bubbles
       
   631         * @static
       
   632         * @property DOM_EVENTS
       
   633         * @type Object
       
   634         */
       
   635         DOM_EVENTS: {
       
   636             click: 1,
       
   637             dblclick: 1,
       
   638             focusin: 1,
       
   639             focusout: 1,
       
   640             keydown: 1,
       
   641             keypress: 1,
       
   642             keyup: 1,
       
   643             mousedown: 1,
       
   644             mouseup: 1,
       
   645             paste: 1
       
   646         },
       
   647 
       
   648         /**
       
   649         * The template string used to create the ContentEditable element
       
   650         * @static
       
   651         * @property HTML
       
   652         * @type String
       
   653         */
       
   654         HTML: '<div></div>',
       
   655 
       
   656         /**
       
   657         * The name of the class (contentEditable)
       
   658         * @static
       
   659         * @property NAME
       
   660         * @type String
       
   661         */
       
   662         NAME: 'contentEditable',
       
   663 
       
   664         /**
       
   665         * The namespace on which ContentEditable plugin will reside.
       
   666         *
       
   667         * @property NS
       
   668         * @type String
       
   669         * @default 'contentEditable'
       
   670         * @static
       
   671         */
       
   672         NS: CONTENT_EDITABLE,
       
   673 
       
   674         ATTRS: {
       
   675             /**
       
   676             * The default text direction for this ContentEditable element. Default: ltr
       
   677             * @attribute dir
       
   678             * @type String
       
   679             */
       
   680             dir: {
       
   681                 lazyAdd: false,
       
   682                 validator: Lang.isString,
       
   683                 setter: '_setDir',
       
   684                 valueFn: '_getDir'
       
   685             },
       
   686 
       
   687             /**
       
   688             * The container to set contentEditable=true or to create on render.
       
   689             * @attribute container
       
   690             * @type String/HTMLElement/Node
       
   691             */
       
   692             container: {
       
   693                 setter: function(n) {
       
   694                     this._container = Y.one(n);
       
   695 
       
   696                     return this._container;
       
   697                 }
       
   698             },
       
   699 
       
   700             /**
       
   701             * The string to inject as Editor content. Default '<br>'
       
   702             * @attribute content
       
   703             * @type String
       
   704             */
       
   705             content: {
       
   706                 getter: '_getHTML',
       
   707                 lazyAdd: false,
       
   708                 setter: '_setHTML',
       
   709                 validator: Lang.isString,
       
   710                 value: '<br>'
       
   711             },
       
   712 
       
   713             /**
       
   714             * The default tag to use for block level items, defaults to: p
       
   715             * @attribute defaultblock
       
   716             * @type String
       
   717             */
       
   718             defaultblock: {
       
   719                 validator: Lang.isString,
       
   720                 value: TAG_PARAGRAPH,
       
   721                 valueFn: '_getDefaultBlock'
       
   722             },
       
   723 
       
   724             /**
       
   725             * A string of CSS to add to the Head of the Editor
       
   726             * @attribute extracss
       
   727             * @type String
       
   728             */
       
   729             extracss: {
       
   730                 lazyAdd: false,
       
   731                 setter: '_setExtraCSS',
       
   732                 validator: Lang.isString,
       
   733                 valueFn: '_getExtraCSS'
       
   734             },
       
   735 
       
   736             /**
       
   737             * Set the id of the new Node. (optional)
       
   738             * @attribute id
       
   739             * @type String
       
   740             * @writeonce
       
   741             */
       
   742             id: {
       
   743                 writeOnce: true,
       
   744                 getter: function(id) {
       
   745                     if (!id) {
       
   746                         id = 'inlineedit-' + Y.guid();
       
   747                     }
       
   748 
       
   749                     return id;
       
   750                 }
       
   751             },
       
   752 
       
   753             /**
       
   754             * The default language. Default: en-US
       
   755             * @attribute lang
       
   756             * @type String
       
   757             */
       
   758             lang: {
       
   759                 validator: Lang.isString,
       
   760                 setter: '_setLang',
       
   761                 lazyAdd: false,
       
   762                 value: 'en-US'
       
   763             },
       
   764 
       
   765             /**
       
   766             * An array of url's to external linked style sheets
       
   767             * @attribute linkedcss
       
   768             * @type String|Array
       
   769             */
       
   770             linkedcss: {
       
   771                 setter: '_setLinkedCSS',
       
   772                 validator: '_validateLinkedCSS'
       
   773                 //value: ''
       
   774             },
       
   775 
       
   776             /**
       
   777             * The Node instance of the container.
       
   778             * @attribute node
       
   779             * @type Node
       
   780             */
       
   781             node: {
       
   782                 readOnly: true,
       
   783                 value: null,
       
   784                 getter: function() {
       
   785                     return this._container;
       
   786                 }
       
   787             },
       
   788 
       
   789             /**
       
   790             * Array of modules to include in the scoped YUI instance at render time. Default: ['node-base', 'editor-selection', 'stylesheet']
       
   791             * @attribute use
       
   792             * @writeonce
       
   793             * @type Array
       
   794             */
       
   795             use: {
       
   796                 validator: Lang.isArray,
       
   797                 writeOnce: true,
       
   798                 value: ['node-base', 'editor-selection', 'stylesheet']
       
   799             }
       
   800         }
       
   801     });
       
   802 
       
   803     Y.namespace('Plugin');
       
   804 
       
   805     Y.Plugin.ContentEditable = ContentEditable;
       
   806 
       
   807 }, '@VERSION@', {"requires": ["node-base", "editor-selection", "stylesheet", "plugin"]});