For unauthenticated requests, the rate limit of GitHub allows for up to 60 requests per hour.
For API requests using Authentication, you can make up to 5,000 requests per hour.
-
@@ -393,6 +426,10 @@ button.secondary:hover {
vscode.postMessage({ type: 'welcome-page' });
});
+ delegate(document.body, '#authorizing-button', 'click', () => {
+ vscode.postMessage({ type: 'authorizing-github' })
+ });
+
const updatePage = () => {
const { token, pageType, valid, validating } = vscode.getState() || { token: '', preview: 'EDIT', valid: true, validating: true };
if (validating) {
diff --git a/extensions/jupyter-web/yarn.lock b/extensions/jupyter-web/yarn.lock
index 9e9cffea8..5dcc9f27c 100644
--- a/extensions/jupyter-web/yarn.lock
+++ b/extensions/jupyter-web/yarn.lock
@@ -969,9 +969,9 @@ locate-path@^5.0.0:
p-locate "^4.1.0"
lodash@^4.17.4, lodash@^4.3.0:
- version "4.17.20"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
- integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lru-cache@^4.0.1:
version "4.1.5"
diff --git a/package.json b/package.json
index 571200832..87c9ccebf 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"lib": "lib"
},
"devDependencies": {
- "@github1s/vscode-web": "0.1.2",
+ "@github1s/vscode-web": "0.1.8",
"@typescript-eslint/eslint-plugin": "^4.15.0",
"@typescript-eslint/parser": "^4.15.0",
"chokidar": "^3.5.1",
diff --git a/resources/favicon-dark.ico b/resources/favicon-dark.ico
deleted file mode 100644
index 12f05d0c2..000000000
Binary files a/resources/favicon-dark.ico and /dev/null differ
diff --git a/resources/favicon-dark.svg b/resources/favicon-dark.svg
new file mode 100644
index 000000000..439c80809
--- /dev/null
+++ b/resources/favicon-dark.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/favicon-light.ico b/resources/favicon-light.ico
deleted file mode 100644
index f64685874..000000000
Binary files a/resources/favicon-light.ico and /dev/null differ
diff --git a/resources/favicon-light.svg b/resources/favicon-light.svg
new file mode 100644
index 000000000..08bd50e08
--- /dev/null
+++ b/resources/favicon-light.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/favicon.ico b/resources/favicon.ico
new file mode 100644
index 000000000..9b88bce89
Binary files /dev/null and b/resources/favicon.ico differ
diff --git a/resources/index-dev-vscode.html b/resources/index-dev-vscode.html
index 2239de4a6..7ad7e99ba 100644
--- a/resources/index-dev-vscode.html
+++ b/resources/index-dev-vscode.html
@@ -12,8 +12,8 @@
-
-
+
+
GitHub1s
diff --git a/resources/index-hash.html b/resources/index-hash.html
index a0bfa01d0..8bbeb9ebb 100644
--- a/resources/index-hash.html
+++ b/resources/index-hash.html
@@ -12,8 +12,8 @@
-
-
+
+
diff --git a/resources/index.html b/resources/index.html
index d608acffd..253867c73 100644
--- a/resources/index.html
+++ b/resources/index.html
@@ -12,8 +12,8 @@
-
-
+
+
diff --git a/scripts/package/copy-resources.sh b/scripts/package/copy-resources.sh
index 15c5c2ecd..7d78bcf4f 100755
--- a/scripts/package/copy-resources.sh
+++ b/scripts/package/copy-resources.sh
@@ -13,7 +13,7 @@ function main() {
else
cp resources/index.html dist/index.html
fi
- cp resources/*.ico dist
+ cp resources/favicon* dist
cp resources/manifest.json dist
echo "copy resources done!"
diff --git a/tests/__tests__/index.test.ts b/tests/__tests__/index.test.ts
index 3a4289cf9..373dbb0ac 100644
--- a/tests/__tests__/index.test.ts
+++ b/tests/__tests__/index.test.ts
@@ -43,7 +43,7 @@ it('should load successfully', async () => {
// Make sure the repo loads
await page.click('div[role="tab"]');
// GitHub repo Link available
- await page.$eval('a[title="Home"][aria-label="Home"]', (el) => el.innerHTML);
+ await page.$eval('div.home-bar[role="toolbar"]', (el) => el.innerHTML);
// File explorer available
await page.$eval(
'div[role="tree"][aria-label="Files Explorer"]',
diff --git a/tests/yarn.lock b/tests/yarn.lock
index ebd3a1fa6..f4f3c1c6e 100644
--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -1971,9 +1971,9 @@ homedir-polyfill@^1.0.0:
parse-passwd "^1.0.0"
hosted-git-info@^2.1.4:
- version "2.8.8"
- resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
- integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
+ version "2.8.9"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
+ integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
html-encoding-sniffer@^2.0.1:
version "2.0.1"
diff --git a/vercel.json b/vercel.json
index a04641195..6a1e04a10 100644
--- a/vercel.json
+++ b/vercel.json
@@ -1,27 +1,49 @@
{
- "routes": [
+ "rewrites": [
{
- "src": "/api/sourcegraph",
- "dest": "https://sourcegraph.com/.api/graphql"
+ "source": "/api/sourcegraph",
+ "destination": "https://sourcegraph.com/.api/graphql"
},
{
- "src": "/static/(.*)",
- "dest": "/static/$1",
- "headers": {
- "Cache-Control": "max-age=604800"
- }
+ "source": "/api/github-auth-callback",
+ "destination": "/api/github-auth-callback"
},
{
- "src": "/favicon(-dark|-light)?.ico",
- "dest": "/favicon$1.ico"
+ "source": "/static/(.*)",
+ "destination": "/api/static-fallback"
},
{
- "src": "/manifest.json",
- "dest": "/manifest.json"
+ "source": "/(.*)",
+ "destination": "/index.html"
+ }
+ ],
+ "headers": [
+ {
+ "source": "/static/(.*)",
+ "headers": [
+ {
+ "key": "Cache-Control",
+ "value": "public, max-age=2592000, immutable"
+ }
+ ]
+ },
+ {
+ "source": "/favicon(-dark|-light)?\\.(ico|svg)",
+ "headers": [
+ {
+ "key": "Cache-Control",
+ "value": "public, max-age=3600"
+ }
+ ]
},
{
- "src": ".*",
- "dest": "/index.html"
+ "source": "/manifest.json",
+ "headers": [
+ {
+ "key": "Cache-Control",
+ "value": "public, max-age=3600"
+ }
+ ]
}
]
-}
\ No newline at end of file
+}
diff --git a/vscode-web-github1s/package.json b/vscode-web-github1s/package.json
index 6359738c4..4a3b604b9 100644
--- a/vscode-web-github1s/package.json
+++ b/vscode-web-github1s/package.json
@@ -1,6 +1,6 @@
{
"name": "@github1s/vscode-web",
- "version": "0.1.2",
+ "version": "0.1.8",
"description": "VS Code web for GitHub1s",
"author": "github1s",
"license": "MIT",
@@ -38,6 +38,7 @@
"xterm-addon-webgl": "0.10.0-beta.1"
},
"devDependencies": {
+ "@types/trusted-types": "^2.0.0",
"npm-run-all": "^4.1.5"
}
}
diff --git a/vscode-web-github1s/src/vs/base/worker/workerMain.ts b/vscode-web-github1s/src/vs/base/worker/workerMain.ts
new file mode 100644
index 000000000..5765195d4
--- /dev/null
+++ b/vscode-web-github1s/src/vs/base/worker/workerMain.ts
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+(function () {
+
+ const MonacoEnvironment = (
self).MonacoEnvironment;
+ const monacoBaseUrl = MonacoEnvironment && MonacoEnvironment.baseUrl ? MonacoEnvironment.baseUrl : '../../../';
+
+ const trustedTypesPolicy = (
+ typeof self.trustedTypes?.createPolicy === 'function'
+ ? self.trustedTypes?.createPolicy('amdLoader', {
+ createScriptURL: value => value,
+ createScript: (_, ...args: string[]) => {
+ // workaround a chrome issue not allowing to create new functions
+ // see https://github.com/w3c/webappsec-trusted-types/wiki/Trusted-Types-for-function-constructor
+ const fnArgs = args.slice(0, -1).join(',');
+ const fnBody = args.pop()!.toString();
+ const body = `(function anonymous(${fnArgs}) {\n${fnBody}\n})`;
+ return body;
+ }
+ })
+ : undefined
+ );
+
+ function loadAMDLoader() {
+ return new Promise((resolve, reject) => {
+ if (typeof (self).define === 'function' && (self).define.amd) {
+ return resolve();
+ }
+ const loaderSrc: string | TrustedScriptURL = monacoBaseUrl + 'vs/loader.js';
+
+ const isCrossOrigin = (/^((http:)|(https:)|(file:))/.test(loaderSrc) && loaderSrc.substring(0, self.origin.length) !== self.origin);
+ if (!isCrossOrigin) {
+ // use `fetch` if possible because `importScripts`
+ // is synchronous and can lead to deadlocks on Safari
+ fetch(loaderSrc).then((response) => {
+ if (response.status !== 200) {
+ throw new Error(response.statusText);
+ }
+ return response.text();
+ }).then((text) => {
+ text = `${text}\n//# sourceURL=${loaderSrc}`;
+ const func = (
+ trustedTypesPolicy
+ // below codes are changed by github1s
+ // fix error in webworker for old browsers
+ ? self.eval(trustedTypesPolicy.createScript('', text).toString())
+ // above codes are changed by github1s
+ : new Function(text)
+ );
+ func.call(self);
+ resolve();
+ }).then(undefined, reject);
+ return;
+ }
+
+ if (trustedTypesPolicy) {
+ importScripts(trustedTypesPolicy.createScriptURL(loaderSrc) as unknown as string);
+ } else {
+ importScripts(loaderSrc as string);
+ }
+ resolve();
+ });
+ }
+
+ const loadCode = function (moduleId: string) {
+ loadAMDLoader().then(() => {
+ require.config({
+ baseUrl: monacoBaseUrl,
+ catchError: true,
+ trustedTypesPolicy,
+ });
+ require([moduleId], function (ws) {
+ setTimeout(function () {
+ let messageHandler = ws.create((msg: any, transfer?: Transferable[]) => {
+ (self).postMessage(msg, transfer);
+ }, null);
+
+ self.onmessage = (e: MessageEvent) => messageHandler.onmessage(e.data);
+ while (beforeReadyMessages.length > 0) {
+ self.onmessage(beforeReadyMessages.shift()!);
+ }
+ }, 0);
+ });
+ });
+ };
+
+ let isFirstMessage = true;
+ let beforeReadyMessages: MessageEvent[] = [];
+ self.onmessage = (message: MessageEvent) => {
+ if (!isFirstMessage) {
+ beforeReadyMessages.push(message);
+ return;
+ }
+
+ isFirstMessage = false;
+ loadCode(message.data);
+ };
+})();
diff --git a/vscode-web-github1s/src/vs/code/browser/workbench/workbench.ts b/vscode-web-github1s/src/vs/code/browser/workbench/workbench.ts
index 5eb930f22..7cd7ff01f 100644
--- a/vscode-web-github1s/src/vs/code/browser/workbench/workbench.ts
+++ b/vscode-web-github1s/src/vs/code/browser/workbench/workbench.ts
@@ -23,6 +23,10 @@ import { parseLogLevel } from 'vs/platform/log/common/log';
import { getBrowserUrl, replaceBrowserUrl } from 'vs/github1s/util';
// eslint-disable-next-line
import { renderNotification } from 'vs/github1s/notification';
+// eslint-disable-next-line
+import { getGitHubAccessToken } from 'vs/github1s/authorizing-github';
+// eslint-disable-next-line
+import { getGitHubAccessTokenWithOverlay, hideAuthorizingOverlay } from 'vs/github1s/authorizing-overlay';
// custom vs code commands defined by github1s
const getGitHub1sCustomCommands: () => {
@@ -31,6 +35,9 @@ const getGitHub1sCustomCommands: () => {
}[] = () => [
{ id: 'github1s.vscode.get-browser-url', handler: getBrowserUrl },
{ id: 'github1s.vscode.replace-browser-url', handler: replaceBrowserUrl },
+ { id: 'github1s.vscode.get-github-access-token', handler: getGitHubAccessToken },
+ { id: 'github1s.vscode.get-github-access-token-with-overlay', handler: getGitHubAccessTokenWithOverlay },
+ { id: 'github1s.vscode.hide-authorizing-overlay', handler: hideAuthorizingOverlay },
];
// above codes are changed by github1s
diff --git a/vscode-web-github1s/src/vs/github1s/authorizing-github.ts b/vscode-web-github1s/src/vs/github1s/authorizing-github.ts
new file mode 100644
index 000000000..526f7f591
--- /dev/null
+++ b/vscode-web-github1s/src/vs/github1s/authorizing-github.ts
@@ -0,0 +1,59 @@
+/**
+ * @file Authorizing to GitHub with OAuth App flow
+ * @doc https://docs.github.com/en/developers/apps/authorizing-oauth-apps
+ * @author netcon
+ */
+
+import { commands } from 'vs/workbench/workbench.web.api';
+
+const CLIENT_ID = 'eae6621348403ea49103';
+const GITHUB_AUTH_URL = `https://github.com/login/oauth/authorize?scope=repo,user:email&client_id=${CLIENT_ID}`;
+const OPEN_WINDOW_FEATURES = 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=800,height=520,top=150,left=150';
+const AUTH_PAGE_ORIGIN = 'https://auth.github1s.com';
+
+const timeout = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
+
+export type AuthMessageData =
+ | { access_token: string; token_type?: string; scope?: string }
+ | { error: string; error_description: string; error_uri?: string };
+
+export const getGitHubAccessToken = (retryWithOverlay: boolean = false) => {
+ const opener = window.open(GITHUB_AUTH_URL, '_blank', OPEN_WINDOW_FEATURES);
+
+ return new Promise((resolve) => {
+ let overlayOpened = false;
+ // if this function isn't called by a user event,
+ // the browser may block opening a new window,
+ // open the overlay to try authorizing again in this case
+ if (!opener && retryWithOverlay) {
+ overlayOpened = true;
+ commands.executeCommand('github1s.vscode.get-github-access-token-with-overlay')
+ .then(data => resolve(data as AuthMessageData));
+ }
+
+ const handleAuthMessage = (event: MessageEvent<{ type: string, payload: AuthMessageData }>) => {
+ // Note that though the browser block opening window and popup a tip,
+ // the user can be still open it from the tip. In this case, the `opener`
+ // is null, and we should still process the authorizing message
+ if (event.origin !== AUTH_PAGE_ORIGIN || (opener && event.source !== opener) || event.data?.type !== 'authorizing') {
+ return;
+ }
+ // if we have retried with overlay, but we received a message from the
+ // blocked window before, and there is no token in it, just ignore the message
+ if (overlayOpened && !('access_token' in event.data.payload)) {
+ return;
+ }
+ // if we get the token here, and the overlay is opened, just close it
+ overlayOpened && commands.executeCommand('github1s.vscode.hide-authorizing-overlay');
+ window.removeEventListener('message', handleAuthMessage);
+ resolve(event.data.payload);
+ };
+
+ window.addEventListener('message', handleAuthMessage);
+ // if there isn't any message from opener window in 300s, remove the message handler
+ timeout(300 * 1000).then(() => {
+ window.removeEventListener('message', handleAuthMessage);
+ resolve({ error: 'authorizing_timeout', error_description: 'Authorizing timeout' });
+ });
+ });
+};
diff --git a/vscode-web-github1s/src/vs/github1s/authorizing-overlay.css b/vscode-web-github1s/src/vs/github1s/authorizing-overlay.css
new file mode 100644
index 000000000..7e3f4c0ef
--- /dev/null
+++ b/vscode-web-github1s/src/vs/github1s/authorizing-overlay.css
@@ -0,0 +1,269 @@
+.github1s-authorizing-mask {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 99999;
+ background-color: rgba(0, 0, 0, .6);
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+}
+
+.github1s-authorizing-visible {
+ overflow: hidden;
+}
+
+.github1s-overlay-visible .monaco-workbench {
+ filter: blur(2px);
+}
+
+@keyframes authorizingDialogBouncedIn {
+ from { opacity: 0; transform: scale(0); }
+ to { opacity: 1; transform: scale(1); }
+}
+
+@keyframes authorizingDialogBouncedOut {
+ from { opacity: 1; transform: scale(1); }
+ to { opacity: 0; transform: scale(0); }
+}
+
+.github1s-authorizing-dialog {
+ color: #ccc;
+ font-family: Inter, sans-serif;
+ width: 80%;
+ max-width: 520px;
+ background-color: #101010;
+ border-radius: 8px;
+ border: 1px solid #666;
+ text-align: center;
+ padding: 40px 20px 52px;
+ position: absolute;
+ margin-top: 20vh;
+ animation-name: authorizingDialogBouncedIn;
+ animation-duration: 0.2s;
+ animation-iteration-count: 1;
+}
+
+.github1s-authorizing-dialog.exiting {
+ animation-name: authorizingDialogBouncedOut;
+}
+
+.github1s-authorizing-dialog a.link {
+ color: #1890ff;
+}
+
+.github1s-authorizing-dialog a.link:hover {
+ color: #40a9ff;
+}
+
+.github1s-authorizing-dialog a.link:active {
+ color: #096dd9;
+}
+
+.github1s-authorizing-dialog [disabled] {
+ opacity: 0.7;
+ cursor: not-allowed !important;
+}
+
+.github1s-authorizing-dialog .error-message {
+ text-align: left;
+ margin-top: 6px;
+ font-size: 13px;
+ color: #ff4d4f;
+}
+
+.github1s-authorizing-dialog .error-message .link {
+ margin-left: 4px;
+}
+
+.github1s-authorizing-dialog .close-button {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 36px;
+ height: 36px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ color: #fff;
+ font-size: 20px;
+ cursor: pointer;
+ transition: color 0.1s;
+}
+
+.github1s-authorizing-dialog .close-button::after {
+ content: '×';
+}
+
+.github1s-authorizing-dialog .close-button:hover {
+ color: #ff4d4f;
+}
+
+.github1s-authorizing-dialog .close-button:active {
+ color: #d9363e;
+}
+
+.github1s-authorizing-dialog .header-title {
+ color: #fff;
+ font-size: 23px;
+ margin-bottom: 20px;
+}
+
+.github1s-authorizing-dialog .feature-list {
+ list-style: none;
+ font-size: 14px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 0;
+ margin: 0 0 20px;
+}
+
+.github1s-authorizing-dialog .features-description .feature-item {
+ margin-right: 12px;
+ white-space: nowrap;
+ line-height: 20px;
+}
+
+.github1s-authorizing-dialog li.feature-item a {
+ color: #ccc;
+ text-decoration: none;
+}
+
+
+.github1s-authorizing-dialog .features-description .feature-item::before {
+ content: '✓';
+ color: #32d74b;
+ margin-right: 4px;
+}
+
+.github1s-authorizing-dialog .features-description .feature-item:last-child {
+ margin-right: 0;
+}
+
+.github1s-authorizing-dialog .github-documentation {
+ font-size: 13px;
+ margin-bottom: 32px;
+}
+
+.github1s-authorizing-dialog .authorizing-methods {
+ display: inline-block;
+ width: 85%;
+ max-width: 320px;
+}
+
+.github1s-authorizing-dialog .authorizing-button {
+ height: 40px;
+ width: 100%;
+ outline: none;
+ margin: 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: #fff;
+ box-shadow: rgba(255, 255, 255, 0.2) 0px 2px 4px;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ font-size: 16px;
+ transition: all 0.1s;
+ cursor: pointer;
+}
+
+.github1s-authorizing-dialog .authorizing-button:not([disabled]):hover {
+ transform: scale(1.03);
+ box-shadow: rgba(255, 255, 255, 0.25) 0px 2px 8px;
+}
+
+.github1s-authorizing-dialog .authorizing-button:not([disabled]):active {
+ transform: scale(0.98);
+}
+
+.github1s-authorizing-dialog .authorizing-button .github-logo {
+ height: 24px;
+ margin-right: 8px;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .split-line {
+ height: 0;
+ border: 1px solid #ccc;
+ margin: 28px 0;
+ position: relative;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .split-line::after {
+ content: 'OR';
+ display: block;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translateY(-50%) translateX(-50%);
+ border: 2px solid #ccc;
+ padding: 4px 16px;
+ border-radius: 8px;
+ background-color: #000;
+ font-size: 12px;
+ font-weight: bold;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .input-oauth-token-form {
+ display: flex;
+ height: 32px;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .create-token-link {
+ font-size: 12px;
+ text-align: left;
+ margin-top: 8px;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .input-oauth-token-form .input-box {
+ flex: 1;
+ outline: none;
+ color: #ccc;
+ border: 1px solid #3c3c3c;
+ background-color: #3c3c3c;
+ border-radius: 4px;
+ padding: 0 8px;
+ margin-right: 8px;
+ font-size: 14px;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .input-oauth-token-form .input-box:focus {
+ border: 1px solid #096dd9;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .input-oauth-token-form .submit-button {
+ border-style: none;
+ outline: none;
+ width: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+ color: #fff;
+ background-color: #09639c;
+ cursor: pointer;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .input-oauth-token-form .submit-button:not([disabled]):hover {
+ background-color: #1177bb;
+}
+
+.github1s-authorizing-dialog .authorizing-methods .input-oauth-token-form .submit-button:not([disabled]):active {
+ color: #ccc;
+ background-color: #0867ab;
+}
+
+@media (max-width: 550px) {
+ .github1s-authorizing-dialog .feature-list {
+ flex-direction: column;
+ }
+
+ .github1s-authorizing-dialog .features-description .feature-item {
+ width: 180px;
+ text-align: left;
+ margin-right: 0;
+ }
+}
diff --git a/vscode-web-github1s/src/vs/github1s/authorizing-overlay.ts b/vscode-web-github1s/src/vs/github1s/authorizing-overlay.ts
new file mode 100644
index 000000000..69a2e8833
--- /dev/null
+++ b/vscode-web-github1s/src/vs/github1s/authorizing-overlay.ts
@@ -0,0 +1,246 @@
+/**
+ * @file authorizing overlay
+ * @author netcon
+ */
+
+import { commands } from 'vs/workbench/workbench.web.api';
+import { getGitHubAccessToken, AuthMessageData } from 'vs/github1s/authorizing-github';
+import 'vs/css!./authorizing-overlay';
+
+const AUTHORIZING_DIALOG_HTML = `
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+/**
+ * `AuthorizingOverlay.getInstance().show()` will open a dialog
+ * and mask the entire page, It returns a Promise of `AuthMessageData`.
+ */
+export class AuthorizingOverlay {
+ private static _instance: AuthorizingOverlay;
+ private _overlayVisible: boolean = false;
+ private _rootElement?: HTMLDivElement;
+ private _finishCallback: (result: AuthMessageData) => void = () => {};
+
+ // only one overlay instance should be exists
+ public static getInstance() {
+ if (AuthorizingOverlay._instance) {
+ return AuthorizingOverlay._instance;
+ }
+ return AuthorizingOverlay._instance = new AuthorizingOverlay();
+ }
+
+ // show the authorizing overlay
+ public show() {
+ if (this._overlayVisible === true) {
+ return;
+ }
+ this._overlayVisible = true;
+ // add `github1s-overlay-visible` to document.body for `filter: blur(2px)`
+ document.body.classList.add('github1s-overlay-visible');
+ document.body.appendChild(this.getRootElement());
+ this.clearAllErrors();
+ return new Promise(resolve => (this._finishCallback = resolve));
+ }
+
+ // hide the authorizing overlay
+ public hide() {
+ if (this._overlayVisible === false) {
+ return;
+ }
+ this._overlayVisible = false;
+ const dialogElement = this.getDialogElement();
+ // run the exiting animation and waiting 0.18s for finishing it
+ dialogElement.classList.add('exiting');
+ setTimeout(() => {
+ dialogElement.classList.remove('exiting');
+ document.body.classList.remove('github1s-overlay-visible');
+ document.body.removeChild(this.getRootElement());
+ }, 180);
+ }
+
+ // get the root html element of the overlay, there would not
+ // create dom repeatedly, just cache it in the first time
+ private getRootElement(): HTMLDivElement {
+ if (!this._rootElement) {
+ this._rootElement = this.createElements();
+ this.registerListeners();
+ }
+ return this._rootElement;
+ }
+
+ // get dialog html element
+ private getDialogElement(): HTMLDivElement {
+ return this.getRootElement().querySelector('.github1s-authorizing-dialog')!;
+ }
+
+ // create necessary doms
+ private createElements(): HTMLDivElement {
+ const element = document.createElement('div');
+
+ element.classList.add('github1s-authorizing-mask');
+ element.innerHTML = AUTHORIZING_DIALOG_HTML;
+ return element;
+ }
+
+ // create a html element to show error messages
+ private createErrorElement(description: string, link?: string) {
+ const element = document.createElement('div');
+
+ element.classList.add('error-message');
+ element.innerText = description;
+ if (link) {
+ const linkElement = document.createElement('a');
+ linkElement.setAttribute('href', link);
+ linkElement.setAttribute('target', '_blank');
+ linkElement.classList.add('link');
+ linkElement.innerText = 'See more';
+ element.appendChild(linkElement);
+ }
+ return element;
+ };
+
+ // clear all exists error messages
+ private clearAllErrors() {
+ this.getDialogElement().querySelectorAll('.error-message')?.forEach(element => {
+ element.parentElement?.removeChild(element);
+ })
+ }
+
+ // set the error message for the Authorizing Button
+ private setAuthorizingButtonError(description: string, link?: string) {
+ this.clearAllErrors();
+ const errorElement = this.createErrorElement(description, link);
+ this.getDialogElement().querySelector('.authorizing-button')?.insertAdjacentElement('afterend', errorElement);
+ }
+
+ // handle the event when user click the Authorizing Button
+ private async handleClickAuthorizingButton() {
+ // open the authorizing window
+ const data = await getGitHubAccessToken(false);
+
+ if ('access_token' in data) {
+ // we got the token here!
+ this._finishCallback(data);
+ return true;
+ }
+ if ('error' in data) {
+ this.setAuthorizingButtonError(data.error_description, data.error_uri);
+ }
+ return false;
+ }
+
+ // set the error message for the input box where user can input token manually
+ private setSubmitTokenError(description: string, link?: string) {
+ this.clearAllErrors();
+ const errorElement = this.createErrorElement(description, link);
+ this.getDialogElement().querySelector('.create-token-link')?.insertAdjacentElement('afterend', errorElement);
+ }
+
+ // handle the event when user click the submit button for token input box
+ private async handleClickSubmitTokenButton() {
+ const token = (this.getDialogElement().querySelector('.input-oauth-token-form .input-box') as HTMLInputElement)?.value;
+
+ if (!token) {
+ this.setSubmitTokenError('Please input the token');
+ return false;
+ }
+
+ type ValidateResult = { valid: boolean; remaining: number; };
+ const tokenStatus = (await commands.executeCommand('github1s.validate-token', token, true)) as ValidateResult;
+
+ if (!tokenStatus.valid) {
+ this.setSubmitTokenError('The token is invalid');
+ return false;
+ }
+
+ if (tokenStatus.remaining <= 0) {
+ this.setSubmitTokenError('The token is valid, but it has exceeded the rate limit');
+ return false;
+ }
+
+ // we got the token here!
+ this._finishCallback({ access_token: token });
+ return true;
+ }
+
+ // register the event listeners
+ private registerListeners() {
+ const dialogElement = this.getDialogElement();
+
+ // close the dialog
+ dialogElement.querySelector('.close-button')?.addEventListener('click', () => {
+ this._finishCallback({ error: 'user_canceled', error_description: 'Authorizing canceled' });
+ this.hide();
+ });
+
+ // click the authorizing button
+ const authorizingButtonElement = dialogElement.querySelector('.authorizing-button');
+ authorizingButtonElement?.addEventListener('click', async () => {
+ this.clearAllErrors();
+ authorizingButtonElement.setAttribute('disabled', 'disabled');
+ // if authorizing successful, then hide the dialog
+ (await this.handleClickAuthorizingButton()) && this.hide();
+ authorizingButtonElement.removeAttribute('disabled');
+ });
+
+ // submit the manually entered token
+ const submitTokenButtonElement = dialogElement.querySelector('.input-oauth-token-form .submit-button');
+ submitTokenButtonElement?.addEventListener('click', async (event: Event) => {
+ event.preventDefault();
+ this.clearAllErrors();
+ submitTokenButtonElement.setAttribute('disabled', 'disabled');
+ // if authorizing successful, then hide the dialog
+ (await this.handleClickSubmitTokenButton()) && this.hide();
+ submitTokenButtonElement.removeAttribute('disabled');
+ });
+ }
+}
+
+export const getGitHubAccessTokenWithOverlay = () => AuthorizingOverlay.getInstance().show();
+export const hideAuthorizingOverlay = () => AuthorizingOverlay.getInstance().hide();
diff --git a/vscode-web-github1s/src/vs/github1s/util.ts b/vscode-web-github1s/src/vs/github1s/util.ts
index d39f0bfb9..216fa27d3 100644
--- a/vscode-web-github1s/src/vs/github1s/util.ts
+++ b/vscode-web-github1s/src/vs/github1s/util.ts
@@ -12,3 +12,19 @@ export const replaceBrowserUrl = (url: string) => {
window.history.replaceState(null, '', url);
}
};
+
+export const delegate = (
+ element: HTMLElement,
+ selector: string,
+ eventName: K,
+ handler: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any
+): void => {
+ return element?.addEventListener(eventName, function (event) {
+ const children = element.querySelectorAll(selector);
+ for (let i = 0, len = children.length; i < len; i++) {
+ if (children[i] === event.target) {
+ handler.call(this, event);
+ }
+ }
+ });
+};
diff --git a/vscode-web-github1s/src/vs/loader.js b/vscode-web-github1s/src/vs/loader.js
new file mode 100644
index 000000000..10ee09e8d
--- /dev/null
+++ b/vscode-web-github1s/src/vs/loader.js
@@ -0,0 +1,1904 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------------------------
+ *---------------------------------------------------------------------------------------------
+ *---------------------------------------------------------------------------------------------
+ *---------------------------------------------------------------------------------------------
+ *---------------------------------------------------------------------------------------------
+ * Please make sure to make edits in the .ts file at https://github.com/microsoft/vscode-loader/
+ *---------------------------------------------------------------------------------------------
+ *---------------------------------------------------------------------------------------------
+ *---------------------------------------------------------------------------------------------
+ *---------------------------------------------------------------------------------------------
+ *--------------------------------------------------------------------------------------------*/
+var _amdLoaderGlobal = this;
+var _commonjsGlobal = typeof global === 'object' ? global : {};
+var AMDLoader;
+(function (AMDLoader) {
+ AMDLoader.global = _amdLoaderGlobal;
+ var Environment = /** @class */ (function () {
+ function Environment() {
+ this._detected = false;
+ this._isWindows = false;
+ this._isNode = false;
+ this._isElectronRenderer = false;
+ this._isWebWorker = false;
+ }
+ Object.defineProperty(Environment.prototype, "isWindows", {
+ get: function () {
+ this._detect();
+ return this._isWindows;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Environment.prototype, "isNode", {
+ get: function () {
+ this._detect();
+ return this._isNode;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Environment.prototype, "isElectronRenderer", {
+ get: function () {
+ this._detect();
+ return this._isElectronRenderer;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(Environment.prototype, "isWebWorker", {
+ get: function () {
+ this._detect();
+ return this._isWebWorker;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Environment.prototype._detect = function () {
+ if (this._detected) {
+ return;
+ }
+ this._detected = true;
+ this._isWindows = Environment._isWindows();
+ this._isNode = (typeof module !== 'undefined' && !!module.exports);
+ this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer');
+ this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function');
+ };
+ Environment._isWindows = function () {
+ if (typeof navigator !== 'undefined') {
+ if (navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0) {
+ return true;
+ }
+ }
+ if (typeof process !== 'undefined') {
+ return (process.platform === 'win32');
+ }
+ return false;
+ };
+ return Environment;
+ }());
+ AMDLoader.Environment = Environment;
+})(AMDLoader || (AMDLoader = {}));
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+var AMDLoader;
+(function (AMDLoader) {
+ var LoaderEvent = /** @class */ (function () {
+ function LoaderEvent(type, detail, timestamp) {
+ this.type = type;
+ this.detail = detail;
+ this.timestamp = timestamp;
+ }
+ return LoaderEvent;
+ }());
+ AMDLoader.LoaderEvent = LoaderEvent;
+ var LoaderEventRecorder = /** @class */ (function () {
+ function LoaderEventRecorder(loaderAvailableTimestamp) {
+ this._events = [new LoaderEvent(1 /* LoaderAvailable */, '', loaderAvailableTimestamp)];
+ }
+ LoaderEventRecorder.prototype.record = function (type, detail) {
+ this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp()));
+ };
+ LoaderEventRecorder.prototype.getEvents = function () {
+ return this._events;
+ };
+ return LoaderEventRecorder;
+ }());
+ AMDLoader.LoaderEventRecorder = LoaderEventRecorder;
+ var NullLoaderEventRecorder = /** @class */ (function () {
+ function NullLoaderEventRecorder() {
+ }
+ NullLoaderEventRecorder.prototype.record = function (type, detail) {
+ // Nothing to do
+ };
+ NullLoaderEventRecorder.prototype.getEvents = function () {
+ return [];
+ };
+ NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder();
+ return NullLoaderEventRecorder;
+ }());
+ AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder;
+})(AMDLoader || (AMDLoader = {}));
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+var AMDLoader;
+(function (AMDLoader) {
+ var Utilities = /** @class */ (function () {
+ function Utilities() {
+ }
+ /**
+ * This method does not take care of / vs \
+ */
+ Utilities.fileUriToFilePath = function (isWindows, uri) {
+ uri = decodeURI(uri).replace(/%23/g, '#');
+ if (isWindows) {
+ if (/^file:\/\/\//.test(uri)) {
+ // This is a URI without a hostname => return only the path segment
+ return uri.substr(8);
+ }
+ if (/^file:\/\//.test(uri)) {
+ return uri.substr(5);
+ }
+ }
+ else {
+ if (/^file:\/\//.test(uri)) {
+ return uri.substr(7);
+ }
+ }
+ // Not sure...
+ return uri;
+ };
+ Utilities.startsWith = function (haystack, needle) {
+ return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle;
+ };
+ Utilities.endsWith = function (haystack, needle) {
+ return haystack.length >= needle.length && haystack.substr(haystack.length - needle.length) === needle;
+ };
+ // only check for "?" before "#" to ensure that there is a real Query-String
+ Utilities.containsQueryString = function (url) {
+ return /^[^\#]*\?/gi.test(url);
+ };
+ /**
+ * Does `url` start with http:// or https:// or file:// or / ?
+ */
+ Utilities.isAbsolutePath = function (url) {
+ return /^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(url);
+ };
+ Utilities.forEachProperty = function (obj, callback) {
+ if (obj) {
+ var key = void 0;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ callback(key, obj[key]);
+ }
+ }
+ }
+ };
+ Utilities.isEmpty = function (obj) {
+ var isEmpty = true;
+ Utilities.forEachProperty(obj, function () {
+ isEmpty = false;
+ });
+ return isEmpty;
+ };
+ Utilities.recursiveClone = function (obj) {
+ if (!obj || typeof obj !== 'object' || obj instanceof RegExp) {
+ return obj;
+ }
+ if (!Array.isArray(obj) && Object.getPrototypeOf(obj) !== Object.prototype) {
+ // only clone "simple" objects
+ return obj;
+ }
+ var result = Array.isArray(obj) ? [] : {};
+ Utilities.forEachProperty(obj, function (key, value) {
+ if (value && typeof value === 'object') {
+ result[key] = Utilities.recursiveClone(value);
+ }
+ else {
+ result[key] = value;
+ }
+ });
+ return result;
+ };
+ Utilities.generateAnonymousModule = function () {
+ return '===anonymous' + (Utilities.NEXT_ANONYMOUS_ID++) + '===';
+ };
+ Utilities.isAnonymousModule = function (id) {
+ return Utilities.startsWith(id, '===anonymous');
+ };
+ Utilities.getHighPerformanceTimestamp = function () {
+ if (!this.PERFORMANCE_NOW_PROBED) {
+ this.PERFORMANCE_NOW_PROBED = true;
+ this.HAS_PERFORMANCE_NOW = (AMDLoader.global.performance && typeof AMDLoader.global.performance.now === 'function');
+ }
+ return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now());
+ };
+ Utilities.NEXT_ANONYMOUS_ID = 1;
+ Utilities.PERFORMANCE_NOW_PROBED = false;
+ Utilities.HAS_PERFORMANCE_NOW = false;
+ return Utilities;
+ }());
+ AMDLoader.Utilities = Utilities;
+})(AMDLoader || (AMDLoader = {}));
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+var AMDLoader;
+(function (AMDLoader) {
+ function ensureError(err) {
+ if (err instanceof Error) {
+ return err;
+ }
+ var result = new Error(err.message || String(err) || 'Unknown Error');
+ if (err.stack) {
+ result.stack = err.stack;
+ }
+ return result;
+ }
+ AMDLoader.ensureError = ensureError;
+ ;
+ var ConfigurationOptionsUtil = /** @class */ (function () {
+ function ConfigurationOptionsUtil() {
+ }
+ /**
+ * Ensure configuration options make sense
+ */
+ ConfigurationOptionsUtil.validateConfigurationOptions = function (options) {
+ function defaultOnError(err) {
+ if (err.phase === 'loading') {
+ console.error('Loading "' + err.moduleId + '" failed');
+ console.error(err);
+ console.error('Here are the modules that depend on it:');
+ console.error(err.neededBy);
+ return;
+ }
+ if (err.phase === 'factory') {
+ console.error('The factory method of "' + err.moduleId + '" has thrown an exception');
+ console.error(err);
+ return;
+ }
+ }
+ options = options || {};
+ if (typeof options.baseUrl !== 'string') {
+ options.baseUrl = '';
+ }
+ if (typeof options.isBuild !== 'boolean') {
+ options.isBuild = false;
+ }
+ if (typeof options.paths !== 'object') {
+ options.paths = {};
+ }
+ if (typeof options.config !== 'object') {
+ options.config = {};
+ }
+ if (typeof options.catchError === 'undefined') {
+ options.catchError = false;
+ }
+ if (typeof options.recordStats === 'undefined') {
+ options.recordStats = false;
+ }
+ if (typeof options.urlArgs !== 'string') {
+ options.urlArgs = '';
+ }
+ if (typeof options.onError !== 'function') {
+ options.onError = defaultOnError;
+ }
+ if (!Array.isArray(options.ignoreDuplicateModules)) {
+ options.ignoreDuplicateModules = [];
+ }
+ if (options.baseUrl.length > 0) {
+ if (!AMDLoader.Utilities.endsWith(options.baseUrl, '/')) {
+ options.baseUrl += '/';
+ }
+ }
+ if (typeof options.cspNonce !== 'string') {
+ options.cspNonce = '';
+ }
+ if (typeof options.preferScriptTags === 'undefined') {
+ options.preferScriptTags = false;
+ }
+ if (!Array.isArray(options.nodeModules)) {
+ options.nodeModules = [];
+ }
+ if (options.nodeCachedData && typeof options.nodeCachedData === 'object') {
+ if (typeof options.nodeCachedData.seed !== 'string') {
+ options.nodeCachedData.seed = 'seed';
+ }
+ if (typeof options.nodeCachedData.writeDelay !== 'number' || options.nodeCachedData.writeDelay < 0) {
+ options.nodeCachedData.writeDelay = 1000 * 7;
+ }
+ if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') {
+ var err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set'));
+ err.phase = 'configuration';
+ options.onError(err);
+ options.nodeCachedData = undefined;
+ }
+ }
+ return options;
+ };
+ ConfigurationOptionsUtil.mergeConfigurationOptions = function (overwrite, base) {
+ if (overwrite === void 0) { overwrite = null; }
+ if (base === void 0) { base = null; }
+ var result = AMDLoader.Utilities.recursiveClone(base || {});
+ // Merge known properties and overwrite the unknown ones
+ AMDLoader.Utilities.forEachProperty(overwrite, function (key, value) {
+ if (key === 'ignoreDuplicateModules' && typeof result.ignoreDuplicateModules !== 'undefined') {
+ result.ignoreDuplicateModules = result.ignoreDuplicateModules.concat(value);
+ }
+ else if (key === 'paths' && typeof result.paths !== 'undefined') {
+ AMDLoader.Utilities.forEachProperty(value, function (key2, value2) { return result.paths[key2] = value2; });
+ }
+ else if (key === 'config' && typeof result.config !== 'undefined') {
+ AMDLoader.Utilities.forEachProperty(value, function (key2, value2) { return result.config[key2] = value2; });
+ }
+ else {
+ result[key] = AMDLoader.Utilities.recursiveClone(value);
+ }
+ });
+ return ConfigurationOptionsUtil.validateConfigurationOptions(result);
+ };
+ return ConfigurationOptionsUtil;
+ }());
+ AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil;
+ var Configuration = /** @class */ (function () {
+ function Configuration(env, options) {
+ this._env = env;
+ this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options);
+ this._createIgnoreDuplicateModulesMap();
+ this._createNodeModulesMap();
+ this._createSortedPathsRules();
+ if (this.options.baseUrl === '') {
+ if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) {
+ var nodeMain = this.options.nodeRequire.main.filename;
+ var dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\'));
+ this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1);
+ }
+ if (this.options.nodeMain && this._env.isNode) {
+ var nodeMain = this.options.nodeMain;
+ var dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\'));
+ this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1);
+ }
+ }
+ }
+ Configuration.prototype._createIgnoreDuplicateModulesMap = function () {
+ // Build a map out of the ignoreDuplicateModules array
+ this.ignoreDuplicateModulesMap = {};
+ for (var i = 0; i < this.options.ignoreDuplicateModules.length; i++) {
+ this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[i]] = true;
+ }
+ };
+ Configuration.prototype._createNodeModulesMap = function () {
+ // Build a map out of nodeModules array
+ this.nodeModulesMap = Object.create(null);
+ for (var _i = 0, _a = this.options.nodeModules; _i < _a.length; _i++) {
+ var nodeModule = _a[_i];
+ this.nodeModulesMap[nodeModule] = true;
+ }
+ };
+ Configuration.prototype._createSortedPathsRules = function () {
+ var _this = this;
+ // Create an array our of the paths rules, sorted descending by length to
+ // result in a more specific -> less specific order
+ this.sortedPathsRules = [];
+ AMDLoader.Utilities.forEachProperty(this.options.paths, function (from, to) {
+ if (!Array.isArray(to)) {
+ _this.sortedPathsRules.push({
+ from: from,
+ to: [to]
+ });
+ }
+ else {
+ _this.sortedPathsRules.push({
+ from: from,
+ to: to
+ });
+ }
+ });
+ this.sortedPathsRules.sort(function (a, b) {
+ return b.from.length - a.from.length;
+ });
+ };
+ /**
+ * Clone current configuration and overwrite options selectively.
+ * @param options The selective options to overwrite with.
+ * @result A new configuration
+ */
+ Configuration.prototype.cloneAndMerge = function (options) {
+ return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options));
+ };
+ /**
+ * Get current options bag. Useful for passing it forward to plugins.
+ */
+ Configuration.prototype.getOptionsLiteral = function () {
+ return this.options;
+ };
+ Configuration.prototype._applyPaths = function (moduleId) {
+ var pathRule;
+ for (var i = 0, len = this.sortedPathsRules.length; i < len; i++) {
+ pathRule = this.sortedPathsRules[i];
+ if (AMDLoader.Utilities.startsWith(moduleId, pathRule.from)) {
+ var result = [];
+ for (var j = 0, lenJ = pathRule.to.length; j < lenJ; j++) {
+ result.push(pathRule.to[j] + moduleId.substr(pathRule.from.length));
+ }
+ return result;
+ }
+ }
+ return [moduleId];
+ };
+ Configuration.prototype._addUrlArgsToUrl = function (url) {
+ if (AMDLoader.Utilities.containsQueryString(url)) {
+ return url + '&' + this.options.urlArgs;
+ }
+ else {
+ return url + '?' + this.options.urlArgs;
+ }
+ };
+ Configuration.prototype._addUrlArgsIfNecessaryToUrl = function (url) {
+ if (this.options.urlArgs) {
+ return this._addUrlArgsToUrl(url);
+ }
+ return url;
+ };
+ Configuration.prototype._addUrlArgsIfNecessaryToUrls = function (urls) {
+ if (this.options.urlArgs) {
+ for (var i = 0, len = urls.length; i < len; i++) {
+ urls[i] = this._addUrlArgsToUrl(urls[i]);
+ }
+ }
+ return urls;
+ };
+ /**
+ * Transform a module id to a location. Appends .js to module ids
+ */
+ Configuration.prototype.moduleIdToPaths = function (moduleId) {
+ var isNodeModule = ((this.nodeModulesMap[moduleId] === true)
+ || (this.options.amdModulesPattern instanceof RegExp && !this.options.amdModulesPattern.test(moduleId)));
+ if (isNodeModule) {
+ // This is a node module...
+ if (this.isBuild()) {
+ // ...and we are at build time, drop it
+ return ['empty:'];
+ }
+ else {
+ // ...and at runtime we create a `shortcut`-path
+ return ['node|' + moduleId];
+ }
+ }
+ var result = moduleId;
+ var results;
+ if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.isAbsolutePath(result)) {
+ results = this._applyPaths(result);
+ for (var i = 0, len = results.length; i < len; i++) {
+ if (this.isBuild() && results[i] === 'empty:') {
+ continue;
+ }
+ if (!AMDLoader.Utilities.isAbsolutePath(results[i])) {
+ results[i] = this.options.baseUrl + results[i];
+ }
+ if (!AMDLoader.Utilities.endsWith(results[i], '.js') && !AMDLoader.Utilities.containsQueryString(results[i])) {
+ results[i] = results[i] + '.js';
+ }
+ }
+ }
+ else {
+ if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.containsQueryString(result)) {
+ result = result + '.js';
+ }
+ results = [result];
+ }
+ return this._addUrlArgsIfNecessaryToUrls(results);
+ };
+ /**
+ * Transform a module id or url to a location.
+ */
+ Configuration.prototype.requireToUrl = function (url) {
+ var result = url;
+ if (!AMDLoader.Utilities.isAbsolutePath(result)) {
+ result = this._applyPaths(result)[0];
+ if (!AMDLoader.Utilities.isAbsolutePath(result)) {
+ result = this.options.baseUrl + result;
+ }
+ }
+ return this._addUrlArgsIfNecessaryToUrl(result);
+ };
+ /**
+ * Flag to indicate if current execution is as part of a build.
+ */
+ Configuration.prototype.isBuild = function () {
+ return this.options.isBuild;
+ };
+ /**
+ * Test if module `moduleId` is expected to be defined multiple times
+ */
+ Configuration.prototype.isDuplicateMessageIgnoredFor = function (moduleId) {
+ return this.ignoreDuplicateModulesMap.hasOwnProperty(moduleId);
+ };
+ /**
+ * Get the configuration settings for the provided module id
+ */
+ Configuration.prototype.getConfigForModule = function (moduleId) {
+ if (this.options.config) {
+ return this.options.config[moduleId];
+ }
+ };
+ /**
+ * Should errors be caught when executing module factories?
+ */
+ Configuration.prototype.shouldCatchError = function () {
+ return this.options.catchError;
+ };
+ /**
+ * Should statistics be recorded?
+ */
+ Configuration.prototype.shouldRecordStats = function () {
+ return this.options.recordStats;
+ };
+ /**
+ * Forward an error to the error handler.
+ */
+ Configuration.prototype.onError = function (err) {
+ this.options.onError(err);
+ };
+ return Configuration;
+ }());
+ AMDLoader.Configuration = Configuration;
+})(AMDLoader || (AMDLoader = {}));
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+var AMDLoader;
+(function (AMDLoader) {
+ /**
+ * Load `scriptSrc` only once (avoid multiple