未验证 提交 5026160f 编写于 作者: F Fatih Acet

Show default Vue app as a webview when sidebar links clicked.

上级 bc6c6e51
......@@ -20,7 +20,7 @@ class DataProvider {
issues.forEach(issue => {
const title = `${this.issuableSign}${issue.iid} · ${issue.title}`;
items.push(new SidebarTreeItem(title, issue.web_url));
items.push(new SidebarTreeItem(title, issue));
});
} else {
items.push(new SidebarTreeItem(this.noItemText));
......
const fs = require('fs');
const path = require('path');
const vscode = require('vscode');
const openers = require('./openers');
const tokenInput = require('./token_input');
......@@ -7,6 +9,7 @@ const searchInput = require('./search_input');
const snippetInput = require('./snippet_input');
const sidebar = require('./sidebar');
const ciConfigValidator = require('./ci_config_validator');
const webviewController = require('./webview_controller');
const IssuableDataProvider = require('./data_providers/issuable').DataProvider;
const CurrentBranchDataProvider = require('./data_providers/current_branch').DataProvider;
......@@ -78,6 +81,7 @@ const registerCommands = () => {
'gl.createSnippet': snippetInput.show,
'gl.validateCIConfig': ciConfigValidator.validate,
'gl.refreshSidebar': sidebar.refresh,
'gl.showRichContent': webviewController.create,
};
Object.keys(commands).forEach(cmd => {
......@@ -88,6 +92,7 @@ const registerCommands = () => {
};
const init = () => {
webviewController.addDeps(context);
tokenService.init(context);
};
......
const vscode = require('vscode');
class SidebarTreeItem extends vscode.TreeItem {
constructor(title, url) {
constructor(title, data) {
super(title);
if (url) {
if (data) {
this.command = {
command: 'vscode.open',
arguments: [vscode.Uri.parse(url)],
};
command: 'gl.showRichContent',
arguments: [data],
}
}
}
}
......
> 1%
last 2 versions
not ie <= 8
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
# webview
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn run serve
```
### Compiles and minifies for production
```
yarn run build
```
### Run your unit tests
```
yarn run test:unit
```
module.exports = {
presets: [
'@vue/app'
]
}
{
"name": "webview",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"vue": "^2.5.17"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.0.1",
"@vue/cli-plugin-unit-mocha": "^3.0.1",
"@vue/cli-service": "^3.0.1",
"@vue/test-utils": "^1.0.0-beta.20",
"chai": "^4.1.2",
"node-sass": "^4.9.0",
"sass-loader": "^7.0.1",
"vue-template-compiler": "^2.5.17"
}
}
module.exports = {
plugins: {
autoprefixer: {}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- <meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https:; script-src 'nonce-{{nonce}}'; style-src 'nonce-{{nonce}}';"> -->
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https:; script-src 'nonce-{{nonce}}' 'unsafe-eval'; style-src 'unsafe-inline';">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>GitLab Workflow</title>
</head>
<body>
<div id="app"></div>
<script nonce="{{nonce}}" src="{{devScriptUri}}"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https:; script-src 'nonce-{{nonce}}'; style-src 'nonce-{{nonce}}';">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>GitLab Workflow</title>
<link nonce="{{nonce}}" href="{{styleUri}}" rel="stylesheet" type="text/css">
</head>
<body>
<div id="app"></div>
<script nonce="{{nonce}}" src="{{vendorUri}}"></script>
<script nonce="{{nonce}}" src="{{appScriptUri}}"></script>
</body>
</html>
<template>
<div id="app">
<img src="#1" alt="" />
<HelloWorld msg="Welcome to VSCode extension 2" />
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>
<style lang="scss">
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
margin-top: 60px;
}
</style>
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" target="_blank" rel="noopener">unit-mocha</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
import { expect } from 'chai'
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
const wrapper = shallowMount(HelloWorld, {
propsData: { msg }
})
expect(wrapper.text()).to.include(msg)
})
})
module.exports = {
filenameHashing: false,
}
此差异已折叠。
const fs = require('fs');
const path = require('path');
const vscode = require('vscode');
let context = null;
const addDeps = (ctx) => {
context = ctx;
}
const getNonce = () => {
let text = "";
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < 32; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
const getResources = () => {
const paths = {
appScriptUri: 'src/webview/dist/js/app.js',
vendorUri: 'src/webview/dist/js/chunk-vendors.js',
styleUri: 'src/webview/dist/css/app.css',
devScriptUri: 'src/webview/dist/app.js',
}
Object.keys(paths).forEach((key) => {
const uri = vscode.Uri.file(path.join(context.extensionPath, paths[key]));
paths[key] = uri.with({ scheme: 'vscode-resource' });
});
return paths;
}
async function create(issuable) {
const panel = vscode.window.createWebviewPanel('glWorkflow', 'GL Workflow', vscode.ViewColumn.One, {
enableScripts: true,
localResourceRoots: [
vscode.Uri.file(path.join(context.extensionPath, 'src'))
]
});
const isDev = !(fs.existsSync(path.join(context.extensionPath, 'src/webview/dist/js/app.js')));
const indexPath = isDev ? 'src/webview/public/dev.html' : 'src/webview/public/index.html';
const { appScriptUri, vendorUri, styleUri, devScriptUri } = getResources();
let html = fs.readFileSync(path.join(context.extensionPath, indexPath), 'UTF-8');
html = html.replace(/{{nonce}}/gm, getNonce())
.replace('{{styleUri}}', styleUri)
.replace('{{vendorUri}}', vendorUri)
.replace('{{appScriptUri}}', appScriptUri)
.replace('{{devScriptUri}}', devScriptUri);
panel.webview.html = html;
}
exports.addDeps = addDeps;
exports.create = create;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册