Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up and refactor side wide shared JS code #4387

Merged
merged 14 commits into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 0 additions & 65 deletions source/js/analytics.js

This file was deleted.

4 changes: 2 additions & 2 deletions source/js/buyers-guide/analytics-events.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ReactGA from "../react-ga-proxy";
import DNT from "../dnt.js";
import { googleAnalytics } from "../common";

function getQuerySelectorEvents(pageTitle, productName) {
return {
Expand Down Expand Up @@ -127,7 +127,7 @@ function setupElementGA(element, eventData) {

const ProductGA = {
init: () => {
if (!DNT.allowTracking) {
if (googleAnalytics.doNotTrack) {
// explicit check on DNT left in, to prevent
// a whole heap of code from executing.
return;
Expand Down
42 changes: 7 additions & 35 deletions source/js/buyers-guide/bg-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import React from "react";
import ReactDOM from "react-dom";
import ReactGA from "../react-ga-proxy.js";
import Storage from "../storage.js";
import * as common from "../common";

import primaryNav from "./components/primary-nav/primary-nav.js";
import navNewsletter from "../nav-newsletter.js";
import CreepVote from "./components/creep-vote/creep-vote.jsx";
import Creepometer from "./components/creepometer/creepometer.jsx";
import JoinUs from "../components/join/join.jsx";

import copyToClipboard from "../../js/copy-to-clipboard.js";
import HomepageSlider from "./homepage-c-slider.js";
Expand Down Expand Up @@ -55,25 +54,14 @@ let main = {
networkSiteURL = `https://${env.HEROKU_APP_NAME}.herokuapp.com`;
}

// TODO: this should probably tap into the analytics.js file that
// we use in main.js so that we only have one place where top level
// changes to how analytics works need to be made.

const gaMeta = document.querySelector(`meta[name="ga-identifier"]`);
if (gaMeta) {
let gaIdentifier = gaMeta.getAttribute(`content`);
ReactGA.initialize(gaIdentifier); // UA-87658599-6 by default
ReactGA.pageview(window.location.pathname);
AnalyticsEvents.init();
} else {
console.warn(`No GA identifier found: skipping bootstrap step`);
}
common.googleAnalytics.init();
AnalyticsEvents.init();

this.enableCopyLinks();
this.injectReactComponents();

primaryNav.init();
navNewsletter.init(networkSiteURL, csrfToken);
common.bindEventHandlers();
common.initiatePrimaryNav(networkSiteURL, csrfToken, primaryNav);

if (document.getElementById(`view-home`)) {
HomepageSlider.init();
Expand Down Expand Up @@ -120,6 +108,8 @@ let main = {

// Embed various React components based on the existence of containers within the current page
injectReactComponents() {
common.injectReactComponents(apps, networkSiteURL, csrfToken);

document.querySelectorAll(`.creep-vote-target`).forEach(element => {
let csrf = element.querySelector(`input[name=csrfmiddlewaretoken]`);
let productName = element.dataset.productName;
Expand Down Expand Up @@ -170,24 +160,6 @@ let main = {
})
);
});

document.querySelectorAll(`.join-us`).forEach(element => {
const props = element.dataset;
const sid = props.signupId || 0;
props.apiUrl = `${networkSiteURL}/api/campaign/signups/${sid}/`;

props.csrfToken = props.csrfToken || csrfToken;
props.isHidden = false;

apps.push(
new Promise(resolve => {
ReactDOM.render(
<JoinUs {...props} whenLoaded={() => resolve()} />,
element
);
})
);
});
}
};

Expand Down
25 changes: 25 additions & 0 deletions source/js/common/bind-event-handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import ReactGA from "../react-ga-proxy.js";

/**
* Bind click handler to #donate-footer-btn
*/
const bindDonateFooterButtonHandler = () => {
let donateFooterBtn = document.getElementById(`donate-footer-btn`);

if (donateFooterBtn) {
donateFooterBtn.addEventListener(`click`, () => {
ReactGA.event({
category: `donate`,
action: `donate button tap`,
label: `${document.title} footer`
});
});
}
};

/**
* Bind event handlers
*/
export default () => {
bindDonateFooterButtonHandler();
};
50 changes: 50 additions & 0 deletions source/js/common/google-analytics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import ReactGA from "../react-ga-proxy.js";

/**
* Check browser's "do not track" setting
* @return {Boolean} if browser's "do not track" setting is on
*/
const checkDoNotTrack = () => {
let _dntStatus = navigator.doNotTrack || navigator.msDoNotTrack,
fxMatch = navigator.userAgent.match(/Firefox\/(\d+)/),
ie10Match = navigator.userAgent.match(/MSIE 10/i),
w8Match = navigator.appVersion.match(/Windows NT 6.2/);

if (fxMatch && Number(fxMatch[1]) < 32) {
_dntStatus = `Unspecified`;
} else if (ie10Match && w8Match) {
_dntStatus = `Unspecified`;
} else {
_dntStatus =
{ "0": `Disabled`, "1": `Enabled` }[_dntStatus] || `Unspecified`;
}

return _dntStatus === `Enabled`;
};

const DO_NOT_TRACK = checkDoNotTrack();

/**
* Initialize Google Analytics and tracking pageviews
*/
const init = () => {
const gaMeta = document.querySelector(`meta[name="ga-identifier"]`);

if (!gaMeta) return;

let gaIdentifier = gaMeta.getAttribute(`content`);

if (!gaIdentifier) {
console.warn(`No GA identifier found: skipping bootstrap step`);
}

if (!DO_NOT_TRACK) {
ReactGA.initialize(gaIdentifier);
ReactGA.pageview(window.location.pathname);
}
};

export default {
doNotTrack: DO_NOT_TRACK,
init: init
};
8 changes: 8 additions & 0 deletions source/js/common/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// The following modules are the common modules which need to be called
// on all pages on the main Foundation site, apps, and microsites.
// e.g., Foundation site, PNI, MozFest etc

export { default as bindEventHandlers } from "./bind-event-handlers";
export { default as googleAnalytics } from "./google-analytics";
export { default as initiatePrimaryNav } from "./initiate-primary-nav";
export { default as injectReactComponents } from "./inject-react-components";
12 changes: 12 additions & 0 deletions source/js/common/initiate-primary-nav.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import navNewsletter from "../nav-newsletter.js";

/**
* Initiate primary nav scripts
* @param {String} siteUrl Foundation site base URL
* @param {String} csrfToken CSRF Token
* @param {Object} primaryNavModule primary nav module to initiate
*/
export default (siteUrl, csrfToken, primaryNavModule) => {
primaryNavModule.init();
navNewsletter.init(siteUrl, csrfToken);
};
41 changes: 41 additions & 0 deletions source/js/common/inject-react-components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react";
import ReactDOM from "react-dom";
import JoinUs from "../components/join/join.jsx";

/**
* Inject newsletter signup forms
* @param {Array} apps The existing array we are using to to track all ReactDOM.render calls
* @param {String} siteUrl Foundation site base URL
* @param {String} csrfToken CSRF Token
*/
const injectJoinUs = (apps, siteUrl, csrfToken) => {
// excluding `.join-us.on-nav` because it's taken care of by nav-newsletter.js
document.querySelectorAll(`.join-us:not(.on-nav)`).forEach(element => {
const props = element.dataset;
const sid = props.signupId || 0;

props.apiUrl = `${siteUrl}/api/campaign/signups/${sid}/`;

props.csrfToken = props.csrfToken || csrfToken;
props.isHidden = false;

apps.push(
new Promise(resolve => {
ReactDOM.render(
<JoinUs {...props} whenLoaded={() => resolve()} />,
element
);
})
);
});
};

/**
* Inject React components
* @param {Array} apps The existing array we are using to to track all ReactDOM.render calls
* @param {String} siteUrl Foundation site base URL
* @param {String} csrfToken CSRF Token
*/
export default (apps, siteUrl, csrfToken) => {
injectJoinUs(apps, siteUrl, csrfToken);
};
6 changes: 3 additions & 3 deletions source/js/components/join/join.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import ReactGA from "react-ga";
import ReactGA from "../../react-ga-proxy.js";
import ReactDOM from "react-dom";
import classNames from "classnames";
import CountrySelect from "../petition/country-select.jsx";
Expand Down Expand Up @@ -452,7 +452,7 @@ export default class JoinUs extends React.Component {
!this.state.apiSubmitted &&
!this.privacy.checked &&
!this.isFlowForm() && (
<span class="form-error-glyph privacy-error d-flex" />
<span className="form-error-glyph privacy-error d-flex" />
)}
</label>
</div>
Expand Down Expand Up @@ -515,7 +515,7 @@ export default class JoinUs extends React.Component {
{this.renderSubmitButton()}
{this.isFlowForm() && (
<button
class="btn btn-primary btn-dismiss flex-1"
className="btn btn-primary btn-dismiss flex-1"
onClick={() => this.props.handleSignUp(false)}
type="button"
>
Expand Down
2 changes: 1 addition & 1 deletion source/js/components/petition/petition.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import ReactGA from "react-ga";
import ReactGA from "../../react-ga-proxy.js";
import classNames from "classnames";
import DonationModal from "./donation-modal.jsx";
import FloatingLabelInput from "./floating-label-input.jsx";
Expand Down
18 changes: 0 additions & 18 deletions source/js/dnt.js

This file was deleted.

Loading