Roo/Template.js
[roojs1] / roojs-debug.js
index 55d4257..961dc5c 100644 (file)
@@ -1006,7 +1006,7 @@ Format  Output      Description
   H      15         24-hour format of an hour with leading zeros
   i      05         Minutes with leading zeros
   s      01         Seconds, with leading zeros
-  O      -0600      Difference to Greenwich time (GMT) in hours
+  O      -0600      Difference to Greenwich time (GMT) in hours (Allows +08, without minutes)
   P      -06:00     Difference to Greenwich time (GMT) with colon between hours and minutes
   T      CST        Timezone setting of the machine running the code
   Z      -21600     Timezone offset in seconds (negative if west of UTC, positive if east)
@@ -1387,7 +1387,9 @@ Date.formatCodeToRegex = function(character, currentGroup) {
                 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n", // -12hrs <= GMT offset <= 14hrs
                 "    (sn + String.leftPad(hr, 2, 0) + String.leftPad(mn, 2, 0)) : null;\n"
             ].join(""),
-            s:"([+\-]\\d{4})"};
+            s:"([+\-]\\d{2,4})"};
+    
+    
     case "P":
        return {g:1,
                c:[
@@ -32846,10 +32848,20 @@ Roo.extend(Roo.tree.RootTreeNodeUI, Roo.tree.TreeNodeUI, {
  * nodes from a specified URL. The response must be a javascript Array definition
  * who's elements are node definition objects. eg:
  * <pre><code>
-   [{ 'id': 1, 'text': 'A folder Node', 'leaf': false },
-    { 'id': 2, 'text': 'A leaf Node', 'leaf': true }]
+{  success : true,
+   data :      [
+   
+    { 'id': 1, 'text': 'A folder Node', 'leaf': false },
+    { 'id': 2, 'text': 'A leaf Node', 'leaf': true }
+    ]
+}
+
+
 </code></pre>
  * <br><br>
+ * The old style respose with just an array is still supported, but not recommended.
+ * <br><br>
+ *
  * A server request is sent, and child nodes are loaded only when a node is expanded.
  * The loading node's id is passed to the server under the parameter name "node" to
  * enable the server to produce the correct child nodes.
@@ -33062,7 +33074,11 @@ Roo.extend(Roo.tree.TreeLoader, Roo.util.Observable, {
             
             var o = Roo.decode(json);
             
-            if (!o.success) {
+            if (this.root === false && typeof(o.success) != undefined) {
+                this.root = 'data'; // the default behaviour for list like data..
+                }
+                
+            if (this.root !== false &&  !o.success) {
                 // it's a failure condition.
                 var a = response.argument;
                 this.fireEvent("loadexception", this, a.node, response);
@@ -33070,8 +33086,10 @@ Roo.extend(Roo.tree.TreeLoader, Roo.util.Observable, {
                 return;
             }
             
+            
+            
             if (this.root !== false) {
-                o = o[this.root];
+                 o = o[this.root];
             }
             
             for(var i = 0, len = o.length; i < len; i++){
@@ -38611,7 +38629,8 @@ Roo.extend(Roo.form.Radio, Roo.form.Checkbox, {
  * @class Ext.form.HtmlEditor
  * @extends Ext.form.Field
  * Provides a lightweight HTML Editor component.
- * WARNING - THIS CURRENTlY ONLY WORKS ON FIREFOX - USE FCKeditor for a cross platform version
+ *
+ * This has been tested on Fireforx / Chrome.. IE may not be so great..
  * 
  * <br><br><b>Note: The focus/blur and validation marking functionality inherited from Ext.form.Field is NOT
  * supported by this editor.</b><br/><br/>
@@ -38787,6 +38806,11 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             
         }
         
+        st +=  '<style type="text/css">' +
+            'IMG { cursor: pointer } ' +
+        '</style>';
+
+        
         return '<html><head>' + st  +
             //<style type="text/css">' +
             //'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}' +
@@ -39015,7 +39039,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     syncValue : function(){
         if(this.initialized){
             var bd = (this.doc.body || this.doc.documentElement);
-            //this.cleanUpPaste();
+            //this.cleanUpPaste(); -- this is done else where and causes havoc..
             var html = bd.innerHTML;
             if(Roo.isSafari){
                 var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
@@ -39025,6 +39049,10 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
             }
             html = this.cleanHtml(html);
+            // fix up the special chars..
+            html = html.replace(/([\x80-\uffff])/g, function (a, b) {
+                return "&#"+b.charCodeAt()+";" 
+            });
             if(this.fireEvent('beforesync', this, html) !== false){
                 this.el.dom.value = html;
                 this.fireEvent('sync', this, html);
@@ -39245,17 +39273,23 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         this.doc.execCommand(cmd, false, value === undefined ? null : value);
         this.syncValue();
     },
-
    
     /**
      * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated
      * to insert tRoo.
-     * @param {String} text
+     * @param {String} text | dom node.. 
      */
-    insertAtCursor : function(text){
+    insertAtCursor : function(text)
+    {
+        
+        
+        
         if(!this.activated){
             return;
         }
+        /*
         if(Roo.isIE){
             this.win.focus();
             var r = this.doc.selection.createRange();
@@ -39264,10 +39298,35 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 r.pasteHTML(text);
                 this.syncValue();
                 this.deferFocus();
+            
             }
-        }else if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
+            return;
+        }
+        */
+        if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
             this.win.focus();
-            this.execCmd('InsertHTML', text);
+            
+            
+            // from jquery ui (MIT licenced)
+            var range, node;
+            var win = this.win;
+            
+            if (win.getSelection && win.getSelection().getRangeAt) {
+                range = win.getSelection().getRangeAt(0);
+                node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
+                range.insertNode(node);
+            } else if (win.document.selection && win.document.selection.createRange) {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                win.document.selection.createRange().pasteHTML(txt);
+            } else {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                this.execCmd('InsertHTML', txt);
+            } 
+            
+            this.syncValue();
+            
             this.deferFocus();
         }
     },
@@ -39281,17 +39340,19 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 switch(c){
                     case 'b':
                         cmd = 'bold';
-                    break;
+                        break;
                     case 'i':
                         cmd = 'italic';
-                    break;
+                        break;
+                    
                     case 'u':
                         cmd = 'underline';
                         break;
+                    
                     case 'v':
                         this.cleanUpPaste.defer(100, this);
                         return;
-                    break;
+                        
                 }
                 if(cmd){
                     this.win.focus();
@@ -40193,6 +40254,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                     html: this.specialChars[i],
                     handler: function(a,b) {
                         editor.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
+                        //editor.insertAtCursor(a.html);
                         
                     },
                     tabIndex:-1
@@ -40758,13 +40820,38 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
      * Protected method that will not generally be called directly. It triggers
      * a toolbar update by reading the markup state of the current selection in the editor.
      */
-    updateToolbar: function(ignore_a,ignore_b,sel){
+    updateToolbar: function(editor,ev,sel){
 
-        
+        //Roo.log(ev);
+        // capture mouse up - this is handy for selecting images..
+        // perhaps should go somewhere else...
         if(!this.editor.activated){
              this.editor.onFirstFocus();
             return;
         }
+        
+        // http://developer.yahoo.com/yui/docs/simple-editor.js.html
+        // selectNode - might want to handle IE?
+        if (ev &&
+            (ev.type == 'mouseup' || ev.type == 'click' ) &&
+            ev.target && ev.target.tagName == 'IMG') {
+            // they have click on an image...
+            // let's see if we can change the selection...
+            sel = ev.target;
+         
+              var nodeRange = sel.ownerDocument.createRange();
+            try {
+                nodeRange.selectNode(sel);
+            } catch (e) {
+                nodeRange.selectNodeContents(sel);
+            }
+            //nodeRange.collapse(true);
+            var s = editor.win.getSelection();
+            s.removeAllRanges();
+            s.addRange(nodeRange);
+        }  
+        
+      
         var updateFooter = sel ? false : true;
         
         
@@ -40902,8 +40989,13 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
         
         tb.add(nm+ ":&nbsp;");
         
+        var styles = [];
+        for(var i in this.styles) {
+            styles.push(i);
+        }
+        
         // styles...
-        if (this.styles) {
+        if (styles && styles.length) {
             
             // this needs a multi-select checkbox...
             tb.addField( new Roo.form.ComboBox({
@@ -40925,6 +41017,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                     'select': function(c, r, i) {
                         // initial support only for on class per el..
                         tb.selectedNode.className =  r ? r.get('val') : '';
+                        editor.syncValue();
                     }
                 }
     
@@ -41360,6 +41453,30 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
             this.fireEvent('actioncomplete', this, action);
             
         }else{
+            
+            // failure condition..
+            // we have a scenario where updates need confirming.
+            // eg. if a locking scenario exists..
+            // we look for { errors : { needs_confirm : true }} in the response.
+            if (typeof(action.result.errors.needs_confirm) != 'undefined') {
+                var _t = this;
+                Roo.MessageBox.confirm(
+                    "Change requires confirmation",
+                    action.result.errorMsg,
+                    function(r) {
+                        if (r != 'yes') {
+                            return;
+                        }
+                        _t.doAction('submit', { params :  { _submit_confirmed : 1 } }  );
+                    }
+                    
+                );
+                
+                
+                
+                return;
+            }
+            
             Roo.callback(o.failure, o.scope, [this, action]);
             // show an error message if no failed handler is set..
             if (!this.hasListener('actionfailed')) {
@@ -51266,7 +51383,15 @@ Roo.grid.CellSelectionModel = function(config){
             * You can use this to trigger add new row.
             * @param {SelectionModel} this
             */
-           "tabend" : true
+           "tabend" : true,
+         /**
+            * @event beforeeditnext
+            * Fires before the next editable sell is made active
+            * You can use this to skip to another cell or fire the tabend
+            *    if you set cell to false
+            * @param {Object} eventdata object : { cell : [ row, col ] } 
+            */
+           "beforeeditnext" : true
     });
     Roo.grid.CellSelectionModel.superclass.constructor.call(this);
 };
@@ -51488,15 +51613,22 @@ Roo.extend(Roo.grid.CellSelectionModel, Roo.grid.AbstractSelectionModel,  {
             
             e.stopEvent();
             
-        }else if(k == e.ENTER &&  !e.ctrlKey){
+        } else if(k == e.ENTER &&  !e.ctrlKey){
             ed.completeEdit();
             e.stopEvent();
             newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
-        }else if(k == e.ESC){
+        
+               } else if(k == e.ESC){
             ed.cancelEdit();
         }
-        
-        
+               
+        if (newCell) {
+            var ecall = { cell : newCell, forward : forward };
+            this.fireEvent('beforeeditnext', ecall );
+            newCell = ecall.cell;
+                       forward = ecall.forward;
+        }
+               
         if(newCell){
             //Roo.log('next cell after edit');
             g.startEditing.defer(100, g, [newCell[0], newCell[1]]);
@@ -52335,13 +52467,7 @@ Roo.XComponent = function(cfg) {
             * Fires when this the componnt is built
             * @param {Roo.XComponent} c the component
             */
-        'built' : true,
-        /**
-            * @event buildcomplete
-            * Fires on the top level element when all elements have been built
-            * @param {Roo.XComponent} c the top level component.
-         */
-        'buildcomplete' : true
+        'built' : true
         
     });
     this.region = this.region || 'center'; // default..
@@ -52409,6 +52535,12 @@ Roo.extend(Roo.XComponent, Roo.util.Observable, {
      */
     items : false,
     
+    /**
+     * @property _tree
+     * The method that retuns the tree of parts that make up this compoennt 
+     * @type {function}
+     */
+    _tree  : false,
     
      /**
      * render
@@ -52436,7 +52568,7 @@ Roo.extend(Roo.XComponent, Roo.util.Observable, {
         
         if (!this.parent) {
             
-            el = el ? Roo.get(el) : false;
+            el = el ? Roo.get(el) : false;     
             
             // it's a top level one..
             this.parent =  {
@@ -52456,15 +52588,17 @@ Roo.extend(Roo.XComponent, Roo.util.Observable, {
             }
         }
         
-        
+               
+               // The 'tree' method is  '_tree now' 
             
-        var tree = this.tree();
+        var tree = this._tree ? this._tree() : this.tree();
         tree.region = tree.region || this.region;
         this.el = this.parent.el.addxtype(tree);
         this.fireEvent('built', this);
         
         this.panel = this.el;
-        this.layout = this.panel.layout;    
+        this.layout = this.panel.layout;
+               this.parentLayout = this.parent.layout  || false;  
          
     }
     
@@ -52525,6 +52659,25 @@ Roo.apply(Roo.XComponent, {
      * * @param {Object} details about module
      */
     register : function(obj) {
+               
+               Roo.XComponent.event.fireEvent('register', obj);
+               switch(typeof(obj.disabled) ) {
+                       
+                       case 'undefined':
+                               break;
+                       
+                       case 'function':
+                               if ( obj.disabled() ) {
+                                       return;
+                               }
+                               break;
+                       default:
+                               if (obj.disabled) {
+                                       return;
+                               }
+                               break;
+               }
+               
         this.modules.push(obj);
          
     },
@@ -52581,20 +52734,26 @@ Roo.apply(Roo.XComponent, {
             try { 
                 obj.parent = this.toObject(opar);
             } catch(e) {
-                Roo.log(e.toString());
+                Roo.log("parent:toObject failed: " + e.toString());
                 return;
             }
             
             if (!obj.parent) {
+                               Roo.debug && Roo.log("GOT top level module");
+                               Roo.debug && Roo.log(obj);
+                               obj.modules = new Roo.util.MixedCollection(false, 
+                    function(o) { return o.order + '' }
+                );
                 this.topModule = obj;
                 return;
             }
+                       // parent is a string (usually a dom element name..)
             if (typeof(obj.parent) == 'string') {
                 this.elmodules.push(obj);
                 return;
             }
             if (obj.parent.constructor != Roo.XComponent) {
-                Roo.log("Object Parent is not instance of XComponent:" + obj.name)
+                Roo.log("Warning : Object Parent is not instance of XComponent:" + obj.name)
             }
             if (!obj.parent.modules) {
                 obj.parent.modules = new Roo.util.MixedCollection(false, 
@@ -52623,18 +52782,25 @@ Roo.apply(Roo.XComponent, {
         
         // make a flat list in order of modules to build.
         var mods = this.topModule ? [ this.topModule ] : [];
+               
+               // elmodules (is a list of DOM based modules )
         Roo.each(this.elmodules,function(e) { mods.push(e) });
 
         
         // add modules to their parents..
         var addMod = function(m) {
-           // Roo.debug && Roo.log(m.modKey);
+                       Roo.debug && Roo.log("build Order: add: " + m.name);
             
             mods.push(m);
             if (m.modules) {
+                               Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules");
                 m.modules.keySort('ASC',  cmp );
+                               Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules (after sort)");
+
                 m.modules.each(addMod);
-            }
+            } else {
+                               Roo.debug && Roo.log("build Order: no child modules");
+                       }
             // not sure if this is used any more..
             if (m.finalize) {
                 m.finalize.name = m.name + " (clean up) ";
@@ -52670,12 +52836,12 @@ Roo.apply(Roo.XComponent, {
         }
         
         
-        
+        var msg = "Building Interface...";
         // flash it up as modal - so we store the mask!?
         Roo.MessageBox.show({ title: 'loading' });
         Roo.MessageBox.show({
            title: "Please wait...",
-           msg: "Building Interface...",
+           msg: msg,
            width:450,
            progress:true,
            closable:false,
@@ -52689,9 +52855,8 @@ Roo.apply(Roo.XComponent, {
             if (!mods.length) {
                 Roo.debug && Roo.log('hide?');
                 Roo.MessageBox.hide();
-                if (_this.topModule) { 
-                    _this.topModule.fireEvent('buildcomplete', _this.topModule);
-                }
+                Roo.XComponent.event.fireEvent('buildcomplete', _this.topModule);
+                
                 // THE END...
                 return false;   
             }
@@ -52707,12 +52872,11 @@ Roo.apply(Roo.XComponent, {
             } 
             
             
-            
-            Roo.MessageBox.updateProgress(
-                (total  - mods.length)/total,  "Building Interface " + (total  - mods.length) + 
+            msg = "Building Interface " + (total  - mods.length) + 
                     " of " + total + 
-                    (m.name ? (' - ' + m.name) : '')
-                    );
+                    (m.name ? (' - ' + m.name) : '');
+                       Roo.debug && Roo.log(msg);
+            Roo.MessageBox.updateProgress(  (total  - mods.length)/total, msg  );
             
          
             // is the module disabled?
@@ -52726,6 +52890,8 @@ Roo.apply(Roo.XComponent, {
             
             // now build 
             
+                       
+                       
             m.render();
             // it's 10 on top level, and 1 on others??? why...
             return progressRun.defer(10, _this);
@@ -52735,13 +52901,49 @@ Roo.apply(Roo.XComponent, {
      
         
         
-    }
-    
-     
+    },
+       
+       
+       /**
+        * Event Object.
+        *
+        *
+        */
+       event: false, 
+    /**
+        * wrapper for event.on - aliased later..  
+        * Typically use to register a event handler for register:
+        *
+        * eg. Roo.XComponent.on('register', function(comp) { comp.disable = true } );
+        *
+        */
+    on : false
    
     
     
 });
+
+Roo.XComponent.event = new Roo.util.Observable({
+               events : { 
+                       /**
+                        * @event register
+                        * Fires when an Component is registered,
+                        * set the disable property on the Component to stop registration.
+                        * @param {Roo.XComponent} c the component being registerd.
+                        * 
+                        */
+                       'register' : true,
+                       /**
+                        * @event buildcomplete
+                        * Fires on the top level element when all elements have been built
+                        * @param {Roo.XComponent} the top level component.
+                        */
+                       'buildcomplete' : true
+                       
+               }
+});
+
+Roo.XComponent.on = Roo.XComponent.event.on.createDelegate(Roo.XComponent.event); 
  //<script type="text/javascript">