forked from external/vscode-xml
parent
6eb35d0a37
commit
93b3083bbf
14 changed files with 129 additions and 129 deletions
10
gulpfile.js
10
gulpfile.js
|
@ -1,9 +1,9 @@
|
|||
var gulp = require('gulp');
|
||||
var gulp = require("gulp");
|
||||
|
||||
var shell = require('gulp-shell');
|
||||
var shell = require("gulp-shell");
|
||||
|
||||
gulp.task('compile-typescript', function () {
|
||||
gulp.src('package.json').pipe(shell('tsc'));
|
||||
gulp.task("compile-typescript", function () {
|
||||
gulp.src("package.json").pipe(shell("tsc"));
|
||||
});
|
||||
|
||||
gulp.task('build', ['compile-typescript']);
|
||||
gulp.task("build", ["compile-typescript"]);
|
|
@ -1,14 +1,14 @@
|
|||
import * as vsc from 'vscode';
|
||||
import * as ext from './Extension';
|
||||
import * as xpath from 'xpath';
|
||||
import { RangeUtil } from './utils/RangeUtil';
|
||||
import { XmlFormatter } from './services/XmlFormatter';
|
||||
import { XPathFeatureProvider } from './providers/XPath';
|
||||
import { XQueryExecutionProvider } from './providers/Execution';
|
||||
import { XmlFormattingEditProvider } from './providers/Formatting';
|
||||
import * as vsc from "vscode";
|
||||
import * as ext from "./Extension";
|
||||
import * as xpath from "xpath";
|
||||
import { RangeUtil } from "./utils/RangeUtil";
|
||||
import { XmlFormatter } from "./services/XmlFormatter";
|
||||
import { XPathFeatureProvider } from "./providers/XPath";
|
||||
import { XQueryExecutionProvider } from "./providers/Execution";
|
||||
import { XmlFormattingEditProvider } from "./providers/Formatting";
|
||||
|
||||
const CFG_SECTION: string = 'xmlTools';
|
||||
const CFG_REMOVE_COMMENTS: string = 'removeCommentsOnMinify';
|
||||
const CFG_SECTION: string = "xmlTools";
|
||||
const CFG_REMOVE_COMMENTS: string = "removeCommentsOnMinify";
|
||||
|
||||
export class TextEditorCommands {
|
||||
static minifyXml(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): void {
|
||||
|
@ -54,13 +54,13 @@ export class TextEditorCommands {
|
|||
editBuilder.replace(edits[i].range, edits[i].newText);
|
||||
|
||||
// wiggle the cursor to deselect the formatted XML (is there a non-hacky way to go about this?)
|
||||
await vsc.commands.executeCommand('cursorMove', {
|
||||
to: 'left',
|
||||
by: 'character'
|
||||
await vsc.commands.executeCommand("cursorMove", {
|
||||
to: "left",
|
||||
by: "character"
|
||||
});
|
||||
await vsc.commands.executeCommand('cursorMove', {
|
||||
to: 'right',
|
||||
by: 'character'
|
||||
await vsc.commands.executeCommand("cursorMove", {
|
||||
to: "right",
|
||||
by: "character"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
import * as vsc from 'vscode';
|
||||
import { TextEditorCommands } from './Commands';
|
||||
import { XmlFormattingEditProvider } from './providers/Formatting';
|
||||
import { XQueryLintingFeatureProvider } from './providers/Linting';
|
||||
import { XQueryCompletionItemProvider } from './providers/Completion';
|
||||
import * as vsc from "vscode";
|
||||
import { TextEditorCommands } from "./Commands";
|
||||
import { XmlFormattingEditProvider } from "./providers/Formatting";
|
||||
import { XQueryLintingFeatureProvider } from "./providers/Linting";
|
||||
import { XQueryCompletionItemProvider } from "./providers/Completion";
|
||||
import { XmlTreeViewDataProvider } from "./providers/XmlTreeView";
|
||||
|
||||
export var GlobalState: vsc.Memento;
|
||||
export var WorkspaceState: vsc.Memento;
|
||||
|
||||
const LANG_XML: string = 'xml';
|
||||
const LANG_XSL: string = 'xsl';
|
||||
const LANG_XQUERY: string = 'xquery;'
|
||||
const MEM_QUERY_HISTORY: string = 'xpathQueryHistory';
|
||||
const LANG_XML: string = "xml";
|
||||
const LANG_XSL: string = "xsl";
|
||||
const LANG_XQUERY: string = "xquery;"
|
||||
const MEM_QUERY_HISTORY: string = "xpathQueryHistory";
|
||||
|
||||
export function activate(ctx: vsc.ExtensionContext) {
|
||||
console.log('activate extension');
|
||||
console.log("activate extension");
|
||||
// expose global and workspace state to the entire extension
|
||||
GlobalState = ctx.globalState;
|
||||
WorkspaceState = ctx.workspaceState;
|
||||
|
||||
// register palette commands
|
||||
ctx.subscriptions.push(
|
||||
vsc.commands.registerTextEditorCommand('xmlTools.minifyXml', TextEditorCommands.minifyXml),
|
||||
vsc.commands.registerTextEditorCommand('xmlTools.evaluateXPath', TextEditorCommands.evaluateXPath),
|
||||
vsc.commands.registerTextEditorCommand('xmlTools.executeXQuery', TextEditorCommands.executeXQuery),
|
||||
vsc.commands.registerTextEditorCommand('xmlTools.formatAsXml', TextEditorCommands.formatAsXml)
|
||||
vsc.commands.registerTextEditorCommand("xmlTools.minifyXml", TextEditorCommands.minifyXml),
|
||||
vsc.commands.registerTextEditorCommand("xmlTools.evaluateXPath", TextEditorCommands.evaluateXPath),
|
||||
vsc.commands.registerTextEditorCommand("xmlTools.executeXQuery", TextEditorCommands.executeXQuery),
|
||||
vsc.commands.registerTextEditorCommand("xmlTools.formatAsXml", TextEditorCommands.formatAsXml)
|
||||
);
|
||||
|
||||
// register language feature providers
|
||||
|
@ -32,7 +32,7 @@ export function activate(ctx: vsc.ExtensionContext) {
|
|||
vsc.languages.registerDocumentFormattingEditProvider([LANG_XML, LANG_XSL], new XmlFormattingEditProvider()),
|
||||
vsc.languages.registerDocumentRangeFormattingEditProvider([LANG_XML, LANG_XSL], new XmlFormattingEditProvider()),
|
||||
|
||||
vsc.languages.registerCompletionItemProvider(LANG_XQUERY, new XQueryCompletionItemProvider(), ':', '$')
|
||||
vsc.languages.registerCompletionItemProvider(LANG_XQUERY, new XQueryCompletionItemProvider(), ":", "$")
|
||||
);
|
||||
|
||||
// listen to editor events (for linting)
|
||||
|
@ -61,7 +61,7 @@ function _handleContextChange(editor: vsc.TextEditor): void {
|
|||
}
|
||||
|
||||
switch (editor.document.languageId) {
|
||||
case 'xquery':
|
||||
case "xquery":
|
||||
XQueryLintingFeatureProvider.provideXQueryDiagnostics(editor);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as vsc from 'vscode';
|
||||
import { XQueryCompleter, XQueryCompletionItem } from '../services/XQueryCompleter';
|
||||
import * as vsc from "vscode";
|
||||
import { XQueryCompleter, XQueryCompletionItem } from "../services/XQueryCompleter";
|
||||
|
||||
export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider {
|
||||
provideCompletionItems(document: vsc.TextDocument, position: vsc.Position): vsc.CompletionItem[] {
|
||||
|
@ -14,20 +14,20 @@ export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider
|
|||
|
||||
switch (completion.meta) {
|
||||
// functions (always qualified with a colon)
|
||||
case 'function':
|
||||
case "function":
|
||||
item.kind = vsc.CompletionItemKind.Function;
|
||||
|
||||
let funcStart = (completion.value.indexOf(':') + 1);
|
||||
let funcEnd = completion.value.indexOf('(');
|
||||
let funcStart = (completion.value.indexOf(":") + 1);
|
||||
let funcEnd = completion.value.indexOf("(");
|
||||
|
||||
item.insertText = completion.value.substring(funcStart, funcEnd);
|
||||
break;
|
||||
|
||||
// variables and parameters (always qualified with a dollar sign)
|
||||
case 'Let binding':
|
||||
case 'Local variable':
|
||||
case 'Window variable':
|
||||
case 'Function parameter':
|
||||
case "Let binding":
|
||||
case "Local variable":
|
||||
case "Window variable":
|
||||
case "Function parameter":
|
||||
item.kind = vsc.CompletionItemKind.Variable;
|
||||
item.insertText = completion.value.substring(1);
|
||||
break;
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
import * as vsc from 'vscode';
|
||||
import { ChildProcess } from '../services/ChildProcess';
|
||||
import * as vsc from "vscode";
|
||||
import { ChildProcess } from "../services/ChildProcess";
|
||||
|
||||
const CFG_SECTION: string = 'xmlTools';
|
||||
const CFG_XQEXEC: string = 'xqueryExecutionEngine';
|
||||
const CFG_XQARGS: string = 'xqueryExecutionArguments';
|
||||
const CFG_SECTION: string = "xmlTools";
|
||||
const CFG_XQEXEC: string = "xqueryExecutionEngine";
|
||||
const CFG_XQARGS: string = "xqueryExecutionArguments";
|
||||
|
||||
export class XQueryExecutionProvider {
|
||||
static async executeXQueryAsync(editor: vsc.TextEditor): Promise<void> {
|
||||
// this disposable will be used for creating status bar messages
|
||||
let disposable: vsc.Disposable;
|
||||
|
||||
if (editor.document.languageId !== 'xquery') {
|
||||
vsc.window.showErrorMessage('This action can only be performed on an XQuery file.');
|
||||
if (editor.document.languageId !== "xquery") {
|
||||
vsc.window.showErrorMessage("This action can only be performed on an XQuery file.");
|
||||
return;
|
||||
}
|
||||
|
||||
let executable = vsc.workspace.getConfiguration(CFG_SECTION).get<string>(CFG_XQEXEC, null);
|
||||
let args = vsc.workspace.getConfiguration(CFG_SECTION).get<string[]>(CFG_XQARGS, []);
|
||||
|
||||
if (!executable || executable == '') {
|
||||
let action = await vsc.window.showWarningMessage('An XQuery execution engine has not been defined.', 'Define Now');
|
||||
if (!executable || executable == "") {
|
||||
let action = await vsc.window.showWarningMessage("An XQuery execution engine has not been defined.", "Define Now");
|
||||
|
||||
if (action == 'Define Now') {
|
||||
vsc.commands.executeCommand('workbench.action.openGlobalSettings');
|
||||
if (action == "Define Now") {
|
||||
vsc.commands.executeCommand("workbench.action.openGlobalSettings");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let inputFile: vsc.Uri;
|
||||
disposable = vsc.window.setStatusBarMessage('Searching for XML files in folder...');
|
||||
let files: vsc.Uri[] = await vsc.workspace.findFiles('**/*.xml', '', 100);
|
||||
disposable = vsc.window.setStatusBarMessage("Searching for XML files in folder...");
|
||||
let files: vsc.Uri[] = await vsc.workspace.findFiles("**/*.xml", "", 100);
|
||||
disposable.dispose();
|
||||
|
||||
// user does not have a folder open - prompt for file name
|
||||
if (typeof files === 'undefined') {
|
||||
vsc.window.showErrorMessage('You must have a folder opened in VS Code to use this feature.');
|
||||
if (typeof files === "undefined") {
|
||||
vsc.window.showErrorMessage("You must have a folder opened in VS Code to use this feature.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -45,16 +45,16 @@ export class XQueryExecutionProvider {
|
|||
let qpItems: any[] = new Array<any>();
|
||||
|
||||
files.forEach((file) => {
|
||||
let filename: string = file.fsPath.replace('\\', '/');
|
||||
let filename: string = file.fsPath.replace("\\", "/");
|
||||
|
||||
qpItems.push({ // must implement vscode.QuickPickItem
|
||||
label: filename.substring(filename.lastIndexOf('/') + 1),
|
||||
label: filename.substring(filename.lastIndexOf("/") + 1),
|
||||
description: file.fsPath,
|
||||
file: file
|
||||
});
|
||||
});
|
||||
|
||||
let selection = await vsc.window.showQuickPick(qpItems, { placeHolder: 'Please select an input file.' });
|
||||
let selection = await vsc.window.showQuickPick(qpItems, { placeHolder: "Please select an input file." });
|
||||
|
||||
if (!selection) {
|
||||
return;
|
||||
|
@ -82,8 +82,8 @@ export class XQueryExecutionProvider {
|
|||
|
||||
if (outputPath) {
|
||||
outputPath = await vsc.window.showInputBox({
|
||||
placeHolder: 'ex. C:\\TEMP\XQueryOutput\\MyOutputFile.xml',
|
||||
prompt: 'Please specify the output file path. Existing file behavior is determined by the execution engine you have specified.',
|
||||
placeHolder: "ex. C:\\TEMP\XQueryOutput\\MyOutputFile.xml",
|
||||
prompt: "Please specify the output file path. Existing file behavior is determined by the execution engine you have specified.",
|
||||
value: outputPath
|
||||
});
|
||||
|
||||
|
@ -91,12 +91,12 @@ export class XQueryExecutionProvider {
|
|||
}
|
||||
|
||||
// call out to the execution engine
|
||||
disposable = vsc.window.setStatusBarMessage('Executing XQuery Script...');
|
||||
disposable = vsc.window.setStatusBarMessage("Executing XQuery Script...");
|
||||
args = args.map<string>((value: string) => {
|
||||
return value
|
||||
.replace('$(script)', editor.document.uri.fsPath)
|
||||
.replace('$(input)', inputFile.fsPath)
|
||||
.replace('$(project)', vsc.workspace.rootPath);
|
||||
.replace("$(script)", editor.document.uri.fsPath)
|
||||
.replace("$(input)", inputFile.fsPath)
|
||||
.replace("$(project)", vsc.workspace.rootPath);
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -106,7 +106,7 @@ export class XQueryExecutionProvider {
|
|||
catch (error) {
|
||||
if (error.message.search(/[Ll]ine:?\s*\d+/gm) > -1) {
|
||||
let match: RegExpExecArray = /[Ll]ine:?\s*\d+/gm.exec(error.message);
|
||||
let line: number = (Number.parseInt(match[0].replace(/([Ll]ine:?\s*)|\s/, '')) - 1);
|
||||
let line: number = (Number.parseInt(match[0].replace(/([Ll]ine:?\s*)|\s/, "")) - 1);
|
||||
|
||||
let selection: string = await vsc.window.showErrorMessage(error.message, `Go to Line ${line}`);
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import * as vsc from 'vscode';
|
||||
import { RangeUtil } from '../utils/RangeUtil';
|
||||
import { XmlFormatter, IXmlFormatterOptions } from '../services/XmlFormatter';
|
||||
import * as vsc from "vscode";
|
||||
import { RangeUtil } from "../utils/RangeUtil";
|
||||
import { XmlFormatter, IXmlFormatterOptions } from "../services/XmlFormatter";
|
||||
|
||||
const CFG_SECTION: string = 'xmlTools';
|
||||
const CFG_SPLIT_NAMESPACES: string = 'splitXmlnsOnFormat';
|
||||
const CFG_SECTION: string = "xmlTools";
|
||||
const CFG_SPLIT_NAMESPACES: string = "splitXmlnsOnFormat";
|
||||
|
||||
export class XmlFormattingEditProvider implements vsc.DocumentFormattingEditProvider, vsc.DocumentRangeFormattingEditProvider {
|
||||
provideDocumentFormattingEdits(document: vsc.TextDocument, options: vsc.FormattingOptions): vsc.TextEdit[] {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import * as vsc from 'vscode';
|
||||
import { XQueryLinter, XQueryDiagnostic } from '../services/XQueryLinter';
|
||||
import * as vsc from "vscode";
|
||||
import { XQueryLinter, XQueryDiagnostic } from "../services/XQueryLinter";
|
||||
|
||||
export class XQueryLintingFeatureProvider {
|
||||
private static _coreDiagnostics: vsc.DiagnosticCollection;
|
||||
|
||||
static get coreDiagnostics(): vsc.DiagnosticCollection {
|
||||
if (!XQueryLintingFeatureProvider._coreDiagnostics) {
|
||||
XQueryLintingFeatureProvider._coreDiagnostics = vsc.languages.createDiagnosticCollection('XQueryDiagnostics');
|
||||
XQueryLintingFeatureProvider._coreDiagnostics = vsc.languages.createDiagnosticCollection("XQueryDiagnostics");
|
||||
}
|
||||
|
||||
return XQueryLintingFeatureProvider._coreDiagnostics;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import * as vsc from 'vscode';
|
||||
import * as ext from '../Extension';
|
||||
import { XPathEvaluator, EvaluatorResult, EvaluatorResultType } from '../services/XPathEvaluator';
|
||||
import * as vsc from "vscode";
|
||||
import * as ext from "../Extension";
|
||||
import { XPathEvaluator, EvaluatorResult, EvaluatorResultType } from "../services/XPathEvaluator";
|
||||
|
||||
const CFG_SECTION: string = 'xmlTools';
|
||||
const CFG_PERSIST_QUERY: string = 'persistXPathQuery';
|
||||
const CFG_IGNORE_DEFAULT_XMLNS: string = 'ignoreDefaultNamespace';
|
||||
const MEM_QUERY_HISTORY: string = 'xpathQueryHistory';
|
||||
const MEM_QUERY_LAST: string = 'xPathQueryLast';
|
||||
const OUTPUT_CHANNEL: string = 'XPath Results';
|
||||
const CFG_SECTION: string = "xmlTools";
|
||||
const CFG_PERSIST_QUERY: string = "persistXPathQuery";
|
||||
const CFG_IGNORE_DEFAULT_XMLNS: string = "ignoreDefaultNamespace";
|
||||
const MEM_QUERY_HISTORY: string = "xpathQueryHistory";
|
||||
const MEM_QUERY_LAST: string = "xPathQueryLast";
|
||||
const OUTPUT_CHANNEL: string = "XPath Results";
|
||||
|
||||
export class XPathFeatureProvider {
|
||||
static async evaluateXPathAsync(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): Promise<void> {
|
||||
|
@ -21,7 +21,7 @@ export class XPathFeatureProvider {
|
|||
// if not, try pulling the last query ran, regardless of document
|
||||
// NOTE: if the user has focus on the output channel when opening the xquery prompt, the channel is the "active" document
|
||||
let history: HistoricQuery[] = memento.get<HistoricQuery[]>(MEM_QUERY_HISTORY, new Array<HistoricQuery>());
|
||||
let globalLastQuery: string = memento.get<string>(MEM_QUERY_LAST, '');
|
||||
let globalLastQuery: string = memento.get<string>(MEM_QUERY_LAST, "");
|
||||
|
||||
let lastQuery: HistoricQuery = history.find((item: HistoricQuery) => {
|
||||
if (item.uri == editor.document.uri.toString()) {
|
||||
|
@ -32,7 +32,7 @@ export class XPathFeatureProvider {
|
|||
});
|
||||
|
||||
// set the inital display value and prompt the user
|
||||
let query: string = '';
|
||||
let query: string = "";
|
||||
|
||||
if (persistQueries) {
|
||||
if (lastQuery) {
|
||||
|
@ -45,8 +45,8 @@ export class XPathFeatureProvider {
|
|||
}
|
||||
|
||||
query = await vsc.window.showInputBox({
|
||||
placeHolder: 'XPath Query',
|
||||
prompt: 'Please enter an XPath query to evaluate.',
|
||||
placeHolder: "XPath Query",
|
||||
prompt: "Please enter an XPath query to evaluate.",
|
||||
value: query
|
||||
});
|
||||
|
||||
|
@ -73,7 +73,7 @@ export class XPathFeatureProvider {
|
|||
outputChannel.clear();
|
||||
|
||||
outputChannel.appendLine(`XPath Query: ${query}`);
|
||||
outputChannel.append('\n');
|
||||
outputChannel.append("\n");
|
||||
|
||||
if (evalResult.type === EvaluatorResultType.NODE_COLLECTION) {
|
||||
(evalResult.result as Node[]).forEach((node: XmlNode) => {
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
let child_process = require('child_process');
|
||||
let child_process = require("child_process");
|
||||
|
||||
export class ChildProcess {
|
||||
static async spawnAsync(executable: string, args: string[]): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
|
||||
let output: string = '';
|
||||
let output: string = "";
|
||||
let handle = child_process.spawn(executable, args);
|
||||
|
||||
handle.stdout.on('data', (data: string) => {
|
||||
handle.stdout.on("data", (data: string) => {
|
||||
output += data;
|
||||
});
|
||||
|
||||
handle.stderr.on('data', (data: string) => {
|
||||
handle.stderr.on("data", (data: string) => {
|
||||
output += data;
|
||||
});
|
||||
|
||||
handle.on('close', (code: string) => {
|
||||
if (code == '0') {
|
||||
handle.on("close", (code: string) => {
|
||||
if (code == "0") {
|
||||
resolve();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as xpath from 'xpath';
|
||||
import * as xpath from "xpath";
|
||||
|
||||
let DOMParser = require('xmldom').DOMParser;
|
||||
let DOMParser = require("xmldom").DOMParser;
|
||||
|
||||
export class EvaluatorResult {
|
||||
type: EvaluatorResultType;
|
||||
|
@ -16,13 +16,13 @@ export class XPathEvaluator {
|
|||
static evaluate(query: string, xml: string, ignoreDefaultNamespace: boolean): EvaluatorResult {
|
||||
if (ignoreDefaultNamespace) {
|
||||
xml = xml.replace(/xmlns=".+"/g, (match: string) => {
|
||||
return match.replace(/xmlns/g, 'xmlns:default');
|
||||
return match.replace(/xmlns/g, "xmlns:default");
|
||||
});
|
||||
}
|
||||
|
||||
let nodes: Node[] = new Array<Node>();
|
||||
|
||||
let xdoc: Document = new DOMParser().parseFromString(xml, 'text/xml');
|
||||
let xdoc: Document = new DOMParser().parseFromString(xml, "text/xml");
|
||||
|
||||
let resolver: xpath.XPathNSResolver = xpath.createNSResolver(xdoc);
|
||||
let result: xpath.XPathResult = xpath.evaluate(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
let XQLint = require('xqlint').XQLint;
|
||||
let XQLint = require("xqlint").XQLint;
|
||||
|
||||
export class XQueryCompleter {
|
||||
constructor(script: string) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
let XQLint = require('xqlint').XQLint;
|
||||
let XQLint = require("xqlint").XQLint;
|
||||
|
||||
export class XQueryLinter {
|
||||
static SEVERITY_WARNING: number = 1;
|
||||
|
|
|
@ -3,19 +3,19 @@ export class XmlFormatter {
|
|||
constructor(options?: IXmlFormatterOptions) {
|
||||
options = options || {};
|
||||
|
||||
if (typeof options.preferSpaces === 'undefined') {
|
||||
if (typeof options.preferSpaces === "undefined") {
|
||||
options.preferSpaces = false;
|
||||
}
|
||||
|
||||
if (typeof options.splitNamespaces === 'undefined') {
|
||||
if (typeof options.splitNamespaces === "undefined") {
|
||||
options.splitNamespaces = true;
|
||||
}
|
||||
|
||||
options.tabSize = options.tabSize || 4;
|
||||
options.newLine = options.newLine || '\n';
|
||||
options.newLine = options.newLine || "\n";
|
||||
|
||||
this.newLine = options.newLine || '\n';
|
||||
this.indentPattern = (options.preferSpaces) ? ' '.repeat(options.tabSize) : '\t';
|
||||
this.newLine = options.newLine || "\n";
|
||||
this.indentPattern = (options.preferSpaces) ? " ".repeat(options.tabSize) : "\t";
|
||||
this.splitNamespaces = options.splitNamespaces;
|
||||
}
|
||||
|
||||
|
@ -25,19 +25,19 @@ export class XmlFormatter {
|
|||
|
||||
format(xml: string): string {
|
||||
xml = this.minify(xml, false);
|
||||
xml = xml.replace(/</g, '~::~<');
|
||||
xml = xml.replace(/</g, "~::~<");
|
||||
|
||||
if (this.splitNamespaces) {
|
||||
xml = xml
|
||||
.replace(/xmlns\:/g, '~::~xmlns:')
|
||||
.replace(/xmlns\=/g, '~::~xmlns=');
|
||||
.replace(/xmlns\:/g, "~::~xmlns:")
|
||||
.replace(/xmlns\=/g, "~::~xmlns=");
|
||||
}
|
||||
|
||||
let parts: string[] = xml.split('~::~');
|
||||
let parts: string[] = xml.split("~::~");
|
||||
console.log(parts);
|
||||
let inComment: boolean = false;
|
||||
let level: number = 0;
|
||||
let output: string = '';
|
||||
let output: string = "";
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
// <!
|
||||
|
@ -59,7 +59,7 @@ export class XmlFormatter {
|
|||
|
||||
// <elm></elm>
|
||||
else if (/^<(\w|:)/.test(parts[i - 1]) && /^<\/(\w|:)/.test(parts[i])
|
||||
&& /^<[\w:\-\.\,\/]+/.exec(parts[i - 1])[0] == /^<\/[\w:\-\.\,]+/.exec(parts[i])[0].replace('/', '')) {
|
||||
&& /^<[\w:\-\.\,\/]+/.exec(parts[i - 1])[0] == /^<\/[\w:\-\.\,]+/.exec(parts[i])[0].replace("/", "")) {
|
||||
|
||||
output += parts[i];
|
||||
if (!inComment) level--;
|
||||
|
@ -118,31 +118,31 @@ export class XmlFormatter {
|
|||
}
|
||||
|
||||
minify(xml: string, removeComments?: boolean): string {
|
||||
if (typeof removeComments === 'undefined') {
|
||||
if (typeof removeComments === "undefined") {
|
||||
removeComments = false;
|
||||
}
|
||||
|
||||
xml = this._stripLineBreaks(xml); // all line breaks outside of CDATA elements
|
||||
xml = (removeComments) ? xml.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g, '') : xml;
|
||||
xml = xml.replace(/>\s{0,}</g, '><'); // insignificant whitespace between tags
|
||||
xml = xml.replace(/"\s+(?=[^\s]+=)/g, '" '); // spaces between attributes
|
||||
xml = xml.replace(/"\s+(?=>)/g, '"'); // spaces between the last attribute and tag close (>)
|
||||
xml = xml.replace(/"\s+(?=\/>)/g, '" '); // spaces between the last attribute and tag close (/>)
|
||||
xml = (removeComments) ? xml.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g, "") : xml;
|
||||
xml = xml.replace(/>\s{0,}</g, "><"); // insignificant whitespace between tags
|
||||
xml = xml.replace(/"\s+(?=[^\s]+=)/g, "\" "); // spaces between attributes
|
||||
xml = xml.replace(/"\s+(?=>)/g, "\""); // spaces between the last attribute and tag close (>)
|
||||
xml = xml.replace(/"\s+(?=\/>)/g, "\" "); // spaces between the last attribute and tag close (/>)
|
||||
xml = xml.replace(/[^ <>="]\s+[^ <>="]+=/g, (match: string) => { // spaces between the node name and the first attribute
|
||||
return match.replace(/\s+/g, ' ');
|
||||
return match.replace(/\s+/g, " ");
|
||||
});
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
private _getIndent(level: number, trailingValue?: string): string {
|
||||
trailingValue = trailingValue || '';
|
||||
trailingValue = trailingValue || "";
|
||||
|
||||
return `${this.newLine}${this.indentPattern.repeat(level)}${trailingValue}`;
|
||||
}
|
||||
|
||||
private _stripLineBreaks(xml: string): string {
|
||||
let output: string = '';
|
||||
let output: string = "";
|
||||
let inTag: boolean = false;
|
||||
let inTagName: boolean = false;
|
||||
let inCdata: boolean = false;
|
||||
|
@ -153,15 +153,15 @@ export class XmlFormatter {
|
|||
let prev: string = xml.charAt(i - 1);
|
||||
let next: string = xml.charAt(i + 1);
|
||||
|
||||
if (char == '!' && (xml.substr(i, 8) == '![CDATA[' || xml.substr(i, 3) == '!--')) {
|
||||
if (char == "!" && (xml.substr(i, 8) == "![CDATA[" || xml.substr(i, 3) == "!--")) {
|
||||
inCdata = true;
|
||||
}
|
||||
|
||||
else if (char == ']' && (xml.substr(i, 3) == ']]>')) {
|
||||
else if (char == "]" && (xml.substr(i, 3) == "]]>")) {
|
||||
inCdata = false;
|
||||
}
|
||||
|
||||
else if (char == '-' && (xml.substr(i, 3) == '-->')) {
|
||||
else if (char == "-" && (xml.substr(i, 3) == "-->")) {
|
||||
inCdata = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as vsc from 'vscode';
|
||||
import * as vsc from "vscode";
|
||||
|
||||
export class RangeUtil {
|
||||
static getRangeForDocument(document: vsc.TextDocument): vsc.Range {
|
||||
|
|
Loading…
Add table
Reference in a new issue