Get rid of some global variables - Part 7 * Replace the following global variables with named imports: - GrEventHelper - GrPluginRestApi - GrRepoApi * Update gr-app-global-var-init.js Change-Id: If1ac4eb7e6acd4191486012a37da0ff90a143e80
diff --git a/polygerrit-ui/app/.eslintrc.js b/polygerrit-ui/app/.eslintrc.js index 242e742..c047f96 100644 --- a/polygerrit-ui/app/.eslintrc.js +++ b/polygerrit-ui/app/.eslintrc.js
@@ -166,10 +166,7 @@ // Instead export variables from modules // TODO(dmfilippov): Remove global variables from polygerrit "Gerrit": "readonly", - "GrEventHelper": "readonly", "GrPluginActionContext": "readonly", - "GrPluginRestApi": "readonly", - "GrRepoApi": "readonly", "GrReporting": "readonly", "GrSettingsApi": "readonly", "GrStylesApi": "readonly",
diff --git a/polygerrit-ui/app/elements/gr-app-global-var-init.js b/polygerrit-ui/app/elements/gr-app-global-var-init.js index 219857f9..18ad0c0 100644 --- a/polygerrit-ui/app/elements/gr-app-global-var-init.js +++ b/polygerrit-ui/app/elements/gr-app-global-var-init.js
@@ -58,6 +58,9 @@ import {GrChangeMetadataApi} from './plugins/gr-change-metadata-api/gr-change-metadata-api.js'; import {GrEmailSuggestionsProvider} from '../scripts/gr-email-suggestions-provider/gr-email-suggestions-provider.js'; import {GrGroupSuggestionsProvider} from '../scripts/gr-group-suggestions-provider/gr-group-suggestions-provider.js'; +import {GrEventHelper} from './plugins/gr-event-helper/gr-event-helper.js'; +import {GrPluginRestApi} from './shared/gr-js-api-interface/gr-plugin-rest-api.js'; +import {GrRepoApi} from './plugins/gr-repo-api/gr-repo-api.js'; export function initGlobalVariables() { window.GrDisplayNameUtils = GrDisplayNameUtils; @@ -99,4 +102,7 @@ window.GrChangeMetadataApi = GrChangeMetadataApi; window.GrEmailSuggestionsProvider = GrEmailSuggestionsProvider; window.GrGroupSuggestionsProvider = GrGroupSuggestionsProvider; + window.GrEventHelper = GrEventHelper; + window.GrPluginRestApi = GrPluginRestApi; + window.GrRepoApi = GrRepoApi; }
diff --git a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.js b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.js index a48082e..63d40fc 100644 --- a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.js +++ b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.js
@@ -24,93 +24,88 @@ document.head.appendChild($_documentContainer.content); -(function(window) { - 'use strict'; +/** @constructor */ +export function GrEventHelper(element) { + this.element = element; + this._unsubscribers = []; +} - /** @constructor */ - function GrEventHelper(element) { - this.element = element; - this._unsubscribers = []; - } +/** + * Add a callback to arbitrary event. + * The callback may return false to prevent event bubbling. + * + * @param {string} event Event name + * @param {function(Event):boolean} callback + * @return {function()} Unsubscribe function. + */ +GrEventHelper.prototype.on = function(event, callback) { + return this._listen(this.element, callback, {event}); +}; - /** - * Add a callback to arbitrary event. - * The callback may return false to prevent event bubbling. - * - * @param {string} event Event name - * @param {function(Event):boolean} callback - * @return {function()} Unsubscribe function. - */ - GrEventHelper.prototype.on = function(event, callback) { - return this._listen(this.element, callback, {event}); - }; +/** + * Alias of onClick + * + * @see onClick + */ +GrEventHelper.prototype.onTap = function(callback) { + return this._listen(this.element, callback); +}; - /** - * Alias of onClick - * - * @see onClick - */ - GrEventHelper.prototype.onTap = function(callback) { - return this._listen(this.element, callback); - }; +/** + * Add a callback to element click or touch. + * The callback may return false to prevent event bubbling. + * + * @param {function(Event):boolean} callback + * @return {function()} Unsubscribe function. + */ +GrEventHelper.prototype.onClick = function(callback) { + return this._listen(this.element, callback); +}; - /** - * Add a callback to element click or touch. - * The callback may return false to prevent event bubbling. - * - * @param {function(Event):boolean} callback - * @return {function()} Unsubscribe function. - */ - GrEventHelper.prototype.onClick = function(callback) { - return this._listen(this.element, callback); - }; +/** + * Alias of captureClick + * + * @see captureClick + */ +GrEventHelper.prototype.captureTap = function(callback) { + return this._listen(this.element.parentElement, callback, {capture: true}); +}; - /** - * Alias of captureClick - * - * @see captureClick - */ - GrEventHelper.prototype.captureTap = function(callback) { - return this._listen(this.element.parentElement, callback, {capture: true}); - }; +/** + * Add a callback to element click or touch ahead of normal flow. + * Callback is installed on parent during capture phase. + * https://www.w3.org/TR/DOM-Level-3-Events/#event-flow + * The callback may return false to cancel regular event listeners. + * + * @param {function(Event):boolean} callback + * @return {function()} Unsubscribe function. + */ +GrEventHelper.prototype.captureClick = function(callback) { + return this._listen(this.element.parentElement, callback, {capture: true}); +}; - /** - * Add a callback to element click or touch ahead of normal flow. - * Callback is installed on parent during capture phase. - * https://www.w3.org/TR/DOM-Level-3-Events/#event-flow - * The callback may return false to cancel regular event listeners. - * - * @param {function(Event):boolean} callback - * @return {function()} Unsubscribe function. - */ - GrEventHelper.prototype.captureClick = function(callback) { - return this._listen(this.element.parentElement, callback, {capture: true}); - }; - - GrEventHelper.prototype._listen = function(container, callback, opt_options) { - const capture = opt_options && opt_options.capture; - const event = opt_options && opt_options.event || 'click'; - const handler = e => { - if (e.path.indexOf(this.element) !== -1) { - let mayContinue = true; - try { - mayContinue = callback(e); - } catch (e) { - console.warn(`Plugin error handing event: ${e}`); - } - if (mayContinue === false) { - e.stopImmediatePropagation(); - e.stopPropagation(); - e.preventDefault(); - } +GrEventHelper.prototype._listen = function(container, callback, opt_options) { + const capture = opt_options && opt_options.capture; + const event = opt_options && opt_options.event || 'click'; + const handler = e => { + if (e.path.indexOf(this.element) !== -1) { + let mayContinue = true; + try { + mayContinue = callback(e); + } catch (e) { + console.warn(`Plugin error handing event: ${e}`); } - }; - container.addEventListener(event, handler, capture); - const unsubscribe = () => - container.removeEventListener(event, handler, capture); - this._unsubscribers.push(unsubscribe); - return unsubscribe; + if (mayContinue === false) { + e.stopImmediatePropagation(); + e.stopPropagation(); + e.preventDefault(); + } + } }; + container.addEventListener(event, handler, capture); + const unsubscribe = () => + container.removeEventListener(event, handler, capture); + this._unsubscribers.push(unsubscribe); + return unsubscribe; +}; - window.GrEventHelper = GrEventHelper; -})(window);
diff --git a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html index c622d12..a27c817 100644 --- a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html +++ b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html
@@ -27,7 +27,6 @@ <dom-element id="some-element"> <script type="module"> import '../../../test/common-test-setup.js'; -import './gr-event-helper.js'; import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js'; Polymer({ is: 'some-element', @@ -51,8 +50,9 @@ <script type="module"> import '../../../test/common-test-setup.js'; -import './gr-event-helper.js'; import {addListener} from '@polymer/polymer/lib/utils/gestures.js'; +import {GrEventHelper} from './gr-event-helper.js'; + suite('gr-event-helper tests', () => { let element; let instance;
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.js b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.js index 6c1a3c8..36d822c 100644 --- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.js +++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.js
@@ -25,51 +25,42 @@ document.head.appendChild($_documentContainer.content); -(function(window) { - 'use strict'; +/** @constructor */ +export function GrRepoApi(plugin) { + this._hook = null; + this.plugin = plugin; +} - // Prevent redefinition. - if (window.GrRepoApi) { return; } +GrRepoApi.prototype._createHook = function(title) { + this._hook = this.plugin.hook('repo-command').onAttached(element => { + const pluginCommand = + document.createElement('gr-plugin-repo-command'); + pluginCommand.title = title; + element.appendChild(pluginCommand); + }); +}; - /** @constructor */ - function GrRepoApi(plugin) { - this._hook = null; - this.plugin = plugin; +GrRepoApi.prototype.createCommand = function(title, callback) { + if (this._hook) { + console.warn('Already set up.'); + return this._hook; } - - GrRepoApi.prototype._createHook = function(title) { - this._hook = this.plugin.hook('repo-command').onAttached(element => { - const pluginCommand = - document.createElement('gr-plugin-repo-command'); - pluginCommand.title = title; - element.appendChild(pluginCommand); - }); - }; - - GrRepoApi.prototype.createCommand = function(title, callback) { - if (this._hook) { - console.warn('Already set up.'); - return this._hook; + this._createHook(title); + this._hook.onAttached(element => { + if (callback(element.repoName, element.config) === false) { + element.hidden = true; } - this._createHook(title); - this._hook.onAttached(element => { - if (callback(element.repoName, element.config) === false) { - element.hidden = true; - } - }); - return this; - }; + }); + return this; +}; - GrRepoApi.prototype.onTap = function(callback) { - if (!this._hook) { - console.warn('Call createCommand first.'); - return this; - } - this._hook.onAttached(element => { - this.plugin.eventHelper(element).on('command-tap', callback); - }); +GrRepoApi.prototype.onTap = function(callback) { + if (!this._hook) { + console.warn('Call createCommand first.'); return this; - }; - - window.GrRepoApi = GrRepoApi; -})(window); + } + this._hook.onAttached(element => { + this.plugin.eventHelper(element).on('command-tap', callback); + }); + return this; +};
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html index 0eed6d9..d16d504 100644 --- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html +++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
@@ -34,7 +34,7 @@ <script type="module"> import '../../../test/common-test-setup.js'; import '../gr-endpoint-decorator/gr-endpoint-decorator.js'; -import './gr-repo-api.js'; + suite('gr-repo-api tests', () => { let sandbox; let repoApi;
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js index 4f4d615..d24077a 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
@@ -16,15 +16,12 @@ */ import '../../../scripts/bundled-polymer.js'; import '../../core/gr-reporting/gr-reporting.js'; -import '../../plugins/gr-event-helper/gr-event-helper.js'; -import '../../plugins/gr-repo-api/gr-repo-api.js'; import '../../plugins/gr-settings-api/gr-settings-api.js'; import '../../plugins/gr-styles-api/gr-styles-api.js'; import '../gr-rest-api-interface/gr-rest-api-interface.js'; import './gr-api-utils.js'; import './gr-js-api-interface-element.js'; import './gr-plugin-action-context.js'; -import './gr-plugin-rest-api.js'; import './gr-public-js-api.js'; import './gr-plugin-loader.js'; import './gr-gerrit.js';
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js index 7f4537b..d84cd83 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js
@@ -14,139 +14,134 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -(function(window) { - 'use strict'; - let restApi; +let restApi; - function getRestApi() { - if (!restApi) { - restApi = document.createElement('gr-rest-api-interface'); +function getRestApi() { + if (!restApi) { + restApi = document.createElement('gr-rest-api-interface'); + } + return restApi; +} + +export function GrPluginRestApi(opt_prefix) { + this.opt_prefix = opt_prefix || ''; +} + +GrPluginRestApi.prototype.getLoggedIn = function() { + return getRestApi().getLoggedIn(); +}; + +GrPluginRestApi.prototype.getVersion = function() { + return getRestApi().getVersion(); +}; + +GrPluginRestApi.prototype.getConfig = function() { + return getRestApi().getConfig(); +}; + +GrPluginRestApi.prototype.invalidateReposCache = function() { + getRestApi().invalidateReposCache(); +}; + +GrPluginRestApi.prototype.getAccount = function() { + return getRestApi().getAccount(); +}; + +GrPluginRestApi.prototype.getAccountCapabilities = function(capabilities) { + return getRestApi().getAccountCapabilities(capabilities); +}; + +GrPluginRestApi.prototype.getRepos = + function(filter, reposPerPage, opt_offset) { + return getRestApi().getRepos(filter, reposPerPage, opt_offset); + }; + +/** + * Fetch and return native browser REST API Response. + * + * @param {string} method HTTP Method (GET, POST, etc) + * @param {string} url URL without base path or plugin prefix + * @param {Object=} payload Respected for POST and PUT only. + * @param {?function(?Response, string=)=} opt_errFn + * passed as null sometimes. + * @return {!Promise} + */ +GrPluginRestApi.prototype.fetch = function(method, url, opt_payload, + opt_errFn, opt_contentType) { + return getRestApi().send(method, this.opt_prefix + url, opt_payload, + opt_errFn, opt_contentType); +}; + +/** + * Fetch and parse REST API response, if request succeeds. + * + * @param {string} method HTTP Method (GET, POST, etc) + * @param {string} url URL without base path or plugin prefix + * @param {Object=} payload Respected for POST and PUT only. + * @param {?function(?Response, string=)=} opt_errFn + * passed as null sometimes. + * @return {!Promise} resolves on success, rejects on error. + */ +GrPluginRestApi.prototype.send = function(method, url, opt_payload, + opt_errFn, opt_contentType) { + return this.fetch(method, url, opt_payload, opt_errFn, opt_contentType) + .then(response => { + if (response.status < 200 || response.status >= 300) { + return response.text().then(text => { + if (text) { + return Promise.reject(new Error(text)); + } else { + return Promise.reject(new Error(response.status)); + } + }); + } else { + return getRestApi().getResponseObject(response); + } + }); +}; + +/** + * @param {string} url URL without base path or plugin prefix + * @return {!Promise} resolves on success, rejects on error. + */ +GrPluginRestApi.prototype.get = function(url) { + return this.send('GET', url); +}; + +/** + * @param {string} url URL without base path or plugin prefix + * @return {!Promise} resolves on success, rejects on error. + */ +GrPluginRestApi.prototype.post = function(url, opt_payload, opt_errFn, + opt_contentType) { + return this.send('POST', url, opt_payload, opt_errFn, opt_contentType); +}; + +/** + * @param {string} url URL without base path or plugin prefix + * @return {!Promise} resolves on success, rejects on error. + */ +GrPluginRestApi.prototype.put = function(url, opt_payload, opt_errFn, + opt_contentType) { + return this.send('PUT', url, opt_payload, opt_errFn, opt_contentType); +}; + +/** + * @param {string} url URL without base path or plugin prefix + * @return {!Promise} resolves on 204, rejects on error. + */ +GrPluginRestApi.prototype.delete = function(url) { + return this.fetch('DELETE', url).then(response => { + if (response.status !== 204) { + return response.text().then(text => { + if (text) { + return Promise.reject(new Error(text)); + } else { + return Promise.reject(new Error(response.status)); + } + }); } - return restApi; - } - - function GrPluginRestApi(opt_prefix) { - this.opt_prefix = opt_prefix || ''; - } - - GrPluginRestApi.prototype.getLoggedIn = function() { - return getRestApi().getLoggedIn(); - }; - - GrPluginRestApi.prototype.getVersion = function() { - return getRestApi().getVersion(); - }; - - GrPluginRestApi.prototype.getConfig = function() { - return getRestApi().getConfig(); - }; - - GrPluginRestApi.prototype.invalidateReposCache = function() { - getRestApi().invalidateReposCache(); - }; - - GrPluginRestApi.prototype.getAccount = function() { - return getRestApi().getAccount(); - }; - - GrPluginRestApi.prototype.getAccountCapabilities = function(capabilities) { - return getRestApi().getAccountCapabilities(capabilities); - }; - - GrPluginRestApi.prototype.getRepos = - function(filter, reposPerPage, opt_offset) { - return getRestApi().getRepos(filter, reposPerPage, opt_offset); - }; - - /** - * Fetch and return native browser REST API Response. - * - * @param {string} method HTTP Method (GET, POST, etc) - * @param {string} url URL without base path or plugin prefix - * @param {Object=} payload Respected for POST and PUT only. - * @param {?function(?Response, string=)=} opt_errFn - * passed as null sometimes. - * @return {!Promise} - */ - GrPluginRestApi.prototype.fetch = function(method, url, opt_payload, - opt_errFn, opt_contentType) { - return getRestApi().send(method, this.opt_prefix + url, opt_payload, - opt_errFn, opt_contentType); - }; - - /** - * Fetch and parse REST API response, if request succeeds. - * - * @param {string} method HTTP Method (GET, POST, etc) - * @param {string} url URL without base path or plugin prefix - * @param {Object=} payload Respected for POST and PUT only. - * @param {?function(?Response, string=)=} opt_errFn - * passed as null sometimes. - * @return {!Promise} resolves on success, rejects on error. - */ - GrPluginRestApi.prototype.send = function(method, url, opt_payload, - opt_errFn, opt_contentType) { - return this.fetch(method, url, opt_payload, opt_errFn, opt_contentType) - .then(response => { - if (response.status < 200 || response.status >= 300) { - return response.text().then(text => { - if (text) { - return Promise.reject(new Error(text)); - } else { - return Promise.reject(new Error(response.status)); - } - }); - } else { - return getRestApi().getResponseObject(response); - } - }); - }; - - /** - * @param {string} url URL without base path or plugin prefix - * @return {!Promise} resolves on success, rejects on error. - */ - GrPluginRestApi.prototype.get = function(url) { - return this.send('GET', url); - }; - - /** - * @param {string} url URL without base path or plugin prefix - * @return {!Promise} resolves on success, rejects on error. - */ - GrPluginRestApi.prototype.post = function(url, opt_payload, opt_errFn, - opt_contentType) { - return this.send('POST', url, opt_payload, opt_errFn, opt_contentType); - }; - - /** - * @param {string} url URL without base path or plugin prefix - * @return {!Promise} resolves on success, rejects on error. - */ - GrPluginRestApi.prototype.put = function(url, opt_payload, opt_errFn, - opt_contentType) { - return this.send('PUT', url, opt_payload, opt_errFn, opt_contentType); - }; - - /** - * @param {string} url URL without base path or plugin prefix - * @return {!Promise} resolves on 204, rejects on error. - */ - GrPluginRestApi.prototype.delete = function(url) { - return this.fetch('DELETE', url).then(response => { - if (response.status !== 204) { - return response.text().then(text => { - if (text) { - return Promise.reject(new Error(text)); - } else { - return Promise.reject(new Error(response.status)); - } - }); - } - return response; - }); - }; - - window.GrPluginRestApi = GrPluginRestApi; -})(window); + return response; + }); +};
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html index 8963821..45f83ee 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html
@@ -26,6 +26,8 @@ <script type="module"> import '../../../test/common-test-setup.js'; import './gr-js-api-interface.js'; +import {GrPluginRestApi} from './gr-plugin-rest-api.js'; + suite('gr-plugin-rest-api tests', () => { let instance; let sandbox;
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js index 99b6d04..6c980f5 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
@@ -25,6 +25,9 @@ import {GrAdminApi} from '../../plugins/gr-admin-api/gr-admin-api.js'; import {GrAnnotationActionsInterface} from './gr-annotation-actions-js-api.js'; import {GrChangeMetadataApi} from '../../plugins/gr-change-metadata-api/gr-change-metadata-api.js'; +import {GrEventHelper} from '../../plugins/gr-event-helper/gr-event-helper.js'; +import {GrPluginRestApi} from './gr-plugin-rest-api.js'; +import {GrRepoApi} from '../../plugins/gr-repo-api/gr-repo-api.js'; (function(window) { 'use strict';