@guardian/ophan-tracker-js 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/adblock-detection.js +24 -0
- package/build/attention.js +149 -0
- package/build/campaign.js +30 -0
- package/build/click-path-capture.js +81 -0
- package/build/components.js +167 -0
- package/build/contribution.js +25 -0
- package/build/core.js +234 -0
- package/build/embed.js +11 -0
- package/build/fb-instant.js +10 -0
- package/build/heatmap.js +32 -0
- package/build/holidays.js +11 -0
- package/build/http-status.js +20 -0
- package/build/iframe-tracking.js +68 -0
- package/build/interactive.js +25 -0
- package/build/jobs-courses.js +11 -0
- package/build/jobs.js +11 -0
- package/build/manage-my-account.js +47 -0
- package/build/membership.js +25 -0
- package/build/ng.js +33 -0
- package/build/perf.js +39 -0
- package/build/privatebrowsing.js +71 -0
- package/build/r2.js +24 -0
- package/build/smart-news.js +19 -0
- package/build/support.js +41 -0
- package/build/transmit.js +107 -0
- package/build/vendor/adBlockDetectionLib.js +367 -0
- package/build/visibility.js +7 -0
- package/build/witness.js +11 -0
- package/package.json +26 -0
- package/readme.md +95 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
import core from './core.js';
|
|
3
|
+
|
|
4
|
+
import transmit from './transmit.js';
|
|
5
|
+
|
|
6
|
+
import attention from './attention.js';
|
|
7
|
+
|
|
8
|
+
import visibility from './visibility.js';
|
|
9
|
+
|
|
10
|
+
core.init("smart-news");
|
|
11
|
+
|
|
12
|
+
if (window.addEventListener != null) {
|
|
13
|
+
attention.init(visibility);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
record: transmit.sendMore,
|
|
18
|
+
viewId: transmit.viewId
|
|
19
|
+
};
|
package/build/support.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
var init, sendInitialEvent;
|
|
3
|
+
|
|
4
|
+
import core from "./core.js";
|
|
5
|
+
|
|
6
|
+
import transmit from "./transmit.js";
|
|
7
|
+
|
|
8
|
+
import attention from "./attention.js";
|
|
9
|
+
|
|
10
|
+
import visibility from "./visibility.js";
|
|
11
|
+
|
|
12
|
+
import "./click-path-capture.js";
|
|
13
|
+
|
|
14
|
+
import "./perf.js";
|
|
15
|
+
|
|
16
|
+
import "./campaign.js";
|
|
17
|
+
|
|
18
|
+
init = function() {
|
|
19
|
+
core.init("support");
|
|
20
|
+
if (window.addEventListener != null) {
|
|
21
|
+
return attention.init(visibility);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
sendInitialEvent = function(url = location.href, referrer = window.document.referrer) {
|
|
26
|
+
var e;
|
|
27
|
+
try {
|
|
28
|
+
transmit.bumpViewId();
|
|
29
|
+
return core.sendInitialEvent(null, url, referrer);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
e = error;
|
|
32
|
+
return console.log(e);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default {
|
|
37
|
+
init: init,
|
|
38
|
+
sendInitialEvent: sendInitialEvent,
|
|
39
|
+
record: transmit.sendMore,
|
|
40
|
+
viewId: transmit.viewId
|
|
41
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
var buildQueryString, bumpViewId, generatePageViewId, isDefined, opanRemoteHost, ref, ref1, ref2, send, sendInitial, sendMore, smartEncode, viewId,
|
|
3
|
+
hasProp = {}.hasOwnProperty;
|
|
4
|
+
|
|
5
|
+
opanRemoteHost = (typeof window !== "undefined" && window !== null ? window.opanRemoteHost : void 0) || "//ophan.theguardian.com";
|
|
6
|
+
|
|
7
|
+
generatePageViewId = function() {
|
|
8
|
+
return new Date().getTime().toString(36) + 'xxxxxxxxxxxx'.replace(/x/g, function() {
|
|
9
|
+
return Math.floor(Math.random() * 36).toString(36);
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// guardian.config.ophan.pageViewId is now pregenerated in
|
|
14
|
+
// the Guardian Frontend Project (https://github.com/guardian/frontend)
|
|
15
|
+
// frontend/common/app/templates/inlineJS/blocking/config.scala.js
|
|
16
|
+
// If you're going to change the generation method, please update that one too
|
|
17
|
+
viewId = (ref = typeof guardian !== "undefined" && guardian !== null ? (ref1 = guardian.config) != null ? (ref2 = ref1.ophan) != null ? ref2.pageViewId : void 0 : void 0 : void 0) != null ? ref : generatePageViewId();
|
|
18
|
+
|
|
19
|
+
bumpViewId = function() {
|
|
20
|
+
return viewId = generatePageViewId();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// send the initial event associated with this page view
|
|
24
|
+
// store the resulting page view id
|
|
25
|
+
// this must only ever be called *once* subsequent calls will
|
|
26
|
+
// be ignored
|
|
27
|
+
sendInitial = function(obj) {
|
|
28
|
+
return send(opanRemoteHost + `/img/1?${buildQueryString(obj)}`);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// send more data - if initial hasn't been sent, queue up and wait for the
|
|
32
|
+
// initial send to occur
|
|
33
|
+
smartEncode = function(value) {
|
|
34
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
35
|
+
return encodeURIComponent(value);
|
|
36
|
+
} else {
|
|
37
|
+
return encodeURIComponent(JSON.stringify(value));
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
sendMore = function(obj, f) {
|
|
42
|
+
var prop, value, values;
|
|
43
|
+
if (JSON) {
|
|
44
|
+
values = (function() {
|
|
45
|
+
var results;
|
|
46
|
+
results = [];
|
|
47
|
+
for (prop in obj) {
|
|
48
|
+
if (!hasProp.call(obj, prop)) continue;
|
|
49
|
+
value = obj[prop];
|
|
50
|
+
if (isDefined(value)) {
|
|
51
|
+
results.push(`${encodeURIComponent(prop)}=${smartEncode(value)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return results;
|
|
55
|
+
})();
|
|
56
|
+
if (values.length) {
|
|
57
|
+
return send(opanRemoteHost + `/img/2?viewId=${viewId}&${values.join('&')}`, f);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
isDefined = function(v) {
|
|
63
|
+
if (Array.isArray(v)) {
|
|
64
|
+
return v.length;
|
|
65
|
+
} else {
|
|
66
|
+
return v != null;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
buildQueryString = function(obj) {
|
|
71
|
+
var prop, value, values;
|
|
72
|
+
obj.viewId = viewId;
|
|
73
|
+
values = (function() {
|
|
74
|
+
var results;
|
|
75
|
+
results = [];
|
|
76
|
+
for (prop in obj) {
|
|
77
|
+
if (!hasProp.call(obj, prop)) continue;
|
|
78
|
+
value = obj[prop];
|
|
79
|
+
if (value != null) {
|
|
80
|
+
results.push(`${encodeURIComponent(prop)}=${encodeURIComponent(value)}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return results;
|
|
84
|
+
})();
|
|
85
|
+
return values.join("&");
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
send = function(url, f) {
|
|
89
|
+
var checker, image;
|
|
90
|
+
image = new Image();
|
|
91
|
+
checker = setInterval(function() {
|
|
92
|
+
if (image.complete) {
|
|
93
|
+
if (typeof f === "function") {
|
|
94
|
+
f();
|
|
95
|
+
}
|
|
96
|
+
return clearInterval(checker);
|
|
97
|
+
}
|
|
98
|
+
}, 10);
|
|
99
|
+
return image.src = url;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export default {
|
|
103
|
+
sendInitial: sendInitial,
|
|
104
|
+
sendMore: sendMore,
|
|
105
|
+
viewId: viewId,
|
|
106
|
+
bumpViewId: bumpViewId
|
|
107
|
+
};
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
// TLDR; This is stripped down from the IAB ad block detection library.
|
|
3
|
+
// https://github.com/InteractiveAdvertisingBureau/AdBlockDetection
|
|
4
|
+
// The aforementioned library is not well maintained
|
|
5
|
+
// and had work in progress network adblocking detection
|
|
6
|
+
|
|
7
|
+
var init = function() {
|
|
8
|
+
|
|
9
|
+
var ofs = 'offset', cl = 'client';
|
|
10
|
+
var noop = function(){};
|
|
11
|
+
|
|
12
|
+
var testedOnce = false;
|
|
13
|
+
var testExecuting = false;
|
|
14
|
+
|
|
15
|
+
var isOldIEevents = (window.addEventListener === undefined);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Options set with default options initialized
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
var _options = {
|
|
22
|
+
loopDelay: 50,
|
|
23
|
+
maxLoop: 5,
|
|
24
|
+
debug: false,
|
|
25
|
+
found: noop,
|
|
26
|
+
notfound: noop,
|
|
27
|
+
complete: noop
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var listeners = []; // event response listeners
|
|
31
|
+
var baitNode = null;
|
|
32
|
+
var quickBait = {
|
|
33
|
+
cssClass: 'ad-slot pub_300x250 pub_300x250m pub_728x90 text-ad textAd text_ad text_ads text-ads text-ad-links'
|
|
34
|
+
};
|
|
35
|
+
var baitTriggers = {
|
|
36
|
+
nullProps: [ofs + 'Parent'],
|
|
37
|
+
zeroProps: []
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
baitTriggers.zeroProps = [
|
|
41
|
+
ofs +'Height', ofs +'Left', ofs +'Top', ofs +'Width', ofs +'Height',
|
|
42
|
+
cl + 'Height', cl + 'Width'
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// result object
|
|
46
|
+
var exeResult = {
|
|
47
|
+
quick: null,
|
|
48
|
+
remote: null
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
var findResult = null; // result of test for ad blocker
|
|
52
|
+
|
|
53
|
+
var timerIds = {
|
|
54
|
+
test: 0,
|
|
55
|
+
download: 0
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
function isFunc(fn){
|
|
59
|
+
return typeof(fn) == 'function';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Make a DOM element
|
|
64
|
+
*/
|
|
65
|
+
function makeEl(tag, attributes){
|
|
66
|
+
var k, v, el, attr = attributes;
|
|
67
|
+
var d = document;
|
|
68
|
+
|
|
69
|
+
el = d.createElement(tag);
|
|
70
|
+
|
|
71
|
+
if(attr){
|
|
72
|
+
for(k in attr){
|
|
73
|
+
if(attr.hasOwnProperty(k)){
|
|
74
|
+
el.setAttribute(k, attr[k]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return el;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function attachEventListener(dom, eventName, handler){
|
|
83
|
+
if(isOldIEevents){
|
|
84
|
+
dom.attachEvent('on' + eventName, handler);
|
|
85
|
+
}
|
|
86
|
+
else{
|
|
87
|
+
dom.addEventListener(eventName, handler, false);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function log(message, isError){
|
|
92
|
+
if(!_options.debug && !isError){
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if(window.console && window.console.log){
|
|
96
|
+
if(isError){
|
|
97
|
+
console.error('[ABD] ' + message);
|
|
98
|
+
}
|
|
99
|
+
else{
|
|
100
|
+
console.log('[ABD] ' + message);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
function beginTest(bait){
|
|
107
|
+
log('start beginTest');
|
|
108
|
+
if(findResult == true){
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
testExecuting = true;
|
|
112
|
+
castBait(bait);
|
|
113
|
+
|
|
114
|
+
exeResult.quick = 'testing';
|
|
115
|
+
|
|
116
|
+
timerIds.test = setTimeout(
|
|
117
|
+
function(){ reelIn(bait, 1); },
|
|
118
|
+
5);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Create the bait node to see how the browser page reacts
|
|
123
|
+
*/
|
|
124
|
+
function castBait(bait){
|
|
125
|
+
var i, d = document, b = d.body;
|
|
126
|
+
var t;
|
|
127
|
+
var baitStyle = 'width: 1px !important; height: 1px !important; position: absolute !important; left: -10000px !important; top: -1000px !important;'
|
|
128
|
+
|
|
129
|
+
if(bait == null || typeof(bait) == 'string'){
|
|
130
|
+
log('invalid bait being cast');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if(bait.style != null){
|
|
135
|
+
baitStyle += bait.style;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
baitNode = makeEl('div', {
|
|
139
|
+
'class': bait.cssClass,
|
|
140
|
+
'style': baitStyle
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
log('adding bait node to DOM');
|
|
144
|
+
|
|
145
|
+
b.appendChild(baitNode);
|
|
146
|
+
|
|
147
|
+
// touch these properties
|
|
148
|
+
for(i=0;i<baitTriggers.nullProps.length;i++){
|
|
149
|
+
t = baitNode[baitTriggers.nullProps[i]];
|
|
150
|
+
}
|
|
151
|
+
for(i=0;i<baitTriggers.zeroProps.length;i++){
|
|
152
|
+
t = baitNode[baitTriggers.zeroProps[i]];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Run tests to see if browser has taken the bait and blocked the bait element
|
|
158
|
+
*/
|
|
159
|
+
function reelIn(bait, attemptNum){
|
|
160
|
+
var i, k, v;
|
|
161
|
+
var body = document.body;
|
|
162
|
+
var found = false;
|
|
163
|
+
|
|
164
|
+
if(baitNode == null){
|
|
165
|
+
log('recast bait');
|
|
166
|
+
castBait(bait || quickBait);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if(typeof(bait) == 'string'){
|
|
170
|
+
log('invalid bait used', true);
|
|
171
|
+
if(clearBaitNode()){
|
|
172
|
+
setTimeout(function(){
|
|
173
|
+
testExecuting = false;
|
|
174
|
+
}, 5);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if(timerIds.test > 0){
|
|
181
|
+
clearTimeout(timerIds.test);
|
|
182
|
+
timerIds.test = 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// test for issues
|
|
186
|
+
|
|
187
|
+
if(body.getAttribute('abp') !== null){
|
|
188
|
+
log('found adblock body attribute');
|
|
189
|
+
found = true;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for(i=0;i<baitTriggers.nullProps.length;i++){
|
|
193
|
+
if(baitNode[baitTriggers.nullProps[i]] == null){
|
|
194
|
+
if(attemptNum>4)
|
|
195
|
+
found = true;
|
|
196
|
+
log('found adblock null attr: ' + baitTriggers.nullProps[i]);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
if(found == true){
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
for(i=0;i<baitTriggers.zeroProps.length;i++){
|
|
205
|
+
if(found == true){
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
if(baitNode[baitTriggers.zeroProps[i]] == 0){
|
|
209
|
+
if(attemptNum>4)
|
|
210
|
+
found = true;
|
|
211
|
+
log('found adblock zero attr: ' + baitTriggers.zeroProps[i]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if(window.getComputedStyle !== undefined) {
|
|
216
|
+
var baitTemp = window.getComputedStyle(baitNode, null);
|
|
217
|
+
if(baitTemp.getPropertyValue('display') == 'none'
|
|
218
|
+
|| baitTemp.getPropertyValue('visibility') == 'hidden') {
|
|
219
|
+
if(attemptNum>4)
|
|
220
|
+
found = true;
|
|
221
|
+
log('found adblock computedStyle indicator');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
testedOnce = true;
|
|
226
|
+
|
|
227
|
+
if(found || attemptNum++ >= _options.maxLoop){
|
|
228
|
+
findResult = found;
|
|
229
|
+
log('exiting test loop - value: ' + findResult);
|
|
230
|
+
notifyListeners();
|
|
231
|
+
if(clearBaitNode()){
|
|
232
|
+
setTimeout(function(){
|
|
233
|
+
testExecuting = false;
|
|
234
|
+
}, 5);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else{
|
|
238
|
+
timerIds.test = setTimeout(function(){
|
|
239
|
+
reelIn(bait, attemptNum);
|
|
240
|
+
}, _options.loopDelay);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function clearBaitNode(){
|
|
245
|
+
if(baitNode === null){
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
try{
|
|
250
|
+
if(isFunc(baitNode.remove)){
|
|
251
|
+
baitNode.remove();
|
|
252
|
+
}
|
|
253
|
+
document.body.removeChild(baitNode);
|
|
254
|
+
}
|
|
255
|
+
catch(ex){
|
|
256
|
+
}
|
|
257
|
+
baitNode = null;
|
|
258
|
+
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Halt the test and any pending timeouts
|
|
264
|
+
*/
|
|
265
|
+
function stopFishing(){
|
|
266
|
+
if(timerIds.test > 0){
|
|
267
|
+
clearTimeout(timerIds.test);
|
|
268
|
+
}
|
|
269
|
+
if(timerIds.download > 0){
|
|
270
|
+
clearTimeout(timerIds.download);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
clearBaitNode();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Fire all registered listeners
|
|
278
|
+
*/
|
|
279
|
+
function notifyListeners(){
|
|
280
|
+
var i, funcs;
|
|
281
|
+
if(findResult === null){
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
for(i=0;i<listeners.length;i++){
|
|
285
|
+
funcs = listeners[i];
|
|
286
|
+
try{
|
|
287
|
+
if(funcs != null){
|
|
288
|
+
if(isFunc(funcs['complete'])){
|
|
289
|
+
funcs['complete'](findResult);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if(findResult && isFunc(funcs['found'])){
|
|
293
|
+
funcs['found']();
|
|
294
|
+
}
|
|
295
|
+
else if(findResult === false && isFunc(funcs['notfound'])){
|
|
296
|
+
funcs['notfound']();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch(ex){
|
|
301
|
+
log('Failure in notify listeners ' + ex.Message, true);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Attaches event listener or fires if events have already passed.
|
|
308
|
+
*/
|
|
309
|
+
function attachOrFire(){
|
|
310
|
+
var fireNow = false;
|
|
311
|
+
var fn;
|
|
312
|
+
|
|
313
|
+
if(document.readyState){
|
|
314
|
+
if(document.readyState == 'complete'){
|
|
315
|
+
fireNow = true;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
fn = function(){
|
|
320
|
+
beginTest(quickBait, false);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if(fireNow){
|
|
324
|
+
fn();
|
|
325
|
+
}
|
|
326
|
+
else{
|
|
327
|
+
attachEventListener(window, 'load', fn);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Public interface of adblock detector
|
|
334
|
+
*/
|
|
335
|
+
return function(options){
|
|
336
|
+
var k, v, funcs;
|
|
337
|
+
|
|
338
|
+
if(!options){
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
funcs = {
|
|
343
|
+
complete: noop,
|
|
344
|
+
found: noop,
|
|
345
|
+
notfound: noop
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
for(k in options){
|
|
349
|
+
if(options.hasOwnProperty(k)){
|
|
350
|
+
if(k == 'complete' || k == 'found' || k == 'notFound'){
|
|
351
|
+
funcs[k.toLowerCase()] = options[k];
|
|
352
|
+
}
|
|
353
|
+
else{
|
|
354
|
+
_options[k] = options[k];
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
listeners.push(funcs);
|
|
360
|
+
|
|
361
|
+
attachOrFire();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
;
|
|
365
|
+
export default {
|
|
366
|
+
init: init()
|
|
367
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
export default {
|
|
3
|
+
state: function() {
|
|
4
|
+
return document.visibilityState || document.webkitVisibilityState || document.mozVisibilityState || document.msVisibilityState;
|
|
5
|
+
},
|
|
6
|
+
changeEvent: document.visibilityState ? "visibilitychange" : document.webkitVisibilityState ? "webkitvisibilitychange" : document.mozVisibilityState ? "mozvisibilitychange" : document.msVisibilityState ? "msvisibilitychange" : void 0
|
|
7
|
+
};
|
package/build/witness.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guardian/ophan-tracker-js",
|
|
3
|
+
"version": "2.0.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=16"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"build/*.js",
|
|
10
|
+
"build/vendor/*.js"
|
|
11
|
+
],
|
|
12
|
+
"main": "build/ng.js",
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@babel/preset-env": "7.22.10",
|
|
15
|
+
"@changesets/cli": "^2.26.2",
|
|
16
|
+
"@rollup/plugin-babel": "6.0.3",
|
|
17
|
+
"@rollup/plugin-terser": "0.4.3",
|
|
18
|
+
"coffeescript": "2.7.0",
|
|
19
|
+
"rollup": "3.28.0"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"coffee-to-esm:watch": "coffee --compile --watch --output build/ assets/coffee/ophan/",
|
|
23
|
+
"coffee-to-esm": "coffee --compile --output build/ assets/coffee/ophan/",
|
|
24
|
+
"prepublishOnly": "npm run coffee-to-esm"
|
|
25
|
+
}
|
|
26
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Ophan Tracker JS
|
|
2
|
+
|
|
3
|
+
Browser JavaScript client for Ophan.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
$ npm install ophan-tracker-js
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Contribute
|
|
12
|
+
|
|
13
|
+
#### Proxy tracker-ts:
|
|
14
|
+
|
|
15
|
+
1. Install dependencies
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
$ brew install lighttpd
|
|
19
|
+
.../ophan/tracker-js $ npm install
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. In one terminal window:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
.../ophan/tracker-js $ grunt
|
|
26
|
+
.../ophan/tracker-js $ grunt watch
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
3. In another terminal window:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
.../ophan/tracker-js $ lighttpd -f lighttpd.conf -D
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
4. Install FoxyProxy (https://getfoxyproxy.org/downloads/) in your browser and create a rule that forces j.ophan.co.uk
|
|
37
|
+
to localhost 8000. (For me FoxyProxy needed a few switches on and off before it decided to start talking to lighttpd.)
|
|
38
|
+
|
|
39
|
+
5. In another terminal window, start a server that is [running the Guardian frontend](https://github.com/guardian/frontend/blob/main/docs/01-start-here/01-installation-steps.md)
|
|
40
|
+
|
|
41
|
+
6. Navigate to where you are running the Guardian locally (e.g. https://localhost:9000/uk)
|
|
42
|
+
|
|
43
|
+
7. Ensure FoxyProxy is enabled
|
|
44
|
+
|
|
45
|
+
8. Develop with pleasure
|
|
46
|
+
|
|
47
|
+
## Publish
|
|
48
|
+
|
|
49
|
+
#### Two formats for release
|
|
50
|
+
|
|
51
|
+
When you make a change to Tracker JS, you must release on *both* these systems:
|
|
52
|
+
|
|
53
|
+
* The NPM package [`@guardian/ophan-tracker-js`](https://www.npmjs.com/package/ophan-tracker-js), commonly used on internally developed Guardian sites like Guardian Frontend and Support Frontend.
|
|
54
|
+
* [https://j.ophan.co.uk/](https://j.ophan.co.uk/jobs.js) - CDN/S3, [deployed through RiffRaff](https://riffraff.gutools.co.uk/deployment/history?projectName=ophan%3A%3Aophan-tracker-js&page=1) and used by some Guardian sites like https://jobs.theguardian.com/. An advantage of this approach is that sites using it immediately get Tracker JS updates, without developer intervention.
|
|
55
|
+
|
|
56
|
+
**Ensure that before you merge a change, you first bump the version in `package.json`. Please make sure you update the [changes.md](changes.md) file too. If you have added a new Ophan client to support a new platform, please add the path to the built output file to the files list in [`package.json`](https://github.com/guardian/ophan/blob/main/tracker-js/package.json#L4).**
|
|
57
|
+
|
|
58
|
+
### Publish to NPM
|
|
59
|
+
|
|
60
|
+
Whenever the Tracker script is changed, [its `ophan-tracker-js` NPM package](https://www.npmjs.com/package/ophan-tracker-js/access) will
|
|
61
|
+
need to be updated to a new version.
|
|
62
|
+
|
|
63
|
+
If you don't already have an NPM account, be sure to set up two-factor authentification.
|
|
64
|
+
|
|
65
|
+
**Log into NPM**
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
$ npm login
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Compile**
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
.../ophan/tracker-js $ npm install
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Publish**
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
.../ophan/tracker-js $ npm publish
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**You will need to be added as an owner of `ophan-tracker-js`. To find the current owners:**
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
$ npm owner ls @guardian/ophan-tracker-js
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**To add someone as an owner:**
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
npm owner add npm.username @guardian/ophan-tracker-js
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
More information on setting owners is available in [NPM's documentation](https://docs.npmjs.com/cli/v7/commands/npm-owner).
|