Bug 1578683 Turn on ESLint rule prefer-boolean-length-check for toolkit and browser r=Standard8
authormonikamaheshwari <monikamaheshwari1996@gmail.com>
Sat, 14 Sep 2019 09:39:26 +0000
changeset 493151 1bbabcc98f008868ead0ad3c969b326147fd9695
parent 493150 fe36492bc1820e6b29954c5877c7f77871780dc2
child 493152 734ba21c24fbbf711b2d4379abc0e48690e612b9
push id36574
push userbtara@mozilla.com
push dateSat, 14 Sep 2019 21:21:09 +0000
treeherdermozilla-central@0765fd605a48 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1578683
milestone71.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1578683 Turn on ESLint rule prefer-boolean-length-check for toolkit and browser r=Standard8 Differential Revision: https://phabricator.services.mozilla.com/D45629
.eslintrc.js
browser/actors/PageStyleChild.jsm
browser/actors/PluginChild.jsm
browser/base/content/aboutNetError.js
browser/base/content/browser-addons.js
browser/base/content/browser-fullScreenAndPointerLock.js
browser/base/content/browser-pageActions.js
browser/base/content/browser-siteProtections.js
browser/base/content/browser-sync.js
browser/base/content/browser-tabsintitlebar.js
browser/base/content/browser.js
browser/base/content/nsContextMenu.js
browser/base/content/pageinfo/security.js
browser/base/content/tabbrowser.js
browser/base/content/test/forms/browser_selectpopup.js
browser/base/content/test/general/browser_contentAreaClick.js
browser/base/content/test/general/browser_contentSearchUI.js
browser/base/content/test/performance/browser_startup_content_mainthreadio.js
browser/base/content/test/performance/browser_startup_flicker.js
browser/base/content/test/plugins/head.js
browser/base/content/test/popupNotifications/browser_popupNotification_4.js
browser/base/content/test/popupNotifications/browser_popupNotification_5.js
browser/base/content/test/popupNotifications/head.js
browser/base/content/test/webextensions/browser_permissions_local_file.js
browser/base/content/test/webextensions/head.js
browser/base/content/test/webrtc/browser_devices_get_user_media_paused.js
browser/base/content/utilityOverlay.js
browser/components/about/AboutPrivateBrowsingHandler.jsm
browser/components/aboutlogins/tests/browser/browser_loginListChanges.js
browser/components/contextualidentity/test/browser/file_reflect_cookie_into_title.html
browser/components/contextualidentity/test/browser/file_set_storages.html
browser/components/customizableui/CustomizableWidgets.jsm
browser/components/customizableui/content/panelUI.js
browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
browser/components/customizableui/test/browser_lwt_telemetry.js
browser/components/downloads/DownloadsCommon.jsm
browser/components/downloads/content/allDownloadsView.js
browser/components/enterprisepolicies/Policies.jsm
browser/components/enterprisepolicies/content/aboutPolicies.js
browser/components/extensions/parent/ext-chrome-settings-overrides.js
browser/components/extensions/parent/ext-menus.js
browser/components/extensions/parent/ext-sessions.js
browser/components/extensions/parent/ext-tabs.js
browser/components/extensions/test/browser/browser_ext_addon_debugging_netmonitor.js
browser/components/extensions/test/browser/browser_ext_browsingData_pluginData.js
browser/components/extensions/test/browser/browser_ext_browsingData_serviceWorkers.js
browser/components/extensions/test/browser/browser_ext_devtools_panel.js
browser/components/extensions/test/browser/browser_ext_sidebarAction_windows.js
browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
browser/components/extensions/test/browser/head.js
browser/components/migration/360seProfileMigrator.jsm
browser/components/migration/ChromeProfileMigrator.jsm
browser/components/migration/EdgeProfileMigrator.jsm
browser/components/migration/IEProfileMigrator.jsm
browser/components/migration/MSMigrationUtils.jsm
browser/components/migration/MigrationUtils.jsm
browser/components/migration/SafariProfileMigrator.jsm
browser/components/migration/tests/unit/test_360se_bookmarks.js
browser/components/migration/tests/unit/test_IE_bookmarks.js
browser/components/migration/tests/unit/test_IE_history.js
browser/components/migration/tests/unit/test_Safari_bookmarks.js
browser/components/newtab/common/Reducers.jsm
browser/components/newtab/content-src/asrouter/templates/StartupOverlay/StartupOverlay.jsx
browser/components/newtab/content-src/asrouter/templates/Trailhead/Trailhead.jsx
browser/components/newtab/content-src/components/DiscoveryStreamBase/DiscoveryStreamBase.jsx
browser/components/newtab/content-src/components/Sections/Sections.jsx
browser/components/newtab/lib/ASRouterTargeting.jsm
browser/components/newtab/lib/CFRPageActions.jsm
browser/components/newtab/lib/PlacesFeed.jsm
browser/components/newtab/lib/ShortURL.jsm
browser/components/newtab/lib/TopStoriesFeed.jsm
browser/components/newtab/test/unit/asrouter/CFRMessageProvider.test.js
browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx
browser/components/originattributes/test/browser/file_windowOpenerRestrictionTarget.html
browser/components/payments/PaymentUIService.jsm
browser/components/payments/res/components/address-option.js
browser/components/payments/res/paymentRequest.js
browser/components/payments/test/mochitest/test_address_form.html
browser/components/payments/test/mochitest/test_basic_card_form.html
browser/components/places/PlacesUIUtils.jsm
browser/components/places/content/browserPlacesViews.js
browser/components/places/content/controller.js
browser/components/places/content/editBookmark.js
browser/components/places/content/places-tree.js
browser/components/places/content/places.js
browser/components/places/content/treeView.js
browser/components/places/tests/browser/browser_paste_into_tags.js
browser/components/places/tests/browser/browser_sort_in_library.js
browser/components/preferences/browserLanguages.js
browser/components/preferences/in-content/findInPage.js
browser/components/preferences/in-content/main.js
browser/components/preferences/in-content/subdialogs.js
browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
browser/components/preferences/in-content/tests/browser_bug410900.js
browser/components/preferences/in-content/tests/browser_cookies_exceptions.js
browser/components/preferences/in-content/tests/browser_permissions_checkPermissionsWereAdded.js
browser/components/preferences/in-content/tests/siteData/head.js
browser/components/preferences/languages.js
browser/components/preferences/siteDataSettings.js
browser/components/search/test/browser/browser_searchTelemetry.js
browser/components/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm
browser/components/sessionstore/SessionStore.jsm
browser/components/sessionstore/test/browser_393716.js
browser/components/sessionstore/test/browser_background_tab_crash.js
browser/components/syncedtabs/TabListView.js
browser/components/translation/TranslationDocument.jsm
browser/components/uitour/UITour.jsm
browser/components/uitour/test/head.js
browser/components/urlbar/UrlbarController.jsm
browser/components/urlbar/UrlbarEventBufferer.jsm
browser/components/urlbar/UrlbarInput.jsm
browser/components/urlbar/UrlbarTokenizer.jsm
browser/components/urlbar/UrlbarView.jsm
browser/components/urlbar/tests/UrlbarTestUtils.jsm
browser/components/urlbar/tests/browser/browser_autocomplete_a11y_label.js
browser/components/urlbar/tests/browser/browser_urlbarCopying.js
browser/components/urlbar/tests/browser/browser_urlbar_speculative_connect_not_with_client_cert.js
browser/extensions/formautofill/FormAutofillHandler.jsm
browser/extensions/formautofill/FormAutofillHeuristics.jsm
browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
browser/extensions/formautofill/content/editDialog.js
browser/extensions/formautofill/test/browser/head.js
browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js
browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js
browser/extensions/pdfjs/test/browser_pdfjs_main.js
browser/modules/AsyncTabSwitcher.jsm
browser/modules/ExtensionsUI.jsm
browser/modules/FaviconLoader.jsm
browser/modules/PermissionUI.jsm
browser/modules/Sanitizer.jsm
browser/modules/WindowsJumpLists.jsm
browser/modules/WindowsPreviewPerTab.jsm
browser/modules/test/browser/browser_PageActions.js
browser/modules/webrtcUI.jsm
toolkit/actors/DateTimePickerChild.jsm
toolkit/actors/PopupBlockingChild.jsm
toolkit/components/aboutmemory/content/aboutMemory.js
toolkit/components/aboutperformance/content/aboutPerformance.js
toolkit/components/antitracking/test/browser/antitracking_head.js
toolkit/components/apppicker/content/appPicker.js
toolkit/components/autocomplete/tests/unit/test_378079.js
toolkit/components/autocomplete/tests/unit/test_393191.js
toolkit/components/autocomplete/tests/unit/test_440866.js
toolkit/components/autocomplete/tests/unit/test_autocomplete_multiple.js
toolkit/components/autocomplete/tests/unit/test_previousResult.js
toolkit/components/backgroundhangmonitor/tests/test_BHRObserver.js
toolkit/components/certviewer/content/certviewer.js
toolkit/components/contentprefs/ContentPrefService2.jsm
toolkit/components/crashes/tests/xpcshell/test_crash_service.js
toolkit/components/ctypes/tests/unit/test_jsctypes.js
toolkit/components/enterprisepolicies/EnterprisePolicies.js
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionChild.jsm
toolkit/components/extensions/ExtensionContent.jsm
toolkit/components/extensions/ExtensionParent.jsm
toolkit/components/extensions/ExtensionPermissions.jsm
toolkit/components/extensions/ExtensionStorageSync.jsm
toolkit/components/extensions/MatchURLFilters.jsm
toolkit/components/extensions/MessageChannel.jsm
toolkit/components/extensions/NativeMessaging.jsm
toolkit/components/extensions/ProxyScriptContext.jsm
toolkit/components/extensions/Schemas.jsm
toolkit/components/extensions/parent/ext-contentScripts.js
toolkit/components/extensions/parent/ext-downloads.js
toolkit/components/extensions/parent/ext-permissions.js
toolkit/components/extensions/test/mochitest/test_chrome_ext_webnavigation_resolved_urls.html
toolkit/components/extensions/test/mochitest/test_ext_activityLog.html
toolkit/components/extensions/test/mochitest/test_ext_async_clipboard.html
toolkit/components/extensions/test/mochitest/test_ext_webrequest_hsts.html
toolkit/components/extensions/test/xpcshell/test_ext_dns.js
toolkit/components/extensions/test/xpcshell/test_ext_downloads_misc.js
toolkit/components/extensions/test/xpcshell/test_ext_incognito.js
toolkit/components/extensions/test/xpcshell/test_ext_proxy_socks.js
toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js
toolkit/components/extensions/test/xpcshell/test_ext_webRequest_urlclassification.js
toolkit/components/extensions/webrequest/WebRequestContent.js
toolkit/components/mozintl/test/test_mozintl_getLocaleDisplayNames.js
toolkit/components/normandy/actions/PreferenceExperimentAction.jsm
toolkit/components/normandy/lib/PreferenceExperiments.jsm
toolkit/components/normandy/test/browser/browser_LogManager.js
toolkit/components/normandy/test/browser/browser_actions_PreferenceExperimentAction.js
toolkit/components/osfile/modules/osfile_async_front.jsm
toolkit/components/osfile/modules/osfile_async_worker.js
toolkit/components/osfile/modules/ospath_unix.jsm
toolkit/components/osfile/modules/ospath_win.jsm
toolkit/components/passwordmgr/LoginHelper.jsm
toolkit/components/passwordmgr/LoginImport.jsm
toolkit/components/passwordmgr/LoginManager.jsm
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/LoginManagerParent.jsm
toolkit/components/passwordmgr/LoginManagerPrompter.jsm
toolkit/components/passwordmgr/LoginRecipes.jsm
toolkit/components/passwordmgr/content/passwordManager.js
toolkit/components/passwordmgr/test/browser/head.js
toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js
toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html
toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
toolkit/components/places/BookmarkHTMLUtils.jsm
toolkit/components/places/BookmarkJSONUtils.jsm
toolkit/components/places/History.jsm
toolkit/components/places/PlacesSyncUtils.jsm
toolkit/components/places/PlacesTransactions.jsm
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/TaggingService.jsm
toolkit/components/places/UnifiedComplete.jsm
toolkit/components/places/tests/PlacesTestUtils.jsm
toolkit/components/places/tests/favicons/test_root_icons.js
toolkit/components/places/tests/head_common.js
toolkit/components/places/tests/history/test_async_history_api.js
toolkit/components/places/tests/history/test_update.js
toolkit/components/places/tests/queries/test_redirects.js
toolkit/components/places/tests/queries/test_results-as-visit.js
toolkit/components/places/tests/unit/test_async_transactions.js
toolkit/components/places/tests/unit/test_bookmarks_html.js
toolkit/components/places/tests/unit/test_bookmarks_json.js
toolkit/components/places/tests/unit/test_null_interfaces.js
toolkit/components/places/tests/unit/test_promiseBookmarksTree.js
toolkit/components/promiseworker/PromiseWorker.jsm
toolkit/components/satchel/FormAutoComplete.jsm
toolkit/components/satchel/InputListAutoComplete.jsm
toolkit/components/satchel/test/satchel_common.js
toolkit/components/satchel/test/unit/test_history_api.js
toolkit/components/search/SearchEngine.jsm
toolkit/components/search/SearchService.jsm
toolkit/components/search/tests/xpcshell/test_SearchStaticData.js
toolkit/components/search/tests/xpcshell/test_notifications.js
toolkit/components/search/tests/xpcshell/test_searchSuggest.js
toolkit/components/search/tests/xpcshell/test_validate_manifests.js
toolkit/components/sessionstore/SessionStoreFunctions.jsm
toolkit/components/telemetry/app/TelemetrySend.jsm
toolkit/components/telemetry/pings/ModulesPing.jsm
toolkit/components/telemetry/pings/TelemetrySession.jsm
toolkit/components/telemetry/tests/browser/browser_HybridContentTelemetry.js
toolkit/components/telemetry/tests/browser/browser_TelemetryGC.js
toolkit/components/telemetry/tests/unit/test_ChildEvents.js
toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
toolkit/components/thumbnails/test/browser_thumbnails_bg_queueing.js
toolkit/components/tooltiptext/TooltipTextProvider.jsm
toolkit/components/url-classifier/UrlClassifierHashCompleter.jsm
toolkit/components/url-classifier/UrlClassifierListManager.jsm
toolkit/components/url-classifier/tests/mochitest/test_classifier.html
toolkit/components/url-classifier/tests/unit/head_urlclassifier.js
toolkit/components/xulstore/old/XULStore.jsm
toolkit/content/aboutNetworking.js
toolkit/content/aboutSupport.js
toolkit/content/aboutTelemetry.js
toolkit/content/aboutUrlClassifier.js
toolkit/content/plugins.js
toolkit/content/tests/widgets/test_videocontrols.html
toolkit/content/tests/widgets/tree_shared.js
toolkit/content/treeUtils.js
toolkit/content/widgets/marquee.js
toolkit/content/widgets/richlistbox.js
toolkit/content/widgets/toolbarbutton.js
toolkit/crashreporter/CrashSubmit.jsm
toolkit/modules/ActorManagerChild.jsm
toolkit/modules/AppMenuNotifications.jsm
toolkit/modules/CertUtils.jsm
toolkit/modules/Console.jsm
toolkit/modules/InlineSpellChecker.jsm
toolkit/modules/NewTabUtils.jsm
toolkit/modules/PopupNotifications.jsm
toolkit/modules/Promise-backend.js
toolkit/modules/ShortcutUtils.jsm
toolkit/modules/Sqlite.jsm
toolkit/modules/Troubleshoot.jsm
toolkit/modules/sessionstore/SessionHistory.jsm
toolkit/modules/subprocess/subprocess_worker_common.js
toolkit/modules/subprocess/subprocess_worker_unix.js
toolkit/modules/tests/chrome/test_findCssSelector.html
toolkit/modules/tests/modules/PromiseTestUtils.jsm
toolkit/modules/tests/xpcshell/test_Promise.js
toolkit/mozapps/downloads/DownloadUtils.jsm
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/Blocklist.jsm
toolkit/mozapps/extensions/content/aboutaddons.js
toolkit/mozapps/extensions/content/aboutaddonsCommon.js
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/shortcuts.js
toolkit/mozapps/extensions/internal/AddonRepository.jsm
toolkit/mozapps/extensions/internal/GMPProvider.jsm
toolkit/mozapps/extensions/internal/XPIDatabase.jsm
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js
toolkit/mozapps/extensions/test/browser/browser_html_list_view.js
toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js
toolkit/mozapps/extensions/test/browser/browser_installssl.js
toolkit/mozapps/extensions/test/browser/browser_updatessl.js
toolkit/mozapps/extensions/test/browser/browser_webapi_install.js
toolkit/mozapps/extensions/test/browser/head.js
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/mozapps/extensions/test/xpcshell/test_addon_manager_telemetry_events.js
toolkit/mozapps/extensions/test/xpcshell/test_plugins.js
toolkit/mozapps/extensions/test/xpcshell/test_pref_properties.js
toolkit/mozapps/preferences/fontbuilder.js
toolkit/mozapps/update/UpdateService.jsm
toolkit/mozapps/update/tests/data/sharedUpdateXML.js
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
toolkit/xre/test/test_install_hash.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -331,10 +331,18 @@ module.exports = {
       "toolkit/content/tests/browser/browser_findbar.js",
       "toolkit/modules/NewTabUtils.jsm",
       "toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js",
       "toolkit/mozapps/extensions/test/browser/head.js",
     ],
     "rules": {
       "no-async-promise-executor": "off",
     }
+  },{
+    "files": [
+      "toolkit/**",
+      "browser/**",
+    ],
+    "rules": {
+      "mozilla/prefer-boolean-length-check": "error",
+    }
   }]
 };
