mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
Treat style tag contents as css when commenting fixes #31685
This commit is contained in:
@@ -23,6 +23,16 @@ suite('Tests for Toggle Comment action from Emmet (HTML)', () => {
|
||||
<li>Another Node</li>
|
||||
</ul>
|
||||
<span/>
|
||||
<style>
|
||||
.boo {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
.hoo {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -39,6 +49,16 @@ suite('Tests for Toggle Comment action from Emmet (HTML)', () => {
|
||||
<li>Another Node</li>
|
||||
</ul>-->
|
||||
<span/>
|
||||
<style>
|
||||
.boo {
|
||||
/*margin: 10px;*/
|
||||
padding: 20px;
|
||||
}
|
||||
/*.hoo {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
}*/
|
||||
</style>
|
||||
</div>
|
||||
`;
|
||||
return withRandomFileEditor(contents, 'html', (editor, doc) => {
|
||||
@@ -46,7 +66,9 @@ suite('Tests for Toggle Comment action from Emmet (HTML)', () => {
|
||||
new Selection(3, 17, 3, 17), // cursor inside the inner span element
|
||||
new Selection(4, 5, 4, 5), // cursor inside opening tag
|
||||
new Selection(5, 35, 5, 35), // cursor inside closing tag
|
||||
new Selection(7, 3, 7, 3) // cursor inside open tag of <ul> one of of whose children is already commented
|
||||
new Selection(7, 3, 7, 3), // cursor inside open tag of <ul> one of of whose children is already commented
|
||||
new Selection(14, 8, 14, 8), // cursor inside the css property inside the style tag
|
||||
new Selection(18, 3, 18, 3) // cursor inside the css rule inside the style tag
|
||||
];
|
||||
|
||||
return toggleComment().then(() => {
|
||||
@@ -69,13 +91,25 @@ suite('Tests for Toggle Comment action from Emmet (HTML)', () => {
|
||||
<li>Another Node</li>
|
||||
</ul>-->
|
||||
<span/>
|
||||
<style>
|
||||
.boo {
|
||||
/*margin: 10px;*/
|
||||
padding: 20px;
|
||||
}
|
||||
/*.hoo {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
}*/
|
||||
</style>
|
||||
</div>
|
||||
`;
|
||||
return withRandomFileEditor(contents, 'html', (editor, doc) => {
|
||||
editor.selections = [
|
||||
new Selection(3, 7, 3, 25), // <span>Hello</span><
|
||||
new Selection(4, 3, 4, 30), // <li><span>There</span></li>
|
||||
new Selection(7, 2, 10, 7) // The <ul> one of of whose children is already commented
|
||||
new Selection(7, 2, 10, 7), // The <ul> one of of whose children is already commented
|
||||
new Selection(14, 4, 14, 17), // css property inside the style tag
|
||||
new Selection(17, 3, 20, 4) // the css rule inside the style tag
|
||||
];
|
||||
|
||||
return toggleComment().then(() => {
|
||||
@@ -98,11 +132,22 @@ suite('Tests for Toggle Comment action from Emmet (HTML)', () => {
|
||||
<li>Another Node</li>
|
||||
</ul>
|
||||
<span/>
|
||||
<style>
|
||||
.boo {
|
||||
/*margin: 10px;
|
||||
padding: 20px;*/
|
||||
}
|
||||
.hoo {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
`;
|
||||
return withRandomFileEditor(contents, 'html', (editor, doc) => {
|
||||
editor.selections = [
|
||||
new Selection(3, 4, 4, 30)
|
||||
new Selection(3, 4, 4, 30),
|
||||
new Selection(14, 4, 15, 18) // 2 css properties inside the style tag
|
||||
];
|
||||
|
||||
return toggleComment().then(() => {
|
||||
@@ -125,6 +170,16 @@ suite('Tests for Toggle Comment action from Emmet (HTML)', () => {
|
||||
<li>Another Node</li>
|
||||
</ul>-->
|
||||
<span/>
|
||||
<style>
|
||||
.boo {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
.hoo {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
`;
|
||||
return withRandomFileEditor(contents, 'html', (editor, doc) => {
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { getNodesInBetween, getNode, parseDocument } from './util';
|
||||
import { Node, Stylesheet, Rule } from 'EmmetNode';
|
||||
import { getNodesInBetween, getNode, parseDocument, sameNodes } from './util';
|
||||
import { Node, Stylesheet, Rule, HtmlNode } from 'EmmetNode';
|
||||
import { isStyleSheet } from 'vscode-emmet-helper';
|
||||
import parseStylesheet from '@emmetio/css-parser';
|
||||
import { DocumentStreamReader } from './bufferStream';
|
||||
|
||||
const startCommentStylesheet = '/*';
|
||||
const endCommentStylesheet = '*/';
|
||||
@@ -21,17 +23,11 @@ export function toggleComment(): Thenable<boolean> {
|
||||
}
|
||||
|
||||
let toggleCommentInternal;
|
||||
let startComment;
|
||||
let endComment;
|
||||
|
||||
if (isStyleSheet(editor.document.languageId)) {
|
||||
toggleCommentInternal = toggleCommentStylesheet;
|
||||
startComment = startCommentStylesheet;
|
||||
endComment = endCommentStylesheet;
|
||||
} else {
|
||||
toggleCommentInternal = toggleCommentHTML;
|
||||
startComment = startCommentHTML;
|
||||
endComment = endCommentHTML;
|
||||
}
|
||||
|
||||
let rootNode = parseDocument(editor.document);
|
||||
@@ -41,65 +37,73 @@ export function toggleComment(): Thenable<boolean> {
|
||||
|
||||
return editor.edit(editBuilder => {
|
||||
editor.selections.reverse().forEach(selection => {
|
||||
let [rangesToUnComment, rangeToComment] = toggleCommentInternal(editor.document, selection, rootNode);
|
||||
rangesToUnComment.forEach((rangeToUnComment: vscode.Range) => {
|
||||
editBuilder.delete(new vscode.Range(rangeToUnComment.start, rangeToUnComment.start.translate(0, startComment.length)));
|
||||
editBuilder.delete(new vscode.Range(rangeToUnComment.end.translate(0, -endComment.length), rangeToUnComment.end));
|
||||
let edits = toggleCommentInternal(editor.document, selection, rootNode);
|
||||
edits.forEach(x => {
|
||||
editBuilder.replace(x.range, x.newText);
|
||||
});
|
||||
if (rangeToComment) {
|
||||
editBuilder.insert(rangeToComment.start, startComment);
|
||||
editBuilder.insert(rangeToComment.end, endComment);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function toggleCommentHTML(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Node): [vscode.Range[], vscode.Range] {
|
||||
function toggleCommentHTML(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Node): vscode.TextEdit[] {
|
||||
const selectionStart = selection.isReversed ? selection.active : selection.anchor;
|
||||
const selectionEnd = selection.isReversed ? selection.anchor : selection.active;
|
||||
|
||||
let startNode = getNode(rootNode, selectionStart, true);
|
||||
let endNode = getNode(rootNode, selectionEnd, true);
|
||||
let startNode = <HtmlNode>getNode(rootNode, selectionStart, true);
|
||||
let endNode = <HtmlNode>getNode(rootNode, selectionEnd, true);
|
||||
|
||||
if (!startNode || !endNode) {
|
||||
return [[], null];
|
||||
return [];
|
||||
}
|
||||
|
||||
if (sameNodes(startNode, endNode) && startNode.name === 'style'
|
||||
&& startNode.open.end.isBefore(selectionStart)
|
||||
&& startNode.close.start.isAfter(selectionEnd)) {
|
||||
let buffer = new DocumentStreamReader(document, startNode.open.end, new vscode.Range(startNode.open.end, startNode.close.start));
|
||||
let cssRootNode = parseStylesheet(buffer);
|
||||
|
||||
return toggleCommentStylesheet(document, selection, cssRootNode);
|
||||
}
|
||||
|
||||
let allNodes: Node[] = getNodesInBetween(startNode, endNode);
|
||||
let rangesToUnComment: vscode.Range[] = [];
|
||||
let edits: vscode.TextEdit[] = [];
|
||||
|
||||
allNodes.forEach(node => {
|
||||
rangesToUnComment = rangesToUnComment.concat(getRangesToUnCommentHTML(node, document));
|
||||
edits = edits.concat(getRangesToUnCommentHTML(node, document));
|
||||
});
|
||||
|
||||
if (startNode.type === 'comment') {
|
||||
return [rangesToUnComment, null];
|
||||
return edits;
|
||||
}
|
||||
|
||||
let rangeToComment = new vscode.Range(allNodes[0].start, allNodes[allNodes.length - 1].end);
|
||||
return [rangesToUnComment, rangeToComment];
|
||||
|
||||
edits.push(new vscode.TextEdit(new vscode.Range(allNodes[0].start, allNodes[0].start), startCommentHTML));
|
||||
edits.push(new vscode.TextEdit(new vscode.Range(allNodes[allNodes.length - 1].end, allNodes[allNodes.length - 1].end), endCommentHTML));
|
||||
|
||||
return edits;
|
||||
}
|
||||
|
||||
function getRangesToUnCommentHTML(node: Node, document: vscode.TextDocument): vscode.Range[] {
|
||||
let rangesToUnComment = [];
|
||||
function getRangesToUnCommentHTML(node: Node, document: vscode.TextDocument): vscode.TextEdit[] {
|
||||
let unCommentTextEdits: vscode.TextEdit[] = [];
|
||||
|
||||
// If current node is commented, then uncomment and return
|
||||
if (node.type === 'comment') {
|
||||
rangesToUnComment.push(new vscode.Range(node.start, node.end));
|
||||
|
||||
return rangesToUnComment;
|
||||
unCommentTextEdits.push(new vscode.TextEdit(new vscode.Range(node.start, node.start.translate(0, startCommentHTML.length)), ''));
|
||||
unCommentTextEdits.push(new vscode.TextEdit(new vscode.Range(node.end.translate(0, -endCommentHTML.length), node.end), ''));
|
||||
|
||||
return unCommentTextEdits;
|
||||
}
|
||||
|
||||
// All children of current node should be uncommented
|
||||
node.children.forEach(childNode => {
|
||||
rangesToUnComment = rangesToUnComment.concat(getRangesToUnCommentHTML(childNode, document));
|
||||
unCommentTextEdits = unCommentTextEdits.concat(getRangesToUnCommentHTML(childNode, document));
|
||||
});
|
||||
|
||||
return rangesToUnComment;
|
||||
return unCommentTextEdits;
|
||||
}
|
||||
|
||||
function toggleCommentStylesheet(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Stylesheet): [vscode.Range[], vscode.Range] {
|
||||
function toggleCommentStylesheet(document: vscode.TextDocument, selection: vscode.Selection, rootNode: Stylesheet): vscode.TextEdit[] {
|
||||
let selectionStart = selection.isReversed ? selection.active : selection.anchor;
|
||||
let selectionEnd = selection.isReversed ? selection.anchor : selection.active;
|
||||
|
||||
@@ -114,14 +118,26 @@ function toggleCommentStylesheet(document: vscode.TextDocument, selection: vscod
|
||||
|
||||
// Uncomment the comments that intersect with the selection.
|
||||
let rangesToUnComment: vscode.Range[] = [];
|
||||
let edits: vscode.TextEdit[] = [];
|
||||
rootNode.comments.forEach(comment => {
|
||||
let commentRange = new vscode.Range(comment.start, comment.end);
|
||||
if (selection.intersection(commentRange)) {
|
||||
rangesToUnComment.push(commentRange);
|
||||
edits.push(new vscode.TextEdit(new vscode.Range(comment.start, comment.start.translate(0, startCommentStylesheet.length)), ''));
|
||||
edits.push(new vscode.TextEdit(new vscode.Range(comment.end.translate(0, -endCommentStylesheet.length), comment.end), ''));
|
||||
}
|
||||
});
|
||||
|
||||
return [rangesToUnComment, rangesToUnComment.length > 0 ? null : selection];
|
||||
if (edits.length > 0) {
|
||||
return edits;
|
||||
}
|
||||
|
||||
return [
|
||||
new vscode.TextEdit(new vscode.Range(selection.start, selection.start), startCommentStylesheet),
|
||||
new vscode.TextEdit(new vscode.Range(selection.end, selection.end), endCommentStylesheet)
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
||||
function adjustStartNodeCss(node: Node, pos: vscode.Position, rootNode: Stylesheet): vscode.Position {
|
||||
|
||||
@@ -77,7 +77,7 @@ function updateImageSizeStyleTag(editor: TextEditor, position: Position): Promis
|
||||
if (currentNode && currentNode.name === 'style'
|
||||
&& currentNode.open.end.isBefore(position)
|
||||
&& currentNode.close.start.isAfter(position)) {
|
||||
let buffer = new DocumentStreamReader(editor.document, currentNode.start, new Range(currentNode.start, currentNode.end));
|
||||
let buffer = new DocumentStreamReader(editor.document, currentNode.open.end, new Range(currentNode.open.end, currentNode.close.start));
|
||||
let rootNode = parseStylesheet(buffer);
|
||||
const node = getNode(rootNode, position);
|
||||
return (node && node.type === 'property') ? <Property>node : null;
|
||||
|
||||
Reference in New Issue
Block a user