examples/bootstrap/dashboard3.bjs
[roojs1] / roojs-debug.js
index 273ec41..8b6778e 100644 (file)
@@ -9569,7 +9569,7 @@ if(opt.anim.isAnimated()){
         
         /**
          * Sets or Returns the value the dom attribute value
-         * @param {String} name The attribute name
+         * @param {String|Object} name The attribute name (or object to set multiple attributes)
          * @param {String} value (optional) The value to set the attribute to
          * @return {String} The attribute value
          */
@@ -9578,6 +9578,14 @@ if(opt.anim.isAnimated()){
                 this.dom.setAttribute(name, arguments[1]);
                 return arguments[1];
             }
+            if (typeof(name) == 'object') {
+                for(var i in name) {
+                    this.attr(i, name[i]);
+                }
+                return name;
+            }
+            
+            
             if (!this.dom.hasAttribute(name)) {
                 return undefined;
             }
@@ -15733,6 +15741,9 @@ Roo.extend(Roo.BoxComponent, Roo.Component, {
  * @class Roo.XComponent
  * A delayed Element creator...
  * Or a way to group chunks of interface together.
+ * technically this is a wrapper around a tree of Roo elements (which defines a 'module'),
+ *  used in conjunction with XComponent.build() it will create an instance of each element,
+ *  then call addxtype() to build the User interface.
  * 
  * Mypart.xyx = new Roo.XComponent({
 
@@ -15756,6 +15767,37 @@ Roo.extend(Roo.BoxComponent, Roo.Component, {
  * It can be used to build a big heiracy, with parent etc.
  * or you can just use this to render a single compoent to a dom element
  * MYPART.render(Roo.Element | String(id) | dom_element )
+ *
+ *
+ * Usage patterns.
+ *
+ * Classic Roo
+ *
+ * Roo is designed primarily as a single page application, so the UI build for a standard interface will
+ * expect a single 'TOP' level module normally indicated by the 'parent' of the XComponent definition being defined as false.
+ *
+ * Each sub module is expected to have a parent pointing to the class name of it's parent module.
+ *
+ * When the top level is false, a 'Roo.BorderLayout' is created and the element is flagged as 'topModule'
+ * - if mulitple topModules exist, the last one is defined as the top module.
+ *
+ * Embeded Roo
+ * 
+ * When the top level or multiple modules are to embedded into a existing HTML page,
+ * the parent element can container '#id' of the element where the module will be drawn.
+ *
+ * Bootstrap Roo
+ *
+ * Unlike classic Roo, the bootstrap tends not to be used as a single page.
+ * it relies more on a include mechanism, where sub modules are included into an outer page.
+ * This is normally managed by the builder tools using Roo.apply( options, Included.Sub.Module )
+ * 
+ * Bootstrap Roo Included elements
+ *
+ * Our builder application needs the ability to preview these sub compoennts. They will normally have parent=false set,
+ * hence confusing the component builder as it thinks there are multiple top level elements. 
+ *
+ * 
  * 
  * @extends Roo.util.Observable
  * @constructor
@@ -15856,21 +15898,47 @@ Roo.extend(Roo.XComponent, Roo.util.Observable, {
         
         el = el || false;
         var hp = this.parent ? 1 : 0;
+        Roo.log(this);
         
         if (!el && typeof(this.parent) == 'string' && this.parent.substring(0,1) == '#') {
             // if parent is a '#.....' string, then let's use that..
-            var ename = this.parent.substr(1)
-            this.parent = (this.parent == '#bootstrap') ? { el : true}  : false; // flags it as a top module...
-            el = Roo.get(ename);
+            var ename = this.parent.substr(1);
+            this.parent = false;
+            Roo.log(ename);
+            switch (ename) {
+                case 'bootstrap-body' :
+                    if (typeof(Roo.bootstrap.Body) != 'undefined') {
+                        this.parent = { el :  new  Roo.bootstrap.Body() };
+                        Roo.log("setting el to doc body");
+                         
+                    } else {
+                        throw "Container is bootstrap body, but Roo.bootstrap.Body is not defined";
+                    }
+                    break;
+                case 'bootstrap':
+                    this.parent = { el : true};
+                    // fall through
+                default:
+                    el = Roo.get(ename);
+                    break;
+            }
+                
+            
             if (!el && !this.parent) {
                 Roo.log("Warning - element can not be found :#" + ename );
                 return;
             }
         }
+        Roo.log("EL:");Roo.log(el);
+        Roo.log("this.parent.el:");Roo.log(this.parent.el);
+        
         var tree = this._tree ? this._tree() : this.tree();
 
+        // altertive root elements ??? - we need a better way to indicate these.
+        var is_alt = (typeof(Roo.bootstrap) != 'undefined' && tree.xns == Roo.bootstrap) ||
+                        (typeof(Roo.mailer) != 'undefined' && tree.xns == Roo.mailer) ;
         
-        if (!this.parent && typeof(Roo.bootstrap) != 'undefined' && tree.xns == Roo.bootstrap) {
+        if (!this.parent && is_alt) {
             //el = Roo.get(document.body);
             this.parent = { el : true };
         }
@@ -27109,7 +27177,11 @@ Roo.extend(Roo.TabPanelItem, Roo.util.Observable, {
     autoSize : function(){
         //this.el.beginMeasure();
         this.textEl.setWidth(1);
-        this.setWidth(this.textEl.dom.scrollWidth+this.pnode.getPadding("lr")+this.inner.getPadding("lr"));
+        /*
+         *  #2804 [new] Tabs in Roojs
+         *  increase the width by 2-4 pixels to prevent the ellipssis showing in chrome
+         */
+        this.setWidth(this.textEl.dom.scrollWidth+this.pnode.getPadding("lr")+this.inner.getPadding("lr") + 2);
         //this.el.endMeasure();
     },
 
@@ -40176,6 +40248,17 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
 
 Roo.form.ComboBoxArray = function(config)
 {
+    this.addEvents({
+        /**
+         * @event remove
+         * Fires when remove the value from the list
+            * @param {Roo.form.ComboBoxArray} _self This combo box array
+             * @param {Roo.form.ComboBoxArray.Item} item removed item
+            */
+        'remove' : true
+        
+        
+    });
     
     Roo.form.ComboBoxArray.superclass.constructor.call(this, config);
     
@@ -40587,11 +40670,12 @@ Roo.extend(Roo.form.ComboBoxArray.Item, Roo.BoxComponent, {
    
     remove : function()
     {
-        
         this.cb.items.remove(this);
         this.el.child('img').un('click', this.remove, this);
         this.el.remove();
         this.cb.updateHiddenEl();
+        
+        this.cb.fireEvent('remove', this.cb, this);
     }
 });/*
  * Based on:
@@ -41280,10 +41364,12 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         //var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
         // this copies styles from the containing element into thsi one..
         // not sure why we need all of this..
-        var ss = this.el.getStyles('font-size', 'background-image', 'background-repeat');
-        ss['background-attachment'] = 'fixed'; // w3c
+        //var ss = this.el.getStyles('font-size', 'background-image', 'background-repeat');
+        
+        //var ss = this.el.getStyles( 'background-image', 'background-repeat');
+        //ss['background-attachment'] = 'fixed'; // w3c
         dbody.bgProperties = 'fixed'; // ie
-        Roo.DomHelper.applyStyles(dbody, ss);
+        //Roo.DomHelper.applyStyles(dbody, ss);
         Roo.EventManager.on(this.doc, {
             //'mousedown': this.onEditorEvent,
             'mouseup': this.onEditorEvent,
@@ -42004,8 +42090,203 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         this.cleanUpChildren(node);
         
         
-    }
-    
+    },
+    /**
+     * Clean up MS wordisms...
+     */
+    cleanWord : function(node)
+    {
+        var _t = this;
+        var cleanWordChildren = function()
+        {
+            if (!node.childNodes.length) {
+                return;
+            }
+            for (var i = node.childNodes.length-1; i > -1 ; i--) {
+               _t.cleanWord(node.childNodes[i]);
+            }
+        }
+        
+        
+        if (!node) {
+            this.cleanWord(this.doc.body);
+            return;
+        }
+        if (node.nodeName == "#text") {
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        if (node.nodeName == "#comment") {
+            node.parentNode.removeChild(node);
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        
+        if (node.tagName.toLowerCase().match(/^(style|script|applet|embed|noframes|noscript)$/)) {
+            node.parentNode.removeChild(node);
+            return;
+        }
+        
+        // remove - but keep children..
+        if (node.tagName.toLowerCase().match(/^(meta|link|\\?xml:|st1:|o:|font)/)) {
+            while (node.childNodes.length) {
+                var cn = node.childNodes[0];
+                node.removeChild(cn);
+                node.parentNode.insertBefore(cn, node);
+            }
+            node.parentNode.removeChild(node);
+            cleanWordChildren();
+            return;
+        }
+        // clean styles
+        if (node.className.length) {
+            
+            var cn = node.className.split(/\W+/);
+            var cna = [];
+            Roo.each(cn, function(cls) {
+                if (cls.match(/Mso[a-zA-Z]+/)) {
+                    return;
+                }
+                cna.push(cls);
+            });
+            node.className = cna.length ? cna.join(' ') : '';
+            if (!cna.length) {
+                node.removeAttribute("class");
+            }
+        }
+        
+        if (node.hasAttribute("lang")) {
+            node.removeAttribute("lang");
+        }
+        
+        if (node.hasAttribute("style")) {
+            
+            var styles = node.getAttribute("style").split(";");
+            var nstyle = [];
+            Roo.each(styles, function(s) {
+                if (!s.match(/:/)) {
+                    return;
+                }
+                var kv = s.split(":");
+                if (kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)) {
+                    return;
+                }
+                // what ever is left... we allow.
+                nstyle.push(s);
+            });
+            node.setAttribute("style", nstyle.length ? nstyle.join(';') : '');
+            if (!nstyle.length) {
+                node.removeAttribute('style');
+            }
+        }
+        
+        cleanWordChildren();
+        
+        
+    },
+    domToHTML : function(currentElement, depth, nopadtext) {
+        
+            depth = depth || 0;
+            nopadtext = nopadtext || false;
+        
+            if (!currentElement) {
+                return this.domToHTML(this.doc.body);
+            }
+            
+            //Roo.log(currentElement);
+            var j;
+            var allText = false;
+            var nodeName = currentElement.nodeName;
+            var tagName = Roo.util.Format.htmlEncode(currentElement.tagName);
+            
+            if  (nodeName == '#text') {
+                return currentElement.nodeValue;
+            }
+            
+            
+            var ret = '';
+            if (nodeName != 'BODY') {
+                 
+                var i = 0;
+                // Prints the node tagName, such as <A>, <IMG>, etc
+                if (tagName) {
+                    var attr = [];
+                    for(i = 0; i < currentElement.attributes.length;i++) {
+                        // quoting?
+                        var aname = currentElement.attributes.item(i).name;
+                        if (!currentElement.attributes.item(i).value.length) {
+                            continue;
+                        }
+                        attr.push(aname + '="' + Roo.util.Format.htmlEncode(currentElement.attributes.item(i).value) + '"' );
+                    }
+                    
+                    ret = "<"+currentElement.tagName+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">";
+                } 
+                else {
+                    
+                    // eack
+                }
+            } else {
+                tagName = false;
+            }
+            if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(tagName) > -1) {
+                return ret;
+            }
+            if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN'].indexOf(tagName) > -1) { // or code?
+                nopadtext = true;
+            }
+            
+            
+            // Traverse the tree
+            i = 0;
+            var currentElementChild = currentElement.childNodes.item(i);
+            var allText = true;
+            var innerHTML  = '';
+            lastnode = '';
+            while (currentElementChild) {
+                // Formatting code (indent the tree so it looks nice on the screen)
+                var nopad = nopadtext;
+                if (lastnode == 'SPAN') {
+                    nopad  = true;
+                }
+                // text
+                if  (currentElementChild.nodeName == '#text') {
+                    var toadd = Roo.util.Format.htmlEncode(currentElementChild.nodeValue);
+                    if (!nopad && toadd.length > 80) {
+                        innerHTML  += "\n" + (new Array( depth + 1 )).join( "  "  );
+                    }
+                    innerHTML  += toadd;
+                    
+                    i++;
+                    currentElementChild = currentElement.childNodes.item(i);
+                    lastNode = '';
+                    continue;
+                }
+                allText = false;
+                
+                innerHTML  += nopad ? '' : "\n" + (new Array( depth + 1 )).join( "  "  );
+                    
+                // Recursively traverse the tree structure of the child node
+                innerHTML   += this.domToHTML(currentElementChild, depth+1, nopadtext);
+                lastnode = currentElementChild.nodeName;
+                i++;
+                currentElementChild=currentElement.childNodes.item(i);
+            }
+            
+            ret += innerHTML;
+            
+            if (!allText) {
+                    // The remaining code is mostly for formatting the tree
+                ret+= nopadtext ? '' : "\n" + (new Array( depth  )).join( "  "  );
+            }
+            
+            
+            if (tagName) {
+                ret+= "</"+tagName+">";
+            }
+            return ret;
+            
+        }
     
     // hide stuff that is not compatible
     /**
@@ -42951,11 +43232,44 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                         c.select('[style]').each(function(s) {
                             s.dom.style.removeProperty(a.actiontype);
                         });
-                        
+                        editorcore.syncValue();
                     },
                     tabIndex:-1
                 });
             }
+            cmenu.menu.items.push({
+                actiontype : 'word',
+                html: 'Remove MS Word Formating',
+                handler: function(a,b) {
+                    editorcore.cleanWord();
+                    editorcore.syncValue();
+                },
+                tabIndex:-1
+            });
+            
+            cmenu.menu.items.push({
+                actiontype : 'all',
+                html: 'Remove All Styles',
+                handler: function(a,b) {
+                    
+                    var c = Roo.get(editorcore.doc.body);
+                    c.select('[style]').each(function(s) {
+                        s.dom.removeAttribute('style');
+                    });
+                    editorcore.syncValue();
+                },
+                tabIndex:-1
+            });
+             cmenu.menu.items.push({
+                actiontype : 'word',
+                html: 'Tidy HTML Source',
+                handler: function(a,b) {
+                    editorcore.doc.body.innerHTML = editorcore.domToHTML();
+                    editorcore.syncValue();
+                },
+                tabIndex:-1
+            });
+            
             
             tb.add(cmenu);
         }