Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d39543e

Browse filesBrowse files
phillipjItalo A. Casas
authored andcommitted
tools,doc: add Google Analytics tracking.
Adds Google Analytics tracking script to all doc pages when `DOCS_ANALYTICS` is set when running `make`: ```bash $ DOCS_ANALYTICS=<GOOGLE ANALYTICS ID> make ``` By default (when `DOCS_ANALYTICS` is not set), no tracking scripts are included. It respects "Do Not Track" settings end users might have in their browser. Also changes make target `doc-upload` from depending on the `$(TARBALL)` target, to only depend on `doc` directly. PR-URL: #6601 Reviewed-By: Johan Bergström <bugs@bergstroem.nu> Reviewed-By: Rod Vagg <rod@vagg.org> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
1 parent 7dff6aa commit d39543e
Copy full SHA for d39543e

File tree

Expand file treeCollapse file tree

6 files changed

+109
-6
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+109
-6
lines changed
Open diff view settings
Collapse file

‎Makefile‎

Copy file name to clipboardExpand all lines: Makefile
+8-2Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ test-v8 test-v8-intl test-v8-benchmarks test-v8-all:
300300
"$ git clone https://github.com/nodejs/node.git"
301301
endif
302302

303+
# Google Analytics ID used for tracking API docs page views, empty
304+
# DOCS_ANALYTICS means no tracking scripts will be included in the
305+
# generated .html files
306+
DOCS_ANALYTICS ?=
307+
303308
apidoc_sources = $(wildcard doc/api/*.md)
304309
apidocs_html = $(apidoc_dirs) $(apiassets) $(addprefix out/,$(apidoc_sources:.md=.html))
305310
apidocs_json = $(apidoc_dirs) $(apiassets) $(addprefix out/,$(apidoc_sources:.md=.json))
@@ -333,7 +338,8 @@ out/doc/api/%.json: doc/api/%.md
333338
[ -x $(NODE) ] && $(NODE) $(gen-json) || node $(gen-json)
334339

335340
# check if ./node is actually set, else use user pre-installed binary
336-
gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html --template=doc/template.html $< > $@
341+
gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html \
342+
--template=doc/template.html --analytics=$(DOCS_ANALYTICS) $< > $@
337343
out/doc/api/%.html: doc/api/%.md
338344
@[ -e tools/doc/node_modules/js-yaml/package.json ] || \
339345
[ -e tools/eslint/node_modules/js-yaml/package.json ] || \
@@ -587,7 +593,7 @@ ifeq ($(XZ), 0)
587593
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).tar.xz.done"
588594
endif
589595

590-
doc-upload: tar
596+
doc-upload: doc
591597
ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)"
592598
chmod -R ug=rw-x+X,o=r+X out/doc/
593599
scp -pr out/doc/ $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/
Collapse file

‎doc/api_assets/dnt_helper.js‎

Copy file name to clipboard
+49Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* http://schalkneethling.github.io/blog/2015/11/06/respect-user-choice-do-not-track/
3+
* https://github.com/schalkneethling/dnt-helper/blob/master/js/dnt-helper.js
4+
*
5+
* Returns true or false based on whether doNotTack is enabled. It also takes into account the
6+
* anomalies, such as !bugzilla 887703, which effect versions of Fx 31 and lower. It also handles
7+
* IE versions on Windows 7, 8 and 8.1, where the DNT implementation does not honor the spec.
8+
* @see https://bugzilla.mozilla.org/show_bug.cgi?id=1217896 for more details
9+
* @params {string} [dnt] - An optional mock doNotTrack string to ease unit testing.
10+
* @params {string} [userAgent] - An optional mock userAgent string to ease unit testing.
11+
* @returns {boolean} true if enabled else false
12+
*/
13+
function _dntEnabled(dnt, userAgent) {
14+
15+
'use strict';
16+
17+
// for old version of IE we need to use the msDoNotTrack property of navigator
18+
// on newer versions, and newer platforms, this is doNotTrack but, on the window object
19+
// Safari also exposes the property on the window object.
20+
var dntStatus = dnt || navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
21+
var ua = userAgent || navigator.userAgent;
22+
23+
// List of Windows versions known to not implement DNT according to the standard.
24+
var anomalousWinVersions = ['Windows NT 6.1', 'Windows NT 6.2', 'Windows NT 6.3'];
25+
26+
var fxMatch = ua.match(/Firefox\/(\d+)/);
27+
var ieRegEx = /MSIE|Trident/i;
28+
var isIE = ieRegEx.test(ua);
29+
// Matches from Windows up to the first occurance of ; un-greedily
30+
// http://www.regexr.com/3c2el
31+
var platform = ua.match(/Windows.+?(?=;)/g);
32+
33+
// With old versions of IE, DNT did not exist so we simply return false;
34+
if (isIE && typeof Array.prototype.indexOf !== 'function') {
35+
return false;
36+
} else if (fxMatch && parseInt(fxMatch[1], 10) < 32) {
37+
// Can't say for sure if it is 1 or 0, due to Fx bug 887703
38+
dntStatus = 'Unspecified';
39+
} else if (isIE && platform && anomalousWinVersions.indexOf(platform.toString()) !== -1) {
40+
// default is on, which does not honor the specification
41+
dntStatus = 'Unspecified';
42+
} else {
43+
// sets dntStatus to Disabled or Enabled based on the value returned by the browser.
44+
// If dntStatus is undefined, it will be set to Unspecified
45+
dntStatus = { '0': 'Disabled', '1': 'Enabled' }[dntStatus] || 'Unspecified';
46+
}
47+
48+
return dntStatus === 'Enabled' ? true : false;
49+
}
Collapse file

‎doc/template.html‎

Copy file name to clipboardExpand all lines: doc/template.html
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ <h2>Table of Contents</h2>
4545
<script src="assets/sh_main.js"></script>
4646
<script src="assets/sh_javascript.min.js"></script>
4747
<script>highlight(undefined, undefined, 'pre');</script>
48+
<!-- __TRACKING__ -->
4849
</body>
4950
</html>
Collapse file

‎test/doctool/test-doctool-html.js‎

Copy file name to clipboardExpand all lines: test/doctool/test-doctool-html.js
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,18 @@ const testData = [
7272
'<p>I exist and am being linked to.</p>' +
7373
'<!-- [end-include:doc_inc_2.md] -->'
7474
},
75+
{
76+
file: path.join(common.fixturesDir, 'sample_document.md'),
77+
html: '<ol><li>fish</li><li><p>fish</p></li><li><p>Redfish</p></li>' +
78+
'<li>Bluefish</li></ol>',
79+
analyticsId: 'UA-67020396-1'
80+
},
7581
];
7682

