google-analytics_analytics.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*******************************************************************************
  2. uBlock Origin - a browser extension to block requests.
  3. Copyright (C) 2019-present Raymond Hill
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see {http://www.gnu.org/licenses/}.
  14. Home: https://github.com/gorhill/uBlock
  15. */
  16. (function() {
  17. 'use strict';
  18. // https://developers.google.com/analytics/devguides/collection/analyticsjs/
  19. const noopfn = function() {
  20. };
  21. //
  22. const Tracker = function() {
  23. };
  24. const p = Tracker.prototype;
  25. p.get = noopfn;
  26. p.set = noopfn;
  27. p.send = noopfn;
  28. //
  29. const w = window;
  30. const gaName = w.GoogleAnalyticsObject || 'ga';
  31. const gaQueue = w[gaName];
  32. // https://github.com/uBlockOrigin/uAssets/pull/4115
  33. const ga = function() {
  34. const len = arguments.length;
  35. if ( len === 0 ) { return; }
  36. const args = Array.from(arguments);
  37. let fn;
  38. let a = args[len-1];
  39. if ( a instanceof Object && a.hitCallback instanceof Function ) {
  40. fn = a.hitCallback;
  41. } else if ( a instanceof Function ) {
  42. fn = ( ) => { a(ga.create()); };
  43. } else {
  44. const pos = args.indexOf('hitCallback');
  45. if ( pos !== -1 && args[pos+1] instanceof Function ) {
  46. fn = args[pos+1];
  47. }
  48. }
  49. if ( fn instanceof Function === false ) { return; }
  50. try {
  51. fn();
  52. } catch (ex) {
  53. }
  54. };
  55. ga.create = function() {
  56. return new Tracker();
  57. };
  58. ga.getByName = function() {
  59. return new Tracker();
  60. };
  61. ga.getAll = function() {
  62. return [new Tracker()];
  63. };
  64. ga.remove = noopfn;
  65. // https://github.com/uBlockOrigin/uAssets/issues/2107
  66. ga.loaded = true;
  67. w[gaName] = ga;
  68. // https://github.com/gorhill/uBlock/issues/3075
  69. const dl = w.dataLayer;
  70. if ( dl instanceof Object ) {
  71. if ( dl.hide instanceof Object && typeof dl.hide.end === 'function' ) {
  72. dl.hide.end();
  73. dl.hide.end = ()=>{};
  74. }
  75. if ( typeof dl.push === 'function' ) {
  76. const doCallback = function(item) {
  77. if ( item instanceof Object === false ) { return; }
  78. if ( typeof item.eventCallback !== 'function' ) { return; }
  79. setTimeout(item.eventCallback, 1);
  80. item.eventCallback = ()=>{};
  81. };
  82. dl.push = new Proxy(dl.push, {
  83. apply: function(target, thisArg, args) {
  84. doCallback(args[0]);
  85. return Reflect.apply(target, thisArg, args);
  86. }
  87. });
  88. if ( Array.isArray(dl) ) {
  89. const q = dl.slice();
  90. for ( const item of q ) {
  91. doCallback(item);
  92. }
  93. }
  94. }
  95. }
  96. // empty ga queue
  97. if ( gaQueue instanceof Function && Array.isArray(gaQueue.q) ) {
  98. const q = gaQueue.q.slice();
  99. gaQueue.q.length = 0;
  100. for ( const entry of q ) {
  101. ga(...entry);
  102. }
  103. }
  104. })();