Skip to content

Commit

Permalink
feat: allow to include shared styles (#41)
Browse files Browse the repository at this point in the history
* feat: allow to include shared styles

* feat: watch the chages for shared styles

* refactor: change the injecting position of shared style
  • Loading branch information
ktsn committed Jun 29, 2018
1 parent 90c47f5 commit 6b07626
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 25 deletions.
11 changes: 11 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@
"onCommand:extension.openVueDesigner"
],
"contributes": {
"configuration": {
"type": "object",
"title": "Vue Designer configuration",
"properties": {
"vueDesigner.sharedStyles": {
"type": "array",
"default": [],
"description": "Path to css files which will be loaded globally in the preview"
}
}
},
"commands": [
{
"command": "extension.openVueDesigner",
Expand Down
7 changes: 7 additions & 0 deletions src/message/bus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,25 @@ export function observeServerEvents(
activeUri: string | undefined
): void {
let lastActiveUri: string | undefined = activeUri
let sharedStyle: string = ''

const vueFileToPayload = (vueFile: VueFile) => {
return _vueFileToPayload(vueFile, assetResolver)
}

bus.on('initClient', () => {
bus.emit('initProject', mapValues(vueFiles, vueFileToPayload))
bus.emit('initSharedStyle', sharedStyle)
if (lastActiveUri) {
bus.emit('changeDocument', lastActiveUri)
}
})

bus.on('loadSharedStyle', style => {
sharedStyle = style
bus.emit('initSharedStyle', style)
})

bus.on('selectNode', payload => {
const vueFile = vueFiles[payload.uri]
if (!vueFile || !vueFile.template || payload.templatePath.length === 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/message/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { VueFilePayload } from '../parser/vue-file'

export interface Events {
initClient: undefined
loadSharedStyle: string
selectNode: {
uri: string
templatePath: number[]
Expand Down Expand Up @@ -44,6 +45,7 @@ export interface Events {

export interface Commands {
initProject: Record<string, VueFilePayload>
initSharedStyle: string
changeDocument: string
highlightEditor: {
uri: string
Expand Down
7 changes: 6 additions & 1 deletion src/payload.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { VueFilePayload } from './parser/vue-file'
import { DeclarationForUpdate, DeclarationForAdd } from './parser/style/types'

export type ServerPayload = InitProject | ChangeDocument
export type ServerPayload = InitProject | InitSharedStyle | ChangeDocument
export type ClientPayload =
| SelectNode
| AddNode
Expand All @@ -14,6 +14,11 @@ export interface InitProject {
vueFiles: Record<string, VueFilePayload>
}

export interface InitSharedStyle {
type: 'InitSharedStyle'
style: string
}

export interface ChangeDocument {
type: 'ChangeDocument'
uri: string
Expand Down
4 changes: 4 additions & 0 deletions src/server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ export function wsCommandEmiter(
send({ type: 'InitProject', vueFiles: payload })
})

observe('initSharedStyle', payload => {
send({ type: 'InitSharedStyle', style: payload })
})

observe('changeDocument', payload => {
send({ type: 'ChangeDocument', uri: payload })
})
Expand Down
4 changes: 3 additions & 1 deletion src/view/components/PageMain.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
:width="width"
:height="height"
:scale="scale"
:shared-style="sharedStyle"
@select="select"
@dragover="setDraggingPlace"
@add="applyDraggingElement"
Expand Down Expand Up @@ -113,7 +114,8 @@ export default Vue.extend({
...projectMapper.mapState({
uri: 'currentUri',
selectedPath: 'selectedPath',
matchedRules: 'matchedRules'
matchedRules: 'matchedRules',
sharedStyle: 'sharedStyle'
}),
...viewportMapper.mapState(['width', 'height', 'scale']),
Expand Down
5 changes: 5 additions & 0 deletions src/view/components/Renderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
:width="width"
:height="height"
:scale="scale"
:shared-style="sharedStyle"
@resize="$emit('resize', arguments[0])"
@zoom="$emit('zoom', arguments[0])"
>
Expand Down Expand Up @@ -71,6 +72,10 @@ export default Vue.extend({
scale: {
type: Number,
required: true
},
sharedStyle: {
type: String,
required: true
}
},
Expand Down
7 changes: 7 additions & 0 deletions src/view/components/Viewport.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
:style="viewportStyle"
@resize="$emit('resize', arguments[0])"
>
<!-- Hack for avoiding template compile error of style elements -->
<div is="style" :text-content.prop="sharedStyle" />

<div class="viewport">
<slot />
</div>
Expand Down Expand Up @@ -43,6 +46,10 @@ export default Vue.extend({
scale: {
type: Number,
required: true
},
sharedStyle: {
type: String,
required: true
}
},
Expand Down
3 changes: 3 additions & 0 deletions src/view/store/modules/project/project-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export class ProjectActions extends Actions<
})
this.matchSelectedNodeWithStyles()
break
case 'InitSharedStyle':
this.mutations.setSharedStyle(data.style)
break
case 'ChangeDocument':
this.mutations.changeDocument(data.uri)
break
Expand Down
10 changes: 5 additions & 5 deletions src/view/store/modules/project/project-getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ export class ProjectGetters extends Getters<ProjectState>() {
const pathEls = doc.uri.split('/')
const displayName = pathEls[pathEls.length - 1].replace(/\..*$/, '')

const styleCodes = doc.styles.reduce<string[]>((acc, style) => {
return acc.concat(genStyle(addScopeToStyle(style, doc.scopeId)))
}, [])

return {
uri: doc.uri,
displayName,
template: doc.template && addScopeToTemplate(doc.template, doc.scopeId),
props: doc.props,
data: doc.data,
childComponents: doc.childComponents,
styleCode: doc.styles
.reduce<string[]>((acc, style) => {
return acc.concat(genStyle(addScopeToStyle(style, doc.scopeId)))
}, [])
.join('\n')
styleCode: styleCodes.join('\n')
}
})
}
Expand Down
4 changes: 4 additions & 0 deletions src/view/store/modules/project/project-mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export class ProjectMutations extends Mutations<ProjectState>() {
}
}

setSharedStyle(style: string): void {
this.state.sharedStyle = style
}

setDraggingUri(uri: string | undefined): void {
this.state.draggingUri = uri
}
Expand Down
1 change: 1 addition & 0 deletions src/view/store/modules/project/project-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DocumentScope } from './types'
export class ProjectState {
documents: Record<string, VueFilePayload> = {}
documentScopes: Record<string, DocumentScope> = {}
sharedStyle = ''
currentUri: string | undefined = undefined
draggingUri: string | undefined = undefined
selectedPath: number[] = []
Expand Down
78 changes: 78 additions & 0 deletions src/vscode/watcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import * as vscode from 'vscode'
import * as path from 'path'

export class Watcher extends vscode.Disposable {
private sharedStyleUris: vscode.Uri[]
private innerWatcher: vscode.FileSystemWatcher

constructor(rootPath: string) {
super(() => {
this.innerWatcher.dispose()
})

const config = vscode.workspace.getConfiguration('vueDesigner')

this.sharedStyleUris = (config.get<string[]>('sharedStyles') || []).map(
stylePath => {
return vscode.Uri.file(path.join(rootPath, stylePath))
}
)

const pattern = new vscode.RelativePattern(rootPath, '**/*.{vue,css}')
this.innerWatcher = vscode.workspace.createFileSystemWatcher(pattern)
}

onDidCreateComponent(
fn: (uri: vscode.Uri, doc: vscode.TextDocument) => void
): void {
this.innerWatcher.onDidCreate(this.createVueListener(fn))
}

onDidChangeComponent(
fn: (uri: vscode.Uri, doc: vscode.TextDocument) => void
): void {
this.innerWatcher.onDidChange(this.createVueListener(fn))
}

onDidDeleteComponent(fn: (uri: vscode.Uri) => void): void {
this.innerWatcher.onDidDelete(fn)
}

onDidChangeSharedStyle(fn: (style: string) => void): void {
const uris = this.sharedStyleUris.map(uri => uri.toString())

const interpolate = (uri: vscode.Uri): void => {
if (uris.indexOf(uri.toString()) < 0) {
return
}

Promise.all(
this.sharedStyleUris.map(uri => {
return vscode.workspace
.openTextDocument(uri)
.then(doc => doc.getText(), () => '')
})
).then(styles => {
fn(styles.join('\n'))
})
}

const w = this.innerWatcher
w.onDidCreate(interpolate)
w.onDidChange(interpolate)
w.onDidDelete(interpolate)
}

private createVueListener(
fn: (uri: vscode.Uri, doc: vscode.TextDocument) => void
): (uri: vscode.Uri) => void {
return uri => {
if (path.extname(uri.fsPath) !== '.vue') {
return
}
vscode.workspace.openTextDocument(uri).then(doc => {
fn(uri, doc)
})
}
}
}
49 changes: 34 additions & 15 deletions src/vue-designer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as vscode from 'vscode'
import * as path from 'path'
import { AddressInfo } from 'net'
import { CommandEmitter, MessageBus, EventObserver } from 'meck'
import {
Expand All @@ -11,6 +12,7 @@ import { VueFile } from './parser/vue-file'
import { Commands, Events } from './message/types'
import { observeServerEvents } from './message/bus'
import { AssetResolver } from './asset-resolver'
import { Watcher } from './vscode/watcher'

function createHighlight(): vscode.TextEditorDecorationType {
return vscode.window.createTextEditorDecorationType({
Expand All @@ -20,8 +22,10 @@ function createHighlight(): vscode.TextEditorDecorationType {

function createVSCodeEventObserver(): EventObserver<Events> {
const folders = vscode.workspace.workspaceFolders
const pattern = folders && new vscode.RelativePattern(folders[0], '**/*.vue')
const watcher = pattern && vscode.workspace.createFileSystemWatcher(pattern)
const watcher = folders && new Watcher(folders[0].uri.fsPath)

const config = vscode.workspace.getConfiguration('vueDesigner')
const sharedStylePaths = config.get<string[]>('sharedStyles') || []

return new EventObserver(emit => {
vscode.window.onDidChangeActiveTextEditor(editor => {
Expand All @@ -42,27 +46,27 @@ function createVSCodeEventObserver(): EventObserver<Events> {
})

if (watcher) {
watcher.onDidCreate(uri => {
vscode.workspace.openTextDocument(uri).then(document => {
emit('addDocument', {
uri: uri.toString(),
code: document.getText()
})
watcher.onDidCreateComponent((uri, doc) => {
emit('addDocument', {
uri: uri.toString(),
code: doc.getText()
})
})

watcher.onDidChange(uri => {
vscode.workspace.openTextDocument(uri).then(document => {
emit('changeDocument', {
uri: uri.toString(),
code: document.getText()
})
watcher.onDidChangeComponent((uri, doc) => {
emit('changeDocument', {
uri: uri.toString(),
code: doc.getText()
})
})

watcher.onDidDelete(uri => {
watcher.onDidDeleteComponent(uri => {
emit('removeDocument', uri.toString())
})

watcher.onDidChangeSharedStyle(style => {
emit('loadSharedStyle', style)
})
}

vscode.workspace.findFiles('**/*.vue', '**/node_modules/**').then(uris => {
Expand All @@ -75,6 +79,21 @@ function createVSCodeEventObserver(): EventObserver<Events> {
})
})
})

if (folders) {
const rootPath = folders[0].uri.fsPath

Promise.all(
sharedStylePaths.map(stylePath => {
const fsStylePath = path.join(rootPath, stylePath)
return vscode.workspace
.openTextDocument(fsStylePath)
.then(doc => doc.getText(), () => '')
})
).then(sharedStyles => {
emit('loadSharedStyle', sharedStyles.join('\n'))
})
}
})
}

Expand Down
Loading

0 comments on commit 6b07626

Please sign in to comment.