@vuedx/vue-virtual-textdocument
Advanced tools
Comparing version 0.1.0-alpha.0 to 0.1.0-alpha.1
@@ -1,2 +0,2 @@ | ||
import { SFCDescriptor, SFCBlock } from '@vue/compiler-sfc'; | ||
import { SFCDescriptor, SFCBlock, CompilerError } from '@vue/compiler-sfc'; | ||
import { TextDocument, Range, Position, TextDocumentContentChangeEvent } from 'vscode-languageserver-textdocument'; | ||
@@ -53,3 +53,3 @@ import { URI } from 'vscode-uri'; | ||
get blocks(): SFCBlock[]; | ||
get parseErrors(): any[]; | ||
get parseErrors(): CompilerError[]; | ||
get content(): string; | ||
@@ -56,0 +56,0 @@ getText(range?: Range): string; |
@@ -1,2 +0,398 @@ | ||
import{parse as t}from"@vue/compiler-sfc";import{parse as e,stringify as r}from"querystring";import{TextDocument as s}from"vscode-languageserver-textdocument";import{URI as i}from"vscode-uri";const n="____";function o(t){return t.endsWith(".vue")}function a(t){return t.indexOf(".vue____")>0}function c(t){return/^[a-z-]+:\/\//i.test(t)?t:h.fsPathToUri(t)}class u{constructor(t,e){this.internal=t,this.container=e,this.uriObject=i.parse(this.internal.uri)}get version(){return this.internal.version}get languageId(){return this.internal.languageId}get lineCount(){return this.internal.lineCount}get uri(){return this.internal.uri}get fsPath(){return this.uriObject.fsPath}get content(){return this.getText()}getText(t){return this.internal.getText(t)}positionAt(t){return this.internal.positionAt(t)}offsetAt(t){return this.internal.offsetAt(t)}toJSON(){return{uri:this.uri,languageId:this.languageId,vertion:this.version,content:this.getText()}}static create(t,e,r,i,n){return new u(s.create(e,r,i,n),t)}static update(t,e,r){return t.internal=s.update(t.internal,e,r),t}}const l={script:"js",template:"vue-html",style:"css",docs:"md"};class h{constructor(t){this.internal=t,this._blocks=[],this._parseErrors=[],this.documents={},this.uriObject=i.parse(this.internal.uri),this.parse()}get version(){return this.internal.version}get languageId(){return this.internal.languageId}get lineCount(){return this.internal.lineCount}get uri(){return this.internal.uri}get fsPath(){return this.uriObject.fsPath}get descriptor(){return this._descriptor}get blocks(){return this._blocks}get parseErrors(){return this._parseErrors}get content(){return this.getText()}getText(t){return this.internal.getText(t)}positionAt(t){return this.internal.positionAt(t)}offsetAt(t){return this.internal.offsetAt(t)}blockAt(t){const e="number"==typeof t?t:this.offsetAt(t);return this._blocks.find(t=>t.loc.start.offset<=e&&e<=t.loc.end.offset)}parse(){const r=this.getText(),{descriptor:s,errors:i}=t(r,{sourceMap:!1,pad:"space",filename:this.fsPath}),n=Object.keys(this.documents);return this._descriptor=s,this._parseErrors=i,this._blocks=[s.script,s.template].filter(g),this._blocks=this._blocks.concat(s.styles).concat(s.customBlocks),this._blocks.sort((t,e)=>t.loc.start.offset-e.loc.start.offset),n.length&&n.forEach(t=>{const r=e(t);if(r&&"index"in r){const t=this._blocks[r.index];this.setBlockDocument(t,this.createBlockDocument(t))}}),s.script&&this.setBlockDocument(s.script,this.createBlockDocument(s.script)),s.template&&this.setBlockDocument(s.template,this.createBlockDocument(s.template)),this}createBlockDocument(t){if(!t)return null;const e=r(this.getSelectorFor(t)),s=this.getUriFor(t),i=function(t){switch(t.type){case"template":return d(t.lang)||"vue-html";case"script":return d(t.lang)||"javascript";case"style":return d(t.lang)||"css";default:return d(t.lang)||"text"}}(t),n=this.documents[e];return n&&n.uri===s&&n.languageId===i?u.update(n,[{text:t.content}],this.version):u.create(this,s,i,this.version,t.content)}all(){return Object.values(this.documents).filter(g)}forTS(){return Object.values(this.documents).filter(g).filter(t=>/^(typescript|javascript)$/.test(t.languageId))}getBlockDocument(t){if(!t)return;const e=this.getSelectorFor(t);if(!e)return;const s=r(e);if("index"in e&&!/^(script|template)$/.test(e.type)&&!this.documents[s]){const t=this.blocks[e.index];t&&this.setBlockDocument(t,this.createBlockDocument(t))}return this.documents[s]}setBlockDocument(t,e){const s=r(this.getSelectorFor(t));e?this.documents[s]=e:delete this.documents[s]}getUriFor(t){const e=this.getSelectorFor(t);return i.file(this.uriObject.path+"____"+("index"in e?`${e.type}__${e.index}`:e.type)+"."+this.getLanguageFor(t)).toString().replace(/^file/,"vue")}getSelectorFor(t){if(!t)return{type:"",index:-1};if("script"===t)return{type:"script"};if("template"===t)return{type:"template"};if("string"==typeof t){const e=p(t);if(!e)throw new Error("Malforated virtual document uri: "+t);return e.selector}if("index"in t)return t;switch(t.type){case"script":return{type:"script"};case"template":return{type:"template"};default:return{type:t.type,index:this.blocks.indexOf(t)}}}getLanguageFor(t){return t.lang||l[t.type]||"txt"}static create(t,e,r,i){if(!o(t))throw new Error("Not a .vue file: "+t);return new h(s.create(t,e,r,i))}static update(t,e,r){return t.internal=s.update(t.internal,e,r),t.parse()}static fsPathToUri(t){const e=i.file(t).toString();return a(t)?e.replace(/^[^:]+/,"vue"):e}}function p(t){const e=i.parse(c(t));if("vue"===e.scheme){const[t,r]=e.fsPath.split("____");if(!r.includes("."))throw new Error("Malformated virtual file uri.");const[s,n]=r.substr(0,r.lastIndexOf(".")).split("__");return{uri:i.file(t).toString(),selector:n?{type:s,index:parseInt(n,10)}:{type:s}}}return null}class m{constructor(t){this.resolve=t,this.map=new Map,this.lowerCaseNames=new Map}normalizeUri(t){const e=t.toLowerCase();return this.lowerCaseNames.get(e)||t}has(t){return this.map.has(this.normalizeUri(t))}get(t){return this.map.get(this.normalizeUri(t))||this.loadSync(t)}set(t,e){this.map.set(t,e),this.lowerCaseNames.set(t.toLowerCase(),t)}delete(t){return this.map.delete(this.normalizeUri(t))}all(){return Array.from(this.map.keys())}dispose(){this.map.clear()}loadSync(t){const e=this.resolve(t);return e&&this.set(t,e),e}}class f{constructor(t,e=(()=>!0)){this.resolve=t,this.useCaseSensitiveFileNames=e,this.map=new Map}normalizeUri(t){return this.useCaseSensitiveFileNames()?t:t.toLowerCase()}has(t){return this.map.has(this.normalizeUri(t))}get(t){return this.map.get(this.normalizeUri(t))||this.load(t)}set(t,e){this.map.set(this.normalizeUri(t),e)}delete(t){return this.map.delete(this.normalizeUri(t))}all(){return Array.from(this.map.keys())}dispose(){this.map.clear()}async load(t){const e=await this.resolve(t);return e&&this.map.set(this.normalizeUri(t),e),e}}function g(t){return null!=t}function d(t){switch(t){case"js":return"javascript";case"ts":return"typescript"}return t}export{f as AsyncDocumentStore,m as DocumentStore,u as VirtualTextDocument,h as VueTextDocument,c as asUri,a as isVirtualFile,o as isVueFile,p as parseVirtualFileUri,n as virtualFileNameSep}; | ||
import { parse } from '@vue/compiler-sfc'; | ||
import { baseCompile, baseParse } from '@vue/compiler-core'; | ||
import { parse as parse$1, stringify } from 'querystring'; | ||
import { TextDocument } from 'vscode-languageserver-textdocument'; | ||
import { URI } from 'vscode-uri'; | ||
// Vue File: foo.vue | ||
// Virtual Script File: foo.vue____script.js | ||
// Virtual Template File: foo.vue____template.vue-html | ||
// Virtual Render File: foo.vue____render.js | ||
// Virtual Style File: foo.vue____style__0.css | ||
const virtualFileNameSep = '____'; | ||
function isVueFile(fileName) { | ||
return fileName.endsWith('.vue'); | ||
} | ||
function isVirtualFile(fileName) { | ||
return fileName.indexOf('.vue' + virtualFileNameSep) > 0; | ||
} | ||
function asUri(fileNameOrUri) { | ||
if (/^[a-z-]+:\/\//i.test(fileNameOrUri)) | ||
return fileNameOrUri; | ||
return VueTextDocument.fsPathToUri(fileNameOrUri); | ||
} | ||
class VirtualTextDocument { | ||
constructor(internal, container) { | ||
this.internal = internal; | ||
this.container = container; | ||
this.uriObject = URI.parse(this.internal.uri); | ||
} | ||
get version() { | ||
return this.internal.version; | ||
} | ||
get languageId() { | ||
return this.internal.languageId; | ||
} | ||
get lineCount() { | ||
return this.internal.lineCount; | ||
} | ||
get uri() { | ||
return this.internal.uri; | ||
} | ||
get fsPath() { | ||
return this.uriObject.fsPath; | ||
} | ||
get content() { | ||
return this.getText(); | ||
} | ||
getText(range) { | ||
return this.internal.getText(range); | ||
} | ||
positionAt(offset) { | ||
return this.internal.positionAt(offset); | ||
} | ||
offsetAt(position) { | ||
return this.internal.offsetAt(position); | ||
} | ||
toJSON() { | ||
return { | ||
uri: this.uri, | ||
languageId: this.languageId, | ||
vertion: this.version, | ||
content: this.getText(), | ||
}; | ||
} | ||
static create(container, uri, languageId, version, content) { | ||
return new VirtualTextDocument(TextDocument.create(uri, languageId, version, content), container); | ||
} | ||
static update(document, changes, version) { | ||
document.internal = TextDocument.update(document.internal, changes, version); | ||
return document; | ||
} | ||
} | ||
const BlockLanguageMap = { | ||
script: 'js', | ||
template: 'vue-html', | ||
style: 'css', | ||
docs: 'md', | ||
}; | ||
class VueTextDocument { | ||
constructor(internal) { | ||
this.internal = internal; | ||
this._blocks = []; | ||
this._parseErrors = []; | ||
this.documents = {}; | ||
this.uriObject = URI.parse(this.internal.uri); | ||
this.parse(); | ||
} | ||
get version() { | ||
return this.internal.version; | ||
} | ||
get languageId() { | ||
return this.internal.languageId; | ||
} | ||
get lineCount() { | ||
return this.internal.lineCount; | ||
} | ||
get uri() { | ||
return this.internal.uri; | ||
} | ||
get fsPath() { | ||
return this.uriObject.fsPath; | ||
} | ||
get descriptor() { | ||
return this._descriptor; | ||
} | ||
get blocks() { | ||
return this._blocks; | ||
} | ||
get parseErrors() { | ||
return this._parseErrors; | ||
} | ||
get content() { | ||
return this.getText(); | ||
} | ||
getText(range) { | ||
return this.internal.getText(range); | ||
} | ||
positionAt(offset) { | ||
return this.internal.positionAt(offset); | ||
} | ||
offsetAt(position) { | ||
return this.internal.offsetAt(position); | ||
} | ||
blockAt(positionOrOffset) { | ||
const offset = typeof positionOrOffset === 'number' | ||
? positionOrOffset | ||
: this.offsetAt(positionOrOffset); | ||
return this._blocks.find((block) => block.loc.start.offset <= offset && offset <= block.loc.end.offset); | ||
} | ||
parse() { | ||
const source = this.getText(); | ||
const { descriptor, errors } = parse(source, { | ||
sourceMap: false, | ||
pad: 'space', | ||
filename: this.fsPath, | ||
compiler: { | ||
compile: baseCompile, | ||
parse: baseParse, | ||
}, | ||
}); | ||
const prevIds = Object.keys(this.documents); | ||
this._descriptor = descriptor; | ||
this._parseErrors = errors; | ||
this._blocks = [descriptor.script, descriptor.template].filter(isNotNull); | ||
this._blocks = this._blocks | ||
.concat(descriptor.styles) | ||
.concat(descriptor.customBlocks); | ||
this._blocks.sort((a, b) => a.loc.start.offset - b.loc.start.offset); | ||
if (prevIds.length) { | ||
prevIds.forEach((id) => { | ||
const selector = parse$1(id); | ||
if (selector && 'index' in selector) { | ||
const block = this._blocks[selector.index]; | ||
this.setBlockDocument(block, this.createBlockDocument(block)); | ||
} | ||
}); | ||
} | ||
if (descriptor.script) { | ||
this.setBlockDocument(descriptor.script, this.createBlockDocument(descriptor.script)); | ||
} | ||
if (descriptor.template) { | ||
this.setBlockDocument(descriptor.template, this.createBlockDocument(descriptor.template)); | ||
} | ||
return this; | ||
} | ||
createBlockDocument(block) { | ||
if (!block) | ||
return null; | ||
const id = stringify(this.getSelectorFor(block)); | ||
const uri = this.getUriFor(block); | ||
const languageId = getLanguageIdForBlock(block); | ||
const prevDocument = this.documents[id]; | ||
if (prevDocument) { | ||
if (prevDocument.uri === uri && prevDocument.languageId === languageId) { | ||
return VirtualTextDocument.update(prevDocument, [{ text: block.content }], this.version); | ||
} | ||
} | ||
return VirtualTextDocument.create(this, uri, languageId, this.version, block.content); | ||
} | ||
all() { | ||
return Object.values(this.documents).filter(isNotNull); | ||
} | ||
forTS() { | ||
return Object.values(this.documents) | ||
.filter(isNotNull) | ||
.filter((document) => /^(typescript|javascript)$/.test(document.languageId)); | ||
} | ||
getBlockDocument(block) { | ||
if (!block) | ||
return; | ||
const selector = this.getSelectorFor(block); | ||
if (!selector) | ||
return; | ||
const id = stringify(selector); | ||
if ('index' in selector && | ||
!/^(script|template)$/.test(selector.type) && | ||
!this.documents[id]) { | ||
const block = this.blocks[selector.index]; | ||
if (block) | ||
this.setBlockDocument(block, this.createBlockDocument(block)); | ||
} | ||
return this.documents[id]; | ||
} | ||
setBlockDocument(block, document) { | ||
const id = stringify(this.getSelectorFor(block)); | ||
if (document) { | ||
this.documents[id] = document; | ||
} | ||
else { | ||
delete this.documents[id]; | ||
} | ||
} | ||
getUriFor(block) { | ||
const selector = this.getSelectorFor(block); | ||
const uri = URI.file(this.uriObject.path + | ||
virtualFileNameSep + | ||
('index' in selector | ||
? `${selector.type}__${selector.index}` | ||
: selector.type) + | ||
'.' + | ||
this.getLanguageFor(block)); | ||
return uri.toString().replace(/^file/, 'vue'); | ||
} | ||
getSelectorFor(block) { | ||
if (!block) | ||
return { type: '', index: -1 }; | ||
if (block === 'script') { | ||
return { type: 'script' }; | ||
} | ||
else if (block === 'template') { | ||
return { type: 'template' }; | ||
} | ||
else if (typeof block === 'string') { | ||
const virtual = parseVirtualFileUri(block); | ||
if (!virtual) | ||
throw new Error(`Malforated virtual document uri: ${block}`); | ||
return virtual.selector; | ||
} | ||
else if ('index' in block) { | ||
return block; | ||
} | ||
else { | ||
switch (block.type) { | ||
case 'script': | ||
return { type: 'script' }; | ||
case 'template': | ||
return { type: 'template' }; | ||
default: | ||
return { | ||
type: block.type, | ||
index: this.blocks.indexOf(block), | ||
}; | ||
} | ||
} | ||
} | ||
getLanguageFor(block) { | ||
return (block.lang || | ||
BlockLanguageMap[block.type] || | ||
'txt'); | ||
} | ||
static create(uri, languageId, version, content) { | ||
if (!isVueFile(uri)) | ||
throw new Error(`Not a .vue file: ${uri}`); | ||
return new VueTextDocument(TextDocument.create(uri, languageId, version, content)); | ||
} | ||
static update(document, changes, version) { | ||
document.internal = TextDocument.update(document.internal, changes, version); | ||
return document.parse(); | ||
} | ||
static fsPathToUri(fsPath) { | ||
const uri = URI.file(fsPath).toString(); | ||
if (isVirtualFile(fsPath)) { | ||
return uri.replace(/^[^:]+/, 'vue'); | ||
} | ||
return uri; | ||
} | ||
} | ||
function parseVirtualFileUri(fileNameOrUri) { | ||
const uri = URI.parse(asUri(fileNameOrUri)); | ||
if (uri.scheme === 'vue') { | ||
const [container, selector] = uri.fsPath.split(virtualFileNameSep); | ||
if (!selector.includes('.')) | ||
throw new Error('Malformated virtual file uri.'); | ||
const [block, index] = selector | ||
.substr(0, selector.lastIndexOf('.')) | ||
.split('__'); | ||
return { | ||
// TODO: DO NOT ASSUME FILE SCHEME! | ||
uri: URI.file(container).toString(), | ||
selector: (index | ||
? { | ||
type: block, | ||
index: parseInt(index, 10), | ||
} | ||
: { type: block }), | ||
}; | ||
} | ||
return null; | ||
} | ||
class DocumentStore { | ||
constructor(resolve) { | ||
this.resolve = resolve; | ||
this.map = new Map(); | ||
this.lowerCaseNames = new Map(); | ||
} | ||
normalizeUri(uri) { | ||
const lower = uri.toLowerCase(); | ||
return this.lowerCaseNames.get(lower) || uri; | ||
} | ||
has(uri) { | ||
return this.map.has(this.normalizeUri(uri)); | ||
} | ||
get(uri) { | ||
return this.map.get(this.normalizeUri(uri)) || this.loadSync(uri); | ||
} | ||
set(uri, document) { | ||
this.map.set(uri, document); | ||
this.lowerCaseNames.set(uri.toLowerCase(), uri); | ||
} | ||
delete(uri) { | ||
return this.map.delete(this.normalizeUri(uri)); | ||
} | ||
all() { | ||
return Array.from(this.map.keys()); | ||
} | ||
dispose() { | ||
this.map.clear(); | ||
} | ||
loadSync(uri) { | ||
const document = this.resolve(uri); | ||
if (document) { | ||
this.set(uri, document); | ||
} | ||
return document; | ||
} | ||
} | ||
class AsyncDocumentStore { | ||
constructor(resolve, useCaseSensitiveFileNames = () => true) { | ||
this.resolve = resolve; | ||
this.useCaseSensitiveFileNames = useCaseSensitiveFileNames; | ||
this.map = new Map(); | ||
} | ||
normalizeUri(uri) { | ||
return this.useCaseSensitiveFileNames() ? uri : uri.toLowerCase(); | ||
} | ||
has(uri) { | ||
return this.map.has(this.normalizeUri(uri)); | ||
} | ||
get(uri) { | ||
return this.map.get(this.normalizeUri(uri)) || this.load(uri); | ||
} | ||
set(uri, document) { | ||
this.map.set(this.normalizeUri(uri), document); | ||
} | ||
delete(uri) { | ||
return this.map.delete(this.normalizeUri(uri)); | ||
} | ||
all() { | ||
return Array.from(this.map.keys()); | ||
} | ||
dispose() { | ||
this.map.clear(); | ||
} | ||
async load(uri) { | ||
const document = await this.resolve(uri); | ||
if (document) { | ||
this.map.set(this.normalizeUri(uri), document); | ||
} | ||
return document; | ||
} | ||
} | ||
function isNotNull(value) { | ||
return value != null; | ||
} | ||
function getLanguageIdForBlock(block) { | ||
switch (block.type) { | ||
case 'template': | ||
return getLanguageIdFromExtension(block.lang) || 'vue-html'; | ||
case 'script': | ||
return getLanguageIdFromExtension(block.lang) || 'javascript'; | ||
case 'style': | ||
return getLanguageIdFromExtension(block.lang) || 'css'; | ||
default: | ||
return getLanguageIdFromExtension(block.lang) || 'text'; | ||
} | ||
} | ||
function getLanguageIdFromExtension(ext) { | ||
switch (ext) { | ||
case 'js': | ||
return 'javascript'; | ||
case 'ts': | ||
return 'typescript'; | ||
} | ||
return ext; | ||
} | ||
export { AsyncDocumentStore, DocumentStore, VirtualTextDocument, VueTextDocument, asUri, isVirtualFile, isVueFile, parseVirtualFileUri, virtualFileNameSep }; | ||
//# sourceMappingURL=vue-virtual-textdocument.esm.js.map |
@@ -1,2 +0,410 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("@vue/compiler-sfc"),e=require("querystring"),r=require("vscode-languageserver-textdocument"),s=require("vscode-uri");function i(t){return t.endsWith(".vue")}function n(t){return t.indexOf(".vue____")>0}function o(t){return/^[a-z-]+:\/\//i.test(t)?t:u.fsPathToUri(t)}class a{constructor(t,e){this.internal=t,this.container=e,this.uriObject=s.URI.parse(this.internal.uri)}get version(){return this.internal.version}get languageId(){return this.internal.languageId}get lineCount(){return this.internal.lineCount}get uri(){return this.internal.uri}get fsPath(){return this.uriObject.fsPath}get content(){return this.getText()}getText(t){return this.internal.getText(t)}positionAt(t){return this.internal.positionAt(t)}offsetAt(t){return this.internal.offsetAt(t)}toJSON(){return{uri:this.uri,languageId:this.languageId,vertion:this.version,content:this.getText()}}static create(t,e,s,i,n){return new a(r.TextDocument.create(e,s,i,n),t)}static update(t,e,s){return t.internal=r.TextDocument.update(t.internal,e,s),t}}const c={script:"js",template:"vue-html",style:"css",docs:"md"};class u{constructor(t){this.internal=t,this._blocks=[],this._parseErrors=[],this.documents={},this.uriObject=s.URI.parse(this.internal.uri),this.parse()}get version(){return this.internal.version}get languageId(){return this.internal.languageId}get lineCount(){return this.internal.lineCount}get uri(){return this.internal.uri}get fsPath(){return this.uriObject.fsPath}get descriptor(){return this._descriptor}get blocks(){return this._blocks}get parseErrors(){return this._parseErrors}get content(){return this.getText()}getText(t){return this.internal.getText(t)}positionAt(t){return this.internal.positionAt(t)}offsetAt(t){return this.internal.offsetAt(t)}blockAt(t){const e="number"==typeof t?t:this.offsetAt(t);return this._blocks.find(t=>t.loc.start.offset<=e&&e<=t.loc.end.offset)}parse(){const r=this.getText(),{descriptor:s,errors:i}=t.parse(r,{sourceMap:!1,pad:"space",filename:this.fsPath}),n=Object.keys(this.documents);return this._descriptor=s,this._parseErrors=i,this._blocks=[s.script,s.template].filter(h),this._blocks=this._blocks.concat(s.styles).concat(s.customBlocks),this._blocks.sort((t,e)=>t.loc.start.offset-e.loc.start.offset),n.length&&n.forEach(t=>{const r=e.parse(t);if(r&&"index"in r){const t=this._blocks[r.index];this.setBlockDocument(t,this.createBlockDocument(t))}}),s.script&&this.setBlockDocument(s.script,this.createBlockDocument(s.script)),s.template&&this.setBlockDocument(s.template,this.createBlockDocument(s.template)),this}createBlockDocument(t){if(!t)return null;const r=e.stringify(this.getSelectorFor(t)),s=this.getUriFor(t),i=function(t){switch(t.type){case"template":return p(t.lang)||"vue-html";case"script":return p(t.lang)||"javascript";case"style":return p(t.lang)||"css";default:return p(t.lang)||"text"}}(t),n=this.documents[r];return n&&n.uri===s&&n.languageId===i?a.update(n,[{text:t.content}],this.version):a.create(this,s,i,this.version,t.content)}all(){return Object.values(this.documents).filter(h)}forTS(){return Object.values(this.documents).filter(h).filter(t=>/^(typescript|javascript)$/.test(t.languageId))}getBlockDocument(t){if(!t)return;const r=this.getSelectorFor(t);if(!r)return;const s=e.stringify(r);if("index"in r&&!/^(script|template)$/.test(r.type)&&!this.documents[s]){const t=this.blocks[r.index];t&&this.setBlockDocument(t,this.createBlockDocument(t))}return this.documents[s]}setBlockDocument(t,r){const s=e.stringify(this.getSelectorFor(t));r?this.documents[s]=r:delete this.documents[s]}getUriFor(t){const e=this.getSelectorFor(t);return s.URI.file(this.uriObject.path+"____"+("index"in e?`${e.type}__${e.index}`:e.type)+"."+this.getLanguageFor(t)).toString().replace(/^file/,"vue")}getSelectorFor(t){if(!t)return{type:"",index:-1};if("script"===t)return{type:"script"};if("template"===t)return{type:"template"};if("string"==typeof t){const e=l(t);if(!e)throw new Error("Malforated virtual document uri: "+t);return e.selector}if("index"in t)return t;switch(t.type){case"script":return{type:"script"};case"template":return{type:"template"};default:return{type:t.type,index:this.blocks.indexOf(t)}}}getLanguageFor(t){return t.lang||c[t.type]||"txt"}static create(t,e,s,n){if(!i(t))throw new Error("Not a .vue file: "+t);return new u(r.TextDocument.create(t,e,s,n))}static update(t,e,s){return t.internal=r.TextDocument.update(t.internal,e,s),t.parse()}static fsPathToUri(t){const e=s.URI.file(t).toString();return n(t)?e.replace(/^[^:]+/,"vue"):e}}function l(t){const e=s.URI.parse(o(t));if("vue"===e.scheme){const[t,r]=e.fsPath.split("____");if(!r.includes("."))throw new Error("Malformated virtual file uri.");const[i,n]=r.substr(0,r.lastIndexOf(".")).split("__");return{uri:s.URI.file(t).toString(),selector:n?{type:i,index:parseInt(n,10)}:{type:i}}}return null}function h(t){return null!=t}function p(t){switch(t){case"js":return"javascript";case"ts":return"typescript"}return t}exports.AsyncDocumentStore=class{constructor(t,e=(()=>!0)){this.resolve=t,this.useCaseSensitiveFileNames=e,this.map=new Map}normalizeUri(t){return this.useCaseSensitiveFileNames()?t:t.toLowerCase()}has(t){return this.map.has(this.normalizeUri(t))}get(t){return this.map.get(this.normalizeUri(t))||this.load(t)}set(t,e){this.map.set(this.normalizeUri(t),e)}delete(t){return this.map.delete(this.normalizeUri(t))}all(){return Array.from(this.map.keys())}dispose(){this.map.clear()}async load(t){const e=await this.resolve(t);return e&&this.map.set(this.normalizeUri(t),e),e}},exports.DocumentStore=class{constructor(t){this.resolve=t,this.map=new Map,this.lowerCaseNames=new Map}normalizeUri(t){const e=t.toLowerCase();return this.lowerCaseNames.get(e)||t}has(t){return this.map.has(this.normalizeUri(t))}get(t){return this.map.get(this.normalizeUri(t))||this.loadSync(t)}set(t,e){this.map.set(t,e),this.lowerCaseNames.set(t.toLowerCase(),t)}delete(t){return this.map.delete(this.normalizeUri(t))}all(){return Array.from(this.map.keys())}dispose(){this.map.clear()}loadSync(t){const e=this.resolve(t);return e&&this.set(t,e),e}},exports.VirtualTextDocument=a,exports.VueTextDocument=u,exports.asUri=o,exports.isVirtualFile=n,exports.isVueFile=i,exports.parseVirtualFileUri=l,exports.virtualFileNameSep="____"; | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
var compilerSfc = require('@vue/compiler-sfc'); | ||
var compilerCore = require('@vue/compiler-core'); | ||
var querystring = require('querystring'); | ||
var vscodeLanguageserverTextdocument = require('vscode-languageserver-textdocument'); | ||
var vscodeUri = require('vscode-uri'); | ||
// Vue File: foo.vue | ||
// Virtual Script File: foo.vue____script.js | ||
// Virtual Template File: foo.vue____template.vue-html | ||
// Virtual Render File: foo.vue____render.js | ||
// Virtual Style File: foo.vue____style__0.css | ||
const virtualFileNameSep = '____'; | ||
function isVueFile(fileName) { | ||
return fileName.endsWith('.vue'); | ||
} | ||
function isVirtualFile(fileName) { | ||
return fileName.indexOf('.vue' + virtualFileNameSep) > 0; | ||
} | ||
function asUri(fileNameOrUri) { | ||
if (/^[a-z-]+:\/\//i.test(fileNameOrUri)) | ||
return fileNameOrUri; | ||
return VueTextDocument.fsPathToUri(fileNameOrUri); | ||
} | ||
class VirtualTextDocument { | ||
constructor(internal, container) { | ||
this.internal = internal; | ||
this.container = container; | ||
this.uriObject = vscodeUri.URI.parse(this.internal.uri); | ||
} | ||
get version() { | ||
return this.internal.version; | ||
} | ||
get languageId() { | ||
return this.internal.languageId; | ||
} | ||
get lineCount() { | ||
return this.internal.lineCount; | ||
} | ||
get uri() { | ||
return this.internal.uri; | ||
} | ||
get fsPath() { | ||
return this.uriObject.fsPath; | ||
} | ||
get content() { | ||
return this.getText(); | ||
} | ||
getText(range) { | ||
return this.internal.getText(range); | ||
} | ||
positionAt(offset) { | ||
return this.internal.positionAt(offset); | ||
} | ||
offsetAt(position) { | ||
return this.internal.offsetAt(position); | ||
} | ||
toJSON() { | ||
return { | ||
uri: this.uri, | ||
languageId: this.languageId, | ||
vertion: this.version, | ||
content: this.getText(), | ||
}; | ||
} | ||
static create(container, uri, languageId, version, content) { | ||
return new VirtualTextDocument(vscodeLanguageserverTextdocument.TextDocument.create(uri, languageId, version, content), container); | ||
} | ||
static update(document, changes, version) { | ||
document.internal = vscodeLanguageserverTextdocument.TextDocument.update(document.internal, changes, version); | ||
return document; | ||
} | ||
} | ||
const BlockLanguageMap = { | ||
script: 'js', | ||
template: 'vue-html', | ||
style: 'css', | ||
docs: 'md', | ||
}; | ||
class VueTextDocument { | ||
constructor(internal) { | ||
this.internal = internal; | ||
this._blocks = []; | ||
this._parseErrors = []; | ||
this.documents = {}; | ||
this.uriObject = vscodeUri.URI.parse(this.internal.uri); | ||
this.parse(); | ||
} | ||
get version() { | ||
return this.internal.version; | ||
} | ||
get languageId() { | ||
return this.internal.languageId; | ||
} | ||
get lineCount() { | ||
return this.internal.lineCount; | ||
} | ||
get uri() { | ||
return this.internal.uri; | ||
} | ||
get fsPath() { | ||
return this.uriObject.fsPath; | ||
} | ||
get descriptor() { | ||
return this._descriptor; | ||
} | ||
get blocks() { | ||
return this._blocks; | ||
} | ||
get parseErrors() { | ||
return this._parseErrors; | ||
} | ||
get content() { | ||
return this.getText(); | ||
} | ||
getText(range) { | ||
return this.internal.getText(range); | ||
} | ||
positionAt(offset) { | ||
return this.internal.positionAt(offset); | ||
} | ||
offsetAt(position) { | ||
return this.internal.offsetAt(position); | ||
} | ||
blockAt(positionOrOffset) { | ||
const offset = typeof positionOrOffset === 'number' | ||
? positionOrOffset | ||
: this.offsetAt(positionOrOffset); | ||
return this._blocks.find((block) => block.loc.start.offset <= offset && offset <= block.loc.end.offset); | ||
} | ||
parse() { | ||
const source = this.getText(); | ||
const { descriptor, errors } = compilerSfc.parse(source, { | ||
sourceMap: false, | ||
pad: 'space', | ||
filename: this.fsPath, | ||
compiler: { | ||
compile: compilerCore.baseCompile, | ||
parse: compilerCore.baseParse, | ||
}, | ||
}); | ||
const prevIds = Object.keys(this.documents); | ||
this._descriptor = descriptor; | ||
this._parseErrors = errors; | ||
this._blocks = [descriptor.script, descriptor.template].filter(isNotNull); | ||
this._blocks = this._blocks | ||
.concat(descriptor.styles) | ||
.concat(descriptor.customBlocks); | ||
this._blocks.sort((a, b) => a.loc.start.offset - b.loc.start.offset); | ||
if (prevIds.length) { | ||
prevIds.forEach((id) => { | ||
const selector = querystring.parse(id); | ||
if (selector && 'index' in selector) { | ||
const block = this._blocks[selector.index]; | ||
this.setBlockDocument(block, this.createBlockDocument(block)); | ||
} | ||
}); | ||
} | ||
if (descriptor.script) { | ||
this.setBlockDocument(descriptor.script, this.createBlockDocument(descriptor.script)); | ||
} | ||
if (descriptor.template) { | ||
this.setBlockDocument(descriptor.template, this.createBlockDocument(descriptor.template)); | ||
} | ||
return this; | ||
} | ||
createBlockDocument(block) { | ||
if (!block) | ||
return null; | ||
const id = querystring.stringify(this.getSelectorFor(block)); | ||
const uri = this.getUriFor(block); | ||
const languageId = getLanguageIdForBlock(block); | ||
const prevDocument = this.documents[id]; | ||
if (prevDocument) { | ||
if (prevDocument.uri === uri && prevDocument.languageId === languageId) { | ||
return VirtualTextDocument.update(prevDocument, [{ text: block.content }], this.version); | ||
} | ||
} | ||
return VirtualTextDocument.create(this, uri, languageId, this.version, block.content); | ||
} | ||
all() { | ||
return Object.values(this.documents).filter(isNotNull); | ||
} | ||
forTS() { | ||
return Object.values(this.documents) | ||
.filter(isNotNull) | ||
.filter((document) => /^(typescript|javascript)$/.test(document.languageId)); | ||
} | ||
getBlockDocument(block) { | ||
if (!block) | ||
return; | ||
const selector = this.getSelectorFor(block); | ||
if (!selector) | ||
return; | ||
const id = querystring.stringify(selector); | ||
if ('index' in selector && | ||
!/^(script|template)$/.test(selector.type) && | ||
!this.documents[id]) { | ||
const block = this.blocks[selector.index]; | ||
if (block) | ||
this.setBlockDocument(block, this.createBlockDocument(block)); | ||
} | ||
return this.documents[id]; | ||
} | ||
setBlockDocument(block, document) { | ||
const id = querystring.stringify(this.getSelectorFor(block)); | ||
if (document) { | ||
this.documents[id] = document; | ||
} | ||
else { | ||
delete this.documents[id]; | ||
} | ||
} | ||
getUriFor(block) { | ||
const selector = this.getSelectorFor(block); | ||
const uri = vscodeUri.URI.file(this.uriObject.path + | ||
virtualFileNameSep + | ||
('index' in selector | ||
? `${selector.type}__${selector.index}` | ||
: selector.type) + | ||
'.' + | ||
this.getLanguageFor(block)); | ||
return uri.toString().replace(/^file/, 'vue'); | ||
} | ||
getSelectorFor(block) { | ||
if (!block) | ||
return { type: '', index: -1 }; | ||
if (block === 'script') { | ||
return { type: 'script' }; | ||
} | ||
else if (block === 'template') { | ||
return { type: 'template' }; | ||
} | ||
else if (typeof block === 'string') { | ||
const virtual = parseVirtualFileUri(block); | ||
if (!virtual) | ||
throw new Error(`Malforated virtual document uri: ${block}`); | ||
return virtual.selector; | ||
} | ||
else if ('index' in block) { | ||
return block; | ||
} | ||
else { | ||
switch (block.type) { | ||
case 'script': | ||
return { type: 'script' }; | ||
case 'template': | ||
return { type: 'template' }; | ||
default: | ||
return { | ||
type: block.type, | ||
index: this.blocks.indexOf(block), | ||
}; | ||
} | ||
} | ||
} | ||
getLanguageFor(block) { | ||
return (block.lang || | ||
BlockLanguageMap[block.type] || | ||
'txt'); | ||
} | ||
static create(uri, languageId, version, content) { | ||
if (!isVueFile(uri)) | ||
throw new Error(`Not a .vue file: ${uri}`); | ||
return new VueTextDocument(vscodeLanguageserverTextdocument.TextDocument.create(uri, languageId, version, content)); | ||
} | ||
static update(document, changes, version) { | ||
document.internal = vscodeLanguageserverTextdocument.TextDocument.update(document.internal, changes, version); | ||
return document.parse(); | ||
} | ||
static fsPathToUri(fsPath) { | ||
const uri = vscodeUri.URI.file(fsPath).toString(); | ||
if (isVirtualFile(fsPath)) { | ||
return uri.replace(/^[^:]+/, 'vue'); | ||
} | ||
return uri; | ||
} | ||
} | ||
function parseVirtualFileUri(fileNameOrUri) { | ||
const uri = vscodeUri.URI.parse(asUri(fileNameOrUri)); | ||
if (uri.scheme === 'vue') { | ||
const [container, selector] = uri.fsPath.split(virtualFileNameSep); | ||
if (!selector.includes('.')) | ||
throw new Error('Malformated virtual file uri.'); | ||
const [block, index] = selector | ||
.substr(0, selector.lastIndexOf('.')) | ||
.split('__'); | ||
return { | ||
// TODO: DO NOT ASSUME FILE SCHEME! | ||
uri: vscodeUri.URI.file(container).toString(), | ||
selector: (index | ||
? { | ||
type: block, | ||
index: parseInt(index, 10), | ||
} | ||
: { type: block }), | ||
}; | ||
} | ||
return null; | ||
} | ||
class DocumentStore { | ||
constructor(resolve) { | ||
this.resolve = resolve; | ||
this.map = new Map(); | ||
this.lowerCaseNames = new Map(); | ||
} | ||
normalizeUri(uri) { | ||
const lower = uri.toLowerCase(); | ||
return this.lowerCaseNames.get(lower) || uri; | ||
} | ||
has(uri) { | ||
return this.map.has(this.normalizeUri(uri)); | ||
} | ||
get(uri) { | ||
return this.map.get(this.normalizeUri(uri)) || this.loadSync(uri); | ||
} | ||
set(uri, document) { | ||
this.map.set(uri, document); | ||
this.lowerCaseNames.set(uri.toLowerCase(), uri); | ||
} | ||
delete(uri) { | ||
return this.map.delete(this.normalizeUri(uri)); | ||
} | ||
all() { | ||
return Array.from(this.map.keys()); | ||
} | ||
dispose() { | ||
this.map.clear(); | ||
} | ||
loadSync(uri) { | ||
const document = this.resolve(uri); | ||
if (document) { | ||
this.set(uri, document); | ||
} | ||
return document; | ||
} | ||
} | ||
class AsyncDocumentStore { | ||
constructor(resolve, useCaseSensitiveFileNames = () => true) { | ||
this.resolve = resolve; | ||
this.useCaseSensitiveFileNames = useCaseSensitiveFileNames; | ||
this.map = new Map(); | ||
} | ||
normalizeUri(uri) { | ||
return this.useCaseSensitiveFileNames() ? uri : uri.toLowerCase(); | ||
} | ||
has(uri) { | ||
return this.map.has(this.normalizeUri(uri)); | ||
} | ||
get(uri) { | ||
return this.map.get(this.normalizeUri(uri)) || this.load(uri); | ||
} | ||
set(uri, document) { | ||
this.map.set(this.normalizeUri(uri), document); | ||
} | ||
delete(uri) { | ||
return this.map.delete(this.normalizeUri(uri)); | ||
} | ||
all() { | ||
return Array.from(this.map.keys()); | ||
} | ||
dispose() { | ||
this.map.clear(); | ||
} | ||
async load(uri) { | ||
const document = await this.resolve(uri); | ||
if (document) { | ||
this.map.set(this.normalizeUri(uri), document); | ||
} | ||
return document; | ||
} | ||
} | ||
function isNotNull(value) { | ||
return value != null; | ||
} | ||
function getLanguageIdForBlock(block) { | ||
switch (block.type) { | ||
case 'template': | ||
return getLanguageIdFromExtension(block.lang) || 'vue-html'; | ||
case 'script': | ||
return getLanguageIdFromExtension(block.lang) || 'javascript'; | ||
case 'style': | ||
return getLanguageIdFromExtension(block.lang) || 'css'; | ||
default: | ||
return getLanguageIdFromExtension(block.lang) || 'text'; | ||
} | ||
} | ||
function getLanguageIdFromExtension(ext) { | ||
switch (ext) { | ||
case 'js': | ||
return 'javascript'; | ||
case 'ts': | ||
return 'typescript'; | ||
} | ||
return ext; | ||
} | ||
exports.AsyncDocumentStore = AsyncDocumentStore; | ||
exports.DocumentStore = DocumentStore; | ||
exports.VirtualTextDocument = VirtualTextDocument; | ||
exports.VueTextDocument = VueTextDocument; | ||
exports.asUri = asUri; | ||
exports.isVirtualFile = isVirtualFile; | ||
exports.isVueFile = isVueFile; | ||
exports.parseVirtualFileUri = parseVirtualFileUri; | ||
exports.virtualFileNameSep = virtualFileNameSep; | ||
//# sourceMappingURL=vue-virtual-textdocument.js.map |
{ | ||
"name": "@vuedx/vue-virtual-textdocument", | ||
"version": "0.1.0-alpha.0", | ||
"version": "0.1.0-alpha.1", | ||
"description": "", | ||
@@ -17,3 +17,4 @@ "main": "dist/vue-virtual-textdocument.js", | ||
"dependencies": { | ||
"@vue/compiler-sfc": "^3.0.0-alpha.9", | ||
"@vue/compiler-core": "^3.0.0-alpha.12", | ||
"@vue/compiler-sfc": "^3.0.0-alpha.12", | ||
"vscode-languageserver-textdocument": "^1.0.1", | ||
@@ -20,0 +21,0 @@ "vscode-uri": "^2.1.1" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
82515
9
906
2
4
1