├── CNAME
├── LICENSE
├── README.md
├── android-chrome-192x192.png
├── android-chrome-256x256.png
├── apple-touch-icon.png
├── browserconfig.xml
├── customizer.html
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── feather.png
├── index.html
├── ldom.dev.js
├── mstile-150x150.png
├── resources
├── FileSaver.js
├── blob.js
├── close.svg
├── main.css
├── menu.svg
├── prism
│ ├── prism.css
│ └── prism.js
└── uglify
│ ├── ast.js
│ ├── compress.js
│ ├── minify.js
│ ├── output.js
│ ├── parse.js
│ ├── scope.js
│ ├── transform.js
│ └── utils.js
├── robots.txt
├── safari-pinned-tab.svg
├── site.webmanifest
└── tests
├── index.html
└── script.js
/CNAME:
--------------------------------------------------------------------------------
1 | lightweightdom.com
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Creative Tech Guy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
LDOM
2 |
3 | A Lightweight JavaScript library to interact with the browser DOM.
4 |
5 | Full documentation, customizers, downloaders and examples available at [lightweightdom.com](https://lightweightdom.com).
6 |
7 | Getting Started
8 |
9 | LDOM is a Lightweight (about 8% of the size of jQuery) way to interact with the browser DOM (Document Object Model).
10 |
11 | If you are familiar with jQuery, then LDOM will feel very similar. In many common use cases, LDOM can simply be a drop-in replacement to jQuery without any problems. One way that LDOM is so much smaller and faster than jQuery is that it doesn't support all of the ancient browsers that jQuery does. That being said, by using LDOM, here are the minimum browser versions that are supported. (Basically any browser since 2013)
12 |
13 | | Browser | Version |
14 | |---------|---------|
15 | | Chrome | 29 |
16 | | Firefox | 23 |
17 | | Safari | 6 |
18 | | IE | 9 |
19 | | Edge | all |
20 | | Opera | 12 |
21 |
22 | Example Usage
23 | Comparison between LDOM and Vanilla JavaScript
24 |
25 | ---
26 |
27 | Set the text of all buttons.
28 |
29 | #### LDOM
30 | ```js
31 | $("button").text("I am a Button");
32 | ```
33 | #### Vanilla JavaScript
34 | ```js
35 | var buttons = document.querySelectorAll("button");
36 | for (var i = 0; i < buttons.length; i++) {
37 | buttons[i].innerText = "I am a Button";
38 | }
39 | ```
40 | ---
41 |
42 | Add a class to all parents of buttons.
43 |
44 | #### LDOM
45 | ```js
46 | $("button").parent().addClass("button-parent");
47 | ```
48 | #### Vanilla JavaScript
49 | ```js
50 | var buttons = document.querySelectorAll("button");
51 | for (var i = 0; i < buttons.length; i++) {
52 | if (buttons[i].parentNode.className.split(" ").indexOf("button-parent") === -1) {
53 | buttons[i].parentNode.className += " " + "button-parent";
54 | }
55 | }
56 | ```
57 | ---
58 |
59 | Add a click event to all buttons. Remove that event from a certain button.
60 |
61 | #### LDOM
62 | ```js
63 | var activateButtonEventId = $("button").on("click", function() {
64 | this.addClass("button-active");
65 | });
66 | $("button").eq(1).off(activateButtonEventId);
67 | ```
68 | #### Vanilla JavaScript
69 | ```js
70 | var buttons = document.querySelectorAll("button");
71 | for (var i = 0; i < buttons.length; i++) {
72 | buttons[i].addEventListener("click", addButtonActiveClass);
73 | }
74 | buttons[1].removeEventListener("click", addButtonActiveClass);
75 |
76 | function addButtonActiveClass(){
77 | if (buttons[i].className.split(" ").indexOf("button-active") === -1) {
78 | buttons[i].className += " " + "button-active";
79 | }
80 | }
81 | ```
82 | ---
83 |
84 |
85 | Create a text element and insert it after each button.
86 |
87 | #### LDOM
88 | ```js
89 | $("")
90 | .css("text-align", "center")
91 | .text("Click the button above!")
92 | .insertAfter($("button"));
93 | ```
94 | #### Vanilla JavaScript
95 | ```js
96 | var textElem = document.createElement("text");
97 | textElem.style.textAlign = "center";
98 | textElem.innerText = "Click the button above!";
99 | var buttons = document.querySelectorAll("button");
100 | for (var i = 0; i < buttons.length; i++) {
101 | buttons[i].parentNode.insertBefore(textElem.cloneNode(true), buttons[i].nextSibling);
102 | }
103 | ```
104 | ---
105 |
106 | ## Like what you see so far?
107 | ## Full documentation, customizers, downloaders and examples available at [lightweightdom.com](https://lightweightdom.com).
108 |
--------------------------------------------------------------------------------
/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/android-chrome-192x192.png
--------------------------------------------------------------------------------
/android-chrome-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/android-chrome-256x256.png
--------------------------------------------------------------------------------
/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/apple-touch-icon.png
--------------------------------------------------------------------------------
/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/customizer.html:
--------------------------------------------------------------------------------
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 | LDOM Customizer
32 |
33 |
34 |
35 |
77 |
78 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
122 |
123 | Customize LDOM Download
124 |
125 | After you have finished development, you can download a minified production version of LDOM here. You can run getLDOMFunctionUsage()
in the browser console of your webpage to see which LDOM functions you don't use. Make sure you interact with all of the features of your webpage to get accurate usage results.
126 |
127 |
128 |
129 |
130 |
131 |
135 |
Minification is not available on this browser. Please use a different browser. Desktop Chrome and Firefox are recommended.
136 |
137 |
138 |
139 |
140 |
141 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
258 |
259 |
--------------------------------------------------------------------------------
/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/favicon-16x16.png
--------------------------------------------------------------------------------
/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/favicon-32x32.png
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/favicon.ico
--------------------------------------------------------------------------------
/feather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/feather.png
--------------------------------------------------------------------------------
/ldom.dev.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var LDOMCache = {
3 | eventListenerCounter: 0,
4 | eventListenerFunctions: {},
5 | eventListenerFunctionsIds: {},
6 | functionsUsed: {}
7 | };
8 |
9 | function $(input) {
10 | if (typeof input === "string" && input[0] === "<" && input[input.length - 1] === ">") {
11 | return new LDOMObject(document.createElement(input.substring(1, input.length - 1)));
12 | } else if (input === null || !input) {
13 | return new LDOMObject([]);
14 | } else if (input._LDOM) {
15 | return input;
16 | } else if (input === window) {
17 | return new LDOMWindowObject();
18 | } else if (input.nodeType > 0) {
19 | return new LDOMObject(input);
20 | } else if (typeof input !== "string" && typeof input.length !== "undefined") {
21 | var elements = [];
22 | for (var i = 0; i < input.length; i++) {
23 | var obj = $(input[i]);
24 | if (obj.length > 0) {
25 | elements.push(obj);
26 | }
27 | }
28 | return new LDOMObject(elements);
29 | } else {
30 | return $(document).find(input);
31 | }
32 | }
33 | window.LDOM = $;
34 | window.$ = window.$ || $;
35 | window.getLDOMFunctionUsage = function() {
36 | var obj = $("");
37 | var keys = Object.keys(Object.getPrototypeOf(obj));
38 | var unused = [];
39 | for (var i = 0; i < keys.length; i++) {
40 | if (keys[i][0] !== "_" && !LDOMCache.functionsUsed[keys[i]] && typeof obj[keys[i]] === "function") {
41 | unused.push(keys[i]);
42 | }
43 | }
44 | return {
45 | used: Object.keys(LDOMCache.functionsUsed),
46 | unused: unused
47 | };
48 | };
49 |
50 | function LDOMObject(elem) {
51 | this._LDOM = true;
52 | if (Array.isArray(elem)) {
53 | this.length = elem.length;
54 | this._elements = elem;
55 | } else {
56 | this.length = 1;
57 | this._node = elem;
58 | }
59 | }
60 |
61 | LDOMObject.prototype.each = each;
62 | LDOMObject.prototype.equals = equals;
63 | LDOMObject.prototype.find = find;
64 | LDOMObject.prototype.get = get;
65 | LDOMObject.prototype.on = on;
66 | LDOMObject.prototype.off = off;
67 | LDOMObject.prototype.trigger = trigger;
68 | LDOMObject.prototype.hide = hide;
69 | LDOMObject.prototype.show = show;
70 | LDOMObject.prototype.toggle = toggle;
71 | LDOMObject.prototype.css = css;
72 | LDOMObject.prototype.html = html;
73 | LDOMObject.prototype.outerHTML = outerHTML;
74 | LDOMObject.prototype.text = text;
75 | LDOMObject.prototype.prop = prop;
76 | LDOMObject.prototype.attr = attr;
77 | LDOMObject.prototype.removeAttr = removeAttr;
78 | LDOMObject.prototype.addClass = addClass;
79 | LDOMObject.prototype.removeClass = removeClass;
80 | LDOMObject.prototype.hasClass = hasClass;
81 | LDOMObject.prototype.parent = parent;
82 | LDOMObject.prototype.children = children;
83 | LDOMObject.prototype.filter = filter;
84 | LDOMObject.prototype.first = first;
85 | LDOMObject.prototype.last = last;
86 | LDOMObject.prototype.eq = eq;
87 | LDOMObject.prototype.insertAfter = insertAfter;
88 | LDOMObject.prototype.insertBefore = insertBefore;
89 | LDOMObject.prototype.appendChild = appendChild;
90 | LDOMObject.prototype.prependChild = prependChild;
91 | LDOMObject.prototype.remove = remove;
92 |
93 | function LDOMWindowObject() {
94 | this._LDOM = true;
95 | this.length = 1;
96 | this._node = window;
97 | }
98 |
99 | LDOMWindowObject.prototype.each = each;
100 | LDOMWindowObject.prototype.equals = equals;
101 | LDOMWindowObject.prototype.get = get;
102 | LDOMWindowObject.prototype.on = on;
103 | LDOMWindowObject.prototype.off = off;
104 | LDOMWindowObject.prototype.trigger = trigger;
105 | LDOMWindowObject.prototype.prop = prop;
106 | LDOMWindowObject.prototype.attr = attr;
107 | LDOMWindowObject.prototype.removeAttr = removeAttr;
108 |
109 | function each(funct, reverse) {
110 | LDOMCache.functionsUsed[arguments.callee.name] = true;
111 | var elementsArray = getElementsArray(this);
112 | var start = reverse ? elementsArray.length - 1 : 0;
113 | var change = reverse ? -1 : 1;
114 | var end = (reverse ? 0 : elementsArray.length - 1) + change;
115 | for (var i = start; i !== end; i += change) {
116 | var shouldContinue = funct.apply(elementsArray[i], [i]);
117 | if (shouldContinue === false) {
118 | break;
119 | }
120 | }
121 | return this;
122 | }
123 |
124 | function equals(ldomObject) {
125 | LDOMCache.functionsUsed[arguments.callee.name] = true;
126 | if (this.length !== ldomObject.length) {
127 | return false;
128 | }
129 | var thisElementsArray = getElementsArray(this);
130 | var otherElementsArray = getElementsArray(ldomObject);
131 | if (thisElementsArray.length !== otherElementsArray.length) {
132 | return false;
133 | }
134 | var otherNodes = [];
135 | for (var i = 0; i < otherElementsArray.length; i++) {
136 | otherNodes.push(otherElementsArray[i]._node);
137 | }
138 | for (var i = 0; i < thisElementsArray.length; i++) {
139 | if (otherNodes.indexOf(thisElementsArray[i]._node) === -1) {
140 | return false;
141 | }
142 | }
143 | return true;
144 | }
145 |
146 | function find(selector) {
147 | LDOMCache.functionsUsed[arguments.callee.name] = true;
148 | var output = [];
149 | this.each(function() {
150 | var elems = this._node.querySelectorAll(selector);
151 | for (var i = 0; i < elems.length; i++) {
152 | output.push(elems[i]);
153 | }
154 | });
155 | return $(output);
156 | }
157 |
158 | function get(index) {
159 | LDOMCache.functionsUsed[arguments.callee.name] = true;
160 | if (!isDefined(index)) {
161 | var nodes = [];
162 | this.each(function() {
163 | nodes.push(this._node);
164 | });
165 | return nodes;
166 | } else {
167 | var elementsArray = getElementsArray(this);
168 | if (index < 0) {
169 | index = elementsArray.length + index;
170 | }
171 | if (!isDefined(elementsArray[index])) {
172 | return null;
173 | }
174 | return elementsArray[index]._node;
175 | }
176 | }
177 |
178 | function on(eventName, handler) {
179 | LDOMCache.functionsUsed[arguments.callee.name] = true;
180 | var eventId = ++LDOMCache.eventListenerCounter;
181 | var handlerWrapper = function(evt) {
182 | handler.apply($(this), [evt]);
183 | };
184 | this.each(function() {
185 | this._node.addEventListener(eventName, handlerWrapper);
186 | var eventIds = this._node._LDOMEvents || [];
187 | eventIds.push(eventId);
188 | this._node._LDOMEvents = eventIds;
189 | });
190 | if (!LDOMCache.eventListenerFunctions[eventName]) {
191 | LDOMCache.eventListenerFunctions[eventName] = {};
192 | }
193 | LDOMCache.eventListenerFunctions[eventName][eventId] = {
194 | funct: handlerWrapper,
195 | count: this.length
196 | };
197 | LDOMCache.eventListenerFunctionsIds[eventId] = {
198 | name: eventName
199 | };
200 | return eventId;
201 | }
202 |
203 | function off(eventName) {
204 | LDOMCache.functionsUsed[arguments.callee.name] = true;
205 | if (!isDefined(eventName)) {
206 | this.each(function() {
207 | var eventIds = this._node._LDOMEvents || [];
208 | for (var i = eventIds.length - 1; i >= 0; i--) {
209 | this.off(eventIds[i]);
210 | }
211 | });
212 | } else if (typeof eventName === "string") {
213 | this.each(function() {
214 | if (!LDOMCache.eventListenerFunctions[eventName]) {
215 | return;
216 | }
217 | var eventIds = this._node._LDOMEvents || [];
218 | for (var i = eventIds.length - 1; i >= 0; i--) {
219 | if (LDOMCache.eventListenerFunctionsIds[eventIds[i]].name === eventName) {
220 | this.off(eventIds[i]);
221 | }
222 | }
223 | });
224 | } else if (typeof eventName === "number") {
225 | var eventId = eventName;
226 | this.each(function() {
227 | if (!LDOMCache.eventListenerFunctionsIds[eventId]) {
228 | return;
229 | }
230 | var eventName = LDOMCache.eventListenerFunctionsIds[eventId].name;
231 | if (!LDOMCache.eventListenerFunctions[eventName][eventId]) {
232 | return;
233 | }
234 | var event = LDOMCache.eventListenerFunctions[eventName][eventId];
235 | this._node.removeEventListener(eventName, event.funct);
236 | var eventIds = this._node._LDOMEvents || [];
237 | eventIds.splice(eventIds.indexOf(eventId), 1);
238 | if (eventIds.length === 0) {
239 | delete this._node._LDOMEvents;
240 | } else {
241 | this._node._LDOMEvents = eventIds;
242 | }
243 | if (--event.count === 0) {
244 | delete LDOMCache.eventListenerFunctions[eventName][eventId];
245 | if (Object.keys(LDOMCache.eventListenerFunctions[eventName]).length === 0) {
246 | delete LDOMCache.eventListenerFunctions[eventName];
247 | }
248 | delete LDOMCache.eventListenerFunctionsIds[eventId];
249 | }
250 | });
251 | }
252 | }
253 |
254 | function trigger(eventName, data) {
255 | LDOMCache.functionsUsed[arguments.callee.name] = true;
256 | var event = document.createEvent("Event");
257 | event.initEvent(eventName, true, true);
258 | for (var key in (data || {})) {
259 | event[key] = data[key];
260 | }
261 | this.each(function() {
262 | var that = this;
263 | setTimeout(function() {
264 | that._node.dispatchEvent(event);
265 | }, 0);
266 | });
267 | return this;
268 | }
269 |
270 | function hide() {
271 | LDOMCache.functionsUsed[arguments.callee.name] = true;
272 | this.each(function() {
273 | if (this._node.style.display === "none") {
274 | return;
275 | }
276 | var isImportant = false;
277 | if (this._node.style.display !== "") {
278 | this._node.setAttribute("data-LDOM-hidden-previous-display", this._node.style.display);
279 | if (this._node.style.getPropertyPriority("display") === "important") {
280 | this._node.setAttribute("data-LDOM-hidden-previous-display-important", "true");
281 | isImportant = true;
282 | }
283 | }
284 | this._node.style.setProperty("display", "none", isImportant ? "important" : "");
285 | });
286 | return this;
287 | }
288 |
289 | function show() {
290 | LDOMCache.functionsUsed[arguments.callee.name] = true;
291 | this.each(function() {
292 | if (this._node.hasAttribute("data-LDOM-hidden-previous-display")) {
293 | this._node.style.setProperty("display", this._node.getAttribute("data-LDOM-hidden-previous-display"), this._node.hasAttribute("data-LDOM-hidden-previous-display-important") ? "important" : "");
294 | this._node.removeAttribute("data-LDOM-hidden-previous-display");
295 | this._node.removeAttribute("data-LDOM-hidden-previous-display-important");
296 | } else if (this._node.style.display === "none") {
297 | this._node.style.display = "";
298 | }
299 | });
300 | return this;
301 | }
302 |
303 | function toggle(show) {
304 | LDOMCache.functionsUsed[arguments.callee.name] = true;
305 | this.each(function() {
306 | var shouldShow = this._node.hasAttribute("data-LDOM-hidden-previous-display") || this._node.style.display === "none";
307 | if (isDefined(show)) {
308 | shouldShow = show;
309 | }
310 | if (shouldShow) {
311 | this.show()
312 | } else {
313 | this.hide();
314 | }
315 | });
316 | return this;
317 | }
318 |
319 | function css(property, value, isImportant) {
320 | LDOMCache.functionsUsed[arguments.callee.name] = true;
321 | if (!isDefined(value)) {
322 | var elementsArray = getElementsArray(this);
323 | return elementsArray.length > 0 ? window.getComputedStyle(elementsArray[0]._node)[property] : "";
324 | } else {
325 | this.each(function() {
326 | this._node.style.setProperty(property, value, isImportant ? "important" : "");
327 | });
328 | return this;
329 | }
330 | }
331 |
332 | function html(htmlString) {
333 | LDOMCache.functionsUsed[arguments.callee.name] = true;
334 | if (!isDefined(htmlString)) {
335 | var elementsArray = getElementsArray(this);
336 | return elementsArray.length > 0 ? elementsArray[0]._node.innerHTML : "";
337 | } else {
338 | return setPropertyAndRemoveDetachedNodes(this, "innerHTML", htmlString);
339 | }
340 | }
341 |
342 | function outerHTML(htmlString) {
343 | LDOMCache.functionsUsed[arguments.callee.name] = true;
344 | if (!isDefined(htmlString)) {
345 | var elementsArray = getElementsArray(this);
346 | return elementsArray.length > 0 ? elementsArray[0]._node.outerHTML : "";
347 | } else {
348 | return setPropertyAndRemoveDetachedNodes(this, "outerHTML", htmlString);
349 | }
350 | }
351 |
352 | function text(textString) {
353 | LDOMCache.functionsUsed[arguments.callee.name] = true;
354 | if (!isDefined(textString)) {
355 | var elementsArray = getElementsArray(this);
356 | return elementsArray.length > 0 ? elementsArray[0]._node.innerText : "";
357 | } else {
358 | return setPropertyAndRemoveDetachedNodes(this, "innerText", textString);
359 | }
360 | }
361 |
362 | function prop(propertyName, value) {
363 | LDOMCache.functionsUsed[arguments.callee.name] = true;
364 | if (!isDefined(value)) {
365 | var elementsArray = getElementsArray(this);
366 | return elementsArray.length > 0 ? elementsArray[0]._node[propertyName] : "";
367 | } else {
368 | this.each(function() {
369 | this._node[propertyName] = value;
370 | });
371 | return this;
372 | }
373 | }
374 |
375 | function attr(attributeName, value) {
376 | LDOMCache.functionsUsed[arguments.callee.name] = true;
377 | if (!isDefined(value)) {
378 | var elementsArray = getElementsArray(this);
379 | return elementsArray.length > 0 ? elementsArray[0]._node.getAttribute(attributeName) : "";
380 | } else {
381 | this.each(function() {
382 | this._node.setAttribute(attributeName, value);
383 | });
384 | return this;
385 | }
386 | }
387 |
388 | function removeAttr(attributeName) {
389 | LDOMCache.functionsUsed[arguments.callee.name] = true;
390 | this.each(function() {
391 | this._node.removeAttribute(attributeName);
392 | });
393 | return this;
394 | }
395 |
396 | function addClass(className) {
397 | LDOMCache.functionsUsed[arguments.callee.name] = true;
398 | this.each(function() {
399 | var classes = (this._node.getAttribute("class") || "").split(" ");
400 | var newClasses = className.split(" ");
401 | for (var i = 0; i < newClasses.length; i++) {
402 | if (classes.indexOf(newClasses[i]) === -1) {
403 | classes.push(newClasses[i]);
404 | }
405 | }
406 | this._node.setAttribute("class", classes.join(" ").trim());
407 | });
408 | return this;
409 | }
410 |
411 | function removeClass(className) {
412 | LDOMCache.functionsUsed[arguments.callee.name] = true;
413 | if (!isDefined(className)) {
414 | this.each(function() {
415 | this._node.removeAttribute("class");
416 | });
417 | } else {
418 | this.each(function() {
419 | var classes = (this._node.getAttribute("class") || "").split(" ");
420 | var newClasses = className.split(" ");
421 | for (var i = 0; i < newClasses.length; i++) {
422 | var classIndex = classes.indexOf(newClasses[i]);
423 | if (classIndex !== -1) {
424 | classes.splice(classIndex, 1);
425 | }
426 | }
427 | this._node.setAttribute("class", classes.join(" ").trim());
428 | });
429 | }
430 | return this;
431 | }
432 |
433 | function hasClass(className, all) {
434 | LDOMCache.functionsUsed[arguments.callee.name] = true;
435 | var doesHaveClass = false;
436 | this.each(function() {
437 | var classes = (this._node.getAttribute("class") || "").split(" ");
438 | if (classes.indexOf(className) !== -1) {
439 | doesHaveClass = true;
440 | if (!all) {
441 | return false;
442 | }
443 | } else {
444 | doesHaveClass = false;
445 | if (all) {
446 | return false;
447 | }
448 | }
449 | });
450 | return doesHaveClass;
451 | }
452 |
453 | function parent() {
454 | LDOMCache.functionsUsed[arguments.callee.name] = true;
455 | var output = [];
456 | this.each(function() {
457 | if (output.indexOf(this._node.parentNode) === -1) {
458 | output.push(this._node.parentNode);
459 | }
460 | });
461 | return $(output);
462 | }
463 |
464 | function children() {
465 | LDOMCache.functionsUsed[arguments.callee.name] = true;
466 | var output = [];
467 | this.each(function() {
468 | var elems = this._node.children;
469 | for (var i = 0; i < elems.length; i++) {
470 | output.push(elems[i]);
471 | }
472 | });
473 | return $(output);
474 | }
475 |
476 | function filter(selector) {
477 | LDOMCache.functionsUsed[arguments.callee.name] = true;
478 | if (!selector) {
479 | return $([]);
480 | }
481 | var matchesMethod = "matches";
482 | if (Element.prototype.matches) {
483 | matchesMethod = "matches";
484 | } else if (Element.prototype.matchesSelector) {
485 | matchesMethod = "matchesSelector";
486 | } else if (Element.prototype.msMatchesSelector) {
487 | matchesMethod = "msMatchesSelector";
488 | } else if (Element.prototype.webkitMatchesSelector) {
489 | matchesMethod = "webkitMatchesSelector";
490 | }
491 | var output = [];
492 | this.each(function() {
493 | if (this._node[matchesMethod](selector)) {
494 | output.push(this);
495 | }
496 | });
497 | return $(output);
498 | }
499 |
500 | function first() {
501 | LDOMCache.functionsUsed[arguments.callee.name] = true;
502 | var elementsArray = getElementsArray(this);
503 | if (elementsArray.length === 0) {
504 | return $([]);
505 | }
506 | return elementsArray[0];
507 | }
508 |
509 | function last() {
510 | LDOMCache.functionsUsed[arguments.callee.name] = true;
511 | var elementsArray = getElementsArray(this);
512 | if (elementsArray.length === 0) {
513 | return $([]);
514 | }
515 | return elementsArray[elementsArray.length - 1];
516 | }
517 |
518 | function eq(index) {
519 | LDOMCache.functionsUsed[arguments.callee.name] = true;
520 | var elementsArray = getElementsArray(this);
521 | if (index < 0) {
522 | index = elementsArray.length + index;
523 | }
524 | if (!isDefined(elementsArray[index])) {
525 | return $([]);
526 | }
527 | return elementsArray[index];
528 | }
529 |
530 | function insertAfter(ldomObjectTarget) {
531 | LDOMCache.functionsUsed[arguments.callee.name] = true;
532 | this.each(function() {
533 | var callingNode = this._node;
534 | ldomObjectTarget.each(function() {
535 | this._node.parentNode.insertBefore(callingNode.cloneNode(true), this._node.nextSibling);
536 | });
537 | }, true);
538 | return this;
539 | }
540 |
541 | function insertBefore(ldomObjectTarget) {
542 | LDOMCache.functionsUsed[arguments.callee.name] = true;
543 | this.each(function() {
544 | var callingNode = this._node;
545 | ldomObjectTarget.each(function() {
546 | this._node.parentNode.insertBefore(callingNode.cloneNode(true), this._node);
547 | });
548 | });
549 | return this;
550 | }
551 |
552 | function appendChild(childElement) {
553 | LDOMCache.functionsUsed[arguments.callee.name] = true;
554 | this.each(function() {
555 | var callingNode = this._node;
556 | childElement.each(function() {
557 | callingNode.appendChild(this._node.cloneNode(true));
558 | });
559 | });
560 | return this;
561 | }
562 |
563 | function prependChild(childElement) {
564 | LDOMCache.functionsUsed[arguments.callee.name] = true;
565 | this.each(function() {
566 | var callingNode = this._node;
567 | childElement.each(function() {
568 | callingNode.insertBefore(this._node.cloneNode(true), callingNode.firstChild);
569 | }, true);
570 | });
571 | return this;
572 | }
573 |
574 | function remove() {
575 | LDOMCache.functionsUsed[arguments.callee.name] = true;
576 | this.each(function() {
577 | if (isDefined(this.off)) {
578 | this.off();
579 | }
580 | this._node.parentNode.removeChild(this._node);
581 | });
582 | }
583 |
584 | // Internal Helper Functions
585 |
586 | function setPropertyAndRemoveDetachedNodes(ldomObject, property, value) {
587 | ldomObject.each(function() {
588 | this.inPage = document.body.contains(this._node);
589 | });
590 | ldomObject.each(function() {
591 | this._node[property] = value;
592 | });
593 | var output = [];
594 | ldomObject.each(function() {
595 | if (!this.inPage || document.body.contains(this._node)) {
596 | output.push(this);
597 | }
598 | delete this.inPage;
599 | });
600 | return $(output);
601 | }
602 |
603 | function getElementsArray(obj) {
604 | if (obj._elements) {
605 | return obj._elements;
606 | } else {
607 | return [obj];
608 | }
609 | }
610 |
611 | function isDefined(obj) {
612 | if (typeof obj === "undefined") {
613 | return false;
614 | }
615 | return true;
616 | }
617 | })();
618 |
--------------------------------------------------------------------------------
/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CreativeTechGuy/LDOM/8cddc30e94a7b6a01b1fcd39aa4c0ae5b43e25dc/mstile-150x150.png
--------------------------------------------------------------------------------
/resources/FileSaver.js:
--------------------------------------------------------------------------------
1 | /* FileSaver.js
2 | * A saveAs() FileSaver implementation.
3 | * 1.3.8
4 | * 2018-03-22 14:03:47
5 | *
6 | * By Eli Grey, https://eligrey.com
7 | * License: MIT
8 | * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
9 | */
10 |
11 | /*global self */
12 | /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
13 |
14 | /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/src/FileSaver.js */
15 |
16 | var saveAs = saveAs || (function(view) {
17 | "use strict";
18 | // IE <10 is explicitly unsupported
19 | if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
20 | return;
21 | }
22 | var
23 | doc = view.document
24 | // only get URL when necessary in case Blob.js hasn't overridden it yet
25 | , get_URL = function() {
26 | return view.URL || view.webkitURL || view;
27 | }
28 | , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
29 | , can_use_save_link = "download" in save_link
30 | , click = function(node) {
31 | var event = new MouseEvent("click");
32 | node.dispatchEvent(event);
33 | }
34 | , is_safari = /constructor/i.test(view.HTMLElement) || view.safari
35 | , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
36 | , setImmediate = view.setImmediate || view.setTimeout
37 | , throw_outside = function(ex) {
38 | setImmediate(function() {
39 | throw ex;
40 | }, 0);
41 | }
42 | , force_saveable_type = "application/octet-stream"
43 | // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
44 | , arbitrary_revoke_timeout = 1000 * 40 // in ms
45 | , revoke = function(file) {
46 | var revoker = function() {
47 | if (typeof file === "string") { // file is an object URL
48 | get_URL().revokeObjectURL(file);
49 | } else { // file is a File
50 | file.remove();
51 | }
52 | };
53 | setTimeout(revoker, arbitrary_revoke_timeout);
54 | }
55 | , dispatch = function(filesaver, event_types, event) {
56 | event_types = [].concat(event_types);
57 | var i = event_types.length;
58 | while (i--) {
59 | var listener = filesaver["on" + event_types[i]];
60 | if (typeof listener === "function") {
61 | try {
62 | listener.call(filesaver, event || filesaver);
63 | } catch (ex) {
64 | throw_outside(ex);
65 | }
66 | }
67 | }
68 | }
69 | , auto_bom = function(blob) {
70 | // prepend BOM for UTF-8 XML and text/* types (including HTML)
71 | // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
72 | if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
73 | return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
74 | }
75 | return blob;
76 | }
77 | , FileSaver = function(blob, name, no_auto_bom) {
78 | if (!no_auto_bom) {
79 | blob = auto_bom(blob);
80 | }
81 | // First try a.download, then web filesystem, then object URLs
82 | var
83 | filesaver = this
84 | , type = blob.type
85 | , force = type === force_saveable_type
86 | , object_url
87 | , dispatch_all = function() {
88 | dispatch(filesaver, "writestart progress write writeend".split(" "));
89 | }
90 | // on any filesys errors revert to saving with object URLs
91 | , fs_error = function() {
92 | if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
93 | // Safari doesn't allow downloading of blob urls
94 | var reader = new FileReader();
95 | reader.onloadend = function() {
96 | var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
97 | var popup = view.open(url, '_blank');
98 | if(!popup) view.location.href = url;
99 | url=undefined; // release reference before dispatching
100 | filesaver.readyState = filesaver.DONE;
101 | dispatch_all();
102 | };
103 | reader.readAsDataURL(blob);
104 | filesaver.readyState = filesaver.INIT;
105 | return;
106 | }
107 | // don't create more object URLs than needed
108 | if (!object_url) {
109 | object_url = get_URL().createObjectURL(blob);
110 | }
111 | if (force) {
112 | view.location.href = object_url;
113 | } else {
114 | var opened = view.open(object_url, "_blank");
115 | if (!opened) {
116 | // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
117 | view.location.href = object_url;
118 | }
119 | }
120 | filesaver.readyState = filesaver.DONE;
121 | dispatch_all();
122 | revoke(object_url);
123 | }
124 | ;
125 | filesaver.readyState = filesaver.INIT;
126 |
127 | if (can_use_save_link) {
128 | object_url = get_URL().createObjectURL(blob);
129 | setImmediate(function() {
130 | save_link.href = object_url;
131 | save_link.download = name;
132 | click(save_link);
133 | dispatch_all();
134 | revoke(object_url);
135 | filesaver.readyState = filesaver.DONE;
136 | }, 0);
137 | return;
138 | }
139 |
140 | fs_error();
141 | }
142 | , FS_proto = FileSaver.prototype
143 | , saveAs = function(blob, name, no_auto_bom) {
144 | return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
145 | }
146 | ;
147 |
148 | // IE 10+ (native saveAs)
149 | if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
150 | return function(blob, name, no_auto_bom) {
151 | name = name || blob.name || "download";
152 |
153 | if (!no_auto_bom) {
154 | blob = auto_bom(blob);
155 | }
156 | return navigator.msSaveOrOpenBlob(blob, name);
157 | };
158 | }
159 |
160 | // todo: detect chrome extensions & packaged apps
161 | //save_link.target = "_blank";
162 |
163 | FS_proto.abort = function(){};
164 | FS_proto.readyState = FS_proto.INIT = 0;
165 | FS_proto.WRITING = 1;
166 | FS_proto.DONE = 2;
167 |
168 | FS_proto.error =
169 | FS_proto.onwritestart =
170 | FS_proto.onprogress =
171 | FS_proto.onwrite =
172 | FS_proto.onabort =
173 | FS_proto.onerror =
174 | FS_proto.onwriteend =
175 | null;
176 |
177 | return saveAs;
178 | }(
179 | typeof self !== "undefined" && self
180 | || typeof window !== "undefined" && window
181 | || this
182 | ));
--------------------------------------------------------------------------------
/resources/blob.js:
--------------------------------------------------------------------------------
1 | /* Blob.js
2 | * A Blob, File, FileReader & URL implementation.
3 | * 2018-08-09
4 | *
5 | * By Eli Grey, http://eligrey.com
6 | * By Jimmy Wärting, https://github.com/jimmywarting
7 | * License: MIT
8 | * See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
9 | */
10 |
11 | ;(function(){
12 |
13 | var global = typeof window === 'object'
14 | ? window : typeof self === 'object'
15 | ? self : this
16 |
17 | var BlobBuilder = global.BlobBuilder
18 | || global.WebKitBlobBuilder
19 | || global.MSBlobBuilder
20 | || global.MozBlobBuilder;
21 |
22 | global.URL = global.URL || global.webkitURL || function(href, a) {
23 | a = document.createElement('a')
24 | a.href = href
25 | return a
26 | }
27 |
28 | var origBlob = global.Blob
29 | var createObjectURL = URL.createObjectURL
30 | var revokeObjectURL = URL.revokeObjectURL
31 | var strTag = global.Symbol && global.Symbol.toStringTag
32 | var blobSupported = false
33 | var blobSupportsArrayBufferView = false
34 | var arrayBufferSupported = !!global.ArrayBuffer
35 | var blobBuilderSupported = BlobBuilder
36 | && BlobBuilder.prototype.append
37 | && BlobBuilder.prototype.getBlob;
38 |
39 | try {
40 | // Check if Blob constructor is supported
41 | blobSupported = new Blob(['ä']).size === 2
42 |
43 | // Check if Blob constructor supports ArrayBufferViews
44 | // Fails in Safari 6, so we need to map to ArrayBuffers there.
45 | blobSupportsArrayBufferView = new Blob([new Uint8Array([1,2])]).size === 2
46 | } catch(e) {}
47 |
48 | /**
49 | * Helper function that maps ArrayBufferViews to ArrayBuffers
50 | * Used by BlobBuilder constructor and old browsers that didn't
51 | * support it in the Blob constructor.
52 | */
53 | function mapArrayBufferViews(ary) {
54 | return ary.map(function(chunk) {
55 | if (chunk.buffer instanceof ArrayBuffer) {
56 | var buf = chunk.buffer;
57 |
58 | // if this is a subarray, make a copy so we only
59 | // include the subarray region from the underlying buffer
60 | if (chunk.byteLength !== buf.byteLength) {
61 | var copy = new Uint8Array(chunk.byteLength);
62 | copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));
63 | buf = copy.buffer;
64 | }
65 |
66 | return buf;
67 | }
68 |
69 | return chunk;
70 | });
71 | }
72 |
73 | function BlobBuilderConstructor(ary, options) {
74 | options = options || {};
75 |
76 | var bb = new BlobBuilder();
77 | mapArrayBufferViews(ary).forEach(function(part) {
78 | bb.append(part);
79 | });
80 |
81 | return options.type ? bb.getBlob(options.type) : bb.getBlob();
82 | };
83 |
84 | function BlobConstructor(ary, options) {
85 | return new origBlob(mapArrayBufferViews(ary), options || {});
86 | };
87 |
88 | if (global.Blob) {
89 | BlobBuilderConstructor.prototype = Blob.prototype;
90 | BlobConstructor.prototype = Blob.prototype;
91 | }
92 |
93 | function FakeBlobBuilder() {
94 | function toUTF8Array(str) {
95 | var utf8 = [];
96 | for (var i=0; i < str.length; i++) {
97 | var charcode = str.charCodeAt(i);
98 | if (charcode < 0x80) utf8.push(charcode);
99 | else if (charcode < 0x800) {
100 | utf8.push(0xc0 | (charcode >> 6),
101 | 0x80 | (charcode & 0x3f));
102 | }
103 | else if (charcode < 0xd800 || charcode >= 0xe000) {
104 | utf8.push(0xe0 | (charcode >> 12),
105 | 0x80 | ((charcode>>6) & 0x3f),
106 | 0x80 | (charcode & 0x3f));
107 | }
108 | // surrogate pair
109 | else {
110 | i++;
111 | // UTF-16 encodes 0x10000-0x10FFFF by
112 | // subtracting 0x10000 and splitting the
113 | // 20 bits of 0x0-0xFFFFF into two halves
114 | charcode = 0x10000 + (((charcode & 0x3ff)<<10)
115 | | (str.charCodeAt(i) & 0x3ff));
116 | utf8.push(0xf0 | (charcode >>18),
117 | 0x80 | ((charcode>>12) & 0x3f),
118 | 0x80 | ((charcode>>6) & 0x3f),
119 | 0x80 | (charcode & 0x3f));
120 | }
121 | }
122 | return utf8;
123 | }
124 | function fromUtf8Array(array) {
125 | var out, i, len, c;
126 | var char2, char3;
127 |
128 | out = "";
129 | len = array.length;
130 | i = 0;
131 | while (i < len) {
132 | c = array[i++];
133 | switch (c >> 4)
134 | {
135 | case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
136 | // 0xxxxxxx
137 | out += String.fromCharCode(c);
138 | break;
139 | case 12: case 13:
140 | // 110x xxxx 10xx xxxx
141 | char2 = array[i++];
142 | out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
143 | break;
144 | case 14:
145 | // 1110 xxxx 10xx xxxx 10xx xxxx
146 | char2 = array[i++];
147 | char3 = array[i++];
148 | out += String.fromCharCode(((c & 0x0F) << 12) |
149 | ((char2 & 0x3F) << 6) |
150 | ((char3 & 0x3F) << 0));
151 | break;
152 | }
153 | }
154 | return out;
155 | }
156 | function isDataView(obj) {
157 | return obj && DataView.prototype.isPrototypeOf(obj)
158 | }
159 | function bufferClone(buf) {
160 | var view = new Array(buf.byteLength)
161 | var array = new Uint8Array(buf)
162 | var i = view.length
163 | while(i--) {
164 | view[i] = array[i]
165 | }
166 | return view
167 | }
168 | function encodeByteArray(input) {
169 | var byteToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
170 |
171 | var output = [];
172 |
173 | for (var i = 0; i < input.length; i += 3) {
174 | var byte1 = input[i];
175 | var haveByte2 = i + 1 < input.length;
176 | var byte2 = haveByte2 ? input[i + 1] : 0;
177 | var haveByte3 = i + 2 < input.length;
178 | var byte3 = haveByte3 ? input[i + 2] : 0;
179 |
180 | var outByte1 = byte1 >> 2;
181 | var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
182 | var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);
183 | var outByte4 = byte3 & 0x3F;
184 |
185 | if (!haveByte3) {
186 | outByte4 = 64;
187 |
188 | if (!haveByte2) {
189 | outByte3 = 64;
190 | }
191 | }
192 |
193 | output.push(
194 | byteToCharMap[outByte1], byteToCharMap[outByte2],
195 | byteToCharMap[outByte3], byteToCharMap[outByte4])
196 | }
197 |
198 | return output.join('')
199 | }
200 |
201 | var create = Object.create || function (a) {
202 | function c() {}
203 | c.prototype = a;
204 | return new c
205 | }
206 |
207 | if (arrayBufferSupported) {
208 | var viewClasses = [
209 | '[object Int8Array]',
210 | '[object Uint8Array]',
211 | '[object Uint8ClampedArray]',
212 | '[object Int16Array]',
213 | '[object Uint16Array]',
214 | '[object Int32Array]',
215 | '[object Uint32Array]',
216 | '[object Float32Array]',
217 | '[object Float64Array]'
218 | ]
219 |
220 | var isArrayBufferView = ArrayBuffer.isView || function(obj) {
221 | return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
222 | }
223 | }
224 |
225 |
226 |
227 | /********************************************************/
228 | /* Blob constructor */
229 | /********************************************************/
230 | function Blob(chunks, opts) {
231 | chunks = chunks || []
232 | for (var i = 0, len = chunks.length; i < len; i++) {
233 | var chunk = chunks[i]
234 | if (chunk instanceof Blob) {
235 | chunks[i] = chunk._buffer
236 | } else if (typeof chunk === 'string') {
237 | chunks[i] = toUTF8Array(chunk)
238 | } else if (arrayBufferSupported && (ArrayBuffer.prototype.isPrototypeOf(chunk) || isArrayBufferView(chunk))) {
239 | chunks[i] = bufferClone(chunk)
240 | } else if (arrayBufferSupported && isDataView(chunk)) {
241 | chunks[i] = bufferClone(chunk.buffer)
242 | } else {
243 | chunks[i] = toUTF8Array(String(chunk))
244 | }
245 | }
246 |
247 | this._buffer = [].concat.apply([], chunks)
248 | this.size = this._buffer.length
249 | this.type = opts ? opts.type || '' : ''
250 | }
251 |
252 | Blob.prototype.slice = function(start, end, type) {
253 | var slice = this._buffer.slice(start || 0, end || this._buffer.length)
254 | return new Blob([slice], {type: type})
255 | }
256 |
257 | Blob.prototype.toString = function() {
258 | return '[object Blob]'
259 | }
260 |
261 |
262 |
263 | /********************************************************/
264 | /* File constructor */
265 | /********************************************************/
266 | function File(chunks, name, opts) {
267 | opts = opts || {}
268 | var a = Blob.call(this, chunks, opts) || this
269 | a.name = name
270 | a.lastModifiedDate = opts.lastModified ? new Date(opts.lastModified) : new Date
271 | a.lastModified = +a.lastModifiedDate
272 |
273 | return a
274 | }
275 |
276 | File.prototype = create(Blob.prototype);
277 | File.prototype.constructor = File;
278 |
279 | if (Object.setPrototypeOf)
280 | Object.setPrototypeOf(File, Blob);
281 | else {
282 | try {File.__proto__ = Blob} catch (e) {}
283 | }
284 |
285 | File.prototype.toString = function() {
286 | return '[object File]'
287 | }
288 |
289 |
290 | /********************************************************/
291 | /* FileReader constructor */
292 | /********************************************************/
293 | function FileReader() {
294 | if (!(this instanceof FileReader))
295 | throw new TypeError("Failed to construct 'FileReader': Please use the 'new' operator, this DOM object constructor cannot be called as a function.")
296 |
297 | var delegate = document.createDocumentFragment()
298 | this.addEventListener = delegate.addEventListener
299 | this.dispatchEvent = function(evt) {
300 | var local = this['on' + evt.type]
301 | if (typeof local === 'function') local(evt)
302 | delegate.dispatchEvent(evt)
303 | }
304 | this.removeEventListener = delegate.removeEventListener
305 | }
306 |
307 | function _read(fr, blob, kind) {
308 | if (!(blob instanceof Blob))
309 | throw new TypeError("Failed to execute '" + kind + "' on 'FileReader': parameter 1 is not of type 'Blob'.")
310 |
311 | fr.result = ''
312 |
313 | setTimeout(function(){
314 | this.readyState = FileReader.LOADING
315 | fr.dispatchEvent(new Event('load'))
316 | fr.dispatchEvent(new Event('loadend'))
317 | })
318 | }
319 |
320 | FileReader.EMPTY = 0
321 | FileReader.LOADING = 1
322 | FileReader.DONE = 2
323 | FileReader.prototype.error = null
324 | FileReader.prototype.onabort = null
325 | FileReader.prototype.onerror = null
326 | FileReader.prototype.onload = null
327 | FileReader.prototype.onloadend = null
328 | FileReader.prototype.onloadstart = null
329 | FileReader.prototype.onprogress = null
330 |
331 | FileReader.prototype.readAsDataURL = function(blob) {
332 | _read(this, blob, 'readAsDataURL')
333 | this.result = 'data:' + blob.type + ';base64,' + encodeByteArray(blob._buffer)
334 | }
335 |
336 | FileReader.prototype.readAsText = function(blob) {
337 | _read(this, blob, 'readAsText')
338 | this.result = fromUtf8Array(blob._buffer)
339 | }
340 |
341 | FileReader.prototype.readAsArrayBuffer = function(blob) {
342 | _read(this, blob, 'readAsText')
343 | this.result = blob._buffer.slice()
344 | }
345 |
346 | FileReader.prototype.abort = function() {}
347 |
348 |
349 | /********************************************************/
350 | /* URL */
351 | /********************************************************/
352 | URL.createObjectURL = function(blob) {
353 | return blob instanceof Blob
354 | ? 'data:' + blob.type + ';base64,' + encodeByteArray(blob._buffer)
355 | : createObjectURL.call(URL, blob)
356 | }
357 |
358 | URL.revokeObjectURL = function(url) {
359 | revokeObjectURL && revokeObjectURL.call(URL, url)
360 | }
361 |
362 | /********************************************************/
363 | /* XHR */
364 | /********************************************************/
365 | var _send = global.XMLHttpRequest && global.XMLHttpRequest.prototype.send
366 | if (_send) {
367 | XMLHttpRequest.prototype.send = function(data) {
368 | if (data instanceof Blob) {
369 | this.setRequestHeader('Content-Type', data.type)
370 | _send.call(this, fromUtf8Array(data._buffer))
371 | } else {
372 | _send.call(this, data)
373 | }
374 | }
375 | }
376 |
377 | global.FileReader = FileReader
378 | global.File = File
379 | global.Blob = Blob
380 | }
381 |
382 | if (strTag) {
383 | File.prototype[strTag] = 'File'
384 | Blob.prototype[strTag] = 'Blob'
385 | FileReader.prototype[strTag] = 'FileReader'
386 | }
387 |
388 | function fixFileAndXHR() {
389 | var isIE = !!global.ActiveXObject || (
390 | '-ms-scroll-limit' in document.documentElement.style &&
391 | '-ms-ime-align' in document.documentElement.style
392 | )
393 |
394 | // Monkey patched
395 | // IE don't set Content-Type header on XHR whose body is a typed Blob
396 | // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6047383
397 | var _send = global.XMLHttpRequest && global.XMLHttpRequest.prototype.send
398 | if (isIE && _send) {
399 | XMLHttpRequest.prototype.send = function(data) {
400 | if (data instanceof Blob) {
401 | this.setRequestHeader('Content-Type', data.type)
402 | _send.call(this, data)
403 | } else {
404 | _send.call(this, data)
405 | }
406 | }
407 | }
408 |
409 | try {
410 | new File([], '')
411 | } catch(e) {
412 | try {
413 | var klass = new Function('class File extends Blob {' +
414 | 'constructor(chunks, name, opts) {' +
415 | 'opts = opts || {};' +
416 | 'super(chunks, opts || {});' +
417 | 'this.name = name;' +
418 | 'this.lastModifiedDate = opts.lastModified ? new Date(opts.lastModified) : new Date;' +
419 | 'this.lastModified = +this.lastModifiedDate;' +
420 | '}};' +
421 | 'return new File([], ""), File'
422 | )()
423 | global.File = klass
424 | } catch(e) {
425 | var klass = function(b, d, c) {
426 | var blob = new Blob(b, c)
427 | var t = c && void 0 !== c.lastModified ? new Date(c.lastModified) : new Date
428 |
429 | blob.name = d
430 | blob.lastModifiedDate = t
431 | blob.lastModified = +t
432 | blob.toString = function() {
433 | return '[object File]'
434 | }
435 |
436 | if (strTag)
437 | blob[strTag] = 'File'
438 |
439 | return blob
440 | }
441 | global.File = klass
442 | }
443 | }
444 | }
445 |
446 | if (blobSupported) {
447 | fixFileAndXHR()
448 | global.Blob = blobSupportsArrayBufferView ? global.Blob : BlobConstructor
449 | } else if (blobBuilderSupported) {
450 | fixFileAndXHR()
451 | global.Blob = BlobBuilderConstructor;
452 | } else {
453 | FakeBlobBuilder()
454 | }
455 |
456 | })();
--------------------------------------------------------------------------------
/resources/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/main.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | body {
6 | font-size: 1.2em;
7 | overflow-y: scroll;
8 | margin: 0;
9 | }
10 |
11 | button {
12 | font-family: "Times New Roman", Times, serif;
13 | }
14 |
15 | h1,
16 | h2,
17 | h3,
18 | h4,
19 | h5,
20 | h6 {
21 | text-align: center;
22 | }
23 |
24 | a {
25 | color: #0000ee;
26 | }
27 |
28 | .p-like {
29 | display: block;
30 | margin: 1em 0;
31 | }
32 |
33 | nav {
34 | width: 13rem;
35 | height: 100%;
36 | border: 1px solid #000000;
37 | display: block;
38 | position: fixed;
39 | overflow-y: auto;
40 | background: #ffefdc;
41 | padding-bottom: 5vh;
42 | }
43 |
44 | .title-link {
45 | color: #ff8800;
46 | text-decoration: none;
47 | }
48 |
49 | .nav-link {
50 | display: block;
51 | color: #0000ee;
52 | padding: 0.25em 0.75em;
53 | text-decoration: none;
54 | }
55 |
56 | .nav-link:nth-child(2n) {
57 | background: #ffe1be;
58 | }
59 |
60 | .nav-link:hover {
61 | background: #ffc98b;
62 | }
63 |
64 | main {
65 | display: block;
66 | padding: 0.5em 1em;
67 | }
68 |
69 | nav ~ main {
70 | width: calc(100% - 13rem - 1rem);
71 | margin-left: calc(13.5rem);
72 | }
73 |
74 | section {
75 | margin: auto;
76 | margin-bottom: 1.5em;
77 | max-width: 60rem;
78 | padding: 0.5em;
79 | border: 1px solid #000000;
80 | }
81 |
82 | .section-title {
83 | margin: 0.5em 0;
84 | }
85 |
86 | .section-title > a {
87 | color: #000000;
88 | text-decoration: none;
89 | }
90 |
91 | .section-title > a::after,
92 | .section-title > a::before {
93 | content: "¶";
94 | padding: 0.5em;
95 | vertical-align: text-top;
96 | opacity: 0;
97 | }
98 |
99 | .section-title > a:hover::after {
100 | opacity: 0.3;
101 | }
102 |
103 | code[class*="language-"] {
104 | font-size: 0.9em;
105 | }
106 |
107 | .large-button {
108 | position: relative;
109 | display: block;
110 | margin: 0.5em auto;
111 | padding: 0.5em 1em;
112 | font-size: 1.25em;
113 | background: #f0c18b;
114 | border: 0;
115 | box-shadow: 2px 2px 5px #000000;
116 | cursor: pointer;
117 | -webkit-transition: background 0.25s;
118 | transition: background 0.25s;
119 | text-decoration: none;
120 | width: 10em;
121 | text-align: center;
122 | color: #000000;
123 | }
124 |
125 | .large-button:hover {
126 | background: #ff8800;
127 | }
128 |
129 | .large-button:active {
130 | box-shadow: none;
131 | top: 2px;
132 | left: 2px;
133 | }
134 |
135 | #menu {
136 | display: none;
137 | position: fixed;
138 | height: 1.25em;
139 | width: 1.25em;
140 | margin: 0.7em;
141 | z-index: 998;
142 | cursor: pointer;
143 | }
144 |
145 | #close {
146 | display: none;
147 | position: fixed;
148 | height: 1.25em;
149 | width: 1.25em;
150 | margin: 0.7em;
151 | z-index: 1000;
152 | cursor: pointer;
153 | }
154 |
155 | table {
156 | margin: 0.4em auto;
157 | border: 1px solid #000000;
158 | }
159 |
160 | table,
161 | tbody,
162 | tr,
163 | th,
164 | td {
165 | border: 1px solid #000000;
166 | border-collapse: collapse;
167 | padding: 0.1em 0.4em;
168 | }
169 |
170 | th {
171 | border-bottom: 2px solid #000000;
172 | }
173 |
174 | .menu-viewing-highlight {
175 | -webkit-transition: background 0.5s;
176 | transition: background 0.5s;
177 | border: 1px solid #ff8800;
178 | background: rgba(255, 119, 0, 0.445) !important;
179 | }
180 |
181 | .doc-title {
182 | text-align: start;
183 | margin: 0;
184 | }
185 |
186 | .doc-box {
187 | border-radius: 1em;
188 | border: 1px dashed #000000;
189 | padding: 0.5em;
190 | margin: 0.5em;
191 | }
192 |
193 | dl {
194 | margin: 0;
195 | }
196 |
197 | dt {
198 | font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
199 | background: #d6d6d6;
200 | display: inline-block;
201 | }
202 |
203 | main > footer {
204 | text-align: center;
205 | margin-bottom: 5em;
206 | }
207 |
208 | nav > footer {
209 | display: none;
210 | text-align: center;
211 | margin: 1em 0;
212 | }
213 |
214 | @media screen and (max-width: 600px) {
215 | nav ~ main {
216 | width: 100%;
217 | margin-left: 0;
218 | }
219 |
220 | .large-button {
221 | font-size: 1em;
222 | }
223 |
224 | nav {
225 | display: none;
226 | width: 100%;
227 | z-index: 999;
228 | }
229 |
230 | #menu {
231 | display: block;
232 | }
233 |
234 | #close {
235 | display: block;
236 | }
237 |
238 | .nav-link {
239 | text-align: center;
240 | }
241 |
242 | .nav-title::before {
243 | content: "LDOM ";
244 | }
245 |
246 | .section-title > a::before {
247 | content: "";
248 | }
249 |
250 | .section-title > a::after {
251 | opacity: 0.3;
252 | }
253 |
254 | nav > footer {
255 | display: block;
256 | }
257 |
258 | section {
259 | padding: 0.15em;
260 | }
261 |
262 | .doc-box {
263 | padding: 0.5em;
264 | margin: 0.15em;
265 | }
266 | }
267 |
--------------------------------------------------------------------------------
/resources/menu.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/prism/prism.css:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.15.0
2 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
3 | /**
4 | * prism.js default theme for JavaScript, CSS and HTML
5 | * Based on dabblet (http://dabblet.com)
6 | * @author Lea Verou
7 | */
8 |
9 | code[class*="language-"],
10 | pre[class*="language-"] {
11 | color: black;
12 | background: none;
13 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
14 | text-align: left;
15 | white-space: pre;
16 | word-spacing: normal;
17 | word-break: normal;
18 | word-wrap: normal;
19 | line-height: 1.5;
20 |
21 | -moz-tab-size: 4;
22 | -o-tab-size: 4;
23 | tab-size: 4;
24 |
25 | -webkit-hyphens: none;
26 | -moz-hyphens: none;
27 | -ms-hyphens: none;
28 | hyphens: none;
29 | }
30 |
31 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
32 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
33 | text-shadow: none;
34 | background: #b3d4fc;
35 | }
36 |
37 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
38 | code[class*="language-"]::selection, code[class*="language-"] ::selection {
39 | text-shadow: none;
40 | background: #b3d4fc;
41 | }
42 |
43 | @media print {
44 | code[class*="language-"],
45 | pre[class*="language-"] {
46 | text-shadow: none;
47 | }
48 | }
49 |
50 | /* Code blocks */
51 | pre[class*="language-"] {
52 | padding: 1em;
53 | margin: .5em 0;
54 | overflow: auto;
55 | }
56 |
57 | :not(pre) > code[class*="language-"],
58 | pre[class*="language-"] {
59 | background: #d6d6d6;
60 | border-radius: .3em;
61 | }
62 |
63 | /* Inline code */
64 | :not(pre) > code[class*="language-"] {
65 | padding: .1em;
66 | white-space: normal;
67 | }
68 |
69 | .token.comment,
70 | .token.prolog,
71 | .token.doctype,
72 | .token.cdata {
73 | color: slategray;
74 | }
75 |
76 | .token.punctuation {
77 | color: #000000;
78 | }
79 |
80 | .namespace {
81 | opacity: .7;
82 | }
83 |
84 | .token.property,
85 | .token.tag,
86 | .token.boolean,
87 | .token.number,
88 | .token.constant,
89 | .token.symbol,
90 | .token.deleted {
91 | color: #905;
92 | }
93 |
94 | .token.selector,
95 | .token.attr-name,
96 | .token.string,
97 | .token.char,
98 | .token.builtin,
99 | .token.inserted {
100 | color: #170099;
101 | }
102 |
103 | .token.operator,
104 | .token.entity,
105 | .token.url,
106 | .language-css .token.string,
107 | .style .token.string {
108 | color: #9a6e3a;
109 | }
110 |
111 | .token.atrule,
112 | .token.attr-value,
113 | .token.keyword {
114 | color: #07a;
115 | }
116 |
117 | .token.function,
118 | .token.class-name {
119 | color: #ff3b0a;
120 | }
121 |
122 | .token.regex,
123 | .token.important,
124 | .token.variable {
125 | color: #e90;
126 | }
127 |
128 | .token.important,
129 | .token.bold {
130 | font-weight: bold;
131 | }
132 | .token.italic {
133 | font-style: italic;
134 | }
135 |
136 | .token.entity {
137 | cursor: help;
138 | }
139 |
140 |
--------------------------------------------------------------------------------
/resources/prism/prism.js:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.15.0
2 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
3 | var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-([\w-]+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,disableWorkerMessageHandler:_self.Prism&&_self.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof r?new r(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(w instanceof s)){if(m&&b!=t.length-1){h.lastIndex=k;var _=h.exec(e);if(!_)break;for(var j=_.index+(d?_[1].length:0),P=_.index+_[0].length,A=b,x=k,O=t.length;O>A&&(P>x||!t[A].type&&!t[A-1].greedy);++A)x+=t[A].length,j>=x&&(++b,k=x);if(t[b]instanceof s)continue;I=A-b,w=e.slice(k,x),_.index-=k}else{h.lastIndex=0;var _=h.exec(w),I=1}if(_){d&&(p=_[1]?_[1].length:0);var j=_.index+p,_=_[0].slice(p),P=j+_.length,N=w.slice(0,j),S=w.slice(P),C=[b,I];N&&(++b,k+=N.length,C.push(N));var E=new s(u,f?n.tokenize(_,f):_,y,_,m);if(C.push(E),S&&C.push(S),Array.prototype.splice.apply(t,C),1!=I&&n.matchGrammar(e,t,r,b,k,!0,u),i)break}else if(i)break}}}}},tokenize:function(e,t){var r=[e],a=t.rest;if(a){for(var l in a)t[l]=a[l];delete t.rest}return n.matchGrammar(e,r,t,0,0,!1),r},hooks:{all:{},add:function(e,t){var r=n.hooks.all;r[e]=r[e]||[],r[e].push(t)},run:function(e,t){var r=n.hooks.all[e];if(r&&r.length)for(var a,l=0;a=r[l++];)a(t)}}},r=n.Token=function(e,t,n,r,a){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length,this.greedy=!!a};if(r.stringify=function(e,t,a){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return r.stringify(n,t,e)}).join("");var l={type:e.type,content:r.stringify(e.content,t,a),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:a};if(e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o=Object.keys(l.attributes).map(function(e){return e+'="'+(l.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+l.tag+' class="'+l.classes.join(" ")+'"'+(o?" "+o:"")+">"+l.content+""+l.tag+">"},!_self.document)return _self.addEventListener?(n.disableWorkerMessageHandler||_self.addEventListener("message",function(e){var t=JSON.parse(e.data),r=t.language,a=t.code,l=t.immediateClose;_self.postMessage(n.highlight(a,n.languages[r],r)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return a&&(n.filename=a.src,n.manual||a.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
4 | Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
5 | Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.languages.css,Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/(
49 |
50 |
51 | LDOM Tests
52 |
53 |
Aggregate Tests Results:
54 |
55 | - / -
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
aBc
64 |
65 |
Some text
66 |
67 |
68 |
69 | Head 1
70 | Item 0
71 |
72 |
73 | Row 1
74 | Item 1
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |