提交 fc6c6931 编写于 作者: R Ramya Achutha Rao

Add typing for emmet node

上级 96524872
...@@ -7,7 +7,7 @@ import * as vscode from 'vscode'; ...@@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import { expand } from '@emmetio/expand-abbreviation'; import { expand } from '@emmetio/expand-abbreviation';
import parseStylesheet from '@emmetio/css-parser'; import parseStylesheet from '@emmetio/css-parser';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { Node, HtmlNode, Rule } from 'EmmetNode';
import { getNode, getInnerRange } from './util'; import { getNode, getInnerRange } from './util';
import { getExpandOptions, extractAbbreviation, isStyleSheet, isAbbreviationValid } from 'vscode-emmet-helper'; import { getExpandOptions, extractAbbreviation, isStyleSheet, isAbbreviationValid } from 'vscode-emmet-helper';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
...@@ -125,12 +125,16 @@ export function isValidLocationForEmmetAbbreviation(currentNode: Node, syntax: s ...@@ -125,12 +125,16 @@ export function isValidLocationForEmmetAbbreviation(currentNode: Node, syntax: s
} }
if (isStyleSheet(syntax)) { if (isStyleSheet(syntax)) {
return currentNode.type !== 'rule' if (currentNode.type !== 'rule') {
|| (currentNode.selectorToken && position.isAfter(currentNode.selectorToken.end)); return true;
}
const currentCssNode = <Rule>currentNode;
return currentCssNode.selectorToken && position.isAfter(currentCssNode.selectorToken.end);
} }
if (currentNode.close) { const currentHtmlNode = <HtmlNode>currentNode;
return getInnerRange(currentNode).contains(position); if (currentHtmlNode.close) {
return getInnerRange(currentHtmlNode).contains(position);
} }
return false; return false;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { HtmlNode } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { isStyleSheet } from 'vscode-emmet-helper'; import { isStyleSheet } from 'vscode-emmet-helper';
import { getNode } from './util'; import { getNode } from './util';
...@@ -29,7 +29,7 @@ function balance(out: boolean) { ...@@ -29,7 +29,7 @@ function balance(out: boolean) {
} }
let getRangeFunction = out ? getRangeToBalanceOut : getRangeToBalanceIn; let getRangeFunction = out ? getRangeToBalanceOut : getRangeToBalanceIn;
let rootNode: Node = parse(new DocumentStreamReader(editor.document)); let rootNode: HtmlNode = parse(new DocumentStreamReader(editor.document));
let newSelections: vscode.Selection[] = []; let newSelections: vscode.Selection[] = [];
editor.selections.forEach(selection => { editor.selections.forEach(selection => {
...@@ -41,8 +41,8 @@ function balance(out: boolean) { ...@@ -41,8 +41,8 @@ function balance(out: boolean) {
editor.selections = newSelections; editor.selections = newSelections;
} }
function getRangeToBalanceOut(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Node): vscode.Selection { function getRangeToBalanceOut(document: vscode.TextDocument, selection: vscode.Selection, rootNode: HtmlNode): vscode.Selection {
let nodeToBalance = getNode(rootNode, selection.start); let nodeToBalance = <HtmlNode>getNode(rootNode, selection.start);
if (!nodeToBalance) { if (!nodeToBalance) {
return; return;
} }
...@@ -62,9 +62,8 @@ function getRangeToBalanceOut(document: vscode.TextDocument, selection: vscode.S ...@@ -62,9 +62,8 @@ function getRangeToBalanceOut(document: vscode.TextDocument, selection: vscode.S
return; return;
} }
function getRangeToBalanceIn(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Node): vscode.Selection { function getRangeToBalanceIn(document: vscode.TextDocument, selection: vscode.Selection, rootNode: HtmlNode): vscode.Selection {
let nodeToBalance: Node = getNode(rootNode, selection.start, true); let nodeToBalance = <HtmlNode>getNode(rootNode, selection.start);
if (!nodeToBalance) { if (!nodeToBalance) {
return; return;
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import parseStylesheet from '@emmetio/css-parser'; import parseStylesheet from '@emmetio/css-parser';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { Node, HtmlNode } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { EmmetCompletionItemProvider, isStyleSheet } from 'vscode-emmet-helper'; import { EmmetCompletionItemProvider, isStyleSheet } from 'vscode-emmet-helper';
import { isValidLocationForEmmetAbbreviation } from './abbreviationActions'; import { isValidLocationForEmmetAbbreviation } from './abbreviationActions';
...@@ -37,12 +37,14 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi ...@@ -37,12 +37,14 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
let rootNode: Node = parseContent(new DocumentStreamReader(document)); let rootNode: Node = parseContent(new DocumentStreamReader(document));
let currentNode = getNode(rootNode, position); let currentNode = getNode(rootNode, position);
if (!isStyleSheet(syntax) if (!isStyleSheet(syntax)) {
&& currentNode const currentHtmlNode = <HtmlNode>currentNode;
&& currentNode.close if (currentHtmlNode
&& currentNode.name === 'style' && currentHtmlNode.close
&& getInnerRange(currentNode).contains(position)) { && currentHtmlNode.name === 'style'
return 'css'; && getInnerRange(currentHtmlNode).contains(position)) {
return 'css';
}
} }
if (!isValidLocationForEmmetAbbreviation(currentNode, syntax, position)) { if (!isValidLocationForEmmetAbbreviation(currentNode, syntax, position)) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { HtmlNode } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { getNode } from './util'; import { getNode } from './util';
...@@ -16,7 +16,7 @@ export function matchTag() { ...@@ -16,7 +16,7 @@ export function matchTag() {
return; return;
} }
let rootNode: Node = parse(new DocumentStreamReader(editor.document)); let rootNode: HtmlNode = parse(new DocumentStreamReader(editor.document));
let updatedSelections = []; let updatedSelections = [];
editor.selections.forEach(selection => { editor.selections.forEach(selection => {
let updatedSelection = getUpdatedSelections(editor, selection.start, rootNode); let updatedSelection = getUpdatedSelections(editor, selection.start, rootNode);
...@@ -30,8 +30,8 @@ export function matchTag() { ...@@ -30,8 +30,8 @@ export function matchTag() {
} }
} }
function getUpdatedSelections(editor: vscode.TextEditor, position: vscode.Position, rootNode: Node): vscode.Selection { function getUpdatedSelections(editor: vscode.TextEditor, position: vscode.Position, rootNode: HtmlNode): vscode.Selection {
let currentNode = getNode(rootNode, position, true); let currentNode = <HtmlNode>getNode(rootNode, position, true);
// If no closing tag or cursor is between open and close tag, then no-op // If no closing tag or cursor is between open and close tag, then no-op
if (!currentNode.close || (position.isAfter(currentNode.open.end) && position.isBefore(currentNode.close.start))) { if (!currentNode.close || (position.isAfter(currentNode.open.end) && position.isBefore(currentNode.close.start))) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { Node } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { isStyleSheet } from 'vscode-emmet-helper'; import { isStyleSheet } from 'vscode-emmet-helper';
import { getNode } from './util'; import { getNode } from './util';
......
...@@ -9,7 +9,7 @@ import { nextItemHTML, prevItemHTML } from './selectItemHTML'; ...@@ -9,7 +9,7 @@ import { nextItemHTML, prevItemHTML } from './selectItemHTML';
import { nextItemStylesheet, prevItemStylesheet } from './selectItemStylesheet'; import { nextItemStylesheet, prevItemStylesheet } from './selectItemStylesheet';
import parseStylesheet from '@emmetio/css-parser'; import parseStylesheet from '@emmetio/css-parser';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { Node } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { isStyleSheet } from 'vscode-emmet-helper'; import { isStyleSheet } from 'vscode-emmet-helper';
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { getDeepestNode, findNextWord, findPrevWord, getNode } from './util'; import { getDeepestNode, findNextWord, findPrevWord, getNode } from './util';
import Node from '@emmetio/node'; import { HtmlNode } from 'EmmetNode';
export function nextItemHTML(selectionStart: vscode.Position, selectionEnd: vscode.Position, editor: vscode.TextEditor, rootNode: Node): vscode.Selection { export function nextItemHTML(selectionStart: vscode.Position, selectionEnd: vscode.Position, editor: vscode.TextEditor, rootNode: HtmlNode): vscode.Selection {
let currentNode = getNode(rootNode, selectionEnd); let currentNode = <HtmlNode>getNode(rootNode, selectionEnd);
let nextNode: Node; let nextNode: HtmlNode;
if (currentNode.type !== 'comment') { if (currentNode.type !== 'comment') {
// If cursor is in the tag name, select tag // If cursor is in the tag name, select tag
...@@ -49,9 +49,9 @@ export function nextItemHTML(selectionStart: vscode.Position, selectionEnd: vsco ...@@ -49,9 +49,9 @@ export function nextItemHTML(selectionStart: vscode.Position, selectionEnd: vsco
return getSelectionFromNode(nextNode, editor.document); return getSelectionFromNode(nextNode, editor.document);
} }
export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vscode.Position, editor: vscode.TextEditor, rootNode: Node): vscode.Selection { export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vscode.Position, editor: vscode.TextEditor, rootNode: HtmlNode): vscode.Selection {
let currentNode = getNode(rootNode, selectionStart); let currentNode = <HtmlNode>getNode(rootNode, selectionStart);
let prevNode: Node; let prevNode: HtmlNode;
if (currentNode.type !== 'comment' && selectionStart.translate(0, -1).isAfter(currentNode.open.start)) { if (currentNode.type !== 'comment' && selectionStart.translate(0, -1).isAfter(currentNode.open.start)) {
...@@ -60,7 +60,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco ...@@ -60,7 +60,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco
} else { } else {
// Select the child that appears just before the cursor and is not a comment // Select the child that appears just before the cursor and is not a comment
prevNode = currentNode.firstChild; prevNode = currentNode.firstChild;
let oldOption: Node; let oldOption: HtmlNode;
while (prevNode.nextSibling && selectionStart.isAfterOrEqual(prevNode.nextSibling.end)) { while (prevNode.nextSibling && selectionStart.isAfterOrEqual(prevNode.nextSibling.end)) {
if (prevNode && prevNode.type !== 'comment') { if (prevNode && prevNode.type !== 'comment') {
oldOption = prevNode; oldOption = prevNode;
...@@ -68,7 +68,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco ...@@ -68,7 +68,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco
prevNode = prevNode.nextSibling; prevNode = prevNode.nextSibling;
} }
prevNode = getDeepestNode((prevNode && prevNode.type !== 'comment') ? prevNode : oldOption); prevNode = <HtmlNode>getDeepestNode((prevNode && prevNode.type !== 'comment') ? prevNode : oldOption);
} }
} }
...@@ -76,7 +76,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco ...@@ -76,7 +76,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco
while (!prevNode && currentNode) { while (!prevNode && currentNode) {
if (currentNode.previousSibling) { if (currentNode.previousSibling) {
if (currentNode.previousSibling.type !== 'comment') { if (currentNode.previousSibling.type !== 'comment') {
prevNode = getDeepestNode(currentNode.previousSibling); prevNode = <HtmlNode>getDeepestNode(currentNode.previousSibling);
} else { } else {
currentNode = currentNode.previousSibling; currentNode = currentNode.previousSibling;
} }
...@@ -90,7 +90,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco ...@@ -90,7 +90,7 @@ export function prevItemHTML(selectionStart: vscode.Position, selectionEnd: vsco
return attrSelection ? attrSelection : getSelectionFromNode(prevNode, editor.document); return attrSelection ? attrSelection : getSelectionFromNode(prevNode, editor.document);
} }
function getSelectionFromNode(node: Node, document: vscode.TextDocument): vscode.Selection { function getSelectionFromNode(node: HtmlNode, document: vscode.TextDocument): vscode.Selection {
if (node && node.open) { if (node && node.open) {
let selectionStart = (<vscode.Position>node.open.start).translate(0, 1); let selectionStart = (<vscode.Position>node.open.start).translate(0, 1);
let selectionEnd = selectionStart.translate(0, node.name.length); let selectionEnd = selectionStart.translate(0, node.name.length);
...@@ -99,7 +99,7 @@ function getSelectionFromNode(node: Node, document: vscode.TextDocument): vscode ...@@ -99,7 +99,7 @@ function getSelectionFromNode(node: Node, document: vscode.TextDocument): vscode
} }
} }
function getNextAttribute(selectionStart: vscode.Position, selectionEnd: vscode.Position, document: vscode.TextDocument, node: Node): vscode.Selection { function getNextAttribute(selectionStart: vscode.Position, selectionEnd: vscode.Position, document: vscode.TextDocument, node: HtmlNode): vscode.Selection {
if (!node.attributes || node.attributes.length === 0 || node.type === 'comment') { if (!node.attributes || node.attributes.length === 0 || node.type === 'comment') {
return; return;
...@@ -150,7 +150,7 @@ function getNextAttribute(selectionStart: vscode.Position, selectionEnd: vscode. ...@@ -150,7 +150,7 @@ function getNextAttribute(selectionStart: vscode.Position, selectionEnd: vscode.
} }
} }
function getPrevAttribute(selectionStart: vscode.Position, selectionEnd: vscode.Position, document: vscode.TextDocument, node: Node): vscode.Selection { function getPrevAttribute(selectionStart: vscode.Position, selectionEnd: vscode.Position, document: vscode.TextDocument, node: HtmlNode): vscode.Selection {
if (!node.attributes || node.attributes.length === 0 || node.type === 'comment') { if (!node.attributes || node.attributes.length === 0 || node.type === 'comment') {
return; return;
......
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { getDeepestNode, findNextWord, findPrevWord, getNode } from './util'; import { getDeepestNode, findNextWord, findPrevWord, getNode } from './util';
import Node from '@emmetio/node'; import { Node, CssNode, Rule, Property } from 'EmmetNode';
export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vscode.Position, editor: vscode.TextEditor, rootNode: Node): vscode.Selection { export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vscode.Position, editor: vscode.TextEditor, rootNode: Node): vscode.Selection {
let currentNode = getNode(rootNode, endOffset, true); let currentNode = <CssNode>getNode(rootNode, endOffset, true);
if (!currentNode) { if (!currentNode) {
currentNode = rootNode; currentNode = <CssNode>rootNode;
} }
// Full property is selected, so select full property value next // Full property is selected, so select full property value next
...@@ -19,7 +19,7 @@ export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vsco ...@@ -19,7 +19,7 @@ export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vsco
} }
// Part or whole of propertyValue is selected, so select the next word in the propertyValue // Part or whole of propertyValue is selected, so select the next word in the propertyValue
if (currentNode.type === 'property' && startOffset.isAfterOrEqual(currentNode.valueToken.start) && endOffset.isBeforeOrEqual(currentNode.valueToken.end)) { if (currentNode.type === 'property' && startOffset.isAfterOrEqual((<Property>currentNode).valueToken.start) && endOffset.isBeforeOrEqual((<Property>currentNode).valueToken.end)) {
let singlePropertyValue = getSelectionFromProperty(currentNode, editor.document, startOffset, endOffset, false, 'next'); let singlePropertyValue = getSelectionFromProperty(currentNode, editor.document, startOffset, endOffset, false, 'next');
if (singlePropertyValue) { if (singlePropertyValue) {
return singlePropertyValue; return singlePropertyValue;
...@@ -27,8 +27,8 @@ export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vsco ...@@ -27,8 +27,8 @@ export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vsco
} }
// Cursor is in the selector or in a property // Cursor is in the selector or in a property
if ((currentNode.type === 'rule' && endOffset.isBefore(currentNode.selectorToken.end)) if ((currentNode.type === 'rule' && endOffset.isBefore((<Rule>currentNode).selectorToken.end))
|| (currentNode.type === 'property' && endOffset.isBefore(currentNode.valueToken.end))) { || (currentNode.type === 'property' && endOffset.isBefore((<Property>currentNode).valueToken.end))) {
return getSelectionFromNode(currentNode, editor.document); return getSelectionFromNode(currentNode, editor.document);
} }
...@@ -48,19 +48,19 @@ export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vsco ...@@ -48,19 +48,19 @@ export function nextItemStylesheet(startOffset: vscode.Position, endOffset: vsco
} }
export function prevItemStylesheet(startOffset: vscode.Position, endOffset: vscode.Position, editor: vscode.TextEditor, rootNode: Node): vscode.Selection { export function prevItemStylesheet(startOffset: vscode.Position, endOffset: vscode.Position, editor: vscode.TextEditor, rootNode: CssNode): vscode.Selection {
let currentNode = getNode(rootNode, startOffset); let currentNode = <CssNode>getNode(rootNode, startOffset);
if (!currentNode) { if (!currentNode) {
currentNode = rootNode; currentNode = rootNode;
} }
// Full property value is selected, so select the whole property next // Full property value is selected, so select the whole property next
if (currentNode.type === 'property' && startOffset.isEqual(currentNode.valueToken.start) && endOffset.isEqual(currentNode.valueToken.end)) { if (currentNode.type === 'property' && startOffset.isEqual((<Property>currentNode).valueToken.start) && endOffset.isEqual((<Property>currentNode).valueToken.end)) {
return getSelectionFromNode(currentNode, editor.document); return getSelectionFromNode(currentNode, editor.document);
} }
// Part of propertyValue is selected, so select the prev word in the propertyValue // Part of propertyValue is selected, so select the prev word in the propertyValue
if (currentNode.type === 'property' && startOffset.isAfterOrEqual(currentNode.valueToken.start) && endOffset.isBeforeOrEqual(currentNode.valueToken.end)) { if (currentNode.type === 'property' && startOffset.isAfterOrEqual((<Property>currentNode).valueToken.start) && endOffset.isBeforeOrEqual((<Property>currentNode).valueToken.end)) {
let singlePropertyValue = getSelectionFromProperty(currentNode, editor.document, startOffset, endOffset, false, 'prev'); let singlePropertyValue = getSelectionFromProperty(currentNode, editor.document, startOffset, endOffset, false, 'prev');
if (singlePropertyValue) { if (singlePropertyValue) {
return singlePropertyValue; return singlePropertyValue;
...@@ -76,7 +76,7 @@ export function prevItemStylesheet(startOffset: vscode.Position, endOffset: vsco ...@@ -76,7 +76,7 @@ export function prevItemStylesheet(startOffset: vscode.Position, endOffset: vsco
while (prevNode.nextSibling && startOffset.isAfterOrEqual(prevNode.nextSibling.end)) { while (prevNode.nextSibling && startOffset.isAfterOrEqual(prevNode.nextSibling.end)) {
prevNode = prevNode.nextSibling; prevNode = prevNode.nextSibling;
} }
prevNode = getDeepestNode(prevNode); prevNode = <CssNode>getDeepestNode(prevNode);
return getSelectionFromProperty(prevNode, editor.document, startOffset, endOffset, false, 'prev'); return getSelectionFromProperty(prevNode, editor.document, startOffset, endOffset, false, 'prev');
...@@ -88,7 +88,7 @@ function getSelectionFromNode(node: Node, document: vscode.TextDocument): vscode ...@@ -88,7 +88,7 @@ function getSelectionFromNode(node: Node, document: vscode.TextDocument): vscode
return; return;
} }
let nodeToSelect = node.type === 'rule' ? node.selectorToken : node; let nodeToSelect = node.type === 'rule' ? (<Rule>node).selectorToken : node;
return new vscode.Selection(nodeToSelect.start, nodeToSelect.end); return new vscode.Selection(nodeToSelect.start, nodeToSelect.end);
} }
...@@ -97,27 +97,28 @@ function getSelectionFromProperty(node: Node, document: vscode.TextDocument, sel ...@@ -97,27 +97,28 @@ function getSelectionFromProperty(node: Node, document: vscode.TextDocument, sel
if (!node || node.type !== 'property') { if (!node || node.type !== 'property') {
return; return;
} }
const propertyNode = <Property>node;
let propertyValue = node.valueToken.stream.substring(node.valueToken.start, node.valueToken.end); let propertyValue = propertyNode.valueToken.stream.substring(propertyNode.valueToken.start, propertyNode.valueToken.end);
selectFullValue = selectFullValue || (direction === 'prev' && selectionStart.isEqual(node.valueToken.start) && selectionEnd.isBefore(node.valueToken.end)); selectFullValue = selectFullValue || (direction === 'prev' && selectionStart.isEqual(propertyNode.valueToken.start) && selectionEnd.isBefore(propertyNode.valueToken.end));
if (selectFullValue) { if (selectFullValue) {
return new vscode.Selection(node.valueToken.start, node.valueToken.end); return new vscode.Selection(propertyNode.valueToken.start, propertyNode.valueToken.end);
} }
let pos; let pos;
if (direction === 'prev') { if (direction === 'prev') {
if (selectionStart.isEqual(node.valueToken.start)) { if (selectionStart.isEqual(propertyNode.valueToken.start)) {
return; return;
} }
pos = selectionStart.isAfter(node.valueToken.end) ? propertyValue.length : selectionStart.character - node.valueToken.start.character; pos = selectionStart.isAfter(propertyNode.valueToken.end) ? propertyValue.length : selectionStart.character - propertyNode.valueToken.start.character;
} }
if (direction === 'next') { if (direction === 'next') {
if (selectionEnd.isEqual(node.valueToken.end) && (selectionStart.isAfter(node.valueToken.start) || propertyValue.indexOf(' ') === -1)) { if (selectionEnd.isEqual(propertyNode.valueToken.end) && (selectionStart.isAfter(propertyNode.valueToken.start) || propertyValue.indexOf(' ') === -1)) {
return; return;
} }
pos = selectionEnd.isEqual(node.valueToken.end) ? -1 : selectionEnd.character - node.valueToken.start.character - 1; pos = selectionEnd.isEqual(propertyNode.valueToken.end) ? -1 : selectionEnd.character - propertyNode.valueToken.start.character - 1;
} }
...@@ -126,8 +127,8 @@ function getSelectionFromProperty(node: Node, document: vscode.TextDocument, sel ...@@ -126,8 +127,8 @@ function getSelectionFromProperty(node: Node, document: vscode.TextDocument, sel
return; return;
} }
const newSelectionStart = (<vscode.Position>node.valueToken.start).translate(0, newSelectionStartOffset); const newSelectionStart = (<vscode.Position>propertyNode.valueToken.start).translate(0, newSelectionStartOffset);
const newSelectionEnd = (<vscode.Position>node.valueToken.start).translate(0, newSelectionEndOffset); const newSelectionEnd = (<vscode.Position>propertyNode.valueToken.start).translate(0, newSelectionEndOffset);
return new vscode.Selection(newSelectionStart, newSelectionEnd); return new vscode.Selection(newSelectionStart, newSelectionEnd);
} }
......
...@@ -7,7 +7,7 @@ import * as vscode from 'vscode'; ...@@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import { getNodesInBetween, getNode } from './util'; import { getNodesInBetween, getNode } from './util';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import parseStylesheet from '@emmetio/css-parser'; import parseStylesheet from '@emmetio/css-parser';
import Node from '@emmetio/node'; import { Node, Stylesheet } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { isStyleSheet } from 'vscode-emmet-helper'; import { isStyleSheet } from 'vscode-emmet-helper';
...@@ -102,7 +102,7 @@ function getRangesToUnCommentHTML(node: Node, document: vscode.TextDocument): vs ...@@ -102,7 +102,7 @@ function getRangesToUnCommentHTML(node: Node, document: vscode.TextDocument): vs
return rangesToUnComment; return rangesToUnComment;
} }
function toggleCommentStylesheet(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Node): [vscode.Range[], vscode.Range] { function toggleCommentStylesheet(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Stylesheet): [vscode.Range[], vscode.Range] {
const selectionStart = selection.isReversed ? selection.active : selection.anchor; const selectionStart = selection.isReversed ? selection.active : selection.anchor;
const selectionEnd = selection.isReversed ? selection.anchor : selection.active; const selectionEnd = selection.isReversed ? selection.anchor : selection.active;
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'EmmetNode' {
import { Position } from 'vscode';
export interface Node {
start: Position
end: Position
type: string
parent: Node
firstChild: Node
nextSibling: Node
previousSibling: Node
children: Node[]
}
export interface Token {
start: Position
end: Position
stream: BufferStream
toString(): string
}
export interface Attribute extends Token {
name: string
value: Token
}
export interface HtmlNode extends Node {
name: string
open: Token
close: Token
parent: HtmlNode
firstChild: HtmlNode
nextSibling: HtmlNode
previousSibling: HtmlNode
children: HtmlNode[]
attributes: Attribute[]
}
export interface CssNode extends Node {
parent: CssNode
firstChild: CssNode
nextSibling: CssNode
previousSibling: CssNode
children: CssNode[]
}
export interface Rule extends CssNode {
selectorToken: Token
}
export interface Property extends CssNode {
valueToken: Token
}
export interface Stylesheet extends Node {
comments: Token[]
}
export interface BufferStream {
peek(): number
next(): number
backUp(n: number): number
current(): string
substring(from: Position, to: Position): string
eat(match): boolean
eatWhile(match): boolean
}
}
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { HtmlNode } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { getNode } from './util'; import { getNode } from './util';
...@@ -16,7 +16,7 @@ export function updateTag(tagName: string) { ...@@ -16,7 +16,7 @@ export function updateTag(tagName: string) {
return; return;
} }
let rootNode: Node = parse(new DocumentStreamReader(editor.document)); let rootNode: HtmlNode = parse(new DocumentStreamReader(editor.document));
let rangesToUpdate = []; let rangesToUpdate = [];
editor.selections.reverse().forEach(selection => { editor.selections.reverse().forEach(selection => {
rangesToUpdate = rangesToUpdate.concat(getRangesToUpdate(editor, selection, rootNode)); rangesToUpdate = rangesToUpdate.concat(getRangesToUpdate(editor, selection, rootNode));
...@@ -29,8 +29,8 @@ export function updateTag(tagName: string) { ...@@ -29,8 +29,8 @@ export function updateTag(tagName: string) {
}); });
} }
function getRangesToUpdate(editor: vscode.TextEditor, selection: vscode.Selection, rootNode: Node): vscode.Range[] { function getRangesToUpdate(editor: vscode.TextEditor, selection: vscode.Selection, rootNode: HtmlNode): vscode.Range[] {
let nodeToUpdate = getNode(rootNode, selection.start); let nodeToUpdate = <HtmlNode>getNode(rootNode, selection.start);
let openStart = (<vscode.Position>nodeToUpdate.open.start).translate(0, 1); let openStart = (<vscode.Position>nodeToUpdate.open.start).translate(0, 1);
let openEnd = openStart.translate(0, nodeToUpdate.name.length); let openEnd = openStart.translate(0, nodeToUpdate.name.length);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import parse from '@emmetio/html-matcher'; import parse from '@emmetio/html-matcher';
import Node from '@emmetio/node'; import { Node, HtmlNode } from 'EmmetNode';
import { DocumentStreamReader } from './bufferStream'; import { DocumentStreamReader } from './bufferStream';
import { isStyleSheet } from 'vscode-emmet-helper'; import { isStyleSheet } from 'vscode-emmet-helper';
...@@ -69,7 +69,7 @@ export function getExcludedModes(): string[] { ...@@ -69,7 +69,7 @@ export function getExcludedModes(): string[] {
* @param includeNodeBoundary * @param includeNodeBoundary
*/ */
export function getNode(root: Node, position: vscode.Position, includeNodeBoundary: boolean = false) { export function getNode(root: Node, position: vscode.Position, includeNodeBoundary: boolean = false) {
let currentNode: Node = root.firstChild; let currentNode = root.firstChild;
let foundNode: Node = null; let foundNode: Node = null;
while (currentNode) { while (currentNode) {
...@@ -93,7 +93,7 @@ export function getNode(root: Node, position: vscode.Position, includeNodeBounda ...@@ -93,7 +93,7 @@ export function getNode(root: Node, position: vscode.Position, includeNodeBounda
* Returns inner range of an html node. * Returns inner range of an html node.
* @param currentNode * @param currentNode
*/ */
export function getInnerRange(currentNode: Node): vscode.Range { export function getInnerRange(currentNode: HtmlNode): vscode.Range {
if (!currentNode.close) { if (!currentNode.close) {
return; return;
} }
...@@ -101,8 +101,8 @@ export function getInnerRange(currentNode: Node): vscode.Range { ...@@ -101,8 +101,8 @@ export function getInnerRange(currentNode: Node): vscode.Range {
} }
export function getOpenCloseRange(document: vscode.TextDocument, position: vscode.Position): [vscode.Range, vscode.Range] { export function getOpenCloseRange(document: vscode.TextDocument, position: vscode.Position): [vscode.Range, vscode.Range] {
let rootNode: Node = parse(new DocumentStreamReader(document)); let rootNode: HtmlNode = parse(new DocumentStreamReader(document));
let nodeToUpdate = getNode(rootNode, position); let nodeToUpdate = <HtmlNode>getNode(rootNode, position);
let openRange = new vscode.Range(nodeToUpdate.open.start, nodeToUpdate.open.end); let openRange = new vscode.Range(nodeToUpdate.open.start, nodeToUpdate.open.end);
let closeRange = null; let closeRange = null;
if (nodeToUpdate.close) { if (nodeToUpdate.close) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册