7783
testData.forEach((item) => {
7884
// Normalize expected data by stripping whitespace
7985
const expected = item.html.replace(/\s/g, '');
86+
const includeAnalytics = typeof item.analyticsId !== 'undefined';
8087

8188
fs.readFile(item.file, 'utf8', common.mustCall((err, input) => {
8289
assert.ifError(err);
@@ -89,6 +96,7 @@ testData.forEach((item) => {
8996
filename: 'foo',
9097
template: 'doc/template.html',
9198
nodeVersion: process.version,
99+
analytics: item.analyticsId,
92100
},
93101
common.mustCall((err, output) => {
94102
assert.ifError(err);
@@ -97,6 +105,16 @@ testData.forEach((item) => {
97105
// Assert that the input stripped of all whitespace contains the
98106
// expected list
99107
assert.notStrictEqual(actual.indexOf(expected), -1);
108+
109+
// Testing the insertion of Google Analytics script when
110+
// an analytics id is provided. Should not be present by default
111+
if (includeAnalytics) {
112+
assert.notStrictEqual(actual.indexOf('google-analytics.com'), -1,
113+
'Google Analytics script was not present');
114+
} else {
115+
assert.strictEqual(actual.indexOf('google-analytics.com'), -1,
116+
'Google Analytics script was present');
117+
}
100118
}));
101119
}));
102120
}));
Collapse file

‎tools/doc/generate.js‎

Copy file name to clipboardExpand all lines: tools/doc/generate.js
+8-4Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,19 @@ let format = 'json';
1111
let template = null;
1212
let inputFile = null;
1313
let nodeVersion = null;
14+
let analytics = null;
1415

1516
args.forEach(function(arg) {
16-
if (!arg.match(/^--/)) {
17+
if (!arg.startsWith('--')) {
1718
inputFile = arg;
18-
} else if (arg.match(/^--format=/)) {
19+
} else if (arg.startsWith('--format=')) {
1920
format = arg.replace(/^--format=/, '');
20-
} else if (arg.match(/^--template=/)) {
21+
} else if (arg.startsWith('--template=')) {
2122
template = arg.replace(/^--template=/, '');
22-
} else if (arg.match(/^--node-version=/)) {
23+
} else if (arg.startsWith('--node-version=')) {
2324
nodeVersion = arg.replace(/^--node-version=/, '');
25+
} else if (arg.startsWith('--analytics=')) {
26+
analytics = arg.replace(/^--analytics=/, '');
2427
}
2528
});
2629

@@ -54,6 +57,7 @@ function next(er, input) {
5457
filename: inputFile,
5558
template: template,
5659
nodeVersion: nodeVersion,
60+
analytics: analytics,
5761
},
5862

5963
function(er, html) {
Collapse file

‎tools/doc/html.js‎

Copy file name to clipboardExpand all lines: tools/doc/html.js
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ function toHTML(opts, cb) {
6767
filename: opts.filename,
6868
template: template,
6969
nodeVersion: nodeVersion,
70+
analytics: opts.analytics,
7071
}, cb);
7172
});
7273
}
@@ -128,6 +129,13 @@ function render(opts, cb) {
128129
gtocData.replace('class="nav-' + id, 'class="nav-' + id + ' active')
129130
);
130131

132+
if (opts.analytics) {
133+
template = template.replace(
134+
'<!-- __TRACKING__ -->',
135+
analyticsScript(opts.analytics)
136+
);
137+
}
138+
131139
// content has to be the last thing we do with
132140
// the lexed tokens, because it's destructive.
133141
const content = marked.parser(lexed);
@@ -137,6 +145,23 @@ function render(opts, cb) {
137145
});
138146
}
139147

148+
function analyticsScript(analytics) {
149+
return `
150+
<script src="assets/dnt_helper.js"></script>
151+
<script>
152+
if (!_dntEnabled()) {
153+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;
154+
i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},
155+
i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];
156+
a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,
157+
'script','//www.google-analytics.com/analytics.js','ga');
158+
ga('create', '${analytics}', 'auto');
159+
ga('send', 'pageview');
160+
}
161+
</script>
162+
`;
163+
}
164+
140165
// handle general body-text replacements
141166
// for example, link man page references to the actual page
142167
function parseText(lexed) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.