www-google-analytics-com_analytics.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. (function () {
  2. 'use strict';
  3. // https://developers.google.com/analytics/devguides/collection/analyticsjs/
  4. const noopfn = function () {
  5. };
  6. //
  7. const Tracker = function () {
  8. };
  9. const p = Tracker.prototype;
  10. p.get = noopfn;
  11. p.set = noopfn;
  12. p.send = noopfn;
  13. //
  14. const w = window;
  15. const gaName = w.GoogleAnalyticsObject || 'ga';
  16. const gaQueue = w[gaName];
  17. const ga = function () {
  18. const len = arguments.length;
  19. if (len === 0) { return; }
  20. const args = Array.from(arguments);
  21. let fn;
  22. let a = args[len - 1];
  23. if (a instanceof Object && typeof a.hitCallback === 'function') {
  24. fn = a.hitCallback;
  25. } else if (a instanceof Function) {
  26. fn = () => { a(ga.create()); };
  27. } else {
  28. const pos = args.indexOf('hitCallback');
  29. if (pos !== -1 && typeof args[pos + 1] === 'function') {
  30. fn = args[pos + 1];
  31. }
  32. }
  33. if (typeof fn !== 'function') { return; }
  34. try {
  35. fn();
  36. } catch (ex) {
  37. }
  38. };
  39. ga.create = function () {
  40. return new Tracker();
  41. };
  42. ga.getByName = function () {
  43. return new Tracker();
  44. };
  45. ga.getAll = function () {
  46. return [new Tracker()];
  47. };
  48. ga.remove = noopfn;
  49. // https://github.com/uBlockOrigin/uAssets/issues/2107
  50. ga.loaded = true;
  51. w[gaName] = ga;
  52. // https://github.com/gorhill/uBlock/issues/3075
  53. const dl = w.dataLayer;
  54. if (dl instanceof Object) {
  55. if (dl.hide instanceof Object && typeof dl.hide.end === 'function') {
  56. dl.hide.end();
  57. dl.hide.end = () => { };
  58. }
  59. if (typeof dl.push === 'function') {
  60. const doCallback = function (item) {
  61. if (item instanceof Object === false) { return; }
  62. if (typeof item.eventCallback !== 'function') { return; }
  63. setTimeout(item.eventCallback, 1);
  64. item.eventCallback = () => { };
  65. };
  66. dl.push = new Proxy(dl.push, {
  67. apply: function (target, thisArg, args) {
  68. doCallback(args[0]);
  69. return Reflect.apply(target, thisArg, args);
  70. }
  71. });
  72. if (Array.isArray(dl)) {
  73. const q = dl.slice();
  74. for (const item of q) {
  75. doCallback(item);
  76. }
  77. }
  78. }
  79. }
  80. // empty ga queue
  81. if (typeof gaQueue === 'function' && Array.isArray(gaQueue.q)) {
  82. const q = gaQueue.q.slice();
  83. gaQueue.q.length = 0;
  84. for (const entry of q) {
  85. ga(...entry);
  86. }
  87. }
  88. })();