return element.dom();
});
+ var FIRST_CONTENT_INDEX = 1;
+
this.wrapper.find(':not(iframe)').addBack().contents()
.filter(function() {return this.nodeType === Node.TEXT_NODE})
.each(function() {
+
// TODO: use DocumentElement API
var el = $(this),
hasSpanBefore = el.prev().length > 0 && $(el.prev()[0]).attr('wlxml-tag') === 'span',
hasSpanAfter = el.next().length > 0 && $(el.next()[0]).attr('wlxml-tag') === 'span';
+ if(el.parent().hasClass('canvas-widget'))
+ return true; // continue
var addInfo = function(toAdd, where) {
var parentContents = elParent.contents(),
idx = parentContents.index(el[0]),
- prev = idx > 0 ? parentContents[idx-1] : null,
+ prev = idx > FIRST_CONTENT_INDEX ? parentContents[idx-1] : null,
next = idx < parentContents.length - 1 ? parentContents[idx+1] : null,
target, key;
+ text.trimmed
+ (endSpace && (hasSpanParent || hasSpanAfter) ? ' ' : '');
} else {
- if(text.trimmed.length === 0 && text.original.length > 0 && elParent.contents().length === 1)
+ if(text.trimmed.length === 0 && text.original.length > 0 && elParent.contents().length === 2)
text.transformed = ' ';
}
canvas.setCurrentElement(canvas.getDocumentElement(e.target), {caretTo: false});
});
-
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(documentElement.DocumentTextElement.isContentContainer(mutation.target) && mutation.target.data === '')
var config = { attributes: false, childList: false, characterData: true, subtree: true, characterDataOldValue: true};
observer.observe(this.d[0], config);
+ this.wrapper.on('mouseover', '[wlxml-tag], [wlxml-text]', function(e) {
+ var el = canvas.getDocumentElement(e.target);
+ if(!el)
+ return;
+ e.stopPropagation();
+ if(el instanceof documentElement.DocumentTextElement)
+ el = el.parent();
+ el.toggleLabel(true);
+ });
+ this.wrapper.on('mouseout', '[wlxml-tag], [wlxml-text]', function(e) {
+ var el = canvas.getDocumentElement(e.target);
+ if(!el)
+ return;
+ e.stopPropagation();
+ if(el instanceof documentElement.DocumentTextElement)
+ el = el.parent();
+ el.toggleLabel(false);
+ });
+
} else {
this.d = null;
}
describe('Canvas', function() {
- describe('Internal HTML representation of a sample document', function() {
- it('works', function() {
- var c = canvas.fromXML('\
- <section>\
- This is some text without its own wrapping tag.\
- <div class="p.subclass">\
- This is a paragraph.\
- </div>\
- <div>\
- This is text in a div <span>with some inline text</span>.\
- </div>\
- This is some text without its own wrapping tag.\
- </section>\
- ');
- var expected = '<div wlxml-tag="section">'
- + '<div wlxml-text>This is some text without its own wrapping tag.</div>'
- + '<div wlxml-tag="div" wlxml-class="p-subclass">'
- + '<div wlxml-text>This is a paragraph.</div>'
- + '</div>'
- + '<div wlxml-tag="div">'
- + '<div wlxml-text>This is text in a div </div>'
- + '<div wlxml-tag="span">'
- + '<div wlxml-text>with some inline text</div>'
- + '</div>'
- + '<div wlxml-text>.</div>'
- + '</div>'
- + '<div wlxml-text>This is some text without its own wrapping tag.</div>'
- + '</div>';
- expect(c.doc().dom()[0].isEqualNode($(expected)[0])).to.be.true;
- });
- });
-
describe('Internal HTML representation of a DocumentNodeElement', function() {
it('is always a div tag', function() {
['section', 'header', 'span', 'aside', 'figure'].forEach(function(tagName) {
it('returns position when browser selection collapsed', function() {
var c = canvas.fromXML('<section>Alice has a cat</section>'),
dom = c.doc().dom(),
- text = $(dom.contents()[0]).contents()[0];
+ text = $(dom.contents()[1]).contents()[0];
expect(text.nodeType).to.equal(Node.TEXT_NODE, 'correct node selected');
expect($(text).text()).to.equal('Alice has a cat');
var c = canvas.fromXML('<section>Alice <span>has</span> a <span>big</span> cat</section>'),
dom = c.doc().dom(),
text = {
- alice: dom.contents()[0],
- has: $(dom.contents()[1]).contents()[0],
- cat: dom.contents()[4]
+ alice: dom.contents()[1],
+ has: $(dom.contents()[2]).contents()[1],
+ cat: dom.contents()[5]
},
cursor = c.getCursor(),
aliceElement = c.getDocumentElement(text.alice),
var c = canvas.fromXML('<section>Alice <span>has</span> a <span>big</span> cat</section>'),
dom = c.doc().dom(),
text = {
- alice: dom.contents()[0],
- has: $(dom.contents()[1]).contents()[0],
- a: dom.contents()[2],
- big: $(dom.contents()[3]).contents()[0],
- cat: dom.contents()[4]
+ alice: dom.contents()[1],
+ has: $(dom.contents()[2]).contents()[1],
+ a: dom.contents()[3],
+ big: $(dom.contents()[4]).contents()[1],
+ cat: dom.contents()[5]
},
cursor = c.getCursor();
});
}
dom.data('other-attrs', params.others);
+
+ var widgets = $('<div class="canvas-widgets" contenteditable="false">');
+ widgets.append($('<span class="canvas-widget canvas-widget-label">').text(params.tag + (params.klass ? ' / ' + params.klass : '')));
+ dom.append(widgets);
+
+ // Make sure widgets aren't navigable with arrow keys
+ widgets.find('*').add(widgets).attr('tabindex', -1);
+
return dom;
},
var element = this;
elementContent.each(function(idx) {
var childElement = DocumentElement.fromHTMLElement(this, element.canvas);
- if(idx === 0 && elementContent.length > 1 && elementContent[1].nodeType === Node.ELEMENT_NODE && (childElement instanceof DocumentTextElement) && $.trim($(this).text()) === '')
+ if(childElement === undefined)
+ return true;
+ if(idx === 1 && elementContent.length > 2 && elementContent[1].nodeType === Node.ELEMENT_NODE && (childElement instanceof DocumentTextElement) && $.trim($(this).text()) === '')
return true;
if(idx > 0 && childElement instanceof DocumentTextElement) {
if(toret[toret.length-1] instanceof DocumentNodeElement && $.trim($(this).text()) === '')
return false;
},
-
getWlxmlMetaAttr: function(attr) {
return this.dom().attr('wlxml-meta-'+attr);
},
+
getWlxmlMetaAttrs: function() {
var toret = [];
var attrList = classAttributes.getMetaAttrsList(this.getWlxmlClass());
}, this);
return toret;
},
+
setWlxmlMetaAttr: function(attr, value) {
this.dom().attr('wlxml-meta-'+attr, value);
+ },
+
+ toggleLabel: function(toggle) {
+ var displayCss = toggle ? 'inline-block' : 'none';
+ var label = this.dom().children('.canvas-widgets').find('.canvas-widget-label');
+ label.css('display', displayCss);
+ this.dom().toggleClass('highlighted-element');
}
});
.highlighted-element {
border: 1px solid red;
}
+
+
+ .canvas-widgets {
+ display: inline;
+ }
+
+ .canvas-widget {
+ display: none;
+ }
+
+ .canvas-widget-label {
+ position: absolute;
+ display: none;
+ top: -20px;
+ left:0;
+ background-color: red;
+ color: white;
+ font-size:12px;
+ font-weight: bold;
+ padding: 1px 3px;
+ //width:300px;
+ opacity: 0.65;
+ font-family: monospace;
+ z-index:9999;
+ }
}
.rng-module-documentCanvas-currentNode {