45 |
--------------------------------------------------------------------------------
/example/vsc-extension-quickstart.md:
--------------------------------------------------------------------------------
1 | # Welcome to your VS Code Extension
2 |
3 | ## What's in the folder
4 |
5 | * This folder contains all of the files necessary for your extension.
6 | * `package.json` - this is the manifest file in which you declare your extension and command.
7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin.
8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command.
9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`.
10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`.
11 |
12 | ## Get up and running straight away
13 |
14 | * Press `F5` to open a new window with your extension loaded.
15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`.
16 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension.
17 | * Find output from your extension in the debug console.
18 |
19 | ## Make changes
20 |
21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`.
22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes.
23 |
24 |
25 | ## Explore the API
26 |
27 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`.
28 |
29 | ## Run tests
30 |
31 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`.
32 | * Press `F5` to run the tests in a new window with your extension loaded.
33 | * See the output of the test result in the debug console.
34 | * Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder.
35 | * The provided test runner will only consider files matching the name pattern `**.test.ts`.
36 | * You can create folders inside the `test` folder to structure your tests any way you want.
37 |
38 | ## Go further
39 |
40 | * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension).
41 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace.
42 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).
43 |
--------------------------------------------------------------------------------
/example/pages/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 | Sample Page
16 |
17 |
18 |
19 |
41 |
42 |
43 |
44 |
45 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/src/pages.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 | import * as fs from 'fs';
3 | import * as path from 'path';
4 | import * as handlebars from 'handlebars';
5 |
6 | export type MessageHandler = (parameters?: any) => Promise;
7 | export interface Template {
8 | id: string;
9 | content?: string;
10 | contentUrl?: string;
11 | }
12 | export interface MesssageMaping {
13 | command: string;
14 | handler: MessageHandler;
15 | templates?: Template[];
16 | forward?: string;
17 | }
18 |
19 | interface Content {
20 | id: string;
21 | body: string;
22 | }
23 | interface CommandResponse {
24 | command: string;
25 | contents?: Content[];
26 | result?: any;
27 | }
28 |
29 | const currentPanels: Map = new Map();
30 |
31 | const initJS = `
32 | function initEventListener(fn) {
33 | window.addEventListener('message', event => {
34 | const message = event.data;
35 | if (message.command.match(/Response$/) && message.contents) {
36 | message.contents.forEach(content => {
37 | let element = document.getElementById(content.id);
38 | element.innerHTML = content.body;
39 | });
40 | } else {
41 | if (fn) {
42 | fn(message);
43 | }
44 | }
45 | });
46 | }
47 | `;
48 |
49 | export function createOrShowPage(
50 | name: string,
51 | viewType: string,
52 | title: string,
53 | base: string,
54 | page: string,
55 | context: vscode.ExtensionContext,
56 | messageMappings: MesssageMaping[]
57 | ) {
58 | let panel = currentPanels.get(name);
59 | if (panel) {
60 | panel.reveal();
61 | } else {
62 | const rootString = path.join(context.extensionPath, base);
63 | const localResourceRoots = vscode.Uri.file(path.join(rootString, '/')).with(
64 | {
65 | scheme: 'vscode-resource',
66 | }
67 | );
68 | panel = vscode.window.createWebviewPanel(
69 | viewType,
70 | title,
71 | vscode.ViewColumn.One,
72 | {
73 | enableScripts: true,
74 | retainContextWhenHidden: true,
75 | localResourceRoots: [localResourceRoots],
76 | }
77 | );
78 |
79 | const pagePath = path.join(rootString, page);
80 | panel.webview.html = fs
81 | .readFileSync(pagePath, 'utf-8')
82 | .replace('{{base}}', localResourceRoots.toString())
83 | .replace('"{{init}}"', initJS);
84 | panel.webview.onDidReceiveMessage(
85 | createDispatch(messageMappings, panel, context)
86 | );
87 | panel.onDidDispose(
88 | () => currentPanels.delete(name),
89 | undefined,
90 | context.subscriptions
91 | );
92 | currentPanels.set(name, panel);
93 | }
94 | }
95 |
96 | function createDispatch(
97 | messageMappings: MesssageMaping[],
98 | currentPanel: vscode.WebviewPanel,
99 | context: vscode.ExtensionContext
100 | ) {
101 | const handler = (message: any) => {
102 | const mapping = messageMappings.find(
103 | mapping => mapping.command === message.command
104 | );
105 | if (mapping) {
106 | const response: CommandResponse = {
107 | command: `${message.command}Response`,
108 | };
109 | mapping.handler.call(null, message.parameters).then(result => {
110 | if (mapping.templates) {
111 | response.contents = [];
112 | mapping.templates.forEach(template => {
113 | if (template.content) {
114 | response.contents?.push({
115 | id: template.id,
116 | body: handlebars.compile(template.content)(result),
117 | });
118 | } else if (template.contentUrl) {
119 | response.contents?.push({
120 | id: template.id,
121 | body: handlebars.compile(
122 | fs
123 | .readFileSync(
124 | path.join(context.extensionPath, template.contentUrl)
125 | )
126 | .toString()
127 | )(result),
128 | });
129 | }
130 | });
131 | } else if (mapping.forward) {
132 | return handler.call(null, {
133 | command: mapping.forward,
134 | parameters: result,
135 | });
136 | } else {
137 | response.result = result;
138 | }
139 | currentPanel.webview.postMessage(response);
140 | });
141 | } else {
142 | vscode.window.showErrorMessage(
143 | `Can not find a handler for ${message.command}.`
144 | );
145 | }
146 | };
147 | return handler;
148 | }
149 |
--------------------------------------------------------------------------------
/example/pages/shared/style.css:
--------------------------------------------------------------------------------
1 |
2 | body.vscode-dark {
3 | color: #e9e9e9;
4 | }
5 |
6 | body.vscode-light {
7 | color: #1b1b1b;
8 | }
9 |
10 | .vscode-light .bd-toc-link {
11 | color: rgba(0,0,0,.65) !important;
12 | }
13 |
14 | .vscode-dark .bd-toc-link {
15 | color: rgba(255,255,255,.65) !important;
16 | }
17 | .vscode-light .bd-sidebar{
18 | border-right: 1px solid rgba(0,0,0,.1);
19 | }
20 |
21 | .vscode-dark .bd-sidebar{
22 | border-right: 1px solid rgba(244,244,244,.1);
23 | }
24 |
25 | .vscode-light .bd-search {
26 | border-bottom: 1px solid rgba(0, 0, 0, .05);
27 | }
28 |
29 | .vscode-dark .bd-search {
30 | border-bottom: 1px solid rgba(244, 244, 244, .05);
31 | }
32 |
33 | .vscode-dark hr{
34 | border-top: 1px solid rgba(244,244,244,.1);
35 | }
36 | .vscode-dark .table{
37 | color:unset;
38 | }
39 |
40 | .vscode-dark .table .thead-light th {
41 | color: #ffffff;
42 | background-color: #343a40;
43 | border-color: #dee2e6;
44 | }
45 | .table tbody tr:hover{
46 | background-color: #424040;
47 | }
48 |
49 | .vscode-light .table tbody tr:hover{
50 | background-color: #dddddd;
51 | }
52 | .container-fluid{
53 | padding-left: unset !important;
54 | padding-right: unset !important;
55 | }
56 |
57 | .extention-title{
58 | font-size:2rem;
59 | }
60 | .list-title ,.extention-title{
61 | font-weight: bold;
62 | }
63 | .version{
64 | font-weight: 100;
65 | font-size: 12px;
66 | }
67 |
68 | .vertical-align {
69 | display: flex;
70 | align-items: center;
71 | }
72 |
73 | #settingBtn{
74 | margin: 0px auto;
75 | width: 100px;
76 | }
77 | .pagetitle{
78 | text-align: center;
79 | }
80 | .pagetitle h1{
81 | margin-top: 20px;
82 | margin-bottom: 20px;
83 | font-size: 3.5rem;
84 | line-height: 2.5rem;
85 | font-weight: bold;
86 | color: #808080 !important;
87 | }
88 | .pagetitle h2{
89 | margin-top: 20px;
90 | margin-bottom: 20px;
91 | }
92 |
93 | .content{
94 | margin:10px;
95 | height:400px;
96 | }
97 | #repos li{
98 | cursor: pointer;
99 | width:100%;
100 | }
101 | .repos_logo{
102 | margin-right:30px;
103 | width: 24px;
104 | }
105 | #menuList{
106 | padding: 0;
107 | }
108 | .bd-navbar {
109 | min-height: 4rem;
110 | background-color: #333333;
111 | box-shadow: 0 0.5rem 1rem rgba(0,0,0,.05), inset 0 -1px 0 rgba(0,0,0,.1);
112 | }
113 | .bd-sidebar {
114 | position: -webkit-sticky;
115 | position: sticky;
116 | top: 4rem;
117 | z-index: 1000;
118 | height: calc(100vh - 4rem);
119 | }
120 | .navbar-brand{
121 | color:white !important;
122 | }
123 | .nav-item img{
124 | width:20px;
125 | }
126 | .bd-toc-link {
127 | display: block;
128 | padding: .25rem 1.5rem;
129 | font-weight: 600;
130 | }
131 | .bd-toc-link:hover { color: #808080; }
132 | .no-padding{
133 | padding:0px !important;
134 | }
135 | .bd-search {
136 | position: relative;
137 | padding: 1rem 15px;
138 | margin-right: -15px;
139 | margin-left: -15px;
140 | }
141 | #scroll-to-top {
142 | position: fixed;
143 | width: 40px;
144 | height: 40px;
145 | right: 25px;
146 | bottom: 25px;
147 | background-color: #444444;
148 | border-radius: 50%;
149 | cursor: pointer;
150 | box-shadow: 1px 1px 1px rgba(0,0,0,.25);
151 | outline: none;
152 | display: flex;
153 | justify-content: center;
154 | align-items: center;
155 | }
156 | #scroll-to-top span.icon::before {
157 | content: "";
158 | display: block;
159 | background: url(imgs/top.png);
160 | width: 16px;
161 | height: 16px;
162 | }
163 | a{
164 | color:#808080;
165 | }
166 | a:hover{
167 | color:#f0f0f0;
168 | border:unset;
169 | }
170 | .tab-content{
171 | height:250px;
172 | overflow: scroll;
173 | width:99%
174 | }
175 | .nav-tabs{
176 | margin-top:20px;
177 | border-bottom: unset;
178 | }
179 | a:focus, textarea:focus {
180 | outline: unset;
181 | outline-offset: unset;
182 | }
183 | .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {
184 | color: #fff;
185 | border-bottom: 1px solid white;
186 | border-top:0px;
187 | border-right:0px;
188 | border-left:0px;
189 | background-color: unset;
190 | }
191 | .nav-link {
192 | margin-right: 2rem;
193 | padding: unset;
194 | }
195 | .nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover {
196 | border-bottom: 1px solid white;
197 | border-top: 1px solid rgba(255, 255, 255, 0);
198 | border-right: 1px solid rgba(255, 255, 255, 0);
199 | border-left: 1px solid rgba(255, 255, 255, 0);
200 | }
201 | .vscode-light .nav-tabs .nav-item.show .nav-link,.vscode-light .nav-tabs .nav-link.active {
202 | color: #333;
203 | border-bottom: 1px solid #808080;
204 | border-top:1px solid rgba(255, 255, 255, 0);
205 | border-right:1px solid rgba(255, 255, 255, 0);
206 | border-left:1px solid rgba(255, 255, 255, 0);
207 | background-color: unset;
208 | }
209 |
210 | .vscode-light .nav-tabs .nav-link:focus, .vscode-light .nav-tabs .nav-link:hover {
211 | color: #333;
212 | border-bottom: 1px solid #808080;
213 | border-top:1px solid rgba(255, 255, 255, 0);
214 | border-right:1px solid rgba(255, 255, 255, 0);
215 | border-left:1px solid rgba(255, 255, 255, 0);
216 | }
217 |
218 | .extension-item:hover{
219 | background-color: #424040;
220 | }
221 |
222 | .vscode-light .extension-item:hover{
223 | background-color: #dddddd;
224 | }
225 | .extension-item{
226 | margin-left:10px;
227 | margin-bottom: 10px;
228 | }
229 |
230 | .sidebar-sticky{
231 | position: sticky;
232 | top: 0;
233 | height: calc(100vh - 135px);
234 | padding-top: .5rem;
235 | overflow-x: hidden;
236 | overflow-y: auto;
237 | list-style: none;
238 | -ms-flex-wrap: wrap;
239 | flex-wrap: wrap;
240 | padding-left: 0;
241 | margin-bottom: 0;
242 | }
243 |
244 | .changelog-sticky{
245 | position: sticky;
246 | top: 0;
247 | height: calc(100vh - 244px);
248 | padding-top: .5rem;
249 | overflow-x: hidden;
250 | overflow-y: auto;
251 | -ms-flex-wrap: wrap;
252 | flex-wrap: wrap;
253 | padding-left: 0;
254 | margin-bottom: 0;
255 | }
256 | .setting-container{
257 | position: sticky;
258 | top: 0;
259 | overflow-x: hidden;
260 | overflow-y: auto;
261 | -ms-flex-wrap: wrap;
262 | flex-wrap: wrap;
263 | padding-left: 0;
264 | margin-bottom: 0;
265 | }
266 |
267 | .vscode-dark pre{
268 | color:white;
269 | }
270 | .example-div{
271 | padding: 10px 10px 0px 10px;
272 | border: 1px solid #b4b1b1;
273 | height: calc(100vh - 244px);
274 | }
275 |
276 | .vscode-light .example-div{
277 | padding: 10px;
278 | border: 1px solid #808080;
279 | }
280 | textarea{
281 | margin-left: 10px;
282 | width:100%;
283 | height:calc(100vh - 244px);
284 | overflow:scroll;
285 | resize: none;
286 | }
287 | .button-div{
288 | margin-top:20px;
289 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vscode-page
2 |
3 | [](https://github.com/google/gts)
4 |
5 | [](https://nodei.co/npm/vscode-page/)
6 |
7 | vscode-page is a light-weight page micro framework for vscode webview, it could accelerate Vs Code Extension Webview development.
8 |
9 | ## Features
10 |
11 | - abstract the communication between html page and WebviewPanel, developers can focus on business logic.
12 | - built-in template engine, with [handlebars.js](https://www.npmjs.com/package/handlebars).
13 | - message mapping, a simple way to organize page logic and view.
14 | - baseUrl support, relative paths can be used in html page.
15 |
16 | ## Installing
17 |
18 | ```shell
19 | npm install vscode-page
20 | ```
21 |
22 | ## Usage
23 |
24 | vscode-page simplifies Webview development with following steps:
25 |
26 | 1. define messages between html page and vscode.WebviewPanel.
27 | 1. develop html page and js functions inside that page.
28 | 1. define MessageMappings.
29 | 1. register a command to create (or show) WebviewPanel with the MessageMappings defined in step 3.
30 |
31 | The whole architecture is shown below:
32 |
33 | 
34 |
35 | Also, there is [a demo project](example) to show its usage. Before check it, please read the following first.
36 |
37 | ### Messaging
38 |
39 | As described in vscode extension guide, html page and WebviewPanel can post messages each other. To standardize this communication, vscode-page defines two message formats.
40 |
41 | #### js -> WebviewPanel
42 |
43 | The message json format :
44 |
45 | - command, an indexed value for a command handler defined in a MessageMapping.
46 | - parameters (optional), an json argument passed to that command handler.
47 |
48 | Here is an example:
49 |
50 | ```json
51 | {
52 | "command": "showExtension",
53 | "parameters": {
54 | "repo": repo,
55 | "extId": extId,
56 | "installed": installed
57 | }
58 | }
59 | ```
60 |
61 | #### WebviewPanel -> js
62 |
63 | The message json format :
64 |
65 | - command, if ending with "Response", it is a response of the prefix. Such as "showExtensionResponse" is response of "showExtension".
66 | - contents (optional), a content array. Each item has following keys:
67 | - id, element id in a html page.
68 | - body, innerHtml (generated by the template defined in a MessageMapping) of the element pointed by id.
69 | - result (optional), return value of the "\${command}" handler.
70 |
71 | Here is an example:
72 |
73 | ```json
74 | {
75 | "command": "showExtensionResponse",
76 | "contents": [
77 | { "id": "title", "body": "Repo / Extension" },
78 | {
79 | "id": "content",
80 | "body": "...."
81 | }
82 | ]
83 | }
84 | ```
85 |
86 | ### HTML Page
87 |
88 | In order to initialize correctly, for each html page, please insert the following two lines in \:
89 |
90 | ```
91 |
92 |
95 | ```
96 |
97 | Here is the explaination:
98 |
99 | - {{base}} will be replaced by "path.join(context.extensionPath, root)", then relative paths can be used in that page.
100 | - {{init}} will be replaced by initEventListener function definition, which defines an EventListener receiving messages from WebviewPanel.
101 |
102 | Then it can be invoked to add an event listener to html page as below:
103 |
104 | ```javascript
105 | initEventListener();
106 | ```
107 |
108 | The default implementation will only process messages ending with "Response" and use contents as innerHtml of selected elements.
109 |
110 | For other messages, a customized function can be passed to initEventListener as below:
111 |
112 | ```javascript
113 | initEventListener(message => {...});
114 | ```
115 |
116 | The message has following key:
117 |
118 | - result, return value of a command handler.
119 |
120 | ### MessageMappings
121 |
122 | A MessageMapping defines:
123 |
124 | - command, the value of "command" field in message posted by js function.
125 | - handler, a function for the command above, its signature is below and the parameters is the value of "parameters" in the same message from js function.
126 |
127 | ```typescript
128 | (parameters?: any) => Promise;
129 | ```
130 |
131 | - templates (optional), a template array for views of response of the command. Each item has the following keys:
132 | - id, element id in html page.
133 | - content, a inline handlebars template, it is optional.
134 | - contentUrl, a url to an external handlebars template, it is optional.
135 | - forward (optional), similar to request-forward pattern in web development, a MessageMapping the request flow will go.
136 |
137 | NOTE:
138 |
139 | - either "content" or "contentUrl" MUST be shown in a MessageMapping, not both.
140 | - both of "templates" and "forward" are optional, but if being used, only one of them can be shown in a MessageMapping.
141 |
142 | Here is a MessageMappings example: [home.ts](example/src/home.ts)
143 |
144 | ### createOrShowPage
145 |
146 | To create or show a WebviewPanel, invoke function createOrShowPage like beblow (from [extension.ts](example/src/extension.ts) in example):
147 |
148 | ```typescript
149 | createOrShowPage(
150 | 'name',
151 | 'ext.home',
152 | 'Sample Page',
153 | 'pages',
154 | 'home.html',
155 | context,
156 | messageMappings
157 | );
158 | ```
159 |
160 | The signature of createOrShowPage:
161 |
162 | ```typescript
163 | export function createOrShowPage(
164 | name: string,
165 | viewType: string,
166 | title: string,
167 | base: string,
168 | page: string,
169 | context: vscode.ExtensionContext,
170 | messageMappings: MesssageMaping[]
171 | );
172 | ```
173 |
174 | Each argument:
175 |
176 | - name, a named index of the WebviewPanel created.
177 | - viewType and title, both of them will be passed to vscode.window.createWebviewPanel.
178 | - base, a relative path to \ in html page.
179 | - page, a path to html file.
180 | - context, vscode.ExtensionContext.
181 | - messageMappings, MesssageMaping array defined, check examples in [home.ts](example/src/home.ts).
182 |
183 | ## Requirements
184 |
185 | vscode-page is a tool for [vscode](https://code.visualstudio.com/) extension development and uses [handlebars.js](https://www.npmjs.com/package/handlebars) as its template engine.
186 |
187 | So, please install **vscode** and **handlebars** first.
188 |
189 | ## Development
190 |
191 | For local debugging, please run the following command under the directory of vscode-page project:
192 |
193 | ```shell
194 | npm link
195 | ```
196 |
197 | Then, in the project using vscode-page, please run the following command:
198 |
199 | ```shell
200 | npm link vscode-page
201 | ```
202 |
203 | NOTE:
204 |
205 | The linked package in application will use its own node_modules, so if you defined your own handlebars helper in application, vscode-page can not find it.
206 |
207 | ```shell
208 | app
209 | |- node_modules
210 | |- vscode-page <-- project linked by "npm link"
211 | | ├─ node_modules
212 | | | |- handlebars.js <-- used by vscode-page
213 | |
214 | |- handlebars.js <-- you defined helper in it
215 | ```
216 |
217 | I can not find an easy way to fix it, only find the following steps. If you have any good idea, please let me know.
218 |
219 | - "npm pack" in vscode-page project.
220 | - "npm install local-package" in your application.
221 |
222 | ## Resources
223 |
224 | - [使用 vscode-page 简化 vscode 插件的 Webview 开发](https://blog.dteam.top/posts/2020-03/simplify-vscode-webview-development-with-vscode-page.html)
225 | - [Simplifying VS Code Webview Development with vscode-page](https://dev.to/foxgem/simplifying-vs-code-webview-development-with-vscode-page-13c3)
226 |
227 | ## Known Issues
228 |
229 | Please visit [issues](https://github.com/DTeam-Top/vscode-page/issues) page to submit new issues or check known issues.
230 |
231 | ## Release Notes
232 |
233 | ### 0.0.1
234 |
235 | First release.
236 |
237 | ## License
238 |
239 | vscode-page is released under the Apache License 2.0 license.
240 |
--------------------------------------------------------------------------------
/example/src/home.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from "vscode";
2 | import { MesssageMaping } from "vscode-page";
3 | import * as handlebars from "handlebars";
4 |
5 | handlebars.registerHelper("formatDate", function(dateTime) {
6 | return new Date(dateTime).toLocaleDateString();
7 | });
8 |
9 | function loadFromHome() {
10 | return {
11 | repositories: [
12 | {
13 | name: "repo1",
14 | options: {
15 | accessKeyId: "...",
16 | accessKeySecret: "...",
17 | bucket: "...",
18 | region: "..."
19 | },
20 | type: "oss"
21 | },
22 | {
23 | name: "repo2",
24 | options: { accessToken: "...", root: "..." },
25 | type: "dropbox"
26 | }
27 | ],
28 | extensionInstalled: [
29 | {
30 | extId: "dteam.my-ext",
31 | version: "0.0.1",
32 | describe: "my-ext",
33 | enabled: true,
34 | repository: "repo1"
35 | }
36 | ]
37 | };
38 | }
39 |
40 | function listExtensions(repo: string) {
41 | return [
42 | {
43 | extId: "dteam.my-ext",
44 | currentVersion: "0.0.1",
45 | icon: "",
46 | describe: "my-ext",
47 | dateCreated: "2020-02-28",
48 | lastUpdate: "2020-02-29"
49 | },
50 | {
51 | extId: "dteam.another-ext",
52 | currentVersion: "0.0.2",
53 | icon:
54 | "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAMAAAC/MqoPAAAAz1BMVEUAAADUBy/DDi7dAzDdAzDdAzDdAzDDDi7DDi7DDi7dAzDdAzDdAzDDDi7DDi7DDi7dAzDdAzDdAzDDDi7DDi7DDi7dAzDdAzDDDi7DDi7dAzDdAzDDDi7DDi7dAzDDDi7fEz3HHTvugZjhh5f97/L78PLqYn7////aaHz74OX44eXmQmTSSmL3wMvww8vhI0rLLEjyobHppbHdAzDDDi7jMlfOO1XoUnHWWW/50Nj00tjscYvdd4nwkaTllqT0sL7stL7hRGPXBjDWBi/FDS4+JsiBAAAARXRSTlMAMDAwj9///9+PIHDPz3AgEGC/v2AQUK+vUJ/v75+AgP////////////////////////9AQP//////////////////r6+TKVt1AAAH7ElEQVR4AezUtaHDUBTA0I9mZtx/zHDMWOY+nQ3U6AsAAAAAAAAAAAAA8Em+f9Ts/v3713TDVK7esh3tRr9xPV+d7iCMtCf9KU5SJcKzXOvonaIU313VmjZK7zRtKXtsY/qI1OlZ9rN7Jb2rlza9IHS0JfoSV9D0wlxboa8oElljO5HeTU/C2E6kC5heN7Yz6QKm143tTLqA6QXrYzub/pxeKmFsV2buQllxZQ3DcJZ1jwuMS7AYGmx84Jy97/+exjNGWLv+zvst+O7gKfnrha6Kna4/ethhq9wUvdIf99G7EV8407xp1zpHevTuff8JrqN//3H/8PgPG0/njx5/2Hg6f/T4w8bTj/bo3ahKNWjdXpC76ty7B/9vMXz9Qbic+0cTOGz2JanRChw94LC55svyvPDNd5VH7+zrQQc2zPORJ/bi5ekhD5t94/zLJoAcOHrEYTNs+pU+M/CAowccNmBl/m1zD646evxhQ7f4Tl96cvzRW1WHjVs3/7HfswY6emv+v0Vy/Yo+oOnUP5rVT1F8SUVPeTnz8/bMaZZV8ipr+J1GDSeiD3/RRyJ61HTW+2bImWoTifxFY3pLQp/+Tp9J6G2eDuZMtflx0mMFffEnfamgd0g6nzNk1vD0R8qcUWZN86BdKXNGmTXr5jknzBlp1gC/4YQ5I82aqPkuZDkjzZprAL0lyxlp1rQB+mNY/iqv3WuY/gSgx6qc0WZNB6DflDWstGbvAPSVKGfEWbM+Ono32UdPezAdmCZn1FkTERPlDJ81PP0WKH+TX7K3oPw2Qm8pckadNW2Efi7IGXnWXEfosSBn5FnTQej3+ZzRZ80DhL7ic0afNWuEfsbnjD5rTiNkfM7osyZi9pzOGX3WvIDoLTpn9FnTJul8zvBZw9NjOmf0WdNh6XzOLJZs1vD0R6qcGU9UWfMUoq9EOfPO+feirFlD9HuinMmcL4CsYZ9e+Kb5sGtMus730nxnH4mioXYhyZmNc95vJVlzDaO3JA1bfqXPJTXbxuiPFTkzdV/pfqbImicYPVa8ML75Tn+reHvsYPSbgpwZuu90PxJkzR2MvhLkTL+iDwRZsz4a+qZG163ovXx3W4AOjc+ZhavofslnTcQNz5l8/Is+ybms4em36Jx5537R/Xs6a26D9BadM9nv9ILOmjZIfwbnTNL9nd5L4ax5CdJjOGcW7ne6X8JZ0wHp9+HHpvJP+hx+hHoA0ldszkzdn3Q/Y7NmDdLP2JzJ/qYXbNacRuDQnBnufrVghGZNRA7Nmf4ufUBlDU9vkY9N5S59Tj5CtVk6mDMLt0v3SyhreHoMPjaN6+gT8BGqw9K5nBm6OrofAVmD0YEHmP/VeLJ6epHv7v/804t9Kyxnkm49vZdiWbNG6Tewhl24erpfYjV7N0JH5Uxe7qPPcyprInYXzAtjle+79PqQH/BPL+a1oJzJ9tMLKGvaMP0xkzNDt5/uR0zWPIHpsZ3+ri7f6+n7Q/69nd6h6UjO5OVl9HkOZA1PXyE5s3CX0f0SyZo1TSdyJh9fTp/kQNbg9IjImaG7nO5HRNZE9Iicyf6LXgBZw9NvWXMG2wB9etE3zZCjj/RFQz7AZDm4wvj0Qi825gw4W9Z0cPp9W86gm9ieXuitbDmDzpQ1a5x+ZsoZeHP+6cUye85ws2RNdEh6N8fXOyi9pc8ZImvaB6UnPD09KD3W5wyRNR09nW9YpmYV9Ed8zlg24Z9e8KaZaugzumgMu6HPGSJr7kaC6XOGyJpIsQs+Z/isuSaht4Jzpj+u3z+TPRsEZ01bQn8cmjOJ27N/9wrS0Kx5IqHHoTmzsdO3oVnT0dMtOVPa6XN71ijpq8CcmTo73c8Cs2atpxtyJguhF/asEdKjsJxJXAjdp2FZE2kWljObMPrWnjVC+q2gnCnD6HN71tBPL4am6RuOXEU3HroBXzTIA0xiOHIV3XjoUvLpxbA4IGcSF0r3aUDWdET0+wE5swmnbwOy5oGIvgr42FAZTp8HfK5oLaKf2XNm6sLpfmbPmtNINPvHhrIm9ML+uaJINXPOJK4J3afmrJHRW8aGzTfN6NvcWLNtHd362FQ2o8+tj1A6emz8duLUNaP7mfErjJ0D0DPDkTPQC+MjlI7+yJYziWtK96kta57K6Ctbzmya07e2rFnL6Ddsj01lc/rc9gh1N5LNlDNT15zuZ6asiXS7sDw2ZQS9sDxCXRPSW4acSRxB96kha9pC+mNDzmwY+taQNU+E9NjwKeiSoc8NH5fuXDW97NctcwzdF4O6za+avvrcnl3Y6A5DQRS+PzMzF5FUMO/139KSeJmONdLe08EIvsR29+e9Of3n1TkdyXt6kI1OvtPP00CbX12n3zZBNzw6Tr/MokTV0m36qo5SbTtO0/uHYAO8k79ulHfy143yTv66Ud6J183VO/G6uXonWDfeu1P56WdWN9478brhtZYlp6+a4VTVKTW9X4dbi1OJ6ed1/DwD78Tr5uqdeN1cvROvm6t34nVz9U68bq7eidfN1Tvxurl6J0A3h6rxb0yfELrxLTo/nd5ndDPwTj66AeOP359+YYfzDZffm74CWTfwTrxurt6J183VO/G6uXonXjdX78Tr5uqdeN1cvROvm6t3ctYNGN9+ffoAGG7XcPdy+t5aN+BxWvxjsat3InTz79E7PekWQPbeyV83qOG//7PI/mhZlmVZlmVZlmVZlmXZPZmSvHpA7pEOAAAAAElFTkSuQmCC",
55 | describe: "another-ext",
56 | dateCreated: "2020-02-28",
57 | lastUpdate: "2020-02-29"
58 | }
59 | ];
60 | }
61 |
62 | function showExtension(extId: string, repo: string) {
63 | const list = listExtensions(repo);
64 | const extIndex = list.map(i => i.extId).indexOf(extId);
65 | if( extId === 'dteam.my-ext') {
66 | return {
67 | metadata: list[extIndex],
68 | readme:
69 | "# my-ext README\n\nThis is My ext. And its version is 0.0.1\n",
70 | changelog:
71 | '# My-Ext Change Log\n\n## 0.0.1\n\nAll notable changes to the "my-ext" extension will be documented in this file.\n\nCheck [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.\n\n## [Unreleased]\n\n- Initial release'
72 | }
73 | } else if( extId === 'dteam.another-ext') {
74 | return {
75 | metadata: list[extIndex],
76 | readme:
77 | "# another-ext README\n\nThis is another ext. And its version is 0.0.2\n",
78 | changelog:
79 | '# Another-Ext Change Log\n\n## 0.0.2\n\nHere we are.\n\n## 0.0.1\n\nAll notable changes to the "another-ext" extension will be documented in this file.\n\nCheck [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.\n\n## [Unreleased]\n\n- Initial release'
80 | };
81 | }
82 | return {};
83 | }
84 |
85 | export const messageMappings: MesssageMaping[] = [
86 | {
87 | command: "ready",
88 | handler: async () => {
89 | let result = loadFromHome();
90 | return {
91 | repositories: result.repositories,
92 | extensionInstalled: result.extensionInstalled,
93 | title: "Installed Extensions"
94 | };
95 | },
96 | templates: [
97 | {
98 | id: "repos",
99 | content: `
100 | {{#each repositories}}
101 |
106 | {{/each}}
107 | `
108 | },
109 | { id: "title", content: "{{title}}" },
110 | {
111 | id: "content",
112 | contentUrl: "pages/list_intalled.hb"
113 | }
114 | ]
115 | },
116 | {
117 | command: "listExtensions",
118 | handler: async parameters => {
119 | let result = await listExtensions(parameters.repo);
120 | let installedExtIds = (await loadFromHome()).extensionInstalled.map(
121 | extension => extension.extId
122 | );
123 | let finalResult = new Array();
124 | result.forEach(extensionMetadata => {
125 | finalResult.push({
126 | extension: extensionMetadata,
127 | installed: installedExtIds.some(id => id === extensionMetadata.extId)
128 | });
129 | });
130 |
131 | return {
132 | title: parameters.repo,
133 | extensions: finalResult
134 | };
135 | },
136 | templates: [
137 | { id: "title", content: "{{title}}" },
138 | {
139 | id: "content",
140 | contentUrl: "pages/list_extension.hb"
141 | }
142 | ]
143 | },
144 | {
145 | command: "showExtension",
146 | handler: async parameters => {
147 | let result = await showExtension(parameters.extId, parameters.repo);
148 | let readMe = (await vscode.commands.executeCommand(
149 | "markdown.api.render",
150 | result.readme
151 | )) as string;
152 | let changelog = (await vscode.commands.executeCommand(
153 | "markdown.api.render",
154 | result.changelog
155 | )) as string;
156 | return {
157 | title: `${parameters.repo} / ${parameters.extId}`,
158 | repo: parameters.repo,
159 | details: result,
160 | readMe: readMe,
161 | changelog: changelog,
162 | installed: parameters.installed
163 | };
164 | },
165 | templates: [
166 | { id: "title", content: "{{title}}" },
167 | {
168 | id: "content",
169 | contentUrl: "pages/detail_extension.hb"
170 | }
171 | ]
172 | },
173 | {
174 | command: "installExtension",
175 | handler: async parameters => {}
176 | },
177 | {
178 | command: "loadRepositories",
179 | handler: async () => {
180 | let result = await loadFromHome();
181 | let example = [
182 | {
183 | name: "repo1",
184 | type: "oss",
185 | options: {
186 | accessKeyId: "...",
187 | accessKeySecret: "...",
188 | bucket: "...",
189 | region: "..."
190 | }
191 | },
192 | {
193 | name: "repo2",
194 | type: "dropbox",
195 | options: {
196 | password: "...",
197 | user: "..."
198 | }
199 | }
200 | ];
201 | return {
202 | repositories: JSON.stringify(result.repositories, undefined, 4),
203 | title: "Repositories Setting",
204 | example: JSON.stringify(example, undefined, 2)
205 | };
206 | },
207 | templates: [
208 | { id: "title", content: "{{title}}" },
209 | {
210 | id: "content",
211 | contentUrl: "pages/setting.hb"
212 | }
213 | ]
214 | },
215 | {
216 | command: "submitRepositories",
217 | handler: async parameters => {
218 | vscode.window.showInformationMessage("Repositories setting is updated.");
219 | },
220 | forward: "ready"
221 | },
222 | {
223 | command: "openExtension",
224 | handler: async parameters => {
225 | vscode.commands.executeCommand("extension.open", parameters.extId);
226 | }
227 | }
228 | ];
229 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/example/pages/shared/popper.js/popper.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) Federico Zivolo 2019
3 | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
4 | */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1=o.clientWidth&&n>=o.clientHeight}),l=0a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-us[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)f(l.top)||'bottom'===n&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.rightwindow.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge});
5 | //# sourceMappingURL=popper.min.js.map
--------------------------------------------------------------------------------
/example/pages/shared/bootstrap/js/bootstrap.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v4.4.1 (https://getbootstrap.com/)
3 | * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */
6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t=t||self).bootstrap={},t.jQuery,t.Popper)}(this,function(t,g,u){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)g(this._element).one(Y.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Se,popperConfig:null},Fe="show",Ue="out",We={HIDE:"hide"+Oe,HIDDEN:"hidden"+Oe,SHOW:"show"+Oe,SHOWN:"shown"+Oe,INSERTED:"inserted"+Oe,CLICK:"click"+Oe,FOCUSIN:"focusin"+Oe,FOCUSOUT:"focusout"+Oe,MOUSEENTER:"mouseenter"+Oe,MOUSELEAVE:"mouseleave"+Oe},qe="fade",Me="show",Ke=".tooltip-inner",Qe=".arrow",Be="hover",Ve="focus",Ye="click",ze="manual",Xe=function(){function i(t,e){if("undefined"==typeof u)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=g(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(g(this.getTipElement()).hasClass(Me))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),g.removeData(this.element,this.constructor.DATA_KEY),g(this.element).off(this.constructor.EVENT_KEY),g(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&g(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===g(this.element).css("display"))throw new Error("Please use show on visible elements");var t=g.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){g(this.element).trigger(t);var n=_.findShadowRoot(this.element),i=g.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=_.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&g(o).addClass(qe);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();g(o).data(this.constructor.DATA_KEY,this),g.contains(this.element.ownerDocument.documentElement,this.tip)||g(o).appendTo(l),g(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new u(this.element,o,this._getPopperConfig(a)),g(o).addClass(Me),"ontouchstart"in document.documentElement&&g(document.body).children().on("mouseover",null,g.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,g(e.element).trigger(e.constructor.Event.SHOWN),t===Ue&&e._leave(null,e)};if(g(this.tip).hasClass(qe)){var h=_.getTransitionDurationFromElement(this.tip);g(this.tip).one(_.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){function e(){n._hoverState!==Fe&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),g(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()}var n=this,i=this.getTipElement(),o=g.Event(this.constructor.Event.HIDE);if(g(this.element).trigger(o),!o.isDefaultPrevented()){if(g(i).removeClass(Me),"ontouchstart"in document.documentElement&&g(document.body).children().off("mouseover",null,g.noop),this._activeTrigger[Ye]=!1,this._activeTrigger[Ve]=!1,this._activeTrigger[Be]=!1,g(this.tip).hasClass(qe)){var r=_.getTransitionDurationFromElement(i);g(i).one(_.TRANSITION_END,e).emulateTransitionEnd(r)}else e();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Pe+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(g(t.querySelectorAll(Ke)),this.getTitle()),g(t).removeClass(qe+" "+Me)},t.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=we(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?g(e).parent().is(t)||t.empty().append(e):t.text(g(e).text())},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t=t||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},t._getPopperConfig=function(t){var e=this;return l({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Qe},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},{},this.config.popperConfig)},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=l({},t.offsets,{},e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:_.isElement(this.config.container)?g(this.config.container):g(document).find(this.config.container)},t._getAttachment=function(t){return Re[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)g(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==ze){var e=t===Be?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Be?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;g(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),this._hideModalHandler=function(){i.element&&i.hide()},g(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==t||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Ve:Be]=!0),g(e.getTipElement()).hasClass(Me)||e._hoverState===Fe?e._hoverState=Fe:(clearTimeout(e._timeout),e._hoverState=Fe,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===Fe&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Ve:Be]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=Ue,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===Ue&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){var e=g(this.element).data();return Object.keys(e).forEach(function(t){-1!==je.indexOf(t)&&delete e[t]}),"number"==typeof(t=l({},this.constructor.Default,{},e,{},"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),_.typeCheckConfig(Ae,t,this.constructor.DefaultType),t.sanitize&&(t.template=we(t.template,t.whiteList,t.sanitizeFn)),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Le);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(g(t).removeClass(qe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=g(this).data(Ne),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),g(this).data(Ne,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return xe}},{key:"NAME",get:function(){return Ae}},{key:"DATA_KEY",get:function(){return Ne}},{key:"Event",get:function(){return We}},{key:"EVENT_KEY",get:function(){return Oe}},{key:"DefaultType",get:function(){return He}}]),i}();g.fn[Ae]=Xe._jQueryInterface,g.fn[Ae].Constructor=Xe,g.fn[Ae].noConflict=function(){return g.fn[Ae]=ke,Xe._jQueryInterface};var $e="popover",Ge="bs.popover",Je="."+Ge,Ze=g.fn[$e],tn="bs-popover",en=new RegExp("(^|\\s)"+tn+"\\S+","g"),nn=l({},Xe.Default,{placement:"right",trigger:"click",content:"",template:'