X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=roojs-ui-debug.js;h=6e15a5e4beec81190fc5835cd2240d970ff1b69e;hb=4661ff928a7659d86219009f55c18ba89fe23059;hp=db88e5e890136310f04e756df8eb9eb1e55e425d;hpb=472a497a012e2d0dcc149b226e986a1c85bcf1ec;p=roojs1 diff --git a/roojs-ui-debug.js b/roojs-ui-debug.js index db88e5e890..6e15a5e4be 100644 --- a/roojs-ui-debug.js +++ b/roojs-ui-debug.js @@ -10302,6 +10302,7 @@ Roo.extend(Roo.LayoutDialog, Roo.BasicDialog, { /** * @class Roo.MessageBox + * @static * Utility class for generating different styles of message boxes. The alias Roo.Msg can also be used. * Example usage: *

@@ -15520,7 +15521,7 @@ Roo.extend(Roo.menu.Item, Roo.menu.BaseItem, {
      */
     text: '',
      /**
-     * @cfg {String} HTML to render in menu
+     * @cfg {String} html to render in menu
      * The text to show on the menu item (HTML version).
      */
     html: '',
@@ -21719,7 +21720,7 @@ Roo.extend(Roo.htmleditor.FilterStyleToTag, Roo.htmleditor.Filter,
         var cn = Array.from(node.childNodes);
         var nn = node;
         Roo.each(inject, function(t) {
-            var nc = node.ownerDocument.createelement(t);
+            var nc = node.ownerDocument.createElement(t);
             nn.appendChild(nc);
             nn = nc;
         });
@@ -21799,6 +21800,42 @@ Roo.extend(Roo.htmleditor.FilterLongBr, Roo.htmleditor.Filter,
 
     }
     
+}); 
+
+/**
+ * @class Roo.htmleditor.FilterBlock
+ * removes id / data-block and contenteditable that are associated with blocks
+ * usage should be done on a cloned copy of the dom
+ * @constructor
+* Run a new Attribute Filter { node : xxxx }}
+* @param {Object} config Configuration options
+ */
+Roo.htmleditor.FilterBlock = function(cfg)
+{
+    Roo.apply(this, cfg);
+    var qa = cfg.node.querySelectorAll;
+    this.removeAttributes('data-block');
+    this.removeAttributes('contenteditable');
+    this.removeAttributes('id');
+    
+}
+
+Roo.apply(Roo.htmleditor.FilterBlock.prototype,
+{
+    node: true, // all tags
+     
+     
+    removeAttributes : function(attr)
+    {
+        var ar = this.node.querySelectorAll('*[' + attr + ']');
+        for (var i =0;i, , etc
-        var ret = "<" + node.tagName +  this.attr(node) ;
-        
-        // elements with no children..
-        if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(node.tagName) > -1) {
-                return ret + '/>';
-        }
-        ret += '>';
-        
-        
-        var cindent = indent === false ? '' : (indent + '  ');
-        // tags where we will not pad the children.. (inline text tags etc..)
-        if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN', 'B', 'I', 'S'].indexOf(node.tagName) > -1) { // or code?
-            cindent = false;
-            
-            
-        }
-        
-        var cn = this.cn(node, cindent );
-        
-        return ret + cn  + '';
-        
-    },
-    cn: function(node, indent)
-    {
-        var ret = [];
-        
-        var ar = Array.from(node.childNodes);
-        for (var i = 0 ; i < ar.length ; i++) {
-            
-            
-            
-            if (indent !== false   // indent==false preservies everything
-                && i > 0
-                && ar[i].nodeType == 3 
-                && ar[i].nodeValue.length > 0
-                && ar[i].nodeValue.match(/^\s+/)
-            ) {
-                if (ret.length && ret[ret.length-1] == "\n" + indent) {
-                    ret.pop(); // remove line break from last?
-                }
-                
-                ret.push(" "); // add a space if i'm a text item with a space at the front, as tidy will strip spaces.
-            }
-            if (indent !== false
-                && ar[i].nodeType == 1 // element - and indent is not set... 
-            ) {
-                ret.push("\n" + indent); 
-            }
-            
-            ret.push(this.tidy(ar[i], indent));
-            // text + trailing indent 
-            if (indent !== false
-                && ar[i].nodeType == 3
-                && ar[i].nodeValue.length > 0
-                && ar[i].nodeValue.match(/\s+$/)
-            ){
-                ret.push("\n" + indent); 
-            }
-            
-            
-            
-            
-        }
-        // what if all text?
-        
-        
-        return ret.join('');
-    },
-    
          
-        
-    attr : function(node)
-    {
-        var attr = [];
-        for(i = 0; i < node.attributes.length;i++) {
-            
-            // skip empty values?
-            if (!node.attributes.item(i).value.length) {
-                continue;
-            }
-            attr.push(  node.attributes.item(i).name + '="' +
-                    Roo.util.Format.htmlEncode(node.attributes.item(i).value) + '"'
-            );
-        }
-        return attr.length ? (' ' + attr.join(' ') ) : '';
-        
-    }
-    
     
+    }
     
 }
 /**
@@ -21955,6 +21883,8 @@ Roo.htmleditor.Tidy.prototype = {
 
 
 
+
+
 Roo.htmleditor.KeyEnter = function(cfg) {
     Roo.apply(this, cfg);
     // this does not actually call walk as it's really just a abstract class
@@ -21962,80 +21892,67 @@ Roo.htmleditor.KeyEnter = function(cfg) {
     Roo.get(this.core.doc.body).on('keypress', this.keypress, this);
 }
 
+//Roo.htmleditor.KeyEnter.i = 0;
+
 
 Roo.htmleditor.KeyEnter.prototype = {
     
     core : false,
     
-    keypress : function(e) {
-        if (e.charCode != 13) {
+    keypress : function(e)
+    {
+        if (e.charCode != 13 && e.charCode != 10) {
+            Roo.log([e.charCode,e]);
             return true;
         }
         e.preventDefault();
         // https://stackoverflow.com/questions/18552336/prevent-contenteditable-adding-div-on-enter-chrome
         var doc = this.core.doc;
-        
-        var docFragment = doc.createDocumentFragment();
-    
-        //add a new line
-        var newEle = doc.createTextNode('\n');
-        docFragment.appendChild(newEle);
-    
+          //add a new line
+       
     
-        var range = this.core.win.getSelection().getRangeAt(0);
-        var n = range.commonAncestorContainer ;
-        while (n && n.nodeType != 1) {
-            n  = n.parentNode;
-        }
-        var li = false;
-        if (n && n.tagName == 'UL') {
-            li = doc.createElement('LI');
-            n.appendChild(li);
-            
-        }
-        if (n && n.tagName == 'LI') {
-            li = doc.createElement('LI');
-            if (n.nextSibling) {
-                n.parentNode.insertBefore(li, n.firstSibling);
-                
-            } else {
-                n.parentNode.appendChild(li);
-            }
+        var sel = this.core.getSelection();
+        var range = sel.getRangeAt(0);
+        var n = range.commonAncestorContainer;
+        var pc = range.closest([ 'ol', 'ul']);
+        var pli = range.closest('li');
+        if (!pc || e.ctrlKey) {
+            sel.insertNode('br', 'after'); 
+         
+            this.core.undoManager.addEvent();
+            this.core.fireEditorEvent(e);
+            return false;
         }
-        if (li) {   
-            range = doc.createRange();
-            range.setStartAfter(li);
-            range.collapse(true);
         
-            //make the cursor there
-            var sel = this.core.win.getSelection();
-            sel.removeAllRanges();
-            sel.addRange(range);
+        // deal with 
  • insetion + if (pli.innerText.trim() == '' && + pli.previousSibling && + pli.previousSibling.nodeName == 'LI' && + pli.previousSibling.innerText.trim() == '') { + pli.parentNode.removeChild(pli.previousSibling); + sel.cursorAfter(pc); + this.core.undoManager.addEvent(); + this.core.fireEditorEvent(e); return false; - - } - //add the br, or p, or something else - newEle = doc.createElement('br'); - docFragment.appendChild(newEle); - //make the br replace selection - - range.deleteContents(); + var li = doc.createElement('LI'); + li.innerHTML = ' '; + if (!pli || !pli.firstSibling) { + pc.appendChild(li); + } else { + pli.parentNode.insertBefore(li, pli.firstSibling); + } + sel.cursorText (li.firstChild); + + this.core.undoManager.addEvent(); + this.core.fireEditorEvent(e); + + return false; - range.insertNode(docFragment); - - //create a new range - range = doc.createRange(); - range.setStartAfter(newEle); - range.collapse(true); - - //make the cursor there - var sel = this.core.win.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - return false; + + } }; @@ -22056,24 +21973,51 @@ Roo.htmleditor.Block = function(cfg) { // do nothing .. should not be called really. } - +/** + * factory method to get the block from an element (using cache if necessary) + * @static + * @param {HtmlElement} the dom element + */ Roo.htmleditor.Block.factory = function(node) { - + var cc = Roo.htmleditor.Block.cache; var id = Roo.get(node).id; - if (typeof(Roo.htmleditor.Block.cache[id]) != 'undefined') { - Roo.htmleditor.Block.cache[id].readElement(); + if (typeof(cc[id]) != 'undefined' && (!cc[id].node || cc[id].node.closest('body'))) { + Roo.htmleditor.Block.cache[id].readElement(node); return Roo.htmleditor.Block.cache[id]; } - - var cls = Roo.htmleditor['Block' + Roo.get(node).attr('data-block')]; + var db = node.getAttribute('data-block'); + if (!db) { + db = node.nodeName.toLowerCase().toUpperCaseFirst(); + } + var cls = Roo.htmleditor['Block' + db]; if (typeof(cls) == 'undefined') { - Roo.log("OOps missing block : " + 'Block' + Roo.get(node).attr('data-block')); + //Roo.log(node.getAttribute('data-block')); + Roo.log("OOps missing block : " + 'Block' + db); return false; } Roo.htmleditor.Block.cache[id] = new cls({ node: node }); return Roo.htmleditor.Block.cache[id]; /// should trigger update element }; + +/** + * initalize all Elements from content that are 'blockable' + * @static + * @param the body element + */ +Roo.htmleditor.Block.initAll = function(body, type) +{ + if (typeof(type) == 'undefined') { + var ia = Roo.htmleditor.Block.initAll; + ia(body,'table'); + ia(body,'td'); + ia(body,'figure'); + return; + } + Roo.each(Roo.get(body).query(type), function(e) { + Roo.htmleditor.Block.factory(e); + },this); +}; // question goes here... do we need to clear out this cache sometimes? // or show we make it relivant to the htmleditor. Roo.htmleditor.Block.cache = {}; @@ -22083,7 +22027,10 @@ Roo.htmleditor.Block.prototype = { node : false, // used by context menu - friendly_name : 'Image with caption', + friendly_name : 'Based Block', + + // text for button to delete this element + deleteTitle : false, context : false, /** @@ -22118,14 +22065,17 @@ Roo.htmleditor.Block.prototype = { // but kiss for now. n = node.getElementsByTagName(tag).item(0); } + if (!n) { + return ''; + } if (attr == 'html') { return n.innerHTML; } if (attr == 'style') { - return Roo.get(n).getStyle(style); + return n.style[style]; } - return Roo.get(n).attr(attr); + return n.hasAttribute(attr) ? n.getAttribute(attr) : ''; }, /** @@ -22156,8 +22106,8 @@ Roo.htmleditor.Block.prototype = { * Block that has an image and a figcaption * @cfg {String} image_src the url for the image * @cfg {String} align (left|right) alignment for the block default left - * @cfg {String} text_align (left|right) alignment for the text caption default left. * @cfg {String} caption the text to appear below (and in the alt tag) + * @cfg {String} caption_display (block|none) display or not the caption * @cfg {String|number} image_width the width of the image number or %? * @cfg {String|number} image_height the height of the image number or %? * @@ -22179,45 +22129,167 @@ Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, { // setable values. image_src: '', - - align: 'left', + align: 'center', caption : '', - text_align: 'left', + caption_display : 'block', + width : '100%', + cls : '', + href: '', + video_url : '', - width : '46%', - margin: '2%', + // margin: '2%', not used + + text_align: 'left', // (left|right) alignment for the text caption default left. - not used at present + // used by context menu friendly_name : 'Image with caption', + deleteTitle : "Delete Image and Caption", - context : { // ?? static really - width : { - title: "Width", - width: 40 - // ?? number - }, - margin : { - title: "Margin", - width: 40 - // ?? number - }, - align: { - title: "Align", - opts : [[ "left"],[ "right"]], - width : 80 + contextMenu : function(toolbar) + { + + var block = function() { + return Roo.htmleditor.Block.factory(toolbar.tb.selectedNode); + }; + + + var rooui = typeof(Roo.bootstrap) == 'undefined' ? Roo : Roo.bootstrap; + + var syncValue = toolbar.editorcore.syncValue; + + var fields = {}; + + return [ + { + xtype : 'TextItem', + text : "Source: ", + xns : rooui.Toolbar //Boostrap? + }, + { + xtype : 'TextField', + allowBlank : false, + width : 150, + name : 'image_src', + listeners : { + keyup : function (combo, e) + { + toolbar.editorcore.selectNode(toolbar.tb.selectedNode); + var b = block(); + b.image_src = this.getValue(); + b.updateElement(); + syncValue(); + toolbar.editorcore.onEditorEvent(); + } + }, + xns : rooui.form + + }, + { + xtype : 'TextItem', + text : "Width: ", + xns : rooui.Toolbar //Boostrap? + }, + { + xtype : 'ComboBox', + allowBlank : false, + displayField : 'val', + editable : true, + listWidth : 100, + triggerAction : 'all', + typeAhead : true, + valueField : 'val', + width : 70, + name : 'width', + listeners : { + select : function (combo, r, index) + { + toolbar.editorcore.selectNode(toolbar.tb.selectedNode); + var b = block(); + b.width = r.get('val'); + b.updateElement(); + syncValue(); + toolbar.editorcore.onEditorEvent(); + } + }, + xns : rooui.form, + store : { + xtype : 'SimpleStore', + data : [ + ['auto'], + ['50%'], + ['100%'] + ], + fields : [ 'val'], + xns : Roo.data + } + }, + { + xtype : 'TextItem', + text : "Align: ", + xns : rooui.Toolbar //Boostrap? + }, + { + xtype : 'ComboBox', + allowBlank : false, + displayField : 'val', + editable : true, + listWidth : 100, + triggerAction : 'all', + typeAhead : true, + valueField : 'val', + width : 70, + name : 'align', + listeners : { + select : function (combo, r, index) + { + toolbar.editorcore.selectNode(toolbar.tb.selectedNode); + var b = block(); + b.align = r.get('val'); + b.updateElement(); + syncValue(); + toolbar.editorcore.onEditorEvent(); + } + }, + xns : rooui.form, + store : { + xtype : 'SimpleStore', + data : [ + ['left'], + ['right'], + ['center'] + ], + fields : [ 'val'], + xns : Roo.data + } + }, - }, - text_align: { - title: "Caption Align", - opts : [ [ "left"],[ "right"],[ "center"]], - width : 80 - }, + + { + xtype : 'Button', + text: 'Hide Caption', + name : 'caption_display', + pressed : false, + enableToggle : true, + setValue : function(v) { + this.toggle(v == 'block' ? false : true); + }, + listeners : { + toggle: function (btn, state) + { + var b = block(); + b.caption_display = b.caption_display == 'block' ? 'none' : 'block'; + this.setText(b.caption_display == 'block' ? "Hide Caption" : "Show Caption"); + b.updateElement(); + syncValue(); + toolbar.editorcore.selectNode(toolbar.tb.selectedNode); + toolbar.editorcore.onEditorEvent(); + } + }, + xns : rooui.Toolbar + } + ]; - - image_src : { - title: "Src", - width: 220 - } }, /** * create a DomHelper friendly object - for use with @@ -22228,48 +22300,115 @@ Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, { var d = document.createElement('div'); d.innerHTML = this.caption; - return { + var m = this.width == '50%' && this.align == 'center' ? '0 auto' : 0; + + var img = { + tag : 'img', + contenteditable : 'false', + src : this.image_src, + alt : d.innerText.replace(/\n/g, " "), // removeHTML.. + style: { + width : 'auto', + 'max-width': '100%', + margin : '0px' + + + } + }; + /* + '
    ' + + '' + + '' + + '' + + '
    ', + */ + + if (this.href.length > 0) { + img = { + tag : 'a', + href: this.href, + contenteditable : 'true', + cn : [ + img + ] + }; + } + + + if (this.video_url.length > 0) { + img = { + tag : 'div', + cls : this.cls, + frameborder : 0, + allowfullscreen : true, + width : 420, // these are for video tricks - that we replace the outer + height : 315, + src : this.video_url, + cn : [ + img + ] + }; + } + + return { tag: 'figure', 'data-block' : 'Figure', contenteditable : 'false', style : { - display: 'table', + display: 'block', float : this.align , - width : this.width, - margin: this.margin + 'max-width': this.width, + width : 'auto', + margin: m, + padding: '10px' + }, + + + align : this.align, cn : [ - { - tag : 'img', - src : this.image_src, - alt : d.innerText.replace(/\n/g, " "), // removeHTML.. - style: { - width: '100%' - } - }, + img, + { tag: 'figcaption', contenteditable : true, style : { - 'text-align': this.text_align + 'text-align': 'left', + 'margin-top' : '16px', + 'font-size' : '16px', + 'line-height' : '24px', + 'font-style': 'italic', + display : this.caption_display }, + cls : this.cls.length > 0 ? (this.cls + '-thumbnail' ) : '', html : this.caption } ] }; + }, readElement : function(node) { + // this should not really come from the link... + this.video_url = this.getVal(node, 'div', 'src'); + this.cls = this.getVal(node, 'div', 'class'); + this.href = this.getVal(node, 'a', 'href'); + this.image_src = this.getVal(node, 'img', 'src'); - this.align = this.getVal(node, 'figure', 'style', 'float'); + + this.align = this.getVal(node, 'figure', 'align'); this.caption = this.getVal(node, 'figcaption', 'html'); - this.text_align = this.getVal(node, 'figcaption', 'style','text-align'); - this.width = this.getVal(node, 'figure', 'style', 'width'); - this.margin = this.getVal(node, 'figure', 'style', 'margin'); + //this.text_align = this.getVal(node, 'figcaption', 'style','text-align'); + this.width = this.getVal(node, 'figure', 'style', 'max-width'); + //this.margin = this.getVal(node, 'figure', 'style', 'margin'); - } + }, + removeNode : function() + { + return this.node; + } @@ -22280,27 +22419,1265 @@ Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, { }) -//