forked from bartveneman/Spanner.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlettering.js
115 lines (98 loc) · 3.84 KB
/
lettering.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*jslint continue: true */
(function (d) {
"use strict";
var
/**
* Check if the given node is eligible for the lettering process;
* @param {DOM node} node [The node that should be checked]
* @return {DOM node} [The node that has been approved or false if the node is not eligible]
*/
checkNode = function (node) {
var
tagName = node.nodeName.toLowerCase(),
safeTags = ["em", "strong", "i", "b", "a", "small", "abbr", "cite", "dfn", "kbd", "samp", "bdo", "q", "span", "sub", "sup"];
if (node.nodeType === 3) {
// Node is a textNode. You're OK;
return node;
}
if (safeTags.indexOf(tagName) !== -1) {
// Assuming we can use firstChild here, as nesting of these
// tags is rarely done. #fingerscrossed;
return node.firstChild;
}
return false;
},
/**
* Wrap the given context in span elements
* @param {DOM node} context [A single DOM node to wrap in span tags]
* @return {DOM node} [The wrapped node]
*/
wrap = function (context) {
var
nodes = context.childNodes,
nodesLength = nodes.length,
node,
letters,
lettersLength,
wrapper = d.createDocumentFragment(),
span,
numLetters = 0,
i,
j;
// Outer loop: iterates over node children to check if
// they are of nodeType 3, which is a TextNode;
for (i = 0; i < nodesLength; i += 1) {
node = checkNode(nodes[i]);
if (!node) {
// not a node
continue;
}
// Split the node's text into separate characters;
letters = node.nodeValue.split('');
lettersLength = letters.length;
// Inner loop: give each seperate letter/character
// its own wrapper span element and append that to
// the documentFragment;
for (j = 0; j < lettersLength; j += 1) {
numLetters += 1;
span = d.createElement("span");
span.className = "char" + numLetters;
span.appendChild(d.createTextNode(letters[j]));
wrapper.appendChild(span);
}
// Replace the textnode with the wrapped substitute;
node.parentNode.replaceChild(wrapper, node);
}
},
/**
* Starting point of the lettering process;
* @param {DOM node(s)} context [The document element to apply lettering to]
* @return {DOM node(s)} [The document element that has lettering applied to]
*/
lettering = function (context) {
var
numElements,
i;
// Check if there is a valid context/DOM node;
if (!context || typeof context !== "object" || context === null) {
throw "Unable to perform lettering on context given.";
}
numElements = context.length;
if (numElements && numElements > 1) {
// Iterate over multiple elements ...
for (i = 0; i < numElements; i += 1) {
wrap(context[i]);
}
} else {
// ... or just a single one;
wrap(context);
}
return context;
};
// Make lettering globally accessible;
if (typeof exports !== "undefined") {
exports = lettering;
} else {
window.lettering = lettering;
}
}(document));