EN
JavaScript - create HTML shortcut
9 points
In this short article, we would like to show how to create shortcut for indicated HTML using JavaScript.
As HTML shortcut we understand inner text and HTML elements cut to desired length.

Practical example:
xxxxxxxxxx
1
2
<html>
3
<head>
4
<style>
5
6
div.html {
7
border: 1px solid blue;
8
}
9
10
div.shortcut {
11
max-height: 150px;
12
text-overflow: ellipsis;
13
white-space: nowrap;
14
overflow: hidden;
15
}
16
17
div.section + div.section {
18
margin: 20px 0 0 0;
19
}
20
21
</style>
22
</head>
23
<body>
24
<div class="section">
25
<div class="title">Input:</div>
26
<div class="html input" id="input">
27
<h4>Title</h4>
28
<p>Example paragraph 1</p>
29
<p>Example paragraph 2</p>
30
<p>Example paragraph 3</p>
31
<p>Example paragraph 4</p>
32
<p>Sign</p>
33
</div>
34
</div>
35
<div class="section">
36
<div class="title">Output (shortcut):</div>
37
<div class="html shortcut" id="shortcut"></div>
38
</div>
39
<script>
40
41
function createArray(collection) {
42
var result = new Array(collection.length);
43
for (var i = 0; i < collection.length; ++i) {
44
result[i] = collection[i];
45
}
46
return result;
47
}
48
49
function createTemplate(html) {
50
var element = document.createElement('template');
51
element.innerHTML = html;
52
return element;
53
}
54
55
function parseHtml(html) {
56
var template = createTemplate(html);
57
return createArray(template.content.childNodes);
58
}
59
60
function renderHtml(nodes) {
61
var html = '';
62
for (var i = 0; i < nodes.length; ++i) {
63
var node = nodes[i];
64
html += node.outerHTML || node.textContent;
65
}
66
return html;
67
}
68
69
function iterateChildren(node, callback) {
70
var nodes = node.childNodes;
71
for (var i = 0; i < nodes.length; ++i) {
72
var result = callback(nodes[i]);
73
if (result === false) {
74
return false;
75
}
76
}
77
return true;
78
}
79
80
function processElement(node, processText) {
81
var index = 0;
82
var result = node.cloneNode(false);
83
var status = iterateChildren(node, function(child) {
84
var item = processNode(child, processText);
85
if (item == null) { // null or undefined
86
return false;
87
}
88
index += 1;
89
result.appendChild(item);
90
});
91
if (status === false && index === 0) {
92
return null;
93
}
94
return result;
95
}
96
97
function processText(node, converter) {
98
var text = converter(node.nodeValue);
99
if (text == null) { // null or undefined
100
return null;
101
}
102
return document.createTextNode(text);
103
}
104
105
function processNode(node, converter) {
106
switch (node.nodeType) {
107
case Node.ELEMENT_NODE:
108
return processElement(node, converter);
109
case Node.TEXT_NODE:
110
return processText(node, converter);
111
default:
112
throw new Error('Unsupported node type.');
113
}
114
}
115
116
function processNodes(nodes, converter) {
117
var result = [];
118
for (var i = 0; i < nodes.length; ++i) {
119
var item = processNode(nodes[i], converter);
120
if (item == null) { // null or undefined
121
break;
122
}
123
result.push(item);
124
}
125
return result;
126
}
127
128
function isWhiteCharacter(value) {
129
return value === ' ' || value === '\f' || value === '\n' || value === '\r' || value === '\t' || value === '\v' || value === '\u00a0' || value === '\u1680' || value === '\u2000' || value === '\u2001' || value === '\u2002' || value === '\u2003' || value === '\u2004' || value === '\u2005' || value === '\u2006' || value === '\u2007' || value === '\u2008' || value === '\u2009' || value === '\u200a' || value === '\u2028' || value === '\u2029' || value === '\u202f' || value === '\u205f' || value === '\u3000' || value === '\ufeff';
130
}
131
132
function createTextShortcut(text, limit) {
133
if (text.length > limit) {
134
var ending = false;
135
for (var i = limit - 3; i > -1; --i) {
136
if (isWhiteCharacter(text[i])) {
137
ending = true;
138
} else {
139
if (ending) {
140
limit = i + 4;
141
break;
142
}
143
}
144
}
145
var part = text.substring(0, limit - 3);
146
return part + '...';
147
}
148
return text;
149
}
150
151
function createNodesShortcut(nodes, limit) {
152
var count = 0; // stores characters count
153
var result = processNodes(nodes, function(text) {
154
if (count < limit) {
155
count += text.length;
156
if (count > limit) {
157
return createTextShortcut(text, text.length - count + limit);
158
}
159
return text;
160
}
161
return null;
162
});
163
return result;
164
}
165
166
function createHtmlShortcut(html, limit) {
167
var nodes = parseHtml(html);
168
var result = createNodesShortcut(nodes, limit);
169
return renderHtml(result);
170
}
171
172
173
// Usage example:
174
175
var inputElement = document.querySelector('#input');
176
var shortcutElement = document.querySelector('#shortcut');
177
178
var shortcutLimit = 50; // limited up to 50 characters
179
180
var inputHtml = inputElement.innerHTML.trim();
181
var shortcutHtml = createHtmlShortcut(inputHtml, shortcutLimit);
182
183
shortcutElement.innerHTML = shortcutHtml;
184
185
</script>
186
</body>
187
</html>