PluginProbe
Taboola / 2.2.3
Taboola v2.2.3
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 +87 -65 1.0.132.2.3 View file →
@@ -1,80 +1,102 @@
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 -}
1 +/* ────────────────────────────────────────────────────────────────────────────
2 + Utility helpers
3 + ────────────────────────────────────────────────────────────────────────── */
19 4
5 +(function () {
6 + 'use strict';
20 7
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 - }
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 + }
31 18
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 - }
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 + }
42 33
43 - return res;
44 - };
45 -}
46 -/* END MIT License code */
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;
47 38
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");
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;
55 45 }
56 - innerInject(n);
57 -}
46 + return current;
47 + }
58 48
59 -function injectWidgetByMarker(markerId){
60 - var markerNode = document.getElementById(markerId);
61 - innerInject(markerNode.parentNode);
62 -}
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 + }
63 65
64 -function innerInject(node){
66 + /* ---------- Injection helpers ----------------------------------------- */
65 67
66 - var c = document.createElement("span");
67 - var s = document.createElement("script");
68 + function injectWidgetByXpath(xpath) {
69 + const anchor =
70 + getElementByXPath(xpath) || document.getElementById('tbdefault');
71 + if (anchor) innerInject(anchor);
72 + }
68 73
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}}";
74 + function injectWidgetByMarker(markerId) {
75 + const markerNode = document.getElementById(markerId);
76 + if (markerNode && markerNode.parentNode) innerInject(markerNode.parentNode);
77 + }
73 78
74 - insertAfter(c,node);
75 - insertAfter(s,c);
76 -}
79 + /* One reflow: build everything in a fragment, then insert once. */
80 + function innerInject(node) {
81 + if (!node) return;
77 82
83 + const fragment = document.createDocumentFragment();
84 + const container = document.createElement('span');
85 + const script = document.createElement('script');
78 86
87 + /* Keep single quotes – some minifiers mangle this otherwise. */
88 + container.insertAdjacentHTML('beforeend', '{{HTML}}');
89 + script.text = "{{SCRIPT}}";
79 90
91 + fragment.appendChild(container);
92 + fragment.appendChild(script);
93 + insertAfter(fragment, node);
94 + }
80 95
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 +}());