Adding mapbox-gl branch
This commit is contained in:
@@ -0,0 +1,645 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.editor.nodeTest');
|
||||
goog.setTestOnly('goog.editor.nodeTest');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.editor.node');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.testing.ExpectedFailures');
|
||||
goog.require('goog.testing.dom');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
var expectedFailures;
|
||||
var parentNode;
|
||||
var childNode1;
|
||||
var childNode2;
|
||||
var childNode3;
|
||||
|
||||
var gChildWsNode1 = null;
|
||||
var gChildTextNode1 = null;
|
||||
var gChildNbspNode1 = null;
|
||||
var gChildMixedNode1 = null;
|
||||
var gChildWsNode2a = null;
|
||||
var gChildWsNode2b = null;
|
||||
var gChildTextNode3a = null;
|
||||
var gChildWsNode3 = null;
|
||||
var gChildTextNode3b = null;
|
||||
|
||||
function setUpPage() {
|
||||
expectedFailures = new goog.testing.ExpectedFailures();
|
||||
parentNode = document.getElementById('parentNode');
|
||||
childNode1 = parentNode.childNodes[0];
|
||||
childNode2 = parentNode.childNodes[1];
|
||||
childNode3 = parentNode.childNodes[2];
|
||||
}
|
||||
|
||||
|
||||
function tearDown() {
|
||||
expectedFailures.handleTearDown();
|
||||
}
|
||||
|
||||
function setUpDomTree() {
|
||||
gChildWsNode1 = document.createTextNode(' \t\r\n');
|
||||
gChildTextNode1 = document.createTextNode('Child node');
|
||||
gChildNbspNode1 = document.createTextNode('\u00a0');
|
||||
gChildMixedNode1 = document.createTextNode('Text\n plus\u00a0');
|
||||
gChildWsNode2a = document.createTextNode('');
|
||||
gChildWsNode2b = document.createTextNode(' ');
|
||||
gChildTextNode3a = document.createTextNode('I am a grand child');
|
||||
gChildWsNode3 = document.createTextNode(' \t \r \n');
|
||||
gChildTextNode3b = document.createTextNode('I am also a grand child');
|
||||
|
||||
childNode3.appendChild(gChildTextNode3a);
|
||||
childNode3.appendChild(gChildWsNode3);
|
||||
childNode3.appendChild(gChildTextNode3b);
|
||||
|
||||
childNode1.appendChild(gChildMixedNode1);
|
||||
childNode1.appendChild(gChildWsNode1);
|
||||
childNode1.appendChild(gChildNbspNode1);
|
||||
childNode1.appendChild(gChildTextNode1);
|
||||
|
||||
childNode2.appendChild(gChildWsNode2a);
|
||||
childNode2.appendChild(gChildWsNode2b);
|
||||
document.body.appendChild(parentNode);
|
||||
}
|
||||
|
||||
function tearDownDomTree() {
|
||||
childNode1.innerHTML = childNode2.innerHTML = childNode3.innerHTML = '';
|
||||
gChildWsNode1 = null;
|
||||
gChildTextNode1 = null;
|
||||
gChildNbspNode1 = null;
|
||||
gChildMixedNode1 = null;
|
||||
gChildWsNode2a = null;
|
||||
gChildWsNode2b = null;
|
||||
gChildTextNode3a = null;
|
||||
gChildWsNode3 = null;
|
||||
gChildTextNode3b = null;
|
||||
}
|
||||
|
||||
function testGetCompatModeQuirks() {
|
||||
var quirksIfr = document.createElement('iframe');
|
||||
document.body.appendChild(quirksIfr);
|
||||
// Webkit used to default to standards mode, but fixed this in
|
||||
// Safari 4/Chrome 2, aka, WebKit 530.
|
||||
// Also IE10 fails here.
|
||||
// TODO(johnlenz): IE10+ inherit quirks mode from the owner document
|
||||
// according to:
|
||||
// http://msdn.microsoft.com/en-us/library/ff955402(v=vs.85).aspx
|
||||
// but this test shows different behavior for IE10 and 11. If we discover
|
||||
// that we care about quirks mode documents we should investigate
|
||||
// this failure.
|
||||
expectedFailures.expectFailureFor(
|
||||
(goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('530')) ||
|
||||
(goog.userAgent.IE && goog.userAgent.isVersionOrHigher('10') &&
|
||||
!goog.userAgent.isVersionOrHigher('11')));
|
||||
expectedFailures.run(function() {
|
||||
assertFalse('Empty sourceless iframe is quirks mode, not standards mode',
|
||||
goog.editor.node.isStandardsMode(
|
||||
goog.dom.getFrameContentDocument(quirksIfr)));
|
||||
});
|
||||
document.body.removeChild(quirksIfr);
|
||||
}
|
||||
|
||||
function testGetCompatModeStandards() {
|
||||
var standardsIfr = document.createElement('iframe');
|
||||
document.body.appendChild(standardsIfr);
|
||||
var doc = goog.dom.getFrameContentDocument(standardsIfr);
|
||||
doc.open();
|
||||
doc.write('<!DOCTYPE HTML><html><head></head><body> </body></html>');
|
||||
doc.close();
|
||||
assertTrue('Iframe with DOCTYPE written in is standards mode',
|
||||
goog.editor.node.isStandardsMode(doc));
|
||||
document.body.removeChild(standardsIfr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DOM tree and tests that getLeftMostLeaf returns proper node
|
||||
*/
|
||||
function testGetLeftMostLeaf() {
|
||||
setUpDomTree();
|
||||
|
||||
assertEquals('Should skip ws node', gChildMixedNode1,
|
||||
goog.editor.node.getLeftMostLeaf(parentNode));
|
||||
assertEquals('Should skip ws node', gChildMixedNode1,
|
||||
goog.editor.node.getLeftMostLeaf(childNode1));
|
||||
assertEquals('Has no non ws leaves', childNode2,
|
||||
goog.editor.node.getLeftMostLeaf(childNode2));
|
||||
assertEquals('Should return first child', gChildTextNode3a,
|
||||
goog.editor.node.getLeftMostLeaf(childNode3));
|
||||
assertEquals('Has no children', gChildTextNode1,
|
||||
goog.editor.node.getLeftMostLeaf(gChildTextNode1));
|
||||
|
||||
tearDownDomTree();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DOM tree and tests that getRightMostLeaf returns proper node
|
||||
*/
|
||||
function testGetRightMostLeaf() {
|
||||
setUpDomTree();
|
||||
|
||||
assertEquals("Should return child3's rightmost child", gChildTextNode3b,
|
||||
goog.editor.node.getRightMostLeaf(parentNode));
|
||||
assertEquals('Should skip ws node', gChildTextNode1,
|
||||
goog.editor.node.getRightMostLeaf(childNode1));
|
||||
assertEquals('Has no non ws leaves', childNode2,
|
||||
goog.editor.node.getRightMostLeaf(childNode2));
|
||||
assertEquals('Should return last child', gChildTextNode3b,
|
||||
goog.editor.node.getRightMostLeaf(childNode3));
|
||||
assertEquals('Has no children', gChildTextNode1,
|
||||
goog.editor.node.getRightMostLeaf(gChildTextNode1));
|
||||
|
||||
tearDownDomTree();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DOM tree and tests that getFirstChild properly ignores
|
||||
* ignorable nodes
|
||||
*/
|
||||
function testGetFirstChild() {
|
||||
setUpDomTree();
|
||||
|
||||
assertNull('Has no none ws children',
|
||||
goog.editor.node.getFirstChild(childNode2));
|
||||
assertEquals('Should skip first child, as it is ws', gChildMixedNode1,
|
||||
goog.editor.node.getFirstChild(childNode1));
|
||||
assertEquals('Should just return first child', gChildTextNode3a,
|
||||
goog.editor.node.getFirstChild(childNode3));
|
||||
assertEquals('Should return first child', childNode1,
|
||||
goog.editor.node.getFirstChild(parentNode));
|
||||
|
||||
assertNull('First child of a text node should return null',
|
||||
goog.editor.node.getFirstChild(gChildTextNode1));
|
||||
assertNull('First child of null should return null',
|
||||
goog.editor.node.getFirstChild(null));
|
||||
|
||||
tearDownDomTree();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a DOM tree and test that getLastChild properly ignores
|
||||
* ignorable nodes
|
||||
*/
|
||||
function testGetLastChild() {
|
||||
setUpDomTree();
|
||||
|
||||
assertNull('Has no none ws children',
|
||||
goog.editor.node.getLastChild(childNode2));
|
||||
assertEquals('Should skip last child, as it is ws', gChildTextNode1,
|
||||
goog.editor.node.getLastChild(childNode1));
|
||||
assertEquals('Should just return last child', gChildTextNode3b,
|
||||
goog.editor.node.getLastChild(childNode3));
|
||||
assertEquals('Should return last child', childNode3,
|
||||
goog.editor.node.getLastChild(parentNode));
|
||||
|
||||
assertNull('Last child of a text node should return null',
|
||||
goog.editor.node.getLastChild(gChildTextNode1));
|
||||
assertNull('Last child of null should return null',
|
||||
goog.editor.node.getLastChild(gChildTextNode1));
|
||||
|
||||
tearDownDomTree();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test if nodes that should be ignorable return false and nodes that should
|
||||
* not be ignored return true.
|
||||
*/
|
||||
function testIsImportant() {
|
||||
var wsNode = document.createTextNode(' \t\r\n');
|
||||
assertFalse('White space node is ignorable',
|
||||
goog.editor.node.isImportant(wsNode));
|
||||
var textNode = document.createTextNode('Hello');
|
||||
assertTrue('Text node is important', goog.editor.node.isImportant(textNode));
|
||||
var nbspNode = document.createTextNode('\u00a0');
|
||||
assertTrue('Node with nbsp is important',
|
||||
goog.editor.node.isImportant(nbspNode));
|
||||
var imageNode = document.createElement('img');
|
||||
assertTrue('Image node is important',
|
||||
goog.editor.node.isImportant(imageNode));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test that isAllNonNbspWhiteSpace returns true if node contains only
|
||||
* whitespace that is not nbsp and false otherwise
|
||||
*/
|
||||
function testIsAllNonNbspWhiteSpace() {
|
||||
var wsNode = document.createTextNode(' \t\r\n');
|
||||
assertTrue('String is all non nbsp',
|
||||
goog.editor.node.isAllNonNbspWhiteSpace(wsNode));
|
||||
var textNode = document.createTextNode('Hello');
|
||||
assertFalse('String should not be whitespace',
|
||||
goog.editor.node.isAllNonNbspWhiteSpace(textNode));
|
||||
var nbspNode = document.createTextNode('\u00a0');
|
||||
assertFalse('String has nbsp',
|
||||
goog.editor.node.isAllNonNbspWhiteSpace(nbspNode));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DOM tree and Test that getPreviousSibling properly ignores
|
||||
* ignorable nodes
|
||||
*/
|
||||
function testGetPreviousSibling() {
|
||||
setUpDomTree();
|
||||
|
||||
assertNull('No previous sibling',
|
||||
goog.editor.node.getPreviousSibling(gChildTextNode3a));
|
||||
assertEquals('Should have text sibling', gChildTextNode3a,
|
||||
goog.editor.node.getPreviousSibling(gChildWsNode3));
|
||||
assertEquals('Should skip over white space sibling', gChildTextNode3a,
|
||||
goog.editor.node.getPreviousSibling(gChildTextNode3b));
|
||||
assertNull('No previous sibling',
|
||||
goog.editor.node.getPreviousSibling(gChildMixedNode1));
|
||||
assertEquals('Should have mixed text sibling', gChildMixedNode1,
|
||||
goog.editor.node.getPreviousSibling(gChildWsNode1));
|
||||
assertEquals('Should skip over white space sibling', gChildMixedNode1,
|
||||
goog.editor.node.getPreviousSibling(gChildNbspNode1));
|
||||
assertNotEquals('Should not move past ws and nbsp', gChildMixedNode1,
|
||||
goog.editor.node.getPreviousSibling(gChildTextNode1));
|
||||
assertEquals('Should go to child 2', childNode2,
|
||||
goog.editor.node.getPreviousSibling(childNode3));
|
||||
assertEquals('Should go to child 1', childNode1,
|
||||
goog.editor.node.getPreviousSibling(childNode2));
|
||||
assertNull('Only has white space siblings',
|
||||
goog.editor.node.getPreviousSibling(gChildWsNode2b));
|
||||
|
||||
tearDownDomTree();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DOM tree and tests that getNextSibling properly ignores igrnorable
|
||||
* nodes when determining the next sibling
|
||||
*/
|
||||
function testGetNextSibling() {
|
||||
setUpDomTree();
|
||||
|
||||
assertEquals('Child 1 should have Child 2', childNode2,
|
||||
goog.editor.node.getNextSibling(childNode1));
|
||||
assertEquals('Child 2 should have child 3', childNode3,
|
||||
goog.editor.node.getNextSibling(childNode2));
|
||||
assertNull('Child 3 has no next sibling',
|
||||
goog.editor.node.getNextSibling(childNode3));
|
||||
assertNotEquals('Should not skip ws and nbsp nodes', gChildTextNode1,
|
||||
goog.editor.node.getNextSibling(gChildMixedNode1));
|
||||
assertNotEquals('Should not skip nbsp node', gChildTextNode1,
|
||||
goog.editor.node.getNextSibling(gChildWsNode1));
|
||||
assertEquals('Should have sibling', gChildTextNode1,
|
||||
goog.editor.node.getNextSibling(gChildNbspNode1));
|
||||
assertNull('Should have no next sibling',
|
||||
goog.editor.node.getNextSibling(gChildTextNode1));
|
||||
assertNull('Only has ws sibling',
|
||||
goog.editor.node.getNextSibling(gChildWsNode2a));
|
||||
assertNull('Has no next sibling',
|
||||
goog.editor.node.getNextSibling(gChildWsNode2b));
|
||||
assertEquals('Should skip ws node', gChildTextNode3b,
|
||||
goog.editor.node.getNextSibling(gChildTextNode3a));
|
||||
|
||||
tearDownDomTree();
|
||||
}
|
||||
|
||||
|
||||
function testIsEmpty() {
|
||||
var textNode = document.createTextNode('');
|
||||
assertTrue('Text node with no content should be empty',
|
||||
goog.editor.node.isEmpty(textNode));
|
||||
textNode.data = '\xa0';
|
||||
assertTrue('Text node with nbsp should be empty',
|
||||
goog.editor.node.isEmpty(textNode));
|
||||
assertFalse('Text node with nbsp should not be empty when prohibited',
|
||||
goog.editor.node.isEmpty(textNode, true));
|
||||
|
||||
textNode.data = ' ';
|
||||
assertTrue('Text node with whitespace should be empty',
|
||||
goog.editor.node.isEmpty(textNode));
|
||||
textNode.data = 'notEmpty';
|
||||
assertFalse('Text node with text should not be empty',
|
||||
goog.editor.node.isEmpty(textNode));
|
||||
|
||||
var div = document.createElement('div');
|
||||
assertTrue('Empty div should be empty',
|
||||
goog.editor.node.isEmpty(div));
|
||||
div.innerHTML = '<iframe></iframe>';
|
||||
assertFalse('Div containing an iframe is not empty',
|
||||
goog.editor.node.isEmpty(div));
|
||||
div.innerHTML = '<img></img>';
|
||||
assertFalse('Div containing an image is not empty',
|
||||
goog.editor.node.isEmpty(div));
|
||||
div.innerHTML = '<embed></embed>';
|
||||
assertFalse('Div containing an embed is not empty',
|
||||
goog.editor.node.isEmpty(div));
|
||||
div.innerHTML = '<div><span></span></div>';
|
||||
assertTrue('Div containing other empty tags is empty',
|
||||
goog.editor.node.isEmpty(div));
|
||||
div.innerHTML = '<div><span> </span></div>';
|
||||
assertTrue('Div containing other empty tags and whitespace is empty',
|
||||
goog.editor.node.isEmpty(div));
|
||||
div.innerHTML = '<div><span>Not empty</span></div>';
|
||||
assertFalse('Div containing tags and text is not empty',
|
||||
goog.editor.node.isEmpty(div));
|
||||
|
||||
var img = document.createElement(goog.dom.TagName.IMG);
|
||||
assertFalse('Empty img should not be empty',
|
||||
goog.editor.node.isEmpty(img));
|
||||
|
||||
var iframe = document.createElement(goog.dom.TagName.IFRAME);
|
||||
assertFalse('Empty iframe should not be empty',
|
||||
goog.editor.node.isEmpty(iframe));
|
||||
|
||||
var embed = document.createElement('embed');
|
||||
assertFalse('Empty embed should not be empty',
|
||||
goog.editor.node.isEmpty(embed));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test that getLength returns 0 if the node has no length and no children,
|
||||
* the # of children if the node has no length but does have children,
|
||||
* and the length of the node if the node does have length
|
||||
*/
|
||||
function testGetLength() {
|
||||
var parentNode = document.createElement('p');
|
||||
|
||||
assertEquals('Length 0 and no children', 0,
|
||||
goog.editor.node.getLength(parentNode));
|
||||
|
||||
var childNode1 = document.createTextNode('node 1');
|
||||
var childNode2 = document.createTextNode('node number 2');
|
||||
var childNode3 = document.createTextNode('');
|
||||
parentNode.appendChild(childNode1);
|
||||
parentNode.appendChild(childNode2);
|
||||
parentNode.appendChild(childNode3);
|
||||
assertEquals('Length 0 and 3 children', 3,
|
||||
goog.editor.node.getLength(parentNode));
|
||||
assertEquals('Text node, length 6', 6,
|
||||
goog.editor.node.getLength(childNode1));
|
||||
assertEquals('Text node, length 0', 0,
|
||||
goog.editor.node.getLength(childNode3));
|
||||
}
|
||||
|
||||
function testFindInChildrenSuccess() {
|
||||
var parentNode = document.createElement('div');
|
||||
parentNode.innerHTML = '<div>foo</div><b>foo2</b>';
|
||||
|
||||
var index = goog.editor.node.findInChildren(parentNode,
|
||||
function(node) {
|
||||
return node.tagName == 'B';
|
||||
});
|
||||
assertEquals('Should find second child', index, 1);
|
||||
}
|
||||
|
||||
function testFindInChildrenFailure() {
|
||||
var parentNode = document.createElement('div');
|
||||
parentNode.innerHTML = '<div>foo</div><b>foo2</b>';
|
||||
|
||||
var index = goog.editor.node.findInChildren(parentNode,
|
||||
function(node) {
|
||||
return false;
|
||||
});
|
||||
assertNull("Shouldn't find a child", index);
|
||||
}
|
||||
|
||||
function testFindHighestMatchingAncestor() {
|
||||
setUpDomTree();
|
||||
var predicateFunc = function(node) {
|
||||
return node.tagName == 'DIV';
|
||||
};
|
||||
var node = goog.editor.node.findHighestMatchingAncestor(
|
||||
gChildTextNode3a, predicateFunc);
|
||||
assertNotNull('Should return an ancestor', node);
|
||||
assertEquals('Should have found "parentNode" as the last ' +
|
||||
'ancestor matching the predicate',
|
||||
parentNode,
|
||||
node);
|
||||
|
||||
predicateFunc = function(node) {
|
||||
return node.childNodes.length == 1;
|
||||
};
|
||||
node = goog.editor.node.findHighestMatchingAncestor(gChildTextNode3a,
|
||||
predicateFunc);
|
||||
assertNull("Shouldn't return an ancestor", node);
|
||||
|
||||
tearDownDomTree();
|
||||
}
|
||||
|
||||
function testIsBlock() {
|
||||
var blockDisplays = ['block', 'list-item', 'table', 'table-caption',
|
||||
'table-cell', 'table-column', 'table-column-group', 'table-footer',
|
||||
'table-footer-group', 'table-header-group', 'table-row',
|
||||
'table-row-group'];
|
||||
|
||||
var structuralTags = [
|
||||
goog.dom.TagName.BODY,
|
||||
goog.dom.TagName.FRAME,
|
||||
goog.dom.TagName.FRAMESET,
|
||||
goog.dom.TagName.HEAD,
|
||||
goog.dom.TagName.HTML
|
||||
];
|
||||
|
||||
// The following tags are considered inline in IE, except LEGEND which is
|
||||
// only a block element in WEBKIT.
|
||||
var ambiguousTags = [
|
||||
goog.dom.TagName.DETAILS,
|
||||
goog.dom.TagName.HR,
|
||||
goog.dom.TagName.ISINDEX,
|
||||
goog.dom.TagName.LEGEND,
|
||||
goog.dom.TagName.MAP,
|
||||
goog.dom.TagName.NOFRAMES,
|
||||
goog.dom.TagName.OPTGROUP,
|
||||
goog.dom.TagName.OPTION,
|
||||
goog.dom.TagName.SUMMARY
|
||||
];
|
||||
|
||||
// Older versions of IE and Gecko consider the following elements to be
|
||||
// inline, but IE9+ and Gecko 2.0+ recognize the new elements.
|
||||
var legacyAmbiguousTags = [
|
||||
goog.dom.TagName.ARTICLE,
|
||||
goog.dom.TagName.ASIDE,
|
||||
goog.dom.TagName.FIGCAPTION,
|
||||
goog.dom.TagName.FIGURE,
|
||||
goog.dom.TagName.FOOTER,
|
||||
goog.dom.TagName.HEADER,
|
||||
goog.dom.TagName.HGROUP,
|
||||
goog.dom.TagName.NAV,
|
||||
goog.dom.TagName.SECTION
|
||||
];
|
||||
|
||||
var tagsToIgnore = goog.array.flatten(structuralTags, ambiguousTags);
|
||||
|
||||
if ((goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) ||
|
||||
(goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('2'))) {
|
||||
goog.array.extend(tagsToIgnore, legacyAmbiguousTags);
|
||||
}
|
||||
|
||||
// Appending an applet tag can cause the test to hang if Java is blocked on
|
||||
// the system.
|
||||
tagsToIgnore.push(goog.dom.TagName.APPLET);
|
||||
|
||||
// Appending an embed tag to the page in IE brings up a warning dialog about
|
||||
// loading Java content.
|
||||
if (goog.userAgent.IE) {
|
||||
tagsToIgnore.push(goog.dom.TagName.EMBED);
|
||||
}
|
||||
|
||||
for (var tag in goog.dom.TagName) {
|
||||
if (goog.array.contains(tagsToIgnore, tag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var el = goog.dom.createElement(tag);
|
||||
document.body.appendChild(el);
|
||||
var display = goog.style.getCascadedStyle(el, 'display') ||
|
||||
goog.style.getComputedStyle(el, 'display');
|
||||
goog.dom.removeNode(el);
|
||||
|
||||
if (goog.editor.node.isBlockTag(el)) {
|
||||
assertContains('Display for ' + tag + ' should be block-like',
|
||||
display, blockDisplays);
|
||||
} else {
|
||||
assertNotContains('Display for ' + tag + ' should not be block-like',
|
||||
display, blockDisplays);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createDivWithTextNodes(var_args) {
|
||||
var dom = goog.dom.createDom('div');
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
goog.dom.appendChild(dom, goog.dom.createTextNode(arguments[i]));
|
||||
}
|
||||
return dom;
|
||||
}
|
||||
|
||||
function testSkipEmptyTextNodes() {
|
||||
assertNull('skipEmptyTextNodes should gracefully handle null',
|
||||
goog.editor.node.skipEmptyTextNodes(null));
|
||||
|
||||
var dom1 = createDivWithTextNodes('abc', '', 'xyz', '', '');
|
||||
assertEquals('expected not to skip first child', dom1.firstChild,
|
||||
goog.editor.node.skipEmptyTextNodes(dom1.firstChild));
|
||||
assertEquals('expected to skip second child', dom1.childNodes[2],
|
||||
goog.editor.node.skipEmptyTextNodes(dom1.childNodes[1]));
|
||||
assertNull('expected to skip all the rest of the children',
|
||||
goog.editor.node.skipEmptyTextNodes(dom1.childNodes[3]));
|
||||
}
|
||||
|
||||
function testIsEditableContainer() {
|
||||
var editableContainerElement = document.getElementById('editableTest');
|
||||
assertTrue('Container element should be considered editable container',
|
||||
goog.editor.node.isEditableContainer(editableContainerElement));
|
||||
|
||||
var nonEditableContainerElement = document.getElementById('parentNode');
|
||||
assertFalse('Other element should not be considered editable container',
|
||||
goog.editor.node.isEditableContainer(nonEditableContainerElement));
|
||||
}
|
||||
|
||||
function testIsEditable() {
|
||||
var editableContainerElement = document.getElementById('editableTest');
|
||||
var childNode = editableContainerElement.firstChild;
|
||||
var childElement = editableContainerElement.getElementsByTagName('span')[0];
|
||||
|
||||
assertFalse('Container element should not be considered editable',
|
||||
goog.editor.node.isEditable(editableContainerElement));
|
||||
assertTrue('Child text node should be considered editable',
|
||||
goog.editor.node.isEditable(childNode));
|
||||
assertTrue('Child element should be considered editable',
|
||||
goog.editor.node.isEditable(childElement));
|
||||
assertTrue('Grandchild node should be considered editable',
|
||||
goog.editor.node.isEditable(childElement.firstChild));
|
||||
assertFalse('Other element should not be considered editable',
|
||||
goog.editor.node.isEditable(document.getElementById('parentNode')));
|
||||
}
|
||||
|
||||
function testFindTopMostEditableAncestor() {
|
||||
var root = document.getElementById('editableTest');
|
||||
var span = root.getElementsByTagName(goog.dom.TagName.SPAN)[0];
|
||||
var textNode = span.firstChild;
|
||||
|
||||
assertEquals('Should return self if self is matched.',
|
||||
textNode, goog.editor.node.findTopMostEditableAncestor(textNode,
|
||||
function(node) {
|
||||
return node.nodeType == goog.dom.NodeType.TEXT;
|
||||
}));
|
||||
assertEquals('Should not walk out of editable node.',
|
||||
null, goog.editor.node.findTopMostEditableAncestor(textNode,
|
||||
function(node) {
|
||||
return node.tagName == goog.dom.TagName.BODY;
|
||||
}));
|
||||
assertEquals('Should not match editable container.',
|
||||
null, goog.editor.node.findTopMostEditableAncestor(textNode,
|
||||
function(node) {
|
||||
return node.tagName == goog.dom.TagName.DIV;
|
||||
}));
|
||||
assertEquals('Should find node in editable container.',
|
||||
span, goog.editor.node.findTopMostEditableAncestor(textNode,
|
||||
function(node) {
|
||||
return node.tagName == goog.dom.TagName.SPAN;
|
||||
}));
|
||||
}
|
||||
|
||||
function testSplitDomTreeAt() {
|
||||
var innerHTML = '<p>1<b>2</b>3</p>';
|
||||
var root = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
|
||||
root.innerHTML = innerHTML;
|
||||
var result = goog.editor.node.splitDomTreeAt(
|
||||
root.getElementsByTagName(goog.dom.TagName.B)[0], null, root);
|
||||
goog.testing.dom.assertHtmlContentsMatch('<p>1<b>2</b></p>', root);
|
||||
goog.testing.dom.assertHtmlContentsMatch('<p>3</p>', result);
|
||||
|
||||
root.innerHTML = innerHTML;
|
||||
result = goog.editor.node.splitDomTreeAt(
|
||||
root.getElementsByTagName(goog.dom.TagName.B)[0],
|
||||
goog.dom.createTextNode('and'),
|
||||
root);
|
||||
goog.testing.dom.assertHtmlContentsMatch('<p>1<b>2</b></p>', root);
|
||||
goog.testing.dom.assertHtmlContentsMatch('<p>and3</p>', result);
|
||||
}
|
||||
|
||||
function testTransferChildren() {
|
||||
var prefix = '<b>Bold 1</b>';
|
||||
var innerHTML = '<b>Bold</b><ul><li>Item 1</li><li>Item 2</li></ul>';
|
||||
|
||||
var root1 = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
root1.innerHTML = innerHTML;
|
||||
|
||||
var root2 = goog.dom.createElement(goog.dom.TagName.P);
|
||||
root2.innerHTML = prefix;
|
||||
|
||||
var b = root1.getElementsByTagName(goog.dom.TagName.B)[0];
|
||||
|
||||
// Transfer the children.
|
||||
goog.editor.node.transferChildren(root2, root1);
|
||||
assertEquals(0, root1.childNodes.length);
|
||||
goog.testing.dom.assertHtmlContentsMatch(prefix + innerHTML, root2);
|
||||
assertEquals(b, root2.getElementsByTagName(goog.dom.TagName.B)[1]);
|
||||
|
||||
// Transfer them back.
|
||||
goog.editor.node.transferChildren(root1, root2);
|
||||
assertEquals(0, root2.childNodes.length);
|
||||
goog.testing.dom.assertHtmlContentsMatch(prefix + innerHTML, root1);
|
||||
assertEquals(b, root1.getElementsByTagName(goog.dom.TagName.B)[1]);
|
||||
}
|
||||
Reference in New Issue
Block a user