PluginProbe
Taboola / 1.0.15
Taboola v1.0.15
1.0.4 1.0.5 1.0.6 1.0.8 2.0.1 2.0.2 2.1.0 2.1.1 2.2.2 2.2.3 3.0.0 3.0.1 3.0.2 3.1.0 trunk 1.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.2 1.0.3
← All changes | js/js_inject.js +65 -87 2.2.31.0.15 View file →
@@ -1,102 +1,80 @@
1 -/* ────────────────────────────────────────────────────────────────────────────
2 - Utility helpers
3 - ────────────────────────────────────────────────────────────────────────── */
1 +function insertAfter(newNode, referenceNode) {
2 + referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
3 +}
4 +function getElementByXPath(xPath, doc){
5 + if(!doc) doc = document;
6 + if(doc.evaluate) return doc.evaluate(xPath, document, null, 9, null).singleNodeValue;
7 + // for IE
8 + while(xPath.charAt(0) == '/') xPath = xPath.substr(1);
9 + var prevElem = doc;
10 + var arr = xPath.split('/');
11 + for(var i=0; i<arr.length; i++){
12 + var step = arr[i].split(/(\w*)\[(\d*)\]/gi).filter(function(v){ return !(v==''||v.match(/\s/gi)) },this);
13 + var elem = step[0];
14 + var elemNum = step[1]?step[1]-1:0; // -1 since xpath is 1 based
15 + if(i<arr.length-1) prevElem = prevElem.getElementsByTagName(elem)[elemNum];
16 + else return prevElem.getElementsByTagName(elem)[elemNum];
17 + }
18 +}
4 19
5 -(function () {
6 - 'use strict';
7 20
8 - /* ---------- insertAfter ------------------------------------------------ */
9 - /* Fast path for “append” avoids creating a reference to nextSibling. */
10 - function insertAfter(newNode, referenceNode) {
11 - const parent = referenceNode.parentNode;
12 - if (parent.lastChild === referenceNode) {
13 - parent.appendChild(newNode);
14 - } else {
15 - parent.insertBefore(newNode, referenceNode.nextSibling);
16 - }
17 - }
21 +/**
22 + * Copyright (c) Mozilla Foundation http://www.mozilla.org/
23 + * This code is available under the terms of the MIT License
24 + */
25 +if (!Array.prototype.filter) {
26 + Array.prototype.filter = function(fun /*, thisp*/) {
27 + var len = this.length >>> 0;
28 + if (typeof fun != "function") {
29 + throw new TypeError();
30 + }
18 31
19 - /* ---------- getElementByXPath ----------------------------------------- */
20 - /* 1) Use native evaluate where available (all evergreen browsers). */
21 - /* 2) Small, allocation-free fallback for very old IE engines. */
22 - function getElementByXPath(xPath, doc = document) {
23 - if (doc.evaluate) {
24 - // XPathResult.FIRST_ORDERED_NODE_TYPE = 9
25 - return doc.evaluate(
26 - xPath,
27 - doc,
28 - null,
29 - 9,
30 - null
31 - ).singleNodeValue;
32 - }
32 + var res = [];
33 + var thisp = arguments[1];
34 + for (var i = 0; i < len; i++) {
35 + if (i in this) {
36 + var val = this[i]; // in case fun mutates this
37 + if (fun.call(thisp, val, i, this)) {
38 + res.push(val);
39 + }
40 + }
41 + }
33 42
34 - // Fallback (legacy IE) – minimal parsing, no .filter / regex loops
35 - xPath = xPath.replace(/^\/+/, ''); // strip leading “/”
36 - const steps = xPath.split('/');
37 - let current = doc;
43 + return res;
44 + };
45 +}
46 +/* END MIT License code */
38 47
39 - for (let i = 0, l = steps.length; i < l && current; i += 1) {
40 - const match = /([^\[\]]+)(?:\[(\d+)\])?/.exec(steps[i]);
41 - if (!match) return null;
42 - const [, tag, idx] = match;
43 - const pos = idx ? (idx - 1) : 0; // XPath indices are 1-based
44 - current = current.getElementsByTagName(tag)[pos] || null;
48 +function injectWidgetByXpath(xpath){
49 +
50 + var n = getElementByXPath(xpath);
51 +
52 + // Default placement in case the xpath location is not found
53 + if (n==null){
54 + n = document.getElementById("tbdefault");
45 55 }
46 - return current;
47 - }
56 + innerInject(n);
57 +}
48 58
49 - /* ---------- Array.prototype.filter polyfill (unchanged API) ------------ */
50 - /* MIT – kept for <= IE8; tightened slightly for speed/readability. */
51 - /* eslint-disable-next-line no-extend-native */
52 - if (!Array.prototype.filter) {
53 - Array.prototype.filter = function (callback, thisArg) {
54 - if (typeof callback !== 'function') throw new TypeError();
55 - const out = [];
56 - for (let i = 0, l = this.length >>> 0; i < l; i += 1) {
57 - if (i in this) {
58 - const val = this[i];
59 - if (callback.call(thisArg, val, i, this)) out.push(val);
60 - }
61 - }
62 - return out;
63 - };
64 - }
59 +function injectWidgetByMarker(markerId){
60 + var markerNode = document.getElementById(markerId);
61 + innerInject(markerNode.parentNode);
62 +}
65 63
66 - /* ---------- Injection helpers ----------------------------------------- */
64 +function innerInject(node){
67 65
68 - function injectWidgetByXpath(xpath) {
69 - const anchor =
70 - getElementByXPath(xpath) || document.getElementById('tbdefault');
71 - if (anchor) innerInject(anchor);
72 - }
66 + var c = document.createElement("span");
67 + var s = document.createElement("script");
73 68
74 - function injectWidgetByMarker(markerId) {
75 - const markerNode = document.getElementById(markerId);
76 - if (markerNode && markerNode.parentNode) innerInject(markerNode.parentNode);
77 - }
69 + // Notice that minifier will replce single quotes to double quotes. here it must remain with single quotes
70 + var noticeForDeveloper = "if JS crashes here, the first innerHTML value should be enclosed with single quotes instead of double, go to the minified version and change it";
71 + c.innerHTML = '{{HTML}}';
72 + s.innerHTML = "{{SCRIPT}}";
78 73
79 - /* One reflow: build everything in a fragment, then insert once. */
80 - function innerInject(node) {
81 - if (!node) return;
74 + insertAfter(c,node);
75 + insertAfter(s,c);
76 +}
82 77
83 - const fragment = document.createDocumentFragment();
84 - const container = document.createElement('span');
85 - const script = document.createElement('script');
86 78
87 - /* Keep single quotes – some minifiers mangle this otherwise. */
88 - container.insertAdjacentHTML('beforeend', '{{HTML}}');
89 - script.text = "{{SCRIPT}}";
90 79
91 - fragment.appendChild(container);
92 - fragment.appendChild(script);
93 - insertAfter(fragment, node);
94 - }
95 80
96 - /* ---------- Export to global scope (names unchanged) ------------------- */
97 - window.insertAfter = insertAfter;
98 - window.getElementByXPath = getElementByXPath;
99 - window.injectWidgetByXpath = injectWidgetByXpath;
100 - window.injectWidgetByMarker = injectWidgetByMarker;
101 - window.innerInject = innerInject;
102 -}());