From 35f01a4c508a948b7b48fda22c2c5b9820274b5e Mon Sep 17 00:00:00 2001 From: Barry Chen Date: Thu, 1 Feb 2018 14:14:30 -0600 Subject: [PATCH] Use eqeqeq. (#3977) --- .eslintrc.yml | 1 + addon/bootstrap.js | 8 +- addon/webextension/background/analytics.js | 2 +- addon/webextension/background/auth.js | 4 +- addon/webextension/background/main.js | 8 +- addon/webextension/blobConverters.js | 2 +- addon/webextension/onboarding/slides.js | 4 +- addon/webextension/selector/shooter.js | 10 +-- addon/webextension/selector/ui.js | 6 +- addon/webextension/selector/uicontrol.js | 28 +++---- addon/webextension/selector/util.js | 6 +- addon/webextension/sitehelper.js | 6 +- server/src/ab-tests.js | 2 +- server/src/browser-send-event.js | 2 +- server/src/db.js | 4 +- server/src/dbschema.js | 4 +- server/src/errors.js | 2 +- server/src/ga-activation.js | 2 +- server/src/pages/homepage/controller.js | 4 +- server/src/pages/metrics/controller.js | 4 +- server/src/pages/metrics/server.js | 2 +- server/src/pages/settings/server.js | 2 +- server/src/pages/shot/editor.js | 48 +++++------ server/src/pages/shot/model.js | 4 +- server/src/pages/shot/server.js | 2 +- server/src/pages/shot/view.js | 6 +- server/src/pages/shotindex/controller.js | 6 +- server/src/reactrender.js | 2 +- server/src/reactruntime.js | 2 +- server/src/server.js | 20 ++--- server/src/servershot.js | 6 +- server/src/share-buttons.js | 6 +- server/src/users.js | 6 +- shared/shot.js | 98 +++++++++++----------- shared/thumbnailGenerator.js | 2 +- static/js/UITour-lib.js | 10 +-- test/test.js | 8 +- 37 files changed, 170 insertions(+), 169 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 37937c1acf..82cb794d68 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -21,6 +21,7 @@ plugins: root: true rules: + eqeqeq: error no-console: [error, {allow: [debug, error, info, trace, warn]}] no-var: error prefer-const: error diff --git a/addon/bootstrap.js b/addon/bootstrap.js index 41561be6d6..ce445d4ce7 100644 --- a/addon/bootstrap.js +++ b/addon/bootstrap.js @@ -42,7 +42,7 @@ const prefObserver = { observe(aSubject, aTopic, aData) { // aSubject is the nsIPrefBranch we're observing (after appropriate QI) // aData is the name of the pref that's been changed (relative to aSubject) - if (aData == USER_DISABLE_PREF) { + if (aData === USER_DISABLE_PREF) { // eslint-disable-next-line promise/catch-or-return appStartupPromise = appStartupPromise.then(handleStartup); } @@ -74,7 +74,7 @@ const LibraryButton = { if (permissionPages.length > 1) { Cu.reportError(new Error("Should not have more than 1 permission page, but got: " + JSON.stringify(permissionPages))); } - this.PAGE_TO_OPEN = permissionPages.length == 1 ? permissionPages[0].replace(/\*$/, "") : "https://screenshots.firefox.com/"; + this.PAGE_TO_OPEN = permissionPages.length === 1 ? permissionPages[0].replace(/\*$/, "") : "https://screenshots.firefox.com/"; this.PAGE_TO_OPEN += "shots"; this.ICON_URL = webExtension.extension.getURL("icons/icon-16-v2.svg"); this.ICON_URL_2X = webExtension.extension.getURL("icons/icon-32-v2.svg"); @@ -194,7 +194,7 @@ function start(webExtension) { } function stop(webExtension, reason) { - if (reason != APP_SHUTDOWN) { + if (reason !== APP_SHUTDOWN) { LibraryButton.uninit(); if (photonPageAction) { photonPageAction.remove(); @@ -263,7 +263,7 @@ function initPhotonPageAction(api, webExtension) { // Establish a port to the WebExtension side. api.browser.runtime.onConnect.addListener((listenerPort) => { - if (listenerPort.name != "photonPageActionPort") { + if (listenerPort.name !== "photonPageActionPort") { return; } port = listenerPort; diff --git a/addon/webextension/background/analytics.js b/addon/webextension/background/analytics.js index 4b60edc64d..83998ff4ed 100644 --- a/addon/webextension/background/analytics.js +++ b/addon/webextension/background/analytics.js @@ -89,7 +89,7 @@ this.analytics = (function() { if (action === 'internal') { return Promise.resolve(); } - if (typeof label == "object" && (!options)) { + if (typeof label === "object" && (!options)) { options = label; label = undefined; } diff --git a/addon/webextension/background/auth.js b/addon/webextension/background/auth.js index 16d25e515a..477e6a4a77 100644 --- a/addon/webextension/background/auth.js +++ b/addon/webextension/background/auth.js @@ -46,7 +46,7 @@ this.auth = (function() { req.open("POST", registerUrl); req.setRequestHeader("content-type", "application/json"); req.onload = catcher.watchFunction(() => { - if (req.status == 200) { + if (req.status === 200) { log.info("Registered login"); initialized = true; saveAuthInfo(JSON.parse(req.responseText)); @@ -82,7 +82,7 @@ this.auth = (function() { const req = new XMLHttpRequest(); req.open("POST", loginUrl); req.onload = catcher.watchFunction(() => { - if (req.status == 404) { + if (req.status === 404) { if (noRegister) { resolve(false); } else { diff --git a/addon/webextension/background/main.js b/addon/webextension/background/main.js index 3acdeced8c..91ee1203ca 100644 --- a/addon/webextension/background/main.js +++ b/addon/webextension/background/main.js @@ -114,7 +114,7 @@ this.main = (function() { const event = active ? "start-shot" : "cancel-shot"; sendEvent(event, "toolbar-button", {incognito: tab.incognito}); }, (error) => { - if ((!hasSeenOnboarding) && error.popupMessage == "UNSHOOTABLE_PAGE") { + if ((!hasSeenOnboarding) && error.popupMessage === "UNSHOOTABLE_PAGE") { sendEvent("goto-onboarding", "selection-button", {incognito: tab.incognito}); return forceOnboarding(); } @@ -159,7 +159,7 @@ this.main = (function() { return false; } const path = url.substr(backend.length).replace(/^\/*/, "").replace(/[?#].*/, ""); - if (path == "shots") { + if (path === "shots") { return true; } if (/^[^/]{1,4000}\/[^/]{1,4000}$/.test(path)) { @@ -228,10 +228,10 @@ this.main = (function() { const url = URL.createObjectURL(blob); let downloadId; const onChangedCallback = catcher.watchFunction(function(change) { - if (!downloadId || downloadId != change.id) { + if (!downloadId || downloadId !== change.id) { return; } - if (change.state && change.state.current != "in_progress") { + if (change.state && change.state.current !== "in_progress") { URL.revokeObjectURL(url); browser.downloads.onChanged.removeListener(onChangedCallback); } diff --git a/addon/webextension/blobConverters.js b/addon/webextension/blobConverters.js index a1111995cd..24adf7b5d9 100644 --- a/addon/webextension/blobConverters.js +++ b/addon/webextension/blobConverters.js @@ -4,7 +4,7 @@ this.blobConverters = (function() { exports.dataUrlToBlob = function(url) { const binary = atob(url.split(',', 2)[1]); let contentType = exports.getTypeFromDataUrl(url); - if (contentType != "image/png" && contentType != "image/jpeg") { + if (contentType !== "image/png" && contentType !== "image/jpeg") { contentType = "image/png"; } const data = Uint8Array.from(binary, char => char.charCodeAt(0)); diff --git a/addon/webextension/onboarding/slides.js b/addon/webextension/onboarding/slides.js index 2293083f68..64e18b066f 100644 --- a/addon/webextension/onboarding/slides.js +++ b/addon/webextension/onboarding/slides.js @@ -145,7 +145,7 @@ this.slides = (function() { callbacks.onEnd(); }))); doc.querySelector("#slide-overlay").addEventListener("click", watchFunction(assertIsTrusted((event) => { - if (event.target == doc.querySelector("#slide-overlay")) { + if (event.target === doc.querySelector("#slide-overlay")) { shooter.sendEvent("cancel-slides", "background-click"); callbacks.onEnd(); } @@ -201,7 +201,7 @@ this.slides = (function() { const slideEl = doc.querySelector("#slide-container"); for (let i = 1; i <= numberOfSlides; i++) { const className = `active-slide-${i}`; - if (i == currentSlide) { + if (i === currentSlide) { slideEl.classList.add(className); } else { slideEl.classList.remove(className); diff --git a/addon/webextension/selector/shooter.js b/addon/webextension/selector/shooter.js index d44a6b2e0e..cefb87bc49 100644 --- a/addon/webextension/selector/shooter.js +++ b/addon/webextension/selector/shooter.js @@ -48,7 +48,7 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'); const ctx = canvas.getContext('2d'); let expand = window.devicePixelRatio !== 1; - if (captureType == 'fullPage' || captureType == 'fullPageTruncated') { + if (captureType === 'fullPage' || captureType === 'fullPageTruncated') { expand = false; canvas.width = width; canvas.height = height; @@ -79,8 +79,8 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars // isSaving indicates we're aleady in the middle of saving // we use a timeout so in the case of a failure the button will // still start working again - if (Math.floor(selectedPos.left) == Math.floor(selectedPos.right) || - Math.floor(selectedPos.top) == Math.floor(selectedPos.bottom)) { + if (Math.floor(selectedPos.left) === Math.floor(selectedPos.right) || + Math.floor(selectedPos.top) === Math.floor(selectedPos.bottom)) { const exc = new Error("Empty selection"); exc.popupMessage = "EMPTY_SELECTION"; exc.noReport = true; @@ -144,7 +144,7 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars return callBackground("openShot", { url, copied }); }); }, (error) => { - if ('popupMessage' in error && (error.popupMessage == "REQUEST_ERROR" || error.popupMessage == 'CONNECTION_ERROR')) { + if ('popupMessage' in error && (error.popupMessage === "REQUEST_ERROR" || error.popupMessage === 'CONNECTION_ERROR')) { // The error has been signaled to the user, but unlike other errors (or // success) we should not abort the selection deactivateAfterFinish = false; @@ -152,7 +152,7 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars ui.iframe.unhide(); return; } - if (error.name != "BackgroundError") { + if (error.name !== "BackgroundError") { // BackgroundError errors are reported in the Background page throw error; } diff --git a/addon/webextension/selector/ui.js b/addon/webextension/selector/ui.js index 01158c5f7d..0e87184547 100644 --- a/addon/webextension/selector/ui.js +++ b/addon/webextension/selector/ui.js @@ -741,7 +741,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars draggerDirection(target) { while (target) { - if (target.nodeType == document.ELEMENT_NODE) { + if (target.nodeType === document.ELEMENT_NODE) { if (target.classList.contains("mover-target")) { for (const name of movements) { if (target.classList.contains("direction-" + name)) { @@ -762,7 +762,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars if (target.tagName === "BUTTON") { return false; } - if (target.nodeType == document.ELEMENT_NODE && target.classList.contains("highlight")) { + if (target.nodeType === document.ELEMENT_NODE && target.classList.contains("highlight")) { return true; } target = target.parentNode; @@ -878,7 +878,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars if (name.startsWith("iframe")) { continue; } - if (typeof exports[name] == "object" && exports[name].remove) { + if (typeof exports[name] === "object" && exports[name].remove) { exports[name].remove(); } } diff --git a/addon/webextension/selector/uicontrol.js b/addon/webextension/selector/uicontrol.js index 507a391561..a9ed91ef67 100644 --- a/addon/webextension/selector/uicontrol.js +++ b/addon/webextension/selector/uicontrol.js @@ -394,13 +394,13 @@ this.uicontrol = (function() { start() { dataUrl = shooter.screenshotPage(selectedPos, captureType); ui.iframe.usePreview(); - ui.Preview.display(dataUrl, captureType == "fullPageTruncated"); + ui.Preview.display(dataUrl, captureType === "fullPageTruncated"); } }; stateHandlers.onboarding = { start() { - if (typeof slides == "undefined") { + if (typeof slides === "undefined") { throw new Error("Attempted to set state to onboarding without loading slides"); } catcher.watchPromise(slides.display({ @@ -555,12 +555,12 @@ this.uicontrol = (function() { evenBetterElement(node, origRect) { let el = node.parentNode; const ELEMENT_NODE = document.ELEMENT_NODE; - while (el && el.nodeType == ELEMENT_NODE) { + while (el && el.nodeType === ELEMENT_NODE) { if (!el.getAttribute) { return null; } const role = el.getAttribute("role"); - if (role === "article" || (el.className && typeof el.className == "string" && el.className.search("tweet ") !== -1)) { + if (role === "article" || (el.className && typeof el.className === "string" && el.className.search("tweet ") !== -1)) { const rect = Selection.getBoundingClientRect(el); if (!rect) { return null; @@ -672,15 +672,15 @@ this.uicontrol = (function() { return null; } const isGoodEl = (el) => { - if (el.nodeType != document.ELEMENT_NODE) { + if (el.nodeType !== document.ELEMENT_NODE) { return false; } - if (el.tagName == "IMG") { + if (el.tagName === "IMG") { const rect = el.getBoundingClientRect(); return rect.width >= this.minAutoImageWidth && rect.height >= this.minAutoImageHeight; } const display = window.getComputedStyle(el).display; - if (['block', 'inline-block', 'table'].indexOf(display) != -1) { + if (['block', 'inline-block', 'table'].indexOf(display) !== -1) { return true; // FIXME: not sure if this is useful: // let rect = el.getBoundingClientRect(); @@ -745,7 +745,7 @@ this.uicontrol = (function() { mousedown(event) { const target = event.target; - if (target.tagName == "HTML") { + if (target.tagName === "HTML") { // This happens when you click on the scrollbar return undefined; } @@ -790,7 +790,7 @@ this.uicontrol = (function() { sendEvent("selection-resized"); ui.Box.display(selectedPos, standardDisplayCallbacks); if (resizeHasMoved) { - if (resizeDirection == "move") { + if (resizeDirection === "move") { const startPos = new Pos(resizeStartSelected.left, resizeStartSelected.top); const endPos = new Pos(selectedPos.left, selectedPos.top); sendEvent( @@ -801,7 +801,7 @@ this.uicontrol = (function() { "resize-selection", "mouseup", eventOptionsForResize(resizeStartSelected, selectedPos)); } - } else if (resizeDirection == "move") { + } else if (resizeDirection === "move") { sendEvent("keep-resize-selection", "mouseup"); } else { sendEvent("keep-move-selection", "mouseup"); @@ -815,14 +815,14 @@ this.uicontrol = (function() { const movement = movements[resizeDirection]; if (movement[0]) { let moveX = movement[0]; - moveX = moveX == "*" ? ["x1", "x2"] : [moveX]; + moveX = moveX === "*" ? ["x1", "x2"] : [moveX]; for (const moveDir of moveX) { selectedPos[moveDir] = util.truncateX(resizeStartSelected[moveDir] + diffX); } } if (movement[1]) { let moveY = movement[1]; - moveY = moveY == "*" ? ["y1", "y2"] : [moveY]; + moveY = moveY === "*" ? ["y1", "y2"] : [moveY]; for (const moveDir of moveY) { selectedPos[moveDir] = util.truncateY(resizeStartSelected[moveDir] + diffY); } @@ -909,7 +909,7 @@ this.uicontrol = (function() { } function isFrameset() { - return document.body.tagName == "FRAMESET"; + return document.body.tagName === "FRAMESET"; } exports.deactivate = function() { @@ -943,7 +943,7 @@ this.uicontrol = (function() { function addHandlers() { ["mouseup", "mousedown", "mousemove", "click"].forEach((eventName) => { const fn = watchFunction(assertIsTrusted((function(eventName, event) { - if (typeof event.button == "number" && event.button !== 0) { + if (typeof event.button === "number" && event.button !== 0) { // Not a left click return undefined; } diff --git a/addon/webextension/selector/util.js b/addon/webextension/selector/util.js index cfa05f340f..891a1fca9c 100644 --- a/addon/webextension/selector/util.js +++ b/addon/webextension/selector/util.js @@ -62,7 +62,7 @@ this.util = (function() { // eslint-disable-line no-unused-vars // Partially outside the box for (let i = 0; i < el.childNodes.length; i++) { const child = el.childNodes[i]; - if (child.nodeType == ELEMENT_NODE) { + if (child.nodeType === ELEMENT_NODE) { traverse(child); } } @@ -72,9 +72,9 @@ this.util = (function() { // eslint-disable-line no-unused-vars } function addText(el) { let t; - if (el.tagName == "IMG") { + if (el.tagName === "IMG") { t = el.getAttribute("alt") || el.getAttribute("title"); - } else if (el.tagName == "A") { + } else if (el.tagName === "A") { t = el.innerText; if (el.getAttribute("href") && !el.getAttribute("href").startsWith("#")) { t += " (" + el.href + ")"; diff --git a/addon/webextension/sitehelper.js b/addon/webextension/sitehelper.js index c193b8e340..880ea68402 100644 --- a/addon/webextension/sitehelper.js +++ b/addon/webextension/sitehelper.js @@ -16,7 +16,7 @@ this.sitehelper = (function() { function sendCustomEvent(name, detail) { - if (typeof detail == "object") { + if (typeof detail === "object") { // Note sending an object can lead to security problems, while a string // is safe to transfer: detail = JSON.stringify(detail); @@ -33,7 +33,7 @@ this.sitehelper = (function() { // This is a very minimal attempt to verify that the XMLHttpRequest object we got // is legitimate. It is not a good test. - if (Object.toString.apply(ContentXMLHttpRequest) != "function XMLHttpRequest() {\n [native code]\n}") { + if (Object.toString.apply(ContentXMLHttpRequest) !== "function XMLHttpRequest() {\n [native code]\n}") { console.warn("Insecure copy of XMLHttpRequest"); return; } @@ -44,7 +44,7 @@ this.sitehelper = (function() { } req.send(""); req.onload = () => { - if (req.status != 200) { + if (req.status !== 200) { console.warn("Attempt to set Screenshots cookie via /api/set-login-cookie failed:", req.status, req.statusText, req.responseText); } }; diff --git a/server/src/ab-tests.js b/server/src/ab-tests.js index 2fe996a412..8a3c64b6c5 100644 --- a/server/src/ab-tests.js +++ b/server/src/ab-tests.js @@ -151,7 +151,7 @@ class Test { } if (excludes.includes("*")) { for (const testName in tests) { - if (testName != this.name && tests[testName].value !== "exclude") { + if (testName !== this.name && tests[testName].value !== "exclude") { return true; } } diff --git a/server/src/browser-send-event.js b/server/src/browser-send-event.js index 25ff0b090b..d29eebdea3 100644 --- a/server/src/browser-send-event.js +++ b/server/src/browser-send-event.js @@ -2,7 +2,7 @@ let sentEvent = false; -if (typeof window != "undefined" && window.sendEvent) { +if (typeof window !== "undefined" && window.sendEvent) { module.exports = window.sendEvent; } else { module.exports = function() { diff --git a/server/src/db.js b/server/src/db.js index 8d5457ad4b..3b51d484c2 100644 --- a/server/src/db.js +++ b/server/src/db.js @@ -74,7 +74,7 @@ exports.insert = function(sql, args) { return true; }).catch(err => { done(); - if (err.code == '23505') { + if (err.code === '23505') { // constraint error, duplicate key return false; } @@ -155,7 +155,7 @@ function initTiming() { return doNothing; } const caller = getCallerPosition(2); - if (caller == "skip") { + if (caller === "skip") { // This happens when getCallerPosition detects we shouldn't time this function call return doNothing; } diff --git a/server/src/dbschema.js b/server/src/dbschema.js index c139c10f70..c438800af4 100644 --- a/server/src/dbschema.js +++ b/server/src/dbschema.js @@ -67,7 +67,7 @@ exports.createTables = function() { WHERE id = $1`, [newId] ).then((count) => { - if (count != 1) { + if (count !== 1) { throw new Error("Should have deleted one row"); } }); @@ -156,6 +156,6 @@ exports.connectionOK = function() { return Promise.resolve(false); } return db.select(`SELECT value FROM property WHERE key = 'patch'`).then((rows) => { - return rows[0].value == MAX_DB_LEVEL; + return parseInt(rows[0].value, 10) === MAX_DB_LEVEL; }); }; diff --git a/server/src/errors.js b/server/src/errors.js index eb431d3837..a00072d5e8 100644 --- a/server/src/errors.js +++ b/server/src/errors.js @@ -10,7 +10,7 @@ exports.create = function create(status, errno, message, data) { payload: { statusCode, errno, - message: statusCode == 500 ? 'Internal server error' : err.message + message: statusCode === 500 ? 'Internal server error' : err.message }, headers: {} }; diff --git a/server/src/ga-activation.js b/server/src/ga-activation.js index d80d49989e..22b3d94f96 100644 --- a/server/src/ga-activation.js +++ b/server/src/ga-activation.js @@ -154,7 +154,7 @@ exports.makeGaActivationString = function(gaId, userId, abTests, hashLocation) { return stubGaJs.replace(/__ABTESTS__/g, JSON.stringify(abTests)); } userId = userId || ""; - if (typeof userId != "string") { + if (typeof userId !== "string") { throw new Error("Invalid user ID type: " + typeof userId); } if (gaId.search(idRegex) === -1) { diff --git a/server/src/pages/homepage/controller.js b/server/src/pages/homepage/controller.js index 41e3b5e88e..b004b3e3d4 100644 --- a/server/src/pages/homepage/controller.js +++ b/server/src/pages/homepage/controller.js @@ -17,11 +17,11 @@ document.addEventListener("addon-present", () => { document.dispatchEvent(new CustomEvent("request-onboarding")); } else if (location.hash === "#tour") { try { - if (typeof Mozilla == "undefined") { + if (typeof Mozilla === "undefined") { // The UITour-lib.js library hasn't loaded yet let count = 10; const interval = setInterval(() => { - if (typeof Mozilla == "undefined") { + if (typeof Mozilla === "undefined") { count--; if (count <= 0) { clearTimeout(interval); diff --git a/server/src/pages/metrics/controller.js b/server/src/pages/metrics/controller.js index 5bc9c893a6..8422b7b5e8 100644 --- a/server/src/pages/metrics/controller.js +++ b/server/src/pages/metrics/controller.js @@ -21,7 +21,7 @@ exports.onChangeLastShotTime = function(days) { const req = new XMLHttpRequest(); req.open("GET", `./api/recent/lastShotCount?lastShotTimeDays=${encodeURIComponent(days)}`); req.onload = function() { - if (req.status == 200) { + if (req.status === 200) { const data = JSON.parse(req.responseText); model.lastShotTimeDays = days; model.lastShotCount = data.count; @@ -43,7 +43,7 @@ exports.onChangeNumberOfShotsTime = function(days) { const req = new XMLHttpRequest(); req.open("GET", `./api/recent/numberOfShots?lastShotTimeDays=${encodeURIComponent(days)}`); req.onload = function() { - if (req.status == 200) { + if (req.status === 200) { const data = JSON.parse(req.responseText); model.numberOfShotsBuckets = data.buckets; render(); diff --git a/server/src/pages/metrics/server.js b/server/src/pages/metrics/server.js index c5e0c70b27..91234b73f8 100644 --- a/server/src/pages/metrics/server.js +++ b/server/src/pages/metrics/server.js @@ -8,7 +8,7 @@ const mozlog = require("../../logging").mozlog("metrics"); const app = exports.app = express(); app.get("/", function(req, res) { - if (req.originalUrl == "/metrics") { + if (req.originalUrl === "/metrics") { // We want a trailing slash res.redirect("/metrics/"); return; diff --git a/server/src/pages/settings/server.js b/server/src/pages/settings/server.js index d6637d398a..21b1b0c7ae 100644 --- a/server/src/pages/settings/server.js +++ b/server/src/pages/settings/server.js @@ -10,7 +10,7 @@ app.get("/", function(req, res) { res.status(403).send("You must have Screenshots installed"); return; } - if (req.originalUrl == "/settings/") { + if (req.originalUrl === "/settings/") { // We don't want a trailing / res.redirect("/settings"); return; diff --git a/server/src/pages/shot/editor.js b/server/src/pages/shot/editor.js index 72050e4b71..ef4a0ca424 100644 --- a/server/src/pages/shot/editor.js +++ b/server/src/pages/shot/editor.js @@ -121,8 +121,8 @@ exports.Editor = class Editor extends React.Component { } renderToolBar() { - const penState = this.state.tool == "pen" ? 'active' : 'inactive'; - const highlighterState = this.state.tool == "highlighter" ? 'active' : 'inactive'; + const penState = this.state.tool === "pen" ? 'active' : 'inactive'; + const highlighterState = this.state.tool === "highlighter" ? 'active' : 'inactive'; return
@@ -244,7 +244,7 @@ exports.Editor = class Editor extends React.Component { mousemove(e) { e.preventDefault(); const rect = this.cropContainer.getBoundingClientRect(); - if (mousedown && selectionState == "creating") { + if (mousedown && selectionState === "creating") { selectedPos = new Selection( this.truncateX(mousedownPos.left), this.truncateY(mousedownPos.top), @@ -257,7 +257,7 @@ exports.Editor = class Editor extends React.Component { this.displayCropBox(selectedPos); } } - if (mousedown && selectionState == "resizing") { + if (mousedown && selectionState === "resizing") { this.resizeCropBox(e); } } @@ -269,21 +269,21 @@ exports.Editor = class Editor extends React.Component { const diffX = event.clientX - rect.left - resizeStartPos.x; const diffY = event.clientY - rect.top - resizeStartPos.y; const movement = movementPositions[resizeDirection]; - const isLeftBorder = selectedPos.left == 0 && resizeStartSelected.left + diffX <= 0; - const isRightBorder = selectedPos.right == this.canvasWidth && resizeStartSelected.right + diffX >= this.canvasWidth; - const isTopBorder = selectedPos.top == 0 && resizeStartSelected.top + diffY <= 0; - const isBottomBorder = selectedPos.bottom == this.canvasHeight && resizeStartSelected.bottom + diffY >= this.canvasHeight; - const isMove = resizeDirection == "move"; + const isLeftBorder = selectedPos.left === 0 && resizeStartSelected.left + diffX <= 0; + const isRightBorder = selectedPos.right === this.canvasWidth && resizeStartSelected.right + diffX >= this.canvasWidth; + const isTopBorder = selectedPos.top === 0 && resizeStartSelected.top + diffY <= 0; + const isBottomBorder = selectedPos.bottom === this.canvasHeight && resizeStartSelected.bottom + diffY >= this.canvasHeight; + const isMove = resizeDirection === "move"; if (movement[0] && !(isMove && (isLeftBorder || isRightBorder))) { let moveX = movement[0]; - moveX = moveX == "*" ? ["x1", "x2"] : [moveX]; + moveX = moveX === "*" ? ["x1", "x2"] : [moveX]; for (const moveDir of moveX) { selectedPos[moveDir] = this.truncateX(resizeStartSelected[moveDir] + diffX); } } if (movement[1] && !(isMove && (isTopBorder || isBottomBorder))) { let moveY = movement[1]; - moveY = moveY == "*" ? ["y1", "y2"] : [moveY]; + moveY = moveY === "*" ? ["y1", "y2"] : [moveY]; for (const moveDir of moveY) { selectedPos[moveDir] = this.truncateY(resizeStartSelected[moveDir] + diffY); } @@ -294,17 +294,17 @@ exports.Editor = class Editor extends React.Component { // Preserves correct dimensions of crop box if the user hits borders preserveDimensions(width, height) { - if (resizeDirection == "move") { - if (selectedPos.left == 0) { + if (resizeDirection === "move") { + if (selectedPos.left === 0) { selectedPos.right = width; } - if (selectedPos.top == 0) { + if (selectedPos.top === 0) { selectedPos.bottom = height; } - if (selectedPos.right == this.canvasWidth) { + if (selectedPos.right === this.canvasWidth) { selectedPos.left = this.canvasWidth - width; } - if (selectedPos.bottom == this.canvasHeight) { + if (selectedPos.bottom === this.canvasHeight) { selectedPos.top = this.canvasHeight - height; } } @@ -456,14 +456,14 @@ exports.Editor = class Editor extends React.Component { } onClickHighlight() { - if (this.state.tool != 'highlighter') { + if (this.state.tool !== 'highlighter') { this.setState({tool: 'highlighter'}); sendEvent("highlighter-select", "annotation-toolbar"); } } onClickPen() { - if (this.state.tool != 'pen') { + if (this.state.tool !== 'pen') { this.setState({tool: 'pen'}); sendEvent("pen-select", "annotation-toolbar"); } @@ -492,27 +492,27 @@ exports.Editor = class Editor extends React.Component { this.imageContext.drawImage(this.highlighter, 0, 0); this.imageContext.globalCompositeOperation = 'multiply'; this.highlightContext.clearRect(0, 0, this.imageCanvas.width, this.imageCanvas.height); - if (this.state.tool != 'crop') { + if (this.state.tool !== 'crop') { this.cropToolBar = null; document.removeEventListener("mousemove", this.mousemove); document.removeEventListener("mousedown", this.mousedown); document.removeEventListener("mouseup", this.mouseup); } this.pos = { x: 0, y: 0 }; - if (this.state.tool == 'highlighter') { + if (this.state.tool === 'highlighter') { this.drawContext = this.highlightContext; this.highlightContext.lineWidth = 20; this.highlightContext.strokeStyle = this.state.color; document.addEventListener("mousemove", this.draw); document.addEventListener("mousedown", this.setPosition); - } else if (this.state.tool == 'pen') { + } else if (this.state.tool === 'pen') { this.drawContext = this.imageContext; this.imageContext.globalCompositeOperation = 'source-over'; this.imageContext.strokeStyle = this.state.color; this.imageContext.lineWidth = this.state.size; document.addEventListener("mousemove", this.draw); document.addEventListener("mousedown", this.setPosition); - } else if (this.state.tool == 'crop') { + } else if (this.state.tool === 'crop') { document.removeEventListener("mousemove", this.draw); document.removeEventListener("mousedown", this.setPosition); document.addEventListener("mousemove", this.mousemove); @@ -533,7 +533,7 @@ exports.Editor = class Editor extends React.Component { } this.drawContext.beginPath(); - this.drawContext.lineCap = this.state.tool == 'highlighter' ? 'square' : 'round'; + this.drawContext.lineCap = this.state.tool === 'highlighter' ? 'square' : 'round'; this.drawContext.moveTo(this.pos.x, this.pos.y); const rect = this.imageCanvas.getBoundingClientRect(); this.pos.x = e.clientX - rect.left, @@ -562,7 +562,7 @@ class ColorPicker extends React.Component { } render() { - const border = this.state.color == 'rgb(255, 255, 255)' ? '#000' : this.state.color; + const border = this.state.color === 'rgb(255, 255, 255)' ? '#000' : this.state.color; return
{this.state.pickerActive ? this.renderColorBoard() : null}
diff --git a/server/src/pages/shot/model.js b/server/src/pages/shot/model.js index f5ba55d5f8..6730191908 100644 --- a/server/src/pages/shot/model.js +++ b/server/src/pages/shot/model.js @@ -25,7 +25,7 @@ exports.createModel = function(req) { id: req.shot.id, productName: req.config.productName, isExtInstalled: !!req.deviceId, - isOwner: req.deviceId == req.shot.ownerId || (req.accountId && req.accountId == req.shot.accountId), + isOwner: req.deviceId === req.shot.ownerId || (req.accountId && req.accountId === req.shot.accountId), gaId: req.config.gaId, deviceId: req.deviceId, authenticated: !!req.deviceId, @@ -54,7 +54,7 @@ exports.createModel = function(req) { id: req.shot.id, productName: req.config.productName, isExtInstalled: !!req.deviceId, - isOwner: req.deviceId == req.shot.ownerId || (req.accountId && req.accountId == req.shot.accountId), + isOwner: req.deviceId === req.shot.ownerId || (req.accountId && req.accountId === req.shot.accountId), gaId: req.config.gaId, deviceId: req.deviceId, authenticated: !!req.deviceId, diff --git a/server/src/pages/shot/server.js b/server/src/pages/shot/server.js index 40f0768a3c..3d9ee46513 100644 --- a/server/src/pages/shot/server.js +++ b/server/src/pages/shot/server.js @@ -12,7 +12,7 @@ app.get("/:id/:domain", function(req, res) { const shotId = `${req.params.id}/${req.params.domain}`; Shot.get(req.backend, shotId).then((shot) => { const noSuchShot = !shot; - const nonOwnerAndBlocked = shot && shot.blockType !== 'none' && req.deviceId != shot.ownerId; + const nonOwnerAndBlocked = shot && shot.blockType !== 'none' && req.deviceId !== shot.ownerId; if (noSuchShot || nonOwnerAndBlocked || shot.deleted) { mozlog.info("shot-404", {shotId, ip: req.ip}); notFound(req, res); diff --git a/server/src/pages/shot/view.js b/server/src/pages/shot/view.js index e2f6793595..fd6a69df94 100644 --- a/server/src/pages/shot/view.js +++ b/server/src/pages/shot/view.js @@ -154,7 +154,7 @@ class Head extends React.Component { if (!url.startsWith("http")) { return url; } - if (url.indexOf("?") == -1) { + if (url.indexOf("?") === -1) { url += "?"; } else { url += "&"; @@ -267,7 +267,7 @@ class Body extends React.Component { renderExpired() { let expireTime = this.props.expireTime; - if (typeof expireTime != "number") { + if (typeof expireTime !== "number") { expireTime = expireTime.getTime(); } const deleteTime = new Date(expireTime + this.props.retentionTime); @@ -703,7 +703,7 @@ class EditableTitle extends React.Component { } onKeyUp(event) { - if ((event.key || event.code) == "Escape") { + if ((event.key || event.code) === "Escape") { this.setState({isEditing: false}); } } diff --git a/server/src/pages/shotindex/controller.js b/server/src/pages/shotindex/controller.js index 298fb4aa34..332d01d0b8 100644 --- a/server/src/pages/shotindex/controller.js +++ b/server/src/pages/shotindex/controller.js @@ -177,7 +177,7 @@ function refreshModel() { req.open("GET", url); req.onload = function() { document.body.classList.remove("search-results-loading"); - if (req.status != 200) { + if (req.status !== 200) { console.warn("Error refreshing:", req.status, req); return; } @@ -194,7 +194,7 @@ document.addEventListener("contextmenu", (event) => { let place = "background"; let node = event.target; while (node) { - if (node.nodeType != document.ELEMENT_NODE) { + if (node.nodeType !== document.ELEMENT_NODE) { node = node.parentNode; continue; } @@ -202,7 +202,7 @@ document.addEventListener("contextmenu", (event) => { place = "shot-tile"; break; } - if (node.tagName == "FORM") { + if (node.tagName === "FORM") { place = "search"; break; } diff --git a/server/src/reactrender.js b/server/src/reactrender.js index 91662eb213..6bde58c5a1 100644 --- a/server/src/reactrender.js +++ b/server/src/reactrender.js @@ -30,7 +30,7 @@ exports.render = function(req, res, page) { userLocales: req.userLocales, messages: req.messages }, serverModel); - if (req.query.data == "json") { + if (req.query.data === "json") { if (req.query.pretty !== undefined) { res.type("json").send(JSON.stringify(jsonModel, null, ' ')); } else { diff --git a/server/src/reactruntime.js b/server/src/reactruntime.js index d1f8eed9eb..4fe3fcec76 100644 --- a/server/src/reactruntime.js +++ b/server/src/reactruntime.js @@ -116,7 +116,7 @@ exports.Page = class Page { const renderBody = () => { const body = this.BodyFactory(model); const curTitle = document.title; - if (model.title && model.title != curTitle) { + if (model.title && model.title !== curTitle) { document.title = model.title; } ReactDOM.render( diff --git a/server/src/server.js b/server/src/server.js index ad8d0f1cf6..7ae675b01e 100644 --- a/server/src/server.js +++ b/server/src/server.js @@ -220,7 +220,7 @@ app.use(function(req, res, next) { if (Object.keys(abTests).length) { // Only send if there's some test const newEncodedAbTests = b64EncodeJson(abTests); - if (encodedAbTests != newEncodedAbTests) { + if (encodedAbTests !== newEncodedAbTests) { cookies.set("abtests", newEncodedAbTests, {signed: true, sameSite: 'lax', maxAge: COOKIE_EXPIRE_TIME}); } } else if (Object.keys(origAbTests).length) { @@ -271,15 +271,15 @@ function decodeAuthHeader(header) { const abTestsEncodedSig = match[4]; if (!keygrip.verify(deviceId, deviceIdSig)) { const exc = new Error("deviceId signature incorrect"); - exc.deviceIdLength = typeof deviceId == "string" ? deviceId.length : String(deviceId); - exc.deviceIdSigLength = typeof deviceIdSig == "string" ? deviceIdSig.length : String(deviceIdSig); + exc.deviceIdLength = typeof deviceId === "string" ? deviceId.length : String(deviceId); + exc.deviceIdSigLength = typeof deviceIdSig === "string" ? deviceIdSig.length : String(deviceIdSig); captureRavenException(exc); return {}; } if (!keygrip.verify(abTestsEncoded, abTestsEncodedSig)) { const exc = new Error("abTests signature incorrect"); - exc.abTestsEncodedLength = typeof abTestsEncoded == "string" ? abTestsEncoded.length : String(abTestsEncoded); - exc.abTestsEncodedSigLength = typeof abTestsEncodedSig == "string" ? abTestsEncodedSig.length : String(abTestsEncodedSig); + exc.abTestsEncodedLength = typeof abTestsEncoded === "string" ? abTestsEncoded.length : String(abTestsEncoded); + exc.abTestsEncodedSigLength = typeof abTestsEncodedSig === "string" ? abTestsEncodedSig.length : String(abTestsEncodedSig); captureRavenException(exc); return {}; } @@ -400,7 +400,7 @@ app.post("/error", function(req, res) { let desc = bodyObj.name; const attrs = []; for (const attr in bodyObj) { - if (attr == "name" || attr == "help" || attr == "version") { + if (attr === "name" || attr === "help" || attr === "version") { continue; } let value = "" + bodyObj[attr]; @@ -569,7 +569,7 @@ app.post("/api/register", function(req, res) { function sendAuthInfo(req, res, params) { const { deviceId, accountId, userAbTests } = params; - if (deviceId.search(/^[a-zA-Z0-9_-]{1,255}$/) == -1) { + if (deviceId.search(/^[a-zA-Z0-9_-]{1,255}$/) === -1) { const exc = new Error("Bad deviceId in login"); exc.deviceId = deviceId; captureRavenException(exc, req); @@ -698,7 +698,7 @@ app.put("/data/:id/:domain", const clipId = Object.getOwnPropertyNames(bodyObj.clips)[0]; let b64 = req.files.blob[0].buffer.toString("base64"); let contentType = req.files.blob[0].mimetype; - if (contentType != "image/png" && contentType != "image/jpeg") { + if (contentType !== "image/png" && contentType !== "image/jpeg") { // Force PNG as a fallback mozlog.warn("invalid-upload-content-type", {contentType}); contentType = "image/png"; @@ -713,7 +713,7 @@ app.put("/data/:id/:domain", } else if (req.body) { bodyObj = req.body; } - if (typeof bodyObj != "object") { + if (typeof bodyObj !== "object") { throw new Error(`Got unexpected req.body type: ${typeof bodyObj}`); } const shotId = `${req.params.id}/${req.params.domain}`; @@ -956,7 +956,7 @@ app.get("/images/:imageid", function(req, res) { }).send(); } let contentType = obj.contentType; - if (contentType != "image/png" && contentType != "image/jpeg") { + if (contentType !== "image/png" && contentType !== "image/jpeg") { contentType = "image/png"; } res.header("Content-Type", contentType); diff --git a/server/src/servershot.js b/server/src/servershot.js index 8b3e7308f2..171a80c1ef 100644 --- a/server/src/servershot.js +++ b/server/src/servershot.js @@ -220,7 +220,7 @@ class Shot extends AbstractShot { }).then(() => { return oks; }).catch((err) => { - if (err.code == '23505') { + if (err.code === '23505') { // This is a duplicate key error, means the insert failed clipRewrites.revertShotUrls(); return false; @@ -632,7 +632,7 @@ Shot.setExpiration = function(backend, shotId, deviceId, expiration, accountId) [shotId, id] ); } - if (typeof expiration != "number") { + if (typeof expiration !== "number") { throw new Error("Bad expiration type"); } else if (expiration < 0) { throw new Error("Expiration less than zero"); @@ -740,7 +740,7 @@ const ClipRewrites = class ClipRewrites { this.toInsertClipIds.push(clip.id); let extension = ".png"; const type = clip.image.type || "png"; - if (type == "jpeg") { + if (type === "jpeg") { extension = ".jpg"; } const imageId = uuid.v4() + extension; diff --git a/server/src/share-buttons.js b/server/src/share-buttons.js index 23486f89b5..79501e43bc 100644 --- a/server/src/share-buttons.js +++ b/server/src/share-buttons.js @@ -23,7 +23,7 @@ exports.ShareButton = class ShareButton extends React.Component { isExtInstalled={this.props.isExtInstalled} />; } - const useNewIcon = this.props.abTests.shotShareIcon && this.props.abTests.shotShareIcon.value == "newicon"; + const useNewIcon = this.props.abTests.shotShareIcon && this.props.abTests.shotShareIcon.value === "newicon"; const shareClasses = classnames("button", "transparent", "share", { "active": this.state.display, "inactive": !this.state.display, @@ -199,7 +199,7 @@ class ShareButtonPanel extends React.Component { } keyMaybeClose(event) { - if ((event.key || event.code) == "Escape") { + if ((event.key || event.code) === "Escape") { this.props.closePanel(); } } @@ -207,7 +207,7 @@ class ShareButtonPanel extends React.Component { /* Returns true if the element is part of the share panel */ isPanel(el) { while (el) { - if (el.id == "share-buttons-panel") { + if (el.id === "share-buttons-panel") { return true; } el = el.parentNode; diff --git a/server/src/users.js b/server/src/users.js index 2e63cb653a..8e797cda7c 100644 --- a/server/src/users.js +++ b/server/src/users.js @@ -11,18 +11,18 @@ function hashMatches(hash, secret) { if (parts[0] !== "shaHmac") { throw new Error("Unknown type of hash"); } - if (parts.length != 3) { + if (parts.length !== 3) { throw new Error("Bad hash format, should be type:nonce:data"); } const expected = createHash(secret, parts[1]); - return expected == hash; + return expected === hash; } function createHash(secret, nonce) { if (!nonce) { nonce = createNonce(); } - if (nonce.search(/^[0-9a-zA-Z]+$/) == -1) { + if (nonce.search(/^[0-9a-zA-Z]+$/) === -1) { throw new Error("Bad nonce"); } const hmac = crypto.createHmac("sha256", nonce); diff --git a/shared/shot.js b/shared/shot.js index e153f9b1b3..33b1f42f70 100644 --- a/shared/shot.js +++ b/shared/shot.js @@ -53,7 +53,7 @@ function isSecureWebUri(url) { function assertOrigin(url) { assertUrl(url); - if (url.search(/^https?:/i) != -1) { + if (url.search(/^https?:/i) !== -1) { const match = (/^https?:\/\/[^/:]{1,4000}\/?$/i).exec(url); if (!match) { throw new Error("Bad origin, might include path"); @@ -65,7 +65,7 @@ function originFromUrl(url) { if (!url) { return null; } - if (url.search(/^https?:/i) == -1) { + if (url.search(/^https?:/i) === -1) { // Non-HTTP URLs don't have an origin return null; } @@ -79,7 +79,7 @@ function originFromUrl(url) { /** Check if the given object has all of the required attributes, and no extra attributes exception those in optional */ function checkObject(obj, required, optional) { - if (typeof obj != "object" || obj === null) { + if (typeof obj !== "object" || obj === null) { throw new Error("Cannot check non-object: " + (typeof obj) + " that is " + JSON.stringify(obj)); } required = required || []; @@ -90,7 +90,7 @@ function checkObject(obj, required, optional) { } optional = optional || []; for (const attr in obj) { - if (required.indexOf(attr) == -1 && optional.indexOf(attr) == -1) { + if (required.indexOf(attr) === -1 && optional.indexOf(attr) === -1) { return false; } } @@ -119,7 +119,7 @@ function jsonify(obj, required, optional) { function resolveUrl(base, url) { // FIXME: totally ad hoc and probably incorrect, but we can't // use any libraries in this file - if (url.search(/^https?:/) != -1) { + if (url.search(/^https?:/) !== -1) { // Absolute url return url; } @@ -154,14 +154,14 @@ function deepEqual(a, b) { if ((a === null || a === undefined) && (b === null || b === undefined)) { return true; } - if (typeof a != "object" || typeof b != "object") { + if (typeof a !== "object" || typeof b !== "object") { return a === b; } if (Array.isArray(a)) { if (!Array.isArray(b)) { return false; } - if (a.length != b.length) { + if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { @@ -270,10 +270,10 @@ class AbstractShot { const ALL_ATTRS = ["clips"].concat(this.REGULAR_ATTRS); assert(checkObject(json, [], ALL_ATTRS), "Bad attr to new Shot():", Object.keys(json)); for (const attr in json) { - if (attr == "clips") { + if (attr === "clips") { continue; } - if (typeof json[attr] == "object" && typeof this[attr] == "object" && this[attr] !== null) { + if (typeof json[attr] === "object" && typeof this[attr] === "object" && this[attr] !== null) { let val = this[attr]; if (val.asJson) { val = val.asJson(); @@ -384,7 +384,7 @@ class AbstractShot { const clip = this.getClip(this.clipNames()[0]); let extension = ".png"; if (clip && clip.image && clip.image.type) { - if (clip.image.type == "jpeg") { + if (clip.image.type === "jpeg") { extension = ".jpg"; } } @@ -433,7 +433,7 @@ class AbstractShot { return this._title; } set docTitle(val) { - assert(val === null || typeof val == "string", "Bad docTitle:", val); + assert(val === null || typeof val === "string", "Bad docTitle:", val); this._title = val; } @@ -441,7 +441,7 @@ class AbstractShot { return this._openGraph || null; } set openGraph(val) { - assert(val === null || typeof val == "object", "Bad openGraph:", val); + assert(val === null || typeof val === "object", "Bad openGraph:", val); if (val) { assert(checkObject(val, [], this._OPENGRAPH_PROPERTIES), "Bad attr to openGraph:", Object.keys(val)); this._openGraph = val; @@ -454,7 +454,7 @@ class AbstractShot { return this._twitterCard || null; } set twitterCard(val) { - assert(val === null || typeof val == "object", "Bad twitterCard:", val); + assert(val === null || typeof val === "object", "Bad twitterCard:", val); if (val) { assert(checkObject(val, [], this._TWITTERCARD_PROPERTIES), "Bad attr to twitterCard:", Object.keys(val)); this._twitterCard = val; @@ -467,7 +467,7 @@ class AbstractShot { return this._userTitle; } set userTitle(val) { - assert(val === null || typeof val == "string", "Bad userTitle:", val); + assert(val === null || typeof val === "string", "Bad userTitle:", val); this._userTitle = val; } @@ -489,7 +489,7 @@ class AbstractShot { return this._createdDate; } set createdDate(val) { - assert(val === null || typeof val == "number", "Bad createdDate:", val); + assert(val === null || typeof val === "number", "Bad createdDate:", val); this._createdDate = val; } @@ -556,7 +556,7 @@ class AbstractShot { return this._siteName || null; } set siteName(val) { - assert(typeof val == "string" || !val); + assert(typeof val === "string" || !val); this._siteName = val; } @@ -564,11 +564,11 @@ class AbstractShot { return this._documentSize; } set documentSize(val) { - assert(typeof val == "object" || !val); + assert(typeof val === "object" || !val); if (val) { assert(checkObject(val, ["height", "width"], "Bad attr to documentSize:", Object.keys(val))); - assert(typeof val.height == "number"); - assert(typeof val.width == "number"); + assert(typeof val.height === "number"); + assert(typeof val.width === "number"); this._documentSize = val; } else { this._documentSize = null; @@ -579,7 +579,7 @@ class AbstractShot { return this._thumbnail; } set thumbnail(val) { - assert(typeof val == "string" || !val); + assert(typeof val === "string" || !val); if (val) { assert(isUrl(val)); this._thumbnail = val; @@ -596,10 +596,10 @@ class AbstractShot { this._abTests = null; return; } - assert(typeof val == "object", "abTests should be an object, not:", typeof val); + assert(typeof val === "object", "abTests should be an object, not:", typeof val); assert(!Array.isArray(val), "abTests should not be an Array"); for (const name in val) { - assert(val[name] && typeof val[name] == "string", `abTests.${name} should be a string:`, typeof val[name]); + assert(val[name] && typeof val[name] === "string", `abTests.${name} should be a string:`, typeof val[name]); } this._abTests = val; } @@ -649,12 +649,12 @@ class _Image { assert(isUrl(json.url), "Bad Image url:", json.url); this.url = json.url; assert((!json.dimensions) || - (typeof json.dimensions.x == "number" && typeof json.dimensions.y == "number"), + (typeof json.dimensions.x === "number" && typeof json.dimensions.y === "number"), "Bad Image dimensions:", json.dimensions); this.dimensions = json.dimensions; - assert(typeof json.title == "string" || !json.title, "Bad Image title:", json.title); + assert(typeof json.title === "string" || !json.title, "Bad Image title:", json.title); this.title = json.title; - assert(typeof json.alt == "string" || !json.alt, "Bad Image alt:", json.alt); + assert(typeof json.alt === "string" || !json.alt, "Bad Image alt:", json.alt); this.alt = json.alt; } @@ -670,11 +670,11 @@ class _Clip { constructor(shot, id, json) { this._shot = shot; assert(checkObject(json, ["createdDate", "image"], ["sortOrder"]), "Bad attrs for Clip:", Object.keys(json)); - assert(typeof id == "string" && id, "Bad Clip id:", id); + assert(typeof id === "string" && id, "Bad Clip id:", id); this._id = id; this.createdDate = json.createdDate; if ('sortOrder' in json) { - assert(typeof json.sortOrder == "number" || !json.sortOrder, "Bad Clip sortOrder:", json.sortOrder); + assert(typeof json.sortOrder === "number" || !json.sortOrder, "Bad Clip sortOrder:", json.sortOrder); } if ('sortOrder' in json) { this.sortOrder = json.sortOrder; @@ -701,7 +701,7 @@ class _Clip { return this._createdDate; } set createdDate(val) { - assert(typeof val == "number" || !val, "Bad Clip createdDate:", val); + assert(typeof val === "number" || !val, "Bad Clip createdDate:", val); this._createdDate = val; } @@ -716,35 +716,35 @@ class _Clip { assert(checkObject(image, ["url"], ["dimensions", "text", "location", "captureType", "type"]), "Bad attrs for Clip Image:", Object.keys(image)); assert(isValidClipImageUrl(image.url), "Bad Clip image URL:", image.url); assert( - image.captureType == "madeSelection" || - image.captureType == "selection" || - image.captureType == "visible" || - image.captureType == "auto" || - image.captureType == "fullPage" || - image.captureType == "fullPageTruncated" || + image.captureType === "madeSelection" || + image.captureType === "selection" || + image.captureType === "visible" || + image.captureType === "auto" || + image.captureType === "fullPage" || + image.captureType === "fullPageTruncated" || !image.captureType, "Bad image.captureType:", image.captureType); - assert(typeof image.text == "string" || !image.text, "Bad Clip image text:", image.text); + assert(typeof image.text === "string" || !image.text, "Bad Clip image text:", image.text); if (image.dimensions) { - assert(typeof image.dimensions.x == "number" && typeof image.dimensions.y == "number", "Bad Clip image dimensions:", image.dimensions); + assert(typeof image.dimensions.x === "number" && typeof image.dimensions.y === "number", "Bad Clip image dimensions:", image.dimensions); } if (image.type) { - assert(image.type == "png" || image.type == "jpeg", "Unexpected image type:", image.type); + assert(image.type === "png" || image.type === "jpeg", "Unexpected image type:", image.type); } assert(image.location && - typeof image.location.left == "number" && - typeof image.location.right == "number" && - typeof image.location.top == "number" && - typeof image.location.bottom == "number", "Bad Clip image pixel location:", image.location); + typeof image.location.left === "number" && + typeof image.location.right === "number" && + typeof image.location.top === "number" && + typeof image.location.bottom === "number", "Bad Clip image pixel location:", image.location); if (image.location.topLeftElement || image.location.topLeftOffset || image.location.bottomRightElement || image.location.bottomRightOffset) { - assert(typeof image.location.topLeftElement == "string" && + assert(typeof image.location.topLeftElement === "string" && image.location.topLeftOffset && - typeof image.location.topLeftOffset.x == "number" && - typeof image.location.topLeftOffset.y == "number" && - typeof image.location.bottomRightElement == "string" && + typeof image.location.topLeftOffset.x === "number" && + typeof image.location.topLeftOffset.y === "number" && + typeof image.location.bottomRightElement === "string" && image.location.bottomRightOffset && - typeof image.location.bottomRightOffset.x == "number" && - typeof image.location.bottomRightOffset.y == "number", + typeof image.location.bottomRightOffset.x === "number" && + typeof image.location.bottomRightOffset.y === "number", "Bad Clip image element location:", image.location); } this._image = image; @@ -761,7 +761,7 @@ class _Clip { return this._sortOrder || null; } set sortOrder(val) { - assert(typeof val == "number" || !val, "Bad Clip sortOrder:", val); + assert(typeof val === "number" || !val, "Bad Clip sortOrder:", val); this._sortOrder = val; } @@ -769,7 +769,7 @@ class _Clip { AbstractShot.prototype.Clip = _Clip; -if (typeof exports != "undefined") { +if (typeof exports !== "undefined") { exports.AbstractShot = AbstractShot; exports.originFromUrl = originFromUrl; exports.isValidClipImageUrl = isValidClipImageUrl; diff --git a/shared/thumbnailGenerator.js b/shared/thumbnailGenerator.js index abaeda0295..cf52c96c46 100644 --- a/shared/thumbnailGenerator.js +++ b/shared/thumbnailGenerator.js @@ -138,7 +138,7 @@ function createThumbnailBlobFromPromise(shot, blobToUrlPromise) { }); } -if (typeof exports != "undefined") { +if (typeof exports !== "undefined") { exports.getThumbnailDimensions = getThumbnailDimensions; exports.createThumbnailUrl = createThumbnailUrl; exports.createThumbnailBlobFromPromise = createThumbnailBlobFromPromise; diff --git a/static/js/UITour-lib.js b/static/js/UITour-lib.js index 3e440a683f..7e078b6aa5 100644 --- a/static/js/UITour-lib.js +++ b/static/js/UITour-lib.js @@ -15,7 +15,7 @@ const Mozilla = Mozilla || {}; "use strict"; // create namespace - if (typeof Mozilla.UITour == "undefined") { + if (typeof Mozilla.UITour === "undefined") { /** * Library that exposes an event-based Web API for communicating with the * desktop browser chrome. It can be used for tasks such as opening menu @@ -60,9 +60,9 @@ const Mozilla = Mozilla || {}; const id = _generateCallbackID(); function listener(event) { - if (typeof event.detail != "object") + if (typeof event.detail !== "object") return; - if (event.detail.callbackID != id) + if (event.detail.callbackID !== id) return; document.removeEventListener("mozUITourResponse", listener); @@ -75,9 +75,9 @@ const Mozilla = Mozilla || {}; let notificationListener = null; function _notificationListener(event) { - if (typeof event.detail != "object") + if (typeof event.detail !== "object") return; - if (typeof notificationListener != "function") + if (typeof notificationListener !== "function") return; notificationListener(event.detail.event, event.detail.params); diff --git a/test/test.js b/test/test.js index 93286150af..37696b52ae 100644 --- a/test/test.js +++ b/test/test.js @@ -185,14 +185,14 @@ function expectCreatedShot(driver, creator) { return driver.getAllWindowHandles().then((tabs) => { // On CircleCI there is consistently one weird tab with the id "22" // It's not a normal tab, so we ignore it: - tabs = tabs.filter((t) => t != "22"); + tabs = tabs.filter((t) => t !== "22"); return tabs.length > startingTabCount; }); }); }).then(() => { return driver.getAllWindowHandles(); }).then((tabs) => { - tabs = tabs.filter((t) => t != "22"); + tabs = tabs.filter((t) => t !== "22"); if (tabs.length < startingTabCount) { throw new Error("New tab did not open"); } @@ -200,7 +200,7 @@ function expectCreatedShot(driver, creator) { }).then(() => { return driver.wait(() => { return driver.getCurrentUrl().then((url) => { - return url != "about:blank" && !url.includes("/creating/") + return url !== "about:blank" && !url.includes("/creating/") }); }); }).then(() => { @@ -232,7 +232,7 @@ describe("Test Screenshots", function() { getChromeElement(driver, shooterSelector) .then((button) => button.getAttribute("label")) .then((label) => { - if (label == "Take a Screenshot") { + if (label === "Take a Screenshot") { assert.equal(label, "Take a Screenshot"); } else { assert.equal(label, "Firefox Screenshots");