Skip to content

Commit

Permalink
Update lib files
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim committed Mar 22, 2015
1 parent db9a20c commit 24acb88
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 120 deletions.
142 changes: 89 additions & 53 deletions lib/rangy-classapplier.js
Expand Up @@ -9,8 +9,8 @@
*
* Copyright 2015, Tim Down
* Licensed under the MIT license.
* Version: 1.3.0-beta.1
* Build date: 12 February 2015
* Version: 1.3.0-beta.2
* Build date: 22 March 2015
*/
(function(factory, root) {
if (typeof define == "function" && define.amd) {
Expand All @@ -28,11 +28,11 @@
var dom = api.dom;
var DomPosition = dom.DomPosition;
var contains = dom.arrayContains;
var isHtmlNamespace = dom.isHtmlNamespace;
var forEach = api.util.forEach;


var defaultTagName = "span";
var createElementNSSupported = api.util.isHostMethod(document, "createElementNS");

function each(obj, func) {
for (var i in obj) {
Expand All @@ -49,53 +49,74 @@
return str.replace(/^\s\s*/, "").replace(/\s\s*$/, "");
}

var hasClass, addClass, removeClass;
if (api.util.isHostObject(document.createElement("div"), "classList")) {
hasClass = function(el, className) {
return el.classList.contains(className);
};

addClass = function(el, className) {
return el.classList.add(className);
};
function classNameContainsClass(fullClassName, className) {
return !!fullClassName && new RegExp("(?:^|\\s)" + className + "(?:\\s|$)").test(fullClassName);
}

removeClass = function(el, className) {
return el.classList.remove(className);
};
} else {
hasClass = function(el, className) {
return el.className && new RegExp("(?:^|\\s)" + className + "(?:\\s|$)").test(el.className);
};
// Inefficient, inelegant nonsense for IE's svg element, which has no classList and non-HTML className implementation
function hasClass(el, className) {
if (typeof el.classList == "object") {
return el.classList.contains(className);
} else {
var classNameSupported = (typeof el.className == "string");
var elClass = classNameSupported ? el.className : el.getAttribute("class");
return classNameContainsClass(elClass, className);
}
}

addClass = function(el, className) {
if (el.className) {
if (!hasClass(el, className)) {
el.className += " " + className;
function addClass(el, className) {
if (typeof el.classList == "object") {
el.classList.add(className);
} else {
var classNameSupported = (typeof el.className == "string");
var elClass = classNameSupported ? el.className : el.getAttribute("class");
if (elClass) {
if (!classNameContainsClass(elClass, className)) {
elClass += " " + className;
}
} else {
el.className = className;
elClass = className;
}
};

removeClass = (function() {
function replacer(matched, whiteSpaceBefore, whiteSpaceAfter) {
return (whiteSpaceBefore && whiteSpaceAfter) ? " " : "";
if (classNameSupported) {
el.className = elClass;
} else {
el.setAttribute("class", elClass);
}
}
}

var removeClass = (function() {
function replacer(matched, whiteSpaceBefore, whiteSpaceAfter) {
return (whiteSpaceBefore && whiteSpaceAfter) ? " " : "";
}

return function(el, className) {
if (el.className) {
el.className = el.className.replace(new RegExp("(^|\\s)" + className + "(\\s|$)"), replacer);
return function(el, className) {
if (typeof el.classList == "object") {
el.classList.remove(className);
} else {
var classNameSupported = (typeof el.className == "string");
var elClass = classNameSupported ? el.className : el.getAttribute("class");
elClass = elClass.replace(new RegExp("(^|\\s)" + className + "(\\s|$)"), replacer);
if (classNameSupported) {
el.className = elClass;
} else {
el.setAttribute("class", elClass);
}
};
})();
}
};
})();

function getClass(el) {
var classNameSupported = (typeof el.className == "string");
return classNameSupported ? el.className : el.getAttribute("class");
}

function sortClassName(className) {
return className && className.split(/\s+/).sort().join(" ");
}

function getSortedClassName(el) {
return sortClassName(el.className);
return sortClassName( getClass(el) );
}

function haveSameClasses(el1, el2) {
Expand All @@ -112,6 +133,11 @@
return true;
}

function canTextBeStyled(textNode) {
var parent = textNode.parentNode;
return (parent && parent.nodeType == 1 && !/^(textarea|style|script|select|iframe)$/i.test(parent.nodeName));
}

function movePosition(position, oldParent, oldIndex, newParent, newIndex) {
var posNode = position.node, posOffset = position.offset;
var newNode = posNode, newOffset = posOffset;
Expand Down Expand Up @@ -169,7 +195,7 @@
movePositionWhenRemovingNode(position, oldParent, oldIndex);
});

node.parentNode.removeChild(node);
dom.removeNode(node);
}

function moveChildrenPreservingPositions(node, newParent, newIndex, removeNode, positionsToPreserve) {
Expand Down Expand Up @@ -227,7 +253,7 @@
attr2 = el2.attributes.getNamedItem(name);
if ( (attr1 === null) != (attr2 === null) ) return false;
if (attr1.specified != attr2.specified) return false;
if (attr1.specified && attr1.value !== attr2.value) return false;
if (attr1.specified && attr1.nodeValue !== attr2.nodeValue) return false;
}
}
return true;
Expand Down Expand Up @@ -386,7 +412,6 @@
}

function areElementsMergeable(el1, el2) {
console.log("areElementsMergeable", haveSameClasses(el1, el2), elementsHaveSameNonClassAttributes(el1, el2))
return el1.namespaceURI == el2.namespaceURI &&
el1.tagName.toLowerCase() == el2.tagName.toLowerCase() &&
haveSameClasses(el1, el2) &&
Expand Down Expand Up @@ -423,7 +448,7 @@
var getPreviousMergeableTextNode = createAdjacentMergeableTextNodeGetter(false),
getNextMergeableTextNode = createAdjacentMergeableTextNodeGetter(true);


function Merge(firstNode) {
this.isElementMerge = (firstNode.nodeType == 1);
this.textNodes = [];
Expand All @@ -445,7 +470,7 @@
if (i > 0) {
parent.removeChild(textNode);
if (!parent.hasChildNodes()) {
parent.parentNode.removeChild(parent);
dom.removeNode(parent);
}
if (positionsToPreserve) {
forEach(positionsToPreserve, function(position) {
Expand Down Expand Up @@ -722,8 +747,13 @@
}
},

createContainer: function(doc) {
var el = doc.createElement(this.elementTagName);
createContainer: function(parentNode) {
var doc = dom.getDocument(parentNode);
var namespace;
var el = createElementNSSupported && !dom.isHtmlNamespace(parentNode) && (namespace = parentNode.namespaceURI) ?
doc.createElementNS(parentNode.namespaceURI, this.elementTagName) :
doc.createElement(this.elementTagName);

this.copyPropertiesToElement(this.elementProperties, el, false);
this.copyAttributesToElement(this.elementAttributes, el);
addClass(el, this.className);
Expand Down Expand Up @@ -761,25 +791,30 @@
},

applyToTextNode: function(textNode, positionsToPreserve) {
var parent = textNode.parentNode;
if (parent.childNodes.length == 1 &&

// Check whether the text node can be styled. Text within a <style> or <script> element, for example,
// should not be styled. See issue 283.
if (canTextBeStyled(textNode)) {
var parent = textNode.parentNode;
if (parent.childNodes.length == 1 &&
this.useExistingElements &&
isHtmlNamespace(parent) &&
this.appliesToElement(parent) &&
this.elementHasProperties(parent, this.elementProperties) &&
this.elementHasAttributes(parent, this.elementAttributes)) {

addClass(parent, this.className);
} else {
var el = this.createContainer(dom.getDocument(textNode));
textNode.parentNode.insertBefore(el, textNode);
el.appendChild(textNode);
addClass(parent, this.className);
} else {
var textNodeParent = textNode.parentNode;
var el = this.createContainer(textNodeParent);
textNodeParent.insertBefore(el, textNode);
el.appendChild(textNode);
}
}

},

isRemovable: function(el) {
return isHtmlNamespace(el) &&
el.tagName.toLowerCase() == this.elementTagName &&
return el.tagName.toLowerCase() == this.elementTagName &&
getSortedClassName(el) == this.elementSortedClassName &&
this.elementHasProperties(el, this.elementProperties) &&
!elementHasNonClassAttributes(el, this.attrExceptions) &&
Expand Down Expand Up @@ -1044,6 +1079,7 @@
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass,
getClass: getClass,
hasSameClasses: haveSameClasses,
hasAllClasses: hasAllClasses,
replaceWithOwnChildren: replaceWithOwnChildrenPreservingPositions,
Expand All @@ -1058,6 +1094,6 @@
api.CssClassApplier = api.ClassApplier = ClassApplier;
api.createCssClassApplier = api.createClassApplier = createClassApplier;
});

return rangy;
}, this);

0 comments on commit 24acb88

Please sign in to comment.