279 lines
9.1 KiB
TypeScript
279 lines
9.1 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* This defines the Gerrit instance. All methods directly attached to Gerrit
|
|
* should be defined or linked here.
|
|
*/
|
|
import {
|
|
getPluginLoader,
|
|
PluginOptionMap,
|
|
PluginLoader,
|
|
} from './gr-plugin-loader';
|
|
import {getRestAPI, send} from './gr-api-utils';
|
|
import {appContext} from '../../../services/app-context';
|
|
import {PluginApi} from '../../plugins/gr-plugin-types';
|
|
import {HttpMethod} from '../../../constants/constants';
|
|
import {RequestPayload} from '../../../types/common';
|
|
import {
|
|
EventCallback,
|
|
EventEmitterService,
|
|
} from '../../../services/gr-event-interface/gr-event-interface';
|
|
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
|
|
import {getRootElement} from '../../../scripts/rootElement';
|
|
import {GrPluginEndpoints} from './gr-plugin-endpoints';
|
|
import {rangesEqual} from '../../diff/gr-diff/gr-diff-utils';
|
|
import {SUGGESTIONS_PROVIDERS_USERS_TYPES} from '../../../scripts/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider';
|
|
import {CoverageType} from '../../../types/types';
|
|
import {RevisionInfo} from '../revision-info/revision-info';
|
|
|
|
export interface GerritGlobal extends EventEmitterService {
|
|
flushPreinstalls?(): void;
|
|
css(rule: string): string;
|
|
install(
|
|
callback: (plugin: PluginApi) => void,
|
|
opt_version?: string,
|
|
src?: string
|
|
): void;
|
|
getLoggedIn(): Promise<boolean>;
|
|
get(url: string, callback?: (response: unknown) => void): void;
|
|
post(
|
|
url: string,
|
|
payload?: RequestPayload,
|
|
callback?: (response: unknown) => void
|
|
): void;
|
|
put(
|
|
url: string,
|
|
payload?: RequestPayload,
|
|
callback?: (response: unknown) => void
|
|
): void;
|
|
delete(url: string, callback?: (response: unknown) => void): void;
|
|
isPluginLoaded(pathOrUrl: string): boolean;
|
|
awaitPluginsLoaded(): Promise<unknown>;
|
|
_loadPlugins(plugins: string[], opts: PluginOptionMap): void;
|
|
_arePluginsLoaded(): boolean;
|
|
_isPluginPreloaded(pathOrUrl: string): boolean;
|
|
_isPluginEnabled(pathOrUrl: string): boolean;
|
|
_isPluginLoaded(pathOrUrl: string): boolean;
|
|
_eventEmitter: EventEmitterService;
|
|
_customStyleSheet: CSSStyleSheet;
|
|
|
|
// exposed methods
|
|
Nav: typeof GerritNav;
|
|
Auth: typeof appContext.authService;
|
|
getRootElement: typeof getRootElement;
|
|
_pluginLoader: PluginLoader;
|
|
_endpoints: GrPluginEndpoints;
|
|
slotToContent(slot: unknown): unknown;
|
|
rangesEqual: typeof rangesEqual;
|
|
SUGGESTIONS_PROVIDERS_USERS_TYPES: typeof SUGGESTIONS_PROVIDERS_USERS_TYPES;
|
|
CoverageType: typeof CoverageType;
|
|
RevisionInfo: typeof RevisionInfo;
|
|
}
|
|
|
|
/**
|
|
* Trigger the preinstalls for bundled plugins.
|
|
* This needs to happen before Gerrit as plugin bundle overrides the Gerrit.
|
|
*/
|
|
function flushPreinstalls() {
|
|
const Gerrit = window.Gerrit;
|
|
if (Gerrit?.flushPreinstalls) {
|
|
Gerrit.flushPreinstalls();
|
|
}
|
|
}
|
|
export const _testOnly_flushPreinstalls = flushPreinstalls;
|
|
|
|
export function initGerritPluginApi() {
|
|
window.Gerrit = window.Gerrit || {};
|
|
flushPreinstalls();
|
|
initGerritPluginsMethods(window.Gerrit as GerritGlobal);
|
|
// Preloaded plugins should be installed after Gerrit.install() is set,
|
|
// since plugin preloader substitutes Gerrit.install() temporarily.
|
|
// (Gerrit.install() is set in initGerritPluginsMethods)
|
|
getPluginLoader().installPreloadedPlugins();
|
|
}
|
|
|
|
export function _testOnly_initGerritPluginApi(): GerritGlobal {
|
|
window.Gerrit = window.Gerrit || {};
|
|
initGerritPluginApi();
|
|
return window.Gerrit as GerritGlobal;
|
|
}
|
|
|
|
export function deprecatedDelete(
|
|
url: string,
|
|
callback?: (response: Response) => void
|
|
) {
|
|
console.warn('.delete() is deprecated! Use plugin.restApi().delete()');
|
|
return getRestAPI()
|
|
.send(HttpMethod.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}`));
|
|
}
|
|
});
|
|
}
|
|
if (callback) callback(response);
|
|
return response;
|
|
});
|
|
}
|
|
|
|
function initGerritPluginsMethods(globalGerritObj: GerritGlobal) {
|
|
/**
|
|
* @deprecated Use plugin.styles().css(rulesStr) instead. Please, consult
|
|
* the documentation how to replace it accordingly.
|
|
*/
|
|
globalGerritObj.css = (rulesStr: string) => {
|
|
console.warn(
|
|
'Gerrit.css(rulesStr) is deprecated!',
|
|
'Use plugin.styles().css(rulesStr)'
|
|
);
|
|
if (!globalGerritObj._customStyleSheet) {
|
|
const styleEl = document.createElement('style');
|
|
document.head.appendChild(styleEl);
|
|
globalGerritObj._customStyleSheet = styleEl.sheet!;
|
|
}
|
|
|
|
const name = `__pg_js_api_class_${globalGerritObj._customStyleSheet.cssRules.length}`;
|
|
globalGerritObj._customStyleSheet.insertRule(
|
|
'.' + name + '{' + rulesStr + '}',
|
|
0
|
|
);
|
|
return name;
|
|
};
|
|
|
|
globalGerritObj.install = (callback, opt_version, opt_src) => {
|
|
getPluginLoader().install(callback, opt_version, opt_src);
|
|
};
|
|
|
|
globalGerritObj.getLoggedIn = () => {
|
|
console.warn(
|
|
'Gerrit.getLoggedIn() is deprecated! ' +
|
|
'Use plugin.restApi().getLoggedIn()'
|
|
);
|
|
return document.createElement('gr-rest-api-interface').getLoggedIn();
|
|
};
|
|
|
|
globalGerritObj.get = (
|
|
url: string,
|
|
callback?: (response: unknown) => void
|
|
) => {
|
|
console.warn('.get() is deprecated! Use plugin.restApi().get()');
|
|
send(HttpMethod.GET, url, callback);
|
|
};
|
|
|
|
globalGerritObj.post = (
|
|
url: string,
|
|
payload?: RequestPayload,
|
|
callback?: (response: unknown) => void
|
|
) => {
|
|
console.warn('.post() is deprecated! Use plugin.restApi().post()');
|
|
send(HttpMethod.POST, url, callback, payload);
|
|
};
|
|
|
|
globalGerritObj.put = (
|
|
url: string,
|
|
payload?: RequestPayload,
|
|
callback?: (response: unknown) => void
|
|
) => {
|
|
console.warn('.put() is deprecated! Use plugin.restApi().put()');
|
|
send(HttpMethod.PUT, url, callback, payload);
|
|
};
|
|
|
|
globalGerritObj.delete = (
|
|
url: string,
|
|
callback?: (response: Response) => void
|
|
) => {
|
|
deprecatedDelete(url, callback);
|
|
};
|
|
|
|
globalGerritObj.awaitPluginsLoaded = () => {
|
|
return getPluginLoader().awaitPluginsLoaded();
|
|
};
|
|
|
|
// TODO(taoalpha): consider removing these proxy methods
|
|
// and using getPluginLoader() directly
|
|
globalGerritObj._loadPlugins = (plugins, opt_option) => {
|
|
getPluginLoader().loadPlugins(plugins, opt_option);
|
|
};
|
|
|
|
globalGerritObj._arePluginsLoaded = () => {
|
|
return getPluginLoader().arePluginsLoaded();
|
|
};
|
|
|
|
globalGerritObj._isPluginPreloaded = url => {
|
|
return getPluginLoader().isPluginPreloaded(url);
|
|
};
|
|
|
|
globalGerritObj._isPluginEnabled = pathOrUrl => {
|
|
return getPluginLoader().isPluginEnabled(pathOrUrl);
|
|
};
|
|
|
|
globalGerritObj._isPluginLoaded = pathOrUrl => {
|
|
return getPluginLoader().isPluginLoaded(pathOrUrl);
|
|
};
|
|
|
|
const eventEmitter = appContext.eventEmitter;
|
|
|
|
// TODO(taoalpha): List all internal supported event names.
|
|
// Also convert this to inherited class once we move Gerrit to class.
|
|
globalGerritObj._eventEmitter = eventEmitter;
|
|
/**
|
|
* Enabling EventEmitter interface on Gerrit.
|
|
*
|
|
* This will enable to signal across different parts of js code without relying on DOM,
|
|
* including core to core, plugin to plugin and also core to plugin.
|
|
*
|
|
* @example
|
|
*
|
|
* // Emit this event from pluginA
|
|
* Gerrit.install(pluginA => {
|
|
* fetch("some-api").then(() => {
|
|
* Gerrit.on("your-special-event", {plugin: pluginA});
|
|
* });
|
|
* });
|
|
*
|
|
* // Listen on your-special-event from pluignB
|
|
* Gerrit.install(pluginB => {
|
|
* Gerrit.on("your-special-event", ({plugin}) => {
|
|
* // do something, plugin is pluginA
|
|
* });
|
|
* });
|
|
*/
|
|
globalGerritObj.addListener = (eventName: string, cb: EventCallback) =>
|
|
eventEmitter.addListener(eventName, cb);
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
globalGerritObj.dispatch = (eventName: string, detail: any) =>
|
|
eventEmitter.dispatch(eventName, detail);
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
globalGerritObj.emit = (eventName: string, detail: any) =>
|
|
eventEmitter.emit(eventName, detail);
|
|
globalGerritObj.off = (eventName: string, cb: EventCallback) =>
|
|
eventEmitter.off(eventName, cb);
|
|
globalGerritObj.on = (eventName: string, cb: EventCallback) =>
|
|
eventEmitter.on(eventName, cb);
|
|
globalGerritObj.once = (eventName: string, cb: EventCallback) =>
|
|
eventEmitter.once(eventName, cb);
|
|
globalGerritObj.removeAllListeners = (eventName: string) =>
|
|
eventEmitter.removeAllListeners(eventName);
|
|
globalGerritObj.removeListener = (eventName: string, cb: EventCallback) =>
|
|
eventEmitter.removeListener(eventName, cb);
|
|
}
|