44 *--------------------------------------------------------------------------------------------*/
55
66import * as vscode from 'vscode' ;
7- import { getNodesInBetween , getNode , parseDocument } from './util' ;
8- import { Node , Stylesheet , Rule } from 'EmmetNode' ;
7+ import { getNodesInBetween , getNode , parseDocument , sameNodes } from './util' ;
8+ import { Node , Stylesheet , Rule , HtmlNode } from 'EmmetNode' ;
99import { isStyleSheet } from 'vscode-emmet-helper' ;
10+ import parseStylesheet from '@emmetio/css-parser' ;
11+ import { DocumentStreamReader } from './bufferStream' ;
1012
1113const startCommentStylesheet = '/*' ;
1214const endCommentStylesheet = '*/' ;
@@ -21,17 +23,11 @@ export function toggleComment(): Thenable<boolean> {
2123 }
2224
2325 let toggleCommentInternal ;
24- let startComment ;
25- let endComment ;
2626
2727 if ( isStyleSheet ( editor . document . languageId ) ) {
2828 toggleCommentInternal = toggleCommentStylesheet ;
29- startComment = startCommentStylesheet ;
30- endComment = endCommentStylesheet ;
3129 } else {
3230 toggleCommentInternal = toggleCommentHTML ;
33- startComment = startCommentHTML ;
34- endComment = endCommentHTML ;
3531 }
3632
3733 let rootNode = parseDocument ( editor . document ) ;
@@ -41,65 +37,73 @@ export function toggleComment(): Thenable<boolean> {
4137
4238 return editor . edit ( editBuilder => {
4339 editor . selections . reverse ( ) . forEach ( selection => {
44- let [ rangesToUnComment , rangeToComment ] = toggleCommentInternal ( editor . document , selection , rootNode ) ;
45- rangesToUnComment . forEach ( ( rangeToUnComment : vscode . Range ) => {
46- editBuilder . delete ( new vscode . Range ( rangeToUnComment . start , rangeToUnComment . start . translate ( 0 , startComment . length ) ) ) ;
47- editBuilder . delete ( new vscode . Range ( rangeToUnComment . end . translate ( 0 , - endComment . length ) , rangeToUnComment . end ) ) ;
40+ let edits = toggleCommentInternal ( editor . document , selection , rootNode ) ;
41+ edits . forEach ( x => {
42+ editBuilder . replace ( x . range , x . newText ) ;
4843 } ) ;
49- if ( rangeToComment ) {
50- editBuilder . insert ( rangeToComment . start , startComment ) ;
51- editBuilder . insert ( rangeToComment . end , endComment ) ;
52- }
53-
5444 } ) ;
5545 } ) ;
5646}
5747
58- function toggleCommentHTML ( document : vscode . TextDocument , selection : vscode . Selection , rootNode : Node ) : [ vscode . Range [ ] , vscode . Range ] {
48+ function toggleCommentHTML ( document : vscode . TextDocument , selection : vscode . Selection , rootNode : Node ) : vscode . TextEdit [ ] {
5949 const selectionStart = selection . isReversed ? selection . active : selection . anchor ;
6050 const selectionEnd = selection . isReversed ? selection . anchor : selection . active ;
6151
62- let startNode = getNode ( rootNode , selectionStart , true ) ;
63- let endNode = getNode ( rootNode , selectionEnd , true ) ;
52+ let startNode = < HtmlNode > getNode ( rootNode , selectionStart , true ) ;
53+ let endNode = < HtmlNode > getNode ( rootNode , selectionEnd , true ) ;
6454
6555 if ( ! startNode || ! endNode ) {
66- return [ [ ] , null ] ;
56+ return [ ] ;
57+ }
58+
59+ if ( sameNodes ( startNode , endNode ) && startNode . name === 'style'
60+ && startNode . open . end . isBefore ( selectionStart )
61+ && startNode . close . start . isAfter ( selectionEnd ) ) {
62+ let buffer = new DocumentStreamReader ( document , startNode . open . end , new vscode . Range ( startNode . open . end , startNode . close . start ) ) ;
63+ let cssRootNode = parseStylesheet ( buffer ) ;
64+
65+ return toggleCommentStylesheet ( document , selection , cssRootNode ) ;
6766 }
6867
6968 let allNodes : Node [ ] = getNodesInBetween ( startNode , endNode ) ;
70- let rangesToUnComment : vscode . Range [ ] = [ ] ;
69+ let edits : vscode . TextEdit [ ] = [ ] ;
7170
7271 allNodes . forEach ( node => {
73- rangesToUnComment = rangesToUnComment . concat ( getRangesToUnCommentHTML ( node , document ) ) ;
72+ edits = edits . concat ( getRangesToUnCommentHTML ( node , document ) ) ;
7473 } ) ;
7574
7675 if ( startNode . type === 'comment' ) {
77- return [ rangesToUnComment , null ] ;
76+ return edits ;
7877 }
7978
80- let rangeToComment = new vscode . Range ( allNodes [ 0 ] . start , allNodes [ allNodes . length - 1 ] . end ) ;
81- return [ rangesToUnComment , rangeToComment ] ;
79+
80+ edits . push ( new vscode . TextEdit ( new vscode . Range ( allNodes [ 0 ] . start , allNodes [ 0 ] . start ) , startCommentHTML ) ) ;
81+ edits . push ( new vscode . TextEdit ( new vscode . Range ( allNodes [ allNodes . length - 1 ] . end , allNodes [ allNodes . length - 1 ] . end ) , endCommentHTML ) ) ;
82+
83+ return edits ;
8284}
8385
84- function getRangesToUnCommentHTML ( node : Node , document : vscode . TextDocument ) : vscode . Range [ ] {
85- let rangesToUnComment = [ ] ;
86+ function getRangesToUnCommentHTML ( node : Node , document : vscode . TextDocument ) : vscode . TextEdit [ ] {
87+ let unCommentTextEdits : vscode . TextEdit [ ] = [ ] ;
8688
8789 // If current node is commented, then uncomment and return
8890 if ( node . type === 'comment' ) {
89- rangesToUnComment . push ( new vscode . Range ( node . start , node . end ) ) ;
9091
91- return rangesToUnComment ;
92+ unCommentTextEdits . push ( new vscode . TextEdit ( new vscode . Range ( node . start , node . start . translate ( 0 , startCommentHTML . length ) ) , '' ) ) ;
93+ unCommentTextEdits . push ( new vscode . TextEdit ( new vscode . Range ( node . end . translate ( 0 , - endCommentHTML . length ) , node . end ) , '' ) ) ;
94+
95+ return unCommentTextEdits ;
9296 }
9397
9498 // All children of current node should be uncommented
9599 node . children . forEach ( childNode => {
96- rangesToUnComment = rangesToUnComment . concat ( getRangesToUnCommentHTML ( childNode , document ) ) ;
100+ unCommentTextEdits = unCommentTextEdits . concat ( getRangesToUnCommentHTML ( childNode , document ) ) ;
97101 } ) ;
98102
99- return rangesToUnComment ;
103+ return unCommentTextEdits ;
100104}
101105
102- function toggleCommentStylesheet ( document : vscode . TextDocument , selection : vscode . Selection , rootNode : Stylesheet ) : [ vscode . Range [ ] , vscode . Range ] {
106+ function toggleCommentStylesheet ( document : vscode . TextDocument , selection : vscode . Selection , rootNode : Stylesheet ) : vscode . TextEdit [ ] {
103107 let selectionStart = selection . isReversed ? selection . active : selection . anchor ;
104108 let selectionEnd = selection . isReversed ? selection . anchor : selection . active ;
105109
@@ -114,14 +118,26 @@ function toggleCommentStylesheet(document: vscode.TextDocument, selection: vscod
114118
115119 // Uncomment the comments that intersect with the selection.
116120 let rangesToUnComment : vscode . Range [ ] = [ ] ;
121+ let edits : vscode . TextEdit [ ] = [ ] ;
117122 rootNode . comments . forEach ( comment => {
118123 let commentRange = new vscode . Range ( comment . start , comment . end ) ;
119124 if ( selection . intersection ( commentRange ) ) {
120125 rangesToUnComment . push ( commentRange ) ;
126+ edits . push ( new vscode . TextEdit ( new vscode . Range ( comment . start , comment . start . translate ( 0 , startCommentStylesheet . length ) ) , '' ) ) ;
127+ edits . push ( new vscode . TextEdit ( new vscode . Range ( comment . end . translate ( 0 , - endCommentStylesheet . length ) , comment . end ) , '' ) ) ;
121128 }
122129 } ) ;
123130
124- return [ rangesToUnComment , rangesToUnComment . length > 0 ? null : selection ] ;
131+ if ( edits . length > 0 ) {
132+ return edits ;
133+ }
134+
135+ return [
136+ new vscode . TextEdit ( new vscode . Range ( selection . start , selection . start ) , startCommentStylesheet ) ,
137+ new vscode . TextEdit ( new vscode . Range ( selection . end , selection . end ) , endCommentStylesheet )
138+ ] ;
139+
140+
125141}
126142
127143function adjustStartNodeCss ( node : Node , pos : vscode . Position , rootNode : Stylesheet ) : vscode . Position {
0 commit comments