Skip to content

Commit

Permalink
feat: use easy ga for firefox,but disabled now
Browse files Browse the repository at this point in the history
  • Loading branch information
ineo6 committed May 13, 2021
1 parent 018bedd commit 11aef65
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 20 deletions.
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ extension/
typings
**/*.d.ts
src/common/template/template.js
views/ga.js
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"location": true,
"chrome": true,
"TEMPLATE": true,
"safari": true
"safari": true,
"Components": true
},
"rules": {
"no-bitwise": 0,
Expand Down
4 changes: 2 additions & 2 deletions src/Background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { isChrome, isNotificationTargetPage } from './util';

let currentUrl = '';
let tabId: number;
const ga = new Analytics();

ga.initialize('UA-39288503-7');
const ga = new Analytics('UA-39288503-7', process.env.TARGET_BROWSER === 'firefox');
ga.initialize();

browser.runtime.onInstalled.addListener((details): void => {
const manifest = browser.runtime.getManifest();
Expand Down
46 changes: 36 additions & 10 deletions src/common/analytics.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { STORE } from '@/common/core.constants';
import extStore from '@/common/core.storage';
import { browser } from 'webextension-polyfill-ts';
import GoogleAnalyticsService from './ga';

export interface IEvent {
eventCategory: string;
Expand Down Expand Up @@ -59,9 +59,27 @@ export const GaEvent = {
};

export default class Analytics {
constructor() {
window._gaq = window._gaq || [];
this.register();
private readonly isFirefox: boolean;

private ga: any;

private readonly trackingId: string;

private readonly disableFirefox: boolean;

constructor(trackingId: string, disableFirefox: boolean) {
this.isFirefox = process.env.TARGET_BROWSER === 'firefox';

this.trackingId = trackingId;
this.disableFirefox = disableFirefox;

if (!this.isFirefox) {
window._gaq = window._gaq || [];
this.register();
} else if (!disableFirefox) {
// @ts-ignore
this.ga = new GoogleAnalyticsService();
}
}

event = GaEvent;
Expand All @@ -71,22 +89,30 @@ export default class Analytics {
const ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = browser.extension.getURL('/ga.js');
ga.src = 'https://ssl.google-analytics.com/ga.js';
const s = document.getElementsByTagName('script')[0];
// @ts-ignore
s.parentNode.insertBefore(ga, s);
})();
}

initialize(trackingId: string) {
window._gaq.push(['_setAccount', trackingId]);
window._gaq.push(['_trackPageview']);
pushQueue(queue: any[]) {
if (this.isFirefox && this.disableFirefox) {
this.ga.send(queue);
} else {
window._gaq.push(queue);
}
}

initialize() {
this.pushQueue(['_setAccount', this.trackingId]);
this.pushQueue(['_trackPageview']);
}

page(page: string) {
if (page) {
if (process.env.NODE_ENV === 'production') {
window._gaq.push(['_trackPageview', page]);
this.pushQueue(['_trackPageview', page]);
}
}
}
Expand All @@ -104,7 +130,7 @@ export default class Analytics {
if (process.env.NODE_ENV === 'production') {
extStore.get(STORE.ANALYSIS).then((result: boolean) => {
if (result) {
window._gaq.push(['_trackEvent', ...eventArr]);
this.pushQueue(['_trackEvent', ...eventArr]);
}
});
} else {
Expand Down
117 changes: 117 additions & 0 deletions src/common/ga.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* simple ga
*/
import extStore from './core.storage';
import TimeoutQueue from './timeout-queue';

const timeoutQueue = new TimeoutQueue();

