// children
var far = Array.from(from.childNodes);
var tar = Array.from(to.childNodes);
- for(var i = 0; i < Math.max(far.length, tar.length); i++) {
- if (i < far.length && i < tar.length) {
- updateNode(far[i], tar[i]);
- continue;
- }
- if (i < far.length) {
- // have from // but no 'to'
- from.removeChild(far[i]);
- continue;
- }
- from.appendChild(tar[i]);
- // have 'to' but no from
+ // if the lengths are different.. then it's probably a editable content change, rather than
+ // a change of the block definition..
+ if (from.innerHTML == to.innerHTML) {
+ return;
+ }
+ if (far.length != tar.length) {
+ from.innerHTML = to.innerHTML;
+ return;
+ }
+
+ for(var i = 0; i < far.length; i++) {
+ updateNode(far[i], tar[i]);
}
}
};
+
+/**
+ * @class Roo.htmleditor.Block
+ * Base class for html editor blocks - do not use it directly .. extend it..
+ * @cfg {DomElement} node The node to apply stuff to.
+ * @cfg {String} friendly_name the name that appears in the context bar about this block
+ * @cfg {Object} Context menu - see Roo.form.HtmlEditor.ToolbarContext
+
+ * @constructor
+ * Create a new Filter.
+ * @param {Object} config Configuration options
+ */
+
+Roo.htmleditor.Block = function(cfg)
+{
+ // do nothing .. should not be called really.
+}
+
+Roo.htmleditor.Block.factory = function(node)
+{
+ var cls = Roo.htmleditor['Block' + Roo.get(node).attr('data-block')];
+ if (typeof(cls) == 'undefined') {
+ Roo.log("OOps missing block : " + 'Block' + Roo.get(node).attr('data-block'));
+ return false;
+ }
+ return new cls({ node: node }); /// should trigger update element
+}
+
+
+Roo.htmleditor.Block.prototype = {
+
+ // used by context menu
+ friendly_name : 'Image with caption',
+
+ context : false,
+ /**
+ * Update a node with values from this object
+ * @param {DomElement} node
+ */
+ updateElement : function(node)
+ {
+ Roo.DomHelper.update(node, this.toObject());
+ },
+ /**
+ * convert to plain HTML for calling insertAtCursor..
+ */
+ toHTML : function()
+ {
+ return Roo.DomHelper.markup(this.toObject());
+ },
+ /**
+ * used by readEleemnt to extract data from a node
+ * may need improving as it's pretty basic
+
+ * @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} style the style property - eg. text-align
+ */
+ getVal : function(node, tag, attr, style)
+ {
+ var n = node;
+ if (n.tagName != tag.toUpperCase()) {
+ // in theory we could do figure[3] << 3rd figure? or some more complex search..?
+ // but kiss for now.
+ n = node.getElementsByTagName(tag).item(0);
+ }
+ if (attr == 'html') {
+ return n.innerHTML;
+ }
+ if (attr == 'style') {
+ return Roo.get(n).getStyle(style);
+ }
+
+ return Roo.get(n).attr(attr);
+
+ },
/**
+ * create a DomHelper friendly object - for use with
+ * Roo.DomHelper.markup / overwrite / etc..
+ * (override this)
+ */
+ toObject : function()
+ {
+ return {};
+ },
+ /**
+ * Read a node that has a 'data-block' property - and extract the values from it.
+ * @param {DomElement} node - the node
+ */
+ readElement : function(node)
+ {
+
+ }
+
+
+}
+
+/**
*
* <figure data-block="BlockFigure" contenteditable="false" role="group" style="text-align:left">' +
<img data-name="image" src="{SRC}">' +
},
align: {
title: "Align",
- opts : [ [""],[ "left"],[ "right"],[ "center"],[ "top"]],
+ opts : [[ "left"],[ "right"]],
width : 80
},
text_align: {
title: "Caption Align",
- opts : [ [""],[ "left"],[ "right"],[ "center"],[ "top"]],
+ opts : [ [ "left"],[ "right"],[ "center"]],
width : 80
},
*/
toObject : function()
{
+ var d = document.createElement('div');
+ d.innerHTML = this.caption;
var img = {
tag : 'img',
src : this.image_src,
- alt : this.caption
+ alt : d.innerText.replace(/\n/g, " ") // removeHTML..
};
if ((''+this.image_width).length) {
img.width = this.image_width;
tag: 'figure',
'data-block' : 'Figure',
contenteditable : 'false',
- style : 'text-align:' + this.align,
+ style : 'display:table; float:' + this.align,
cn : [
img,
{
tag: 'figcaption',
contenteditable : true,
- style : 'text-align:left',
+ style : 'text-align:' + this.text_align,
html : this.caption
}
]
readElement : function(node)
{
this.image_src = this.getVal(node, 'img', 'src');
- this.align = this.getVal(node, 'figure', 'style', 'text-align');
+ this.align = this.getVal(node, 'figure', 'style', 'float');
this.caption = this.getVal(node, 'figcaption', 'html');
this.text_align = this.getVal(node, 'figcaption', 'style','text-align');
}
// update attributes
- if (db) {
- var dbo = new cls({node : sel});
+ if (block) {
+
this.tb.fields.each(function(e) {
- e.setValue(dob[e.attrname]);
+ e.setValue(block[e.attrname]);
});
}
this.updateToolbarStyles(sel);
- // flag our selected Node.
- this.tb.selectedNode = sel;
-
+
Roo.menu.MenuMgr.hideAll();
width: item.width ? item.width : 130,
listeners : {
'select': function(c, r, i) {
- if (tb.selectedNode.hasClass('data-block')) {
+ if (tb.selectedNode.hasAttribute('data-block')) {
var b = Roo.htmleditor.Block.factory(tb.selectedNode);
b[c.attrname] = r.get('val');
b.updateElement(tb.selectedNode);
listeners: {
'change' : function(f, nv, ov) {
- if (tb.selectedNode.hasClass('data-block')) {
+ if (tb.selectedNode.hasAttribute('data-block')) {
var b = Roo.htmleditor.Block.factory(tb.selectedNode);
- b[c.attrname] = nv;
+ b[f.attrname] = nv;
b.updateElement(tb.selectedNode);
editorcore.syncValue();
return;
// remove
// undo does not work.
var sn = tb.selectedNode;
- var stn = sn.childNodes[0] || sn.nextSibling || sn.previousSibling || pn;
+ var stn = sn.childNodes[0] || sn.nextSibling || sn.previousSibling || sn.parentNode;
if (sn.hasAttribute('data-block')) {
+ stn = sn.nextSibling || sn.previousSibling || sn.parentNode;
sn.parentNode.removeChild(sn);
+
} else {
// remove and keep parents.
a = new Roo.htmleditor.FilterKeepChildren({tag : false});