X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=roojs-bootstrap-debug.js;h=97def3e421e55c1b010b55a4858285f46a9efafe;hb=03abc9af9c101e8a0e4b20acda7b1164a94102fe;hp=ff7d054e3376adf0d8726ab52c2158e5569dbcbc;hpb=3ceb008849553fc9d0235f889c190a73330ea822;p=roojs1 diff --git a/roojs-bootstrap-debug.js b/roojs-bootstrap-debug.js index ff7d054e33..97def3e421 100644 --- a/roojs-bootstrap-debug.js +++ b/roojs-bootstrap-debug.js @@ -9157,6 +9157,7 @@ Currently the Table uses multiple headers to try and handle XL / Medium etc... * also adds table-responsive (see bootstrap docs for details) * @cfg {Boolean} loadMask (true|false) default false * @cfg {Boolean} footerShow (true|false) generate tfoot, default true + * @cfg {Boolean} summaryFooterShow (true|false) generate tfoot for summary, default false * @cfg {Boolean} headerShow (true|false) generate thead, default true * @cfg {Boolean} rowSelection (true|false) default false * @cfg {Boolean} cellSelection (true|false) default false @@ -9165,6 +9166,7 @@ Currently the Table uses multiple headers to try and handle XL / Medium etc... * @cfg {Boolean} lazyLoad auto load data while scrolling to the end (default false) * @cfg {Boolean} auto_hide_footer auto hide footer if only one page (default false) * @cfg {Boolean} enableColumnResize default true if columns can be resized = needs scrollBody to be set to work (drag/drop) + * @cfg {Boolean} disableAutoSize disable autoSize() and initCSS() * * * @cfg {Number} minColumnWidth default 50 pixels minimum column width @@ -9340,8 +9342,10 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, { store : false, loadMask : false, footerShow : true, + summaryFooterShow : false, headerShow : true, enableColumnResize: true, + disableAutoSize: false, rowSelection : false, cellSelection : false, @@ -9414,9 +9418,10 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, { cfg.cn.push(this.renderBody()); - if(this.footerShow){ + if(this.footerShow || this.summaryFooterShow){ cfg.cn.push(this.renderFooter()); } + // where does this come from? //cfg.cls+= ' TableGrid'; } @@ -9503,7 +9508,9 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, { initCSS : function() { - + if(this.disableAutoSize) { + return; + } var cm = this.cm, styles = []; this.CSS.removeStyleSheet(this.id + '-cssrules'); @@ -9975,8 +9982,6 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, { return footer; }, - - onLoad : function() { // Roo.log('ds onload'); @@ -10033,6 +10038,33 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, { this.mainFoot.show(); } } + + if(!this.footerShow && this.summaryFooterShow) { + + var tr = { + tag : 'tr', + cn : [] + }; + + for(var i = 0, len = cm.getColumnCount(); i < len; i++){ + + var value = cm.config[i].summaryFooter; + + var td = { + tag: 'td', + cls : ' x-fcol-' + i, + style: '', + html: cm.config[i].summaryFooter + }; + + tr.cn.push(td); + + } + + tfoot.dom.innerHTML = ''; + + tfoot.createChild(tr); + } Roo.each(this.el.select('tbody td', true).elements, function(e){ e.on('mouseover', _this.onMouseover, _this); @@ -10507,6 +10539,9 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, { */ autoSize : function() { + if(this.disableAutoSize) { + return; + } //var ctr = Roo.get(this.container.dom.parentElement); var ctr = Roo.get(this.el.dom); @@ -11277,7 +11312,13 @@ Roo.extend(Roo.form.Action.Submit, Roo.form.Action, { } var ret = false; try { - ret = Roo.decode(response.responseText); + var rt = response.responseText; + if (rt.match(/^\. + * + * @method cdata + * @param {String} text String to write out inside the comment. + */ + comment: function(text) { + this.html.push(''); + }, + /** + * Writes a PI node such as . + * + * @method pi + * @param {String} name Name of the pi. + * @param {String} text String to write out inside the pi. + */ + pi: function(name, text) { + text ? this.html.push('') : this.html.push(''); + this.indent != '' && this.html.push('\n'); + }, + /** + * Writes a doctype node such as . + * + * @method doctype + * @param {String} text String to write out inside the doctype. + */ + doctype: function(text) { + this.html.push('', this.indent != '' ? '\n' : ''); + }, + /** + * Resets the internal buffer if one wants to reuse the writer. + * + * @method reset + */ + reset: function() { + this.html.length = 0; + this.state = []; + this.pushState({ + indentstr : '', + in_pre : false, + in_inline : false + }) + }, + /** + * Returns the contents that got serialized. + * + * @method getContent + * @return {String} HTML contents that got written down. + */ + getContent: function() { + return this.html.join('').replace(/\n$/, ''); + }, + + pushState : function(cfg) + { + this.state.push(cfg); + Roo.apply(this, cfg); + }, + + popState : function() + { + if (this.state.length < 1) { + return; // nothing to push + } + var cfg = { + in_pre: false, + indentstr : '' + }; + this.state.pop(); + if (this.state.length > 0) { + cfg = this.state[this.state.length-1]; + } + Roo.apply(this, cfg); + }, + + addLine: function() + { + if (this.html.length < 1) { + return; + } + + + var value = this.html[this.html.length - 1]; + if (value.length > 0 && '\n' !== value) { + this.html.push('\n'); + } + } + + +//'pre script noscript style textarea video audio iframe object code' +// shortended... 'area base basefont br col frame hr img input isindex link meta param embed source wbr track'); +// inline +}; + +Roo.htmleditor.TidyWriter.inline_elements = [ + 'SPAN','STRONG','B','EM','I','FONT','STRIKE','U','VAR', + 'CITE','DFN','CODE','MARK','Q','SUP','SUB','SAMP', 'A' +]; +Roo.htmleditor.TidyWriter.shortend_elements = [ + 'AREA','BASE','BASEFONT','BR','COL','FRAME','HR','IMG','INPUT', + 'ISINDEX','LINK','','META','PARAM','EMBED','SOURCE','WBR','TRACK' +]; + +Roo.htmleditor.TidyWriter.whitespace_elements = [ + 'PRE','SCRIPT','NOSCRIPT','STYLE','TEXTAREA','VIDEO','AUDIO','IFRAME','OBJECT','CODE' +];/*** + * This is based loosely on tinymce + * @class Roo.htmleditor.TidyEntities + * @static + * https://github.com/thorn0/tinymce.html/blob/master/tinymce.html.js + * + * Not 100% sure this is actually used or needed. + */ + +Roo.htmleditor.TidyEntities = { + + /** + * initialize data.. + */ + init : function (){ + + this.namedEntities = this.buildEntitiesLookup(this.namedEntitiesData, 32); + + }, + + + buildEntitiesLookup: function(items, radix) { + var i, chr, entity, lookup = {}; + if (!items) { + return {}; + } + items = typeof(items) == 'string' ? items.split(',') : items; + radix = radix || 10; + // Build entities lookup table + for (i = 0; i < items.length; i += 2) { + chr = String.fromCharCode(parseInt(items[i], radix)); + // Only add non base entities + if (!this.baseEntities[chr]) { + entity = '&' + items[i + 1] + ';'; + lookup[chr] = entity; + lookup[entity] = chr; + } + } + return lookup; + + }, + + asciiMap : { + 128: '€', + 130: '‚', + 131: 'ƒ', + 132: '„', + 133: '…', + 134: '†', + 135: '‡', + 136: 'ˆ', + 137: '‰', + 138: 'Š', + 139: '‹', + 140: 'Œ', + 142: 'Ž', + 145: '‘', + 146: '’', + 147: '“', + 148: '”', + 149: '•', + 150: '–', + 151: '—', + 152: '˜', + 153: '™', + 154: 'š', + 155: '›', + 156: 'œ', + 158: 'ž', + 159: 'Ÿ' + }, + // Raw entities + baseEntities : { + '"': '"', + // Needs to be escaped since the YUI compressor would otherwise break the code + '\'': ''', + '<': '<', + '>': '>', + '&': '&', + '`': '`' + }, + // Reverse lookup table for raw entities + reverseEntities : { + '<': '<', + '>': '>', + '&': '&', + '"': '"', + ''': '\'' + }, + + attrsCharsRegExp : /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + textCharsRegExp : /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + rawCharsRegExp : /[<>&\"\']/g, + entityRegExp : /&#([a-z0-9]+);?|&([a-z0-9]+);/gi, + namedEntities : false, + namedEntitiesData : [ + '50', + 'nbsp', + '51', + 'iexcl', + '52', + 'cent', + '53', + 'pound', + '54', + 'curren', + '55', + 'yen', + '56', + 'brvbar', + '57', + 'sect', + '58', + 'uml', + '59', + 'copy', + '5a', + 'ordf', + '5b', + 'laquo', + '5c', + 'not', + '5d', + 'shy', + '5e', + 'reg', + '5f', + 'macr', + '5g', + 'deg', + '5h', + 'plusmn', + '5i', + 'sup2', + '5j', + 'sup3', + '5k', + 'acute', + '5l', + 'micro', + '5m', + 'para', + '5n', + 'middot', + '5o', + 'cedil', + '5p', + 'sup1', + '5q', + 'ordm', + '5r', + 'raquo', + '5s', + 'frac14', + '5t', + 'frac12', + '5u', + 'frac34', + '5v', + 'iquest', + '60', + 'Agrave', + '61', + 'Aacute', + '62', + 'Acirc', + '63', + 'Atilde', + '64', + 'Auml', + '65', + 'Aring', + '66', + 'AElig', + '67', + 'Ccedil', + '68', + 'Egrave', + '69', + 'Eacute', + '6a', + 'Ecirc', + '6b', + 'Euml', + '6c', + 'Igrave', + '6d', + 'Iacute', + '6e', + 'Icirc', + '6f', + 'Iuml', + '6g', + 'ETH', + '6h', + 'Ntilde', + '6i', + 'Ograve', + '6j', + 'Oacute', + '6k', + 'Ocirc', + '6l', + 'Otilde', + '6m', + 'Ouml', + '6n', + 'times', + '6o', + 'Oslash', + '6p', + 'Ugrave', + '6q', + 'Uacute', + '6r', + 'Ucirc', + '6s', + 'Uuml', + '6t', + 'Yacute', + '6u', + 'THORN', + '6v', + 'szlig', + '70', + 'agrave', + '71', + 'aacute', + '72', + 'acirc', + '73', + 'atilde', + '74', + 'auml', + '75', + 'aring', + '76', + 'aelig', + '77', + 'ccedil', + '78', + 'egrave', + '79', + 'eacute', + '7a', + 'ecirc', + '7b', + 'euml', + '7c', + 'igrave', + '7d', + 'iacute', + '7e', + 'icirc', + '7f', + 'iuml', + '7g', + 'eth', + '7h', + 'ntilde', + '7i', + 'ograve', + '7j', + 'oacute', + '7k', + 'ocirc', + '7l', + 'otilde', + '7m', + 'ouml', + '7n', + 'divide', + '7o', + 'oslash', + '7p', + 'ugrave', + '7q', + 'uacute', + '7r', + 'ucirc', + '7s', + 'uuml', + '7t', + 'yacute', + '7u', + 'thorn', + '7v', + 'yuml', + 'ci', + 'fnof', + 'sh', + 'Alpha', + 'si', + 'Beta', + 'sj', + 'Gamma', + 'sk', + 'Delta', + 'sl', + 'Epsilon', + 'sm', + 'Zeta', + 'sn', + 'Eta', + 'so', + 'Theta', + 'sp', + 'Iota', + 'sq', + 'Kappa', + 'sr', + 'Lambda', + 'ss', + 'Mu', + 'st', + 'Nu', + 'su', + 'Xi', + 'sv', + 'Omicron', + 't0', + 'Pi', + 't1', + 'Rho', + 't3', + 'Sigma', + 't4', + 'Tau', + 't5', + 'Upsilon', + 't6', + 'Phi', + 't7', + 'Chi', + 't8', + 'Psi', + 't9', + 'Omega', + 'th', + 'alpha', + 'ti', + 'beta', + 'tj', + 'gamma', + 'tk', + 'delta', + 'tl', + 'epsilon', + 'tm', + 'zeta', + 'tn', + 'eta', + 'to', + 'theta', + 'tp', + 'iota', + 'tq', + 'kappa', + 'tr', + 'lambda', + 'ts', + 'mu', + 'tt', + 'nu', + 'tu', + 'xi', + 'tv', + 'omicron', + 'u0', + 'pi', + 'u1', + 'rho', + 'u2', + 'sigmaf', + 'u3', + 'sigma', + 'u4', + 'tau', + 'u5', + 'upsilon', + 'u6', + 'phi', + 'u7', + 'chi', + 'u8', + 'psi', + 'u9', + 'omega', + 'uh', + 'thetasym', + 'ui', + 'upsih', + 'um', + 'piv', + '812', + 'bull', + '816', + 'hellip', + '81i', + 'prime', + '81j', + 'Prime', + '81u', + 'oline', + '824', + 'frasl', + '88o', + 'weierp', + '88h', + 'image', + '88s', + 'real', + '892', + 'trade', + '89l', + 'alefsym', + '8cg', + 'larr', + '8ch', + 'uarr', + '8ci', + 'rarr', + '8cj', + 'darr', + '8ck', + 'harr', + '8dl', + 'crarr', + '8eg', + 'lArr', + '8eh', + 'uArr', + '8ei', + 'rArr', + '8ej', + 'dArr', + '8ek', + 'hArr', + '8g0', + 'forall', + '8g2', + 'part', + '8g3', + 'exist', + '8g5', + 'empty', + '8g7', + 'nabla', + '8g8', + 'isin', + '8g9', + 'notin', + '8gb', + 'ni', + '8gf', + 'prod', + '8gh', + 'sum', + '8gi', + 'minus', + '8gn', + 'lowast', + '8gq', + 'radic', + '8gt', + 'prop', + '8gu', + 'infin', + '8h0', + 'ang', + '8h7', + 'and', + '8h8', + 'or', + '8h9', + 'cap', + '8ha', + 'cup', + '8hb', + 'int', + '8hk', + 'there4', + '8hs', + 'sim', + '8i5', + 'cong', + '8i8', + 'asymp', + '8j0', + 'ne', + '8j1', + 'equiv', + '8j4', + 'le', + '8j5', + 'ge', + '8k2', + 'sub', + '8k3', + 'sup', + '8k4', + 'nsub', + '8k6', + 'sube', + '8k7', + 'supe', + '8kl', + 'oplus', + '8kn', + 'otimes', + '8l5', + 'perp', + '8m5', + 'sdot', + '8o8', + 'lceil', + '8o9', + 'rceil', + '8oa', + 'lfloor', + '8ob', + 'rfloor', + '8p9', + 'lang', + '8pa', + 'rang', + '9ea', + 'loz', + '9j0', + 'spades', + '9j3', + 'clubs', + '9j5', + 'hearts', + '9j6', + 'diams', + 'ai', + 'OElig', + 'aj', + 'oelig', + 'b0', + 'Scaron', + 'b1', + 'scaron', + 'bo', + 'Yuml', + 'm6', + 'circ', + 'ms', + 'tilde', + '802', + 'ensp', + '803', + 'emsp', + '809', + 'thinsp', + '80c', + 'zwnj', + '80d', + 'zwj', + '80e', + 'lrm', + '80f', + 'rlm', + '80j', + 'ndash', + '80k', + 'mdash', + '80o', + 'lsquo', + '80p', + 'rsquo', + '80q', + 'sbquo', + '80s', + 'ldquo', + '80t', + 'rdquo', + '80u', + 'bdquo', + '810', + 'dagger', + '811', + 'Dagger', + '81g', + 'permil', + '81p', + 'lsaquo', + '81q', + 'rsaquo', + '85c', + 'euro' + ], + + + /** + * Encodes the specified string using raw entities. This means only the required XML base entities will be encoded. + * + * @method encodeRaw + * @param {String} text Text to encode. + * @param {Boolean} attr Optional flag to specify if the text is attribute contents. + * @return {String} Entity encoded text. + */ + encodeRaw: function(text, attr) + { + var t = this; + return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) { + return t.baseEntities[chr] || chr; + }); + }, + /** + * Encoded the specified text with both the attributes and text entities. This function will produce larger text contents + * since it doesn't know if the context is within a attribute or text node. This was added for compatibility + * and is exposed as the DOMUtils.encode function. + * + * @method encodeAllRaw + * @param {String} text Text to encode. + * @return {String} Entity encoded text. + */ + encodeAllRaw: function(text) { + var t = this; + return ('' + text).replace(this.rawCharsRegExp, function(chr) { + return t.baseEntities[chr] || chr; + }); + }, + /** + * Encodes the specified string using numeric entities. The core entities will be + * encoded as named ones but all non lower ascii characters will be encoded into numeric entities. + * + * @method encodeNumeric + * @param {String} text Text to encode. + * @param {Boolean} attr Optional flag to specify if the text is attribute contents. + * @return {String} Entity encoded text. + */ + encodeNumeric: function(text, attr) { + var t = this; + return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) { + // Multi byte sequence convert it to a single entity + if (chr.length > 1) { + return '&#' + (1024 * (chr.charCodeAt(0) - 55296) + (chr.charCodeAt(1) - 56320) + 65536) + ';'; + } + return t.baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';'; + }); + }, + /** + * Encodes the specified string using named entities. The core entities will be encoded + * as named ones but all non lower ascii characters will be encoded into named entities. + * + * @method encodeNamed + * @param {String} text Text to encode. + * @param {Boolean} attr Optional flag to specify if the text is attribute contents. + * @param {Object} entities Optional parameter with entities to use. + * @return {String} Entity encoded text. + */ + encodeNamed: function(text, attr, entities) { + var t = this; + entities = entities || this.namedEntities; + return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) { + return t.baseEntities[chr] || entities[chr] || chr; + }); + }, + /** + * Returns an encode function based on the name(s) and it's optional entities. + * + * @method getEncodeFunc + * @param {String} name Comma separated list of encoders for example named,numeric. + * @param {String} entities Optional parameter with entities to use instead of the built in set. + * @return {function} Encode function to be used. + */ + getEncodeFunc: function(name, entities) { + entities = this.buildEntitiesLookup(entities) || this.namedEntities; + var t = this; + function encodeNamedAndNumeric(text, attr) { + return text.replace(attr ? t.attrsCharsRegExp : t.textCharsRegExp, function(chr) { + return t.baseEntities[chr] || entities[chr] || '&#' + chr.charCodeAt(0) + ';' || chr; + }); + } + + function encodeCustomNamed(text, attr) { + return t.encodeNamed(text, attr, entities); + } + // Replace + with , to be compatible with previous TinyMCE versions + name = this.makeMap(name.replace(/\+/g, ',')); + // Named and numeric encoder + if (name.named && name.numeric) { + return this.encodeNamedAndNumeric; + } + // Named encoder + if (name.named) { + // Custom names + if (entities) { + return encodeCustomNamed; + } + return this.encodeNamed; + } + // Numeric + if (name.numeric) { + return this.encodeNumeric; + } + // Raw encoder + return this.encodeRaw; + }, + /** + * Decodes the specified string, this will replace entities with raw UTF characters. + * + * @method decode + * @param {String} text Text to entity decode. + * @return {String} Entity decoded string. + */ + decode: function(text) + { + var t = this; + return text.replace(this.entityRegExp, function(all, numeric) { + if (numeric) { + numeric = 'x' === numeric.charAt(0).toLowerCase() ? parseInt(numeric.substr(1), 16) : parseInt(numeric, 10); + // Support upper UTF + if (numeric > 65535) { + numeric -= 65536; + return String.fromCharCode(55296 + (numeric >> 10), 56320 + (1023 & numeric)); + } + return t.asciiMap[numeric] || String.fromCharCode(numeric); + } + return t.reverseEntities[all] || t.namedEntities[all] || t.nativeDecode(all); + }); + }, + nativeDecode : function (text) { + return text; + }, + makeMap : function (items, delim, map) { + var i; + items = items || []; + delim = delim || ','; + if (typeof items == "string") { + items = items.split(delim); + } + map = map || {}; + i = items.length; + while (i--) { + map[items[i]] = {}; + } + return map; + } +}; + + + +Roo.htmleditor.TidyEntities.init(); /** * @class Roo.htmleditor.KeyEnter * Handle Enter press.. @@ -26918,7 +28376,17 @@ Roo.htmleditor.KeyEnter.prototype = { var pc = range.closest([ 'ol', 'ul']); var pli = range.closest('li'); if (!pc || e.ctrlKey) { - sel.insertNode('br', 'after'); + // on it list, or ctrl pressed. + if (!e.ctrlKey) { + sel.insertNode('br', 'after'); + } else { + // only do this if we have ctrl key.. + var br = doc.createElement('br'); + br.className = 'clear'; + br.setAttribute('style', 'clear: both'); + sel.insertNode(br, 'after'); + } + this.core.undoManager.addEvent(); this.core.fireEditorEvent(e); @@ -27282,9 +28750,11 @@ Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, { store : { xtype : 'SimpleStore', data : [ - ['50%'], + ['100%'], ['80%'], - ['100%'] + ['50%'], + ['20%'], + ['10%'] ], fields : [ 'val'], xns : Roo.data @@ -28354,7 +29824,6 @@ Roo.extend(Roo.htmleditor.BlockTd, Roo.htmleditor.Block, { */ toObject : function() { - var ret = { tag : 'td', contenteditable : 'true', // this stops cell selection from picking the table. @@ -28395,6 +29864,9 @@ Roo.extend(Roo.htmleditor.BlockTd, Roo.htmleditor.Block, { this.colspan = Math.max(1,1*node.getAttribute('colspan')); this.rowspan = Math.max(1,1*node.getAttribute('rowspan')); this.html = node.innerHTML; + if (node.style.textAlign != '') { + this.textAlign = node.style.textAlign; + } }, @@ -28452,7 +29924,7 @@ Roo.extend(Roo.htmleditor.BlockTd, Roo.htmleditor.Block, { c.col = cn; } - if (typeof(this.colWidths[cn]) == 'undefined') { + if (typeof(this.colWidths[cn]) == 'undefined' && c.colspan < 2) { this.colWidths[cn] = ce.style.width; if (this.colWidths[cn] != '') { all_auto = false; @@ -28521,6 +29993,9 @@ Roo.extend(Roo.htmleditor.BlockTd, Roo.htmleditor.Block, { this.colspan += rc.colspan; this.node.setAttribute('colspan', this.colspan); + var table = this.toTableArray(); + this.normalizeWidths(table); + this.updateWidths(table); }, @@ -28555,19 +30030,17 @@ Roo.extend(Roo.htmleditor.BlockTd, Roo.htmleditor.Block, { this.colspan = 1; for(var r = cd.row; r < cd.row + cd.rowspan; r++) { - - + for(var c = cd.col; c < cd.col + cd.colspan; c++) { if (r == cd.row && c == cd.col) { this.node.removeAttribute('rowspan'); this.node.removeAttribute('colspan'); - continue; } var ntd = this.node.cloneNode(); // which col/row should be 0.. - ntd.removeAttribute('id'); // - //ntd.style.width = ''; + ntd.removeAttribute('id'); + ntd.style.width = this.colWidths[c]; ntd.innerHTML = ''; table[r][c] = { cell : ntd, col : c, row: r , colspan : 1 , rowspan : 1 }; } @@ -28575,8 +30048,6 @@ Roo.extend(Roo.htmleditor.BlockTd, Roo.htmleditor.Block, { } this.redrawAllCells(table); - - }, @@ -28625,13 +30096,21 @@ Roo.extend(Roo.htmleditor.BlockTd, Roo.htmleditor.Block, { el.width = Math.floor(this.colWidths[c]) +'%'; el.updateElement(el.node); } + if (this.colWidths[0] != false && table[r][c].colspan > 1) { + var el = Roo.htmleditor.Block.factory(table[r][c].cell); + var width = 0; + for(var i = 0; i < table[r][c].colspan; i ++) { + width += Math.floor(this.colWidths[c + i]); + } + el.width = width +'%'; + el.updateElement(el.node); + } table[r][c].cell = false; // done } } }, normalizeWidths : function(table) { - if (this.colWidths[0] === false) { var nw = 100.0 / this.colWidths.length; this.colWidths.forEach(function(w,i) { @@ -29141,11 +30620,42 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component, { if (this.enableBlocks) { new Roo.htmleditor.FilterBlock({ node : div }); } + + var html = div.innerHTML; + //?? tidy? - var tidy = new Roo.htmleditor.TidySerializer({ - inner: true - }); - var html = tidy.serialize(div); + if (this.autoClean) { + + new Roo.htmleditor.FilterAttributes({ + node : div, + attrib_white : [ + 'href', + 'src', + 'name', + 'align', + 'colspan', + 'rowspan', + 'data-display', + 'data-width', + 'start' , + 'style', + // youtube embed. + 'class', + 'allowfullscreen', + 'frameborder', + 'width', + 'height', + 'alt' + ], + attrib_clean : ['href', 'src' ] + }); + + var tidy = new Roo.htmleditor.TidySerializer({ + inner: true + }); + html = tidy.serialize(div); + + } if(Roo.isSafari){ @@ -29359,7 +30869,7 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component, { .map(function(g) { return g.toDataURL(); }) .filter(function(g) { return g != 'about:blank'; }); - + //Roo.log(html); html = this.cleanWordChars(html); var d = (new DOMParser().parseFromString(html, 'text/html')).body; @@ -29377,7 +30887,17 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component, { return false; } + + if (images.length > 0) { + // replace all v:imagedata - with img. + var ar = Array.from(d.getElementsByTagName('v:imagedata')); + Roo.each(ar, function(node) { + node.parentNode.insertBefore(d.ownerDocument.createElement('img'), node ); + node.parentNode.removeChild(node); + }); + + Roo.each(d.getElementsByTagName('img'), function(img, i) { img.setAttribute('src', images[i]); }); @@ -29388,12 +30908,12 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component, { new Roo.htmleditor.FilterStyleToTag({ node : d }); new Roo.htmleditor.FilterAttributes({ node : d, - attrib_white : ['href', 'src', 'name', 'align', 'colspan', 'rowspan', 'data-display', 'data-width'], + attrib_white : ['href', 'src', 'name', 'align', 'colspan', 'rowspan', 'data-display', 'data-width', 'start'], attrib_clean : ['href', 'src' ] }); new Roo.htmleditor.FilterBlack({ node : d, tag : this.black}); // should be fonts.. - new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT', 'O:P' ]} ); + new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT', ':' ]} ); new Roo.htmleditor.FilterParagraph({ node : d }); new Roo.htmleditor.FilterSpan({ node : d }); new Roo.htmleditor.FilterLongBr({ node : d }); @@ -30083,6 +31603,7 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component, { cleanWord : function(node) { new Roo.htmleditor.FilterWord({ node : node ? node : this.doc.body }); + new Roo.htmleditor.FilterKeepChildren({node : node ? node : this.doc.body, tag : [ 'FONT', ':' ]} ); }, @@ -32556,10 +34077,18 @@ Roo.extend(Roo.bootstrap.Tooltip, Roo.bootstrap.Component, { this.el.removeClass(['fade','top','bottom', 'left', 'right','in', 'bs-tooltip-top','bs-tooltip-bottom', 'bs-tooltip-left', 'bs-tooltip-right']); + + if(this.bindEl.attr('tooltip-class')) { + this.el.addClass(this.bindEl.attr('tooltip-class')); + } var placement = typeof this.placement == 'function' ? this.placement.call(this, this.el, on_el) : this.placement; + + if(this.bindEl.attr('tooltip-placement')) { + placement = this.bindEl.attr('tooltip-placement'); + } var autoToken = /\s?auto?\s?/i; var autoPlace = autoToken.test(placement); @@ -32649,6 +34178,9 @@ Roo.extend(Roo.bootstrap.Tooltip, Roo.bootstrap.Component, { return; } //this.el.setXY([0,0]); + if(this.bindEl.attr('tooltip-class')) { + this.el.removeClass(this.bindEl.attr('tooltip-class')); + } this.el.removeClass(['show', 'in']); //this.el.hide();