]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/editor/frame.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / editor / frame.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('frame', function(Y) {
9
10     /**
11      * Creates a wrapper around an iframe. It loads the content either from a local
12      * file or from script and creates a local YUI instance bound to that new window and document.
13      * @module editor
14      * @submodule frame
15      */     
16     /**
17      * Creates a wrapper around an iframe. It loads the content either from a local
18      * file or from script and creates a local YUI instance bound to that new window and document.
19      * @class Frame
20      * @for Frame
21      * @extends Base
22      * @constructor
23      */
24
25     var Frame = function() {
26         Frame.superclass.constructor.apply(this, arguments);
27     };
28
29     Y.extend(Frame, Y.Base, {
30         /**
31         * @private
32         * @property _ready
33         * @description Internal reference set when the content is ready.
34         * @type Boolean
35         */
36         _ready: null,
37         /**
38         * @private
39         * @property _rendered
40         * @description Internal reference set when render is called.
41         * @type Boolean
42         */
43         _rendered: null,
44         /**
45         * @private
46         * @property _iframe
47         * @description Internal Node reference to the iFrame or the window
48         * @type Node
49         */
50         _iframe: null,
51         /**
52         * @private
53         * @property _instance
54         * @description Internal reference to the YUI instance bound to the iFrame or window
55         * @type YUI
56         */
57         _instance: null,
58         /**
59         * @private
60         * @method _create
61         * @description Create the iframe or Window and get references to the Document & Window
62         * @return {Object} Hash table containing references to the new Document & Window
63         */
64         _create: function(cb) {
65             var win, doc, res, node;
66             
67             this._iframe = Y.Node.create(Frame.HTML);
68             this._iframe.setStyle('visibility', 'hidden');
69             this._iframe.set('src', this.get('src'));
70             this.get('container').append(this._iframe);
71
72             this._iframe.set('height', '99%');
73
74             
75             var html = '',
76                 extra_css = ((this.get('extracss')) ? '<style id="extra_css">' + this.get('extracss') + '</style>' : '');
77
78             html = Y.substitute(Frame.PAGE_HTML, {
79                 DIR: this.get('dir'),
80                 LANG: this.get('lang'),
81                 TITLE: this.get('title'),
82                 META: Frame.META,
83                 LINKED_CSS: this.get('linkedcss'),
84                 CONTENT: this.get('content'),
85                 BASE_HREF: this.get('basehref'),
86                 DEFAULT_CSS: Frame.DEFAULT_CSS,
87                 EXTRA_CSS: extra_css
88             });
89             if (Y.config.doc.compatMode != 'BackCompat') {
90                 
91                 //html = Frame.DOC_TYPE + "\n" + html;
92                 html = Frame.getDocType() + "\n" + html;
93             } else {
94             }
95
96
97
98             res = this._resolveWinDoc();
99             res.doc.open();
100             res.doc.write(html);
101             res.doc.close();
102
103             if (this.get('designMode')) {
104                 res.doc.designMode = 'on';
105             }
106             
107             if (!res.doc.documentElement) {
108                 var timer = Y.later(1, this, function() {
109                     if (res.doc && res.doc.documentElement) {
110                         cb(res);
111                         timer.cancel();
112                     }
113                 }, null, true);
114             } else {
115                 cb(res);
116             }
117
118         },
119         /**
120         * @private
121         * @method _resolveWinDoc
122         * @description Resolves the document and window from an iframe or window instance
123         * @param {Object} c The YUI Config to add the window and document to
124         * @return {Object} Object hash of window and document references, if a YUI config was passed, it is returned.
125         */
126         _resolveWinDoc: function(c) {
127             var config = (c) ? c : {};
128             config.win = Y.Node.getDOMNode(this._iframe.get('contentWindow'));
129             config.doc = Y.Node.getDOMNode(this._iframe.get('contentWindow.document'));
130             if (!config.doc) {
131                 config.doc = Y.config.doc;
132             }
133             if (!config.win) {
134                 config.win = Y.config.win;
135             }
136             return config;
137         },
138         /**
139         * @private
140         * @method _onDomEvent
141         * @description Generic handler for all DOM events fired by the iframe or window. This handler
142         * takes the current EventFacade and augments it to fire on the Frame host. It adds two new properties
143         * to the EventFacade called frameX and frameY which adds the scroll and xy position of the iframe
144         * to the original pageX and pageY of the event so external nodes can be positioned over the frame.
145         * @param {Event.Facade} e
146         */
147         _onDomEvent: function(e) {
148             var xy, node;
149
150             e.frameX = e.frameY = 0;
151
152             if (e.pageX > 0 || e.pageY > 0) {
153                 if (e.type.substring(0, 3) !== 'key') {
154                     node = this._instance.one('win');
155                     xy = this._iframe.getXY();
156                     e.frameX = xy[0] + e.pageX - node.get('scrollLeft');
157                     e.frameY = xy[1] + e.pageY - node.get('scrollTop');
158                 }
159             }
160
161             e.frameTarget = e.target;
162             e.frameCurrentTarget = e.currentTarget;
163             e.frameEvent = e;
164
165             this.fire('dom:' + e.type, e);
166         },
167         initializer: function() {
168             this.publish('ready', {
169                 emitFacade: true,
170                 defaultFn: this._defReadyFn
171             });
172         },
173         destructor: function() {
174             var inst = this.getInstance();
175
176             inst.one('doc').detachAll();
177             inst = null;
178             this._iframe.remove();
179         },
180         /**
181         * @private
182         * @method _DOMPaste
183         * @description Simple pass thru handler for the paste event so we can do content cleanup
184         * @param {Event.Facade} e
185         */
186         _DOMPaste: function(e) {
187             var inst = this.getInstance(),
188                 data = '', win = inst.config.win;
189
190             if (e._event.originalTarget) {
191                 data = e._event.originalTarget;
192             }
193             if (e._event.clipboardData) {
194                 data = e._event.clipboardData.getData('Text');
195             }
196             
197             if (win.clipboardData) {
198                 data = win.clipboardData.getData('Text');
199                 if (data === '') { // Could be empty, or failed
200                     // Verify failure
201                     if (!win.clipboardData.setData('Text', data)) {
202                         data = null;
203                     }
204                 }
205             }
206             
207
208             e.frameTarget = e.target;
209             e.frameCurrentTarget = e.currentTarget;
210             e.frameEvent = e;
211             
212             if (data) {
213                 e.clipboardData = {
214                     data: data,
215                     getData: function() {
216                         return data;
217                     }
218                 };
219             } else {
220                 e.clipboardData = null;
221             }
222
223             this.fire('dom:paste', e);
224         },
225         /**
226         * @private
227         * @method _defReadyFn
228         * @description Binds DOM events, sets the iframe to visible and fires the ready event
229         */
230         _defReadyFn: function() {
231             var inst = this.getInstance(),
232                 fn = Y.bind(this._onDomEvent, this),
233                 kfn = ((Y.UA.ie) ? Y.throttle(fn, 200) : fn);
234
235             inst.Node.DOM_EVENTS.activate = 1;
236             inst.Node.DOM_EVENTS.beforedeactivate = 1;
237             inst.Node.DOM_EVENTS.focusin = 1;
238             inst.Node.DOM_EVENTS.deactivate = 1;
239             inst.Node.DOM_EVENTS.focusout = 1;
240
241             //Y.each(inst.Node.DOM_EVENTS, function(v, k) {
242             Y.each(Frame.DOM_EVENTS, function(v, k) {
243                 if (v === 1) {
244                     if (k !== 'focus' && k !== 'blur' && k !== 'paste') {
245                         if (k.substring(0, 3) === 'key') {
246                             if (k === 'keydown') {
247                                 inst.on(k, fn, inst.config.doc);
248                             } else {
249                                 inst.on(k, kfn, inst.config.doc);
250                             }
251                         } else {
252                             inst.on(k, fn, inst.config.doc);
253                         }
254                     }
255                 }
256             }, this);
257
258             inst.Node.DOM_EVENTS.paste = 1;
259             
260             inst.on('paste', Y.bind(this._DOMPaste, this), inst.one('body'));
261
262             //Adding focus/blur to the window object
263             inst.on('focus', fn, inst.config.win);
264             inst.on('blur', fn, inst.config.win);
265
266             inst._use = inst.use;
267             inst.use = Y.bind(this.use, this);
268             this._iframe.setStyles({
269                 visibility: 'inherit'
270             });
271             inst.one('body').setStyle('display', 'block');
272             if (Y.UA.ie) {
273                 this._fixIECursors();
274             }
275         },
276         /**
277         * It appears that having a BR tag anywhere in the source "below" a table with a percentage width (in IE 7 & 8)
278         * if there is any TEXTINPUT's outside the iframe, the cursor will rapidly flickr and the CPU would occasionally 
279         * spike. This method finds all <BR>'s below the sourceIndex of the first table. Does some checks to see if they
280         * can be modified and replaces then with a <WBR> so the layout will remain in tact, but the flickering will
281         * no longer happen.
282         * @method _fixIECursors
283         * @private
284         */
285         _fixIECursors: function() {
286             var inst = this.getInstance(),
287                 tables = inst.all('table'),
288                 brs = inst.all('br'), si;
289
290             if (tables.size() && brs.size()) {
291                 //First Table
292                 si = tables.item(0).get('sourceIndex');
293                 brs.each(function(n) {
294                     var p = n.get('parentNode'),
295                         c = p.get('children'), b = p.all('>br');
296                     
297                     if (p.test('div')) {
298                         if (c.size() > 2) {
299                             n.replace(inst.Node.create('<wbr>'));
300                         } else {
301                             if (n.get('sourceIndex') > si) {
302                                 if (b.size()) {
303                                     n.replace(inst.Node.create('<wbr>'));
304                                 }
305                             } else {
306                                 if (b.size() > 1) {
307                                     n.replace(inst.Node.create('<wbr>'));
308                                 }
309                             }
310                         }
311                     }
312                     
313                 });
314             }
315         },
316         /**
317         * @private
318         * @method _onContentReady
319         * @description Called once the content is available in the frame/window and calls the final use call
320         * on the internal instance so that the modules are loaded properly.
321         */
322         _onContentReady: function(e) {
323             if (!this._ready) {
324                 this._ready = true;
325                 var inst = this.getInstance(),
326                     args = Y.clone(this.get('use'));
327                 
328                 this.fire('contentready');
329
330                 if (e) {
331                     inst.config.doc = Y.Node.getDOMNode(e.target);
332                 }
333                 //TODO Circle around and deal with CSS loading...
334                 args.push(Y.bind(function() {
335                     if (inst.Selection) {
336                         inst.Selection.DEFAULT_BLOCK_TAG = this.get('defaultblock');
337                     }
338
339                     this.fire('ready');
340                 }, this));
341                 inst.use.apply(inst, args);
342
343                 inst.one('doc').get('documentElement').addClass('yui-js-enabled');
344             }
345         },
346         /**
347         * @private
348         * @method _resolveBaseHref
349         * @description Resolves the basehref of the page the frame is created on. Only applies to dynamic content.
350         * @param {String} href The new value to use, if empty it will be resolved from the current url.
351         * @return {String}
352         */
353         _resolveBaseHref: function(href) {
354             if (!href || href === '') {
355                 href = Y.config.doc.location.href;
356                 if (href.indexOf('?') !== -1) { //Remove the query string
357                     href = href.substring(0, href.indexOf('?'));
358                 }
359                 href = href.substring(0, href.lastIndexOf('/')) + '/';
360             }
361             return href;
362         },
363         /**
364         * @private
365         * @method _getHTML
366         * @description Get the content from the iframe
367         * @param {String} html The raw HTML from the body of the iframe.
368         * @return {String}
369         */
370         _getHTML: function(html) {
371             if (this._ready) {
372                 var inst = this.getInstance();
373                 html = inst.one('body').get('innerHTML');
374             }
375             return html;
376         },
377         /**
378         * @private
379         * @method _setHTML
380         * @description Set the content of the iframe
381         * @param {String} html The raw HTML to set the body of the iframe to.
382         * @return {String}
383         */
384         _setHTML: function(html) {
385             if (this._ready) {
386                 var inst = this.getInstance();
387                 inst.one('body').set('innerHTML', html);
388             } else {
389                 //This needs to be wrapped in a contentready callback for the !_ready state
390                 this.on('contentready', Y.bind(function(html, e) {
391                     var inst = this.getInstance();
392                     inst.one('body').set('innerHTML', html);
393                 }, this, html));
394             }
395             return html;
396         },
397         /**
398         * @private
399         * @method _setLinkedCSS
400         * @description Set's the linked CSS on the instance..
401         */
402         _getLinkedCSS: function(urls) {
403             if (!Y.Lang.isArray(urls)) {
404                 urls = [urls];
405             }
406             var str = '';
407             if (!this._ready) {
408                 Y.each(urls, function(v) {
409                     if (v !== '') {
410                         str += '<link rel="stylesheet" href="' + v + '" type="text/css">';
411                     }
412                 });
413             } else {
414                 str = urls;
415             }
416             return str;
417         },
418         /**
419         * @private
420         * @method _setLinkedCSS
421         * @description Set's the linked CSS on the instance..
422         */
423         _setLinkedCSS: function(css) {
424             if (this._ready) {
425                 var inst = this.getInstance();
426                 inst.Get.css(css);
427             }
428             return css;
429         },
430         /**
431         * @private
432         * @method _setExtraCSS
433         * @description Set's the extra CSS on the instance..
434         */
435         _setExtraCSS: function(css) {
436             if (this._ready) {
437                 var inst = this.getInstance(),
438                     node = inst.get('#extra_css');
439                 
440                 node.remove();
441                 inst.one('head').append('<style id="extra_css">' + css + '</style>');
442             }
443             return css;
444         },
445         /**
446         * @private
447         * @method _instanceLoaded
448         * @description Called from the first YUI instance that sets up the internal instance.
449         * This loads the content into the window/frame and attaches the contentready event.
450         * @param {YUI} inst The internal YUI instance bound to the frame/window
451         */
452         _instanceLoaded: function(inst) {
453             this._instance = inst;
454             this._onContentReady();
455             
456             var doc = this._instance.config.doc;
457
458             if (this.get('designMode')) {
459                 if (!Y.UA.ie) {
460                     try {
461                         //Force other browsers into non CSS styling
462                         doc.execCommand('styleWithCSS', false, false);
463                         doc.execCommand('insertbronreturn', false, false);
464                     } catch (err) {}
465                 }
466             }
467         },
468         //BEGIN PUBLIC METHODS
469         /**
470         * @method use
471         * @description This is a scoped version of the normal YUI.use method & is bound to this frame/window.
472         * At setup, the inst.use method is mapped to this method.
473         */
474         use: function() {
475             var inst = this.getInstance(),
476                 args = Y.Array(arguments),
477                 cb = false;
478
479             if (Y.Lang.isFunction(args[args.length - 1])) {
480                 cb = args.pop();
481             }
482             if (cb) {
483                 args.push(function() {
484                     cb.apply(inst, arguments);
485
486                 });
487             }
488             inst._use.apply(inst, args);
489         },
490         /**
491         * @method delegate
492         * @description A delegate method passed to the instance's delegate method
493         * @param {String} type The type of event to listen for
494         * @param {Function} fn The method to attach
495         * @param {String} cont The container to act as a delegate, if no "sel" passed, the body is assumed as the container.
496         * @param {String} sel The selector to match in the event (optional)
497         * @return {EventHandle} The Event handle returned from Y.delegate
498         */
499         delegate: function(type, fn, cont, sel) {
500             var inst = this.getInstance();
501             if (!inst) {
502                 return false;
503             }
504             if (!sel) {
505                 sel = cont;
506                 cont = 'body';
507             }
508             return inst.delegate(type, fn, cont, sel);
509         },
510         /**
511         * @method getInstance
512         * @description Get a reference to the internal YUI instance.
513         * @return {YUI} The internal YUI instance
514         */
515         getInstance: function() {
516             return this._instance;
517         },
518         /**
519         * @method render
520         * @description Render the iframe into the container config option or open the window.
521         * @param {String/HTMLElement/Node} node The node to render to
522         * @return {Y.Frame}
523         * @chainable
524         */
525         render: function(node) {
526             if (this._rendered) {
527                 return this;
528             }
529             this._rendered = true;
530             if (node) {
531                 this.set('container', node);
532             }
533
534             this._create(Y.bind(function(res) {
535
536                 var inst, timer,
537                     cb = Y.bind(function(i) {
538                         this._instanceLoaded(i);
539                     }, this),
540                     args = Y.clone(this.get('use')),
541                     config = {
542                         debug: false,
543                         win: res.win,
544                         doc: res.doc
545                     },
546                     fn = Y.bind(function() {
547                         config = this._resolveWinDoc(config);
548                         inst = YUI(config);
549
550                         try {
551                             inst.use('node-base', cb);
552                             if (timer) {
553                                 clearInterval(timer);
554                             }
555                         } catch (e) {
556                             timer = setInterval(function() {
557                                 fn();
558                             }, 350);
559                         }
560                     }, this);
561
562                 args.push(fn);
563
564                 Y.use.apply(Y, args);
565
566             }, this));
567
568             return this;
569         },
570         /**
571         * @private
572         * @method _handleFocus
573         * @description Does some tricks on focus to set the proper cursor position.
574         */
575         _handleFocus: function() {
576             var inst = this.getInstance(),
577                 sel = new inst.Selection();
578
579             if (sel.anchorNode) {
580                 var n = sel.anchorNode,
581                     c = n.get('childNodes');
582
583                 if (c.size() == 1) {
584                     if (c.item(0).test('br')) {
585                         sel.selectNode(n, true, false);
586                     }
587                     if (c.item(0).test('p')) {
588                         n = c.item(0).one('br.yui-cursor').get('parentNode');
589                         sel.selectNode(n, true, false);
590                     }
591                 }
592             }
593         },
594         /**
595         * @method focus
596         * @description Set the focus to the iframe
597         * @param {Function} fn Callback function to execute after focus happens        
598         * @return {Frame}
599         * @chainable        
600         */
601         focus: function(fn) {
602             if (Y.UA.ie) {
603                 try {
604                     Y.one('win').focus();
605                     this.getInstance().one('win').focus();
606                 } catch (ierr) {
607                 }
608                 if (fn === true) {
609                     this._handleFocus();
610                 }
611                 if (Y.Lang.isFunction(fn)) {
612                     fn();
613                 }
614             } else {
615                 try {
616                     Y.one('win').focus();
617                     Y.later(100, this, function() {
618                         this.getInstance().one('win').focus();
619                         if (fn === true) {
620                             this._handleFocus();
621                         }
622                         if (Y.Lang.isFunction(fn)) {
623                             fn();
624                         }
625                     });
626                 } catch (ferr) {
627                 }
628             }
629             return this;
630         },
631         /**
632         * @method show
633         * @description Show the iframe instance
634         * @return {Frame}
635         * @chainable        
636         */
637         show: function() {
638             this._iframe.setStyles({
639                 position: 'static',
640                 left: ''
641             });
642             if (Y.UA.gecko) {
643                 try {
644                     this._instance.config.doc.designMode = 'on';
645                 } catch (e) { }
646                 this.focus();
647             }           
648             return this;
649         },
650         /**
651         * @method hide
652         * @description Hide the iframe instance
653         * @return {Frame}
654         * @chainable        
655         */
656         hide: function() {
657             this._iframe.setStyles({
658                 position: 'absolute',
659                 left: '-999999px'
660             });
661             return this;
662         }
663     }, {
664         
665         /**
666         * @static
667         * @property DOM_EVENTS
668         * @description The DomEvents that the frame automatically attaches and bubbles
669         * @type Object
670         */
671         DOM_EVENTS: {
672             dblclick: 1,
673             click: 1,
674             paste: 1,
675             mouseup: 1,
676             mousedown: 1,
677             keyup: 1,
678             keydown: 1,
679             keypress: 1,
680             activate: 1,
681             deactivate: 1,
682             beforedeactivate: 1,
683             focusin: 1,
684             focusout: 1
685         },
686
687         /**
688         * @static
689         * @property DEFAULT_CSS
690         * @description The default css used when creating the document.
691         * @type String
692         */
693         //DEFAULT_CSS: 'html { height: 95%; } body { padding: 7px; background-color: #fff; font: 13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a, a:visited, a:hover { color: blue !important; text-decoration: underline !important; cursor: text !important; } img { cursor: pointer !important; border: none; }',
694         DEFAULT_CSS: 'body { background-color: #fff; font: 13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a, a:visited, a:hover { color: blue !important; text-decoration: underline !important; cursor: text !important; } img { cursor: pointer !important; border: none; }',
695         /**
696         * @static
697         * @property HTML
698         * @description The template string used to create the iframe
699         * @type String
700         */
701         //HTML: '<iframe border="0" frameBorder="0" marginWidth="0" marginHeight="0" leftMargin="0" topMargin="0" allowTransparency="true" width="100%" height="99%"></iframe>',
702         HTML: '<iframe border="0" frameBorder="0" marginWidth="0" marginHeight="0" leftMargin="0" topMargin="0" allowTransparency="true" width="100%" height="99%"></iframe>',
703         /**
704         * @static
705         * @property PAGE_HTML
706         * @description The template used to create the page when created dynamically.
707         * @type String
708         */
709         PAGE_HTML: '<html dir="{DIR}" lang="{LANG}"><head><title>{TITLE}</title>{META}<base href="{BASE_HREF}"/>{LINKED_CSS}<style id="editor_css">{DEFAULT_CSS}</style>{EXTRA_CSS}</head><body>{CONTENT}</body></html>',
710
711         /**
712         * @static
713         * @method getDocType
714         * @description Parses document.doctype and generates a DocType to match the parent page, if supported.
715         * For IE8, it grabs document.all[0].nodeValue and uses that. For IE < 8, it falls back to Frame.DOC_TYPE.
716         * @returns {String} The normalized DocType to apply to the iframe
717         */
718         getDocType: function() {
719             var dt = Y.config.doc.doctype,
720                 str = Frame.DOC_TYPE;
721
722             if (dt) {
723                 str = '<!DOCTYPE ' + dt.name + ((dt.publicId) ? ' ' + dt.publicId : '') + ((dt.systemId) ? ' ' + dt.systemId : '') + '>';
724             } else {
725                 if (Y.config.doc.all) {
726                     dt = Y.config.doc.all[0];
727                     if (dt.nodeType) {
728                         if (dt.nodeType === 8) {
729                             if (dt.nodeValue) {
730                                 if (dt.nodeValue.toLowerCase().indexOf('doctype') !== -1) {
731                                     str = '<!' + dt.nodeValue + '>';
732                                 }
733                             }
734                         }
735                     }
736                 }
737             }
738             return str;
739         },
740         /**
741         * @static
742         * @property DOC_TYPE
743         * @description The DOCTYPE to prepend to the new document when created. Should match the one on the page being served.
744         * @type String
745         */
746         DOC_TYPE: '<!DOCTYPE HTML PUBLIC "-/'+'/W3C/'+'/DTD HTML 4.01/'+'/EN" "http:/'+'/www.w3.org/TR/html4/strict.dtd">',
747         /**
748         * @static
749         * @property META
750         * @description The meta-tag for Content-Type to add to the dynamic document
751         * @type String
752         */
753         //META: '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">',
754         META: '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>',
755         /**
756         * @static
757         * @property NAME
758         * @description The name of the class (frame)
759         * @type String
760         */
761         NAME: 'frame',
762         ATTRS: {
763             /**
764             * @attribute title
765             * @description The title to give the blank page.
766             * @type String
767             */
768             title: {
769                 value: 'Blank Page'
770             },
771             /**
772             * @attribute dir
773             * @description The default text direction for this new frame. Default: ltr
774             * @type String
775             */
776             dir: {
777                 value: 'ltr'
778             },
779             /**
780             * @attribute lang
781             * @description The default language. Default: en-US
782             * @type String
783             */
784             lang: {
785                 value: 'en-US'
786             },
787             /**
788             * @attribute src
789             * @description The src of the iframe/window. Defaults to javascript:;
790             * @type String
791             */
792             src: {
793                 //Hackish, IE needs the false in the Javascript URL
794                 value: 'javascript' + ((Y.UA.ie) ? ':false' : ':') + ';'
795             },
796             /**
797             * @attribute designMode
798             * @description Should designMode be turned on after creation.
799             * @writeonce
800             * @type Boolean
801             */
802             designMode: {
803                 writeOnce: true,
804                 value: false
805             },
806             /**
807             * @attribute content
808             * @description The string to inject into the body of the new frame/window.
809             * @type String
810             */
811             content: {
812                 value: '<br>',
813                 setter: '_setHTML',
814                 getter: '_getHTML'
815             },
816             /**
817             * @attribute basehref
818             * @description The base href to use in the iframe.
819             * @type String
820             */
821             basehref: {
822                 value: false,
823                 getter: '_resolveBaseHref'
824             },
825             /**
826             * @attribute use
827             * @description Array of modules to include in the scoped YUI instance at render time. Default: ['none', 'selector-css2']
828             * @writeonce
829             * @type Array
830             */
831             use: {
832                 writeOnce: true,
833                 value: ['substitute', 'node', 'node-style', 'selector-css3']
834             },
835             /**
836             * @attribute container
837             * @description The container to append the iFrame to on render.
838             * @type String/HTMLElement/Node
839             */
840             container: {
841                 value: 'body',
842                 setter: function(n) {
843                     return Y.one(n);
844                 }
845             },
846             /**
847             * @attribute node
848             * @description The Node instance of the iframe.
849             * @type Node
850             */
851             node: {
852                 readOnly: true,
853                 value: null,
854                 getter: function() {
855                     return this._iframe;
856                 }
857             },
858             /**
859             * @attribute id
860             * @description Set the id of the new Node. (optional)
861             * @type String
862             * @writeonce
863             */
864             id: {
865                 writeOnce: true,
866                 getter: function(id) {
867                     if (!id) {
868                         id = 'iframe-' + Y.guid();
869                     }
870                     return id;
871                 }
872             },
873             /**
874             * @attribute linkedcss
875             * @description An array of url's to external linked style sheets
876             * @type String
877             */
878             linkedcss: {
879                 value: '',
880                 getter: '_getLinkedCSS',
881                 setter: '_setLinkedCSS'
882             },
883             /**
884             * @attribute extracss
885             * @description A string of CSS to add to the Head of the Editor
886             * @type String
887             */
888             extracss: {
889                 value: '',
890                 setter: '_setExtraCSS'
891             },
892             /**
893             * @attribute host
894             * @description A reference to the Editor instance 
895             * @type Object
896             */
897             host: {
898                 value: false
899             },
900             /**
901             * @attribute defaultblock
902             * @description The default tag to use for block level items, defaults to: p
903             * @type String
904             */            
905             defaultblock: {
906                 value: 'p'
907             }
908         }
909     });
910
911
912     Y.Frame = Frame;
913
914
915
916 }, '3.3.0' ,{requires:['base', 'node', 'selector-css3', 'substitute'], skinnable:false});