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