};
Roo.extend(Roo.grid.ColumnModel, Roo.util.Observable, {
/**
- * @cfg {String} header The header text to display in the Grid view.
+ * @cfg {String} header [required] The header text to display in the Grid view.
*/
/**
* @cfg {String} xsHeader Header at Bootsrap Extra Small width (default for all)
* @cfg {String} xlHeader Header at Bootsrap extra Large width
*/
/**
- * @cfg {String} dataIndex (Optional) The name of the field in the grid's {@link Roo.data.Store}'s
+ * @cfg {String} dataIndex The name of the field in the grid's {@link Roo.data.Store}'s
* {@link Roo.data.Record} definition from which to draw the column's value. If not
* specified, the column's index is used as an index into the Record's data Array.
*/
/**
- * @cfg {Number} width (Optional) The initial width in pixels of the column. Using this
+ * @cfg {Number} width The initial width in pixels of the column. Using this
* instead of {@link Roo.grid.Grid#autoSizeColumns} is more efficient.
*/
/**
- * @cfg {Boolean} sortable (Optional) True if sorting is to be allowed on this column.
+ * @cfg {Boolean} sortable True if sorting is to be allowed on this column.
* Defaults to the value of the {@link #defaultSortable} property.
* Whether local/remote sorting is used is specified in {@link Roo.data.Store#remoteSort}.
*/
/**
- * @cfg {Boolean} locked (Optional) True to lock the column in place while scrolling the Grid. Defaults to false.
+ * @cfg {Boolean} locked True to lock the column in place while scrolling the Grid. Defaults to false.
*/
/**
- * @cfg {Boolean} fixed (Optional) True if the column width cannot be changed. Defaults to false.
+ * @cfg {Boolean} fixed True if the column width cannot be changed. Defaults to false.
*/
/**
- * @cfg {Boolean} resizable (Optional) False to disable column resizing. Defaults to true.
+ * @cfg {Boolean} resizable False to disable column resizing. Defaults to true.
*/
/**
- * @cfg {Boolean} hidden (Optional) True to hide the column. Defaults to false.
+ * @cfg {Boolean} hidden True to hide the column. Defaults to false.
*/
/**
- * @cfg {Function} renderer (Optional) A function used to generate HTML markup for a cell
+ * @cfg {Function} renderer A function used to generate HTML markup for a cell
* given the cell's data value. See {@link #setRenderer}. If not specified, the
* default renderer returns the escaped data value. If an object is returned (bootstrap only)
* then it is treated as a Roo Component object instance, and it is rendered after the initial row is rendered
*/
/**
- * @cfg {Roo.grid.GridEditor} editor (Optional) For grid editors - returns the grid editor
+ * @cfg {Roo.grid.GridEditor} editor For grid editors - returns the grid editor
*/
/**
- * @cfg {String} align (Optional) Set the CSS text-align property of the column. Defaults to undefined.
+ * @cfg {String} align (left|right) Set the CSS text-align property of the column. Defaults to undefined (left).
*/
/**
- * @cfg {String} valign (Optional) Set the CSS vertical-align property of the column (eg. middle, top, bottom etc). Defaults to undefined.
+ * @cfg {String} valign (top|bottom|middle) Set the CSS vertical-align property of the column (eg. middle, top, bottom etc). Defaults to undefined (middle)
*/
/**
- * @cfg {String} cursor (Optional)
+ * @cfg {String} cursor ( auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing)
*/
/**
- * @cfg {String} tooltip (Optional)
+ * @cfg {String} tooltip mouse over tooltip text
*/
/**
- * @cfg {Number} xs (Optional) can be '0' for hidden at this size (number less than 12)
+ * @cfg {Number} xs can be '0' for hidden at this size (number less than 12)
*/
/**
- * @cfg {Number} sm (Optional) can be '0' for hidden at this size (number less than 12)
+ * @cfg {Number} sm can be '0' for hidden at this size (number less than 12)
*/
/**
- * @cfg {Number} md (Optional) can be '0' for hidden at this size (number less than 12)
+ * @cfg {Number} md can be '0' for hidden at this size (number less than 12)
*/
/**
- * @cfg {Number} lg (Optional) can be '0' for hidden at this size (number less than 12)
+ * @cfg {Number} lg can be '0' for hidden at this size (number less than 12)
*/
/**
- * @cfg {Number} xl (Optional) can be '0' for hidden at this size (number less than 12)
+ * @cfg {Number} xl can be '0' for hidden at this size (number less than 12)
*/
/**
* Returns the id of the column at the specified index.
Roo.htmleditor.FilterWord = function(cfg)
{
// no need to apply config.
- this.walk(cfg.node);
+ this.replaceDocBullets(cfg.node);
+
+ // this.walk(cfg.node);
+
+
}
Roo.extend(Roo.htmleditor.FilterWord, Roo.htmleditor.Filter,
node.removeChild(cn);
node.parentNode.insertBefore(cn, node);
// move node to parent - and clean it..
- this.replaceTag(cn);
+ if (cn.nodeType == 1) {
+ this.replaceTag(cn);
+ }
+
}
node.parentNode.removeChild(node);
/// no need to iterate chidlren = it's got none..
+ },
+
+ styleToObject: function(node)
+ {
+ var styles = (node.getAttribute("style") || '').split(";");
+ var ret = {};
+ Roo.each(styles, function(s) {
+ if (!s.match(/:/)) {
+ return;
+ }
+ var kv = s.split(":");
+
+ // what ever is left... we allow.
+ ret[kv[0]] = kv[1];
+ });
+ return ret;
+ },
+
+
+ replaceDocBullets : function(doc)
+ {
+ // this is a bit odd - but it appears some indents use ql-indent-1
+
+ var listpara = doc.getElementsByClassName('ql-indent-1');
+ while(listpara.length) {
+ this.replaceDocBullet(listpara.item(0));
+ }
+
+ var listpara = doc.getElementsByClassName('MsoListParagraph');
+ while(listpara.length) {
+ this.replaceDocBullet(listpara.item(0));
+ }
+ },
+
+ replaceDocBullet : function(p)
+ {
+ // gather all the siblings.
+ var ns = p,
+ parent = p.parentNode,
+ doc = parent.ownerDocument,
+ items = [];
+ while (ns) {
+ if (ns.nodeType != 1) {
+ ns = ns.nextSibling;
+ continue;
+ }
+ if (!ns.className.match(/(MsoListParagraph|ql-indent-1)/i)) {
+ break;
+ }
+ items.push(ns);
+ ns = ns.nextSibling;
+
+ }
+ var ul = parent.ownerDocument.createElement('ul'); // what about number lists...
+ parent.insertBefore(ul, p);
+ var lvl = 0;
+ var stack = [ ul ];
+ var last_li = false;
+ items.forEach(function(n) {
+ //Roo.log("got innertHMLT=" + n.innerHTML);
+
+ var spans = n.getElementsByTagName('span');
+ if (!spans.length) {
+ //Roo.log("No spans found");
+
+ parent.removeChild(n);
+ return; // skip it...
+ }
+
+
+
+ var style = {};
+ for(var i = 0; i < spans.length; i++) {
+
+ style = this.styleToObject(spans[i]);
+ if (typeof(style['mso-list']) == 'undefined') {
+ continue;
+ }
+
+ spans[i].parentNode.removeChild(spans[i]); // remove the fake bullet.
+ break;
+ }
+ //Roo.log("NOW GOT innertHMLT=" + n.innerHTML);
+ style = this.styleToObject(n); // mo-list is from the parent node.
+ if (typeof(style['mso-list']) == 'undefined') {
+ //Roo.log("parent is missing level");
+ parent.removeChild(n);
+ return;
+ }
+
+ var nlvl = (style['mso-list'].split(' ')[1].replace(/level/,'') *1) - 1;
+ if (nlvl > lvl) {
+ //new indent
+ var nul = doc.createElement('ul'); // what about number lists...
+ last_li.appendChild(nul);
+ stack[nlvl] = nul;
+ }
+ lvl = nlvl;
+
+ var nli = stack[nlvl].appendChild(doc.createElement('li'));
+ last_li = nli;
+ nli.innerHTML = n.innerHTML;
+ //Roo.log("innerHTML = " + n.innerHTML);
+ parent.removeChild(n);
+
+ // copy children of p into nli
+ /*while(n.firstChild) {
+ var fc = n.firstChild;
+ n.removeChild(fc);
+ nli.appendChild(fc);
+ }*/
+
+
+ },this);
+
+
+
+
}
+
+
+
});
/**
* @class Roo.htmleditor.FilterStyleToTag
* @param {DomElement} node
* @param {String} tag - tag to find, eg. IMG ?? might be better to use DomQuery ?
- * @param {String} attribute (use html - for contents, or style for using next param as style)
+ * @param {String} attribute (use html - for contents, style for using next param as style, or false to return the node)
* @param {String} style the style property - eg. text-align
*/
getVal : function(node, tag, attr, style)
if (!n) {
return '';
}
+ if (attr === false) {
+ return n;
+ }
if (attr == 'html') {
return n.innerHTML;
}
store : {
xtype : 'SimpleStore',
data : [
- ['auto'],
['50%'],
+ ['80%'],
['100%']
],
fields : [ 'val'],
pressed : false,
enableToggle : true,
setValue : function(v) {
- this.toggle(v == 'block' ? false : true);
+ // this trigger toggle.
+
+ this.setText(v ? "Hide Caption" : "Show Caption");
+ this.setPressed(v != 'block');
},
listeners : {
toggle: function (btn, state)
var d = document.createElement('div');
d.innerHTML = this.caption;
- var m = this.width == '50%' && this.align == 'center' ? '0 auto' : 0;
+ var m = this.width != '100%' && this.align == 'center' ? '0 auto' : 0;
+ var iw = this.align == 'center' ? this.width : '100%';
var img = {
tag : 'img',
contenteditable : 'false',
src : this.image_src,
alt : d.innerText.replace(/\n/g, " ").replace(/\s+/g, ' ').trim(), // removeHTML and reduce spaces..
style: {
- width : 'auto',
- 'max-width': '100%',
- margin : '0px'
-
+ width : iw,
+ maxWidth : iw + ' !important', // this is not getting rendered?
+ margin : m
}
};
};
}
// we remove caption totally if its hidden... - will delete data.. but otherwise we end up with fake caption
- var captionhtml = this.caption_display == 'hidden' ? '' : (this.caption.length ? this.caption : "Caption");
+ var captionhtml = this.caption_display == 'none' ? '' : (this.caption.length ? this.caption : "Caption");
- return {
+
+ var ret = {
tag: 'figure',
'data-block' : 'Figure',
+ 'data-width' : this.width,
contenteditable : 'false',
style : {
display: 'block',
float : this.align ,
- 'max-width': this.width,
- width : 'auto',
- margin: m,
- padding: '10px'
+ maxWidth : this.align == 'center' ? '100% !important' : (this.width + ' !important'),
+ width : this.align == 'center' ? '100%' : this.width,
+ margin: '0px',
+ padding: this.align == 'center' ? '0' : '0 10px' ,
+ textAlign : this.align // seems to work for email..
},
tag: 'figcaption',
'data-display' : this.caption_display,
style : {
- 'text-align': 'left',
- 'margin-top' : '16px',
- 'font-size' : '16px',
- 'line-height' : '24px',
- display : this.caption_display
+ textAlign : 'left',
+ fontSize : '16px',
+ lineHeight : '24px',
+ display : this.caption_display,
+ maxWidth : (this.align == 'center' ? this.width : '100%' ) + ' !important',
+ margin: m,
+ width: this.align == 'center' ? this.width : '100%'
+
+
},
cls : this.cls.length > 0 ? (this.cls + '-thumbnail' ) : '',
cn : [
{
- // we can not rely on yahoo syndication to use CSS elements - so have to use '<i>' to encase stuff.
- tag : 'i',
- contenteditable : true,
- html : captionhtml
+ tag: 'div',
+ style : {
+ marginTop : '16px',
+ textAlign : 'left'
+ },
+ align: 'left',
+ cn : [
+ {
+ // we can not rely on yahoo syndication to use CSS elements - so have to use '<i>' to encase stuff.
+ tag : 'i',
+ contenteditable : true,
+ html : captionhtml
+ }
+
+ ]
}
+
]
}
]
};
+ return ret;
},
this.image_src = this.getVal(node, 'img', 'src');
this.align = this.getVal(node, 'figure', 'align');
- this.caption = this.getVal(node, 'figcaption', 'html');
- // remove '<i>
- if (this.caption.trim().match(/^<i[^>]*>/i)) {
- this.caption = this.caption.trim().replace(/^<i[^>]*>/i, '').replace(/^<\/i>$/i, '');
+ var figcaption = this.getVal(node, 'figcaption', false);
+ if (figcaption !== '') {
+ this.caption = this.getVal(figcaption, 'i', 'html');
}
+
+
this.caption_display = this.getVal(node, 'figcaption', 'data-display');
//this.text_align = this.getVal(node, 'figcaption', 'style','text-align');
- this.width = this.getVal(node, 'figure', 'style', 'max-width');
+ this.width = this.getVal(node, true, 'data-width');
//this.margin = this.getVal(node, 'figure', 'style', 'margin');
},
//Roo.log("HtmlEditorCore:syncValue (EDITOR->TEXT)");
if(this.initialized){
- this.undoManager.addEvent();
+ if (this.undoManager) {
+ this.undoManager.addEvent();
+ }
var bd = (this.doc.body || this.doc.documentElement);
var cd = (e.browserEvent.clipboardData || window.clipboardData);
// check what type of paste - if it's an image, then handle it differently.
- if (cd.files.length > 0) {
+ if (cd.files && cd.files.length > 0) {
// pasting images?
var urlAPI = (window.createObjectURL && window) ||
(window.URL && URL.revokeObjectURL && URL) ||
this.insertAtCursor('<img src=" + url + ">');
return false;
}
-
+ if (cd.types.indexOf('text/html') < 0 ) {
+ return false;
+ }
+ var images = [];
var html = cd.getData('text/html'); // clipboard event
- var parser = new Roo.rtf.Parser(cd.getData('text/rtf'));
- var images = parser.doc ? parser.doc.getElementsByType('pict') : [];
- Roo.log(images);
+ if (cd.types.indexOf('text/rtf') > -1) {
+ var parser = new Roo.rtf.Parser(cd.getData('text/rtf'));
+ images = parser.doc ? parser.doc.getElementsByType('pict') : [];
+ }
+ //Roo.log(images);
//Roo.log(imgs);
// fixme..
images = images.filter(function(g) { return !g.path.match(/^rtf\/(head|pgdsctbl|listtable|footerf)/); }) // ignore headers/footers etc.
});
}
if (this.autoClean) {
+ new Roo.htmleditor.FilterWord({ node : d });
+
new Roo.htmleditor.FilterStyleToTag({ node : d });
new Roo.htmleditor.FilterAttributes({
node : d,
- attrib_white : ['href', 'src', 'name', 'align'],
+ attrib_white : ['href', 'src', 'name', 'align', 'colspan', 'rowspan', 'data-display', 'data-width'],
attrib_clean : ['href', 'src' ]
});
new Roo.htmleditor.FilterBlack({ node : d, tag : this.black});
new Roo.htmleditor.FilterParagraph({ node : d });
new Roo.htmleditor.FilterSpan({ node : d });
new Roo.htmleditor.FilterLongBr({ node : d });
+ new Roo.htmleditor.FilterComment({ node : d });
+
+
}
if (this.enableBlocks) {
if (this.enableBlocks) {
Roo.htmleditor.Block.initAll(this.doc.body);
}
-
+
e.preventDefault();
return false;