class GoogleAnalytics {
constructor(trackingId: string) {
this.analyticsId = trackingId;

this.init();
this.initUserUniqueId();
}

analyticsId = '';

xhr: XMLHttpRequest | undefined;

userUniqueId: number = 0;

storeUniqueId(uniqueId: number) {
this.userUniqueId = uniqueId;
extStore.set('_user_unique_id', uniqueId);
}

async retrieveUniqueId() {
const uid = await extStore.get('_user_unique_id');

return uid;
}

makeRandomId() {
return 1000000000 + Math.floor(Math.random() * (2147483647 - 1000000000));
}

async initUserUniqueId() {
if (this.userUniqueId) {
return;
}

let uniqueId = await this.retrieveUniqueId();
if (uniqueId) {
this.userUniqueId = uniqueId;
} else {
this.userUniqueId = this.makeRandomId();
this.storeUniqueId(this.userUniqueId);
}
}

init() {
this.xhr = new XMLHttpRequest();
}

qsStringify(obj: any) {
const s = [];
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key]) {
s.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
}
}
return s.join('&');
}

addRequest(opts: any) {
let url = 'http://www.google-analytics.com/collect';
let params = this.qsStringify({
v: 1,
tid: this.analyticsId,
cid: this.userUniqueId,
t: opts[0] || 'pageview',
ec: opts[1],
ea: opts[2],
el: opts[3],
ev: opts[4],
z: 1000000000 + Math.floor(Math.random() * (2147483647 - 1000000000)),
});

const self = this;

timeoutQueue.add(function() {
self.xhr?.open('POST', url, true);
// @ts-ignore
if (self.xhr?.channel) {
// firefox customization
// @ts-ignore
self.xhr.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
}
self.xhr?.send(params);
});
}

req(args: any) {
if (this.userUniqueId) {
this.addRequest(args);
}
}

send(opts: [string, string, string, string, string, string, string]) {
const [type, ...eventOpts] = opts;

if (type === '_trackEvent') {
this.req(['event', ...eventOpts]);
}
}
}

function GoogleAnalyticsService(trackingId: string) {
if (!GoogleAnalyticsService.prototype._singletonInstance) {
GoogleAnalyticsService.prototype._singletonInstance = new GoogleAnalytics(trackingId);
}

return GoogleAnalyticsService.prototype._singletonInstance;
}

export default GoogleAnalyticsService;
35 changes: 35 additions & 0 deletions src/common/timeout-queue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class TimeoutQueue {
running = false;

queue: Function[] = [];

timeout = 300;

add(callback: Function) {
this.queue.push(() => {
const finished = callback();

if (typeof finished === 'undefined' || finished) {
this.next();
}
});

if (!this.running) {
this.next();
}

return this;
}

next() {
this.running = false;
const shift = this.queue.shift();

if (shift) {
this.running = true;
setTimeout(shift, this.timeout);
}
}
}

export default TimeoutQueue;
8 changes: 6 additions & 2 deletions src/manifest/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ const devMatches = ['https://github.com/*', 'https://gitlab.com/*', 'https://try

const prodMatches = ['http://*/*', 'https://*/*'];

let csp = "script-src 'self' 'unsafe-eval'; object-src 'self'";
let csp = "script-src 'self' https://ssl.google-analytics.com 'unsafe-eval'; object-src 'self'";

if (process.env.NODE_ENV === 'production') {
csp = "script-src 'self'; object-src 'self'";
csp = "script-src 'self' https://ssl.google-analytics.com; object-src 'self'";
}

if (process.env.TARGET_BROWSER === 'firefox') {
csp.replace(' https://ssl.google-analytics.com', '');
}

const manifestInput = {
Expand Down
1 change: 1 addition & 0 deletions typings/custom-typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ declare module 'clipboard';

declare var TEMPLATE;
declare var RepoMeta;
declare var Components;

interface Window {
_gaq: any[];
Expand Down
4 changes: 0 additions & 4 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ module.exports = {
from: 'views/inject.js',
to: 'inject.js',
},
{
from: 'views/ga.js',
to: 'ga.js',
},
{
from: 'node_modules/@ineo6/file-icons/lib/fonts',
to: 'fonts',
Expand Down

0 comments on commit 11aef65

Please sign in to comment.