--- a/browser/actors/PageStyleChild.jsm
+++ b/browser/actors/PageStyleChild.jsm
@@ -99,17 +99,17 @@ class PageStyleChild extends ActorChild 
     let result = [];
 
     for (let currentStyleSheet of styleSheets) {
       if (!currentStyleSheet.title) {
         continue;
       }
 
       // Skip any stylesheets that don't match the screen media type.
-      if (currentStyleSheet.media.length > 0) {
+      if (currentStyleSheet.media.length) {
         let mediaQueryList = currentStyleSheet.media.mediaText;
         if (!content.matchMedia(mediaQueryList).matches) {
           continue;
         }
       }
 
       let URI;
       try {
--- a/browser/actors/PluginChild.jsm
+++ b/browser/actors/PluginChild.jsm
@@ -330,33 +330,33 @@ class PluginChild extends JSWindowActorC
     let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
     linkNode.addEventListener(
       "click",
       function(evt) {
         if (!evt.isTrusted) {
           return;
         }
         evt.preventDefault();
-        if (callbackArgs.length == 0) {
+        if (!callbackArgs.length) {
           callbackArgs = [evt];
         }
         self[callbackName].apply(self, callbackArgs);
       },
       true
     );
 
     linkNode.addEventListener(
       "keydown",
       function(evt) {
         if (!evt.isTrusted) {
           return;
         }
         if (evt.keyCode == evt.DOM_VK_RETURN) {
           evt.preventDefault();
-          if (callbackArgs.length == 0) {
+          if (!callbackArgs.length) {
             callbackArgs = [evt];
           }
           evt.preventDefault();
           self[callbackName].apply(self, callbackArgs);
         }
       },
       true
     );
@@ -798,17 +798,17 @@ class PluginChild extends JSWindowActorC
     if (pluginElOrTag === null) {
       // cwu.plugins may contain non-plugin <object>s, filter them out
       plugins = this.contentWindow.windowUtils.plugins.filter(
         p =>
           p.getContentTypeForMIMEType(p.actualType) ==
           Ci.nsIObjectLoadingContent.TYPE_PLUGIN
       );
 
-      if (plugins.length == 0) {
+      if (!plugins.length) {
         this.removeNotification();
         return;
       }
     } else {
       plugins = [pluginElOrTag];
     }
 
     // Iterate over the plugins and ensure we have one value for each
--- a/browser/base/content/aboutNetError.js
+++ b/browser/base/content/aboutNetError.js
@@ -858,17 +858,17 @@ function setTechnicalDetailsOnCertError(
       default:
         setL10NLabel("cert-error-intro", args);
         setL10NLabel("cert-error-untrusted-default", {}, {}, false);
     }
   }
 
   if (failedCertInfo.isDomainMismatch) {
     let subjectAltNames = failedCertInfo.subjectAltNames.split(",");
-    subjectAltNames = subjectAltNames.filter(name => name.length > 0);
+    subjectAltNames = subjectAltNames.filter(name => !!name.length);
     let numSubjectAltNames = subjectAltNames.length;
 
     if (numSubjectAltNames != 0) {
       if (numSubjectAltNames == 1) {
         args["alt-name"] = subjectAltNames[0];
 
         // Let's check if we want to make this a link.
         let okHost = failedCertInfo.subjectAltNames;
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -296,17 +296,17 @@ var gXPInstallObserver = {
 
       showNextConfirmation();
     };
 
     let unsigned = installInfo.installs.filter(
       i => i.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING
     );
     let someUnsigned =
-      unsigned.length > 0 && unsigned.length < installInfo.installs.length;
+      !!unsigned.length && unsigned.length < installInfo.installs.length;
 
     options.eventCallback = aEvent => {
       switch (aEvent) {
         case "removed":
           cancelInstallation();
           break;
         case "shown":
           let addonList = document.getElementById(
@@ -356,17 +356,17 @@ var gXPInstallObserver = {
     );
     if (unsigned.length == installInfo.installs.length) {
       // None of the add-ons are verified
       messageString = gNavigatorBundle.getString(
         "addonConfirmInstallUnsigned.message"
       );
       notification.setAttribute("warning", "true");
       options.learnMoreURL += "unsigned-addons";
-    } else if (unsigned.length == 0) {
+    } else if (!unsigned.length) {
       // All add-ons are verified or don't need to be verified
       messageString = gNavigatorBundle.getString("addonConfirmInstall.message");
       notification.removeAttribute("warning");
       options.learnMoreURL += "find-and-install-add-ons";
     } else {
       // Some of the add-ons are unverified, the list of names will indicate
       // which
       messageString = gNavigatorBundle.getString(
@@ -445,17 +445,17 @@ var gXPInstallObserver = {
    */
   removeAllNotifications(browser) {
     let notifications = this.NOTIFICATION_IDS.map(id =>
       PopupNotifications.getNotification(id, browser)
     ).filter(notification => notification != null);
 
     PopupNotifications.remove(notifications, true);
 
-    return notifications.length > 0;
+    return !!notifications.length;
   },
 
   logWarningFullScreenInstallBlocked() {
     // If notifications have been removed, log a warning to the website console
     let consoleMsg = Cc["@mozilla.org/scripterror;1"].createInstance(
       Ci.nsIScriptError
     );
     let message = gBrowserBundle.GetStringFromName(
--- a/browser/base/content/browser-fullScreenAndPointerLock.js
+++ b/browser/base/content/browser-fullScreenAndPointerLock.js
@@ -431,17 +431,17 @@ var FullScreen = {
   },
 
   _handlePermPromptShow() {
     if (
       !FullScreen.permissionsFullScreenAllowed &&
       window.fullScreen &&
       PopupNotifications.getNotification(
         this._permissionNotificationIDs
-      ).filter(n => !n.dismissed).length > 0
+      ).filter(n => !n.dismissed).length
     ) {
       this.exitDomFullScreen();
       this._logWarningPermissionPromptFS("fullScreenCanceled");
     }
   },
 
   receiveMessage(aMessage) {
     let browser = aMessage.target;
@@ -508,17 +508,17 @@ var FullScreen = {
     }
 
     // Remove permission prompts when entering full-screen.
     if (!FullScreen.permissionsFullScreenAllowed) {
       let notifications = PopupNotifications.getNotification(
         this._permissionNotificationIDs
       ).filter(n => !n.dismissed);
       PopupNotifications.remove(notifications, true);
-      if (notifications.length > 0) {
+      if (notifications.length) {
         this._logWarningPermissionPromptFS("promptCanceled");
       }
     }
 
     document.documentElement.setAttribute("inDOMFullscreen", true);
 
     if (gFindBarInitialized) {
       gFindBar.close(true);
--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -1304,17 +1304,17 @@ BrowserPageActions.shareURL = {
     BrowserPageActions.takeActionTitleFromPanel(action);
   },
 
   onShowingSubview(panelViewNode) {
     let bodyNode = panelViewNode.querySelector(".panel-subview-body");
 
     // We cache the providers + the UI if the user selects the share
     // panel multiple times while the panel is open.
-    if (this._cached && bodyNode.children.length > 0) {
+    if (this._cached && bodyNode.children.length) {
       return;
     }
 
     let sharingService = this._sharingService;
     let url = gBrowser.selectedBrowser.currentURI;
     let currentURI = gURLBar.makeURIReadable(url).displaySpec;
     let shareProviders = sharingService.getSharingProviders(currentURI);
     let fragment = document.createDocumentFragment();
--- a/browser/base/content/browser-siteProtections.js
+++ b/browser/base/content/browser-siteProtections.js
@@ -411,17 +411,17 @@ var TrackingProtection = {
     }
 
     // If we don't have trackers we would usually not show the menu item
     // allowing the user to show the sub-panel. However, in the edge case
     // that we annotated trackers on the page using the strict list but did
     // not detect trackers on the page using the basic list, we currently
     // still show the panel. To reduce the confusion, tell the user that we have
     // not detected any tracker.
-    if (fragment.childNodes.length == 0) {
+    if (!fragment.childNodes.length) {
       let emptyBox = document.createXULElement("vbox");
       let emptyImage = document.createXULElement("image");
       emptyImage.classList.add("protections-popup-trackersView-empty-image");
       emptyImage.classList.add("tracking-protection-icon");
 
       let emptyLabel = document.createXULElement("label");
       emptyLabel.classList.add("protections-popup-empty-label");
       emptyLabel.textContent = gNavigatorBundle.getString(
--- a/browser/base/content/browser-sync.js
+++ b/browser/base/content/browser-sync.js
@@ -790,17 +790,17 @@ var gSync = {
       // We can only be in this case in the page action menu.
       return;
     }
 
     const fragment = document.createDocumentFragment();
 
     const state = UIState.get();
     if (state.status == UIState.STATUS_SIGNED_IN) {
-      if (this.sendTabTargets.length > 0) {
+      if (this.sendTabTargets.length) {
         this._appendSendTabDeviceList(
           fragment,
           createDeviceNodeFn,
           url,
           title,
           multiselected
         );
       } else {
--- a/browser/base/content/browser-tabsintitlebar.js
+++ b/browser/base/content/browser-tabsintitlebar.js
@@ -69,17 +69,17 @@ var TabsInTitlebar;
     _update() {
       if (!this._initialized) {
         return;
       }
 
       let allowed =
         this.systemSupported &&
         !window.fullScreen &&
-        Object.keys(this._disallowed).length == 0;
+        !Object.keys(this._disallowed).length;
       if (allowed) {
         document.documentElement.setAttribute("tabsintitlebar", "true");
         if (AppConstants.platform == "macosx") {
           document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
           document.documentElement.removeAttribute("drawtitle");
         } else {
           document.documentElement.setAttribute("chromemargin", "0,2,2,2");
         }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3877,17 +3877,17 @@ function BrowserReloadWithFlags(reloadFl
         remoteType: E10SUtils.DEFAULT_REMOTE_TYPE,
       });
       loadBrowserURI(browser, url);
     } else {
       unchangedRemoteness.push(tab);
     }
   }
 
-  if (unchangedRemoteness.length == 0) {
+  if (!unchangedRemoteness.length) {
     return;
   }
 
   // Reset temporary permissions on the remaining tabs to reload.
   // This is done here because we only want to reset
   // permissions on user reload.
   for (let tab of unchangedRemoteness) {
     SitePermissions.clearTemporaryPermissions(tab.linkedBrowser);
@@ -4682,17 +4682,17 @@ const BrowserSearch = {
     BrowserPageActions.addSearchEngine.updateEngines();
 
     var searchBar = this.searchBar;
     if (!searchBar) {
       return;
     }
 
     var engines = gBrowser.selectedBrowser.engines;
-    if (engines && engines.length > 0) {
+    if (engines && engines.length) {
       searchBar.setAttribute("addengines", "true");
     } else {
       searchBar.removeAttribute("addengines");
     }
   },
 
   /**
    * Focuses the search bar if present on the toolbar, or the address bar,
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -320,17 +320,17 @@ nsContextMenu.prototype = {
       this.actor = this.browser.browsingContext.currentWindowGlobal.getActor(
         "ContextMenu"
       );
     }
 
     const { gBrowser } = this.browser.ownerGlobal;
 
     this.textSelected = this.selectionInfo.text;
-    this.isTextSelected = this.textSelected.length != 0;
+    this.isTextSelected = !!this.textSelected.length;
     this.webExtBrowserType = this.browser.getAttribute(
       "webextension-view-type"
     );
     this.inWebExtBrowser = !!this.webExtBrowserType;
     this.inTabBrowser =
       gBrowser && gBrowser.getTabForBrowser
         ? !!gBrowser.getTabForBrowser(this.browser)
         : false;
--- a/browser/base/content/pageinfo/security.js
+++ b/browser/base/content/pageinfo/security.js
@@ -178,17 +178,17 @@ var security = {
       document.l10n.setAttributes(siteDataLabel, "security-site-data-no");
       clearSiteDataButton.setAttribute("disabled", "true");
       return;
     }
 
     let usage = this.siteData.reduce((acc, site) => acc + site.usage, 0);
     if (usage > 0) {
       let size = DownloadUtils.convertByteUnits(usage);
-      let hasCookies = this.siteData.some(site => site.cookies.length > 0);
+      let hasCookies = this.siteData.some(site => !!site.cookies.length);
       if (hasCookies) {
         document.l10n.setAttributes(
           siteDataLabel,
           "security-site-data-cookies",
           { value: size[0], unit: size[1] }
         );
       } else {
         document.l10n.setAttributes(siteDataLabel, "security-site-data-only", {
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -3315,21 +3315,17 @@
           // We've already called beforeunload on all the relevant tabs if we get here,
           // so avoid calling it again:
           window.skipNextCanClose = true;
         }
 
         // Closing the tab and replacing it with a blank one is notably slower
         // than closing the window right away. If the caller opts in, take
         // the fast path.
-        if (
-          closeWindow &&
-          closeWindowFastpath &&
-          this._removingTabs.length == 0
-        ) {
+        if (closeWindow && closeWindowFastpath && !this._removingTabs.length) {
           // This call actually closes the window, unless the user
           // cancels the operation.  We are finished here in both cases.
           this._windowIsClosing = window.closeWindow(
             true,
             window.warnAboutClosingWindow
           );
           return false;
         }
@@ -6274,18 +6270,19 @@ var TabContextMenu = {
       "context_duplicateTab"
     ).hidden = multiselectionContext;
     document.getElementById(
       "context_duplicateTabs"
     ).hidden = !multiselectionContext;
 
     // Disable "Close Tabs to the Right" if there are no tabs
     // following it.
-    document.getElementById("context_closeTabsToTheEnd").disabled =
-      gBrowser.getTabsToTheEndFrom(this.contextTab).length == 0;
+    document.getElementById(
+      "context_closeTabsToTheEnd"
+    ).disabled = !gBrowser.getTabsToTheEndFrom(this.contextTab).length;
 
     // Disable "Close other Tabs" if there are no unpinned tabs.
     let unpinnedTabsToClose = multiselectionContext
       ? gBrowser.visibleTabs.filter(t => !t.multiselected && !t.pinned).length
       : gBrowser.visibleTabs.filter(t => t != this.contextTab && !t.pinned)
           .length;
     document.getElementById("context_closeOtherTabs").disabled =
       unpinnedTabsToClose < 1;
--- a/browser/base/content/test/forms/browser_selectpopup.js
+++ b/browser/base/content/test/forms/browser_selectpopup.js
@@ -792,17 +792,17 @@ async function performLargePopupTests(wi
       "Popup top position in within browser area"
     );
     ok(
       rect.bottom <= browserRect.bottom,
       "Popup bottom position in within browser area"
     );
 
     // Don't check the scroll position for the last step as the popup will be cut off.
-    if (positions.length > 0) {
+    if (positions.length) {
       let cs = win.getComputedStyle(selectPopup);
       let bpBottom =
         parseFloat(cs.paddingBottom) + parseFloat(cs.borderBottomWidth);
       let selectedOption = 60;
 
       if (Services.prefs.getBoolPref("dom.forms.selectSearch")) {
         // Use option 61 instead of 60, as the 60th option element is actually the
         // 61st child, since the first child is now the search input field.
--- a/browser/base/content/test/general/browser_contentAreaClick.js
+++ b/browser/base/content/test/general/browser_contentAreaClick.js
@@ -286,21 +286,21 @@ function setupTestBrowserWindow() {
 }
 
 function runNextTest() {
   if (!gCurrentTest) {
     gCurrentTest = gTests.shift();
     gCurrentTest.setup();
   }
 
-  if (gCurrentTest.targets.length == 0) {
+  if (!gCurrentTest.targets.length) {
     info(gCurrentTest.desc + ": cleaning up...");
     gCurrentTest.clean();
 
-    if (gTests.length > 0) {
+    if (gTests.length) {
       gCurrentTest = gTests.shift();
       gCurrentTest.setup();
     } else {
       finishTest();
       return;
     }
   }
 
--- a/browser/base/content/test/general/browser_contentSearchUI.js
+++ b/browser/base/content/test/general/browser_contentSearchUI.js
@@ -741,20 +741,20 @@ function checkState(
   let expectedState = {
     selectedIndex: expectedSelectedIdx,
     numSuggestions: expectedSuggestions.length,
     suggestionAtIndex: expectedSuggestions.map(s => s.str),
     isFormHistorySuggestionAtIndex: expectedSuggestions.map(
       s => s.type == "formHistory"
     ),
 
-    tableHidden: expectedSuggestions.length == 0,
+    tableHidden: !expectedSuggestions.length,
 
     inputValue: expectedInputVal,
-    ariaExpanded: expectedSuggestions.length == 0 ? "false" : "true",
+    ariaExpanded: !expectedSuggestions.length ? "false" : "true",
   };
   if (expectedSelectedButtonIdx != undefined) {
     expectedState.selectedButtonIndex = expectedSelectedButtonIdx;
   } else if (expectedSelectedIdx < expectedSuggestions.length) {
     expectedState.selectedButtonIndex = -1;
   } else {
     expectedState.selectedButtonIndex =
       expectedSelectedIdx - expectedSuggestions.length;
--- a/browser/base/content/test/performance/browser_startup_content_mainthreadio.js
+++ b/browser/base/content/test/performance/browser_startup_content_mainthreadio.js
@@ -395,17 +395,17 @@ add_task(async function() {
 
     if (!whitelist.length) {
       continue;
     }
     // The I/O interposer is disabled if !RELEASE_OR_BETA, so we expect to have
     // no I/O marker in that case, but it's good to keep the test running to check
     // that we are still able to produce startup profiles.
     is(
-      markers.length > 0,
+      !!markers.length,
       !AppConstants.RELEASE_OR_BETA,
       procName +
         " startup profiles should have IO markers in builds that are not RELEASE_OR_BETA"
     );
     if (!markers.length) {
       // If a profile unexpectedly contains no I/O marker, avoid generating
       // plenty of confusing "unused whitelist entry" failures.
       continue;
--- a/browser/base/content/test/performance/browser_startup_flicker.js
+++ b/browser/base/content/test/performance/browser_startup_flicker.js
@@ -11,17 +11,17 @@
 add_task(async function() {
   let startupRecorder = Cc["@mozilla.org/test/startuprecorder;1"].getService()
     .wrappedJSObject;
   await startupRecorder.done;
 
   // Ensure all the frame data is in the test compartment to avoid traversing
   // a cross compartment wrapper for each pixel.
   let frames = Cu.cloneInto(startupRecorder.data.frames, {});
-  ok(frames.length > 0, "Should have captured some frames.");
+  ok(!!frames.length, "Should have captured some frames.");
 
   let unexpectedRects = 0;
   let alreadyFocused = false;
   for (let i = 1; i < frames.length; ++i) {
     let frame = frames[i],
       previousFrame = frames[i - 1];
     let rects = compareFrames(frame, previousFrame);
 
--- a/browser/base/content/test/plugins/head.js
+++ b/browser/base/content/test/plugins/head.js
@@ -466,13 +466,13 @@ function promiseForNotificationShown(not
  */
 function promiseUpdatePluginBindings(browser) {
   return ContentTask.spawn(browser, {}, async function() {
     let doc = content.document;
     let elems = doc.getElementsByTagName("embed");
     if (!elems || elems.length < 1) {
       elems = doc.getElementsByTagName("object");
     }
-    if (elems && elems.length > 0) {
+    if (elems && elems.length) {
       elems[0].clientTop;
     }
   });
 }
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
@@ -128,17 +128,17 @@ var tests = [
 
       let promiseWin = BrowserTestUtils.waitForNewWindow();
       gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
       let win = await promiseWin;
 
       let anchor = win.document.getElementById("default-notification-icon");
       win.PopupNotifications._reshowNotifications(anchor);
       ok(
-        win.PopupNotifications.panel.children.length == 0,
+        !win.PopupNotifications.panel.children.length,
         "no notification displayed in new window"
       );
       ok(
         notifyObj.swappingCallbackTriggered,
         "the swapping callback was triggered"
       );
       ok(
         notifyObj.removedCallbackTriggered,
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_5.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_5.js
@@ -242,17 +242,17 @@ var tests = [
 
       let promiseWin = BrowserTestUtils.waitForNewWindow();
       gBrowser.replaceTabWithWindow(firstTab);
       let win = await promiseWin;
 
       let anchor = win.document.getElementById("default-notification-icon");
       win.PopupNotifications._reshowNotifications(anchor);
       ok(
-        win.PopupNotifications.panel.children.length == 0,
+        !win.PopupNotifications.panel.children.length,
         "no notification displayed in new window"
       );
 
       await BrowserTestUtils.closeWindow(win);
       await waitForWindowReadyForPopupNotifications(window);
 
       let id = PopupNotifications.panel.firstElementChild.getAttribute(
         "popupid"
--- a/browser/base/content/test/popupNotifications/head.js
+++ b/browser/base/content/test/popupNotifications/head.js
@@ -64,17 +64,17 @@ function setup() {
   });
 }
 
 function goNext() {
   executeSoon(() => executeSoon(runNextTest));
 }
 
 async function runNextTest() {
-  if (tests.length == 0) {
+  if (!tests.length) {
     executeSoon(finish);
     return;
   }
 
   let nextTest = tests.shift();
   if (nextTest.onShown) {
     let shownState = false;
     onPopupEvent("popupshowing", function() {
@@ -241,17 +241,17 @@ function checkPopup(popup, notifyObj) {
       "main action accesskey matches"
     );
     is(
       notification.hasAttribute("buttonhighlight"),
       !notifyObj.mainAction.disableHighlight,
       "main action highlight matches"
     );
   }
-  if (notifyObj.secondaryActions && notifyObj.secondaryActions.length > 0) {
+  if (notifyObj.secondaryActions && notifyObj.secondaryActions.length) {
     let secondaryAction = notifyObj.secondaryActions[0];
     is(
       notification.getAttribute("secondarybuttonlabel"),
       secondaryAction.label,
       "secondary action label matches"
     );
     is(
       notification.getAttribute("secondarybuttonaccesskey"),
@@ -325,25 +325,25 @@ function waitForNotificationPanelHidden(
     onPopupEvent("popuphidden", function() {
       resolve(this);
     });
   });
 }
 
 function triggerMainCommand(popup) {
   let notifications = popup.childNodes;
-  ok(notifications.length > 0, "at least one notification displayed");
+  ok(!!notifications.length, "at least one notification displayed");
   let notification = notifications[0];
   info("Triggering main command for notification " + notification.id);
   EventUtils.synthesizeMouseAtCenter(notification.button, {});
 }
 
 function triggerSecondaryCommand(popup, index) {
   let notifications = popup.childNodes;
-  ok(notifications.length > 0, "at least one notification displayed");
+  ok(!!notifications.length, "at least one notification displayed");
   let notification = notifications[0];
   info("Triggering secondary command for notification " + notification.id);
 
   if (index == 0) {
     EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
     return;
   }
 
--- a/browser/base/content/test/webextensions/browser_permissions_local_file.js
+++ b/browser/base/content/test/webextensions/browser_permissions_local_file.js
@@ -46,17 +46,17 @@ add_task(async function test_install_ext
   // Check the telemetry.
   let snapshot = Services.telemetry.snapshotEvents(
     Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
     true
   );
 
   // Make sure we got some data.
   ok(
-    snapshot.parent && snapshot.parent.length > 0,
+    snapshot.parent && !!snapshot.parent.length,
     "Got parent telemetry events in the snapshot"
   );
 
   // Only look at the related events after stripping the timestamp and category.
   let relatedEvents = snapshot.parent
     .filter(
       ([timestamp, category, method, object]) =>
         category == "addonsManager" &&
--- a/browser/base/content/test/webextensions/head.js
+++ b/browser/base/content/test/webextensions/head.js
@@ -250,17 +250,17 @@ function checkNotification(panel, checkI
     is(icon, checkIcon, "Notification icon is correct");
   }
 
   is(
     ul.childElementCount,
     permissions.length,
     `Permissions list has ${permissions.length} entries`
   );
-  if (permissions.length == 0) {
+  if (!permissions.length) {
     is(header.getAttribute("hidden"), "true", "Permissions header is hidden");
     is(
       learnMoreLink.getAttribute("hidden"),
       "true",
       "Permissions learn more is hidden"
     );
   } else {
     is(header.getAttribute("hidden"), "", "Permissions header is visible");
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_paused.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_paused.js
@@ -40,17 +40,17 @@ function stopClonedTracks(audio, video) 
     let clones = content.wrappedJSObject.gClones || [];
     if (args.audio != null) {
       clones.filter(t => t.kind == "audio").forEach(t => t.stop());
     }
     if (args.video != null) {
       clones.filter(t => t.kind == "video").forEach(t => t.stop());
     }
     let liveClones = clones.filter(t => t.readyState == "live");
-    if (liveClones.length == 0) {
+    if (!liveClones.length) {
       delete content.wrappedJSObject.gClones;
     } else {
       content.wrappedJSObject.gClones = liveClones;
     }
   });
 }
 
 var gTests = [
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -883,17 +883,17 @@ function eventMatchesKey(aEvent, aKey) {
 
   if (aEvent.key != keyPressed) {
     return false;
   }
   let eventModifiers = modifiers.filter(modifier =>
     aEvent.getModifierState(modifier)
   );
   // Check if aEvent has a modifier and aKey doesn't
-  if (eventModifiers.length > 0 && keyModifiers.length == 0) {
+  if (eventModifiers.length && !keyModifiers.length) {
     return false;
   }
   // Check whether aKey's modifiers match aEvent's modifiers
   if (keyModifiers) {
     keyModifiers = keyModifiers.split(/[\s,]+/);
     // Capitalize first letter of aKey's modifers to compare to aEvent's modifier
     keyModifiers.forEach(function(modifier, index) {
       if (modifier == "accel") {
--- a/browser/components/about/AboutPrivateBrowsingHandler.jsm
+++ b/browser/components/about/AboutPrivateBrowsingHandler.jsm
@@ -42,17 +42,17 @@ var AboutPrivateBrowsingHandler = {
         let win = aMessage.target.browser.ownerGlobal;
         win.OpenBrowserWindow({ private: true });
         break;
       }
       case "SearchHandoff": {
         let searchAlias = "";
         let searchAliases =
           Services.search.defaultEngine.wrappedJSObject.__internalAliases;
-        if (searchAliases && searchAliases.length > 0) {
+        if (searchAliases && searchAliases.length) {
           searchAlias = `${searchAliases[0]} `;
         }
         let urlBar = aMessage.target.browser.ownerGlobal.gURLBar;
         let isFirstChange = true;
 
         if (!aMessage.data || !aMessage.data.text) {
           urlBar.setHiddenFocus();
         } else {
--- a/browser/components/aboutlogins/tests/browser/browser_loginListChanges.js
+++ b/browser/components/aboutlogins/tests/browser/browser_loginListChanges.js
@@ -65,17 +65,17 @@ add_task(async function test_login_remov
     origin: "https://www.example.com",
   };
   let browser = gBrowser.selectedBrowser;
   browser.messageManager.sendAsyncMessage("AboutLogins:LoginRemoved", login);
 
   await ContentTask.spawn(browser, login, async removedLogin => {
     let loginList = Cu.waiveXrays(content.document.querySelector("login-list"));
     let loginRemoved = await ContentTaskUtils.waitForCondition(() => {
-      return loginList._loginGuidsSortedOrder.length == 0;
+      return !loginList._loginGuidsSortedOrder.length;
     }, "Waiting for login to get removed");
     ok(loginRemoved, "The login should be removed from the page");
   });
 });
 
 add_task(async function test_all_logins_removed() {
   // Setup the test with 2 logins.
   let logins = [
@@ -116,17 +116,17 @@ add_task(async function test_all_logins_
     );
   });
 
   Services.logins.removeAllLogins();
 
   await ContentTask.spawn(browser, null, async () => {
     let loginList = Cu.waiveXrays(content.document.querySelector("login-list"));
     let loginFound = await ContentTaskUtils.waitForCondition(() => {
-      return loginList._loginGuidsSortedOrder.length == 0;
+      return !loginList._loginGuidsSortedOrder.length;
     }, "Waiting for logins to be cleared");
     ok(loginFound, "Logins should be cleared");
     ok(
       content.document.documentElement.classList.contains("no-logins"),
       "Should be in no logins view after clearing"
     );
     ok(
       loginList.classList.contains("no-logins"),
--- a/browser/components/contextualidentity/test/browser/file_reflect_cookie_into_title.html
+++ b/browser/components/contextualidentity/test/browser/file_reflect_cookie_into_title.html
@@ -1,15 +1,15 @@
 <html>
   <head>
     <meta charset="UTF-8">
     <title>title not set</title>
     <script>
       // if we have a query string, use it to set the cookie and localStorage
-      if (window.location.search.length > 0) {
+      if (window.location.search.length) {
         let context_name = window.location.search.substr(1);
         document.cookie = "userContextId=" + context_name;
         localStorage.setItem("userContext", context_name);
       }
 
       // get the cookie
       let [name, val] = document.cookie.split("=");
 
--- a/browser/components/contextualidentity/test/browser/file_set_storages.html
+++ b/browser/components/contextualidentity/test/browser/file_set_storages.html
@@ -3,17 +3,17 @@
     <meta charset="UTF-8">
     <title>Bug 1238183</title>
   </head>
   <body>
     <script type="application/javascript">
       "use strict";
 
       // if we have a query string, use it to set storages
-      if (window.location.search.length > 0) {
+      if (window.location.search.length) {
         let context_name = window.location.search.substr(1);
         localStorage.setItem("userContext", context_name);
         sessionStorage.setItem("userContext", context_name);
 
         let request = indexedDB.open("idb", 1);
 
         request.onerror = function() {
           throw new Error("error opening db connection");
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -762,17 +762,17 @@ if (Services.prefs.getBoolPref("identity
       clientItem.setAttribute(
         "tooltiptext",
         window.gSync.formatLastSyncDate(new Date(client.lastModified))
       );
       clientItem.textContent = client.name;
 
       attachFragment.appendChild(clientItem);
 
-      if (client.tabs.length == 0) {
+      if (!client.tabs.length) {
         let label = this._appendMessageLabel(
           "notabsforclientlabel",
           attachFragment
         );
         label.setAttribute("class", "PanelUI-remotetabs-notabsforclient-label");
       } else {
         // If this page will display all tabs, show no additional buttons.
         // If the next page will display all the remaining tabs, show a "Show All" button
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -815,17 +815,17 @@ const PanelUI = {
           n.options.onDismissed(window);
         }
       });
       this._hidePopup();
       this._clearBadge();
       if (!notifications[0].options.badgeOnly) {
         this._showBannerItem(notifications[0]);
       }
-    } else if (doorhangers.length > 0) {
+    } else if (doorhangers.length) {
       // Only show the doorhanger if the window is focused and not fullscreen
       if (
         (window.fullScreen && this.autoHideToolbarInFullScreen) ||
         Services.focus.activeWindow !== window
       ) {
         this._hidePopup();
         this._showBadge(doorhangers[0]);
         this._showBannerItem(doorhangers[0]);
--- a/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
+++ b/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
@@ -118,17 +118,17 @@ add_task(async function() {
   EventUtils.synthesizeMouseAtCenter(themesButton, {});
   info("Clicked on themes button a third time");
   await popupShownPromise;
 
   let activeThemes = popup.querySelectorAll(
     "toolbarbutton.customization-lwtheme-menu-theme[active]"
   );
   is(activeThemes.length, 1, "Exactly 1 theme should be selected");
-  if (activeThemes.length > 0) {
+  if (activeThemes.length) {
     is(
       activeThemes[0].theme.id,
       LIGHT_THEME_ID,
       "Light theme should be selected"
     );
   }
   popup.hidePopup();
 
@@ -150,17 +150,17 @@ add_task(async function() {
   EventUtils.synthesizeMouseAtCenter(themesButton, {});
   info("Clicked on themes button a fourth time");
   await popupShownPromise;
 
   activeThemes = popup.querySelectorAll(
     "toolbarbutton.customization-lwtheme-menu-theme[active]"
   );
   is(activeThemes.length, 1, "Exactly 1 theme should be selected");
-  if (activeThemes.length > 0) {
+  if (activeThemes.length) {
     is(
       activeThemes[0].theme.id,
       "my-theme-5@example.com",
       "Last installed theme should be selected"
     );
   }
 
   let firstLWTheme = footer.previousElementSibling;
@@ -178,17 +178,17 @@ add_task(async function() {
   EventUtils.synthesizeMouseAtCenter(themesButton, {});
   info("Clicked on themes button");
   await popupShownPromise;
 
   activeThemes = popup.querySelectorAll(
     "toolbarbutton.customization-lwtheme-menu-theme[active]"
   );
   is(activeThemes.length, 1, "Exactly 1 theme should be selected");
-  if (activeThemes.length > 0) {
+  if (activeThemes.length) {
     is(
       activeThemes[0].theme.id,
       firstLWThemeId,
       "First theme should be selected"
     );
   }
 
   is(
--- a/browser/components/customizableui/test/browser_lwt_telemetry.js
+++ b/browser/components/customizableui/test/browser_lwt_telemetry.js
@@ -36,17 +36,17 @@ add_task(async function testCustomize() 
 
   let snapshot = Services.telemetry.snapshotEvents(
     Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
     true
   );
 
   // Make sure we got some data.
   ok(
-    snapshot.parent && snapshot.parent.length > 0,
+    snapshot.parent && !!snapshot.parent.length,
     "Got parent telemetry events in the snapshot"
   );
 
   // Only look at the related events after stripping the timestamp and category.
   let relatedEvents = snapshot.parent
     .filter(
       ([timestamp, category, method, object]) =>
         category == "addonsManager" && object == "customize"
--- a/browser/components/downloads/DownloadsCommon.jsm
+++ b/browser/components/downloads/DownloadsCommon.jsm
@@ -978,17 +978,17 @@ const DownloadsViewPrototype = {
    * The specified object is initialized with the currently available status.
    *
    * @param aView
    *        View object to be added.  This reference must be
    *        passed to removeView before termination.
    */
   addView(aView) {
     // Start receiving events when the first of our views is registered.
-    if (this._views.length == 0) {
+    if (!this._views.length) {
       if (this._isPrivate) {
         PrivateDownloadsData.addView(this);
       } else {
         DownloadsData.addView(this);
       }
     }
 
     this._views.push(aView);
@@ -1016,17 +1016,17 @@ const DownloadsViewPrototype = {
    */
   removeView(aView) {
     let index = this._views.indexOf(aView);
     if (index != -1) {
       this._views.splice(index, 1);
     }
 
     // Stop receiving events when the last of our views is unregistered.
-    if (this._views.length == 0) {
+    if (!this._views.length) {
       if (this._isPrivate) {
         PrivateDownloadsData.removeView(this);
       } else {
         DownloadsData.removeView(this);
       }
     }
   },
 
@@ -1170,17 +1170,17 @@ DownloadsIndicatorDataCtor.prototype = {
    * Removes an object previously added using addView.
    *
    * @param aView
    *        DownloadsIndicatorView object to be removed.
    */
   removeView(aView) {
     DownloadsViewPrototype.removeView.call(this, aView);
 
-    if (this._views.length == 0) {
+    if (!this._views.length) {
       this._itemCount = 0;
     }
   },
 
   onDownloadAdded(download) {
     DownloadsViewPrototype.onDownloadAdded.call(this, download);
     this._itemCount++;
     this._updateViews();
@@ -1388,17 +1388,17 @@ DownloadsSummaryData.prototype = {
    * Removes an object previously added using addView.
    *
    * @param aView
    *        DownloadsSummary view to be removed.
    */
   removeView(aView) {
     DownloadsViewPrototype.removeView.call(this, aView);
 
-    if (this._views.length == 0) {
+    if (!this._views.length) {
       // Clear out our collection of Download objects. If we ever have
       // another view registered with us, this will get re-populated.
       this._downloads = [];
     }
   },
 
   onDownloadAdded(download) {
     DownloadsViewPrototype.onDownloadAdded.call(this, download);
@@ -1443,17 +1443,17 @@ DownloadsSummaryData.prototype = {
   /**
    * A generator function for the Download objects this summary is currently
    * interested in. This generator is passed off to summarizeDownloads in order
    * to generate statistics about the downloads we care about - in this case,
    * it's the downloads in this._downloads after the first few to exclude,
    * which was set when constructing this DownloadsSummaryData instance.
    */
   *_downloadsForSummary() {
-    if (this._downloads.length > 0) {
+    if (this._downloads.length) {
       for (let i = this._numToExclude; i < this._downloads.length; ++i) {
         yield this._downloads[i];
       }
     }
   },
 
   /**
    * Computes aggregate values based on the current state of downloads.
--- a/browser/components/downloads/content/allDownloadsView.js
+++ b/browser/components/downloads/content/allDownloadsView.js
@@ -332,17 +332,17 @@ DownloadsPlacesView.prototype = {
   },
 
   get selectedNode() {
     let selectedNodes = this.selectedNodes;
     return selectedNodes.length == 1 ? selectedNodes[0] : null;
   },
 
   get hasSelection() {
-    return this.selectedNodes.length > 0;
+    return !!this.selectedNodes.length;
   },
 
   get controller() {
     return this._richlistbox.controller;
   },
 
   get searchTerm() {
     return this._searchTerm;
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -864,17 +864,17 @@ var Policies = {
 
   Homepage: {
     onBeforeUIStartup(manager, param) {
       // |homepages| will be a string containing a pipe-separated ('|') list of
       // URLs because that is what the "Home page" section of about:preferences
       // (and therefore what the pref |browser.startup.homepage|) accepts.
       if (param.URL) {
         let homepages = param.URL.href;
-        if (param.Additional && param.Additional.length > 0) {
+        if (param.Additional && param.Additional.length) {
           homepages += "|" + param.Additional.map(url => url.href).join("|");
         }
         setDefaultPref("browser.startup.homepage", homepages, param.Locked);
         if (param.Locked) {
           setAndLockPref(
             "pref.browser.homepage.disable_button.current_page",
             true
           );
--- a/browser/components/enterprisepolicies/content/aboutPolicies.js
+++ b/browser/components/enterprisepolicies/content/aboutPolicies.js
@@ -164,17 +164,17 @@ function generatePolicy(data, row, depth
 
         for (let i = 0; i < depth; i++) {
           new_row.appendChild(col(""));
         }
 
         generatePolicy(data[count], new_row, depth + 1, new_cont, false, false);
       }
     }
-  } else if (typeof data == "object" && Object.keys(data).length > 0) {
+  } else if (typeof data == "object" && Object.keys(data).length) {
     let count = 0;
     for (let obj in data) {
       if (count == 0) {
         row.appendChild(col(obj));
         if (count == Object.keys(data).length - 1) {
           generatePolicy(
             data[obj],
             row,
--- a/browser/components/extensions/parent/ext-chrome-settings-overrides.js
+++ b/browser/components/extensions/parent/ext-chrome-settings-overrides.js
@@ -231,17 +231,17 @@ this.chrome_settings_overrides = class e
     // We can call removeEngine in nsSearchService startup, if so we dont
     // need to reforward the call, just disable the web extension.
     if (!Services.search.isInitialized) {
       return;
     }
 
     try {
       let engines = await Services.search.getEnginesByExtensionID(id);
-      if (engines.length > 0) {
+      if (engines.length) {
         await Services.search.removeWebExtensionEngine(id);
       }
     } catch (e) {
       Cu.reportError(e);
     }
   }
 
   static removeSearchSettings(id) {
@@ -450,32 +450,32 @@ this.chrome_settings_overrides = class e
     let { extension } = this;
     let isCurrent = false;
     let index = -1;
     if (
       extension.startupReason === "ADDON_UPGRADE" &&
       !extension.addonData.builtIn
     ) {
       let engines = await Services.search.getEnginesByExtensionID(extension.id);
-      if (engines.length > 0) {
+      if (engines.length) {
         let firstEngine = engines[0];
         let firstEngineName = firstEngine.name;
         // There can be only one engine right now
         isCurrent =
           (await Services.search.getDefault()).name == firstEngineName;
         // Get position of engine and store it
         index = (await Services.search.getEngines())
           .map(engine => engine.name)
           .indexOf(firstEngineName);
         await Services.search.removeEngine(firstEngine);
       }
     }
     try {
       let engines = await Services.search.addEnginesFromExtension(extension);
-      if (engines.length > 0) {
+      if (engines.length) {
         await ExtensionSettingsStore.initialize();
         await ExtensionSettingsStore.addSetting(
           extension.id,
           DEFAULT_SEARCH_STORE_TYPE,
           ENGINE_ADDED_SETTING_NAME,
           engines[0].name
         );
       }
--- a/browser/components/extensions/parent/ext-menus.js
+++ b/browser/components/extensions/parent/ext-menus.js
@@ -307,17 +307,17 @@ var gMenuBuilder = {
         }
       }
     }
   },
 
   buildSingleElement(item, contextData) {
     let doc = contextData.menu.ownerDocument;
     let element;
-    if (item.children.length > 0) {
+    if (item.children.length) {
       element = this.createMenuElement(doc, item);
     } else if (item.type == "separator") {
       element = doc.createXULElement("menuseparator");
     } else {
       element = doc.createXULElement("menuitem");
     }
 
     return this.customizeElement(element, item, contextData);
--- a/browser/components/extensions/parent/ext-sessions.js
+++ b/browser/components/extensions/parent/ext-sessions.js
@@ -175,17 +175,17 @@ this.sessions = class extends ExtensionA
             let recentlyClosedTabs = [];
             for (let window of windowTracker.browserWindows()) {
               let closedTabData = SessionStore.getClosedTabData(window, false);
               for (let tab of closedTabData) {
                 recentlyClosedTabs.push(tab);
               }
             }
 
-            if (recentlyClosedTabs.length > 0) {
+            if (recentlyClosedTabs.length) {
               // Sort the tabs.
               recentlyClosedTabs.sort((a, b) => b.closedAt - a.closedAt);
 
               // Use the closedId of the most recently closed tab to restore it.
               closedId = recentlyClosedTabs[0].closedId;
               session = SessionStore.undoCloseById(
                 closedId,
                 extension.privateBrowsingAllowed
--- a/browser/components/extensions/parent/ext-tabs.js
+++ b/browser/components/extensions/parent/ext-tabs.js
@@ -1587,17 +1587,17 @@ this.tabs = class extends ExtensionAPI {
           for (let tab of getNativeTabsFromIDArray(tabIds)) {
             if (tab.ownerGlobal && !tab.hidden) {
               tab.ownerGlobal.gBrowser.hideTab(tab, extension.id);
               if (tab.hidden) {
                 hidden.push(tabTracker.getId(tab));
               }
             }
           }
-          if (hidden.length > 0) {
+          if (hidden.length) {
             let win = Services.wm.getMostRecentWindow("navigator:browser");
             tabHidePopup.open(win, extension.id);
           }
           return hidden;
         },
 
         highlight(highlightInfo) {
           if (!gMultiSelectEnabled) {
@@ -1611,17 +1611,17 @@ this.tabs = class extends ExtensionAPI {
           }
           let window = windowTracker.getWindow(windowId, context);
           if (!context.canAccessWindow(window)) {
             throw new ExtensionError(`Invalid window ID: ${windowId}`);
           }
 
           if (!Array.isArray(tabs)) {
             tabs = [tabs];
-          } else if (tabs.length == 0) {
+          } else if (!tabs.length) {
             throw new ExtensionError("No highlighted tab.");
           }
           window.gBrowser.selectedTabs = tabs.map(tabIndex => {
             let tab = window.gBrowser.tabs[tabIndex];
             if (!tab) {
               throw new ExtensionError("No tab at index: " + tabIndex);
             }
             return tab;
--- a/browser/components/extensions/test/browser/browser_ext_addon_debugging_netmonitor.js
+++ b/browser/components/extensions/test/browser/browser_ext_addon_debugging_netmonitor.js
@@ -58,17 +58,17 @@ async function setupToolboxTest(extensio
 
   let requests;
 
   await waitFor(() => {
     requests = Array.from(store.getState().requests.requests.values()).filter(
       filterRequest
     );
 
-    return requests.length > 0;
+    return !!requests.length;
   });
 
   // Call a function defined in the target extension to make assertions
   // on the network requests collected by the netmonitor panel.
   await consoleFront.evaluateJSAsync(
     `testNetworkRequestReceived(${JSON.stringify(requests)});`
   );
 
--- a/browser/components/extensions/test/browser/browser_ext_browsingData_pluginData.js
+++ b/browser/components/extensions/test/browser/browser_ext_browsingData_pluginData.js
@@ -31,17 +31,17 @@ const PLUGIN_TAG = getTestPlugin();
    returns a Promise that resolves once we've forced a layout flush, which
    triggers the PluginBindAttached event to fire. This trick only works if
    there is some sort of plugin in the page.
  */
 function promiseUpdatePluginBindings(browser) {
   return ContentTask.spawn(browser, {}, async function() {
     let doc = content.document;
     let elems = doc.getElementsByTagName("embed");
-    if (elems && elems.length > 0) {
+    if (elems && elems.length) {
       elems[0].clientTop; // eslint-disable-line no-unused-expressions
     }
   });
 }
 
 function stored(needles) {
   let something = pluginHost.siteHasData(PLUGIN_TAG, null);
   if (!needles) {
--- a/browser/components/extensions/test/browser/browser_ext_browsingData_serviceWorkers.js
+++ b/browser/components/extensions/test/browser/browser_ext_browsingData_serviceWorkers.js
@@ -85,17 +85,17 @@ add_task(async function testServiceWorke
   }
   is(serviceWorkers.length, 2, "ServiceWorkers have been registered.");
 
   extension.sendMessage();
 
   await extension.awaitMessage("serviceWorkersRemoved");
 
   // The serviceWorkers and not necessarily removed immediately.
-  while (serviceWorkers.length > 0) {
+  while (serviceWorkers.length) {
     serviceWorkers = serviceWorkerManager.getAllRegistrations();
     await new Promise(resolve => setTimeout(resolve, 1));
   }
   is(serviceWorkers.length, 0, "ServiceWorkers have been removed.");
 
   await extension.unload();
   await BrowserTestUtils.closeWindow(win);
 });
--- a/browser/components/extensions/test/browser/browser_ext_devtools_panel.js
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_panel.js
@@ -435,17 +435,17 @@ add_task(async function test_devtools_pa
   await extension.awaitMessage("devtools_panel_shown");
 
   // Check that the aria-label has been set on the devtools panel.
   const panelFrame = toolbox.doc.getElementById(
     `toolbox-panel-iframe-${panelId}`
   );
   const panelInfo = getPanelInfo(toolbox);
   ok(
-    panelInfo.panelLabel && panelInfo.panelLabel.length > 0,
+    panelInfo.panelLabel && !!panelInfo.panelLabel.length,
     "Expect the registered panel to include a non empty panelLabel property"
   );
   is(
     panelFrame && panelFrame.getAttribute("aria-label"),
     panelInfo.panelLabel,
     "Got the expected aria-label on the extension panel frame"
   );
 
--- a/browser/components/extensions/test/browser/browser_ext_sidebarAction_windows.js
+++ b/browser/components/extensions/test/browser/browser_ext_sidebarAction_windows.js
@@ -38,32 +38,32 @@ add_task(async function sidebar_windows(
   ok(
     !document.getElementById("sidebar-box").hidden,
     "sidebar box is visible in first window"
   );
   // Check that the menuitem has our image styling.
   let elements = document.getElementsByClassName("webextension-menuitem");
   // ui is in flux, at time of writing we potentially have 3 menuitems, later
   // it may be two or one, just make sure one is there.
-  ok(elements.length > 0, "have a menuitem");
+  ok(!!elements.length, "have a menuitem");
   let style = elements[0].getAttribute("style");
   ok(style.includes("webextension-menuitem-image"), "this menu has style");
 
   let secondSidebar = extension.awaitMessage("sidebar");
 
   // SidebarUI relies on window.opener being set, which is normal behavior when
   // using menu or key commands to open a new browser window.
   let win = await BrowserTestUtils.openNewBrowserWindow();
 
   await secondSidebar;
   ok(
     !win.document.getElementById("sidebar-box").hidden,
     "sidebar box is visible in second window"
   );
   // Check that the menuitem has our image styling.
   elements = win.document.getElementsByClassName("webextension-menuitem");
-  ok(elements.length > 0, "have a menuitem");
+  ok(!!elements.length, "have a menuitem");
   style = elements[0].getAttribute("style");
   ok(style.includes("webextension-menuitem-image"), "this menu has style");
 
   await extension.unload();
   await BrowserTestUtils.closeWindow(win);
 });
--- a/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
+++ b/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
@@ -78,17 +78,17 @@ add_task(async function testWebNavigatio
 
         // Pick a random frameId.
         let nonExistentFrameId = Math.floor(Math.random() * 10000);
 
         // Increment the picked random nonExistentFrameId until it doesn't exists.
         while (
           getAllFramesDetails.filter(
             details => details.frameId == nonExistentFrameId
-          ).length > 0
+          ).length
         ) {
           nonExistentFrameId += 1;
         }
 
         // Check that getFrame Promise is rejected with the expected error message on nonexistent frameId.
         await browser.test.assertRejects(
           browser.webNavigation.getFrame({
             tabId,
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -497,17 +497,17 @@ async function closeContextMenu(contextM
 async function openExtensionContextMenu(selector = "#img1") {
   let contextMenu = await openContextMenu(selector);
   let topLevelMenu = contextMenu.getElementsByAttribute(
     "ext-type",
     "top-level-menu"
   );
 
   // Return null if the extension only has one item and therefore no extension menu.
-  if (topLevelMenu.length == 0) {
+  if (!topLevelMenu.length) {
     return null;
   }
 
   let extensionMenu = topLevelMenu[0];
   let popupShownPromise = BrowserTestUtils.waitForEvent(
     contextMenu,
     "popupshown"
   );
--- a/browser/components/migration/360seProfileMigrator.jsm
+++ b/browser/components/migration/360seProfileMigrator.jsm
@@ -312,17 +312,17 @@ Qihoo360seProfileMigrator.prototype.getS
     profiles[noLoggedInUser ? "unshift" : "push"]({
       id: this._defaultUserPath,
       name: "Default",
     });
   }
 
   this.__sourceProfiles = profiles.filter(profile => {
     let resources = this.getResources(profile);
-    return resources && resources.length > 0;
+    return resources && !!resources.length;
   });
   return this.__sourceProfiles;
 };
 
 Qihoo360seProfileMigrator.prototype._getIdFromConfig = function(aConfig) {
   return aConfig.UserMd5 || getHash(aConfig.email);
 };
 
--- a/browser/components/migration/ChromeProfileMigrator.jsm
+++ b/browser/components/migration/ChromeProfileMigrator.jsm
@@ -180,17 +180,17 @@ ChromeProfileMigrator.prototype.getSourc
       profile,
       resources: await this.getResources(profile),
     }))
   );
 
   // Only list profiles from which any data can be imported
   this.__sourceProfiles = profileResources
     .filter(({ resources }) => {
-      return resources && resources.length > 0;
+      return resources && !!resources.length;
     }, this)
     .map(({ profile }) => profile);
   return this.__sourceProfiles;
 };
 
 Object.defineProperty(ChromeProfileMigrator.prototype, "sourceLocked", {
   get: function Chrome_sourceLocked() {
     // There is an exclusive lock on some SQLite databases. Assume they are locked for now.
@@ -215,20 +215,17 @@ async function GetBookmarksResource(aPro
         };
         // Parse Chrome bookmark file that is JSON format
         let bookmarkJSON = await OS.File.read(bookmarksPath, {
           encoding: "UTF-8",
         });
         let roots = JSON.parse(bookmarkJSON).roots;
 
         // Importing bookmark bar items
-        if (
-          roots.bookmark_bar.children &&
-          roots.bookmark_bar.children.length > 0
-        ) {
+        if (roots.bookmark_bar.children && roots.bookmark_bar.children.length) {
           // Toolbar
           let parentGuid = PlacesUtils.bookmarks.toolbarGuid;
           let bookmarks = convertBookmarks(
             roots.bookmark_bar.children,
             errorGatherer
           );
           if (!MigrationUtils.isStartupMigration) {
             parentGuid = await MigrationUtils.createImportedBookmarksFolder(
@@ -238,17 +235,17 @@ async function GetBookmarksResource(aPro
           }
           await MigrationUtils.insertManyBookmarksWrapper(
             bookmarks,
             parentGuid
           );
         }
 
         // Importing bookmark menu items
-        if (roots.other.children && roots.other.children.length > 0) {
+        if (roots.other.children && roots.other.children.length) {
           // Bookmark menu
           let parentGuid = PlacesUtils.bookmarks.menuGuid;
           let bookmarks = convertBookmarks(roots.other.children, errorGatherer);
           if (!MigrationUtils.isStartupMigration) {
             parentGuid = await MigrationUtils.createImportedBookmarksFolder(
               "Chrome",
               parentGuid
             );
@@ -324,17 +321,17 @@ async function GetHistoryResource(aProfi
                 },
               ],
             });
           } catch (e) {
             Cu.reportError(e);
           }
         }
 
-        if (pageInfos.length > 0) {
+        if (pageInfos.length) {
           await MigrationUtils.insertVisitsWrapper(pageInfos);
         }
       })().then(
         () => {
           aCallback(true);
         },
         ex => {
           Cu.reportError(ex);
@@ -515,17 +512,17 @@ async function GetWindowsPasswordsResour
               );
           }
           logins.push(loginInfo);
         } catch (e) {
           Cu.reportError(e);
         }
       }
       try {
-        if (logins.length > 0) {
+        if (logins.length) {
           await MigrationUtils.insertLoginsWrapper(logins);
         }
       } catch (e) {
         Cu.reportError(e);
       }
       crypto.finalize();
       aCallback(true);
     },
--- a/browser/components/migration/EdgeProfileMigrator.jsm
+++ b/browser/components/migration/EdgeProfileMigrator.jsm
@@ -158,17 +158,17 @@ EdgeTypedURLMigrator.prototype = {
           {
             transition: PlacesUtils.history.TRANSITIONS.TYPED,
             date: time ? PlacesUtils.toDate(time) : new Date(),
           },
         ],
       });
     }
 
-    if (pageInfos.length == 0) {
+    if (!pageInfos.length) {
       aCallback(typedURLs.size == 0);
       return;
     }
 
     MigrationUtils.insertVisitsWrapper(pageInfos).then(
       () => aCallback(true),
       () => aCallback(false)
     );
--- a/browser/components/migration/IEProfileMigrator.jsm
+++ b/browser/components/migration/IEProfileMigrator.jsm
@@ -64,17 +64,17 @@ History.prototype = {
       // like HTMLHelp and others.  Since we don't properly map handling for
       // all of them we just avoid importing them.
       if (!["http", "https", "ftp", "file"].includes(url.scheme)) {
         continue;
       }
 
       let title = entry.get("title");
       // Embed visits have no title and don't need to be imported.
-      if (title.length == 0) {
+      if (!title.length) {
         continue;
       }
 
       // The typed urls are already fixed-up, so we can use them for comparison.
       let transition = typedURLs.has(url.spec)
         ? PlacesUtils.history.TRANSITIONS.LINK
         : PlacesUtils.history.TRANSITIONS.TYPED;
       // use the current date if we have no visits for this entry.
@@ -88,17 +88,17 @@ History.prototype = {
             transition,
             date: time ? PlacesUtils.toDate(entry.get("time")) : new Date(),
           },
         ],
       });
     }
 
     // Check whether there is any history to import.
-    if (pageInfos.length == 0) {
+    if (!pageInfos.length) {
       aCallback(true);
       return;
     }
 
     MigrationUtils.insertVisitsWrapper(pageInfos).then(
       () => aCallback(true),
       () => aCallback(false)
     );
@@ -230,17 +230,17 @@ IE7FormPasswords.prototype = {
         }
       } catch (e) {
         Cu.reportError(
           "Error while importing logins for " + uri.spec + ": " + e
         );
       }
     }
 
-    if (logins.length > 0) {
+    if (logins.length) {
       await MigrationUtils.insertLoginsWrapper(logins);
     }
 
     // if the number of the imported values is less than the number of values in the key, it means
     // that not all the values were imported and an error should be reported
     if (successfullyDecryptedValues < key.valueCount) {
       Cu.reportError(
         "We failed to decrypt and import some logins. " +
--- a/browser/components/migration/MSMigrationUtils.jsm
+++ b/browser/components/migration/MSMigrationUtils.jsm
@@ -664,44 +664,44 @@ Cookies.prototype = {
    * can't rely exclusively on it as a record separator.
    *
    * @note All the times are in FILETIME format.
    */
   _parseCookieBuffer(aTextBuffer) {
     // Note the last record is an empty string...
     let records = [];
     let lines = aTextBuffer.split("\n");
-    while (lines.length > 0) {
+    while (lines.length) {
       let record = lines.splice(0, 9);
       // ... which means this is going to be a 1-element array for that record
       if (record.length > 1) {
         records.push(record);
       }
     }
     for (let record of records) {
       let [name, value, hostpath, flags, expireTimeLo, expireTimeHi] = record;
 
       // IE stores deleted cookies with a zero-length value, skip them.
-      if (value.length == 0) {
+      if (!value.length) {
         continue;
       }
 
       // IE sometimes has cookies created by apps that use "~~local~~/local/file/path"
       // as the hostpath, ignore those:
       if (hostpath.startsWith("~~local~~")) {
         continue;
       }
 
       let hostLen = hostpath.indexOf("/");
       let host = hostpath.substr(0, hostLen);
       let path = hostpath.substr(hostLen);
 
       // For a non-null domain, assume it's what Mozilla considers
       // a domain cookie.  See bug 222343.
-      if (host.length > 0) {
+      if (host.length) {
         // Fist delete any possible extant matching host cookie.
         Services.cookies.remove(host, name, path, false, {});
         // Now make it a domain cookie.
         if (host[0] != "." && !hostIsIPAddress(host)) {
           host = "." + host;
         }
       }
 
@@ -965,17 +965,17 @@ WindowsVaultFormPasswords.prototype = {
           migrationSucceeded = false;
           Cu.reportError(e);
         } finally {
           // move to next item in the table returned by VaultEnumerateItems
           item = item.increment();
         }
       }
 
-      if (logins.length > 0) {
+      if (logins.length) {
         await MigrationUtils.insertLoginsWrapper(logins);
       }
     } catch (e) {
       Cu.reportError(e);
       migrationSucceeded = false;
     } finally {
       if (successfulVaultOpen) {
         // close current vault
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -239,17 +239,17 @@ var MigratorPrototype = {
   /**
    * DO NOT OVERRIDE - After deCOMing migration, the UI will just call
    * migrate for each resource.
    *
    * @see nsIBrowserProfileMigrator
    */
   migrate: async function MP_migrate(aItems, aStartup, aProfile) {
     let resources = await this._getMaybeCachedResources(aProfile);
-    if (resources.length == 0) {
+    if (!resources.length) {
       throw new Error("migrate called for a non-existent source");
     }
 
     if (aItems != Ci.nsIBrowserProfileMigrator.ALL) {
       resources = resources.filter(r => aItems & r.type);
     }
 
     // Used to periodically give back control to the main-thread loop.
@@ -476,21 +476,21 @@ var MigratorPrototype = {
     // For a single-profile source, check if any data is available.
     // For multiple-profiles source, make sure that at least one
     // profile is available.
     let exists = false;
     try {
       let profiles = await this.getSourceProfiles();
       if (!profiles) {
         let resources = await this._getMaybeCachedResources("");
-        if (resources && resources.length > 0) {
+        if (resources && resources.length) {
           exists = true;
         }
       } else {
-        exists = profiles.length > 0;
+        exists = !!profiles.length;
       }
     } catch (ex) {
       Cu.reportError(ex);
     }
     return exists;
   },
 
   /** * PRIVATE STUFF - DO NOT OVERRIDE ***/
--- a/browser/components/migration/SafariProfileMigrator.jsm
+++ b/browser/components/migration/SafariProfileMigrator.jsm
@@ -108,17 +108,17 @@ Bookmarks.prototype = {
         } else if (type == "WebBookmarkTypeLeaf") {
           entriesFiltered.push(entry);
         }
       }
     } else {
       entriesFiltered = aEntries;
     }
 
-    if (entriesFiltered.length == 0) {
+    if (!entriesFiltered.length) {
       return;
     }
 
     let folderGuid = -1;
     switch (aCollection) {
       case this.ROOT_COLLECTION: {
         // In Safari, it is possible (though quite cumbersome) to move
         // bookmarks to the bookmarks root, which is the parent folder of
@@ -266,17 +266,17 @@ History.prototype = {
             } catch (ex) {
               // Safari's History file may contain malformed URIs which
               // will be ignored.
               Cu.reportError(ex);
               failedOnce = true;
             }
           }
         }
-        if (pageInfos.length == 0) {
+        if (!pageInfos.length) {
           // If we failed at least once, then we didn't succeed in importing,
           // otherwise we didn't actually have anything to import, so we'll
           // report it as a success.
           aCallback(!failedOnce);
           return;
         }
 
         MigrationUtils.insertVisitsWrapper(pageInfos).then(
@@ -308,17 +308,17 @@ MainPreferencesPropertyList.prototype = 
    * @see PropertyListUtils.read
    */
   read: function MPPL_read(aCallback) {
     if ("_dict" in this) {
       aCallback(this._dict);
       return;
     }
 
-    let alreadyReading = this._callbacks.length > 0;
+    let alreadyReading = !!this._callbacks.length;
     this._callbacks.push(aCallback);
     if (!alreadyReading) {
       PropertyListUtils.read(this._file, aDict => {
         this._dict = aDict;
         for (let callback of this._callbacks) {
           try {
             callback(aDict);
           } catch (ex) {
@@ -341,17 +341,17 @@ SearchStrings.prototype = {
     this._mainPreferencesPropertyList.read(
       MigrationUtils.wrapMigrateFunction(function migrateSearchStrings(aDict) {
         if (!aDict) {
           throw new Error("Could not get preferences dictionary");
         }
 
         if (aDict.has("RecentSearchStrings")) {
           let recentSearchStrings = aDict.get("RecentSearchStrings");
-          if (recentSearchStrings && recentSearchStrings.length > 0) {
+          if (recentSearchStrings && recentSearchStrings.length) {
             let changes = recentSearchStrings.map(searchString => ({
               op: "add",
               fieldname: "searchbar-history",
               value: searchString,
             }));
             FormHistory.update(changes);
           }
         }
--- a/browser/components/migration/tests/unit/test_360se_bookmarks.js
+++ b/browser/components/migration/tests/unit/test_360se_bookmarks.js
@@ -37,17 +37,17 @@ add_task(async function() {
         itemCount++;
       }
       if (
         event.itemType == PlacesUtils.bookmarks.TYPE_FOLDER &&
         event.title == "360 \u76f8\u5173"
       ) {
         gotFolder = true;
       }
-      if (expectedParents.length > 0 && event.title == label) {
+      if (expectedParents.length && event.title == label) {
         let index = expectedParents.indexOf(event.parentId);
         Assert.ok(index != -1, "Found expected parent");
         expectedParents.splice(index, 1);
       }
     }
   };
   PlacesUtils.observers.addListener(["bookmark-added"], listener);
 
--- a/browser/components/migration/tests/unit/test_IE_bookmarks.js
+++ b/browser/components/migration/tests/unit/test_IE_bookmarks.js
@@ -18,17 +18,17 @@ add_task(async function() {
   ];
 
   let itemCount = 0;
   let listener = events => {
     for (let event of events) {
       if (event.title != label) {
         itemCount++;
       }
-      if (expectedParents.length > 0 && event.title == label) {
+      if (expectedParents.length && event.title == label) {
         let index = expectedParents.indexOf(event.parentId);
         Assert.notEqual(index, -1);
         expectedParents.splice(index, 1);
       }
     }
   };
   PlacesUtils.observers.addListener(["bookmark-added"], listener);
 
--- a/browser/components/migration/tests/unit/test_IE_history.js
+++ b/browser/components/migration/tests/unit/test_IE_history.js
@@ -40,11 +40,11 @@ add_task(async function test_IE_history(
   Assert.ok(await migrator.isSourceAvailable(), "Source is available");
 
   await promiseMigration(migrator, MigrationUtils.resourceTypes.HISTORY);
 
   for (let { url, title } of TEST_ENTRIES) {
     let entry = await PlacesUtils.history.fetch(url, { includeVisits: true });
     Assert.equal(entry.url, url, "Should have the correct URL");
     Assert.equal(entry.title, title, "Should have the correct title");
-    Assert.ok(entry.visits.length > 0, "Should have some visits");
+    Assert.ok(!!entry.visits.length, "Should have some visits");
   }
 });
--- a/browser/components/migration/tests/unit/test_Safari_bookmarks.js
+++ b/browser/components/migration/tests/unit/test_Safari_bookmarks.js
@@ -24,17 +24,17 @@ add_task(async function() {
         itemCount++;
       }
       if (
         event.itemType == PlacesUtils.bookmarks.TYPE_FOLDER &&
         event.title == "Stuff"
       ) {
         gotFolder = true;
       }
-      if (expectedParents.length > 0 && event.title == label) {
+      if (expectedParents.length && event.title == label) {
         let index = expectedParents.indexOf(event.parentId);
         Assert.ok(index != -1, "Found expected parent");
         expectedParents.splice(index, 1);
       }
     }
   };
   PlacesUtils.observers.addListener(["bookmark-added"], listener);
 
--- a/browser/components/newtab/common/Reducers.jsm
+++ b/browser/components/newtab/common/Reducers.jsm
@@ -302,17 +302,17 @@ function Sections(prevState = INITIAL_ST
         if (section && section.id === action.data.id) {
           hasMatch = true;
           return Object.assign({}, section, action.data);
         }
         return section;
       });
       // Otherwise, append it
       if (!hasMatch) {
-        const initialized = !!(action.data.rows && action.data.rows.length > 0);
+        const initialized = !!(action.data.rows && !!action.data.rows.length);
         const section = Object.assign(
           { title: "", rows: [], enabled: false },
           action.data,
           { initialized }
         );
         newState.push(section);
       }
       return newState;
@@ -322,17 +322,17 @@ function Sections(prevState = INITIAL_ST
           // If the action is updating rows, we should consider initialized to be true.
           // This can be overridden if initialized is defined in the action.data
           const initialized = action.data.rows ? { initialized: true } : {};
 
           // Make sure pinned cards stay at their current position when rows are updated.
           // Disabling a section (SECTION_UPDATE with empty rows) does not retain pinned cards.
           if (
             action.data.rows &&
-            action.data.rows.length > 0 &&
+            !!action.data.rows.length &&
             section.rows.find(card => card.pinned)
           ) {
             const rows = Array.from(action.data.rows);
             section.rows.forEach((card, index) => {
               if (card.pinned) {
                 // Only add it if it's not already there.
                 if (rows[index].guid !== card.guid) {
                   rows.splice(index, 0, card);
--- a/browser/components/newtab/content-src/asrouter/templates/StartupOverlay/StartupOverlay.jsx
+++ b/browser/components/newtab/content-src/asrouter/templates/StartupOverlay/StartupOverlay.jsx
@@ -77,17 +77,17 @@ export class StartupOverlay extends Reac
     this.removeOverlay();
   }
 
   /**
    * Report to telemetry additional information about the form submission.
    */
   _getFormInfo() {
     const value = {
-      has_flow_params: this.props.flowParams.flowId.length > 0,
+      has_flow_params: !!this.props.flowParams.flowId.length,
     };
     return { value };
   }
 
   onInputInvalid(e) {
     let error = e.target.previousSibling;
     error.classList.add("active");
     e.target.classList.add("invalid");
--- a/browser/components/newtab/content-src/asrouter/templates/Trailhead/Trailhead.jsx
+++ b/browser/components/newtab/content-src/asrouter/templates/Trailhead/Trailhead.jsx
@@ -107,17 +107,17 @@ export class Trailhead extends React.Pur
     // Bug 1190882 - Focus in a disappearing dialog confuses screen readers
     this.props.document.activeElement.blur();
   }
 
   /**
    * Report to telemetry additional information about the form submission.
    */
   _getFormInfo() {
-    const value = { has_flow_params: this.props.flowParams.flowId.length > 0 };
+    const value = { has_flow_params: !!this.props.flowParams.flowId.length };
     return { value };
   }
 
   onInputInvalid(e) {
     let error = e.target.previousSibling;
     error.classList.add("active");
     e.target.classList.add("invalid");
     e.preventDefault(); // Override built-in form validation popup
--- a/browser/components/newtab/content-src/components/DiscoveryStreamBase/DiscoveryStreamBase.jsx
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamBase/DiscoveryStreamBase.jsx
@@ -330,17 +330,17 @@ export class _DiscoveryStreamBase extend
       <React.Fragment>
         {topSites &&
           this.renderLayout([
             {
               width: 12,
               components: [topSites],
             },
           ])}
-        {layoutRender.length > 0 && (
+        {!!layoutRender.length && (
           <CollapsibleSection
             className="ds-layout"
             collapsed={topStories.pref.collapsed}
             dispatch={this.props.dispatch}
             icon={topStories.icon}
             id={topStories.id}
             isFixed={true}
             learnMore={{
--- a/browser/components/newtab/content-src/components/Sections/Sections.jsx
+++ b/browser/components/newtab/content-src/components/Sections/Sections.jsx
@@ -195,17 +195,17 @@ export class Section extends React.PureC
     const { pocketCta, isUserLoggedIn } = Pocket || {};
     const { useCta } = pocketCta || {};
 
     // Don't display anything until we have a definitve result from Pocket,
     // to avoid a flash of logged out state while we render.
     const isPocketLoggedInDefined =
       isUserLoggedIn === true || isUserLoggedIn === false;
 
-    const hasTopics = topics && topics.length > 0;
+    const hasTopics = topics && !!topics.length;
 
     const shouldShowPocketCta =
       id === "topstories" && useCta && isUserLoggedIn === false;
 
     // Show topics only for top stories and if it has loaded with topics.
     // The classs .top-stories-bottom-container ensures content doesn't shift as things load.
     const shouldShowTopics =
       id === "topstories" &&
--- a/browser/components/newtab/lib/ASRouterTargeting.jsm
+++ b/browser/components/newtab/lib/ASRouterTargeting.jsm
@@ -91,17 +91,17 @@ function CheckBrowserNeedsUpdate(
       this._lastUpdated = 0;
       this._value = null;
     },
     get() {
       return new Promise((resolve, reject) => {
         const now = Date.now();
         const updateServiceListener = {
           onCheckComplete(request, updates) {
-            checker._value = updates.length > 0;
+            checker._value = !!updates.length;
             resolve(checker._value);
           },
           onError(request, update) {
             reject(request);
           },
 
           QueryInterface: ChromeUtils.generateQI(["nsIUpdateCheckListener"]),
         };
--- a/browser/components/newtab/lib/CFRPageActions.jsm
+++ b/browser/components/newtab/lib/CFRPageActions.jsm
@@ -252,17 +252,17 @@ class PageAction {
       this.window.document
         .getElementById(ANIMATION_BUTTON_ID)
         .removeEventListener("click", this.onAnimationButtonClick);
       delete this.onAnimationButtonClick;
     }
   }
 
   _clearScheduledStateChanges() {
-    while (this.stateTransitionTimeoutIDs.length > 0) {
+    while (this.stateTransitionTimeoutIDs.length) {
       // clearTimeout is safe even with invalid/expired IDs
       this.window.clearTimeout(this.stateTransitionTimeoutIDs.pop());
     }
   }
 
   // This is called when the popup closes as a result of interaction _outside_
   // the popup, e.g. by hitting <esc>
   _popupStateChange(state) {
--- a/browser/components/newtab/lib/PlacesFeed.jsm
+++ b/browser/components/newtab/lib/PlacesFeed.jsm
@@ -361,17 +361,17 @@ class PlacesFeed {
 
   fillSearchTopSiteTerm({ _target, data }) {
     _target.browser.ownerGlobal.gURLBar.search(`${data.label} `);
   }
 
   _getSearchPrefix() {
     const searchAliases =
       Services.search.defaultEngine.wrappedJSObject.__internalAliases;
-    if (searchAliases && searchAliases.length > 0) {
+    if (searchAliases && searchAliases.length) {
       return `${searchAliases[0]} `;
     }
     return "";
   }
 
   handoffSearchToAwesomebar({ _target, data, meta }) {
     const searchAlias = this._getSearchPrefix();
     const urlBar = _target.browser.ownerGlobal.gURLBar;
--- a/browser/components/newtab/lib/ShortURL.jsm
+++ b/browser/components/newtab/lib/ShortURL.jsm
@@ -66,17 +66,17 @@ function shortURL({ url }) {
     return url;
   }
 
   // Clean up the url (lowercase hostname via URL and remove www.)
   const hostname = parsed.hostname.replace(/^www\./i, "");
 
   // Remove the eTLD (e.g., com, net) and the preceding period from the hostname
   const eTLD = getETLD(hostname);
-  const eTLDExtra = eTLD.length > 0 ? -(eTLD.length + 1) : Infinity;
+  const eTLDExtra = eTLD.length ? -(eTLD.length + 1) : Infinity;
 
   // Ideally get the short eTLD-less host but fall back to longer url parts
   return (
     handleIDNHost(hostname.slice(0, eTLDExtra) || hostname) ||
     parsed.pathname ||
     parsed.href
   );
 }
--- a/browser/components/newtab/lib/TopStoriesFeed.jsm
+++ b/browser/components/newtab/lib/TopStoriesFeed.jsm
@@ -309,31 +309,31 @@ this.TopStoriesFeed = class TopStoriesFe
         affinities.timeSegments,
         affinities.parameterSets,
         affinities.maxHistoryQueryResults,
         affinities.version,
         affinities.scores
       );
       this.domainAffinitiesLastUpdated = affinities._timestamp;
     }
-    if (stories && stories.length > 0 && this.storiesLastUpdated === 0) {
+    if (stories && !!stories.length && this.storiesLastUpdated === 0) {
       this.updateSettings(data.stories.settings);
       this.stories = this.rotate(this.transform(stories));
       this.storiesLastUpdated = data.stories._timestamp;
       if (data.stories.spocs && data.stories.spocs.length) {
         this.spocCampaignMap = new Map(
           data.stories.spocs.map(s => [s.id, `${s.campaign_id}`])
         );
         this.spocs = this.transform(data.stories.spocs).filter(
           s => s.score >= s.min_score
         );
         this.cleanUpCampaignImpressionPref();
       }
     }
-    if (topics && topics.length > 0 && this.topicsLastUpdated === 0) {
+    if (topics && !!topics.length && this.topicsLastUpdated === 0) {
       this.topics = topics;
       this.topicsLastUpdated = data.topics._timestamp;
     }
 
     return { topics: this.topics, stories: this.stories };
   }
 
   dispatchRelevanceScore(start) {
--- a/browser/components/newtab/test/unit/asrouter/CFRMessageProvider.test.js
+++ b/browser/components/newtab/test/unit/asrouter/CFRMessageProvider.test.js
@@ -46,13 +46,13 @@ describe("CFRMessageProvider", () => {
 
     // 6 en-* locales, fr and de
     assert.lengthOf(pinTabMessage.targeting.match(/en-|fr|de/g), 8);
   });
   it("should contain `www.` version of the hosts", () => {
     const pinTabMessage = messages.find(m => m.id === "PIN_TAB");
 
     assert.isTrue(
-      pinTabMessage.trigger.params.filter(host => host.startsWith("www."))
-        .length > 0
+      !!pinTabMessage.trigger.params.filter(host => host.startsWith("www."))
+        .length
     );
   });
 });
--- a/browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx
+++ b/browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx
@@ -458,17 +458,17 @@ describe("<TopSiteLink>", () => {
   it("should not add the url to the href if it a search shortcut", () => {
     link.searchTopSite = true;
     const wrapper = shallow(<TopSiteLink link={link} />);
     assert.isUndefined(wrapper.find("a").props().href);
   });
   it("should have rtl direction automatically set for text", () => {
     const wrapper = shallow(<TopSiteLink link={link} />);
 
-    assert.isTrue(wrapper.find("[dir='auto']").length > 0);
+    assert.isTrue(!!wrapper.find("[dir='auto']").length);
   });
   it("should render a title", () => {
     const wrapper = shallow(<TopSiteLink link={link} title="foobar" />);
     const titleEl = wrapper.find(".title");
 
     assert.equal(titleEl.text(), "foobar");
   });
   it("should have only the title as the text of the link", () => {
--- a/browser/components/originattributes/test/browser/file_windowOpenerRestrictionTarget.html
+++ b/browser/components/originattributes/test/browser/file_windowOpenerRestrictionTarget.html
@@ -5,17 +5,17 @@
   <title>title not set</title>
   <script>
     // If the query string is given, we are expecting the window.opener can be accessed
     // across different first party domains, so we will match the cookie value.
     // Otherwise, the access of window.opener should be treated as cross-origin.
     // Therefore, it should fail at this setting.
     let openerRestriction = true;
     let cookieValue;
-    if (window.location.search.length > 0) {
+    if (window.location.search.length) {
       cookieValue = window.location.search.substr(1);
       openerRestriction = false;
     }
 
     try {
       let openerFrame = window.opener.frames.child;
       let result = openerFrame.document.cookie === cookieValue;
       if (result && !openerRestriction) {
--- a/browser/components/payments/PaymentUIService.jsm
+++ b/browser/components/payments/PaymentUIService.jsm
@@ -240,17 +240,17 @@ PaymentUIService.prototype = {
 
     if (!dialogContainer.hidden) {
       // If the container is no longer hidden then the background was added after
       // `tabmodaldialogready` so remove it.
       browser.parentElement.querySelector(".paymentDialogBackground").remove();
 
       if (
         !browser.tabModalPromptBox ||
-        browser.tabModalPromptBox.listPrompts().length == 0
+        !browser.tabModalPromptBox.listPrompts().length
       ) {
         browser.removeAttribute("tabmodalPromptShowing");
       }
     }
     return true;
   },
 
   getDialogContainerForMerchantBrowser(merchantBrowser) {
--- a/browser/components/payments/res/components/address-option.js
+++ b/browser/components/payments/res/components/address-option.js
@@ -138,17 +138,17 @@ export default class AddressOption exten
         continue;
       }
 
       if (!fieldEl.textContent && !requiredFields.includes(field.fieldId)) {
         // The field is empty and we don't need to show "Missing …" so don't append.
         continue;
       }
 
-      if (lineEl.children.length > 0) {
+      if (lineEl.children.length) {
         lineEl.append(this.dataset.fieldSeparator);
       }
       lineEl.appendChild(fieldEl);
 
       // Add a break after this field, if requested.
       if (++visibleFieldCount == breakAfterNthField) {
         lineEl = this._line2;
       }
--- a/browser/components/payments/res/paymentRequest.js
+++ b/browser/components/payments/res/paymentRequest.js
@@ -138,18 +138,18 @@ var paymentRequest = {
       tempAddresses: detail.tempAddresses,
       tempBasicCards: detail.tempBasicCards,
       isPrivate: detail.isPrivate,
       page: {
         id: "payment-summary",
       },
     };
 
-    let hasSavedAddresses = Object.keys(this.getAddresses(state)).length != 0;
-    let hasSavedCards = Object.keys(this.getBasicCards(state)).length != 0;
+    let hasSavedAddresses = !!Object.keys(this.getAddresses(state)).length;
+    let hasSavedCards = !!Object.keys(this.getBasicCards(state)).length;
     let shippingRequested = state.request.paymentOptions.requestShipping;
 
     // Onboarding wizard flow.
     if (!hasSavedAddresses && shippingRequested) {
       state.page = {
         id: "shipping-address-page",
         onboardingWizard: true,
       };
@@ -277,17 +277,17 @@ var paymentRequest = {
         modifier.supportedMethods &&
         modifier.supportedMethods != selectedMethod.methodName
       ) {
         return false;
       }
       let supportedNetworks =
         (modifier.data && modifier.data.supportedNetworks) || [];
       return (
-        supportedNetworks.length == 0 ||
+        !supportedNetworks.length ||
         supportedNetworks.includes(selectedMethod["cc-type"])
       );
     });
     return appliedModifier || null;
   },
 
   /**
    * @param {object} state object representing the UI state
--- a/browser/components/payments/test/mochitest/test_address_form.html
+++ b/browser/components/payments/test/mochitest/test_address_form.html
@@ -577,17 +577,17 @@ add_task(async function test_customMerch
     savedAddresses: {
       [address1.guid]: deepClone(address1),
     },
   };
   await form.requestStore.setState(state);
   display.appendChild(form);
   await asyncElementRendered();
 
-  ok(form.querySelectorAll(":-moz-ui-invalid").length > 0, "Check fields are visibly invalid");
+  ok(!!form.querySelectorAll(":-moz-ui-invalid").length, "Check fields are visibly invalid");
   info("merchant cleared the errors");
   await form.requestStore.setState({
     request: {
       paymentDetails: {
         shippingAddressErrors: {},
       },
       paymentOptions: {},
     },
--- a/browser/components/payments/test/mochitest/test_basic_card_form.html
+++ b/browser/components/payments/test/mochitest/test_basic_card_form.html
@@ -440,17 +440,17 @@ add_task(async function test_edit() {
       guid: minimalCard.guid,
       selectedStateKey: "selectedPaymentCard",
     },
     savedBasicCards: {
       [minimalCard.guid]: deepClone(minimalCard),
     },
   });
   await asyncElementRendered();
-  ok(form.querySelectorAll(":-moz-ui-invalid").length > 0,
+  ok(!!form.querySelectorAll(":-moz-ui-invalid").length,
      "Check fields are visibly invalid on an 'edit' form with missing fields");
   checkCCForm(form, minimalCard);
 
   info("change to no selected card");
   await form.requestStore.setState({
     page: {
       id: "basic-card-page",
     },
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -915,17 +915,17 @@ var PlacesUIUtils = {
       title: aFetchInfo.title,
       uri: aFetchInfo.url !== undefined ? aFetchInfo.url.href : "",
 
       get type() {
         if (aFetchInfo.itemType == PlacesUtils.bookmarks.TYPE_FOLDER) {
           return Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER;
         }
 
-        if (this.uri.length == 0) {
+        if (!this.uri.length) {
           throw new Error("Unexpected item type");
         }
 
         if (/^place:/.test(this.uri)) {
           if (this.isFolderShortcutQueryString(this.uri)) {
             return Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT;
           }
 
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -815,17 +815,17 @@ PlacesViewBase.prototype = {
   _onPopupShowing: function PVB__onPopupShowing(aEvent) {
     // Avoid handling popupshowing of inner views.
     let popup = aEvent.originalTarget;
 
     this._ensureMarkers(popup);
 
     // Remove any delayed element, see _cleanPopup for details.
     if ("_delayedRemovals" in popup) {
-      while (popup._delayedRemovals.length > 0) {
+      while (popup._delayedRemovals.length) {
         popup.removeChild(popup._delayedRemovals.shift());
       }
     }
 
     if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
       if (!popup._placesNode.containerOpen) {
         popup._placesNode.containerOpen = true;
       }
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -934,17 +934,17 @@ PlacesController.prototype = {
     for (let range of ranges) {
       totalItems += await this._removeRange(
         range,
         transactions,
         removedFolders
       );
     }
 
-    if (transactions.length > 0) {
+    if (transactions.length) {
       await PlacesUIUtils.batchUpdatesForNode(
         this._view.result,
         totalItems,
         async () => {
           await PlacesTransactions.batch(transactions);
         }
       );
     }
@@ -1109,17 +1109,17 @@ PlacesController.prototype = {
     if (action == "cut" && actionOwner != this.profileName) {
       action = "copy";
     }
 
     return action;
   },
 
   _releaseClipboardOwnership: function PC__releaseClipboardOwnership() {
-    if (this.cutNodes.length > 0) {
+    if (this.cutNodes.length) {
       // This clears the logical clipboard, doesn't remove data.
       this.clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
     }
   },
 
   _clearClipboard: function PC__clearClipboard() {
     let xferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(
       Ci.nsITransferable
@@ -1170,17 +1170,17 @@ PlacesController.prototype = {
     let xferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(
       Ci.nsITransferable
     );
     xferable.init(null);
     let hasData = false;
     // This order matters here!  It controls how this and other applications
     // select data to be inserted based on type.
     contents.forEach(function(content) {
-      if (content.entries.length > 0) {
+      if (content.entries.length) {
         hasData = true;
         let glue =
           content.type == PlacesUtils.TYPE_X_MOZ_PLACE ? "," : PlacesUtils.endl;
         addData(content.type, content.entries.join(glue));
       }
     });
 
     // Track the exected action in the xferable.  This must be the last flavor
@@ -1304,17 +1304,17 @@ PlacesController.prototype = {
       this._view
     );
 
     // Cut/past operations are not repeatable, so clear the clipboard.
     if (action == "cut") {
       this._clearClipboard();
     }
 
-    if (itemsToSelect.length > 0) {
+    if (itemsToSelect.length) {
       this._view.selectItems(itemsToSelect, false);
     }
   },
 
   /**
    * Checks if we can insert into a container.
    * @param   container
    *          The container were we are want to drop
--- a/browser/components/places/content/editBookmark.js
+++ b/browser/components/places/content/editBookmark.js
@@ -183,17 +183,17 @@ var gEditItemOverlay = {
     this._keyword = newKeyword;
     this._initTextField(this._keywordField, newKeyword);
 
     if (!newKeyword) {
       let entries = [];
       await PlacesUtils.keywords.fetch({ url: this._paneInfo.uri.spec }, e =>
         entries.push(e)
       );
-      if (entries.length > 0) {
+      if (entries.length) {
         // We show an existing keyword if either POST data was not provided, or
         // if the POST data is the same.
         let existingKeyword = entries[0].keyword;
         let postData = this._paneInfo.postData;
         if (postData) {
           let sameEntry = entries.find(e => e.postData === postData);
           existingKeyword = sameEntry ? sameEntry.keyword : "";
         }
@@ -575,23 +575,23 @@ var gEditItemOverlay = {
    * For a given array of currently-set tags and the tags-input-field
    * value, returns which tags should be removed and which should be added in
    * the form of { removedTags: [...], newTags: [...] }.
    */
   _getTagsChanges(aCurrentTags) {
     let inputTags = this._getTagsArrayFromTagsInputField();
 
     // Optimize the trivial cases (which are actually the most common).
-    if (inputTags.length == 0 && aCurrentTags.length == 0) {
+    if (!inputTags.length && !aCurrentTags.length) {
       return { newTags: [], removedTags: [] };
     }
-    if (inputTags.length == 0) {
+    if (!inputTags.length) {
       return { newTags: [], removedTags: aCurrentTags };
     }
-    if (aCurrentTags.length == 0) {
+    if (!aCurrentTags.length) {
       return { newTags: inputTags, removedTags: [] };
     }
 
     // Do not remove tags that may be reinserted with a different
     // case, since the tagging service may handle those more efficiently.
     let lcInputTags = inputTags.map(t => t.toLowerCase());
     let removedTags = aCurrentTags.filter(
       t => !lcInputTags.includes(t.toLowerCase())
@@ -604,27 +604,27 @@ var gEditItemOverlay = {
   _setTagsFromTagsInputField(aCurrentTags, aURIs) {
     let { removedTags, newTags } = this._getTagsChanges(aCurrentTags);
     if (removedTags.length + newTags.length == 0) {
       return false;
     }
 
     let setTags = async () => {
       let promises = [];
-      if (removedTags.length > 0) {
+      if (removedTags.length) {
         let promise = PlacesTransactions.Untag({
           urls: aURIs,
           tags: removedTags,
         })
           .transact()
           .catch(Cu.reportError);
         this.transactionPromises.push(promise);
         promises.push(promise);
       }
-      if (newTags.length > 0) {
+      if (newTags.length) {
         let promise = PlacesTransactions.Tag({ urls: aURIs, tags: newTags })
           .transact()
           .catch(Cu.reportError);
         this.transactionPromises.push(promise);
         promises.push(promise);
       }
       // Don't use Promise.all because we want these to be executed in order.
       for (let promise of promises) {
@@ -990,17 +990,17 @@ var gEditItemOverlay = {
    *
    * @return Array of tag strings found in the field value.
    */
   _getTagsArrayFromTagsInputField() {
     let tags = this._element("tagsField").value;
     return tags
       .trim()
       .split(/\s*,\s*/) // Split on commas and remove spaces.
-      .filter(tag => tag.length > 0); // Kill empty tags.
+      .filter(tag => !!tag.length); // Kill empty tags.
   },
 
   async newFolder() {
     let ip = this._folderTree.insertionPoint;
 
     // default to the bookmarks menu folder
     if (!ip) {
       ip = new PlacesInsertionPoint({
--- a/browser/components/places/content/places-tree.js
+++ b/browser/components/places/content/places-tree.js
@@ -736,17 +736,17 @@
         if (index != -1) {
           nodes.push(node);
           foundOne = true;
           guids.splice(index, 1);
         }
 
         var concreteGuid = PlacesUtils.getConcreteItemGuid(node);
         if (
-          guids.length == 0 ||
+          !guids.length ||
           !PlacesUtils.nodeIsContainer(node) ||
           checkedGuidsSet.has(concreteGuid)
         ) {
           return foundOne;
         }
 
         // Only follow a query if it has been been explicitly opened by the
         // caller. We support the "AllBookmarks" case to allow callers to
@@ -763,21 +763,17 @@
         }
 
         checkedGuidsSet.add(concreteGuid);
 
         // Remember the beginning state so that we can re-close
         // this node if we don't find any additional results here.
         var previousOpenness = node.containerOpen;
         node.containerOpen = true;
-        for (
-          var child = 0;
-          child < node.childCount && guids.length > 0;
-          child++
-        ) {
+        for (var child = 0; child < node.childCount && guids.length; child++) {
           var childNode = node.getChild(child);
           var found = findNodes(childNode);
           if (!foundOne) {
             foundOne = found;
           }
         }
 
         // If we didn't find any additional matches in this node's
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -250,22 +250,22 @@ var PlacesOrganizer = {
   handleEvent: function PO_handleEvent(aEvent) {
     if (aEvent.type != "AppCommand") {
       return;
     }
 
     aEvent.stopPropagation();
     switch (aEvent.command) {
       case "Back":
-        if (this._backHistory.length > 0) {
+        if (this._backHistory.length) {
           this.back();
         }
         break;
       case "Forward":
-        if (this._forwardHistory.length > 0) {
+        if (this._forwardHistory.length) {
           this.forward();
         }
         break;
       case "Search":
         PlacesSearchBox.findAll();
         break;
     }
   },
@@ -292,26 +292,26 @@ var PlacesOrganizer = {
 
     if (!this._places.hasSelection) {
       // If no node was found for the given place: uri, just load it directly
       ContentArea.currentPlace = aLocation;
     }
     this.updateDetailsPane();
 
     // update navigation commands
-    if (this._backHistory.length == 0) {
+    if (!this._backHistory.length) {
       document
         .getElementById("OrganizerCommand:Back")
         .setAttribute("disabled", true);
     } else {
       document
         .getElementById("OrganizerCommand:Back")
         .removeAttribute("disabled");
     }
-    if (this._forwardHistory.length == 0) {
+    if (!this._forwardHistory.length) {
       document
         .getElementById("OrganizerCommand:Forward")
         .setAttribute("disabled", true);
     } else {
       document
         .getElementById("OrganizerCommand:Forward")
         .removeAttribute("disabled");
     }
@@ -538,17 +538,17 @@ var PlacesOrganizer = {
 
     // Remove existing menu items.  Last item is the restoreFromFile item.
     while (restorePopup.childNodes.length > 1) {
       restorePopup.firstChild.remove();
     }
 
     (async function() {
       let backupFiles = await PlacesBackups.getBackupFiles();
-      if (backupFiles.length == 0) {
+      if (!backupFiles.length) {
         return;
       }
 
       // Populate menu with backups.
       for (let i = 0; i < backupFiles.length; i++) {
         let fileSize = (await OS.File.stat(backupFiles[i])).size;
         let [size, unit] = DownloadUtils.convertByteUnits(fileSize);
         let sizeString = PlacesUtils.getFormattedString("backupFileSizeText", [
@@ -824,17 +824,17 @@ var PlacesSearchBox = {
     return document.getElementById("searchFilter");
   },
 
   /**
    * Folders to include when searching.
    */
   _folders: [],
   get folders() {
-    if (this._folders.length == 0) {
+    if (!this._folders.length) {
       this._folders = PlacesUtils.bookmarks.userContentRoots;
     }
     return this._folders;
   },
   set folders(aFolders) {
     this._folders = aFolders;
     return aFolders;
   },
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -170,17 +170,17 @@ PlacesTreeView.prototype = {
       throw new Error("The root node is never visible");
     }
 
     // A node is removed form the view either if it has no parent or if its
     // root-ancestor is not the root node (in which case that's the node
     // for which nodeRemoved was called).
     let ancestors = Array.from(PlacesUtils.nodeAncestors(aNode));
     if (
-      ancestors.length == 0 ||
+      !ancestors.length ||
       ancestors[ancestors.length - 1] != this._rootNode
     ) {
       throw new Error("Removed node passed to _getRowForNode");
     }
 
     // Ensure that the entire chain is open, otherwise that node is invisible.
     for (let ancestor of ancestors) {
       if (!ancestor.containerOpen) {
@@ -517,17 +517,17 @@ PlacesTreeView.prototype = {
    *        _getSelectedNodesInRange.
    * @param aUpdatedContainer
    *        The container which was updated.
    */
   _restoreSelection: function PTV__restoreSelection(
     aNodesInfo,
     aUpdatedContainer
   ) {
-    if (aNodesInfo.length == 0) {
+    if (!aNodesInfo.length) {
       return;
     }
 
     let selection = this.selection;
 
     // Attempt to ensure that previously-visible selection will be visible
     // if it's re-selected.  However, we can only ensure that for one row.
     let scrollToRow = -1;
@@ -850,17 +850,17 @@ PlacesTreeView.prototype = {
       throw Cr.NS_ERROR_UNEXPECTED;
     }
 
     // If this node is a container it could take up more than one row.
     let count = this._countVisibleRowsForNodeAtRow(oldRow);
 
     // Persist selection state.
     let nodesToReselect = this._getSelectedNodesInRange(oldRow, oldRow + count);
-    if (nodesToReselect.length > 0) {
+    if (nodesToReselect.length) {
       this.selection.selectEventsSuppressed = true;
     }
 
     // Redraw the parent if its twisty state has changed.
     if (aOldParent != this._rootNode && !aOldParent.hasChildren) {
       let parentRow = oldRow - 1;
       this._tree.invalidateRow(parentRow);
     }
@@ -870,17 +870,17 @@ PlacesTreeView.prototype = {
       this._nodeDetails.delete(makeNodeDetailsKey(splicedNode));
     }
     this._tree.rowCountChanged(oldRow, -count);
 
     // Insert the node into the new position.
     this.nodeInserted(aNewParent, aNode, aNewIndex);
 
     // Restore selection.
-    if (nodesToReselect.length > 0) {
+    if (nodesToReselect.length) {
       this._restoreSelection(nodesToReselect, aNewParent);
       this.selection.selectEventsSuppressed = false;
     }
   },
 
   _invalidateCellValue: function PTV__invalidateCellValue(aNode, aColumnType) {
     console.assert(this._result, "Got a notification but have no result!");
     if (!this._tree || !this._result) {
@@ -1056,17 +1056,17 @@ PlacesTreeView.prototype = {
       let oldSelectionCount = this.selection.count;
       if (replaceCount) {
         this._tree.rowCountChanged(startReplacement, -replaceCount);
       }
 
       // Select the row next to the closed container if any of its
       // children were selected, and nothing else is selected.
       if (
-        nodesToReselect.length > 0 &&
+        nodesToReselect.length &&
         nodesToReselect.length == oldSelectionCount
       ) {
         this.selection.rangedSelect(startReplacement, startReplacement, true);
         this._tree.ensureRowIsVisible(startReplacement);
       }
 
       this.selection.selectEventsSuppressed = false;
       return;
--- a/browser/components/places/tests/browser/browser_paste_into_tags.js
+++ b/browser/components/places/tests/browser/browser_paste_into_tags.js
@@ -61,17 +61,17 @@ add_task(async function() {
   tags = PlacesUtils.tagging.getTagsForURI(MOZURISPEC);
   ok(tags.length == 1, "history node is tagged: " + tags.length);
 
   // check if a bookmark was created
   let bookmarks = [];
   await PlacesUtils.bookmarks.fetch({ url: MOZURISPEC }, bm => {
     bookmarks.push(bm);
   });
-  ok(bookmarks.length > 0, "bookmark exists for the tagged history item");
+  ok(!!bookmarks.length, "bookmark exists for the tagged history item");
 
   // is the bookmark visible in the UI?
   // get the Unsorted Bookmarks node
   PlacesOrganizer.selectLeftPaneBuiltIn("UnfiledBookmarks");
 
   // now we can see what is in the ContentTree tree
   let unsortedNode = ContentTree.view.view.nodeForTreeIndex(1);
   ok(unsortedNode, "unsortedNode is not null: " + unsortedNode.uri);
--- a/browser/components/places/tests/browser/browser_sort_in_library.js
+++ b/browser/components/places/tests/browser/browser_sort_in_library.js
@@ -165,17 +165,17 @@ function testInvalid(aOrganizerWin, aPla
  *        the Places window
  * @param aPlaceContentTree
  *        the placeContent tree in aOrganizerWin
  * @param aUnsortFirst
  *        true if, before each sort we try, we should sort to SORT_BY_NONE
  */
 function testSortByColAndDir(aOrganizerWin, aPlaceContentTree, aUnsortFirst) {
   let cols = aPlaceContentTree.getElementsByTagName("treecol");
-  ok(cols.length > 0, "sanity check: placeContent should contain columns");
+  ok(!!cols.length, "sanity check: placeContent should contain columns");
 
   for (let i = 0; i < cols.length; i++) {
     let col = cols.item(i);
     ok(
       col.hasAttribute("anonid"),
       "sanity check: column " + col.id + " should have anonid"
     );
 
--- a/browser/components/preferences/browserLanguages.js
+++ b/browser/components/preferences/browserLanguages.js
@@ -61,17 +61,17 @@ async function installFromUrl(url, hash,
   await install.install();
   return install.addon;
 }
 
 async function dictionaryIdsForLocale(locale) {
   let entries = await RemoteSettings("language-dictionaries").get({
     filters: { id: locale },
   });
-  if (entries.length > 0) {
+  if (entries.length) {
     return entries[0].dictionaries;
   }
   return [];
 }
 
 class OrderedListBox {
   constructor({
     richlistbox,
@@ -507,17 +507,17 @@ var gBrowserLanguagesDialog = {
     this._availableLocales.setItems(items);
     this._availableLocales.enableWithMessageId(
       "browser-languages-select-language"
     );
   },
 
   async loadLocalesFromInstalled(available) {
     let items;
-    if (available.length > 0) {
+    if (available.length) {
       items = await getLocaleDisplayInfo(available);
       items.push(await this.createInstalledLabel());
     } else {
       items = [];
     }
     if (this.downloadEnabled) {
       items.push({
         label: await document.l10n.formatValue("browser-languages-search"),
--- a/browser/components/preferences/in-content/findInPage.js
+++ b/browser/components/preferences/in-content/findInPage.js
@@ -189,17 +189,17 @@ var gSearchResultsPane = {
         }
       }
       let range = document.createRange();
       range.setStart(startNode, startValue);
       range.setEnd(endNode, endValue);
       this.getFindSelection(startNode.ownerGlobal).addRange(range);
     }
 
-    return indices.length > 0;
+    return !!indices.length;
   },
 
   /**
    * Get the selection instance from given window
    *
    * @param Object win
    *   The window object points to frame's window
    */
@@ -562,17 +562,17 @@ var gSearchResultsPane = {
       //
       // The result is an array of arrays of l10n ids and optionally attribute names.
       //
       // Example: [["containers-add-button", "label"], ["user-context-personal"]]
       const refs = nodeObject
         .getAttribute("search-l10n-ids")
         .split(",")
         .map(s => s.trim().split("."))
-        .filter(s => s[0].length > 0);
+        .filter(s => !!s[0].length);
 
       const messages = await document.l10n.formatMessages(
         refs.map(ref => ({ id: ref[0] }))
       );
 
       // Map the localized messages taking value or a selected attribute and
       // building a string of concatenated translated strings out of it.
       let keywords = messages
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -1057,17 +1057,17 @@ var gMainPane = {
     );
     contentContainer.textContent = "";
     gMainPane.requestingLocales = null;
   },
 
   /* Confirm the locale change and restart the browser in the new locale. */
   confirmBrowserLanguageChange(event) {
     let localesString = (event.target.getAttribute("locales") || "").trim();
-    if (!localesString || localesString.length == 0) {
+    if (!localesString || !localesString.length) {
       return;
     }
     let locales = localesString.split(",");
     Services.locale.requestedLocales = locales;
 
     // Record the change in telemetry before we restart.
     gMainPane.recordBrowserLanguagesTelemetry("apply");
 
--- a/browser/components/preferences/in-content/subdialogs.js
+++ b/browser/components/preferences/in-content/subdialogs.js
@@ -613,17 +613,17 @@ var gSubDialog = {
    * @type {Array}
    */
   _dialogs: [],
   _dialogStack: null,
   _dialogTemplate: null,
   _nextDialogID: 0,
   _preloadDialog: null,
   get _topDialog() {
-    return this._dialogs.length > 0
+    return this._dialogs.length
       ? this._dialogs[this._dialogs.length - 1]
       : undefined;
   },
 
   init() {
     this._dialogStack = document.getElementById("dialogStack");
     this._dialogTemplate = document.getElementById("dialogTemplate");
     this._preloadDialog = new SubDialog({
@@ -634,17 +634,17 @@ var gSubDialog = {
   },
 
   open(aURL, aFeatures = null, aParams = null, aClosingCallback = null) {
     // If we're already open/opening on this URL, do nothing.
     if (this._topDialog && this._topDialog._openedURL == aURL) {
       return;
     }
 
-    if (this._dialogs.length == 0) {
+    if (!this._dialogs.length) {
       // When opening the first dialog, show the dialog stack to make sure
       // the browser binding can be constructed.
       this._dialogStack.hidden = false;
     }
 
     this._preloadDialog.open(aURL, aFeatures, aParams, aClosingCallback);
     this._dialogs.push(this._preloadDialog);
     this._preloadDialog = new SubDialog({
--- a/browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
+++ b/browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
@@ -179,17 +179,17 @@ function getDialogId(dialogDoc) {
 function assertTelemetryRecorded(events) {
   let snapshot = Services.telemetry.snapshotEvents(
     Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
     true
   );
 
   // Make sure we got some data.
   ok(
-    snapshot.parent && snapshot.parent.length > 0,
+    snapshot.parent && !!snapshot.parent.length,
     "Got parent telemetry events in the snapshot"
   );
 
   // Only look at the related events after stripping the timestamp and category.
   let relatedEvents = snapshot.parent
     .filter(([timestamp, category]) => category == TELEMETRY_CATEGORY)
     .map(relatedEvent => relatedEvent.slice(2, 6));
 
@@ -598,17 +598,17 @@ add_task(async function testInstallFromA
   is(
     Services.locale.availableLocales.sort().join(","),
     "en-US,pl",
     "Polish is now installed"
   );
 
   await BrowserTestUtils.waitForCondition(async () => {
     let newDicts = await AddonManager.getAddonsByTypes(["dictionary"]);
-    let done = newDicts.length != 0;
+    let done = !!newDicts.length;
 
     if (done) {
       is(
         newDicts[0].id,
         DICTIONARY_ID_PL,
         "The polish dictionary was installed"
       );
     }
--- a/browser/components/preferences/in-content/tests/browser_bug410900.js
+++ b/browser/components/preferences/in-content/tests/browser_bug410900.js
@@ -27,17 +27,17 @@ function test() {
     .then(() => runTest(gBrowser.selectedBrowser.contentWindow));
 }
 
 function runTest(win) {
   var rbox = win.document.getElementById("handlersView");
   ok(rbox, "handlersView is present");
 
   var items = rbox && rbox.getElementsByTagName("richlistitem");
-  ok(items && items.length > 0, "App handler list populated");
+  ok(items && !!items.length, "App handler list populated");
 
   var handlerAdded = false;
   for (let i = 0; i < items.length; i++) {
     if (items[i].getAttribute("type") == "apppanetest") {
       handlerAdded = true;
     }
   }
   ok(handlerAdded, "apppanetest protocol handler was successfully added");
--- a/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js
+++ b/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js
@@ -541,17 +541,17 @@ async function runTest(test, getObservan
 function createObserveAllPromise(observances) {
   return new Promise(resolve => {
     let permObserver = {
       observe(aSubject, aTopic, aData) {
         if (aTopic != "perm-changed") {
           return;
         }
 
-        if (observances.length == 0) {
+        if (!observances.length) {
           // Should fail here as we are not expecting a notification, but we
           // don't. See bug 1063410.
           return;
         }
 
         info(`observed perm-changed (remaining ${observances.length - 1})`);
 
         let permission = aSubject.QueryInterface(Ci.nsIPermission);
@@ -571,17 +571,17 @@ function createObserveAllPromise(observa
         if (expected.origin) {
           is(
             permission.principal.origin,
             expected.origin,
             'property: "origin" should be equal'
           );
         }
 
-        if (observances.length == 0) {
+        if (!observances.length) {
           Services.obs.removeObserver(permObserver, "perm-changed");
           executeSoon(resolve);
         }
       },
     };
     Services.obs.addObserver(permObserver, "perm-changed");
   });
 }
--- a/browser/components/preferences/in-content/tests/browser_permissions_checkPermissionsWereAdded.js
+++ b/browser/components/preferences/in-content/tests/browser_permissions_checkPermissionsWereAdded.js
@@ -44,17 +44,17 @@ const _addWebsiteAddressToPermissionBox 
   is(
     buttonDialog.hasAttribute("disabled"),
     false,
     "When the user add an url the button should be clickable"
   );
   buttonDialog.click();
   let permissionsBox = dialog.document.getElementById("permissionsBox");
   let children = permissionsBox.getElementsByAttribute("origin", "*");
-  is(children.length == 0, false, "Website added in url should be in the list");
+  is(!children.length, false, "Website added in url should be in the list");
 };
 
 const _checkIfPermissionsWereAdded = (dialog, expectedResult) => {
   let permissionsBox = dialog.document.getElementById("permissionsBox");
   for (let website of expectedResult) {
     let elements = permissionsBox.getElementsByAttribute("origin", website);
     is(elements.length, 1, "It should find only one coincidence");
   }
--- a/browser/components/preferences/in-content/tests/siteData/head.js
+++ b/browser/components/preferences/in-content/tests/siteData/head.js
@@ -257,17 +257,17 @@ async function loadServiceWorkerTestPage
     );
   }, `Fail to load service worker test ${url}`);
   BrowserTestUtils.removeTab(tab);
 }
 
 function promiseServiceWorkersCleared() {
   return BrowserTestUtils.waitForCondition(() => {
     let serviceWorkers = serviceWorkerManager.getAllRegistrations();
-    if (serviceWorkers.length == 0) {
+    if (!serviceWorkers.length) {
       ok(true, "Cleared all service workers");
       return true;
     }
     return false;
   }, "Should clear all service workers");
 }
 
 function promiseServiceWorkerRegisteredFor(url) {
--- a/browser/components/preferences/languages.js
+++ b/browser/components/preferences/languages.js
@@ -181,17 +181,17 @@ var gLanguagesDialog = {
       this._acceptLanguages[languages[i]] = true;
     }
 
     // We're forcing an early localization here because otherwise
     // the initial sizing of the dialog will happen before it and
     // result in overflow.
     await document.l10n.translateFragment(this._activeLanguages);
 
-    if (this._activeLanguages.childNodes.length > 0) {
+    if (this._activeLanguages.childNodes.length) {
       this._activeLanguages.ensureIndexIsVisible(selectedIndex);
       this._activeLanguages.selectedIndex = selectedIndex;
     }
 
     // Update states of accept-language list and buttons according to
     // privacy.resistFingerprinting and privacy.spoof_english.
     this.readSpoofEnglish();
   },
--- a/browser/components/preferences/siteDataSettings.js
+++ b/browser/components/preferences/siteDataSettings.js
@@ -143,18 +143,18 @@ let gSiteDataSettings = {
     setEventListener("removeAll", "command", this.onClickRemoveAll);
     setEventListener("removeSelected", "command", this.removeSelected);
   },
 
   _updateButtonsState() {
     let items = this._list.getElementsByTagName("richlistitem");
     let removeSelectedBtn = document.getElementById("removeSelected");
     let removeAllBtn = document.getElementById("removeAll");
-    removeSelectedBtn.disabled = this._list.selectedItems.length == 0;
-    removeAllBtn.disabled = items.length == 0;
+    removeSelectedBtn.disabled = !this._list.selectedItems.length;
+    removeAllBtn.disabled = !items.length;
 
     let l10nId = this._searchBox.value
       ? "site-data-remove-shown"
       : "site-data-remove-all";
     document.l10n.setAttributes(removeAllBtn, l10nId);
   },
 
   /**
@@ -254,17 +254,17 @@ let gSiteDataSettings = {
   async saveChanges() {
     // Tracks whether the user confirmed their decision.
     let allowed = false;
 
     let removals = this._sites
       .filter(site => site.userAction == "remove")
       .map(site => site.host);
 
-    if (removals.length > 0) {
+    if (removals.length) {
       if (this._sites.length == removals.length) {
         allowed = SiteDataManager.promptSiteDataRemoval(window);
         if (allowed) {
           try {
             await SiteDataManager.removeAll();
           } catch (e) {
             Cu.reportError(e);
           }
@@ -318,17 +318,17 @@ let gSiteDataSettings = {
 
   onCommandSearch() {
     this._buildSitesList(this._sites);
     this._list.clearSelection();
   },
 
   onClickRemoveAll() {
     let siteItems = this._list.getElementsByTagName("richlistitem");
-    if (siteItems.length > 0) {
+    if (siteItems.length) {
       this._removeSiteItems(siteItems);
     }
   },
 
   onKeyPress(e) {
     if (e.keyCode == KeyEvent.DOM_VK_ESCAPE) {
       this.close();
     } else if (
--- a/browser/components/search/test/browser/browser_searchTelemetry.js
+++ b/browser/components/search/test/browser/browser_searchTelemetry.js
@@ -50,17 +50,17 @@ async function assertTelemetry(expectedH
   await TestUtils.waitForCondition(() => {
     histSnapshot = searchCounts.snapshot();
     return (
       Object.getOwnPropertyNames(histSnapshot).length ==
       Object.getOwnPropertyNames(expectedHistograms).length
     );
   }, "should have the correct number of histograms");
 
-  if (Object.entries(expectedScalars).length > 0) {
+  if (Object.entries(expectedScalars).length) {
     await TestUtils.waitForCondition(() => {
       scalars =
         Services.telemetry.getSnapshotForKeyedScalars("main", false).parent ||
         {};
       return Object.getOwnPropertyNames(expectedScalars).every(
         scalar => scalar in scalars
       );
     }, "should have the expected keyed scalars");
--- a/browser/components/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm
+++ b/browser/components/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm
@@ -87,17 +87,17 @@ var RecentlyClosedTabsAndWindowsMenuUtil
     aWindow,
     aTagName,
     aPrefixRestoreAll = false,
     aRestoreAllLabel = "menuRestoreAllWindows.label"
   ) {
     let closedWindowData = SessionStore.getClosedWindowData(false);
     let doc = aWindow.document;
     let fragment = doc.createDocumentFragment();
-    if (closedWindowData.length != 0) {
+    if (closedWindowData.length) {
       let menuLabelString = navigatorBundle.GetStringFromName(
         "menuUndoCloseWindowLabel"
       );
       let menuLabelStringSingleTab = navigatorBundle.GetStringFromName(
         "menuUndoCloseWindowSingleTabLabel"
       );
 
       for (let i = 0; i < closedWindowData.length; i++) {
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -2064,17 +2064,17 @@ var SessionStoreInternal = {
       for (let j = openTabs.length - 1; j >= 0; j--) {
         if (openTabs[j].entries.some(containsDomain, this)) {
           openTabs.splice(j, 1);
           if (this._closedWindows[ix].selected > j) {
             this._closedWindows[ix].selected--;
           }
         }
       }
-      if (openTabs.length == 0) {
+      if (!openTabs.length) {
         this._closedWindows.splice(ix, 1);
       } else if (openTabs.length != openTabCount) {
         // Adjust the window's title if we removed an open tab
         let selectedTab = openTabs[this._closedWindows[ix].selected - 1];
         // some duplication from restoreHistory - make sure we get the correct title
         let activeIndex = (selectedTab.index || selectedTab.entries.length) - 1;
         if (activeIndex >= selectedTab.entries.length) {
           activeIndex = selectedTab.entries.length - 1;
@@ -3817,17 +3817,17 @@ var SessionStoreInternal = {
 
     if (winData.sizemode != "minimized") {
       winData.sizemodeBeforeMinimized = winData.sizemode;
     }
 
     var hidden = WINDOW_HIDEABLE_FEATURES.filter(function(aItem) {
       return aWindow[aItem] && !aWindow[aItem].visible;
     });
-    if (hidden.length != 0) {
+    if (hidden.length) {
       winData.hidden = hidden.join(",");
     } else if (winData.hidden) {
       delete winData.hidden;
     }
 
     let sidebarBox = aWindow.document.getElementById("sidebar-box");
     let sidebar = sidebarBox.getAttribute("sidebarcommand");
     if (sidebar && sidebarBox.getAttribute("checked") == "true") {
@@ -3908,24 +3908,24 @@ var SessionStoreInternal = {
     if (AppConstants.platform != "macosx") {
       // If no non-popup browser window remains open, return the state of the last
       // closed window(s). We only want to do this when we're actually "ending"
       // the session.
       // XXXzpao We should do this for _restoreLastWindow == true, but that has
       //        its own check for popups. c.f. bug 597619
       if (
         nonPopupCount == 0 &&
-        lastClosedWindowsCopy.length > 0 &&
+        !!lastClosedWindowsCopy.length &&
         RunState.isQuitting
       ) {
         // prepend the last non-popup browser window, so that if the user loads more tabs
         // at startup we don't accidentally add them to a popup window
         do {
           total.unshift(lastClosedWindowsCopy.shift());
-        } while (total[0].isPopup && lastClosedWindowsCopy.length > 0);
+        } while (total[0].isPopup && lastClosedWindowsCopy.length);
       }
     }
 
     if (activeWindow) {
       this.activeWindowSSiCache = activeWindow.__SSi || "";
     }
     ix = ids.indexOf(this.activeWindowSSiCache);
     // We don't want to restore focus to a minimized window or a window which had all its
@@ -4080,17 +4080,17 @@ var SessionStoreInternal = {
     if (!winData.tabs) {
       winData.tabs = [];
       // don't restore a single blank tab when we've had an external
       // URL passed in for loading at startup (cf. bug 357419)
     } else if (
       firstWindow &&
       !overwriteTabs &&
       winData.tabs.length == 1 &&
-      (!winData.tabs[0].entries || winData.tabs[0].entries.length == 0)
+      (!winData.tabs[0].entries || !winData.tabs[0].entries.length)
     ) {
       winData.tabs = [];
     }
 
     // See SessionStoreInternal.restoreTabs for a description of what
     // selectTab represents.
     let selectTab = 0;
     if (overwriteTabs) {
@@ -5294,17 +5294,17 @@ var SessionStoreInternal = {
    * @param aRecentCrashes is the number of consecutive crashes
    * @returns whether a restore page will be needed for the session state
    */
   _needsRestorePage: function ssi_needsRestorePage(aState, aRecentCrashes) {
     const SIX_HOURS_IN_MS = 6 * 60 * 60 * 1000;
 
     // don't display the page when there's nothing to restore
     let winData = aState.windows || null;
-    if (!winData || winData.length == 0) {
+    if (!winData || !winData.length) {
       return false;
     }
 
     // don't wrap a single about:sessionrestore page
     if (
       this._hasSingleTabWithURL(winData, "about:sessionrestore") ||
       this._hasSingleTabWithURL(winData, "about:welcomeback")
     ) {
--- a/browser/components/sessionstore/test/browser_393716.js
+++ b/browser/components/sessionstore/test/browser_393716.js
@@ -32,17 +32,17 @@ add_task(async function test_set_tabstat
   let state = ss.getTabState(tab);
   ok(state, "get the tab's state");
 
   // verify the tab state's integrity
   state = JSON.parse(state);
   ok(
     state instanceof Object &&
       state.entries instanceof Array &&
-      state.entries.length > 0,
+      !!state.entries.length,
     "state object seems valid"
   );
   ok(
     state.entries.length == 1 && state.entries[0].url == URL,
     "Got the expected state object (test URL)"
   );
   ok(
     state.extData && state.extData[key] == value,
--- a/browser/components/sessionstore/test/browser_background_tab_crash.js
+++ b/browser/components/sessionstore/test/browser_background_tab_crash.js
@@ -75,17 +75,17 @@ async function setupBackgroundTabs(testF
  *
  * @param tabs (Array(<xul:tab>))
  *        The tabs to crash.
  * @return Promise
  *        Resolves once the tabs have crashed and entered the pending
  *        background state.
  */
 async function crashBackgroundTabs(tabs) {
-  Assert.ok(tabs.length > 0, "Need to crash at least one tab.");
+  Assert.ok(!!tabs.length, "Need to crash at least one tab.");
   for (let tab of tabs) {
     Assert.ok(tab.linkedBrowser.isRemoteBrowser, "tab is remote");
   }
 
   let remotenessChangePromises = tabs.map(t => {
     return BrowserTestUtils.waitForEvent(t, "TabRemotenessChange");
   });
 
--- a/browser/components/syncedtabs/TabListView.js
+++ b/browser/components/syncedtabs/TabListView.js
@@ -575,17 +575,17 @@ TabListView.prototype = {
         } else if (
           el.getAttribute("id") != "syncedTabsOpenAllInTabs" &&
           el.getAttribute("id") != "syncedTabsManageDevices"
         ) {
           show = true;
         }
       } else if (el.getAttribute("id") == "syncedTabsOpenAllInTabs") {
         const tabs = item.querySelectorAll(".item-tabs-list > .item.tab");
-        show = tabs.length > 0;
+        show = !!tabs.length;
       } else if (el.getAttribute("id") == "syncedTabsRefresh") {
         show = true;
       } else if (el.getAttribute("id") == "syncedTabsManageDevices") {
         show = true;
       }
       el.hidden = !show;
 
       el = el.nextElementSibling;
--- a/browser/components/translation/TranslationDocument.jsm
+++ b/browser/components/translation/TranslationDocument.jsm
@@ -67,17 +67,17 @@ this.TranslationDocument.prototype = {
     // basically represents an element from a page with only text content
     // inside.
 
     // This distinction is useful for optimization purposes: we treat a
     // simple root as plain-text in the translation process and with that
     // we are able to reduce their data payload sent to the translation service.
 
     for (let root of this.roots) {
-      if (root.children.length == 0 && root.nodeRef.childElementCount == 0) {
+      if (!root.children.length && root.nodeRef.childElementCount == 0) {
         root.isSimpleRoot = true;
       }
     }
   },
 
   /**
    * Creates a TranslationItem object, which should be called
    * for each node returned by getTranslationNodes.
@@ -492,17 +492,17 @@ function parseResultNode(item, node) {
  * @param target   A string that is either "translation"
  *                 or "original".
  */
 function swapTextForItem(item, target) {
   // visitStack is the stack of items that we still need to visit.
   // Let's start the process by adding the root item.
   let visitStack = [item];
 
-  while (visitStack.length > 0) {
+  while (visitStack.length) {
     let curItem = visitStack.shift();
 
     let domNode = curItem.nodeRef;
     if (!domNode) {
       // Skipping this item due to a missing node.
       continue;
     }
 
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -411,17 +411,17 @@ var UITour = {
             }
 
             let iconURL = null;
             if (typeof data.icon == "string") {
               iconURL = this.resolveURL(browser, data.icon);
             }
 
             let buttons = [];
-            if (Array.isArray(data.buttons) && data.buttons.length > 0) {
+            if (Array.isArray(data.buttons) && data.buttons.length) {
               for (let buttonData of data.buttons) {
                 if (
                   typeof buttonData == "object" &&
                   typeof buttonData.label == "string" &&
                   typeof buttonData.callbackID == "string"
                 ) {
                   let callback = buttonData.callbackID;
                   let button = {
@@ -843,17 +843,17 @@ var UITour = {
       // character restriction on the value - they will be escaped as necessary.
       let reSimpleString = /^[-_a-zA-Z0-9]*$/;
       for (let name in campaignParams) {
         let value = campaignParams[name];
         if (
           typeof name != "string" ||
           typeof value != "string" ||
           !name.startsWith("utm_") ||
-          value.length == 0 ||
+          !value.length ||
           !reSimpleString.test(name)
         ) {
           log.warn("_populateCampaignParams: invalid campaign param specified");
           return false;
         }
         url.searchParams.append(name, value);
       }
     }
--- a/browser/components/uitour/test/head.js
+++ b/browser/components/uitour/test/head.js
@@ -529,17 +529,17 @@ function done(usingAddTask = false) {
       } else {
         executeSoon(nextTest);
       }
     });
   });
 }
 
 function nextTest() {
-  if (tests.length == 0) {
+  if (!tests.length) {
     info("finished tests in this file");
     finish();
     return;
   }
   let test = tests.shift();
   info("Starting " + test.name);
   waitForFocus(function() {
     loadUITourTestPage(function() {
--- a/browser/components/urlbar/UrlbarController.jsm
+++ b/browser/components/urlbar/UrlbarController.jsm
@@ -387,17 +387,17 @@ class UrlbarController {
    * @param {string} reason Reason for the speculative connect request.
    * @note speculative connect to:
    *  - Search engine heuristic results
    *  - autofill results
    *  - http/https results
    */
   speculativeConnect(result, context, reason) {
     // Never speculative connect in private contexts.
-    if (!this.input || context.isPrivate || context.results.length == 0) {
+    if (!this.input || context.isPrivate || !context.results.length) {
       return;
     }
     let { url } = UrlbarUtils.getUrlFromResult(result);
     if (!url) {
       return;
     }
 
     switch (reason) {
--- a/browser/components/urlbar/UrlbarEventBufferer.jsm
+++ b/browser/components/urlbar/UrlbarEventBufferer.jsm
@@ -226,17 +226,17 @@ class UrlbarEventBufferer {
    * Checks whether a given event should be deferred
    * @param {Event} event The event that should maybe be deferred.
    * @returns {boolean} Whether the event should be deferred.
    */
   shouldDeferEvent(event) {
     // If any event has been deferred for this search, then defer all subsequent
     // events so that the user does not experience them out of order.
     // All events will be replayed when _deferringTimeout fires.
-    if (this._eventsQueue.length > 0) {
+    if (this._eventsQueue.length) {
       return true;
     }
 
     // At this point, no events have been deferred for this search; we must
     // figure out if this event should be deferred.
     let isMacNavigation =
       AppConstants.platform == "macosx" &&
       event.ctrlKey &&
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -1958,17 +1958,17 @@ function getDroppableData(event) {
     links = Services.droppedLinkHandler.dropLinks(event);
   } catch (ex) {
     // This is either an unexpected failure or a security exception; in either
     // case we should always return null.
     return null;
   }
   // The URL bar automatically handles inputs with newline characters,
   // so we can get away with treating text/x-moz-url flavours as text/plain.
-  if (links.length > 0 && links[0].url) {
+  if (links.length && links[0].url) {
     event.preventDefault();
     let href = links[0].url;
     if (UrlbarUtils.stripUnsafeProtocolOnPaste(href) != href) {
       // We may have stripped an unsafe protocol like javascript: and if so
       // there's no point in handling a partial drop.
       event.stopImmediatePropagation();
       return null;
     }
--- a/browser/components/urlbar/UrlbarTokenizer.jsm
+++ b/browser/components/urlbar/UrlbarTokenizer.jsm
@@ -153,17 +153,17 @@ var UrlbarTokenizer = {
    * returns false, it's surely not an origin, if it returns true, the result
    * must still be verified through URIFixup.
    *
    * @param {string} token
    *        The string token to verify
    * @returns {boolean} whether the token looks like an origin.
    */
   looksLikeOrigin(token) {
-    if (token.length == 0) {
+    if (!token.length) {
       return false;
     }
     let atIndex = token.indexOf("@");
     if (atIndex != -1 && this.REGEXP_COMMON_EMAIL.test(token)) {
       // We prefer handling it as an email rather than an origin with userinfo.
       return false;
     }
     let userinfo = atIndex != -1 ? token.slice(0, atIndex) : "";
@@ -307,17 +307,17 @@ function filterTokens(tokens) {
       tokenObj.type = UrlbarTokenizer.TYPE.POSSIBLE_ORIGIN;
     } else if (UrlbarTokenizer.looksLikeUrl(token, { requirePath: true })) {
       tokenObj.type = UrlbarTokenizer.TYPE.POSSIBLE_URL;
     }
     filtered.push(tokenObj);
   }
 
   // Handle restriction characters.
-  if (restrictions.length > 0) {
+  if (restrictions.length) {
     // We can apply two kind of restrictions: type (bookmark, search, ...) and
     // matching (url, title). These kind of restrictions can be combined, but we
     // can only have one restriction per kind.
     let matchingRestrictionFound = false;
     let typeRestrictionFound = false;
     function assignRestriction(r) {
       if (r && !(matchingRestrictionFound && typeRestrictionFound)) {
         if (
--- a/browser/components/urlbar/UrlbarView.jsm
+++ b/browser/components/urlbar/UrlbarView.jsm
@@ -757,17 +757,17 @@ class UrlbarView {
     );
     title._tooltip = result.title;
     if (title.hasAttribute("overflow")) {
       title.setAttribute("title", title._tooltip);
     }
 
     let tagsContainer = item._elements.get("tagsContainer");
     tagsContainer.textContent = "";
-    if (result.payload.tags && result.payload.tags.length > 0) {
+    if (result.payload.tags && result.payload.tags.length) {
       tagsContainer.append(
         ...result.payload.tags.map((tag, i) => {
           const element = this._createElement("span");
           element.className = "urlbarView-tag";
           this._addTextContentWithHighlights(
             element,
             tag,
             result.payloadHighlights.tags[i]
--- a/browser/components/urlbar/tests/UrlbarTestUtils.jsm
+++ b/browser/components/urlbar/tests/UrlbarTestUtils.jsm
@@ -136,18 +136,18 @@ var UrlbarTestUtils = {
     details.title = result.title;
     details.tags = "tags" in result.payload ? result.payload.tags : [];
     let actions = element.getElementsByClassName("urlbarView-action");
     let urls = element.getElementsByClassName("urlbarView-url");
     let typeIcon = element.querySelector(".urlbarView-type-icon");
     let typeIconStyle = win.getComputedStyle(typeIcon);
     details.displayed = {
       title: element.getElementsByClassName("urlbarView-title")[0].textContent,
-      action: actions.length > 0 ? actions[0].textContent : null,
-      url: urls.length > 0 ? urls[0].textContent : null,
+      action: actions.length ? actions[0].textContent : null,
+      url: urls.length ? urls[0].textContent : null,
       typeIcon: typeIconStyle["background-image"],
     };
     details.element = {
       action: element.getElementsByClassName("urlbarView-action")[0],
       row: element,
       separator: element.getElementsByClassName(
         "urlbarView-title-separator"
       )[0],
--- a/browser/components/urlbar/tests/browser/browser_autocomplete_a11y_label.js
+++ b/browser/components/urlbar/tests/browser/browser_autocomplete_a11y_label.js
@@ -130,10 +130,10 @@ add_task(async function searchSuggestion
           "— Search with browser_searchSuggestionEngine searchSuggestionEngine.xml",
         "Result label should be: <search term>— Search with <engine name>"
       );
       if (!selected) {
         element.toggleAttribute("selected", false);
       }
     }
   }
-  Assert.ok(expectedSearches.length == 0);
+  Assert.ok(!expectedSearches.length);
 });
--- a/browser/components/urlbar/tests/browser/browser_urlbarCopying.js
+++ b/browser/components/urlbar/tests/browser/browser_urlbarCopying.js
@@ -236,17 +236,17 @@ var tests = [
   {
     copyVal: "<example.com/би>ография",
     copyExpected: "http://example.com/би",
   },
 ];
 
 function nextTest() {
   let testCase = tests.shift();
-  if (tests.length == 0) {
+  if (!tests.length) {
     runTest(testCase, finish);
   } else {
     runTest(testCase, nextTest);
   }
 }
 
 function runTest(testCase, cb) {
   function doCheck() {
@@ -287,17 +287,17 @@ function testCopy(copyVal, targetValue, 
       }
       if (startBracket > endBracket || startBracket == -1) {
         offsets = [];
         break;
       }
       offsets.push([startBracket, endBracket - 1]);
       copyVal = copyVal.replace("<", "").replace(">", "");
     }
-    if (offsets.length == 0 || copyVal != gURLBar.value) {
+    if (!offsets.length || copyVal != gURLBar.value) {
       ok(false, "invalid copyVal: " + copyVal);
     }
     gURLBar.selectionStart = offsets[0][0];
     gURLBar.selectionEnd = offsets[0][1];
     if (offsets.length > 1) {
       let sel = gURLBar.editor.selection;
       let r0 = sel.getRangeAt(0);
       let node0 = r0.startContainer;
--- a/browser/components/urlbar/tests/browser/browser_urlbar_speculative_connect_not_with_client_cert.js
+++ b/browser/components/urlbar/tests/browser/browser_urlbar_speculative_connect_not_with_client_cert.js
@@ -35,17 +35,17 @@ const clientAuthDialogs = {
     rememberClientAuthCertificate
   ) {
     ok(
       expectingChooseCertificate,
       `${
         expectingChooseCertificate ? "" : "not "
       }expecting chooseCertificate to be called`
     );
-    ok(certList.length > 0, "Should have at least one certificate");
+    ok(!!certList.length, "Should have at least one certificate");
     selectedIndex.value = 0;
     rememberClientAuthCertificate.value = false;
     chooseCertificateCalled = true;
     return true;
   },
 
   QueryInterface: ChromeUtils.generateQI([Ci.nsIClientAuthDialogs]),
 };
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -512,17 +512,17 @@ class FormAutofillSection {
    *          A record object consists of three properties:
    *            - guid: The id of the previously-filled profile or null if omitted.
    *            - record: A valid record converted from details with trimmed result.
    *            - untouchedFields: Fields that aren't touched after autofilling.
    *          Return `null` for any uncreatable or invalid record.
    */
   createRecord() {
     let details = this.fieldDetails;
-    if (!this.isEnabled() || !details || details.length == 0) {
+    if (!this.isEnabled() || !details || !details.length) {
       return null;
     }
 
     let data = {
       guid: this.filledRecordGUID,
       record: {},
       untouchedFields: [],
     };
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -162,17 +162,17 @@ class FieldScanner {
    *          each section.
    */
   getSectionFieldDetails() {
     // When the section feature is disabled, `getSectionFieldDetails` should
     // provide a single address and credit card section result.
     if (!this._sectionEnabled) {
       return this._getFinalDetails(this.fieldDetails);
     }
-    if (this._sections.length == 0) {
+    if (!this._sections.length) {
       return [];
     }
     if (
       this._sections.length == 1 &&
       this._sections[0].name == DEFAULT_SECTION_NAME
     ) {
       this._classifySections();
     }
@@ -299,17 +299,17 @@ class FieldScanner {
         // Deduplicate each set of fieldDetails
         let details = section.fieldDetails;
         section.fieldDetails = details.filter((detail, index) => {
           let previousFields = details.slice(0, index);
           return !previousFields.find(f => this._isSameField(detail, f));
         });
         return section;
       })
-      .filter(section => section.fieldDetails.length > 0);
+      .filter(section => !!section.fieldDetails.length);
   }
 
   elementExisting(index) {
     return index < this._elements.length;
   }
 }
 
 var LabelUtils = {
@@ -347,17 +347,17 @@ var LabelUtils = {
       return this._labelStrings.get(element);
     }
     let strings = [];
     let _extractLabelStrings = el => {
       if (this.EXCLUDED_TAGS.includes(el.tagName)) {
         return;
       }
 
-      if (el.nodeType == el.TEXT_NODE || el.childNodes.length == 0) {
+      if (el.nodeType == el.TEXT_NODE || !el.childNodes.length) {
         let trimmedText = el.textContent.trim();
         if (trimmedText) {
           strings.push(trimmedText);
         }
         return;
       }
 
       for (let node of el.childNodes) {
@@ -995,17 +995,17 @@ this.FormAutofillHeuristics = {
         fieldName: "email",
         section: "",
         addressType: "",
         contactType: "",
       };
     }
 
     let regexps = this._getRegExpList(isAutoCompleteOff, element.tagName);
-    if (regexps.length == 0) {
+    if (!regexps.length) {
       return null;
     }
 
     let matchedFieldName = this._findMatchedFieldName(element, regexps);
     if (matchedFieldName) {
       return {
         fieldName: matchedFieldName,
         section: "",
--- a/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
+++ b/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
@@ -73,17 +73,17 @@ class ProfileAutoCompleteResult {
     // Force return success code if the focused field is auto-filled in order
     // to show clear form button popup.
     if (isInputAutofilled) {
       resultCode = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
     }
     // The result code of this result object.
     if (resultCode) {
       this.searchResult = resultCode;
-    } else if (matchingProfiles.length > 0) {
+    } else if (matchingProfiles.length) {
       this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
     } else {
       this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
     }
 
     // An array of primary and secondary labels for each profile.
     this._popupLabels = this._generateLabels(
       this._focusedFieldName,
--- a/browser/extensions/formautofill/content/editDialog.js
+++ b/browser/extensions/formautofill/content/editDialog.js
@@ -127,19 +127,17 @@ class AutofillEditDialog {
     if (event.keyCode == KeyEvent.DOM_VK_ESCAPE) {
       window.close();
     }
   }
 
   updateSaveButtonState() {
     // Toggle disabled attribute on the save button based on
     // whether the form is filled or empty.
-    if (
-      Object.keys(this._elements.fieldContainer.buildFormObject()).length == 0
-    ) {
+    if (!Object.keys(this._elements.fieldContainer.buildFormObject()).length) {
       this._elements.save.setAttribute("disabled", true);
     } else {
       this._elements.save.removeAttribute("disabled");
     }
   }
 
   /**
    * Attach event listener
--- a/browser/extensions/formautofill/test/browser/head.js
+++ b/browser/extensions/formautofill/test/browser/head.js
@@ -238,17 +238,17 @@ async function expectPopupOpen(browser) 
   const { autoCompletePopup } = browser;
   await BrowserTestUtils.waitForCondition(
     () => autoCompletePopup.popupOpen,
     "popup should be open"
   );
   await BrowserTestUtils.waitForCondition(() => {
     const listItemElems = getDisplayedPopupItems(browser);
     return (
-      [...listItemElems].length > 0 &&
+      !![...listItemElems].length &&
       [...listItemElems].every(item => {
         return (
           (item.getAttribute("originaltype") == "autofill-profile" ||
             item.getAttribute("originaltype") == "autofill-insecureWarning" ||
             item.getAttribute("originaltype") == "autofill-footer") &&
           item.hasAttribute("formautofillattached")
         );
       })
@@ -324,17 +324,17 @@ function removeAddresses(guids) {
 function removeCreditCards(guids) {
   info("expecting credit card removed");
   Services.cpmm.sendAsyncMessage("FormAutofill:RemoveCreditCards", { guids });
   return TestUtils.topicObserved("formautofill-storage-changed");
 }
 
 function getNotification(index = 0) {
   let notifications = PopupNotifications.panel.childNodes;
-  ok(notifications.length > 0, "at least one notification displayed");
+  ok(!!notifications.length, "at least one notification displayed");
   ok(true, notifications.length + " notification(s)");
   return notifications[index];
 }
 
 /**
  * Clicks the popup notification button and wait for popup hidden.
  *
  * @param {string} button The button type in popup notification.
--- a/browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js
+++ b/browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js
@@ -137,17 +137,17 @@ var ParentUtils = {
     await this._operateRecord(CREDITCARDS_COLLECTION_NAME, ...arguments);
   },
 
   async cleanUpAddresses() {
     const guids = (await this._getRecords(ADDRESSES_COLLECTION_NAME)).map(
       record => record.guid
     );
 
-    if (guids.length == 0) {
+    if (!guids.length) {
       return;
     }
 
     await this.operateAddress(
       "remove",
       { guids },
       "FormAutofillTest:AddressesCleanedUp"
     );
@@ -156,17 +156,17 @@ var ParentUtils = {
   async cleanUpCreditCards() {
     if (!FormAutofill.isAutofillCreditCardsAvailable) {
       return;
     }
     const guids = (await this._getRecords(CREDITCARDS_COLLECTION_NAME)).map(
       record => record.guid
     );
 
-    if (guids.length == 0) {
+    if (!guids.length) {
       return;
     }
 
     await this.operateCreditCard(
       "remove",
       { guids },
       "FormAutofillTest:CreditCardsCleanedUp"
     );
--- a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js
+++ b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js
@@ -417,17 +417,17 @@ add_task(async function test_all_pattern
       expectedValue.items.forEach((item, index) => {
         equal(actual.getValueAt(index), item.value);
         equal(actual.getCommentAt(index), item.comment);
         equal(actual.getLabelAt(index), item.label);
         equal(actual.getStyleAt(index), item.style);
         equal(actual.getImageAt(index), item.image);
       });
 
-      if (expectedValue.items.length != 0) {
+      if (expectedValue.items.length) {
         Assert.throws(
           () => actual.getValueAt(expectedItemLength),
           /Index out of range\./
         );
 
         Assert.throws(
           () => actual.getLabelAt(expectedItemLength),
           /Index out of range\./
--- a/browser/extensions/pdfjs/test/browser_pdfjs_main.js
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_main.js
@@ -57,16 +57,16 @@ add_task(async function test() {
         // Verify that initial page is 1
         var pgNumber = content.document.querySelector("input#pageNumber").value;
         Assert.equal(parseInt(pgNumber, 10), 1, "initial page is 1");
 
         // Bookmark button
         var viewBookmark = content.document.querySelector("a#viewBookmark");
         viewBookmark.click();
 
-        Assert.ok(viewBookmark.href.length > 0, "viewBookmark button has href");
+        Assert.ok(!!viewBookmark.href.length, "viewBookmark button has href");
 
         var viewer = content.wrappedJSObject.PDFViewerApplication;
         await viewer.close();
       });
     }
   );
 });
--- a/browser/modules/AsyncTabSwitcher.jsm
+++ b/browser/modules/AsyncTabSwitcher.jsm
@@ -1303,17 +1303,17 @@ class AsyncTabSwitcher {
       dump(s + "\n");
     } else {
       Services.console.logStringMessage(s);
     }
   }
 
   addLogFlag(flag, ...subFlags) {
     if (this.logging()) {
-      if (subFlags.length > 0) {
+      if (subFlags.length) {
         flag += `(${subFlags.map(f => (f ? 1 : 0)).join("")})`;
       }
       this._logFlags.push(flag);
     }
   }
 
   logState(suffix) {
     if (!this.logging()) {
@@ -1415,23 +1415,23 @@ class AsyncTabSwitcher {
         } else {
           accum += `${lastMatch}...${i - 1}:${tabStrings[lastMatch]} `;
         }
       }
 
       lastMatch = i;
     }
 
-    if (unloadedTabsStrings.length > 0) {
+    if (unloadedTabsStrings.length) {
       accum += `${unloadedTabsStrings.join(",")}:(unloaded) `;
     }
 
     accum += "cached: " + this.tabLayerCache.length + " ";
 
-    if (this._logFlags.length > 0) {
+    if (this._logFlags.length) {
       accum += `[${this._logFlags.join(",")}] `;
       this._logFlags = [];
     }
 
     // It can be annoying to read through the entirety of a log string just
     // to check if something changed or not. So if we can tell that nothing
     // changed, just write "unchanged" to save the reader's time.
     let logString;
--- a/browser/modules/ExtensionsUI.jsm
+++ b/browser/modules/ExtensionsUI.jsm
@@ -235,17 +235,17 @@ var ExtensionsUI = {
         Services.prefs.getBoolPref("extensions.ui.ignoreUnsigned", false)
       ) {
         info.unsigned = false;
       }
 
       let strings = this._buildStrings(info);
 
       // If this is an update with no promptable permissions, just apply it
-      if (info.type == "update" && strings.msgs.length == 0) {
+      if (info.type == "update" && !strings.msgs.length) {
         info.resolve();
         return;
       }
 
       let icon = info.unsigned
         ? "chrome://browser/skin/warning.svg"
         : info.icon;
 
@@ -283,17 +283,17 @@ var ExtensionsUI = {
         }
       );
     } else if (topic == "webextension-update-permissions") {
       let info = subject.wrappedJSObject;
       info.type = "update";
       let strings = this._buildStrings(info);
 
       // If we don't prompt for any new permissions, just apply it
-      if (strings.msgs.length == 0) {
+      if (!strings.msgs.length) {
         info.resolve();
         return;
       }
 
       let update = {
         strings,
         permissions: info.permissions,
         install: info.install,
@@ -321,17 +321,17 @@ var ExtensionsUI = {
       } = subject.wrappedJSObject;
       let strings = this._buildStrings({
         type: "optional",
         addon: { name },
         permissions,
       });
 
       // If we don't have any promptable permissions, just proceed
-      if (strings.msgs.length == 0) {
+      if (!strings.msgs.length) {
         resolve(true);
         return;
       }
       resolve(this.showPermissionsPrompt(browser, strings, icon));
     } else if (topic == "webextension-defaultsearch-prompt") {
       let {
         browser,
         name,
@@ -394,24 +394,24 @@ var ExtensionsUI = {
         let doc = this.browser.ownerDocument;
         if (topic == "showing") {
           let textEl = doc.getElementById("addon-webext-perm-text");
           textEl.textContent = strings.text;
           textEl.hidden = !strings.text;
 
           let listIntroEl = doc.getElementById("addon-webext-perm-intro");
           listIntroEl.textContent = strings.listIntro;
-          listIntroEl.hidden = strings.msgs.length == 0;
+          listIntroEl.hidden = !strings.msgs.length;
 
           let listInfoEl = doc.getElementById("addon-webext-perm-info");
           listInfoEl.textContent = strings.learnMore;
           listInfoEl.href =
             Services.urlFormatter.formatURLPref("app.support.baseURL") +
             "extension-permissions";
-          listInfoEl.hidden = strings.msgs.length == 0;
+          listInfoEl.hidden = !strings.msgs.length;
 
           let list = doc.getElementById("addon-webext-perm-list");
           while (list.firstChild) {
             list.firstChild.remove();
           }
 
           for (let msg of strings.msgs) {
             let item = doc.createElementNS(HTML_NS, "li");
--- a/browser/modules/FaviconLoader.jsm
+++ b/browser/modules/FaviconLoader.jsm
@@ -421,17 +421,17 @@ function guessType(icon) {
 
 /*
  * Selects the best rich icon and tab icon from a list of IconInfo objects.
  *
  * @param {Array} iconInfos A list of IconInfo objects.
  * @param {integer} preferredWidth The preferred width for tab icons.
  */
 function selectIcons(iconInfos, preferredWidth) {
-  if (iconInfos.length == 0) {
+  if (!iconInfos.length) {
     return {
       richIcon: null,
       tabIcon: null,
     };
   }
 
   let preferredIcon;
   let bestSizedIcon;
@@ -593,17 +593,17 @@ class FaviconLoader {
     );
   }
 
   loadIcons() {
     // If the page is unloaded immediately after the DeferredTask's timer fires
     // we can still attempt to load icons, which will fail since the content
     // window is no longer available. Checking if iconInfos has been cleared
     // allows us to bail out early in this case.
-    if (this.iconInfos.length == 0) {
+    if (!this.iconInfos.length) {
       return;
     }
 
     let preferredWidth =
       PREFERRED_WIDTH * Math.ceil(this.mm.content.devicePixelRatio);
     let { richIcon, tabIcon } = selectIcons(this.iconInfos, preferredWidth);
     this.iconInfos = [];
 
--- a/browser/modules/PermissionUI.jsm
+++ b/browser/modules/PermissionUI.jsm
@@ -1057,17 +1057,17 @@ PermissionUI.PersistentStoragePermission
  * @param request (nsIContentPermissionRequest)
  *        The request for a permission from content.
  */
 function MIDIPermissionPrompt(request) {
   this.request = request;
   let types = request.types.QueryInterface(Ci.nsIArray);
   let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
   this.isSysexPerm =
-    perm.options.length > 0 &&
+    !!perm.options.length &&
     perm.options.queryElementAt(0, Ci.nsISupportsString) == "sysex";
   this.permName = "midi";
   if (this.isSysexPerm) {
     this.permName = "midi-sysex";
   }
 }
 
 MIDIPermissionPrompt.prototype = {
--- a/browser/modules/Sanitizer.jsm
+++ b/browser/modules/Sanitizer.jsm
@@ -547,17 +547,17 @@ var Sanitizer = {
           // started prompting, stop, because the user might not even remember initiating the
           // 'forget', and the timespans will be all wrong by now anyway:
           if (Date.now() > startDate + 60 * 1000) {
             this._resetAllWindowClosures(windowList);
             throw new Error("Sanitize could not close windows: timeout");
           }
         }
 
-        if (windowList.length == 0) {
+        if (!windowList.length) {
           return;
         }
 
         // If/once we get here, we should actually be able to close all windows.
 
         let refObj = {};
         TelemetryStopwatch.start("FX_SANITIZE_OPENWINDOWS", refObj);
 
--- a/browser/modules/WindowsJumpLists.jsm
+++ b/browser/modules/WindowsJumpLists.jsm
@@ -213,17 +213,17 @@ var WinTaskbarJumpList = {
    *       _pendingStatements object, using a different LIST_TYPE entry for
    *       each statement. Once finished they must remove it and call
    *       commitBuild().  When there will be no more _pendingStatements,
    *       commitBuild() will commit for real.
    */
 
   _pendingStatements: {},
   _hasPendingStatements: function WTBJL__hasPendingStatements() {
-    return Object.keys(this._pendingStatements).length > 0;
+    return !!Object.keys(this._pendingStatements).length;
   },
 
   async _buildList() {
     if (this._hasPendingStatements()) {
       // We were requested to update the list while another update was in
       // progress, this could happen at shutdown, idle or privatebrowsing.
       // Abort the current list building.
       for (let listType in this._pendingStatements) {
@@ -260,17 +260,17 @@ var WinTaskbarJumpList = {
 
   /**
    * Taskbar api wrappers
    */
 
   async _startBuild() {
     this._builder.abortListBuild();
     let URIsToRemove = await this._builder.initListBuild();
-    if (URIsToRemove.length > 0) {
+    if (URIsToRemove.length) {
       // Prior to building, delete removed items from history.
       this._clearHistory(URIsToRemove);
     }
   },
 
   _commitBuild: function WTBJL__commitBuild() {
     if (this._hasPendingStatements()) {
       return;
@@ -297,26 +297,26 @@ var WinTaskbarJumpList = {
         task.description,
         task.args,
         task.iconIndex,
         null
       );
       items.appendElement(item);
     }, this);
 
-    if (items.length > 0) {
+    if (items.length) {
       this._builder.addListToBuild(
         this._builder.JUMPLIST_CATEGORY_TASKS,
         items
       );
     }
   },
 
   _buildCustom: function WTBJL__buildCustom(title, items) {
-    if (items.length > 0) {
+    if (items.length) {
       this._builder.addListToBuild(
         this._builder.JUMPLIST_CATEGORY_CUSTOMLIST,
         items,
         title
       );
     }
   },
 
@@ -422,17 +422,17 @@ var WinTaskbarJumpList = {
   ) {
     var file = Services.dirsvc.get("XREExeF", Ci.nsIFile);
 
     var handlerApp = Cc[
       "@mozilla.org/uriloader/local-handler-app;1"
     ].createInstance(Ci.nsILocalHandlerApp);
     handlerApp.executable = file;
     // handlers default to the leaf name if a name is not specified
-    if (name && name.length != 0) {
+    if (name && name.length) {
       handlerApp.name = name;
     }
     handlerApp.detailedDescription = description;
     handlerApp.appendParameter(args);
 
     var item = Cc["@mozilla.org/windows-jumplistshortcut;1"].createInstance(
       Ci.nsIJumpListShortcut
     );
@@ -494,17 +494,17 @@ var WinTaskbarJumpList = {
           // in case we get a bad uri
           return Services.io.newURI(spec);
         } catch (e) {
           return null;
         }
       })
       .filter(uri => !!uri);
 
-    if (URIsToRemove.length > 0) {
+    if (URIsToRemove.length) {
       PlacesUtils.history.remove(URIsToRemove).catch(Cu.reportError);
     }
   },
 
   /**
    * Prefs utilities
    */
 
--- a/browser/modules/WindowsPreviewPerTab.jsm
+++ b/browser/modules/WindowsPreviewPerTab.jsm
@@ -834,17 +834,17 @@ var AeroPeek = {
     // This occurs when the taskbar service is not available (xp, vista)
     if (!this.available || !this._prefenabled) {
       return;
     }
 
     win.gTaskbarTabGroup.destroy();
     delete win.gTaskbarTabGroup;
 
-    if (this.windows.length == 0) {
+    if (!this.windows.length) {
       this.destroy();
     }
   },
 
   resetCacheTimer() {
     this.cacheTimer.cancel();
     this.cacheTimer.init(
       this,
--- a/browser/modules/test/browser/browser_PageActions.js
+++ b/browser/modules/test/browser/browser_PageActions.js
@@ -1391,17 +1391,17 @@ add_task(async function perWindowState()
 // removes the action, and then adds it back.  Since the action was removed and
 // re-added without restarting the app (or more accurately without calling
 // PageActions._purgeUnregisteredPersistedActions), the action should remain in
 // persisted state and retain its last placement in the urlbar.
 add_task(async function removeRetainState() {
   // Get the list of actions initially in the urlbar.
   let initialActionsInUrlbar = PageActions.actionsInUrlbar(window);
   Assert.ok(
-    initialActionsInUrlbar.length > 0,
+    !!initialActionsInUrlbar.length,
     "This test expects there to be at least one action in the urlbar initially (like the bookmark star)"
   );
 
   // Add a test action.
   let id = "test-removeRetainState";
   let testAction = PageActions.addAction(
     new PageActions.Action({
       id,
@@ -1749,17 +1749,17 @@ add_task(async function contextMenu() {
   action.remove();
 
   // Check the telemetry was collected properly.
   let snapshot = Services.telemetry.snapshotEvents(
     Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
     true
   );
   ok(
-    snapshot.parent && snapshot.parent.length > 0,
+    snapshot.parent && !!snapshot.parent.length,
     "Got parent telemetry events in the snapshot"
   );
   let relatedEvents = snapshot.parent
     .filter(
       ([timestamp, category, method]) =>
         category == "addonsManager" && method == "action"
     )
     .map(relatedEvent => relatedEvent.slice(3, 6));
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -694,18 +694,18 @@ function prompt(aBrowser, aRequest) {
           // can remove them if the user clicks 'Stop Sharing'. There's no
           // other way for the stop sharing code to know the hostnames of frames
           // using devices until bug 1066082 is fixed.
           let browser = this.browser;
           browser._devicePermissionPrincipals =
             browser._devicePermissionPrincipals || [];
           browser._devicePermissionPrincipals.push(principal);
 
-          let camNeeded = videoDevices.length > 0;
-          let micNeeded = audioDevices.length > 0;
+          let camNeeded = !!videoDevices.length;
+          let micNeeded = !!audioDevices.length;
           checkOSPermission(camNeeded, micNeeded).then(havePermission => {
             if (havePermission) {
               let mm = browser.messageManager;
               mm.sendAsyncMessage("webrtc:Allow", {
                 callID: aRequest.callID,
                 windowID: aRequest.windowID,
                 devices: allowedDevices,
               });
@@ -1062,18 +1062,18 @@ function prompt(aBrowser, aRequest) {
         if (remember) {
           // Remember on which URIs we set persistent permissions so that we
           // can remove them if the user clicks 'Stop Sharing'.
           aBrowser._devicePermissionPrincipals =
             aBrowser._devicePermissionPrincipals || [];
           aBrowser._devicePermissionPrincipals.push(principal);
         }
 
-        let camNeeded = videoDevices.length > 0;
-        let micNeeded = audioDevices.length > 0;
+        let camNeeded = !!videoDevices.length;
+        let micNeeded = !!audioDevices.length;
         let havePermission = await checkOSPermission(camNeeded, micNeeded);
         if (!havePermission) {
           denyRequestNoPermission(notification.browser, aRequest);
           return;
         }
 
         let mm = notification.browser.messageManager;
         mm.sendAsyncMessage("webrtc:Allow", {
--- a/toolkit/actors/DateTimePickerChild.jsm
+++ b/toolkit/actors/DateTimePickerChild.jsm
@@ -171,18 +171,17 @@ class DateTimePickerChild extends JSWind
         let value = this._inputElement.getDateTimeInputBoxValue();
         this.sendAsyncMessage("FormDateTime:OpenPicker", {
           rect: this.getBoundingContentRect(this._inputElement),
           dir: this.getComputedDirection(this._inputElement),
           type: this._inputElement.type,
           detail: {
             // Pass partial value if it's available, otherwise pass input
             // element's value.
-            value:
-              Object.keys(value).length > 0 ? value : this._inputElement.value,
+            value: Object.keys(value).length ? value : this._inputElement.value,
             min: this._inputElement.getMinimum(),
             max: this._inputElement.getMaximum(),
             step: this._inputElement.getStep(),
             stepBase: this._inputElement.getStepBase(),
           },
         });
         break;
       }
--- a/toolkit/actors/PopupBlockingChild.jsm
+++ b/toolkit/actors/PopupBlockingChild.jsm
@@ -135,17 +135,17 @@ class PopupBlockingChild extends ActorCh
           requestingDocument != removedDoc
         ) {
           i++;
         } else {
           this.popupData.splice(i, 1);
           this.popupDataInternal.splice(i, 1);
         }
       }
-      if (this.popupData.length == 0) {
+      if (!this.popupData.length) {
         this.popupData = null;
         this.popupDataInternal = null;
       }
       if (!this.popupData || oldLength > this.popupData.length) {
         this.updateBlockedPopups(false);
       }
     }
   }
--- a/toolkit/components/aboutmemory/content/aboutMemory.js
+++ b/toolkit/components/aboutmemory/content/aboutMemory.js
@@ -1742,17 +1742,17 @@ function appendWarningElements(
       "",
       "WARNING: the moz_malloc_usable_size() function does not work for " +
         "this platform and/or configuration.  This means that much of the " +
         "heap-allocated memory is not measured by individual memory reporters " +
         "and so will fall under 'heap-unclassified'.\n\n"
     );
   }
 
-  if (gUnsafePathsWithInvalidValuesForThisProcess.length > 0) {
+  if (gUnsafePathsWithInvalidValuesForThisProcess.length) {
     let div = appendElement(aP, "div");
     appendElementWithText(
       div,
       "p",
       "",
       "WARNING: the following values are negative or unreasonably large.\n"
     );
 
--- a/toolkit/components/aboutperformance/content/aboutPerformance.js
+++ b/toolkit/components/aboutperformance/content/aboutPerformance.js
@@ -264,17 +264,17 @@ var State = {
 
   /**
    * Update the internal state.
    *
    * @return {Promise}
    */
   async update() {
     // If the buffer is empty, add one value for bootstraping purposes.
-    if (this._buffer.length == 0) {
+    if (!this._buffer.length) {
       this._latest = await this._promiseSnapshot();
       this._buffer.push(this._latest);
       await wait(BUFFER_SAMPLING_RATE_MS * 1.1);
     }
 
     let now = Cu.now();
 
     // If we haven't sampled in a while, add a sample to the buffer.
--- a/toolkit/components/antitracking/test/browser/antitracking_head.js
+++ b/toolkit/components/antitracking/test/browser/antitracking_head.js
@@ -666,17 +666,17 @@ this.AntiTracking = {
         case Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_FOREIGN:
           expectedCategory = "cookieBlockedForeign";
           break;
       }
 
       if (expectedCategory == "") {
         is(allMessages.length, 0, "No console messages should be generated");
       } else {
-        ok(allMessages.length != 0, "Some console message should be generated");
+        ok(!!allMessages.length, "Some console message should be generated");
       }
       for (let msg of allMessages) {
         is(
           msg.category,
           expectedCategory,
           "Message should be of expected category"
         );
       }
--- a/toolkit/components/apppicker/content/appPicker.js
+++ b/toolkit/components/apppicker/content/appPicker.js
@@ -73,17 +73,17 @@ AppPicker.prototype = {
 
     // Grab a list of nsILocalHandlerApp application helpers to list
     var fileList = mimeInfo.possibleLocalHandlers;
 
     var list = document.getElementById("app-picker-listbox");
 
     var primaryCount = 0;
 
-    if (!fileList || fileList.length == 0) {
+    if (!fileList || !fileList.length) {
       // display a message saying nothing is configured
       document.getElementById("app-picker-notfound").removeAttribute("hidden");
       return;
     }
 
     for (var idx = 0; idx < fileList.length; idx++) {
       var file = fileList.queryElementAt(idx, nsILocalHandlerApp);
       try {
--- a/toolkit/components/autocomplete/tests/unit/test_378079.js
+++ b/toolkit/components/autocomplete/tests/unit/test_378079.js
@@ -59,17 +59,17 @@ AutoCompleteInput.prototype = {
 /**
  * nsIAutoCompleteResult implementation
  */
 function AutoCompleteResult(aValues, aComments, aStyles) {
   this._values = aValues;
   this._comments = aComments;
   this._styles = aStyles;
 
-  if (this._values.length > 0) {
+  if (this._values.length) {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
   } else {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
   }
 }
 AutoCompleteResult.prototype = {
   constructor: AutoCompleteResult,
 
--- a/toolkit/components/autocomplete/tests/unit/test_393191.js
+++ b/toolkit/components/autocomplete/tests/unit/test_393191.js
@@ -58,17 +58,17 @@ AutoCompleteInput.prototype = {
 /**
  * nsIAutoCompleteResult implementation
  */
 function AutoCompleteResult(aValues, aComments, aStyles) {
   this._values = aValues;
   this._comments = aComments;
   this._styles = aStyles;
 
-  if (this._values.length > 0) {
+  if (this._values.length) {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
   } else {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
   }
 }
 AutoCompleteResult.prototype = {
   constructor: AutoCompleteResult,
 
--- a/toolkit/components/autocomplete/tests/unit/test_440866.js
+++ b/toolkit/components/autocomplete/tests/unit/test_440866.js
@@ -57,17 +57,17 @@ AutoCompleteInput.prototype = {
 /**
  * nsIAutoCompleteResult implementation
  */
 function AutoCompleteResult(aValues, aComments, aStyles) {
   this._values = aValues;
   this._comments = aComments;
   this._styles = aStyles;
 
-  if (this._values.length > 0) {
+  if (this._values.length) {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
   } else {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
   }
 }
 AutoCompleteResult.prototype = {
   constructor: AutoCompleteResult,
 
--- a/toolkit/components/autocomplete/tests/unit/test_autocomplete_multiple.js
+++ b/toolkit/components/autocomplete/tests/unit/test_autocomplete_multiple.js
@@ -123,24 +123,24 @@ AutoCompleteSearch.prototype = {
   // AutoCompleteResult
   _result: null,
 
   /**
    * Return the same result set for every search
    */
   startSearch(aSearchString, aSearchParam, aPreviousResult, aListener) {
     var result = this._result;
-    if (result._values.length > 0) {
+    if (result._values.length) {
       result.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS_ONGOING;
     } else {
       result.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH_ONGOING;
     }
     aListener.onSearchResult(this, result);
 
-    if (result._values.length > 0) {
+    if (result._values.length) {
       result.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
     } else {
       result.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
     }
     aListener.onSearchResult(this, result);
   },
 
   stopSearch() {},
--- a/toolkit/components/autocomplete/tests/unit/test_previousResult.js
+++ b/toolkit/components/autocomplete/tests/unit/test_previousResult.js
@@ -58,17 +58,17 @@ AutoCompleteInput.prototype = {
 
 /**
  * nsIAutoCompleteResult implementation
  */
 function AutoCompleteResult(aValues, aComments, aStyles) {
   this._values = aValues;
   this._comments = aComments;
   this._styles = aStyles;
-  if (this._values.length > 0) {
+  if (this._values.length) {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
   } else {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
   }
 }
 AutoCompleteResult.prototype = {
   constructor: AutoCompleteResult,
 
--- a/toolkit/components/backgroundhangmonitor/tests/test_BHRObserver.js
+++ b/toolkit/components/backgroundhangmonitor/tests/test_BHRObserver.js
@@ -89,17 +89,17 @@ add_task(async function test_BHRObserver
   equal(hangs.length, 3);
   hangs.forEach(hang => {
     ok(hang.duration > 0);
     ok(hang.thread == "Gecko" || hang.thread == "Gecko_Child");
     equal(typeof hang.runnableName, "string");
 
     // hang.stack
     ok(Array.isArray(hang.stack));
-    ok(hang.stack.length > 0);
+    ok(!!hang.stack.length);
     hang.stack.forEach(entry => {
       // Each stack frame entry is either a native or pseudostack entry. A
       // native stack entry is an array with module index (number), and offset
       // (hex string), while the pseudostack entry is a bare string.
       if (Array.isArray(entry)) {
         equal(entry.length, 2);
         equal(typeof entry[0], "number");
         equal(typeof entry[1], "string");
@@ -136,17 +136,17 @@ add_task(async function test_BHRObserver
 
   telSvc.payload.hangs.forEach(hang => {
     ok(hang.duration > 0);
     ok(hang.thread == "Gecko" || hang.thread == "Gecko_Child");
     equal(typeof hang.runnableName, "string");
 
     // hang.stack
     ok(Array.isArray(hang.stack));
-    ok(hang.stack.length > 0);
+    ok(!!hang.stack.length);
     hang.stack.forEach(entry => {
       // Each stack frame entry is either a native or pseudostack entry. A
       // native stack entry is an array with module index (number), and offset
       // (hex string), while the pseudostack entry is a bare string.
       if (Array.isArray(entry)) {
         equal(entry.length, 2);
         equal(typeof entry[0], "number");
         ok(entry[0] < telSvc.payload.hangs.length);
--- a/toolkit/components/certviewer/content/certviewer.js
+++ b/toolkit/components/certviewer/content/certviewer.js
@@ -42,17 +42,17 @@ const createEntryItem = (label, info) =>
   return {
     label,
     info,
   };
 };
 
 const addToResultUsing = (callback, certItems, sectionTitle, Critical) => {
   let items = callback();
-  if (items.length > 0) {
+  if (items.length) {
     certItems.push({
       sectionTitle,
       sectionItems: items,
       Critical,
     });
   }
 };
 
--- a/toolkit/components/contentprefs/ContentPrefService2.jsm
+++ b/toolkit/components/contentprefs/ContentPrefService2.jsm
@@ -935,17 +935,17 @@ ContentPrefService2.prototype = {
     }
 
     try {
       callbacks.onDone(
         ok
           ? Ci.nsIContentPrefCallback2.COMPLETE_OK
           : Ci.nsIContentPrefCallback2.COMPLETE_ERROR,
         ok,
-        rows && rows.length > 0
+        rows && !!rows.length
       );
     } catch (e) {
       Cu.reportError(e);
     }
   },
 
   /**
    * Parses the domain (the "group", to use the database's term) from the given
--- a/toolkit/components/crashes/tests/xpcshell/test_crash_service.js
+++ b/toolkit/components/crashes/tests/xpcshell/test_crash_service.js
@@ -88,38 +88,38 @@ async function test_addCrashBase(crashId
   );
   Assert.ok(crash.metadata.StackTraces, "The StackTraces field is present.\n");
 
   try {
     let stackTraces = JSON.parse(crash.metadata.StackTraces);
     Assert.equal(stackTraces.status, "OK");
     Assert.ok(stackTraces.crash_info, "The crash_info field is populated.");
     Assert.ok(
-      stackTraces.modules && stackTraces.modules.length > 0,
+      stackTraces.modules && !!stackTraces.modules.length,
       "The module list is populated."
     );
     Assert.ok(
-      stackTraces.threads && stackTraces.threads.length > 0,
+      stackTraces.threads && !!stackTraces.threads.length,
       "The thread list is populated."
     );
 
     if (allThreads) {
       Assert.ok(
         stackTraces.threads.length > 1,
         "The stack trace contains more than one thread."
       );
     } else {
       Assert.ok(
         stackTraces.threads.length == 1,
         "The stack trace contains exactly one thread."
       );
     }
 
     let frames = stackTraces.threads[0].frames;
-    Assert.ok(frames && frames.length > 0, "The stack trace is present.\n");
+    Assert.ok(frames && !!frames.length, "The stack trace is present.\n");
   } catch (e) {
     Assert.ok(false, "StackTraces does not contain valid JSON.");
   }
 
   try {
     let telemetryEnvironment = JSON.parse(crash.metadata.TelemetryEnvironment);
     Assert.equal(telemetryEnvironment.EscapedField, "EscapedData\n\nfoo");
   } catch (e) {
--- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js
+++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js
@@ -2848,17 +2848,17 @@ function run_FunctionType_tests() {
   ]);
 
   let f_t = ctypes.FunctionType(ctypes.default_abi, g_t);
   let name = "g_t()";
   Assert.equal(f_t.name, name);
   Assert.equal(f_t.size, undefined);
   Assert.ok(f_t.abi === ctypes.default_abi);
   Assert.ok(f_t.returnType === g_t);
-  Assert.ok(f_t.argTypes.length == 0);
+  Assert.ok(!f_t.argTypes.length);
 
   Assert.equal(f_t.toString(), "type " + name);
   Assert.equal(f_t.toSource(), "ctypes.FunctionType(ctypes.default_abi, g_t)");
 
   let fp_t = f_t.ptr;
   name = "g_t(*)()";
   Assert.equal(fp_t.name, name);
   Assert.equal(fp_t.size, ctypes.uintptr_t.size);
--- a/toolkit/components/enterprisepolicies/EnterprisePolicies.js
+++ b/toolkit/components/enterprisepolicies/EnterprisePolicies.js
@@ -183,17 +183,17 @@ EnterprisePoliciesManager.prototype = {
   },
 
   _schedulePolicyCallback(timing, callback) {
     this._callbacks[timing].push(callback);
   },
 
   _runPoliciesCallbacks(timing) {
     let callbacks = this._callbacks[timing];
-    while (callbacks.length > 0) {
+    while (callbacks.length) {
       let callback = callbacks.shift();
       try {
         callback();
       } catch (ex) {
         log.error("Error running ", callback, `for ${timing}:`, ex);
       }
     }
   },
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -934,17 +934,17 @@ class ExtensionData {
       const langpackId = `langpack-${manifest.langpack_id}-${productCodeName}`;
 
       // 3. Compute L10nRegistry sources for this langpack.
       const l10nRegistrySources = {};
 
       // Check if there's a root directory `/localization` in the langpack.
       // If there is one, add it with the name `toolkit` as a FileSource.
       const entries = await this.readDirectory("localization");
-      if (entries.length > 0) {
+      if (entries.length) {
         l10nRegistrySources.toolkit = "";
       }
 
       // Add any additional sources listed in the manifest
       if (manifest.sources) {
         for (const [sourceName, { base_path }] of Object.entries(
           manifest.sources
         )) {
@@ -1399,20 +1399,19 @@ class ExtensionData {
       );
     }
 
     if (info.type == "sideload") {
       result.header = bundle.formatStringFromName(
         "webextPerms.sideloadHeader",
         ["<>"]
       );
-      let key =
-        result.msgs.length == 0
-          ? "webextPerms.sideloadTextNoPerms"
-          : "webextPerms.sideloadText2";
+      let key = !result.msgs.length
+        ? "webextPerms.sideloadTextNoPerms"
+        : "webextPerms.sideloadText2";
       result.text = bundle.GetStringFromName(key);
       result.acceptText = bundle.GetStringFromName(
         "webextPerms.sideloadEnable.label"
       );
       result.cancelText = bundle.GetStringFromName(
         "webextPerms.sideloadCancel.label"
       );
       if (haveAccessKeys) {
@@ -1647,17 +1646,17 @@ class Extension extends ExtensionData {
     }
 
     /* eslint-disable mozilla/balanced-listeners */
     this.on("add-permissions", (ignoreEvent, permissions) => {
       for (let perm of permissions.permissions) {
         this.permissions.add(perm);
       }
 
-      if (permissions.origins.length > 0) {
+      if (permissions.origins.length) {
         let patterns = this.whiteListedHosts.patterns.map(host => host.pattern);
 
         this.whiteListedHosts = new MatchPatternSet(
           new Set([...patterns, ...permissions.origins]),
           {
             restrictSchemes: this.restrictSchemes,
             ignorePath: true,
           }
@@ -2493,17 +2492,17 @@ class Langpack extends ExtensionData {
   parseManifest() {
     return StartupCache.manifests.get(this.manifestCacheKey, () =>
       super.parseManifest()
     );
   }
 
   async startup(reason) {
     this.chromeRegistryHandle = null;
-    if (this.startupData.chromeEntries.length > 0) {
+    if (this.startupData.chromeEntries.length) {
       const manifestURI = Services.io.newURI(
         "manifest.json",
         null,
         this.rootURI
       );
       this.chromeRegistryHandle = aomStartup.registerChrome(
         manifestURI,
         this.startupData.chromeEntries
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -834,44 +834,44 @@ class BrowserExtensionContent extends Ev
     // Only used in addon processes.
     this.views = new Set();
 
     // Only used for devtools views.
     this.devtoolsViews = new Set();
 
     /* eslint-disable mozilla/balanced-listeners */
     this.on("add-permissions", (ignoreEvent, permissions) => {
-      if (permissions.permissions.length > 0) {
+      if (permissions.permissions.length) {
         let perms = new Set(this.policy.permissions);
         for (let perm of permissions.permissions) {
           perms.add(perm);
         }
         this.policy.permissions = perms;
       }
 
-      if (permissions.origins.length > 0) {
+      if (permissions.origins.length) {
         let patterns = this.whiteListedHosts.patterns.map(host => host.pattern);
 
         this.policy.allowedOrigins = new MatchPatternSet(
           [...patterns, ...permissions.origins],
           { restrictSchemes, ignorePath: true }
         );
       }
     });
 
     this.on("remove-permissions", (ignoreEvent, permissions) => {
-      if (permissions.permissions.length > 0) {
+      if (permissions.permissions.length) {
         let perms = new Set(this.policy.permissions);
         for (let perm of permissions.permissions) {
           perms.delete(perm);
         }
         this.policy.permissions = perms;
       }
 
-      if (permissions.origins.length > 0) {
+      if (permissions.origins.length) {
         let origins = permissions.origins.map(
           origin => new MatchPattern(origin, { ignorePath: true }).pattern
         );
 
         this.policy.allowedOrigins = new MatchPatternSet(
           this.whiteListedHosts.patterns.filter(
             host => !origins.includes(host.pattern)
           )
@@ -1193,17 +1193,17 @@ class ChildAPIManager {
       principal: context.principal,
     };
     Object.assign(params, contextData);
 
     this.messageManager.sendAsyncMessage("API:CreateProxyContext", params);
 
     this.permissionsChangedCallbacks = new Set();
     this.updatePermissions = null;
-    if (this.context.extension.optionalPermissions.length > 0) {
+    if (this.context.extension.optionalPermissions.length) {
       this.updatePermissions = () => {
         for (let callback of this.permissionsChangedCallbacks) {
           try {
             callback();
           } catch (err) {
             Cu.reportError(err);
           }
         }
--- a/toolkit/components/extensions/ExtensionContent.jsm
+++ b/toolkit/components/extensions/ExtensionContent.jsm
@@ -350,17 +350,17 @@ class Script {
 
     if (matcher.wantReturnValue) {
       this.compileScripts();
       this.loadCSS();
     }
   }
 
   get requiresCleanup() {
-    return !this.removeCSS && (this.css.length > 0 || this.cssCodeHash);
+    return !this.removeCSS && (!!this.css.length || this.cssCodeHash);
   }
 
   async addCSSCode(cssCode) {
     if (!cssCode) {
       return;
     }
 
     // Store the hash of the cssCode.
@@ -526,17 +526,17 @@ class Script {
         // stylesheets aren't in effect (since there's no document to block). So
         // we need to do something custom here, similar to what we do for
         // scripts. Blocking parsing is overkill, since we really just want to
         // block layout and onload. But we have an API to do the former and not
         // the latter, so we do it that way. This hopefully isn't a performance
         // problem since there are no network loads involved, and since we cache
         // the stylesheets on first load. We should fix this up if it does becomes
         // a problem.
-        if (this.css.length > 0) {
+        if (this.css.length) {
           context.contentWindow.document.blockParsing(cssPromise, {
             blockScriptCreated: false,
           });
         }
       }
     }
 
     let scripts = this.getCompiledScripts(context);
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -130,24 +130,24 @@ let apiManager = new (class extends Sche
       );
     });
     /* eslint-enable mozilla/balanced-listeners */
 
     // Handle any changes that happened during startup
     let disabledIds = AddonManager.getStartupChanges(
       AddonManager.STARTUP_CHANGE_DISABLED
     );
-    if (disabledIds.length > 0) {
+    if (disabledIds.length) {
       this._callHandlers(disabledIds, "disable", "onDisable");
     }
 
     let uninstalledIds = AddonManager.getStartupChanges(
       AddonManager.STARTUP_CHANGE_UNINSTALLED
     );
-    if (uninstalledIds.length > 0) {
+    if (uninstalledIds.length) {
       this._callHandlers(uninstalledIds, "uninstall", "onUninstall");
     }
   }
 
   getModuleJSONURLs() {
     return Array.from(
       Services.catMan.enumerateCategory(CATEGORY_EXTENSION_MODULES),
       ({ value }) => value
--- a/toolkit/components/extensions/ExtensionPermissions.jsm
+++ b/toolkit/components/extensions/ExtensionPermissions.jsm
@@ -116,17 +116,17 @@ var ExtensionPermissions = {
     for (let origin of perms.origins) {
       origin = new MatchPattern(origin, { ignorePath: true }).pattern;
       if (!origins.includes(origin)) {
         added.origins.push(origin);
         origins.push(origin);
       }
     }
 
-    if (added.permissions.length > 0 || added.origins.length > 0) {
+    if (added.permissions.length || added.origins.length) {
       await this._update(extensionId, { permissions, origins });
       if (emitter) {
         emitter.emit("add-permissions", added);
       }
     }
   },
 
   /**
@@ -155,17 +155,17 @@ var ExtensionPermissions = {
 
       let i = origins.indexOf(origin);
       if (i >= 0) {
         removed.origins.push(origin);
         origins.splice(i, 1);
       }
     }
 
-    if (removed.permissions.length > 0 || removed.origins.length > 0) {
+    if (removed.permissions.length || removed.origins.length) {
       await this._update(extensionId, { permissions, origins });
       if (emitter) {
         emitter.emit("remove-permissions", removed);
       }
     }
   },
 
   async removeAll(extensionId) {
--- a/toolkit/components/extensions/ExtensionStorageSync.jsm
+++ b/toolkit/components/extensions/ExtensionStorageSync.jsm
@@ -814,17 +814,17 @@ class ExtensionStorageSync {
 
     return extensions;
   }
 
   async syncAll() {
     const extensions = await this.getExtensions();
     const extIds = Array.from(extensions, extension => extension.id);
     log.debug(`Syncing extension settings for ${JSON.stringify(extIds)}`);
-    if (extIds.length == 0) {
+    if (!extIds.length) {
       // No extensions to sync. Get out.
       return;
     }
     await this.ensureCanSync(extIds);
     await this.checkSyncKeyRing();
     const promises = Array.from(extensions, extension => {
       return openCollection(this.cryptoCollection, extension).then(coll => {
         return this.sync(extension, coll);
@@ -903,17 +903,17 @@ class ExtensionStorageSync {
       // might violate client code's assumptions, since from their
       // perspective, we were in state L, but this diff is from R ->
       // L.
       const accepted = resolution.accepted;
       changes[accepted.key] = {
         newValue: accepted.data,
       };
     }
-    if (Object.keys(changes).length > 0) {
+    if (Object.keys(changes).length) {
       this.notifyListeners(extension, changes);
     }
     log.info(`Successfully synced '${collection.name}'`);
   }
 
   /**
    * Utility function that handles the common stuff about syncing all
    * Kinto collections (including "meta" collections like the crypto
@@ -1054,17 +1054,17 @@ class ExtensionStorageSync {
       keys: newKeys.asWBO().cleartext,
       salts: newSalts,
       uuid: collectionKeys.uuid,
       // Add a field for the current kB hash.
       kbHash: kbHash,
     };
     await this.cryptoCollection.upsert(newRecord);
     const result = await this._syncKeyRing(newRecord);
-    if (result.resolved.length != 0) {
+    if (result.resolved.length) {
       // We had a conflict which was automatically resolved. We now
       // have a new keyring which might have keys for the
       // collections. Recurse.
       return this.ensureCanSync(extIds);
     }
 
     // No conflicts. We're good.
     return newKeys;
@@ -1137,17 +1137,17 @@ class ExtensionStorageSync {
       // adding a UUID to the keyring. UUIDs are preserved throughout
       // the lifetime of a keyring, so the only time a keyring UUID
       // changes is when a new keyring is uploaded, which only happens
       // after a server wipe. So when we get a "conflict" (resolved by
       // server_wins), we check whether the server version has a new
       // UUID. If so, reset our sync status, so that we'll reupload
       // everything.
       const result = await this.cryptoCollection.sync(this);
-      if (result.resolved.length > 0) {
+      if (result.resolved.length) {
         // Automatically-resolved conflict. It should
         // be for the keys record.
         const resolutionIds = result.resolved.map(resolution => resolution.id);
         if (resolutionIds > 1) {
           // This should never happen -- there is only ever one record
           // in this collection.
           log.error(
             `Too many resolutions for sync-storage-crypto collection: ${JSON.stringify(
@@ -1314,17 +1314,17 @@ class ExtensionStorageSync {
               oldValue: res.data.data,
             };
           }
         }
         return changes;
       },
       { preloadIds: ids }
     );
-    if (Object.keys(changes).length > 0) {
+    if (Object.keys(changes).length) {
       this.notifyListeners(extension, changes);
     }
     const histogram = this._telemetry.getKeyedHistogramById(
       HISTOGRAM_REMOVE_OPS
     );
     histogram.add(extension.id, keys.length);
   }
 
--- a/toolkit/components/extensions/MatchURLFilters.jsm
+++ b/toolkit/components/extensions/MatchURLFilters.jsm
@@ -16,17 +16,17 @@ var EXPORTED_SYMBOLS = ["MatchURLFilters
 
 // Match WebNavigation URL Filters.
 class MatchURLFilters {
   constructor(filters) {
     if (!Array.isArray(filters)) {
       throw new TypeError("filters should be an array");
     }
 
-    if (filters.length == 0) {
+    if (!filters.length) {
       throw new Error("filters array should not be empty");
     }
 
     this.filters = filters;
   }
 
   matches(url) {
     let uri = Services.io.newURI(url);
--- a/toolkit/components/extensions/MessageChannel.jsm
+++ b/toolkit/components/extensions/MessageChannel.jsm
@@ -887,17 +887,17 @@ this.MessageChannel = {
     return pending.promise;
   },
 
   _callHandlers(handlers, data) {
     let responseType = data.responseType;
 
     // At least one handler is required for all response types but
     // RESPONSE_ALL.
-    if (handlers.length == 0 && responseType != this.RESPONSE_ALL) {
+    if (!handlers.length && responseType != this.RESPONSE_ALL) {
       return Promise.reject({
         result: MessageChannel.RESULT_NO_HANDLER,
         message: "No matching message handler",
       });
     }
 
     if (responseType == this.RESPONSE_SINGLE) {
       if (handlers.length > 1) {
@@ -922,17 +922,17 @@ this.MessageChannel = {
         return Promise.reject(e);
       }
     });
     data = null;
     responses = responses.filter(response => response !== undefined);
 
     switch (responseType) {
       case this.RESPONSE_FIRST:
-        if (responses.length == 0) {
+        if (!responses.length) {
           return Promise.reject({
             result: MessageChannel.RESULT_NO_RESPONSE,
             message: "No handler returned a response",
           });
         }
 
         return Promise.race(responses);
 
--- a/toolkit/components/extensions/NativeMessaging.jsm
+++ b/toolkit/components/extensions/NativeMessaging.jsm
@@ -193,17 +193,17 @@ var NativeApp = class extends EventEmitt
         if (err.errorCode != Subprocess.ERROR_END_OF_FILE) {
           Cu.reportError(err instanceof Error ? err : err.message);
         }
         this._cleanup(err);
       });
   }
 
   _startWrite() {
-    if (this.sendQueue.length == 0) {
+    if (!this.sendQueue.length) {
       return;
     }
 
     if (this.writePromise) {
       throw new Error("Entered _startWrite() while writePromise is non-null");
     }
 
     let buffer = this.sendQueue.shift();
@@ -225,17 +225,17 @@ var NativeApp = class extends EventEmitt
 
   _startStderrRead() {
     let proc = this.proc;
     let app = this.name;
     (async function() {
       let partial = "";
       while (true) {
         let data = await proc.stderr.readString();
-        if (data.length == 0) {
+        if (!data.length) {
           // We have hit EOF, just stop reading
           if (partial) {
             Services.console.logStringMessage(
               `stderr output from native app ${app}: ${partial}`
             );
           }
           break;
         }
--- a/toolkit/components/extensions/ProxyScriptContext.jsm
+++ b/toolkit/components/extensions/ProxyScriptContext.jsm
@@ -338,17 +338,17 @@ const ProxyInfoData = {
             fileName: error.fileName,
             lineNumber: error.lineNumber,
             stack: error.stack,
           });
         }
         proxyData = proxyRules;
       // fall through
       case "object":
-        if (Array.isArray(proxyData) && proxyData.length > 0) {
+        if (Array.isArray(proxyData) && proxyData.length) {
           return ProxyInfoData.createProxyInfoFromData(
             proxyData,
             defaultProxyInfo
           );
         }
       // Not an array, fall through to error.
       default:
         throw new ExtensionError(
--- a/toolkit/components/extensions/Schemas.jsm
+++ b/toolkit/components/extensions/Schemas.jsm
@@ -3186,17 +3186,17 @@ class SchemaRoots extends Namespaces {
         results.push(ns);
       }
     }
 
     if (results.length == 1) {
       return results[0];
     }
 
-    if (results.length > 0) {
+    if (results.length) {
       return new Namespaces(this.root, name, name.split("."), results);
     }
     return null;
   }
 
   getNamespace(name, create) {
     let ns = this._namespaces.get(name);
     if (!ns) {
--- a/toolkit/components/extensions/parent/ext-contentScripts.js
+++ b/toolkit/components/extensions/parent/ext-contentScripts.js
@@ -80,27 +80,27 @@ class ContentScriptParent {
       const blob = new context.cloneScope.Blob(data, { type: mime });
       const blobURL = context.cloneScope.URL.createObjectURL(blob);
 
       this.blobURLs.add(blobURL);
 
       return blobURL;
     };
 
-    if (details.js && details.js.length > 0) {
+    if (details.js && details.js.length) {
       options.jsPaths = details.js.map(data => {
         if (data.file) {
           return data.file;
         }
 
         return convertCodeToURL([data.code], "text/javascript");
       });
     }
 
-    if (details.css && details.css.length > 0) {
+    if (details.css && details.css.length) {
       options.cssPaths = details.css.map(data => {
         if (data.file) {
           return data.file;
         }
 
         return convertCodeToURL([data.code], "text/css");
       });
     }
--- a/toolkit/components/extensions/parent/ext-downloads.js
+++ b/toolkit/components/extensions/parent/ext-downloads.js
@@ -553,17 +553,17 @@ this.downloads = class extends Extension
         download(options) {
           let { filename } = options;
           if (filename && AppConstants.platform === "win") {
             // cross platform javascript code uses "/"
             filename = filename.replace(/\//g, "\\");
           }
 
           if (filename != null) {
-            if (filename.length == 0) {
+            if (!filename.length) {
               return Promise.reject({ message: "filename must not be empty" });
             }
 
             let path = OS.Path.split(filename);
             if (path.absolute) {
               return Promise.reject({
                 message: "filename must not be an absolute path",
               });
@@ -1060,17 +1060,17 @@ this.downloads = class extends Extension
             DOWNLOAD_ITEM_CHANGE_FIELDS.forEach(fld => {
               if (item[fld] != item.prechange[fld]) {
                 changes[fld] = {
                   previous: noundef(item.prechange[fld]),
                   current: noundef(item[fld]),
                 };
               }
             });
-            if (Object.keys(changes).length > 0) {
+            if (Object.keys(changes).length) {
               changes.id = item.id;
               fire.async(changes);
             }
           }
         ),
 
         onCreated: downloadEventManagerAPI(
           context,
--- a/toolkit/components/extensions/parent/ext-permissions.js
+++ b/toolkit/components/extensions/parent/ext-permissions.js
@@ -56,17 +56,17 @@ this.permissions = class extends Extensi
             );
             origins = origins.filter(
               origin =>
                 !context.extension.whiteListedHosts.subsumes(
                   new MatchPattern(origin)
                 )
             );
 
-            if (permissions.length == 0 && origins.length == 0) {
+            if (!permissions.length && !origins.length) {
               return true;
             }
 
             let browser = context.pendingEventBrowser || context.xulBrowser;
             let allow = await new Promise(resolve => {
               let subject = {
                 wrappedJSObject: {
                   browser,
--- a/toolkit/components/extensions/test/mochitest/test_chrome_ext_webnavigation_resolved_urls.html
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_webnavigation_resolved_urls.html
@@ -12,17 +12,17 @@
 <script type="text/javascript">
 "use strict";
 
 add_task(async function webnav_unresolved_uri_on_expected_URI_scheme() {
   function background() {
     let checkURLs;
 
     browser.webNavigation.onCompleted.addListener(async msg => {
-      if (checkURLs.length > 0) {
+      if (checkURLs.length) {
         let expectedURL = checkURLs.shift();
         browser.test.assertEq(expectedURL, msg.url, "Got the expected URL");
         await browser.tabs.remove(msg.tabId);
         browser.test.sendMessage("next");
       }
     });
 
     browser.test.onMessage.addListener((name, urls) => {
--- a/toolkit/components/extensions/test/mochitest/test_ext_activityLog.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_activityLog.html
@@ -260,17 +260,17 @@ add_task(async function test_api() {
       } else {
         browser.test.assertEq(test.name, details.name, "name matches");
       }
       browser.test.assertEq(
         JSON.stringify(test.data),
         JSON.stringify(details.data),
         "message matches"
       );
-      if (expecting.length == 0) {
+      if (!expecting.length) {
         await browser.tabs.remove(tab.id);
         browser.test.notifyPass("activity");
       }
     }, "watched@tests.mozilla.org");
 
     browser.test.onMessage.addListener(async msg => {
       if (msg === "opentab") {
         tab = await browser.tabs.create({url: expectedUrl});
--- a/toolkit/components/extensions/test/mochitest/test_ext_async_clipboard.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_async_clipboard.html
@@ -326,17 +326,17 @@ add_task(async function test_contentscri
     clipboardRead().then(function(dataT) {
       // On macOS if we clear the clipboard and read from it, there will be
       // no items in the data transfer object.
       // On linux with e10s enabled clearing of the clipboard does not happen in
       // the same way as it does on other platforms. So when we clear  the clipboard
       // and read from it, the data transfer object contains an item of type
       // text/plain and kind string, but we can't call getAsString on it to verify
       // that at least it is an empty string because the callback never gets invoked.
-      if (dataT.items.length == 0 ||
+      if (!dataT.items.length ||
         (dataT.items.length == 1 && dataT.items[0].type == "text/plain" &&
          dataT.items[0].kind == "string")) {
         browser.test.succeed("Read promise successfully resolved");
       } else {
         browser.test.fail("Read read the wrong thing from clipboard, " +
           "data transfer has this many items:" + dataT.items.length);
       }
       browser.test.sendMessage("ready");
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_hsts.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_hsts.html
@@ -39,17 +39,17 @@ function getExtension() {
       let cert = securityInfo.certificates[0];
       let now = Date.now();
       browser.test.assertTrue(Number.isInteger(cert.validity.start), "cert start is integer");
       browser.test.assertTrue(Number.isInteger(cert.validity.end), "cert end is integer");
       browser.test.assertTrue(cert.validity.start < now, "cert start validity is correct");
       browser.test.assertTrue(now < cert.validity.end, "cert end validity is correct");
       if (options.rawDER) {
         for (let cert of securityInfo.certificates) {
-          browser.test.assertTrue(cert.rawDER.length > 0, "have rawDER");
+          browser.test.assertTrue(!!cert.rawDER.length, "have rawDER");
         }
       }
     }
 
     browser.webRequest.onHeadersReceived.addListener(async (details) => {
       browser.test.assertEq(expect.shift(), "onHeadersReceived");
 
       // We exepect all requests to have been upgraded at this point.
--- a/toolkit/components/extensions/test/xpcshell/test_ext_dns.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_dns.js
@@ -101,17 +101,17 @@ add_task(async function test_dns_resolve
       // It seems there are platform differences happening that make this
       // testing difficult. We're going to rely on other existing dns tests to validate
       // the dns service itself works and only validate that we're getting generally
       // expected results in the webext api.
       ok(
         result.addresses.length >= test.expect.addresses.length,
         "expected number of addresses returned"
       );
-      if (test.expect.addresses.length > 0 && result.addresses.length > 0) {
+      if (test.expect.addresses.length && result.addresses.length) {
         ok(
           result.addresses.includes(test.expect.addresses[0]),
           "got expected ip address"
         );
       }
     }
   }
 
--- a/toolkit/components/extensions/test/xpcshell/test_ext_downloads_misc.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_misc.js
@@ -164,17 +164,17 @@ function backgroundScript() {
           });
         }
 
         // Events that did occur have been removed from expected so if
         // expected is empty, we're done.  If we didn't see all the
         // expected events and we're not looking for an exact match,
         // then we just may not have seen the event yet, so return without
         // failing and check() will be called again when a new event arrives.
-        if (expected.length == 0) {
+        if (!expected.length) {
           events = remaining;
           eventWaiter = null;
           resolve();
         } else if (exact) {
           fail(
             `Mismatched event: expecting ${JSON.stringify(
               expected[0]
             )} but got ${JSON.stringify(Array.from(remaining)[0])}`
--- a/toolkit/components/extensions/test/xpcshell/test_ext_incognito.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_incognito.js
@@ -24,17 +24,17 @@ function assertActionAMTelemetryEvent(
   { actionType } = {}
 ) {
   const snapshot = Services.telemetry.snapshotEvents(
     Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
     true
   );
 
   ok(
-    snapshot.parent && snapshot.parent.length > 0,
+    snapshot.parent && !!snapshot.parent.length,
     "Got parent telemetry events in the snapshot"
   );
 
   const events = snapshot.parent
     .filter(([timestamp, category, method, object, value, extra]) => {
       return (
         category === "addonsManager" &&
         method === "action" &&
--- a/toolkit/components/extensions/test/xpcshell/test_ext_proxy_socks.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_proxy_socks.js
@@ -96,17 +96,17 @@ class SocksClient {
     }
   }
 
   write(buf) {
     this.socket.send(new Uint8Array(buf).buffer);
   }
 
   checkSocksGreeting() {
-    if (this.inbuf.length == 0) {
+    if (!this.inbuf.length) {
       return;
     }
 
     if (this.inbuf[0] == 4) {
       this.type = "socks4";
       this.state = STATE_WAIT_SOCKS4_REQUEST;
       this.checkSocks4Request();
     } else if (this.inbuf[0] == 5) {
--- a/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js
@@ -199,17 +199,17 @@ class KintoServer {
             path: req.path,
             status: 201, // FIXME -- only for new posts??
             headers: { ETag: 3000 }, // FIXME???
             body: oneBody,
           };
         }),
       };
 
-      if (this.conflicts.length > 0) {
+      if (this.conflicts.length) {
         const nextConflict = this.conflicts.shift();
         if (!nextConflict.transient) {
           this.records.push(nextConflict);
         }
         const { data } = nextConflict;
         postResponse = {
           responses: body.requests.map(req => {
             return {
--- a/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_urlclassification.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_urlclassification.js
@@ -9,17 +9,17 @@ const { Schemas } = ChromeUtils.import("
  */
 add_task(async function test_webrequest_url_classification_enum() {
   // use normalizeManifest to get the schema loaded.
   await ExtensionTestUtils.normalizeManifest({ permissions: ["webRequest"] });
 
   let ns = Schemas.getNamespace("webRequest");
   let schema_enum = ns.get("UrlClassificationFlags").enumeration;
   ok(
-    schema_enum.length > 0,
+    !!schema_enum.length,
     `UrlClassificationFlags: ${JSON.stringify(schema_enum)}`
   );
 
   let prefix = /^(?:CLASSIFIED_)/;
   let entries = 0;
   for (let c of Object.keys(Ci.nsIHttpChannel).filter(name =>
     prefix.test(name)
   )) {
--- a/toolkit/components/extensions/webrequest/WebRequestContent.js
+++ b/toolkit/components/extensions/webrequest/WebRequestContent.js
@@ -195,17 +195,17 @@ var ContentPolicy = {
     }
 
     let data = {
       url,
       type: WebRequestCommon.typeForPolicyType(policyType),
       windowId,
       parentWindowId,
     };
-    if (frameAncestors.length > 0) {
+    if (frameAncestors.length) {
       data.frameAncestors = frameAncestors;
     }
     if (requestOrigin) {
       data.documentUrl = requestOrigin.spec;
     }
     if (requestPrincipal && requestPrincipal.URI) {
       data.originUrl = requestPrincipal.URI.spec;
     }
--- a/toolkit/components/mozintl/test/test_mozintl_getLocaleDisplayNames.js
+++ b/toolkit/components/mozintl/test/test_mozintl_getLocaleDisplayNames.js
@@ -117,20 +117,16 @@ add_test(function test_invalid_regions()
   Assert.throws(() => gRegDN([{}]), /All region codes must be strings/);
   Assert.throws(() => gRegDN([true]), /All region codes must be strings/);
   run_next_test();
 });
 
 add_test(function test_availableLocaleDisplayNames() {
   let langCodes = gAvLocDN("language");
   equal(
-    langCodes.length > 0,
+    !!langCodes.length,
     true,
     "There should be some language codes available"
   );
   let regCodes = gAvLocDN("region");
-  equal(
-    regCodes.length > 0,
-    true,
-    "There should be some region codes available"
-  );
+  equal(!!regCodes.length, true, "There should be some region codes available");
   run_next_test();
 });
--- a/toolkit/components/normandy/actions/PreferenceExperimentAction.jsm
+++ b/toolkit/components/normandy/actions/PreferenceExperimentAction.jsm
@@ -66,17 +66,17 @@ class PreferenceExperimentAction extends
       for (const branch of branches) {
         const conflictingPrefs = Object.keys(branch.preferences).filter(
           preferenceName => {
             return activeExperiments.some(exp =>
               exp.preferences.hasOwnProperty(preferenceName)
             );
           }
         );
-        if (conflictingPrefs.length > 0) {
+        if (conflictingPrefs.length) {
           throw new Error(
             `Experiment ${slug} ignored; another active experiment is already using the
             ${conflictingPrefs[0]} preference.`
           );
         }
       }
 
       // Determine if enrollment is currently paused for this experiment.
--- a/toolkit/components/normandy/lib/PreferenceExperiments.jsm
+++ b/toolkit/components/normandy/lib/PreferenceExperiments.jsm
@@ -421,17 +421,17 @@ var PreferenceExperiments = {
     const preferencesWithConflicts = Object.keys(preferences).filter(
       preferenceName => {
         return activeExperiments.some(e =>
           e.preferences.hasOwnProperty(preferenceName)
         );
       }
     );
 
-    if (preferencesWithConflicts.length > 0) {
+    if (preferencesWithConflicts.length) {
       TelemetryEvents.sendEvent("enrollFailed", "preference_study", slug, {
         reason: "pref-conflict",
       });
       throw new Error(
         `Another preference experiment for the pref "${
           preferencesWithConflicts[0]
         }" is currently active.`
       );
--- a/toolkit/components/normandy/test/browser/browser_LogManager.js
+++ b/toolkit/components/normandy/test/browser/browser_LogManager.js
@@ -9,17 +9,17 @@ add_task(async function() {
   LogManager.configure(5);
   const secondLogger = LogManager.getLogger("second");
   is(firstLogger.level, 5, "First logger level inherited from root logger.");
   is(secondLogger.level, 5, "Second logger level inherited from root logger.");
 
   // Ensure that our loggers have at least one appender.
   LogManager.configure(Log.Level.Warn);
   const logger = LogManager.getLogger("test");
-  ok(logger.appenders.length > 0, "Loggers have at least one appender.");
+  ok(!!logger.appenders.length, "Loggers have at least one appender.");
 
   // Ensure our loggers log to the console.
   await new Promise(resolve => {
     SimpleTest.waitForExplicitFinish();
     SimpleTest.monitorConsole(resolve, [{ message: /legend has it/ }]);
     logger.warn("legend has it");
     SimpleTest.endMonitorConsole();
   });
--- a/toolkit/components/normandy/test/browser/browser_actions_PreferenceExperimentAction.js
+++ b/toolkit/components/normandy/test/browser/browser_actions_PreferenceExperimentAction.js
@@ -439,17 +439,17 @@ decorate_task(
       .stub(action, "chooseBranch")
       .callsFake(async function(slug, branches) {
         return branches[0];
       });
     await action.runRecipe(recipe);
     await action.finalize();
 
     const activeExperiments = await PreferenceExperiments.getAllActive();
-    ok(activeExperiments.length > 0);
+    ok(!!activeExperiments.length);
     Assert.deepEqual(activeExperiments, [
       {
         slug: "integration test experiment",
         actionName: "PreferenceExperimentAction",
         branch: "branch1",
         preferences: {
           "fake.preference": {
             preferenceBranchType: "user",
--- a/toolkit/components/osfile/modules/osfile_async_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_async_front.jsm
@@ -350,21 +350,21 @@ var Scheduler = (this.Scheduler = {
         if (
           !reset &&
           ((openedFiles && openedFiles.length) ||
             (openedDirectoryIterators && openedDirectoryIterators.length))
         ) {
           // The worker still holds resources. Report them.
 
           let msg = "";
-          if (openedFiles.length > 0) {
+          if (openedFiles.length) {
             msg +=
               "The following files are still open:\n" + openedFiles.join("\n");
           }
-          if (openedDirectoryIterators.length > 0) {
+          if (openedDirectoryIterators.length) {
             msg +=
               "The following directory iterators are still open:\n" +
               openedDirectoryIterators.join("\n");
           }
 
           LOG("WARNING: File descriptors leaks detected.\n" + msg);
         }
 
--- a/toolkit/components/osfile/modules/osfile_async_worker.js
+++ b/toolkit/components/osfile/modules/osfile_async_worker.js
@@ -174,18 +174,17 @@ if (this.Components) {
       let result = {
         openedFiles: OpenedFiles.listOpenedResources(),
         openedDirectoryIterators: OpenedDirectoryIterators.listOpenedResources(),
         killed: false, // Placeholder
       };
 
       // Is it safe to kill the worker?
       let safe =
-        result.openedFiles.length == 0 &&
-        result.openedDirectoryIterators.length == 0;
+        !result.openedFiles.length && !result.openedDirectoryIterators.length;
       result.killed = safe && kill;
 
       return new Meta(result, { shutdown: result.killed });
     },
     // Functions of OS.File
     stat: function stat(path, options) {
       return exports.OS.File.Info.toMsg(
         exports.OS.File.stat(Type.path.fromMsg(path), options)
--- a/toolkit/components/osfile/modules/ospath_unix.jsm
+++ b/toolkit/components/osfile/modules/ospath_unix.jsm
@@ -83,17 +83,17 @@ exports.dirname = dirname;
  */
 var join = function(...path) {
   // If there is a path that starts with a "/", eliminate everything before
   let paths = [];
   for (let subpath of path) {
     if (subpath == null) {
       throw new TypeError("invalid path component");
     }
-    if (subpath.length == 0) {
+    if (!subpath.length) {
       continue;
     } else if (subpath[0] == "/") {
       paths = [subpath];
     } else {
       paths.push(subpath);
     }
   }
   return paths.join("/");
@@ -112,17 +112,17 @@ var normalize = function(path) {
     absolute = false;
   }
   path.split("/").forEach(function(v) {
     switch (v) {
       case "":
       case ".": // fallthrough
         break;
       case "..":
-        if (stack.length == 0) {
+        if (!stack.length) {
           if (absolute) {
             throw new Error("Path is ill-formed: attempting to go past root");
           } else {
             stack.push("..");
           }
         } else if (stack[stack.length - 1] == "..") {
           stack.push("..");
         } else {
--- a/toolkit/components/osfile/modules/ospath_win.jsm
+++ b/toolkit/components/osfile/modules/ospath_win.jsm
@@ -250,17 +250,17 @@ var normalize = function(path) {
   // And now, fill |stack| from the components,
   // popping whenever there is a ".."
   path.split("\\").forEach(function loop(v) {
     switch (v) {
       case "":
       case ".": // Ignore
         break;
       case "..":
-        if (stack.length == 0) {
+        if (!stack.length) {
           if (absolute) {
             throw new Error("Path is ill-formed: attempting to go past root");
           } else {
             stack.push("..");
           }
         } else if (stack[stack.length - 1] == "..") {
           stack.push("..");
         } else {
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -470,26 +470,26 @@ this.LoginHelper = {
             throw new Error("Unexpected propertybag item: " + prop.name);
         }
       }
     } else {
       throw new Error("newLoginData needs an expected interface!");
     }
 
     // Sanity check the login
-    if (newLogin.origin == null || newLogin.origin.length == 0) {
+    if (newLogin.origin == null || !newLogin.origin.length) {
       throw new Error("Can't add a login with a null or empty origin.");
     }
 
     // For logins w/o a username, set to "", not null.
     if (newLogin.username == null) {
       throw new Error("Can't add a login with a null username.");
     }
 
-    if (newLogin.password == null || newLogin.password.length == 0) {
+    if (newLogin.password == null || !newLogin.password.length) {
       throw new Error("Can't add a login with a null or empty password.");
     }
 
     if (newLogin.formActionOrigin || newLogin.formActionOrigin == "") {
       // We have a form submit URL. Can't have a HTTP realm.
       if (newLogin.httpRealm != null) {
         throw new Error(
           "Can't add a login with both a httpRealm and formActionOrigin."
@@ -640,17 +640,17 @@ this.LoginHelper = {
     /**
      * @return {bool} whether `login` is preferred over its duplicate (considering `uniqueKeys`)
      *                `existingLogin`.
      *
      * `resolveBy` is a sorted array so we can return true the first time `login` is preferred
      * over the existingLogin.
      */
     function isLoginPreferred(existingLogin, login) {
-      if (!resolveBy || resolveBy.length == 0) {
+      if (!resolveBy || !resolveBy.length) {
         // If there is no preference, prefer the existing login.
         return false;
       }
 
       for (let preference of resolveBy) {
         switch (preference) {
           case "actionOrigin": {
             if (!preferredFormActionOrigin) {
--- a/toolkit/components/passwordmgr/LoginImport.jsm
+++ b/toolkit/components/passwordmgr/LoginImport.jsm
@@ -58,17 +58,17 @@ this.LoginImport.prototype = {
    * Imports login-related data from the previous SQLite storage format.
    */
   async import() {
     // We currently migrate data directly from the database to the JSON store at
     // first run, then we set a preference to prevent repeating the import.
     // Thus, merging with existing data is not a use case we support.  This
     // restriction might be removed to support re-importing passwords set by an
     // old version by flipping the import preference and restarting.
-    if (this.store.data.logins.length > 0) {
+    if (this.store.data.logins.length) {
       throw new Error(
         "Unable to import saved passwords because some data " +
           "has already been imported or saved."
       );
     }
 
     // When a timestamp is not specified, we will use the same reference time.
     let referenceTimeMs = Date.now();
--- a/toolkit/components/passwordmgr/LoginManager.jsm
+++ b/toolkit/components/passwordmgr/LoginManager.jsm
@@ -250,26 +250,26 @@ LoginManager.prototype = {
   /**
    * Ensures that a login isn't missing any necessary fields.
    *
    * @param login
    *        The login to check.
    */
   _checkLogin(login) {
     // Sanity check the login
-    if (login.origin == null || login.origin.length == 0) {
+    if (login.origin == null || !login.origin.length) {
       throw new Error("Can't add a login with a null or empty origin.");
     }
 
     // For logins w/o a username, set to "", not null.
     if (login.username == null) {
       throw new Error("Can't add a login with a null username.");
     }
 
-    if (login.password == null || login.password.length == 0) {
+    if (login.password == null || !login.password.length) {
       throw new Error("Can't add a login with a null or empty password.");
     }
 
     if (login.formActionOrigin || login.formActionOrigin == "") {
       // We have a form submit URL. Can't have a HTTP realm.
       if (login.httpRealm != null) {
         throw new Error(
           "Can't add a login with both a httpRealm and formActionOrigin."
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -830,20 +830,19 @@ this.LoginManagerContent = {
     log("_detectInsecureFormLikes", topWindow.location.href);
 
     // Returns true if this window or any subframes have insecure login forms.
     let hasInsecureLoginForms = thisWindow => {
       let doc = thisWindow.document;
       let rootElsWeakSet = LoginFormFactory.getRootElementsWeakSetForDocument(
         doc
       );
-      let hasLoginForm =
-        ChromeUtils.nondeterministicGetWeakSetKeys(rootElsWeakSet).filter(
-          el => el.isConnected
-        ).length > 0;
+      let hasLoginForm = !!ChromeUtils.nondeterministicGetWeakSetKeys(
+        rootElsWeakSet
+      ).filter(el => el.isConnected).length;
       return (
         (hasLoginForm && !thisWindow.isSecureContext) ||
         Array.prototype.some.call(thisWindow.frames, frame =>
           hasInsecureLoginForms(frame)
         )
       );
     };
 
@@ -1112,17 +1111,17 @@ this.LoginManagerContent = {
 
       pwFields[pwFields.length] = {
         index: i,
         element,
       };
     }
 
     // If too few or too many fields, bail out.
-    if (pwFields.length == 0) {
+    if (!pwFields.length) {
       log("(form ignored -- no password fields.)");
       return null;
     } else if (pwFields.length > 3) {
       log(
         "(form ignored -- too many password fields. [ got ",
         pwFields.length,
         "])"
       );
@@ -1723,17 +1722,17 @@ this.LoginManagerContent = {
       PASSWORD_AUTOCOMPLETE_NEW_PASSWORD: 11,
     };
 
     try {
       // Nothing to do if we have no matching (excluding form action
       // checks) logins available, and there isn't a need to show
       // the insecure form warning.
       if (
-        foundLogins.length == 0 &&
+        !foundLogins.length &&
         (InsecurePasswordUtils.isFormSecure(form) ||
           !LoginHelper.showInsecureFieldWarning)
       ) {
         // We don't log() here since this is a very common case.
         autofillResult = AUTOFILL_RESULT.NO_SAVED_LOGINS;
         return;
       }
 
@@ -1826,17 +1825,17 @@ this.LoginManagerContent = {
           loginOrigin,
           formActionOrigin
         );
       }
 
       // Nothing to do if we have no matching logins available.
       // Only insecure pages reach this block and logs the same
       // telemetry flag.
-      if (foundLogins.length == 0) {
+      if (!foundLogins.length) {
         // We don't log() here since this is a very common case.
         autofillResult = AUTOFILL_RESULT.NO_SAVED_LOGINS;
         return;
       }
 
       // Prevent autofilling insecure forms.
       if (
         !userTriggered &&
@@ -1869,17 +1868,17 @@ this.LoginManagerContent = {
           l.password.length <= maxPasswordLen;
         if (!fit) {
           log("Ignored", l.username, "login: won't fit");
         }
 
         return fit;
       }, this);
 
-      if (logins.length == 0) {
+      if (!logins.length) {
         log("form not filled, none of the logins fit in the field");
         autofillResult = AUTOFILL_RESULT.NO_LOGINS_FIT;
         return;
       }
 
       const passwordACFieldName = passwordField.getAutocompleteInfo().fieldName;
 
       // If the password field has the autocomplete value of "new-password"
@@ -1910,17 +1909,17 @@ this.LoginManagerContent = {
       ) {
         // If username was specified in the field, it's disabled or it's readOnly, only fill in the
         // password if we find a matching login.
         let username = usernameField.value.toLowerCase();
 
         let matchingLogins = logins.filter(
           l => l.username.toLowerCase() == username
         );
-        if (matchingLogins.length == 0) {
+        if (!matchingLogins.length) {
           log(
             "Password not filled. None of the stored logins match the username already present."
           );
           autofillResult = AUTOFILL_RESULT.EXISTING_USERNAME;
           return;
         }
 
         // If there are multiple, and one matches case, use it
--- a/toolkit/components/passwordmgr/LoginManagerParent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm
@@ -606,17 +606,17 @@ this.LoginManagerParent = {
     let autoSavedStorageGUID = "";
     if (generatedPW && generatedPW.storageGUID) {
       autoSavedStorageGUID = generatedPW.storageGUID;
     }
 
     // If we didn't find a username field, but seem to be changing a
     // password, allow the user to select from a list of applicable
     // logins to update the password for.
-    if (!usernameField && oldPasswordField && logins.length > 0) {
+    if (!usernameField && oldPasswordField && logins.length) {
       let prompter = this._getPrompter(browser, openerTopWindowID);
 
       if (logins.length == 1) {
         let oldLogin = logins[0];
 
         if (oldLogin.password == formLogin.password) {
           recordLoginUse(oldLogin);
           log(
--- a/toolkit/components/passwordmgr/LoginManagerPrompter.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerPrompter.jsm
@@ -445,17 +445,17 @@ LoginManagerPrompter.prototype = {
         checkBoxLabel = this._getLocalizedString("rememberPassword");
       }
 
       // Look for existing logins.
       foundLogins = Services.logins.findLogins(origin, null, realm);
 
       // XXX Like the original code, we can't deal with multiple
       // account selection. (bug 227632)
-      if (foundLogins.length > 0) {
+      if (foundLogins.length) {
         selectedLogin = foundLogins[0];
 
         // If the caller provided a username, try to use it. If they
         // provided only a password, this will try to find a password-only
         // login (or return null if none exists).
         if (aUsername.value) {
           selectedLogin = this._repickSelectedLogin(
             foundLogins,
@@ -682,17 +682,17 @@ LoginManagerPrompter.prototype = {
         foundLogins,
         ["username"],
         resolveBy,
         origin
       );
       this.log(foundLogins.length, "matching logins remain after deduping");
 
       // XXX Can't select from multiple accounts yet. (bug 227632)
-      if (foundLogins.length > 0) {
+      if (foundLogins.length) {
         selectedLogin = foundLogins[0];
         this._SetAuthInfo(
           aAuthInfo,
           selectedLogin.username,
           selectedLogin.password
         );
 
         // Allow automatic proxy login
@@ -1030,17 +1030,17 @@ LoginManagerPrompter.prototype = {
     );
 
     let chromeDoc = browser.ownerDocument;
     let currentNotification;
 
     let updateButtonStatus = element => {
       let mainActionButton = element.button;
       // Disable the main button inside the menu-button if the password field is empty.
-      if (login.password.length == 0) {
+      if (!login.password.length) {
         mainActionButton.setAttribute("disabled", true);
         chromeDoc
           .getElementById("password-notification-password")
           .classList.add("popup-notification-invalid-input");
       } else {
         mainActionButton.removeAttribute("disabled");
         chromeDoc
           .getElementById("password-notification-password")
@@ -1059,17 +1059,17 @@ LoginManagerPrompter.prototype = {
         schemeUpgrades: LoginHelper.schemeUpgrades,
       });
 
       let logins = this._filterUpdatableLogins(
         login,
         foundLogins,
         autoSavedLoginGuid
       );
-      let msgNames = logins.length == 0 ? saveMsgNames : changeMsgNames;
+      let msgNames = !logins.length ? saveMsgNames : changeMsgNames;
 
       // Update the label based on whether this will be a new login or not.
       let label = this._getLocalizedString(msgNames.buttonLabel);
       let accessKey = this._getLocalizedString(msgNames.buttonAccessKey);
 
       // Update the labels for the next time the panel is opened.
       currentNotification.mainAction.label = label;
       currentNotification.mainAction.accessKey = accessKey;
--- a/toolkit/components/passwordmgr/LoginRecipes.jsm
+++ b/toolkit/components/passwordmgr/LoginRecipes.jsm
@@ -146,26 +146,26 @@ LoginRecipesParent.prototype = {
    * Validate the recipe is sane and then add it to the set of recipes.
    *
    * @param {Object} recipe
    */
   add(recipe) {
     log.debug("Adding recipe:", recipe);
     let recipeKeys = Object.keys(recipe);
     let unknownKeys = recipeKeys.filter(key => !SUPPORTED_KEYS.includes(key));
-    if (unknownKeys.length > 0) {
+    if (unknownKeys.length) {
       throw new Error(
         "The following recipe keys aren't supported: " + unknownKeys.join(", ")
       );
     }
 
     let missingRequiredKeys = REQUIRED_KEYS.filter(
       key => !recipeKeys.includes(key)
     );
-    if (missingRequiredKeys.length > 0) {
+    if (missingRequiredKeys.length) {
       throw new Error(
         "The following required recipe keys are missing: " +
           missingRequiredKeys.join(", ")
       );
     }
 
     if (!Array.isArray(recipe.hosts)) {
       throw new Error("'hosts' must be a array");
--- a/toolkit/components/passwordmgr/content/passwordManager.js
+++ b/toolkit/components/passwordmgr/content/passwordManager.js
@@ -311,17 +311,17 @@ function LoadSignons() {
   signonsTree.view = signonsTreeView;
   // The sort column didn't change. SortTree (called by
   // SignonColumnSort) assumes we want to toggle the sort
   // direction but here we don't so we have to trick it
   lastSignonSortAscending = !lastSignonSortAscending;
   SignonColumnSort(lastSignonSortColumn);
 
   // disable "remove all signons" button if there are no signons
-  if (signons.length == 0) {
+  if (!signons.length) {
     removeAllButton.setAttribute("disabled", "true");
     togglePasswordsButton.setAttribute("disabled", "true");
   } else {
     removeAllButton.removeAttribute("disabled");
     togglePasswordsButton.removeAttribute("disabled");
   }
 
   return true;
@@ -357,17 +357,17 @@ function SignonSelected() {
   if (selections.length) {
     removeButton.removeAttribute("disabled");
   } else {
     removeButton.setAttribute("disabled", true);
   }
 }
 
 function DeleteSignon() {
-  let syncNeeded = signonsTreeView._filterSet.length != 0;
+  let syncNeeded = !!signonsTreeView._filterSet.length;
   let tree = signonsTree;
   let view = signonsTreeView;
   let table = GetVisibleLogins();
 
   // Turn off tree selection notifications during the deletion
   tree.view.selection.selectEventsSuppressed = true;
 
   // remove selected items from list (by setting them to null) and place in deleted list
@@ -421,17 +421,17 @@ async function DeleteAllSignons() {
       null,
       dummy
     ) == 1
   ) {
     // 1 == "No" button
     return;
   }
 
-  let syncNeeded = signonsTreeView._filterSet.length != 0;
+  let syncNeeded = !!signonsTreeView._filterSet.length;
   let view = signonsTreeView;
   let table = GetVisibleLogins();
 
   // remove all items from table and place in deleted table
   for (let i = 0; i < table.length; i++) {
     deletedSignons.push(table[i]);
   }
   table.length = 0;
--- a/toolkit/components/passwordmgr/test/browser/head.js
+++ b/toolkit/components/passwordmgr/test/browser/head.js
@@ -296,17 +296,17 @@ async function getCaptureDoorhangerThatM
       );
     }
   }
   return notif;
 }
 
 function getDoorhangerButton(aPopup, aButtonIndex) {
   let notifications = aPopup.owner.panel.children;
-  ok(notifications.length > 0, "at least one notification displayed");
+  ok(!!notifications.length, "at least one notification displayed");
   ok(true, notifications.length + " notification(s)");
   let notification = notifications[0];
 
   if (aButtonIndex == "button") {
     return notification.button;
   } else if (aButtonIndex == "secondaryButton") {
     return notification.secondaryButton;
   }
--- a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
+++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
@@ -475,17 +475,17 @@ SimpleTest.registerCleanupFunction(() =>
     if (LoginManagerParent._recipeManager) {
       LoginManagerParent._recipeManager.reset();
     }
 
     // Cleanup PopupNotifications (if on a relevant platform)
     let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
     if (chromeWin && chromeWin.PopupNotifications) {
       let notes = chromeWin.PopupNotifications._currentNotifications;
-      if (notes.length > 0) {
+      if (notes.length) {
         dump("Removing " + notes.length + " popup notifications.\n");
       }
       for (let note of notes) {
         note.remove();
       }
     }
   });
 });
--- a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js
+++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js
@@ -192,17 +192,17 @@ addMessageListener("proxyLoginManager", 
     return arg;
   });
 
   let rv = Services.logins[msg.methodName](...recreatedArgs);
   if (rv instanceof Ci.nsILoginInfo) {
     rv = LoginHelper.loginToVanillaObject(rv);
   } else if (
     Array.isArray(rv) &&
-    rv.length > 0 &&
+    !!rv.length &&
     rv[0] instanceof Ci.nsILoginInfo
   ) {
     rv = rv.map(login => LoginHelper.loginToVanillaObject(login));
   }
   return rv;
 });
 
 addMessageListener("isLoggedIn", () => {
--- a/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html
@@ -53,17 +53,17 @@
 
     var gExpectedDialogs = 0;
     var gCurrentTest;
     function runNextTest() {
       is(gExpectedDialogs, 0, "received expected number of auth dialogs");
       mm.sendAsyncMessage("prepareForNextTest");
       mm.addMessageListener("prepareForNextTestDone", function prepared(msg) {
         mm.removeMessageListener("prepareForNextTestDone", prepared);
-        if (pendingTests.length > 0) {
+        if (pendingTests.length) {
           ({expectedDialogs: gExpectedDialogs,
             test: gCurrentTest} = pendingTests.shift());
           gCurrentTest.call(this);
         } else {
           mm.sendAsyncMessage("cleanup");
           mm.addMessageListener("cleanupDone", () => {
             // mm.destroy() is called as a cleanup function by runInParent(), no
             // need to do it here.
--- a/toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
+++ b/toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
@@ -1167,17 +1167,17 @@ add_task(async function test_all_pattern
           item.comment.comment,
           `Comment.comment ${index}`
         );
       } else {
         equal(actualComment, item.comment, `Comment ${index}`);
       }
     });
 
-    if (pattern.items.length != 0) {
+    if (pattern.items.length) {
       Assert.throws(
         () => actual.getValueAt(pattern.items.length),
         /Index out of range\./
       );
 
       Assert.throws(
         () => actual.getLabelAt(pattern.items.length),
         /Index out of range\./
--- a/toolkit/components/places/BookmarkHTMLUtils.jsm
+++ b/toolkit/components/places/BookmarkHTMLUtils.jsm
@@ -567,18 +567,17 @@ BookmarkImporter.prototype = {
       bookmark.dateAdded = bookmark.lastModified;
     }
 
     if (tags) {
       bookmark.tags = tags
         .split(",")
         .filter(
           aTag =>
-            aTag.length > 0 &&
-            aTag.length <= PlacesUtils.bookmarks.MAX_TAG_LENGTH
+            !!aTag.length && aTag.length <= PlacesUtils.bookmarks.MAX_TAG_LENGTH
         );
 
       // If we end up with none, then delete the property completely.
       if (!bookmark.tags.length) {
         delete bookmark.tags;
       }
     }
 
@@ -859,17 +858,17 @@ function BookmarkExporter(aBookmarksTree
   }
 
   // For backwards compatibility reasons the bookmarks menu is the root, while
   // the bookmarks toolbar and unfiled bookmarks will be child items.
   this._root = rootsMap.get("bookmarksMenuFolder");
 
   for (let key of ["toolbarFolder", "unfiledBookmarksFolder"]) {
     let root = rootsMap.get(key);
-    if (root.children && root.children.length > 0) {
+    if (root.children && root.children.length) {
       if (!this._root.children) {
         this._root.children = [];
       }
       this._root.children.push(root);
     }
   }
 }
 
--- a/toolkit/components/places/BookmarkJSONUtils.jsm
+++ b/toolkit/components/places/BookmarkJSONUtils.jsm
@@ -244,21 +244,17 @@ BookmarkImporter.prototype = {
    * @rejects JavaScript exception.
    */
   async importFromJSON(aString) {
     let nodes = PlacesUtils.unwrapNodes(
       aString,
       PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER
     );
 
-    if (
-      nodes.length == 0 ||
-      !nodes[0].children ||
-      nodes[0].children.length == 0
-    ) {
+    if (!nodes.length || !nodes[0].children || !nodes[0].children.length) {
       return;
     }
 
     await this.import(nodes[0]);
   },
 
   async import(rootNode) {
     // Change to rootNode.children as we don't import the root, and also filter
@@ -271,33 +267,33 @@ BookmarkImporter.prototype = {
     }
 
     let folderIdToGuidMap = {};
 
     // Now do some cleanup on the imported nodes so that the various guids
     // match what we need for insertTree, and we also have mappings of folders
     // so we can repair any searches after inserting the bookmarks (see bug 824502).
     for (let node of nodes) {
-      if (!node.children || node.children.length == 0) {
+      if (!node.children || !node.children.length) {
         continue;
       } // Nothing to restore for this root
 
       // Ensure we set the source correctly.
       node.source = this._source;
 
       // Translate the node for insertTree.
       let folders = translateTreeTypes(node);
 
       folderIdToGuidMap = Object.assign(folderIdToGuidMap, folders);
     }
 
     // Now we can add the actual nodes to the database.
     for (let node of nodes) {
       // Drop any nodes without children, we can't insert them.
-      if (!node.children || node.children.length == 0) {
+      if (!node.children || !node.children.length) {
         continue;
       }
 
       // Drop any roots whose guid we don't recognise - we don't support anything
       // apart from the built-in roots.
       if (!PlacesUtils.bookmarks.userContentRoots.includes(node.guid)) {
         continue;
       }
@@ -473,17 +469,17 @@ function translateTreeTypes(node) {
   }
 
   if (node.tags) {
     // Separate any tags into an array, and ignore any that are too long.
     node.tags = node.tags
       .split(",")
       .filter(
         aTag =>
-          aTag.length > 0 && aTag.length <= PlacesUtils.bookmarks.MAX_TAG_LENGTH
+          !!aTag.length && aTag.length <= PlacesUtils.bookmarks.MAX_TAG_LENGTH
       );
 
     // If we end up with none, then delete the property completely.
     if (!node.tags.length) {
       delete node.tags;
     }
   }
 
--- a/toolkit/components/places/History.jsm
+++ b/toolkit/components/places/History.jsm
@@ -350,17 +350,17 @@ var History = Object.freeze({
    * @throws (TypeError)
    *       If `pages` has an unexpected type or if a string provided
    *       is neither a valid GUID nor a valid URI or if `pages`
    *       is an empty array.
    */
   remove(pages, onResult = null) {
     // Normalize and type-check arguments
     if (Array.isArray(pages)) {
-      if (pages.length == 0) {
+      if (!pages.length) {
         throw new TypeError("Expected at least one page");
       }
     } else {
       pages = [pages];
     }
 
     let guids = [];
     let urls = [];
@@ -842,17 +842,17 @@ function sqlBindPlaceholders(values, pre
  * Invalidate and recompute the frecency of a list of pages,
  * informing frecency observers.
  *
  * @param {OpenConnection} db an Sqlite connection
  * @param {Array} idList The `moz_places` identifiers to invalidate.
  * @returns {Promise} resolved when done
  */
 var invalidateFrecencies = async function(db, idList) {
-  if (idList.length == 0) {
+  if (!idList.length) {
     return;
   }
   await db.execute(
     `UPDATE moz_places
      SET frecency = NOTIFY_FRECENCY(
        CALCULATE_FRECENCY(id), url, guid, hidden, last_visit_date
      ) WHERE id in (${sqlBindPlaceholders(idList)})`,
     idList
@@ -941,17 +941,17 @@ var clear = async function(db) {
  */
 var cleanupPages = async function(db, pages) {
   await invalidateFrecencies(
     db,
     pages.filter(p => p.hasForeign || p.hasVisits).map(p => p.id)
   );
 
   let pagesToRemove = pages.filter(p => !p.hasForeign && !p.hasVisits);
-  if (pagesToRemove.length == 0) {
+  if (!pagesToRemove.length) {
     return;
   }
 
   let idsToRemove = pagesToRemove.map(p => p.id);
   // Note, we are already in a transaction, since callers create it.
   // Check relations regardless, to avoid creating orphans in case of
   // async race conditions.
   await db.execute(
@@ -1268,17 +1268,17 @@ var removeVisitsByFilter = async functio
           date: new Date(row.getResultByName("date")),
           transition: row.getResultByName("visit_type"),
         });
       }
     }
   );
 
   try {
-    if (visitsToRemove.length == 0) {
+    if (!visitsToRemove.length) {
       // Nothing to do
       return false;
     }
 
     let pages = [];
     await db.executeTransaction(async function() {
       // 2. Remove all offending visits.
       await db.execute(
@@ -1315,17 +1315,17 @@ var removeVisitsByFilter = async functio
 
     notifyCleanup(db, pages, transition);
     notifyOnResult(onResultData, onResult); // don't wait
   } finally {
     // Ensure we cleanup embed visits, even if we bailed out early.
     PlacesUtils.history.clearEmbedVisits();
   }
 
-  return visitsToRemove.length != 0;
+  return !!visitsToRemove.length;
 };
 
 // Inner implementation of History.removeByFilter
 var removeByFilter = async function(db, filter, onResult = null) {
   // 1. Create fragment for date filtration
   let dateFilterSQLFragment = "";
   let conditions = [];
   let params = {};
@@ -1467,17 +1467,17 @@ var remove = async function(db, { guids,
         title: row.getResultByName("title"),
         frecency: row.getResultByName("frecency"),
         url: new URL(url),
       });
     }
   });
 
   try {
-    if (pages.length == 0) {
+    if (!pages.length) {
       // Nothing to do
       return false;
     }
 
     await db.executeTransaction(async function() {
       // 2. Remove all visits to these pages.
       let pageIds = pages.map(p => p.id);
       await db.execute(
@@ -1621,17 +1621,17 @@ var update = async function(db, pageInfo
     params.description = pageInfo.description;
   }
   if ("previewImageURL" in pageInfo) {
     updateFragments.push("preview_image_url");
     params.preview_image_url = pageInfo.previewImageURL
       ? pageInfo.previewImageURL.href
       : null;
   }
-  if (updateFragments.length > 0) {
+  if (updateFragments.length) {
     // Since this data may be written at every visit and is textual, avoid
     // overwriting the existing record if it didn't change.
     await db.execute(
       `
       UPDATE moz_places
       SET ${updateFragments.map(v => `${v} = :${v}`).join(", ")}
       WHERE id = :id
         AND (${updateFragments
--- a/toolkit/components/places/PlacesSyncUtils.jsm
+++ b/toolkit/components/places/PlacesSyncUtils.jsm
@@ -338,17 +338,17 @@ const HistorySyncUtils = (PlacesSyncUtil
     let db = await PlacesUtils.promiseDBConnection();
     let rows = await db.executeCached(
       `
         SELECT guid
         FROM moz_places
         WHERE url_hash = hash(:page_url) AND url = :page_url`,
       { page_url: canonicalURL.href }
     );
-    if (rows.length == 0) {
+    if (!rows.length) {
       return null;
     }
     return rows[0].getResultByName("guid");
   },
 
   /**
    * Fetch information about a guid (url, title and frecency)
    *
@@ -1478,17 +1478,17 @@ const BookmarkSyncUtils = (PlacesSyncUti
    */
   async ensureMobileQuery() {
     let db = await PlacesUtils.promiseDBConnection();
 
     let mobileChildGuids = await fetchChildGuids(
       db,
       PlacesUtils.bookmarks.mobileGuid
     );
-    let hasMobileBookmarks = mobileChildGuids.length > 0;
+    let hasMobileBookmarks = !!mobileChildGuids.length;
 
     Services.prefs.setBoolPref(MOBILE_BOOKMARKS_PREF, hasMobileBookmarks);
   },
 
   /**
    * Fetches an array of GUIDs for items that have an annotation set with the
    * given value.
    */
@@ -2017,21 +2017,21 @@ function tagItem(item, tags) {
 
   // Remove leading and trailing whitespace, then filter out empty tags.
   let newTags = tags ? tags.map(tag => tag.trim()).filter(Boolean) : [];
 
   // Removing the last tagged item will also remove the tag. To preserve
   // tag IDs, we temporarily tag a dummy URI, ensuring the tags exist.
   let dummyURI = PlacesUtils.toURI("about:weave#BStore_tagURI");
   let bookmarkURI = PlacesUtils.toURI(item.url.href);
-  if (newTags && newTags.length > 0) {
+  if (newTags && newTags.length) {
     PlacesUtils.tagging.tagURI(dummyURI, newTags, SOURCE_SYNC);
   }
   PlacesUtils.tagging.untagURI(bookmarkURI, null, SOURCE_SYNC);
-  if (newTags && newTags.length > 0) {
+  if (newTags && newTags.length) {
     PlacesUtils.tagging.tagURI(bookmarkURI, newTags, SOURCE_SYNC);
   }
   PlacesUtils.tagging.untagURI(dummyURI, null, SOURCE_SYNC);
 
   return newTags;
 }
 
 // `PlacesUtils.bookmarks.update` checks if we've supplied enough properties,
--- a/toolkit/components/places/PlacesTransactions.jsm
+++ b/toolkit/components/places/PlacesTransactions.jsm
@@ -260,17 +260,17 @@ class TransactionsHistoryArray extends A
    *        If false, an entry will we created only if there's no undo entry
    *        to extend.
    */
   add(proxifiedTransaction, forceNewEntry = false) {
     if (!this.isProxifiedTransactionObject(proxifiedTransaction)) {
       throw new Error("aProxifiedTransaction is not a proxified transaction");
     }
 
-    if (this.length == 0 || forceNewEntry) {
+    if (!this.length || forceNewEntry) {
       this.clearRedoEntries();
       this.unshift([proxifiedTransaction]);
     } else {
       this[this.undoPosition].unshift(proxifiedTransaction);
     }
   }
 
   /**
@@ -291,17 +291,17 @@ class TransactionsHistoryArray extends A
       this._undoPosition = 0;
     }
   }
 
   /**
    * Clear all entries.
    */
   clearAllEntries() {
-    if (this.length > 0) {
+    if (this.length) {
       this.splice(0);
       this._undoPosition = 0;
     }
   }
 }
 
 XPCOMUtils.defineLazyGetter(
   this,
@@ -310,17 +310,17 @@ XPCOMUtils.defineLazyGetter(
 );
 
 var PlacesTransactions = {
   /**
    * @see Batches in the module documentation.
    */
   batch(transactionsToBatch) {
     if (Array.isArray(transactionsToBatch)) {
-      if (transactionsToBatch.length == 0) {
+      if (!transactionsToBatch.length) {
         throw new Error("Must pass a non-empty array");
       }
 
       if (
         transactionsToBatch.some(
           o => !TransactionsHistory.isProxifiedTransactionObject(o)
         )
       ) {
@@ -720,17 +720,17 @@ function DefineTransaction(requiredProps
   let ctor = function(input) {
     // We want to support both syntaxes:
     // let t = new PlacesTransactions.NewBookmark(),
     // let t = PlacesTransactions.NewBookmark()
     if (this == PlacesTransactions) {
       return new ctor(input);
     }
 
-    if (requiredProps.length > 0 || optionalProps.length > 0) {
+    if (requiredProps.length || optionalProps.length) {
       // Bind the input properties to the arguments of execute.
       input = DefineTransaction.verifyInput(
         input,
         requiredProps,
         optionalProps
       );
       this.execute = this.execute.bind(this, input);
     }
@@ -853,17 +853,17 @@ DefineTransaction.defineArrayInputProp =
     validateInput(input, required) {
       if (name in input) {
         // It's not allowed to set both though.
         if (basePropertyName in input) {
           throw new Error(`It is not allowed to set both ${name} and
                           ${basePropertyName} as  input properties`);
         }
         let array = this.validateValue(input[name]);
-        if (required && array.length == 0) {
+        if (required && !array.length) {
           throw new Error(`Empty array passed for required input property:
                            ${name}`);
         }
         return array;
       }
       // If the property is required and it's not set as is, check if the base
       // property is set.
       if (required && !(basePropertyName in input)) {
@@ -891,17 +891,17 @@ DefineTransaction.getInputObjectForSingl
   optionalProps
 ) {
   // The following input forms may be deduced from a single value:
   // * a single required property with or without optional properties (the given
   //   value is set to the required property).
   // * a single optional property with no required properties.
   if (
     requiredProps.length > 1 ||
-    (requiredProps.length == 0 && optionalProps.length > 1)
+    (!requiredProps.length && optionalProps.length > 1)
   ) {
     throw new Error("Transaction input isn't an object");
   }
 
   let propName =
     requiredProps.length == 1 ? requiredProps[0] : optionalProps[0];
   let propValue =
     this.inputProps.get(propName).isArrayProperty && !Array.isArray(input)
@@ -910,17 +910,17 @@ DefineTransaction.getInputObjectForSingl
   return { [propName]: propValue };
 };
 
 DefineTransaction.verifyInput = function(
   input,
   requiredProps = [],
   optionalProps = []
 ) {
-  if (requiredProps.length == 0 && optionalProps.length == 0) {
+  if (!requiredProps.length && !optionalProps.length) {
     return {};
   }
 
   // If there's just a single required/optional property, we allow passing it
   // as is, so, for example, one could do PlacesTransactions.Remove(myGuid)
   // rather than PlacesTransactions.Remove({ guid: myGuid}).
   // This shortcut isn't supported for "complex" properties, like objects (note
   // there is no use case for this at the moment anyway).
@@ -1087,36 +1087,36 @@ var PT = PlacesTransactions;
 PT.NewBookmark = DefineTransaction(
   ["parentGuid", "url"],
   ["index", "title", "tags"]
 );
 PT.NewBookmark.prototype = Object.seal({
   async execute({ parentGuid, url, index, title, tags }) {
     let info = { parentGuid, index, url, title };
     // Filter tags to exclude already existing ones.
-    if (tags.length > 0) {
+    if (tags.length) {
       let currentTags = PlacesUtils.tagging.getTagsForURI(
         Services.io.newURI(url.href)
       );
       tags = tags.filter(t => !currentTags.includes(t));
     }
 
     async function createItem() {
       info = await PlacesUtils.bookmarks.insert(info);
-      if (tags.length > 0) {
+      if (tags.length) {
         PlacesUtils.tagging.tagURI(Services.io.newURI(url.href), tags);
       }
     }
 
     await createItem();
 
     this.undo = async function() {
       // Pick up the removed info so we have the accurate last-modified value.
       await PlacesUtils.bookmarks.remove(info);
-      if (tags.length > 0) {
+      if (tags.length) {
         PlacesUtils.tagging.untagURI(Services.io.newURI(url.href), tags);
       }
     };
     this.redo = async function() {
       await createItem();
     };
     return info.guid;
   },
@@ -1146,17 +1146,17 @@ PT.NewFolder.prototype = Object.seal({
           type: PlacesUtils.bookmarks.TYPE_FOLDER,
         },
       ],
       // insertTree uses guid as the parent for where it is being inserted
       // into.
       guid: parentGuid,
     };
 
-    if (children && children.length > 0) {
+    if (children && children.length) {
       // Ensure to specify a guid for each child to be restored on redo.
       info.children[0].children = children.map(c => {
         c.guid = PlacesUtils.history.makeGuid();
         return c;
       });
     }
 
     async function createItem() {
@@ -1297,40 +1297,40 @@ PT.EditUrl.prototype = Object.seal({
     let originalURI = Services.io.newURI(originalInfo.url.href);
     let originalTags = PlacesUtils.tagging.getTagsForURI(originalURI);
     let updatedInfo = { guid, url };
     let newURIAdditionalTags = null;
 
     async function updateItem() {
       updatedInfo = await PlacesUtils.bookmarks.update(updatedInfo);
       // Move tags from the original URI to the new URI.
-      if (originalTags.length > 0) {
+      if (originalTags.length) {
         // Untag the original URI only if this was the only bookmark.
         if (!(await PlacesUtils.bookmarks.fetch({ url: originalInfo.url }))) {
           PlacesUtils.tagging.untagURI(originalURI, originalTags);
         }
         let currentNewURITags = PlacesUtils.tagging.getTagsForURI(uri);
         newURIAdditionalTags = originalTags.filter(
           t => !currentNewURITags.includes(t)
         );
-        if (newURIAdditionalTags && newURIAdditionalTags.length > 0) {
+        if (newURIAdditionalTags && newURIAdditionalTags.length) {
           PlacesUtils.tagging.tagURI(uri, newURIAdditionalTags);
         }
       }
     }
     await updateItem();
 
     this.undo = async function() {
       await PlacesUtils.bookmarks.update(originalInfo);
       // Move tags from new URI to original URI.
-      if (originalTags.length > 0) {
+      if (originalTags.length) {
         // Only untag the new URI if this is the only bookmark.
         if (
           newURIAdditionalTags &&
-          newURIAdditionalTags.length > 0 &&
+          !!newURIAdditionalTags.length &&
           !(await PlacesUtils.bookmarks.fetch({ url }))
         ) {
           PlacesUtils.tagging.untagURI(uri, newURIAdditionalTags);
         }
         PlacesUtils.tagging.tagURI(originalURI, originalTags);
       }
     };
 
@@ -1411,28 +1411,28 @@ PT.SortByName.prototype = {
 
     // This is not great, since it does main-thread IO.
     // PromiseBookmarksTree can't be used, since it' won't stop at the first level'.
     let root = PlacesUtils.getFolderContents(guid, false, false).root;
     for (let i = 0; i < root.childCount; ++i) {
       let node = root.getChild(i);
       oldOrderGuids.push(node.bookmarkGuid);
       if (PlacesUtils.nodeIsSeparator(node)) {
-        if (preSepNodes.length > 0) {
+        if (preSepNodes.length) {
           preSepNodes.sort(sortingMethod);
           newOrderGuids.push(...preSepNodes.map(n => n.bookmarkGuid));
           preSepNodes = [];
         }
         newOrderGuids.push(node.bookmarkGuid);
       } else {
         preSepNodes.push(node);
       }
     }
     root.containerOpen = false;
-    if (preSepNodes.length > 0) {
+    if (preSepNodes.length) {
       preSepNodes.sort(sortingMethod);
       newOrderGuids.push(...preSepNodes.map(n => n.bookmarkGuid));
     }
     await PlacesUtils.bookmarks.reorder(guid, newOrderGuids);
 
     this.undo = async function() {
       await PlacesUtils.bookmarks.reorder(guid, oldOrderGuids);
     };
@@ -1553,31 +1553,31 @@ PT.Untag = DefineTransaction(["urls"], [
 PT.Untag.prototype = {
   execute({ urls, tags }) {
     let onUndo = [],
       onRedo = [];
     for (let url of urls) {
       let uri = Services.io.newURI(url.href);
       let tagsToRemove;
       let tagsSet = PlacesUtils.tagging.getTagsForURI(uri);
-      if (tags.length > 0) {
+      if (tags.length) {
         tagsToRemove = tags.filter(t => tagsSet.includes(t));
       } else {
         tagsToRemove = tagsSet;
       }
-      if (tagsToRemove.length > 0) {
+      if (tagsToRemove.length) {
         PlacesUtils.tagging.untagURI(uri, tagsToRemove);
       }
       onUndo.unshift(() => {
-        if (tagsToRemove.length > 0) {
+        if (tagsToRemove.length) {
           PlacesUtils.tagging.tagURI(uri, tagsToRemove);
         }
       });
       onRedo.push(() => {
-        if (tagsToRemove.length > 0) {
+        if (tagsToRemove.length) {
           PlacesUtils.tagging.untagURI(uri, tagsToRemove);
         }
       });
     }
     this.undo = async function() {
       for (let f of onUndo) {
         await f();
       }
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -851,28 +851,28 @@ var PlacesUtils = {
   SYNC_BOOKMARK_VALIDATORS,
   SYNC_CHANGE_RECORD_VALIDATORS,
 
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
 
   _shutdownFunctions: [],
   registerShutdownFunction: function PU_registerShutdownFunction(aFunc) {
     // If this is the first registered function, add the shutdown observer.
-    if (this._shutdownFunctions.length == 0) {
+    if (!this._shutdownFunctions.length) {
       Services.obs.addObserver(this, this.TOPIC_SHUTDOWN);
     }
     this._shutdownFunctions.push(aFunc);
   },
 
   // nsIObserver
   observe: function PU_observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case this.TOPIC_SHUTDOWN:
         Services.obs.removeObserver(this, this.TOPIC_SHUTDOWN);
-        while (this._shutdownFunctions.length > 0) {
+        while (this._shutdownFunctions.length) {
           this._shutdownFunctions.shift().apply(this);
         }
         break;
     }
   },
 
   /**
    * Determines whether or not a ResultNode is a host container.
@@ -2819,17 +2819,17 @@ var GuidHelper = {
 
     let itemId = await PlacesUtils.withConnectionWrapper(
       "GuidHelper.getItemId",
       async function(db) {
         let rows = await db.executeCached(
           "SELECT b.id, b.guid from moz_bookmarks b WHERE b.guid = :guid LIMIT 1",
           { guid: aGuid }
         );
-        if (rows.length == 0) {
+        if (!rows.length) {
           throw new Error("no item found for the given GUID");
         }
 
         return rows[0].getResultByName("id");
       }
     );
 
     this.updateCache(itemId, aGuid);
@@ -2874,17 +2874,17 @@ var GuidHelper = {
 
     let guid = await PlacesUtils.withConnectionWrapper(
       "GuidHelper.getItemGuid",
       async function(db) {
         let rows = await db.executeCached(
           "SELECT b.id, b.guid from moz_bookmarks b WHERE b.id = :id LIMIT 1",
           { id: aItemId }
         );
-        if (rows.length == 0) {
+        if (!rows.length) {
           throw new Error("no item found for the given itemId");
         }
 
         return rows[0].getResultByName("guid");
       }
     );
 
     this.updateCache(aItemId, guid);
--- a/toolkit/components/places/TaggingService.jsm
+++ b/toolkit/components/places/TaggingService.jsm
@@ -126,17 +126,17 @@ TaggingService.prototype = {
         if (typeof idOrName == "number" && this._tagFolders[idOrName]) {
           // This is a tag folder id.
           tag.id = idOrName;
           // We can't know the name at this point, since a previous tag could
           // want to change it.
           tag.__defineGetter__("name", () => this._tagFolders[tag.id]);
         } else if (
           typeof idOrName == "string" &&
-          idOrName.length > 0 &&
+          !!idOrName.length &&
           idOrName.length <= PlacesUtils.bookmarks.MAX_TAG_LENGTH
         ) {
           // This is a tag name.
           tag.name = trim ? idOrName.trim() : idOrName;
           // We can't know the id at this point, since a previous tag could
           // have created it.
           tag.__defineGetter__("id", () => this._getItemIdForTag(tag.name));
         } else {
@@ -146,17 +146,17 @@ TaggingService.prototype = {
           );
         }
         return tag;
       });
   },
 
   // nsITaggingService
   tagURI: function TS_tagURI(aURI, aTags, aSource) {
-    if (!aURI || !aTags || !Array.isArray(aTags) || aTags.length == 0) {
+    if (!aURI || !aTags || !Array.isArray(aTags) || !aTags.length) {
       throw Components.Exception(
         "Invalid value for tags",
         Cr.NS_ERROR_INVALID_ARG
       );
     }
 
     // This also does some input validation.
     let tags = this._convertInputMixedTagsArray(aTags, true);
@@ -225,17 +225,17 @@ TaggingService.prototype = {
 
     if (count == 0) {
       PlacesUtils.bookmarks.removeItem(aTagId, aSource);
     }
   },
 
   // nsITaggingService
   untagURI: function TS_untagURI(aURI, aTags, aSource) {
-    if (!aURI || (aTags && (!Array.isArray(aTags) || aTags.length == 0))) {
+    if (!aURI || (aTags && (!Array.isArray(aTags) || !aTags.length))) {
       throw Components.Exception(
         "Invalid value for tags",
         Cr.NS_ERROR_INVALID_ARG
       );
     }
 
     if (!aTags) {
       // Passing null should clear all tags for aURI, see the IDL.
--- a/toolkit/components/places/UnifiedComplete.jsm
+++ b/toolkit/components/places/UnifiedComplete.jsm
@@ -642,17 +642,17 @@ function Search(
   // Use the original string here, not the stripped one, so the tokenizer can
   // properly recognize token types.
   let { tokens } = UrlbarTokenizer.tokenize({
     searchString: unescapedSearchString,
   });
 
   // This allows to handle leading or trailing restriction characters specially.
   this._leadingRestrictionToken = null;
-  if (tokens.length > 0) {
+  if (tokens.length) {
     if (
       UrlbarTokenizer.isRestrictionToken(tokens[0]) &&
       (tokens.length > 1 ||
         tokens[0].type == UrlbarTokenizer.TYPE.RESTRICT_SEARCH)
     ) {
       this._leadingRestrictionToken = tokens[0].value;
     }
 
@@ -667,17 +667,17 @@ function Search(
 
   // The heuristic token is the first filtered search token, but only when it's
   // actually the first thing in the search string.  If a prefix or restriction
   // character occurs first, then the heurstic token is null.  We use the
   // heuristic token to help determine the heuristic result.  It may be a Places
   // keyword, a search engine alias, an extension keyword, or simply a URL or
   // part of the search string the user has typed.  We won't know until we
   // create the heuristic result.
-  let firstToken = this._searchTokens.length > 0 && this._searchTokens[0].value;
+  let firstToken = !!this._searchTokens.length && this._searchTokens[0].value;
   this._heuristicToken =
     firstToken && this._trimmedOriginalSearchString.startsWith(firstToken)
       ? firstToken
       : null;
 
   this._keywordSubstitute = null;
 
   this._prohibitSearchSuggestions = prohibitSearchSuggestions;
@@ -1334,17 +1334,17 @@ Search.prototype = {
 
     return false;
   },
 
   async _matchFirstHeuristicResult(conn) {
     // We always try to make the first result a special "heuristic" result.  The
     // heuristics below determine what type of result it will be, if any.
 
-    let hasSearchTerms = this._searchTokens.length > 0;
+    let hasSearchTerms = !!this._searchTokens.length;
 
     if (hasSearchTerms) {
       // It may be a keyword registered by an extension.
       let matched = await this._matchExtensionHeuristicResult();
       if (matched) {
         return true;
       }
     }
@@ -2037,17 +2037,17 @@ Search.prototype = {
     }
 
     // Do not apply the special style if the user is doing a search from the
     // location bar but the entered terms match an irrelevant portion of the
     // URL. For example, "https://www.google.com/search?q=terms&client=firefox"
     // when searching for "Firefox".
     let terms = parseResult.terms.toLowerCase();
     if (
-      this._searchTokens.length > 0 &&
+      this._searchTokens.length &&
       this._searchTokens.every(token => !terms.includes(token.value))
     ) {
       return;
     }
 
     // Turn the match into a searchengine action with a favicon.
     match.value = PlacesUtils.mozActionURI("searchengine", {
       engineName: parseResult.engineName,
@@ -2204,17 +2204,17 @@ Search.prototype = {
         count: 0,
       }));
 
       // If we have matches from the previous search, we want to replace them
       // in-place to reduce flickering.
       // This requires walking the previous matches and marking their existence
       // into the current buckets, so that, when we'll add the new matches to
       // the buckets, we can either append or replace a match.
-      if (this._previousSearchMatchTypes.length > 0) {
+      if (this._previousSearchMatchTypes.length) {
         for (let type of this._previousSearchMatchTypes) {
           for (let bucket of this._buckets) {
             if (type == bucket.type && bucket.count < bucket.available) {
               bucket.count++;
               break;
             }
           }
         }
@@ -2249,17 +2249,17 @@ Search.prototype = {
    * current search
    * @param type
    *        The UrlbarUtils.RESULT_GROUP to clean up.  Pass null (or another
    *        falsey value) to clean up all groups.
    * @param [optional] notify
    *        Whether to notify a result change.
    */
   _cleanUpNonCurrentMatches(type, notify = true) {
-    if (this._previousSearchMatchTypes.length == 0 || !this.pending) {
+    if (!this._previousSearchMatchTypes.length || !this.pending) {
       return;
     }
 
     let index = 0;
     let changed = false;
     if (!this._buckets) {
       // No match arrived yet, so any match of the given type should be removed
       // from the top.
@@ -2290,20 +2290,17 @@ Search.prototype = {
       this.notifyResult(true);
     }
   },
 
   /**
    * If in restrict mode, cleanups non current matches for all the empty types.
    */
   cleanUpRestrictNonCurrentMatches() {
-    if (
-      this.hasBehavior("restrict") &&
-      this._previousSearchMatchTypes.length > 0
-    ) {
+    if (this.hasBehavior("restrict") && this._previousSearchMatchTypes.length) {
       for (let type of new Set(this._previousSearchMatchTypes)) {
         if (this._counts[type] == 0) {
           // Don't notify, since we are about to notify completion.
           this._cleanUpNonCurrentMatches(type, false);
         }
       }
     }
   },
@@ -2608,17 +2605,17 @@ Search.prototype = {
     // Don't try to autofill if the search term includes any whitespace.
     // This may confuse completeDefaultIndex cause the AUTOCOMPLETE_MATCH
     // tokenizer ends up trimming the search string and returning a value
     // that doesn't match it, or is even shorter.
     if (REGEXP_SPACES.test(this._originalSearchString)) {
       return false;
     }
 
-    if (this._searchString.length == 0) {
+    if (!this._searchString.length) {
       return false;
     }
 
     if (this._prohibitAutoFill) {
       return false;
     }
 
     return true;
@@ -2898,18 +2895,18 @@ UnifiedComplete.prototype = {
       insertMethod != UrlbarUtils.INSERTMETHOD.APPEND
     ) {
       let result = this._currentSearch._result;
       // Only reuse the previous result when one of the search strings is an
       // extension of the other one.  We could expand this to any case, but
       // that may leave exposed unrelated matches for a longer time.
       let previousSearchString = result.searchString;
       let stringsRelated =
-        previousSearchString.length > 0 &&
-        searchString.length > 0 &&
+        !!previousSearchString.length &&
+        !!searchString.length &&
         (previousSearchString.includes(searchString) ||
           searchString.includes(previousSearchString));
       if (insertMethod == UrlbarUtils.INSERTMETHOD.MERGE || stringsRelated) {
         previousResult = result;
       }
     }
 
     let search = (this._currentSearch = new Search(
--- a/toolkit/components/places/tests/PlacesTestUtils.jsm
+++ b/toolkit/components/places/tests/PlacesTestUtils.jsm
@@ -193,17 +193,17 @@ var PlacesTestUtils = Object.freeze({
    */
   async isPageInDB(aURI) {
     let url = aURI instanceof Ci.nsIURI ? aURI.spec : aURI;
     let db = await PlacesUtils.promiseDBConnection();
     let rows = await db.executeCached(
       "SELECT id FROM moz_places WHERE url_hash = hash(:url) AND url = :url",
       { url }
     );
-    return rows.length > 0;
+    return !!rows.length;
   },
 
   /**
    * Asynchronously checks how many visits exist for a specified page.
    * @param aURI
    *        nsIURI or address to look for.
    *
    * @return {Promise}
--- a/toolkit/components/places/tests/favicons/test_root_icons.js
+++ b/toolkit/components/places/tests/favicons/test_root_icons.js
@@ -126,17 +126,17 @@ add_task(async function test_removePages
 
   await PlacesUtils.history.removeByFilter({
     beginDate: new Date(0),
     endDt: new Date(),
   });
   await PlacesTestUtils.promiseAsyncUpdates();
   rows = await db.execute("SELECT * FROM moz_icons");
   // Debug logging for possible intermittent failure (bug 1358368).
-  if (rows.length != 0) {
+  if (rows.length) {
     dump_table("moz_icons");
   }
   Assert.equal(rows.length, 0, "There should be no icon entry");
 });
 
 add_task(async function test_different_host() {
   let pageURI = NetUtil.newURI("http://places.test/page/");
   await PlacesTestUtils.addVisits(pageURI);
--- a/toolkit/components/places/tests/head_common.js
+++ b/toolkit/components/places/tests/head_common.js
@@ -702,18 +702,18 @@ function do_compare_arrays(a1, a2, sorte
   if (a1.length != a2.length) {
     return false;
   }
 
   if (sorted) {
     return a1.every((e, i) => e == a2[i]);
   }
   return (
-    a1.filter(e => !a2.includes(e)).length == 0 &&
-    a2.filter(e => !a1.includes(e)).length == 0
+    !a1.filter(e => !a2.includes(e)).length &&
+    !a2.filter(e => !a1.includes(e)).length
   );
 }
 
 /**
  * Generic nsINavBookmarkObserver that doesn't implement anything, but provides
  * dummy methods to prevent errors about an object not having a certain method.
  */
 function NavBookmarkObserver() {}
@@ -799,17 +799,17 @@ async function foreign_count(url) {
   }
   let db = await PlacesUtils.promiseDBConnection();
   let rows = await db.executeCached(
     `SELECT foreign_count FROM moz_places
      WHERE url_hash = hash(:url) AND url = :url
     `,
     { url }
   );
-  return rows.length == 0 ? 0 : rows[0].getResultByName("foreign_count");
+  return !rows.length ? 0 : rows[0].getResultByName("foreign_count");
 }
 
 function compareAscending(a, b) {
   if (a > b) {
     return 1;
   }
   if (a < b) {
     return -1;
@@ -901,19 +901,19 @@ async function compareFavicons(icon1, ic
           let size = inputStream.available();
           resolve(NetUtil.readInputStreamToString(inputStream, size));
         }
       );
     });
   }
 
   let data1 = await getIconData(icon1);
-  Assert.ok(data1.length > 0, "Should fetch icon data");
+  Assert.ok(!!data1.length, "Should fetch icon data");
   let data2 = await getIconData(icon2);
-  Assert.ok(data2.length > 0, "Should fetch icon data");
+  Assert.ok(!!data2.length, "Should fetch icon data");
   Assert.deepEqual(data1, data2, msg);
 }
 
 /**
  * Get the internal "root" folder name for an item, specified by its itemGuid.
  * If the itemGuid does not point to a root folder, null is returned.
  *
  * @param itemGuid
--- a/toolkit/components/places/tests/history/test_async_history_api.js
+++ b/toolkit/components/places/tests/history/test_async_history_api.js
@@ -371,17 +371,17 @@ add_task(async function test_non_addable
       // NetUtil.newURI() can throw if e.g. our app knows about imap://
       // but the account is not set up and so the URL is invalid for us.
       // Note this in the log but ignore as it's not the subject of this test.
       info("Could not construct URI for '" + url + "'; ignoring");
     }
   });
 
   let placesResult = await promiseUpdatePlaces(places);
-  if (placesResult.results.length > 0) {
+  if (placesResult.results.length) {
     do_throw("Unexpected success.");
   }
   for (let place of placesResult.errors) {
     info("Checking '" + place.info.uri.spec + "'");
     Assert.equal(place.resultCode, Cr.NS_ERROR_INVALID_ARG);
     Assert.equal(false, await PlacesUtils.history.hasVisits(place.info.uri));
   }
   await PlacesTestUtils.promiseAsyncUpdates();
@@ -392,31 +392,31 @@ add_task(async function test_duplicate_g
   // another visit, fails.
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_duplicate_guid_fails_first"),
     visits: [new VisitInfo()],
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   Assert.ok(await PlacesUtils.history.hasVisits(placeInfo.uri));
 
   let badPlace = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_duplicate_guid_fails_second"),
     visits: [new VisitInfo()],
     guid: placeInfo.guid,
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(badPlace.uri));
   placesResult = await promiseUpdatePlaces(badPlace);
-  if (placesResult.results.length > 0) {
+  if (placesResult.results.length) {
     do_throw("Unexpected success.");
   }
   let badPlaceInfo = placesResult.errors[0];
   Assert.equal(badPlaceInfo.resultCode, Cr.NS_ERROR_STORAGE_CONSTRAINT);
   Assert.equal(
     false,
     await PlacesUtils.history.hasVisits(badPlaceInfo.info.uri)
   );
@@ -434,17 +434,17 @@ add_task(async function test_invalid_ref
   );
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
   Assert.equal(
     false,
     await PlacesUtils.history.hasVisits(place.visits[0].referrerURI)
   );
 
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   Assert.ok(await PlacesUtils.history.hasVisits(placeInfo.uri));
 
   // Check to make sure we do not visit the invalid referrer.
   Assert.equal(
     false,
@@ -469,17 +469,17 @@ add_task(async function test_nonnsIURI_r
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_nonnsIURI_referrerURI_ignored"),
     visits: [new VisitInfo()],
   };
   place.visits[0].referrerURI = place.uri.spec + "_nonnsIURI";
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
 
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   Assert.ok(await PlacesUtils.history.hasVisits(placeInfo.uri));
 
   // Check to make sure from_visit is zero in database.
   let stmt = DBConn().createStatement(
     `SELECT from_visit
@@ -503,17 +503,17 @@ add_task(async function test_old_referre
     uri: NetUtil.newURI(TEST_DOMAIN + "test_old_referrer_ignored_referrer"),
     visits: [new VisitInfo(TRANSITION_LINK, oldTime)],
   };
 
   // First we must add our referrer to the history so that it is not ignored
   // as being invalid.
   Assert.equal(false, await PlacesUtils.history.hasVisits(referrerPlace.uri));
   let placesResult = await promiseUpdatePlaces(referrerPlace);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
 
   // Now that the referrer is added, we can add a page with a valid
   // referrer to determine if the recency of the referrer is taken into
   // account.
   Assert.ok(await PlacesUtils.history.hasVisits(referrerPlace.uri));
 
@@ -521,17 +521,17 @@ add_task(async function test_old_referre
   visitInfo.referrerURI = referrerPlace.uri;
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_old_referrer_ignored_page"),
     visits: [visitInfo],
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
   placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   Assert.ok(await PlacesUtils.history.hasVisits(place.uri));
 
   // Though the visit will not contain the referrer, we must examine the
   // database to be sure.
   Assert.equal(placeInfo.visits[0].referrerURI, null);
@@ -553,34 +553,34 @@ add_task(async function test_old_referre
 add_task(async function test_place_id_ignored() {
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_place_id_ignored_first"),
     visits: [new VisitInfo()],
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   Assert.ok(await PlacesUtils.history.hasVisits(place.uri));
 
   let placeId = placeInfo.placeId;
   Assert.notEqual(placeId, 0);
 
   let badPlace = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_place_id_ignored_second"),
     visits: [new VisitInfo()],
     placeId,
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(badPlace.uri));
   placesResult = await promiseUpdatePlaces(badPlace);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   placeInfo = placesResult.results[0];
 
   Assert.notEqual(placeInfo.placeId, placeId);
   Assert.ok(await PlacesUtils.history.hasVisits(badPlace.uri));
 
   await PlacesTestUtils.promiseAsyncUpdates();
@@ -626,17 +626,17 @@ add_task(async function test_add_visit()
   for (let t in PlacesUtils.history.TRANSITIONS) {
     let transitionType = PlacesUtils.history.TRANSITIONS[t];
     place.visits.push(new VisitInfo(transitionType, VISIT_TIME));
   }
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
 
   let callbackCount = 0;
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   for (let placeInfo of placesResult.results) {
     Assert.ok(await PlacesUtils.history.hasVisits(place.uri));
 
     // Check mozIPlaceInfo properties.
     Assert.ok(place.uri.equals(placeInfo.uri));
     Assert.equal(placeInfo.frecency, -1); // We don't pass frecency here!
@@ -693,17 +693,17 @@ add_task(async function test_properties_
       visits: [new VisitInfo(transitionType)],
     };
     Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
     places.push(place);
   }
 
   let callbackCount = 0;
   let placesResult = await promiseUpdatePlaces(places);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   for (let placeInfo of placesResult.results) {
     let uri = placeInfo.uri;
     Assert.ok(await PlacesUtils.history.hasVisits(uri));
     let visit = placeInfo.visits[0];
     print(
       "TEST-INFO | test_properties_saved | updatePlaces callback for " +
@@ -769,17 +769,17 @@ add_task(async function test_guid_saved(
     uri: NetUtil.newURI(TEST_DOMAIN + "test_guid_saved"),
     guid: "__TESTGUID__",
     visits: [new VisitInfo()],
   };
   do_check_valid_places_guid(place.guid);
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
 
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   let uri = placeInfo.uri;
   Assert.ok(await PlacesUtils.history.hasVisits(uri));
   Assert.equal(placeInfo.guid, place.guid);
   do_check_guid_for_uri(uri, place.guid);
   await PlacesTestUtils.promiseAsyncUpdates();
@@ -797,17 +797,17 @@ add_task(async function test_referrer_sa
     },
   ];
   places[1].visits[0].referrerURI = places[0].uri;
   Assert.equal(false, await PlacesUtils.history.hasVisits(places[0].uri));
   Assert.equal(false, await PlacesUtils.history.hasVisits(places[1].uri));
 
   let resultCount = 0;
   let placesResult = await promiseUpdatePlaces(places);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   for (let placeInfo of placesResult.results) {
     let uri = placeInfo.uri;
     Assert.ok(await PlacesUtils.history.hasVisits(uri));
     let visit = placeInfo.visits[0];
 
     // We need to insert all of our visits before we can test conditions.
@@ -841,24 +841,24 @@ add_task(async function test_guid_change
   // First, add a visit for it.
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_guid_change_saved"),
     visits: [new VisitInfo()],
   };
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
 
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   // Then, change the guid with visits.
   place.guid = "_GUIDCHANGE_";
   place.visits = [new VisitInfo()];
   placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   do_check_guid_for_uri(place.uri, place.guid);
 
   await PlacesTestUtils.promiseAsyncUpdates();
 });
 
 add_task(async function test_title_change_saved() {
@@ -866,43 +866,43 @@ add_task(async function test_title_chang
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_title_change_saved"),
     title: "original title",
     visits: [new VisitInfo()],
   };
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
 
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
 
   // Now, make sure the empty string clears the title.
   place.title = "";
   place.visits = [new VisitInfo()];
   placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   do_check_title_for_uri(place.uri, null);
 
   // Then, change the title with visits.
   place.title = "title change";
   place.visits = [new VisitInfo()];
   placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   do_check_title_for_uri(place.uri, place.title);
 
   // Lastly, check that the title is cleared if we set it to null.
   place.title = null;
   place.visits = [new VisitInfo()];
   placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   do_check_title_for_uri(place.uri, place.title);
 
   await PlacesTestUtils.promiseAsyncUpdates();
 });
 
 add_task(async function test_no_title_does_not_clear_title() {
@@ -911,24 +911,24 @@ add_task(async function test_no_title_do
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_no_title_does_not_clear_title"),
     title: TITLE,
     visits: [new VisitInfo()],
   };
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
 
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   // Now, make sure that not specifying a title does not clear it.
   delete place.title;
   place.visits = [new VisitInfo()];
   placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   do_check_title_for_uri(place.uri, TITLE);
 
   await PlacesTestUtils.promiseAsyncUpdates();
 });
 
 add_task(async function test_title_change_notifies() {
@@ -945,17 +945,17 @@ add_task(async function test_title_chang
     "DO NOT WANT",
     function() {
       do_throw("unexpected callback!");
     }
   );
 
   PlacesUtils.history.addObserver(silentObserver);
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
 
   // The second case to test is that we don't get the notification when we add
   // it for the first time.  The first case will fail before our callback if it
   // is busted, so we can do this now.
   place.uri = NetUtil.newURI(place.uri.spec + "/new-visit-with-title");
   place.title = "title 1";
@@ -1162,31 +1162,31 @@ add_task(async function test_ignore_erro
   // another visit, fails - but doesn't report if we told it not to.
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_duplicate_guid_fails_first"),
     visits: [new VisitInfo()],
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   Assert.ok(await PlacesUtils.history.hasVisits(placeInfo.uri));
 
   let badPlace = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_duplicate_guid_fails_second"),
     visits: [new VisitInfo()],
     guid: placeInfo.guid,
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(badPlace.uri));
   placesResult = await promiseUpdatePlaces(badPlace, { ignoreErrors: true });
-  if (placesResult.results.length > 0) {
+  if (placesResult.results.length) {
     do_throw("Unexpected success.");
   }
   Assert.equal(
     placesResult.errors.length,
     0,
     "Should have seen 0 errors because we disabled reporting."
   );
   Assert.equal(
@@ -1234,17 +1234,17 @@ add_task(async function test_ignore_resu
   // another visit, fails - but doesn't report if we told it not to.
   let place = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_duplicate_guid_fails_first"),
     visits: [new VisitInfo()],
   };
 
   Assert.equal(false, await PlacesUtils.history.hasVisits(place.uri));
   let placesResult = await promiseUpdatePlaces(place);
-  if (placesResult.errors.length > 0) {
+  if (placesResult.errors.length) {
     do_throw("Unexpected error.");
   }
   let placeInfo = placesResult.results[0];
   Assert.ok(await PlacesUtils.history.hasVisits(placeInfo.uri));
 
   let badPlace = {
     uri: NetUtil.newURI(TEST_DOMAIN + "test_duplicate_guid_fails_second"),
     visits: [new VisitInfo()],
--- a/toolkit/components/places/tests/history/test_update.js
+++ b/toolkit/components/places/tests/history/test_update.js
@@ -160,17 +160,17 @@ add_task(async function test_description
     descriptionInDB,
     "description should be updated via GUID as expected"
   );
 
   description = "Test descipriton".repeat(1000);
   await PlacesUtils.history.update({ url: TEST_URL, description });
   descriptionInDB = await PlacesTestUtils.fieldInDB(TEST_URL, "description");
   Assert.ok(
-    0 < descriptionInDB.length < description.length,
+    !!descriptionInDB.length < description.length,
     "a long description should be truncated"
   );
 
   description = null;
   await PlacesUtils.history.update({ url: TEST_URL, description });
   descriptionInDB = await PlacesTestUtils.fieldInDB(TEST_URL, "description");
   Assert.strictEqual(
     description,
--- a/toolkit/components/places/tests/queries/test_redirects.js
+++ b/toolkit/components/places/tests/queries/test_redirects.js
@@ -45,19 +45,19 @@ function check_results_callback(aSequenc
     // Embed visits never appear in results.
     if (aVisit.transType == Ci.nsINavHistoryService.TRANSITION_EMBED) {
       return false;
     }
 
     if (!includeHidden && isHidden(aVisit)) {
       // If the page has any non-hidden visit, then it's visible.
       if (
-        visits.filter(function(refVisit) {
+        !visits.filter(function(refVisit) {
           return refVisit.uri == aVisit.uri && !isHidden(refVisit);
-        }).length == 0
+        }).length
       ) {
         return false;
       }
     }
 
     return true;
   });
 
--- a/toolkit/components/places/tests/queries/test_results-as-visit.js
+++ b/toolkit/components/places/tests/queries/test_results-as-visit.js
@@ -15,17 +15,17 @@ function createTestData() {
   function generateVisits(aPage) {
     for (var i = 0; i < aPage.visitCount; i++) {
       testData.push({
         isInQuery: aPage.inQuery,
         isVisit: true,
         title: aPage.title,
         uri: aPage.uri,
         lastVisit: newTimeInMicroseconds(),
-        isTag: aPage.tags && aPage.tags.length > 0,
+        isTag: aPage.tags && !!aPage.tags.length,
         tagArray: aPage.tags,
       });
     }
   }
 
   var pages = [
     {
       uri: "http://foo.com/",
--- a/toolkit/components/places/tests/unit/test_async_transactions.js
+++ b/toolkit/components/places/tests/unit/test_async_transactions.js
@@ -1728,20 +1728,19 @@ add_task(async function test_untag_uri()
 
     function ensureTagsSet() {
       for (let url of urls) {
         ensureTagsForURI(url, preRemovalTags.get(url));
       }
     }
     function ensureTagsUnset() {
       for (let url of urls) {
-        let expectedTags =
-          tagsRemoved.length == 0
-            ? []
-            : preRemovalTags.get(url).filter(tag => !tagsRemoved.includes(tag));
+        let expectedTags = !tagsRemoved.length
+          ? []
+          : preRemovalTags.get(url).filter(tag => !tagsRemoved.includes(tag));
         ensureTagsForURI(url, expectedTags);
       }
     }
 
     await PT.Untag(aInfo).transact();
     await ensureTagsUnset();
     await PT.undo();
     await ensureTagsSet();
--- a/toolkit/components/places/tests/unit/test_bookmarks_html.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_html.js
@@ -365,17 +365,17 @@ function checkItem(aExpected, aNode) {
           break;
         case "feedUrl":
           // No more supported.
           break;
         case "children":
           let folder = aNode.QueryInterface(
             Ci.nsINavHistoryContainerResultNode
           );
-          Assert.equal(folder.hasChildren, aExpected.children.length > 0);
+          Assert.equal(folder.hasChildren, !!aExpected.children.length);
           folder.containerOpen = true;
           Assert.equal(folder.childCount, aExpected.children.length);
 
           for (let index = 0; index < aExpected.children.length; index++) {
             await checkItem(aExpected.children[index], folder.getChild(index));
           }
 
           folder.containerOpen = false;
--- a/toolkit/components/places/tests/unit/test_bookmarks_json.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_json.js
@@ -265,17 +265,17 @@ async function checkItem(aExpected, aNod
         });
         Assert.equal(
           pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO),
           aExpected.charset
         );
         break;
       case "children":
         let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
-        Assert.equal(folder.hasChildren, aExpected.children.length > 0);
+        Assert.equal(folder.hasChildren, !!aExpected.children.length);
         folder.containerOpen = true;
         Assert.equal(folder.childCount, aExpected.children.length);
 
         for (let index = 0; index < aExpected.children.length; index++) {
           await checkItem(aExpected.children[index], folder.getChild(index));
         }
 
         folder.containerOpen = false;
--- a/toolkit/components/places/tests/unit/test_null_interfaces.js
+++ b/toolkit/components/places/tests/unit/test_null_interfaces.js
@@ -45,17 +45,17 @@ function run_test() {
 
     let okName = function(name) {
       info(`Checking if function is okay to test: ${name}`);
       let func = s[name];
 
       let mesg = "";
       if (typeof func != "function") {
         mesg = "Not a function!";
-      } else if (func.length == 0) {
+      } else if (!func.length) {
         mesg = "No args needed!";
       } else if (name == "QueryInterface") {
         mesg = "Ignore QI!";
       }
 
       if (mesg) {
         info(`${mesg} Skipping: ${name}`);
         return false;
--- a/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js
+++ b/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js
@@ -71,17 +71,17 @@ async function compareToNode(aItem, aNod
           childNode.itemId == PlacesUtils.tagsFolderId ||
           aExcludedGuids.includes(childNode.bookmarkGuid)
         ) {
           continue;
         }
         expectedChildrenNodes.push(childNode);
       }
 
-      if (expectedChildrenNodes.length > 0) {
+      if (expectedChildrenNodes.length) {
         Assert.ok(Array.isArray(aItem.children));
         Assert.equal(aItem.children.length, expectedChildrenNodes.length);
         for (let i = 0; i < aItem.children.length; i++) {
           nodesCount += await compareToNode(
             aItem.children[i],
             expectedChildrenNodes[i],
             false,
             aExcludedGuids
@@ -182,17 +182,17 @@ function new_folder(aInfo) {
 // Walks a result nodes tree and test promiseBookmarksTree for each node.
 // DO NOT COPY THIS LOGIC:  It is done here to accomplish a more comprehensive
 // test of the API (the entire hierarchy data is available in the very test).
 async function test_promiseBookmarksTreeForEachNode(
   aNode,
   aOptions,
   aExcludedGuids
 ) {
-  Assert.ok(aNode.bookmarkGuid && aNode.bookmarkGuid.length > 0);
+  Assert.ok(aNode.bookmarkGuid && !!aNode.bookmarkGuid.length);
   let item = await PlacesUtils.promiseBookmarksTree(
     aNode.bookmarkGuid,
     aOptions
   );</