pkg-forms-debug.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:264k
源码类别:

中间件编程

开发平台:

JavaScript

  1.              * @event push
  2.              * Fires when the iframe editor is updated with content from the textarea.
  3.              * @param {HtmlEditor} this
  4.              * @param {String} html
  5.              */
  6.             'push',
  7.              /**
  8.              * @event editmodechange
  9.              * Fires when the editor switches edit modes
  10.              * @param {HtmlEditor} this
  11.              * @param {Boolean} sourceEdit True if source edit, false if standard editing.
  12.              */
  13.             'editmodechange'
  14.         )
  15.     },
  16.     // private
  17.     createFontOptions : function(){
  18.         var buf = [], fs = this.fontFamilies, ff, lc;
  19.         for(var i = 0, len = fs.length; i< len; i++){
  20.             ff = fs[i];
  21.             lc = ff.toLowerCase();
  22.             buf.push(
  23.                 '<option value="',lc,'" style="font-family:',ff,';"',
  24.                     (this.defaultFont == lc ? ' selected="true">' : '>'),
  25.                     ff,
  26.                 '</option>'
  27.             );
  28.         }
  29.         return buf.join('');
  30.     },
  31.     
  32.     /*
  33.      * Protected method that will not generally be called directly. It
  34.      * is called when the editor creates its toolbar. Override this method if you need to
  35.      * add custom toolbar buttons.
  36.      * @param {HtmlEditor} editor
  37.      */
  38.     createToolbar : function(editor){
  39.         
  40.         var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
  41.         
  42.         function btn(id, toggle, handler){
  43.             return {
  44.                 itemId : id,
  45.                 cls : 'x-btn-icon',
  46.                 iconCls: 'x-edit-'+id,
  47.                 enableToggle:toggle !== false,
  48.                 scope: editor,
  49.                 handler:handler||editor.relayBtnCmd,
  50.                 clickEvent:'mousedown',
  51.                 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
  52.                 overflowText: editor.buttonTips[id].title || undefined,
  53.                 tabIndex:-1
  54.             };
  55.         }
  56.         // build the toolbar
  57.         var tb = new Ext.Toolbar({
  58.             renderTo:this.wrap.dom.firstChild
  59.         });
  60.         // stop form submits
  61.         this.mon(tb.el, 'click', function(e){
  62.             e.preventDefault();
  63.         });
  64.         if(this.enableFont && !Ext.isSafari2){
  65.             this.fontSelect = tb.el.createChild({
  66.                 tag:'select',
  67.                 cls:'x-font-select',
  68.                 html: this.createFontOptions()
  69.             });
  70.             this.mon(this.fontSelect, 'change', function(){
  71.                 var font = this.fontSelect.dom.value;
  72.                 this.relayCmd('fontname', font);
  73.                 this.deferFocus();
  74.             }, this);
  75.             tb.add(
  76.                 this.fontSelect.dom,
  77.                 '-'
  78.             );
  79.         }
  80.         if(this.enableFormat){
  81.             tb.add(
  82.                 btn('bold'),
  83.                 btn('italic'),
  84.                 btn('underline')
  85.             );
  86.         }
  87.         if(this.enableFontSize){
  88.             tb.add(
  89.                 '-',
  90.                 btn('increasefontsize', false, this.adjustFont),
  91.                 btn('decreasefontsize', false, this.adjustFont)
  92.             );
  93.         }
  94.         if(this.enableColors){
  95.             tb.add(
  96.                 '-', {
  97.                     itemId:'forecolor',
  98.                     cls:'x-btn-icon',
  99.                     iconCls: 'x-edit-forecolor',
  100.                     clickEvent:'mousedown',
  101.                     tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
  102.                     tabIndex:-1,
  103.                     menu : new Ext.menu.ColorMenu({
  104.                         allowReselect: true,
  105.                         focus: Ext.emptyFn,
  106.                         value:'000000',
  107.                         plain:true,
  108.                         listeners: {
  109.                             scope: this,
  110.                             select: function(cp, color){
  111.                                 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
  112.                                 this.deferFocus();
  113.                             }
  114.                         },
  115.                         clickEvent:'mousedown'
  116.                     })
  117.                 }, {
  118.                     itemId:'backcolor',
  119.                     cls:'x-btn-icon',
  120.                     iconCls: 'x-edit-backcolor',
  121.                     clickEvent:'mousedown',
  122.                     tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
  123.                     tabIndex:-1,
  124.                     menu : new Ext.menu.ColorMenu({
  125.                         focus: Ext.emptyFn,
  126.                         value:'FFFFFF',
  127.                         plain:true,
  128.                         allowReselect: true,
  129.                         listeners: {
  130.                             scope: this,
  131.                             select: function(cp, color){
  132.                                 if(Ext.isGecko){
  133.                                     this.execCmd('useCSS', false);
  134.                                     this.execCmd('hilitecolor', color);
  135.                                     this.execCmd('useCSS', true);
  136.                                     this.deferFocus();
  137.                                 }else{
  138.                                     this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
  139.                                     this.deferFocus();
  140.                                 }
  141.                             }
  142.                         },
  143.                         clickEvent:'mousedown'
  144.                     })
  145.                 }
  146.             );
  147.         }
  148.         if(this.enableAlignments){
  149.             tb.add(
  150.                 '-',
  151.                 btn('justifyleft'),
  152.                 btn('justifycenter'),
  153.                 btn('justifyright')
  154.             );
  155.         }
  156.         if(!Ext.isSafari2){
  157.             if(this.enableLinks){
  158.                 tb.add(
  159.                     '-',
  160.                     btn('createlink', false, this.createLink)
  161.                 );
  162.             }
  163.             if(this.enableLists){
  164.                 tb.add(
  165.                     '-',
  166.                     btn('insertorderedlist'),
  167.                     btn('insertunorderedlist')
  168.                 );
  169.             }
  170.             if(this.enableSourceEdit){
  171.                 tb.add(
  172.                     '-',
  173.                     btn('sourceedit', true, function(btn){
  174.                         this.toggleSourceEdit(!this.sourceEditMode);
  175.                     })
  176.                 );
  177.             }
  178.         }
  179.         this.tb = tb;
  180.     },
  181.     /**
  182.      * Protected method that will not generally be called directly. It
  183.      * is called when the editor initializes the iframe with HTML contents. Override this method if you
  184.      * want to change the initialization markup of the iframe (e.g. to add stylesheets).
  185.      */
  186.     getDocMarkup : function(){
  187.         return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
  188.     },
  189.     // private
  190.     getEditorBody : function(){
  191.         return this.doc.body || this.doc.documentElement;
  192.     },
  193.     // private
  194.     getDoc : function(){
  195.         return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
  196.     },
  197.     // private
  198.     getWin : function(){
  199.         return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
  200.     },
  201.     // private
  202.     onRender : function(ct, position){
  203.         Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
  204.         this.el.dom.style.border = '0 none';
  205.         this.el.dom.setAttribute('tabIndex', -1);
  206.         this.el.addClass('x-hidden');
  207.         if(Ext.isIE){ // fix IE 1px bogus margin
  208.             this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
  209.         }
  210.         this.wrap = this.el.wrap({
  211.             cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
  212.         });
  213.         this.createToolbar(this);
  214.         this.disableItems(true);
  215.         // is this needed?
  216.         // this.tb.doLayout();
  217.         this.createIFrame();
  218.         if(!this.width){
  219.             var sz = this.el.getSize();
  220.             this.setSize(sz.width, this.height || sz.height);
  221.         }
  222.     },
  223.     createIFrame: function(){
  224.         var iframe = document.createElement('iframe');
  225.         iframe.name = Ext.id();
  226.         iframe.frameBorder = '0';
  227.         iframe.src = Ext.isIE ? Ext.SSL_SECURE_URL : "javascript:;";
  228.         this.wrap.dom.appendChild(iframe);
  229.         this.iframe = iframe;
  230.         this.monitorTask = Ext.TaskMgr.start({
  231.             run: this.checkDesignMode,
  232.             scope: this,
  233.             interval:100
  234.         });
  235.     },
  236.     initFrame : function(){
  237.         Ext.TaskMgr.stop(this.monitorTask);
  238.         this.doc = this.getDoc();
  239.         this.win = this.getWin();
  240.         this.doc.open();
  241.         this.doc.write(this.getDocMarkup());
  242.         this.doc.close();
  243.         var task = { // must defer to wait for browser to be ready
  244.             run : function(){
  245.                 if(this.doc.body || this.doc.readyState == 'complete'){
  246.                     Ext.TaskMgr.stop(task);
  247.                     this.doc.designMode="on";
  248.                     this.initEditor.defer(10, this);
  249.                 }
  250.             },
  251.             interval : 10,
  252.             duration:10000,
  253.             scope: this
  254.         };
  255.         Ext.TaskMgr.start(task);
  256.     },
  257.     checkDesignMode : function(){
  258.         if(this.wrap && this.wrap.dom.offsetWidth){
  259.             var doc = this.getDoc();
  260.             if(!doc){
  261.                 return;
  262.             }
  263.             if(!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on'){
  264.                 this.initFrame();
  265.             }
  266.         }
  267.     },
  268.     
  269.     disableItems: function(disabled){
  270.         if(this.fontSelect){
  271.             this.fontSelect.dom.disabled = disabled;
  272.         }
  273.         this.tb.items.each(function(item){
  274.             if(item.itemId != 'sourceedit'){
  275.                 item.setDisabled(disabled);
  276.             }
  277.         });
  278.     },
  279.     // private
  280.     onResize : function(w, h){
  281.         Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
  282.         if(this.el && this.iframe){
  283.             if(typeof w == 'number'){
  284.                 var aw = w - this.wrap.getFrameWidth('lr');
  285.                 this.el.setWidth(this.adjustWidth('textarea', aw));
  286.                 this.tb.setWidth(aw);
  287.                 this.iframe.style.width = Math.max(aw, 0) + 'px';
  288.             }
  289.             if(typeof h == 'number'){
  290.                 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
  291.                 this.el.setHeight(this.adjustWidth('textarea', ah));
  292.                 this.iframe.style.height = Math.max(ah, 0) + 'px';
  293.                 if(this.doc){
  294.                     this.getEditorBody().style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
  295.                 }
  296.             }
  297.         }
  298.     },
  299.     /**
  300.      * Toggles the editor between standard and source edit mode.
  301.      * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
  302.      */
  303.     toggleSourceEdit : function(sourceEditMode){
  304.         if(sourceEditMode === undefined){
  305.             sourceEditMode = !this.sourceEditMode;
  306.         }
  307.         this.sourceEditMode = sourceEditMode === true;
  308.         var btn = this.tb.items.get('sourceedit');
  309.         if(btn.pressed !== this.sourceEditMode){
  310.             btn.toggle(this.sourceEditMode);
  311.             if(!btn.xtbHidden){
  312.                 return;
  313.             }
  314.         }
  315.         if(this.sourceEditMode){
  316.             this.disableItems(true);
  317.             this.syncValue();
  318.             this.iframe.className = 'x-hidden';
  319.             this.el.removeClass('x-hidden');
  320.             this.el.dom.removeAttribute('tabIndex');
  321.             this.el.focus();
  322.         }else{
  323.             if(this.initialized){
  324.                 this.disableItems(false);
  325.             }
  326.             this.pushValue();
  327.             this.iframe.className = '';
  328.             this.el.addClass('x-hidden');
  329.             this.el.dom.setAttribute('tabIndex', -1);
  330.             this.deferFocus();
  331.         }
  332.         var lastSize = this.lastSize;
  333.         if(lastSize){
  334.             delete this.lastSize;
  335.             this.setSize(lastSize);
  336.         }
  337.         this.fireEvent('editmodechange', this, this.sourceEditMode);
  338.     },
  339.     // private used internally
  340.     createLink : function(){
  341.         var url = prompt(this.createLinkText, this.defaultLinkValue);
  342.         if(url && url != 'http:/'+'/'){
  343.             this.relayCmd('createlink', url);
  344.         }
  345.     },
  346.     // private (for BoxComponent)
  347.     adjustSize : Ext.BoxComponent.prototype.adjustSize,
  348.     // private (for BoxComponent)
  349.     getResizeEl : function(){
  350.         return this.wrap;
  351.     },
  352.     // private (for BoxComponent)
  353.     getPositionEl : function(){
  354.         return this.wrap;
  355.     },
  356.     // private
  357.     initEvents : function(){
  358.         this.originalValue = this.getValue();
  359.     },
  360.     /**
  361.      * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
  362.      * @method
  363.      */
  364.     markInvalid : Ext.emptyFn,
  365.     
  366.     /**
  367.      * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
  368.      * @method
  369.      */
  370.     clearInvalid : Ext.emptyFn,
  371.     // docs inherit from Field
  372.     setValue : function(v){
  373.         Ext.form.HtmlEditor.superclass.setValue.call(this, v);
  374.         this.pushValue();
  375.         return this;
  376.     },
  377.     /**
  378.      * Protected method that will not generally be called directly. If you need/want
  379.      * custom HTML cleanup, this is the method you should override.
  380.      * @param {String} html The HTML to be cleaned
  381.      * @return {String} The cleaned HTML
  382.      */
  383.     cleanHtml : function(html){
  384.         html = String(html);
  385.         if(html.length > 5){
  386.             if(Ext.isWebKit){ // strip safari nonsense
  387.                 html = html.replace(/sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
  388.             }
  389.         }
  390.         if(html == this.defaultValue){
  391.             html = '';
  392.         }
  393.         return html;
  394.     },
  395.     /**
  396.      * Protected method that will not generally be called directly. Syncs the contents
  397.      * of the editor iframe with the textarea.
  398.      */
  399.     syncValue : function(){
  400.         if(this.initialized){
  401.             var bd = this.getEditorBody();
  402.             var html = bd.innerHTML;
  403.             if(Ext.isWebKit){
  404.                 var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
  405.                 var m = bs.match(/text-align:(.*?);/i);
  406.                 if(m && m[1]){
  407.                     html = '<div style="'+m[0]+'">' + html + '</div>';
  408.                 }
  409.             }
  410.             html = this.cleanHtml(html);
  411.             if(this.fireEvent('beforesync', this, html) !== false){
  412.                 this.el.dom.value = html;
  413.                 this.fireEvent('sync', this, html);
  414.             }
  415.         }
  416.     },
  417.     
  418.     //docs inherit from Field
  419.     getValue : function() {
  420.         this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
  421.         return Ext.form.HtmlEditor.superclass.getValue.call(this);
  422.     },
  423.     /**
  424.      * Protected method that will not generally be called directly. Pushes the value of the textarea
  425.      * into the iframe editor.
  426.      */
  427.     pushValue : function(){
  428.         if(this.initialized){
  429.             var v = this.el.dom.value;
  430.             if(!this.activated && v.length < 1){
  431.                 v = this.defaultValue;
  432.             }
  433.             if(this.fireEvent('beforepush', this, v) !== false){
  434.                 this.getEditorBody().innerHTML = v;
  435.                 if(Ext.isGecko){
  436.                     // Gecko hack, see: https://bugzilla.mozilla.org/show_bug.cgi?id=232791#c8
  437.                     var d = this.doc,
  438.                         mode = d.designMode.toLowerCase();
  439.                     
  440.                     d.designMode = mode.toggle('on', 'off');
  441.                     d.designMode = mode;
  442.                 }
  443.                 this.fireEvent('push', this, v);
  444.             }
  445.         }
  446.     },
  447.     // private
  448.     deferFocus : function(){
  449.         this.focus.defer(10, this);
  450.     },
  451.     // docs inherit from Field
  452.     focus : function(){
  453.         if(this.win && !this.sourceEditMode){
  454.             this.win.focus();
  455.         }else{
  456.             this.el.focus();
  457.         }
  458.     },
  459.     // private
  460.     initEditor : function(){
  461.         //Destroying the component during/before initEditor can cause issues.
  462.         try{
  463.             var dbody = this.getEditorBody();
  464.             var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
  465.             ss['background-attachment'] = 'fixed'; // w3c
  466.             dbody.bgProperties = 'fixed'; // ie
  467.             Ext.DomHelper.applyStyles(dbody, ss);
  468.             if(this.doc){
  469.                 try{
  470.                     Ext.EventManager.removeAll(this.doc);
  471.                 }catch(e){}
  472.             }
  473.             this.doc = this.getDoc();
  474.             Ext.EventManager.on(this.doc, {
  475.                 'mousedown': this.onEditorEvent,
  476.                 'dblclick': this.onEditorEvent,
  477.                 'click': this.onEditorEvent,
  478.                 'keyup': this.onEditorEvent,
  479.                 buffer:100,
  480.                 scope: this
  481.             });
  482.             if(Ext.isGecko){
  483.                 Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
  484.             }
  485.             if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
  486.                 Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
  487.             }
  488.             this.initialized = true;
  489.             this.fireEvent('initialize', this);
  490.             this.doc.editorInitialized = true;
  491.             this.pushValue();
  492.         }catch(e){}
  493.     },
  494.     // private
  495.     onDestroy : function(){
  496.         if(this.monitorTask){
  497.             Ext.TaskMgr.stop(this.monitorTask);
  498.         }
  499.         if(this.rendered){
  500.             Ext.destroy(this.tb);
  501.             if(this.wrap){
  502.                 this.wrap.dom.innerHTML = '';
  503.                 this.wrap.remove();
  504.             }
  505.         }
  506.         if(this.el){
  507.             this.el.removeAllListeners();
  508.             this.el.remove();
  509.         }
  510.  
  511.         if(this.doc){
  512.             try{
  513.                 Ext.EventManager.removeAll(this.doc);
  514.                 for (var prop in this.doc){
  515.                    delete this.doc[prop];
  516.                 }
  517.             }catch(e){}
  518.         }
  519.         this.purgeListeners();
  520.     },
  521.     // private
  522.     onFirstFocus : function(){
  523.         this.activated = true;
  524.         this.disableItems(false);
  525.         if(Ext.isGecko){ // prevent silly gecko errors
  526.             this.win.focus();
  527.             var s = this.win.getSelection();
  528.             if(!s.focusNode || s.focusNode.nodeType != 3){