/
githubmirror
/
brackets
Обзор
Документация
Войти
/
githubmirror
/
brackets
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/extensions/default/InAppNotifications/main.js
335 строк
13 KB
Shubham Yadav
Remove console logs
21 май 2019, 11:41
21 май 2019, 11:41
a4784f5
Код
Авторство
О чём код?
/* * Copyright (c) 2019 - present Adobe. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ /** * module for displaying in-app notifications * */ define(function (require, exports, module) { "use strict"; var AppInit = brackets.getModule("utils/AppInit"), PreferencesManager = brackets.getModule("preferences/PreferencesManager"), ExtensionUtils = brackets.getModule("utils/ExtensionUtils"), ExtensionManager = brackets.getModule("extensibility/ExtensionManager"), HealthLogger = brackets.getModule("utils/HealthLogger"), NotificationBarHtml = require("text!htmlContent/notificationContainer.html"); ExtensionUtils.loadStyleSheet(module, "styles/styles.css"); // duration of one day in milliseconds var ONE_DAY = 1000 * 60 * 60 * 24; // Init default last notification number PreferencesManager.stateManager.definePreference("lastHandledNotificationNumber", "number", 0); // Init default last info URL fetch time PreferencesManager.stateManager.definePreference("lastNotificationURLFetchTime", "number", 0); /** * Constructs notification info URL for XHR * * @param {string=} localeParam - optional locale, defaults to 'brackets.getLocale()' when omitted. * @returns {string} the new notification info url */ function _getVersionInfoUrl(localeParam) { var locale = localeParam || brackets.getLocale(); if (locale.length > 2) { locale = locale.substring(0, 2); } return brackets.config.notification_info_url.replace("<locale>", locale); } /** * Get a data structure that has information for all Brackets targeted notifications. * * _notificationInfoUrl is used for unit testing. */ function _getNotificationInformation(_notificationInfoUrl) { // Last time the versionInfoURL was fetched var lastInfoURLFetchTime = PreferencesManager.getViewState("lastNotificationURLFetchTime"); var result = new $.Deferred(); var fetchData = false; var data; // If we don't have data saved in prefs, fetch data = PreferencesManager.getViewState("notificationInfo"); if (!data) { fetchData = true; } // If more than 24 hours have passed since our last fetch, fetch again if (Date.now() > lastInfoURLFetchTime + ONE_DAY) { fetchData = true; } if (fetchData) { var lookupPromise = new $.Deferred(), localNotificationInfoUrl; // If the current locale isn't "en" or "en-US", check whether we actually have a // locale-specific notification target, and fall back to "en" if not. var locale = brackets.getLocale().toLowerCase(); if (locale !== "en" && locale !== "en-us") { localNotificationInfoUrl = _notificationInfoUrl || _getVersionInfoUrl(); // Check if we can reach a locale specific notifications source $.ajax({ url: localNotificationInfoUrl, cache: false, type: "HEAD" }).fail(function (jqXHR, status, error) { // Fallback to "en" locale localNotificationInfoUrl = _getVersionInfoUrl("en"); }).always(function (jqXHR, status, error) { lookupPromise.resolve(); }); } else { localNotificationInfoUrl = _notificationInfoUrl || _getVersionInfoUrl("en"); lookupPromise.resolve(); } lookupPromise.done(function () { $.ajax({ url: localNotificationInfoUrl, dataType: "json", cache: false }).done(function (notificationInfo, textStatus, jqXHR) { lastInfoURLFetchTime = (new Date()).getTime(); PreferencesManager.setViewState("lastNotificationURLFetchTime", lastInfoURLFetchTime); PreferencesManager.setViewState("notificationInfo", notificationInfo); result.resolve(notificationInfo); }).fail(function (jqXHR, status, error) { // When loading data for unit tests, the error handler is // called but the responseText is valid. Try to use it here, // but *don't* save the results in prefs. if (!jqXHR.responseText) { // Text is NULL or empty string, reject(). result.reject(); return; } try { data = JSON.parse(jqXHR.responseText); result.resolve(data); } catch (e) { result.reject(); } }); }); } else { result.resolve(data); } return result.promise(); } /** * Check for notifications, notification overlays are always displayed * * @return {$.Promise} jQuery Promise object that is resolved or rejected after the notification check is complete. */ function checkForNotification(versionInfoUrl) { var result = new $.Deferred(); _getNotificationInformation(versionInfoUrl) .done(function (notificationInfo) { // Get all available notifications var notifications = notificationInfo.notifications; if (notifications && notifications.length > 0) { // Iterate through notifications and act only on the most recent // applicable notification notifications.every(function(notificationObj) { // Only show the notification overlay if the user hasn't been // alerted of this notification if (_checkNotificationValidity(notificationObj)) { if (notificationObj.silent) { // silent notifications, to gather user validity based on filters HealthLogger.sendAnalyticsData("notification", notificationObj.sequence, "handled"); } else { showNotification(notificationObj); } // Break, we have acted on one notification already return false; } // Continue, we haven't yet got a notification to act on return true; }); } result.resolve(); }) .fail(function () { // Error fetching the update data. If this is a forced check, alert the user result.reject(); }); return result.promise(); } function _checkPlatform(filters, _platform) { return !filters.platforms || filters.platforms.length === 0 || filters.platforms.indexOf(_platform) >=0; } function _checkBuild(filters, _build) { return !filters.builds || filters.builds.length === 0 || filters.builds.indexOf(_build) >=0; } function _checkVersion(filters, _version) { var re = new RegExp(filters.version); return re.exec(_version); } function _checkLocale(filters, _locale) { return !filters.locales || filters.locales.length === 0 || filters.locales.indexOf(_locale) >=0; } function _checkExpiry(expiry) { return Date.now() <= expiry; } function _checkExtensions(filters) { //if no property called extensions then it's a universal notification if (filters.extensions === undefined) { return true; } var allExtensions = ExtensionManager.extensions, allExtnsMatched = true, userExtensionKeys = Object.keys(allExtensions).filter(function(k) { return allExtensions[k].installInfo.locationType === 'user'; }); if (!filters.extensions) { //if property called extensions exists but has a falsy value //then number of user extensions must be zero allExtnsMatched = userExtensionKeys.length === 0; } else if (filters.extensions.length === 0) { //if property called extensions exists but is an empty array //then number of user extensions must greater than zero allExtnsMatched = userExtensionKeys.length > 0; } else { //if property called extensions exists but is a non empty array //then notification is targetted to users having the fitered extensions var filteredExtns = filters.extensions, extnIterator = null; for (var i=0; i < filteredExtns.length; i++) { extnIterator = filteredExtns[i]; if (userExtensionKeys.indexOf(extnIterator) === -1) { allExtnsMatched = false; break; } } } return allExtnsMatched; } function _checkNotificationValidity(notificationObj) { var filters = notificationObj.filters, _platform = brackets.getPlatformInfo(), _locale = brackets.getLocale(), _lastHandledNotificationNumber = PreferencesManager.getViewState("lastHandledNotificationNumber"), // Extract current build number from package.json version field 0.0.0-0 _buildNumber = Number(/-([0-9]+)/.exec(brackets.metadata.version)[1]), _version = brackets.metadata.apiVersion; if(_locale.length > 2) { _locale = _locale.substring(0, 2); } return notificationObj.sequence > _lastHandledNotificationNumber && _checkExpiry(notificationObj.expiry) && _checkPlatform(filters, _platform) && _checkLocale(filters, _locale) && _checkVersion(filters, _version) && _checkBuild(filters, _buildNumber) && _checkExtensions(filters); } /** * Removes and cleans up the notification bar from DOM */ function cleanNotificationBar() { var $notificationBar = $('#notification-bar'); if ($notificationBar.length > 0) { $notificationBar.remove(); } } /** * Displays the Notification Bar UI * @param {object} msgObj - json object containing message info to be displayed * */ function showNotification(msgObj) { var $htmlContent = $(msgObj.html), $notificationBarElement = $(NotificationBarHtml); // Remove any SCRIPT tag to avoid secuirity issues $htmlContent.find('script').remove(); // Remove any STYLE tag to avoid styling impact on Brackets DOM $htmlContent.find('style').remove(); cleanNotificationBar(); //Remove an already existing notification bar, if any $notificationBarElement.prependTo(".content"); var $notificationBar = $('#notification-bar'), $notificationContent = $notificationBar.find('.content-container'), $closeIcon = $notificationBar.find('.close-icon'); $notificationContent.append($htmlContent); HealthLogger.sendAnalyticsData("notification", msgObj.sequence, "shown"); // Click handlers on actionable elements if ($closeIcon.length > 0) { $closeIcon.click(function () { cleanNotificationBar(); PreferencesManager.setViewState("lastHandledNotificationNumber", msgObj.sequence); HealthLogger.sendAnalyticsData("notification", msgObj.sequence, "dismissedByClose"); }); } if (msgObj.actionables) { $(msgObj.actionables).click(function () { cleanNotificationBar(); PreferencesManager.setViewState("lastHandledNotificationNumber", msgObj.sequence); HealthLogger.sendAnalyticsData("notification", msgObj.sequence, "dismissedBy" + this.id); }); } } AppInit.appReady(function () { checkForNotification(); }); // For unit tests only exports.checkForNotification = checkForNotification; });