});
});
+describe('Displaying span nodes', function() {
+ it('inlines a span element with a text', function() {
+ var c = getCanvasFromXML('<section><span>Alice</span></section>'),
+ spanElement = c.doc().children()[0];
+ expect(spanElement.isBlock()).to.equal(false);
+ });
+ it('renders non-span element as a block', function() {
+ var c = getCanvasFromXML('<section><span></span></section>'),
+ element = c.doc().children()[0],
+ node = element.wlxmlNode;
+
+ expect(element.isBlock()).to.equal(false, 'initially inline');
+ node = node.setTag('div');
+ expect(node.getData('canvasElement').isBlock()).to.equal(true, 'block');
+ });
+
+ it('inlines a span element if its block content gets removed', function() {
+ var c = getCanvasFromXML('<section><span>Alice <div>has</div> a cat!</span></section>'),
+ spanElement = c.doc().children()[0],
+ divNode = spanElement.wlxmlNode.contents()[1];
+
+ expect(spanElement.isBlock()).to.equal(true, 'initially a block');
+ divNode.detach();
+ expect(spanElement.isBlock()).to.equal(false, 'inlined after removing inner block');
+
+ spanElement.wlxmlNode.append({tagName: 'div'});
+
+ expect(spanElement.isBlock()).to.equal(true, 'block again after bringing back inner block');
+ });
+
+ it('keeps showing element as a block after changing its node tag to span if it contains elements of non-span nodes', function() {
+ var c = getCanvasFromXML('<section><div><div></div></div></section>'),
+ outerDivElement = c.doc().children()[0],
+ outerDivNode = outerDivElement.wlxmlNode;
+ outerDivNode = outerDivNode.setTag('span');
+ expect(c.doc().children()[0].isBlock()).to.equal(true);
+ });
+});
+
describe('Cursor', function() {
/* globals Node */
var getSelection;
};
$.extend(DocumentElement.prototype, {
+ refreshPath: function() {
+ this.parents().forEach(function(parent) {
+ parent.refresh();
+ });
+ this.refresh();
+ },
+ refresh: function() {
+ // noop
+ },
bound: function() {
return $.contains(document.documentElement, this.dom()[0]);
},
}
var target = (action === 'append' || action === 'prepend') ? e._container() : e.dom();
target[action](element.dom());
+ e.refreshPath();
return element;
};
$.extend(DocumentNodeElement.prototype, {
+ init: function() {
+ // noo[]
+ },
createDOM: function() {
var dom = $('<div>')
.attr('document-node-element', ''),
this.wlxmlNode.contents().forEach(function(node) {
container.append(this.canvas.createElement(node).dom());
}.bind(this));
+
+ this.init();
+
return dom;
},
_container: function() {
return this.dom().children('[document-element-content]');
},
detach: function() {
+ var parents = this.parents();
this.dom().detach();
this.canvas = null;
- return this;
+ if(parents[0]) {
+ parents[0].refreshPath();
+ }
+ return this;
},
append: function(params) {
return manipulate(this, params, 'append');
}
this.manager = wlxmlManagers.getFor(this);
this.manager.setup();
+
+ this.refreshPath();
},
toggleLabel: function(toggle) {
var displayCss = toggle ? 'inline-block' : 'none';
if(this.manager) {
this.manager.toggle(toggle);
}
+ },
+
+ isBlock: function() {
+ return this.dom().css('display') === 'block';
+ },
+
+ containsBlock: function() {
+ return this.children()
+ .filter(function(child) {
+ return child instanceof DocumentNodeElement;
+ })
+ .some(function(child) {
+ if(child.isBlock()) {
+ return true;
+ } else {
+ return child.containsBlock();
+ }
+ });
+ },
+
+ displayAsBlock: function() {
+ this.dom().css('display', 'block');
+ this._container().css('display', 'block');
+ },
+ displayInline: function() {
+ this.dom().css('display', 'inline');
+ this._container().css('display', 'inline');
}
});
this.dom().wrap('<div>');
this.dom().parent().after(element.dom());
this.dom().unwrap();
+ this.refreshPath();
return element;
},
before: function(params) {
this.dom().wrap('<div>');
this.dom().parent().before(element.dom());
this.dom().unwrap();
+ this.refreshPath();
return element;
},
toggleHighlight: function() {
// do nothing for now
}
+
+});
+
+var SpanElement = function() {
+ DocumentNodeElement.apply(this, Array.prototype.slice.call(arguments, 0));
+};
+SpanElement.prototype = $.extend(Object.create(DocumentNodeElement.prototype), {
+ init: function() {
+ if(this.containsBlock()) {
+ this.displayAsBlock();
+ } else {
+ this.displayInline();
+ }
+ },
+ refresh: function() {
+ this.init();
+ }
});
+var elements = {
+ span: SpanElement
+};
+
+
return {
DocumentElement: DocumentElement,
DocumentNodeElement: DocumentNodeElement,
- DocumentTextElement: DocumentTextElement
+ DocumentTextElement: DocumentTextElement, //,
+ factoryForTag: function(tagName) {
+ return elements[tagName] || DocumentNodeElement;
+ }
};
});
\ No newline at end of file