🎉 initiate project *astro_rewrite*
This commit is contained in:
		
							parent
							
								
									ffd4d5e86c
								
							
						
					
					
						commit
						2ba37bfbe3
					
				
					 8658 changed files with 2268794 additions and 2538 deletions
				
			
		
							
								
								
									
										585
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlCompletion.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										585
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlCompletion.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,585 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../parser/htmlScanner", "../htmlLanguageTypes", "../parser/htmlEntities", "@vscode/l10n", "../utils/strings", "../utils/object", "../languageFacts/dataProvider", "./pathCompletion"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.HTMLCompletion = void 0; | ||||
|     const htmlScanner_1 = require("../parser/htmlScanner"); | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     const htmlEntities_1 = require("../parser/htmlEntities"); | ||||
|     const l10n = require("@vscode/l10n"); | ||||
|     const strings_1 = require("../utils/strings"); | ||||
|     const object_1 = require("../utils/object"); | ||||
|     const dataProvider_1 = require("../languageFacts/dataProvider"); | ||||
|     const pathCompletion_1 = require("./pathCompletion"); | ||||
|     class HTMLCompletion { | ||||
|         constructor(lsOptions, dataManager) { | ||||
|             this.lsOptions = lsOptions; | ||||
|             this.dataManager = dataManager; | ||||
|             this.completionParticipants = []; | ||||
|         } | ||||
|         setCompletionParticipants(registeredCompletionParticipants) { | ||||
|             this.completionParticipants = registeredCompletionParticipants || []; | ||||
|         } | ||||
|         async doComplete2(document, position, htmlDocument, documentContext, settings) { | ||||
|             if (!this.lsOptions.fileSystemProvider || !this.lsOptions.fileSystemProvider.readDirectory) { | ||||
|                 return this.doComplete(document, position, htmlDocument, settings); | ||||
|             } | ||||
|             const participant = new pathCompletion_1.PathCompletionParticipant(this.dataManager, this.lsOptions.fileSystemProvider.readDirectory); | ||||
|             const contributedParticipants = this.completionParticipants; | ||||
|             this.completionParticipants = [participant].concat(contributedParticipants); | ||||
|             const result = this.doComplete(document, position, htmlDocument, settings); | ||||
|             try { | ||||
|                 const pathCompletionResult = await participant.computeCompletions(document, documentContext); | ||||
|                 return { | ||||
|                     isIncomplete: result.isIncomplete || pathCompletionResult.isIncomplete, | ||||
|                     items: pathCompletionResult.items.concat(result.items) | ||||
|                 }; | ||||
|             } | ||||
|             finally { | ||||
|                 this.completionParticipants = contributedParticipants; | ||||
|             } | ||||
|         } | ||||
|         doComplete(document, position, htmlDocument, settings) { | ||||
|             const result = this._doComplete(document, position, htmlDocument, settings); | ||||
|             return this.convertCompletionList(result); | ||||
|         } | ||||
|         _doComplete(document, position, htmlDocument, settings) { | ||||
|             const result = { | ||||
|                 isIncomplete: false, | ||||
|                 items: [] | ||||
|             }; | ||||
|             const completionParticipants = this.completionParticipants; | ||||
|             const dataProviders = this.dataManager.getDataProviders().filter(p => p.isApplicable(document.languageId) && (!settings || settings[p.getId()] !== false)); | ||||
|             const voidElements = this.dataManager.getVoidElements(dataProviders); | ||||
|             const doesSupportMarkdown = this.doesSupportMarkdown(); | ||||
|             const text = document.getText(); | ||||
|             const offset = document.offsetAt(position); | ||||
|             const node = htmlDocument.findNodeBefore(offset); | ||||
|             if (!node) { | ||||
|                 return result; | ||||
|             } | ||||
|             const scanner = (0, htmlScanner_1.createScanner)(text, node.start); | ||||
|             let currentTag = ''; | ||||
|             let currentAttributeName; | ||||
|             function getReplaceRange(replaceStart, replaceEnd = offset) { | ||||
|                 if (replaceStart > offset) { | ||||
|                     replaceStart = offset; | ||||
|                 } | ||||
|                 return { start: document.positionAt(replaceStart), end: document.positionAt(replaceEnd) }; | ||||
|             } | ||||
|             function collectOpenTagSuggestions(afterOpenBracket, tagNameEnd) { | ||||
|                 const range = getReplaceRange(afterOpenBracket, tagNameEnd); | ||||
|                 dataProviders.forEach((provider) => { | ||||
|                     provider.provideTags().forEach(tag => { | ||||
|                         result.items.push({ | ||||
|                             label: tag.name, | ||||
|                             kind: htmlLanguageTypes_1.CompletionItemKind.Property, | ||||
|                             documentation: (0, dataProvider_1.generateDocumentation)(tag, undefined, doesSupportMarkdown), | ||||
|                             textEdit: htmlLanguageTypes_1.TextEdit.replace(range, tag.name), | ||||
|                             insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.PlainText | ||||
|                         }); | ||||
|                     }); | ||||
|                 }); | ||||
|                 return result; | ||||
|             } | ||||
|             function getLineIndent(offset) { | ||||
|                 let start = offset; | ||||
|                 while (start > 0) { | ||||
|                     const ch = text.charAt(start - 1); | ||||
|                     if ("\n\r".indexOf(ch) >= 0) { | ||||
|                         return text.substring(start, offset); | ||||
|                     } | ||||
|                     if (!isWhiteSpace(ch)) { | ||||
|                         return null; | ||||
|                     } | ||||
|                     start--; | ||||
|                 } | ||||
|                 return text.substring(0, offset); | ||||
|             } | ||||
|             function collectCloseTagSuggestions(afterOpenBracket, inOpenTag, tagNameEnd = offset) { | ||||
|                 const range = getReplaceRange(afterOpenBracket, tagNameEnd); | ||||
|                 const closeTag = isFollowedBy(text, tagNameEnd, htmlLanguageTypes_1.ScannerState.WithinEndTag, htmlLanguageTypes_1.TokenType.EndTagClose) ? '' : '>'; | ||||
|                 let curr = node; | ||||
|                 if (inOpenTag) { | ||||
|                     curr = curr.parent; // don't suggest the own tag, it's not yet open
 | ||||
|                 } | ||||
|                 while (curr) { | ||||
|                     const tag = curr.tag; | ||||
|                     if (tag && (!curr.closed || curr.endTagStart && (curr.endTagStart > offset))) { | ||||
|                         const item = { | ||||
|                             label: '/' + tag, | ||||
|                             kind: htmlLanguageTypes_1.CompletionItemKind.Property, | ||||
|                             filterText: '/' + tag, | ||||
|                             textEdit: htmlLanguageTypes_1.TextEdit.replace(range, '/' + tag + closeTag), | ||||
|                             insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.PlainText | ||||
|                         }; | ||||
|                         const startIndent = getLineIndent(curr.start); | ||||
|                         const endIndent = getLineIndent(afterOpenBracket - 1); | ||||
|                         if (startIndent !== null && endIndent !== null && startIndent !== endIndent) { | ||||
|                             const insertText = startIndent + '</' + tag + closeTag; | ||||
|                             item.textEdit = htmlLanguageTypes_1.TextEdit.replace(getReplaceRange(afterOpenBracket - 1 - endIndent.length), insertText); | ||||
|                             item.filterText = endIndent + '</' + tag; | ||||
|                         } | ||||
|                         result.items.push(item); | ||||
|                         return result; | ||||
|                     } | ||||
|                     curr = curr.parent; | ||||
|                 } | ||||
|                 if (inOpenTag) { | ||||
|                     return result; | ||||
|                 } | ||||
|                 dataProviders.forEach(provider => { | ||||
|                     provider.provideTags().forEach(tag => { | ||||
|                         result.items.push({ | ||||
|                             label: '/' + tag.name, | ||||
|                             kind: htmlLanguageTypes_1.CompletionItemKind.Property, | ||||
|                             documentation: (0, dataProvider_1.generateDocumentation)(tag, undefined, doesSupportMarkdown), | ||||
|                             filterText: '/' + tag.name + closeTag, | ||||
|                             textEdit: htmlLanguageTypes_1.TextEdit.replace(range, '/' + tag.name + closeTag), | ||||
|                             insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.PlainText | ||||
|                         }); | ||||
|                     }); | ||||
|                 }); | ||||
|                 return result; | ||||
|             } | ||||
|             const collectAutoCloseTagSuggestion = (tagCloseEnd, tag) => { | ||||
|                 if (settings && settings.hideAutoCompleteProposals) { | ||||
|                     return result; | ||||
|                 } | ||||
|                 if (!this.dataManager.isVoidElement(tag, voidElements)) { | ||||
|                     const pos = document.positionAt(tagCloseEnd); | ||||
|                     result.items.push({ | ||||
|                         label: '</' + tag + '>', | ||||
|                         kind: htmlLanguageTypes_1.CompletionItemKind.Property, | ||||
|                         filterText: '</' + tag + '>', | ||||
|                         textEdit: htmlLanguageTypes_1.TextEdit.insert(pos, '$0</' + tag + '>'), | ||||
|                         insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.Snippet | ||||
|                     }); | ||||
|                 } | ||||
|                 return result; | ||||
|             }; | ||||
|             function collectTagSuggestions(tagStart, tagEnd) { | ||||
|                 collectOpenTagSuggestions(tagStart, tagEnd); | ||||
|                 collectCloseTagSuggestions(tagStart, true, tagEnd); | ||||
|                 return result; | ||||
|             } | ||||
|             function getExistingAttributes() { | ||||
|                 const existingAttributes = Object.create(null); | ||||
|                 node.attributeNames.forEach(attribute => { | ||||
|                     existingAttributes[attribute] = true; | ||||
|                 }); | ||||
|                 return existingAttributes; | ||||
|             } | ||||
|             function collectAttributeNameSuggestions(nameStart, nameEnd = offset) { | ||||
|                 let replaceEnd = offset; | ||||
|                 while (replaceEnd < nameEnd && text[replaceEnd] !== '<') { // < is a valid attribute name character, but we rather assume the attribute name ends. See #23236.
 | ||||
|                     replaceEnd++; | ||||
|                 } | ||||
|                 const currentAttribute = text.substring(nameStart, nameEnd); | ||||
|                 const range = getReplaceRange(nameStart, replaceEnd); | ||||
|                 let value = ''; | ||||
|                 if (!isFollowedBy(text, nameEnd, htmlLanguageTypes_1.ScannerState.AfterAttributeName, htmlLanguageTypes_1.TokenType.DelimiterAssign)) { | ||||
|                     const defaultValue = settings?.attributeDefaultValue ?? 'doublequotes'; | ||||
|                     if (defaultValue === 'empty') { | ||||
|                         value = '=$1'; | ||||
|                     } | ||||
|                     else if (defaultValue === 'singlequotes') { | ||||
|                         value = '=\'$1\''; | ||||
|                     } | ||||
|                     else { | ||||
|                         value = '="$1"'; | ||||
|                     } | ||||
|                 } | ||||
|                 const seenAttributes = getExistingAttributes(); | ||||
|                 // include current typing attribute
 | ||||
|                 seenAttributes[currentAttribute] = false; | ||||
|                 dataProviders.forEach(provider => { | ||||
|                     provider.provideAttributes(currentTag).forEach(attr => { | ||||
|                         if (seenAttributes[attr.name]) { | ||||
|                             return; | ||||
|                         } | ||||
|                         seenAttributes[attr.name] = true; | ||||
|                         let codeSnippet = attr.name; | ||||
|                         let command; | ||||
|                         if (attr.valueSet !== 'v' && value.length) { | ||||
|                             codeSnippet = codeSnippet + value; | ||||
|                             if (attr.valueSet || attr.name === 'style') { | ||||
|                                 command = { | ||||
|                                     title: 'Suggest', | ||||
|                                     command: 'editor.action.triggerSuggest' | ||||
|                                 }; | ||||
|                             } | ||||
|                         } | ||||
|                         result.items.push({ | ||||
|                             label: attr.name, | ||||
|                             kind: attr.valueSet === 'handler' ? htmlLanguageTypes_1.CompletionItemKind.Function : htmlLanguageTypes_1.CompletionItemKind.Value, | ||||
|                             documentation: (0, dataProvider_1.generateDocumentation)(attr, undefined, doesSupportMarkdown), | ||||
|                             textEdit: htmlLanguageTypes_1.TextEdit.replace(range, codeSnippet), | ||||
|                             insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.Snippet, | ||||
|                             command | ||||
|                         }); | ||||
|                     }); | ||||
|                 }); | ||||
|                 collectDataAttributesSuggestions(range, seenAttributes); | ||||
|                 return result; | ||||
|             } | ||||
|             function collectDataAttributesSuggestions(range, seenAttributes) { | ||||
|                 const dataAttr = 'data-'; | ||||
|                 const dataAttributes = {}; | ||||
|                 dataAttributes[dataAttr] = `${dataAttr}$1="$2"`; | ||||
|                 function addNodeDataAttributes(node) { | ||||
|                     node.attributeNames.forEach(attr => { | ||||
|                         if ((0, strings_1.startsWith)(attr, dataAttr) && !dataAttributes[attr] && !seenAttributes[attr]) { | ||||
|                             dataAttributes[attr] = attr + '="$1"'; | ||||
|                         } | ||||
|                     }); | ||||
|                     node.children.forEach(child => addNodeDataAttributes(child)); | ||||
|                 } | ||||
|                 if (htmlDocument) { | ||||
|                     htmlDocument.roots.forEach(root => addNodeDataAttributes(root)); | ||||
|                 } | ||||
|                 Object.keys(dataAttributes).forEach(attr => result.items.push({ | ||||
|                     label: attr, | ||||
|                     kind: htmlLanguageTypes_1.CompletionItemKind.Value, | ||||
|                     textEdit: htmlLanguageTypes_1.TextEdit.replace(range, dataAttributes[attr]), | ||||
|                     insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.Snippet | ||||
|                 })); | ||||
|             } | ||||
|             function collectAttributeValueSuggestions(valueStart, valueEnd = offset) { | ||||
|                 let range; | ||||
|                 let addQuotes; | ||||
|                 let valuePrefix; | ||||
|                 if (offset > valueStart && offset <= valueEnd && isQuote(text[valueStart])) { | ||||
|                     // inside quoted attribute
 | ||||
|                     const valueContentStart = valueStart + 1; | ||||
|                     let valueContentEnd = valueEnd; | ||||
|                     // valueEnd points to the char after quote, which encloses the replace range
 | ||||
|                     if (valueEnd > valueStart && text[valueEnd - 1] === text[valueStart]) { | ||||
|                         valueContentEnd--; | ||||
|                     } | ||||
|                     const wsBefore = getWordStart(text, offset, valueContentStart); | ||||
|                     const wsAfter = getWordEnd(text, offset, valueContentEnd); | ||||
|                     range = getReplaceRange(wsBefore, wsAfter); | ||||
|                     valuePrefix = offset >= valueContentStart && offset <= valueContentEnd ? text.substring(valueContentStart, offset) : ''; | ||||
|                     addQuotes = false; | ||||
|                 } | ||||
|                 else { | ||||
|                     range = getReplaceRange(valueStart, valueEnd); | ||||
|                     valuePrefix = text.substring(valueStart, offset); | ||||
|                     addQuotes = true; | ||||
|                 } | ||||
|                 if (completionParticipants.length > 0) { | ||||
|                     const tag = currentTag.toLowerCase(); | ||||
|                     const attribute = currentAttributeName.toLowerCase(); | ||||
|                     const fullRange = getReplaceRange(valueStart, valueEnd); | ||||
|                     for (const participant of completionParticipants) { | ||||
|                         if (participant.onHtmlAttributeValue) { | ||||
|                             participant.onHtmlAttributeValue({ document, position, tag, attribute, value: valuePrefix, range: fullRange }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 dataProviders.forEach(provider => { | ||||
|                     provider.provideValues(currentTag, currentAttributeName).forEach(value => { | ||||
|                         const insertText = addQuotes ? '"' + value.name + '"' : value.name; | ||||
|                         result.items.push({ | ||||
|                             label: value.name, | ||||
|                             filterText: insertText, | ||||
|                             kind: htmlLanguageTypes_1.CompletionItemKind.Unit, | ||||
|                             documentation: (0, dataProvider_1.generateDocumentation)(value, undefined, doesSupportMarkdown), | ||||
|                             textEdit: htmlLanguageTypes_1.TextEdit.replace(range, insertText), | ||||
|                             insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.PlainText | ||||
|                         }); | ||||
|                     }); | ||||
|                 }); | ||||
|                 collectCharacterEntityProposals(); | ||||
|                 return result; | ||||
|             } | ||||
|             function scanNextForEndPos(nextToken) { | ||||
|                 if (offset === scanner.getTokenEnd()) { | ||||
|                     token = scanner.scan(); | ||||
|                     if (token === nextToken && scanner.getTokenOffset() === offset) { | ||||
|                         return scanner.getTokenEnd(); | ||||
|                     } | ||||
|                 } | ||||
|                 return offset; | ||||
|             } | ||||
|             function collectInsideContent() { | ||||
|                 for (const participant of completionParticipants) { | ||||
|                     if (participant.onHtmlContent) { | ||||
|                         participant.onHtmlContent({ document, position }); | ||||
|                     } | ||||
|                 } | ||||
|                 return collectCharacterEntityProposals(); | ||||
|             } | ||||
|             function collectCharacterEntityProposals() { | ||||
|                 // character entities
 | ||||
|                 let k = offset - 1; | ||||
|                 let characterStart = position.character; | ||||
|                 while (k >= 0 && (0, strings_1.isLetterOrDigit)(text, k)) { | ||||
|                     k--; | ||||
|                     characterStart--; | ||||
|                 } | ||||
|                 if (k >= 0 && text[k] === '&') { | ||||
|                     const range = htmlLanguageTypes_1.Range.create(htmlLanguageTypes_1.Position.create(position.line, characterStart - 1), position); | ||||
|                     for (const entity in htmlEntities_1.entities) { | ||||
|                         if ((0, strings_1.endsWith)(entity, ';')) { | ||||
|                             const label = '&' + entity; | ||||
|                             result.items.push({ | ||||
|                                 label, | ||||
|                                 kind: htmlLanguageTypes_1.CompletionItemKind.Keyword, | ||||
|                                 documentation: l10n.t('Character entity representing \'{0}\'', htmlEntities_1.entities[entity]), | ||||
|                                 textEdit: htmlLanguageTypes_1.TextEdit.replace(range, label), | ||||
|                                 insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.PlainText | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 return result; | ||||
|             } | ||||
|             function suggestDoctype(replaceStart, replaceEnd) { | ||||
|                 const range = getReplaceRange(replaceStart, replaceEnd); | ||||
|                 result.items.push({ | ||||
|                     label: '!DOCTYPE', | ||||
|                     kind: htmlLanguageTypes_1.CompletionItemKind.Property, | ||||
|                     documentation: 'A preamble for an HTML document.', | ||||
|                     textEdit: htmlLanguageTypes_1.TextEdit.replace(range, '!DOCTYPE html>'), | ||||
|                     insertTextFormat: htmlLanguageTypes_1.InsertTextFormat.PlainText | ||||
|                 }); | ||||
|             } | ||||
|             let token = scanner.scan(); | ||||
|             while (token !== htmlLanguageTypes_1.TokenType.EOS && scanner.getTokenOffset() <= offset) { | ||||
|                 switch (token) { | ||||
|                     case htmlLanguageTypes_1.TokenType.StartTagOpen: | ||||
|                         if (scanner.getTokenEnd() === offset) { | ||||
|                             const endPos = scanNextForEndPos(htmlLanguageTypes_1.TokenType.StartTag); | ||||
|                             if (position.line === 0) { | ||||
|                                 suggestDoctype(offset, endPos); | ||||
|                             } | ||||
|                             return collectTagSuggestions(offset, endPos); | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.StartTag: | ||||
|                         if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) { | ||||
|                             return collectOpenTagSuggestions(scanner.getTokenOffset(), scanner.getTokenEnd()); | ||||
|                         } | ||||
|                         currentTag = scanner.getTokenText(); | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.AttributeName: | ||||
|                         if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) { | ||||
|                             return collectAttributeNameSuggestions(scanner.getTokenOffset(), scanner.getTokenEnd()); | ||||
|                         } | ||||
|                         currentAttributeName = scanner.getTokenText(); | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.DelimiterAssign: | ||||
|                         if (scanner.getTokenEnd() === offset) { | ||||
|                             const endPos = scanNextForEndPos(htmlLanguageTypes_1.TokenType.AttributeValue); | ||||
|                             return collectAttributeValueSuggestions(offset, endPos); | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.AttributeValue: | ||||
|                         if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) { | ||||
|                             return collectAttributeValueSuggestions(scanner.getTokenOffset(), scanner.getTokenEnd()); | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.Whitespace: | ||||
|                         if (offset <= scanner.getTokenEnd()) { | ||||
|                             switch (scanner.getScannerState()) { | ||||
|                                 case htmlLanguageTypes_1.ScannerState.AfterOpeningStartTag: | ||||
|                                     const startPos = scanner.getTokenOffset(); | ||||
|                                     const endTagPos = scanNextForEndPos(htmlLanguageTypes_1.TokenType.StartTag); | ||||
|                                     return collectTagSuggestions(startPos, endTagPos); | ||||
|                                 case htmlLanguageTypes_1.ScannerState.WithinTag: | ||||
|                                 case htmlLanguageTypes_1.ScannerState.AfterAttributeName: | ||||
|                                     return collectAttributeNameSuggestions(scanner.getTokenEnd()); | ||||
|                                 case htmlLanguageTypes_1.ScannerState.BeforeAttributeValue: | ||||
|                                     return collectAttributeValueSuggestions(scanner.getTokenEnd()); | ||||
|                                 case htmlLanguageTypes_1.ScannerState.AfterOpeningEndTag: | ||||
|                                     return collectCloseTagSuggestions(scanner.getTokenOffset() - 1, false); | ||||
|                                 case htmlLanguageTypes_1.ScannerState.WithinContent: | ||||
|                                     return collectInsideContent(); | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.EndTagOpen: | ||||
|                         if (offset <= scanner.getTokenEnd()) { | ||||
|                             const afterOpenBracket = scanner.getTokenOffset() + 1; | ||||
|                             const endOffset = scanNextForEndPos(htmlLanguageTypes_1.TokenType.EndTag); | ||||
|                             return collectCloseTagSuggestions(afterOpenBracket, false, endOffset); | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.EndTag: | ||||
|                         if (offset <= scanner.getTokenEnd()) { | ||||
|                             let start = scanner.getTokenOffset() - 1; | ||||
|                             while (start >= 0) { | ||||
|                                 const ch = text.charAt(start); | ||||
|                                 if (ch === '/') { | ||||
|                                     return collectCloseTagSuggestions(start, false, scanner.getTokenEnd()); | ||||
|                                 } | ||||
|                                 else if (!isWhiteSpace(ch)) { | ||||
|                                     break; | ||||
|                                 } | ||||
|                                 start--; | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.StartTagClose: | ||||
|                         if (offset <= scanner.getTokenEnd()) { | ||||
|                             if (currentTag) { | ||||
|                                 return collectAutoCloseTagSuggestion(scanner.getTokenEnd(), currentTag); | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.Content: | ||||
|                         if (offset <= scanner.getTokenEnd()) { | ||||
|                             return collectInsideContent(); | ||||
|                         } | ||||
|                         break; | ||||
|                     default: | ||||
|                         if (offset <= scanner.getTokenEnd()) { | ||||
|                             return result; | ||||
|                         } | ||||
|                         break; | ||||
|                 } | ||||
|                 token = scanner.scan(); | ||||
|             } | ||||
|             return result; | ||||
|         } | ||||
|         doQuoteComplete(document, position, htmlDocument, settings) { | ||||
|             const offset = document.offsetAt(position); | ||||
|             if (offset <= 0) { | ||||
|                 return null; | ||||
|             } | ||||
|             const defaultValue = settings?.attributeDefaultValue ?? 'doublequotes'; | ||||
|             if (defaultValue === 'empty') { | ||||
|                 return null; | ||||
|             } | ||||
|             const char = document.getText().charAt(offset - 1); | ||||
|             if (char !== '=') { | ||||
|                 return null; | ||||
|             } | ||||
|             const value = defaultValue === 'doublequotes' ? '"$1"' : '\'$1\''; | ||||
|             const node = htmlDocument.findNodeBefore(offset); | ||||
|             if (node && node.attributes && node.start < offset && (!node.endTagStart || node.endTagStart > offset)) { | ||||
|                 const scanner = (0, htmlScanner_1.createScanner)(document.getText(), node.start); | ||||
|                 let token = scanner.scan(); | ||||
|                 while (token !== htmlLanguageTypes_1.TokenType.EOS && scanner.getTokenEnd() <= offset) { | ||||
|                     if (token === htmlLanguageTypes_1.TokenType.AttributeName && scanner.getTokenEnd() === offset - 1) { | ||||
|                         // Ensure the token is a valid standalone attribute name
 | ||||
|                         token = scanner.scan(); // this should be the = just written
 | ||||
|                         if (token !== htmlLanguageTypes_1.TokenType.DelimiterAssign) { | ||||
|                             return null; | ||||
|                         } | ||||
|                         token = scanner.scan(); | ||||
|                         // Any non-attribute valid tag
 | ||||
|                         if (token === htmlLanguageTypes_1.TokenType.Unknown || token === htmlLanguageTypes_1.TokenType.AttributeValue) { | ||||
|                             return null; | ||||
|                         } | ||||
|                         return value; | ||||
|                     } | ||||
|                     token = scanner.scan(); | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
|         doTagComplete(document, position, htmlDocument) { | ||||
|             const offset = document.offsetAt(position); | ||||
|             if (offset <= 0) { | ||||
|                 return null; | ||||
|             } | ||||
|             const char = document.getText().charAt(offset - 1); | ||||
|             if (char === '>') { | ||||
|                 const voidElements = this.dataManager.getVoidElements(document.languageId); | ||||
|                 const node = htmlDocument.findNodeBefore(offset); | ||||
|                 if (node && node.tag && !this.dataManager.isVoidElement(node.tag, voidElements) && node.start < offset && (!node.endTagStart || node.endTagStart > offset)) { | ||||
|                     const scanner = (0, htmlScanner_1.createScanner)(document.getText(), node.start); | ||||
|                     let token = scanner.scan(); | ||||
|                     while (token !== htmlLanguageTypes_1.TokenType.EOS && scanner.getTokenEnd() <= offset) { | ||||
|                         if (token === htmlLanguageTypes_1.TokenType.StartTagClose && scanner.getTokenEnd() === offset) { | ||||
|                             return `$0</${node.tag}>`; | ||||
|                         } | ||||
|                         token = scanner.scan(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else if (char === '/') { | ||||
|                 let node = htmlDocument.findNodeBefore(offset); | ||||
|                 while (node && node.closed && !(node.endTagStart && (node.endTagStart > offset))) { | ||||
|                     node = node.parent; | ||||
|                 } | ||||
|                 if (node && node.tag) { | ||||
|                     const scanner = (0, htmlScanner_1.createScanner)(document.getText(), node.start); | ||||
|                     let token = scanner.scan(); | ||||
|                     while (token !== htmlLanguageTypes_1.TokenType.EOS && scanner.getTokenEnd() <= offset) { | ||||
|                         if (token === htmlLanguageTypes_1.TokenType.EndTagOpen && scanner.getTokenEnd() === offset) { | ||||
|                             return `${node.tag}>`; | ||||
|                         } | ||||
|                         token = scanner.scan(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
|         convertCompletionList(list) { | ||||
|             if (!this.doesSupportMarkdown()) { | ||||
|                 list.items.forEach(item => { | ||||
|                     if (item.documentation && typeof item.documentation !== 'string') { | ||||
|                         item.documentation = { | ||||
|                             kind: 'plaintext', | ||||
|                             value: item.documentation.value | ||||
|                         }; | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             return list; | ||||
|         } | ||||
|         doesSupportMarkdown() { | ||||
|             if (!(0, object_1.isDefined)(this.supportsMarkdown)) { | ||||
|                 if (!(0, object_1.isDefined)(this.lsOptions.clientCapabilities)) { | ||||
|                     this.supportsMarkdown = true; | ||||
|                     return this.supportsMarkdown; | ||||
|                 } | ||||
|                 const documentationFormat = this.lsOptions.clientCapabilities.textDocument?.completion?.completionItem?.documentationFormat; | ||||
|                 this.supportsMarkdown = Array.isArray(documentationFormat) && documentationFormat.indexOf(htmlLanguageTypes_1.MarkupKind.Markdown) !== -1; | ||||
|             } | ||||
|             return this.supportsMarkdown; | ||||
|         } | ||||
|     } | ||||
|     exports.HTMLCompletion = HTMLCompletion; | ||||
|     function isQuote(s) { | ||||
|         return /^["']*$/.test(s); | ||||
|     } | ||||
|     function isWhiteSpace(s) { | ||||
|         return /^\s*$/.test(s); | ||||
|     } | ||||
|     function isFollowedBy(s, offset, intialState, expectedToken) { | ||||
|         const scanner = (0, htmlScanner_1.createScanner)(s, offset, intialState); | ||||
|         let token = scanner.scan(); | ||||
|         while (token === htmlLanguageTypes_1.TokenType.Whitespace) { | ||||
|             token = scanner.scan(); | ||||
|         } | ||||
|         return token === expectedToken; | ||||
|     } | ||||
|     function getWordStart(s, offset, limit) { | ||||
|         while (offset > limit && !isWhiteSpace(s[offset - 1])) { | ||||
|             offset--; | ||||
|         } | ||||
|         return offset; | ||||
|     } | ||||
|     function getWordEnd(s, offset, limit) { | ||||
|         while (offset < limit && !isWhiteSpace(s[offset])) { | ||||
|             offset++; | ||||
|         } | ||||
|         return offset; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										184
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlFolding.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlFolding.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,184 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../htmlLanguageTypes", "../parser/htmlScanner"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.HTMLFolding = void 0; | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     const htmlScanner_1 = require("../parser/htmlScanner"); | ||||
|     class HTMLFolding { | ||||
|         constructor(dataManager) { | ||||
|             this.dataManager = dataManager; | ||||
|         } | ||||
|         limitRanges(ranges, rangeLimit) { | ||||
|             ranges = ranges.sort((r1, r2) => { | ||||
|                 let diff = r1.startLine - r2.startLine; | ||||
|                 if (diff === 0) { | ||||
|                     diff = r1.endLine - r2.endLine; | ||||
|                 } | ||||
|                 return diff; | ||||
|             }); | ||||
|             // compute each range's nesting level in 'nestingLevels'.
 | ||||
|             // count the number of ranges for each level in 'nestingLevelCounts'
 | ||||
|             let top = void 0; | ||||
|             const previous = []; | ||||
|             const nestingLevels = []; | ||||
|             const nestingLevelCounts = []; | ||||
|             const setNestingLevel = (index, level) => { | ||||
|                 nestingLevels[index] = level; | ||||
|                 if (level < 30) { | ||||
|                     nestingLevelCounts[level] = (nestingLevelCounts[level] || 0) + 1; | ||||
|                 } | ||||
|             }; | ||||
|             // compute nesting levels and sanitize
 | ||||
|             for (let i = 0; i < ranges.length; i++) { | ||||
|                 const entry = ranges[i]; | ||||
|                 if (!top) { | ||||
|                     top = entry; | ||||
|                     setNestingLevel(i, 0); | ||||
|                 } | ||||
|                 else { | ||||
|                     if (entry.startLine > top.startLine) { | ||||
|                         if (entry.endLine <= top.endLine) { | ||||
|                             previous.push(top); | ||||
|                             top = entry; | ||||
|                             setNestingLevel(i, previous.length); | ||||
|                         } | ||||
|                         else if (entry.startLine > top.endLine) { | ||||
|                             do { | ||||
|                                 top = previous.pop(); | ||||
|                             } while (top && entry.startLine > top.endLine); | ||||
|                             if (top) { | ||||
|                                 previous.push(top); | ||||
|                             } | ||||
|                             top = entry; | ||||
|                             setNestingLevel(i, previous.length); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             let entries = 0; | ||||
|             let maxLevel = 0; | ||||
|             for (let i = 0; i < nestingLevelCounts.length; i++) { | ||||
|                 const n = nestingLevelCounts[i]; | ||||
|                 if (n) { | ||||
|                     if (n + entries > rangeLimit) { | ||||
|                         maxLevel = i; | ||||
|                         break; | ||||
|                     } | ||||
|                     entries += n; | ||||
|                 } | ||||
|             } | ||||
|             const result = []; | ||||
|             for (let i = 0; i < ranges.length; i++) { | ||||
|                 const level = nestingLevels[i]; | ||||
|                 if (typeof level === 'number') { | ||||
|                     if (level < maxLevel || (level === maxLevel && entries++ < rangeLimit)) { | ||||
|                         result.push(ranges[i]); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return result; | ||||
|         } | ||||
|         getFoldingRanges(document, context) { | ||||
|             const voidElements = this.dataManager.getVoidElements(document.languageId); | ||||
|             const scanner = (0, htmlScanner_1.createScanner)(document.getText()); | ||||
|             let token = scanner.scan(); | ||||
|             const ranges = []; | ||||
|             const stack = []; | ||||
|             let lastTagName = null; | ||||
|             let prevStart = -1; | ||||
|             function addRange(range) { | ||||
|                 ranges.push(range); | ||||
|                 prevStart = range.startLine; | ||||
|             } | ||||
|             while (token !== htmlLanguageTypes_1.TokenType.EOS) { | ||||
|                 switch (token) { | ||||
|                     case htmlLanguageTypes_1.TokenType.StartTag: { | ||||
|                         const tagName = scanner.getTokenText(); | ||||
|                         const startLine = document.positionAt(scanner.getTokenOffset()).line; | ||||
|                         stack.push({ startLine, tagName }); | ||||
|                         lastTagName = tagName; | ||||
|                         break; | ||||
|                     } | ||||
|                     case htmlLanguageTypes_1.TokenType.EndTag: { | ||||
|                         lastTagName = scanner.getTokenText(); | ||||
|                         break; | ||||
|                     } | ||||
|                     case htmlLanguageTypes_1.TokenType.StartTagClose: | ||||
|                         if (!lastTagName || !this.dataManager.isVoidElement(lastTagName, voidElements)) { | ||||
|                             break; | ||||
|                         } | ||||
|                     // fallthrough
 | ||||
|                     case htmlLanguageTypes_1.TokenType.EndTagClose: | ||||
|                     case htmlLanguageTypes_1.TokenType.StartTagSelfClose: { | ||||
|                         let i = stack.length - 1; | ||||
|                         while (i >= 0 && stack[i].tagName !== lastTagName) { | ||||
|                             i--; | ||||
|                         } | ||||
|                         if (i >= 0) { | ||||
|                             const stackElement = stack[i]; | ||||
|                             stack.length = i; | ||||
|                             const line = document.positionAt(scanner.getTokenOffset()).line; | ||||
|                             const startLine = stackElement.startLine; | ||||
|                             const endLine = line - 1; | ||||
|                             if (endLine > startLine && prevStart !== startLine) { | ||||
|                                 addRange({ startLine, endLine }); | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                     case htmlLanguageTypes_1.TokenType.Comment: { | ||||
|                         let startLine = document.positionAt(scanner.getTokenOffset()).line; | ||||
|                         const text = scanner.getTokenText(); | ||||
|                         const m = text.match(/^\s*#(region\b)|(endregion\b)/); | ||||
|                         if (m) { | ||||
|                             if (m[1]) { // start pattern match
 | ||||
|                                 stack.push({ startLine, tagName: '' }); // empty tagName marks region
 | ||||
|                             } | ||||
|                             else { | ||||
|                                 let i = stack.length - 1; | ||||
|                                 while (i >= 0 && stack[i].tagName.length) { | ||||
|                                     i--; | ||||
|                                 } | ||||
|                                 if (i >= 0) { | ||||
|                                     const stackElement = stack[i]; | ||||
|                                     stack.length = i; | ||||
|                                     const endLine = startLine; | ||||
|                                     startLine = stackElement.startLine; | ||||
|                                     if (endLine > startLine && prevStart !== startLine) { | ||||
|                                         addRange({ startLine, endLine, kind: htmlLanguageTypes_1.FoldingRangeKind.Region }); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         else { | ||||
|                             const endLine = document.positionAt(scanner.getTokenOffset() + scanner.getTokenLength()).line; | ||||
|                             if (startLine < endLine) { | ||||
|                                 addRange({ startLine, endLine, kind: htmlLanguageTypes_1.FoldingRangeKind.Comment }); | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 token = scanner.scan(); | ||||
|             } | ||||
|             const rangeLimit = context && context.rangeLimit || Number.MAX_VALUE; | ||||
|             if (ranges.length > rangeLimit) { | ||||
|                 return this.limitRanges(ranges, rangeLimit); | ||||
|             } | ||||
|             return ranges; | ||||
|         } | ||||
|     } | ||||
|     exports.HTMLFolding = HTMLFolding; | ||||
| }); | ||||
							
								
								
									
										160
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlFormatter.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlFormatter.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,160 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../htmlLanguageTypes", "../beautify/beautify-html", "../utils/strings"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.format = void 0; | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     const beautify_html_1 = require("../beautify/beautify-html"); | ||||
|     const strings_1 = require("../utils/strings"); | ||||
|     function format(document, range, options) { | ||||
|         let value = document.getText(); | ||||
|         let includesEnd = true; | ||||
|         let initialIndentLevel = 0; | ||||
|         const tabSize = options.tabSize || 4; | ||||
|         if (range) { | ||||
|             let startOffset = document.offsetAt(range.start); | ||||
|             // include all leading whitespace iff at the beginning of the line
 | ||||
|             let extendedStart = startOffset; | ||||
|             while (extendedStart > 0 && isWhitespace(value, extendedStart - 1)) { | ||||
|                 extendedStart--; | ||||
|             } | ||||
|             if (extendedStart === 0 || isEOL(value, extendedStart - 1)) { | ||||
|                 startOffset = extendedStart; | ||||
|             } | ||||
|             else { | ||||
|                 // else keep at least one whitespace
 | ||||
|                 if (extendedStart < startOffset) { | ||||
|                     startOffset = extendedStart + 1; | ||||
|                 } | ||||
|             } | ||||
|             // include all following whitespace until the end of the line
 | ||||
|             let endOffset = document.offsetAt(range.end); | ||||
|             let extendedEnd = endOffset; | ||||
|             while (extendedEnd < value.length && isWhitespace(value, extendedEnd)) { | ||||
|                 extendedEnd++; | ||||
|             } | ||||
|             if (extendedEnd === value.length || isEOL(value, extendedEnd)) { | ||||
|                 endOffset = extendedEnd; | ||||
|             } | ||||
|             range = htmlLanguageTypes_1.Range.create(document.positionAt(startOffset), document.positionAt(endOffset)); | ||||
|             // Do not modify if substring starts in inside an element
 | ||||
|             // Ending inside an element is fine as it doesn't cause formatting errors
 | ||||
|             const firstHalf = value.substring(0, startOffset); | ||||
|             if (new RegExp(/.*[<][^>]*$/).test(firstHalf)) { | ||||
|                 //return without modification
 | ||||
|                 value = value.substring(startOffset, endOffset); | ||||
|                 return [{ | ||||
|                         range: range, | ||||
|                         newText: value | ||||
|                     }]; | ||||
|             } | ||||
|             includesEnd = endOffset === value.length; | ||||
|             value = value.substring(startOffset, endOffset); | ||||
|             if (startOffset !== 0) { | ||||
|                 const startOfLineOffset = document.offsetAt(htmlLanguageTypes_1.Position.create(range.start.line, 0)); | ||||
|                 initialIndentLevel = computeIndentLevel(document.getText(), startOfLineOffset, options); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             range = htmlLanguageTypes_1.Range.create(htmlLanguageTypes_1.Position.create(0, 0), document.positionAt(value.length)); | ||||
|         } | ||||
|         const htmlOptions = { | ||||
|             indent_size: tabSize, | ||||
|             indent_char: options.insertSpaces ? ' ' : '\t', | ||||
|             indent_empty_lines: getFormatOption(options, 'indentEmptyLines', false), | ||||
|             wrap_line_length: getFormatOption(options, 'wrapLineLength', 120), | ||||
|             unformatted: getTagsFormatOption(options, 'unformatted', void 0), | ||||
|             content_unformatted: getTagsFormatOption(options, 'contentUnformatted', void 0), | ||||
|             indent_inner_html: getFormatOption(options, 'indentInnerHtml', false), | ||||
|             preserve_newlines: getFormatOption(options, 'preserveNewLines', true), | ||||
|             max_preserve_newlines: getFormatOption(options, 'maxPreserveNewLines', 32786), | ||||
|             indent_handlebars: getFormatOption(options, 'indentHandlebars', false), | ||||
|             end_with_newline: includesEnd && getFormatOption(options, 'endWithNewline', false), | ||||
|             extra_liners: getTagsFormatOption(options, 'extraLiners', void 0), | ||||
|             wrap_attributes: getFormatOption(options, 'wrapAttributes', 'auto'), | ||||
|             wrap_attributes_indent_size: getFormatOption(options, 'wrapAttributesIndentSize', void 0), | ||||
|             eol: '\n', | ||||
|             indent_scripts: getFormatOption(options, 'indentScripts', 'normal'), | ||||
|             templating: getTemplatingFormatOption(options, 'all'), | ||||
|             unformatted_content_delimiter: getFormatOption(options, 'unformattedContentDelimiter', ''), | ||||
|         }; | ||||
|         let result = (0, beautify_html_1.html_beautify)(trimLeft(value), htmlOptions); | ||||
|         if (initialIndentLevel > 0) { | ||||
|             const indent = options.insertSpaces ? (0, strings_1.repeat)(' ', tabSize * initialIndentLevel) : (0, strings_1.repeat)('\t', initialIndentLevel); | ||||
|             result = result.split('\n').join('\n' + indent); | ||||
|             if (range.start.character === 0) { | ||||
|                 result = indent + result; // keep the indent
 | ||||
|             } | ||||
|         } | ||||
|         return [{ | ||||
|                 range: range, | ||||
|                 newText: result | ||||
|             }]; | ||||
|     } | ||||
|     exports.format = format; | ||||
|     function trimLeft(str) { | ||||
|         return str.replace(/^\s+/, ''); | ||||
|     } | ||||
|     function getFormatOption(options, key, dflt) { | ||||
|         if (options && options.hasOwnProperty(key)) { | ||||
|             const value = options[key]; | ||||
|             if (value !== null) { | ||||
|                 return value; | ||||
|             } | ||||
|         } | ||||
|         return dflt; | ||||
|     } | ||||
|     function getTagsFormatOption(options, key, dflt) { | ||||
|         const list = getFormatOption(options, key, null); | ||||
|         if (typeof list === 'string') { | ||||
|             if (list.length > 0) { | ||||
|                 return list.split(',').map(t => t.trim().toLowerCase()); | ||||
|             } | ||||
|             return []; | ||||
|         } | ||||
|         return dflt; | ||||
|     } | ||||
|     function getTemplatingFormatOption(options, dflt) { | ||||
|         const value = getFormatOption(options, 'templating', dflt); | ||||
|         if (value === true) { | ||||
|             return ['auto']; | ||||
|         } | ||||
|         return ['none']; | ||||
|     } | ||||
|     function computeIndentLevel(content, offset, options) { | ||||
|         let i = offset; | ||||
|         let nChars = 0; | ||||
|         const tabSize = options.tabSize || 4; | ||||
|         while (i < content.length) { | ||||
|             const ch = content.charAt(i); | ||||
|             if (ch === ' ') { | ||||
|                 nChars++; | ||||
|             } | ||||
|             else if (ch === '\t') { | ||||
|                 nChars += tabSize; | ||||
|             } | ||||
|             else { | ||||
|                 break; | ||||
|             } | ||||
|             i++; | ||||
|         } | ||||
|         return Math.floor(nChars / tabSize); | ||||
|     } | ||||
|     function isEOL(text, offset) { | ||||
|         return '\r\n'.indexOf(text.charAt(offset)) !== -1; | ||||
|     } | ||||
|     function isWhitespace(text, offset) { | ||||
|         return ' \t'.indexOf(text.charAt(offset)) !== -1; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										56
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlHighlighting.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlHighlighting.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../parser/htmlScanner", "../htmlLanguageTypes"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.findDocumentHighlights = void 0; | ||||
|     const htmlScanner_1 = require("../parser/htmlScanner"); | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     function findDocumentHighlights(document, position, htmlDocument) { | ||||
|         const offset = document.offsetAt(position); | ||||
|         const node = htmlDocument.findNodeAt(offset); | ||||
|         if (!node.tag) { | ||||
|             return []; | ||||
|         } | ||||
|         const result = []; | ||||
|         const startTagRange = getTagNameRange(htmlLanguageTypes_1.TokenType.StartTag, document, node.start); | ||||
|         const endTagRange = typeof node.endTagStart === 'number' && getTagNameRange(htmlLanguageTypes_1.TokenType.EndTag, document, node.endTagStart); | ||||
|         if (startTagRange && covers(startTagRange, position) || endTagRange && covers(endTagRange, position)) { | ||||
|             if (startTagRange) { | ||||
|                 result.push({ kind: htmlLanguageTypes_1.DocumentHighlightKind.Read, range: startTagRange }); | ||||
|             } | ||||
|             if (endTagRange) { | ||||
|                 result.push({ kind: htmlLanguageTypes_1.DocumentHighlightKind.Read, range: endTagRange }); | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     exports.findDocumentHighlights = findDocumentHighlights; | ||||
|     function isBeforeOrEqual(pos1, pos2) { | ||||
|         return pos1.line < pos2.line || (pos1.line === pos2.line && pos1.character <= pos2.character); | ||||
|     } | ||||
|     function covers(range, position) { | ||||
|         return isBeforeOrEqual(range.start, position) && isBeforeOrEqual(position, range.end); | ||||
|     } | ||||
|     function getTagNameRange(tokenType, document, startOffset) { | ||||
|         const scanner = (0, htmlScanner_1.createScanner)(document.getText(), startOffset); | ||||
|         let token = scanner.scan(); | ||||
|         while (token !== htmlLanguageTypes_1.TokenType.EOS && token !== tokenType) { | ||||
|             token = scanner.scan(); | ||||
|         } | ||||
|         if (token !== htmlLanguageTypes_1.TokenType.EOS) { | ||||
|             return { start: document.positionAt(scanner.getTokenOffset()), end: document.positionAt(scanner.getTokenEnd()) }; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										279
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlHover.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlHover.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,279 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../parser/htmlScanner", "../htmlLanguageTypes", "../utils/object", "../languageFacts/dataProvider", "../parser/htmlEntities", "../utils/strings", "@vscode/l10n"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.HTMLHover = void 0; | ||||
|     const htmlScanner_1 = require("../parser/htmlScanner"); | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     const object_1 = require("../utils/object"); | ||||
|     const dataProvider_1 = require("../languageFacts/dataProvider"); | ||||
|     const htmlEntities_1 = require("../parser/htmlEntities"); | ||||
|     const strings_1 = require("../utils/strings"); | ||||
|     const l10n = require("@vscode/l10n"); | ||||
|     class HTMLHover { | ||||
|         constructor(lsOptions, dataManager) { | ||||
|             this.lsOptions = lsOptions; | ||||
|             this.dataManager = dataManager; | ||||
|         } | ||||
|         doHover(document, position, htmlDocument, options) { | ||||
|             const convertContents = this.convertContents.bind(this); | ||||
|             const doesSupportMarkdown = this.doesSupportMarkdown(); | ||||
|             const offset = document.offsetAt(position); | ||||
|             const node = htmlDocument.findNodeAt(offset); | ||||
|             const text = document.getText(); | ||||
|             if (!node || !node.tag) { | ||||
|                 return null; | ||||
|             } | ||||
|             const dataProviders = this.dataManager.getDataProviders().filter(p => p.isApplicable(document.languageId)); | ||||
|             function getTagHover(currTag, range, open) { | ||||
|                 for (const provider of dataProviders) { | ||||
|                     let hover = null; | ||||
|                     provider.provideTags().forEach(tag => { | ||||
|                         if (tag.name.toLowerCase() === currTag.toLowerCase()) { | ||||
|                             let markupContent = (0, dataProvider_1.generateDocumentation)(tag, options, doesSupportMarkdown); | ||||
|                             if (!markupContent) { | ||||
|                                 markupContent = { | ||||
|                                     kind: doesSupportMarkdown ? 'markdown' : 'plaintext', | ||||
|                                     value: '' | ||||
|                                 }; | ||||
|                             } | ||||
|                             hover = { contents: markupContent, range }; | ||||
|                         } | ||||
|                     }); | ||||
|                     if (hover) { | ||||
|                         hover.contents = convertContents(hover.contents); | ||||
|                         return hover; | ||||
|                     } | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|             function getAttrHover(currTag, currAttr, range) { | ||||
|                 for (const provider of dataProviders) { | ||||
|                     let hover = null; | ||||
|                     provider.provideAttributes(currTag).forEach(attr => { | ||||
|                         if (currAttr === attr.name && attr.description) { | ||||
|                             const contentsDoc = (0, dataProvider_1.generateDocumentation)(attr, options, doesSupportMarkdown); | ||||
|                             if (contentsDoc) { | ||||
|                                 hover = { contents: contentsDoc, range }; | ||||
|                             } | ||||
|                             else { | ||||
|                                 hover = null; | ||||
|                             } | ||||
|                         } | ||||
|                     }); | ||||
|                     if (hover) { | ||||
|                         hover.contents = convertContents(hover.contents); | ||||
|                         return hover; | ||||
|                     } | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|             function getAttrValueHover(currTag, currAttr, currAttrValue, range) { | ||||
|                 for (const provider of dataProviders) { | ||||
|                     let hover = null; | ||||
|                     provider.provideValues(currTag, currAttr).forEach(attrValue => { | ||||
|                         if (currAttrValue === attrValue.name && attrValue.description) { | ||||
|                             const contentsDoc = (0, dataProvider_1.generateDocumentation)(attrValue, options, doesSupportMarkdown); | ||||
|                             if (contentsDoc) { | ||||
|                                 hover = { contents: contentsDoc, range }; | ||||
|                             } | ||||
|                             else { | ||||
|                                 hover = null; | ||||
|                             } | ||||
|                         } | ||||
|                     }); | ||||
|                     if (hover) { | ||||
|                         hover.contents = convertContents(hover.contents); | ||||
|                         return hover; | ||||
|                     } | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|             function getEntityHover(text, range) { | ||||
|                 let currEntity = filterEntity(text); | ||||
|                 for (const entity in htmlEntities_1.entities) { | ||||
|                     let hover = null; | ||||
|                     const label = '&' + entity; | ||||
|                     if (currEntity === label) { | ||||
|                         let code = htmlEntities_1.entities[entity].charCodeAt(0).toString(16).toUpperCase(); | ||||
|                         let hex = 'U+'; | ||||
|                         if (code.length < 4) { | ||||
|                             const zeroes = 4 - code.length; | ||||
|                             let k = 0; | ||||
|                             while (k < zeroes) { | ||||
|                                 hex += '0'; | ||||
|                                 k += 1; | ||||
|                             } | ||||
|                         } | ||||
|                         hex += code; | ||||
|                         const contentsDoc = l10n.t('Character entity representing \'{0}\', unicode equivalent \'{1}\'', htmlEntities_1.entities[entity], hex); | ||||
|                         if (contentsDoc) { | ||||
|                             hover = { contents: contentsDoc, range }; | ||||
|                         } | ||||
|                         else { | ||||
|                             hover = null; | ||||
|                         } | ||||
|                     } | ||||
|                     if (hover) { | ||||
|                         hover.contents = convertContents(hover.contents); | ||||
|                         return hover; | ||||
|                     } | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|             function getTagNameRange(tokenType, startOffset) { | ||||
|                 const scanner = (0, htmlScanner_1.createScanner)(document.getText(), startOffset); | ||||
|                 let token = scanner.scan(); | ||||
|                 while (token !== htmlLanguageTypes_1.TokenType.EOS && (scanner.getTokenEnd() < offset || scanner.getTokenEnd() === offset && token !== tokenType)) { | ||||
|                     token = scanner.scan(); | ||||
|                 } | ||||
|                 if (token === tokenType && offset <= scanner.getTokenEnd()) { | ||||
|                     return { start: document.positionAt(scanner.getTokenOffset()), end: document.positionAt(scanner.getTokenEnd()) }; | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|             function getEntityRange() { | ||||
|                 let k = offset - 1; | ||||
|                 let characterStart = position.character; | ||||
|                 while (k >= 0 && (0, strings_1.isLetterOrDigit)(text, k)) { | ||||
|                     k--; | ||||
|                     characterStart--; | ||||
|                 } | ||||
|                 let n = k + 1; | ||||
|                 let characterEnd = characterStart; | ||||
|                 while ((0, strings_1.isLetterOrDigit)(text, n)) { | ||||
|                     n++; | ||||
|                     characterEnd++; | ||||
|                 } | ||||
|                 if (k >= 0 && text[k] === '&') { | ||||
|                     let range = null; | ||||
|                     if (text[n] === ';') { | ||||
|                         range = htmlLanguageTypes_1.Range.create(htmlLanguageTypes_1.Position.create(position.line, characterStart), htmlLanguageTypes_1.Position.create(position.line, characterEnd + 1)); | ||||
|                     } | ||||
|                     else { | ||||
|                         range = htmlLanguageTypes_1.Range.create(htmlLanguageTypes_1.Position.create(position.line, characterStart), htmlLanguageTypes_1.Position.create(position.line, characterEnd)); | ||||
|                     } | ||||
|                     return range; | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|             function filterEntity(text) { | ||||
|                 let k = offset - 1; | ||||
|                 let newText = '&'; | ||||
|                 while (k >= 0 && (0, strings_1.isLetterOrDigit)(text, k)) { | ||||
|                     k--; | ||||
|                 } | ||||
|                 k = k + 1; | ||||
|                 while ((0, strings_1.isLetterOrDigit)(text, k)) { | ||||
|                     newText += text[k]; | ||||
|                     k += 1; | ||||
|                 } | ||||
|                 newText += ';'; | ||||
|                 return newText; | ||||
|             } | ||||
|             if (node.endTagStart && offset >= node.endTagStart) { | ||||
|                 const tagRange = getTagNameRange(htmlLanguageTypes_1.TokenType.EndTag, node.endTagStart); | ||||
|                 if (tagRange) { | ||||
|                     return getTagHover(node.tag, tagRange, false); | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|             const tagRange = getTagNameRange(htmlLanguageTypes_1.TokenType.StartTag, node.start); | ||||
|             if (tagRange) { | ||||
|                 return getTagHover(node.tag, tagRange, true); | ||||
|             } | ||||
|             const attrRange = getTagNameRange(htmlLanguageTypes_1.TokenType.AttributeName, node.start); | ||||
|             if (attrRange) { | ||||
|                 const tag = node.tag; | ||||
|                 const attr = document.getText(attrRange); | ||||
|                 return getAttrHover(tag, attr, attrRange); | ||||
|             } | ||||
|             const entityRange = getEntityRange(); | ||||
|             if (entityRange) { | ||||
|                 return getEntityHover(text, entityRange); | ||||
|             } | ||||
|             function scanAttrAndAttrValue(nodeStart, attrValueStart) { | ||||
|                 const scanner = (0, htmlScanner_1.createScanner)(document.getText(), nodeStart); | ||||
|                 let token = scanner.scan(); | ||||
|                 let prevAttr = undefined; | ||||
|                 while (token !== htmlLanguageTypes_1.TokenType.EOS && (scanner.getTokenEnd() <= attrValueStart)) { | ||||
|                     token = scanner.scan(); | ||||
|                     if (token === htmlLanguageTypes_1.TokenType.AttributeName) { | ||||
|                         prevAttr = scanner.getTokenText(); | ||||
|                     } | ||||
|                 } | ||||
|                 return prevAttr; | ||||
|             } | ||||
|             const attrValueRange = getTagNameRange(htmlLanguageTypes_1.TokenType.AttributeValue, node.start); | ||||
|             if (attrValueRange) { | ||||
|                 const tag = node.tag; | ||||
|                 const attrValue = trimQuotes(document.getText(attrValueRange)); | ||||
|                 const matchAttr = scanAttrAndAttrValue(node.start, document.offsetAt(attrValueRange.start)); | ||||
|                 if (matchAttr) { | ||||
|                     return getAttrValueHover(tag, matchAttr, attrValue, attrValueRange); | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
|         convertContents(contents) { | ||||
|             if (!this.doesSupportMarkdown()) { | ||||
|                 if (typeof contents === 'string') { | ||||
|                     return contents; | ||||
|                 } | ||||
|                 // MarkupContent
 | ||||
|                 else if ('kind' in contents) { | ||||
|                     return { | ||||
|                         kind: 'plaintext', | ||||
|                         value: contents.value | ||||
|                     }; | ||||
|                 } | ||||
|                 // MarkedString[]
 | ||||
|                 else if (Array.isArray(contents)) { | ||||
|                     contents.map(c => { | ||||
|                         return typeof c === 'string' ? c : c.value; | ||||
|                     }); | ||||
|                 } | ||||
|                 // MarkedString
 | ||||
|                 else { | ||||
|                     return contents.value; | ||||
|                 } | ||||
|             } | ||||
|             return contents; | ||||
|         } | ||||
|         doesSupportMarkdown() { | ||||
|             if (!(0, object_1.isDefined)(this.supportsMarkdown)) { | ||||
|                 if (!(0, object_1.isDefined)(this.lsOptions.clientCapabilities)) { | ||||
|                     this.supportsMarkdown = true; | ||||
|                     return this.supportsMarkdown; | ||||
|                 } | ||||
|                 const contentFormat = this.lsOptions.clientCapabilities?.textDocument?.hover?.contentFormat; | ||||
|                 this.supportsMarkdown = Array.isArray(contentFormat) && contentFormat.indexOf(htmlLanguageTypes_1.MarkupKind.Markdown) !== -1; | ||||
|             } | ||||
|             return this.supportsMarkdown; | ||||
|         } | ||||
|     } | ||||
|     exports.HTMLHover = HTMLHover; | ||||
|     function trimQuotes(s) { | ||||
|         if (s.length <= 1) { | ||||
|             return s.replace(/['"]/, ''); | ||||
|         } | ||||
|         if (s[0] === `'` || s[0] === `"`) { | ||||
|             s = s.slice(1); | ||||
|         } | ||||
|         if (s[s.length - 1] === `'` || s[s.length - 1] === `"`) { | ||||
|             s = s.slice(0, -1); | ||||
|         } | ||||
|         return s; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										38
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlLinkedEditing.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlLinkedEditing.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../htmlLanguageTypes"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.findLinkedEditingRanges = void 0; | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     function findLinkedEditingRanges(document, position, htmlDocument) { | ||||
|         const offset = document.offsetAt(position); | ||||
|         const node = htmlDocument.findNodeAt(offset); | ||||
|         const tagLength = node.tag ? node.tag.length : 0; | ||||
|         if (!node.endTagStart) { | ||||
|             return null; | ||||
|         } | ||||
|         if ( | ||||
|         // Within open tag, compute close tag
 | ||||
|         (node.start + '<'.length <= offset && offset <= node.start + '<'.length + tagLength) || | ||||
|             // Within closing tag, compute open tag
 | ||||
|             node.endTagStart + '</'.length <= offset && offset <= node.endTagStart + '</'.length + tagLength) { | ||||
|             return [ | ||||
|                 htmlLanguageTypes_1.Range.create(document.positionAt(node.start + '<'.length), document.positionAt(node.start + '<'.length + tagLength)), | ||||
|                 htmlLanguageTypes_1.Range.create(document.positionAt(node.endTagStart + '</'.length), document.positionAt(node.endTagStart + '</'.length + tagLength)) | ||||
|             ]; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|     exports.findLinkedEditingRanges = findLinkedEditingRanges; | ||||
| }); | ||||
							
								
								
									
										158
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlLinks.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlLinks.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,158 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../parser/htmlScanner", "../utils/strings", "vscode-uri", "../htmlLanguageTypes"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.HTMLDocumentLinks = void 0; | ||||
|     const htmlScanner_1 = require("../parser/htmlScanner"); | ||||
|     const strings = require("../utils/strings"); | ||||
|     const vscode_uri_1 = require("vscode-uri"); | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     function normalizeRef(url) { | ||||
|         const first = url[0]; | ||||
|         const last = url[url.length - 1]; | ||||
|         if (first === last && (first === '\'' || first === '\"')) { | ||||
|             url = url.substring(1, url.length - 1); | ||||
|         } | ||||
|         return url; | ||||
|     } | ||||
|     function validateRef(url, languageId) { | ||||
|         if (!url.length) { | ||||
|             return false; | ||||
|         } | ||||
|         if (languageId === 'handlebars' && /{{|}}/.test(url)) { | ||||
|             return false; | ||||
|         } | ||||
|         return /\b(w[\w\d+.-]*:\/\/)?[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))/.test(url); | ||||
|     } | ||||
|     function getWorkspaceUrl(documentUri, tokenContent, documentContext, base) { | ||||
|         if (/^\s*javascript\:/i.test(tokenContent) || /[\n\r]/.test(tokenContent)) { | ||||
|             return undefined; | ||||
|         } | ||||
|         tokenContent = tokenContent.replace(/^\s*/g, ''); | ||||
|         const match = tokenContent.match(/^(\w[\w\d+.-]*):/); | ||||
|         if (match) { | ||||
|             // Absolute link that needs no treatment
 | ||||
|             const schema = match[1].toLowerCase(); | ||||
|             if (schema === 'http' || schema === 'https' || schema === 'file') { | ||||
|                 return tokenContent; | ||||
|             } | ||||
|             return undefined; | ||||
|         } | ||||
|         if (/^\#/i.test(tokenContent)) { | ||||
|             return documentUri + tokenContent; | ||||
|         } | ||||
|         if (/^\/\//i.test(tokenContent)) { | ||||
|             // Absolute link (that does not name the protocol)
 | ||||
|             const pickedScheme = strings.startsWith(documentUri, 'https://') ? 'https' : 'http'; | ||||
|             return pickedScheme + ':' + tokenContent.replace(/^\s*/g, ''); | ||||
|         } | ||||
|         if (documentContext) { | ||||
|             return documentContext.resolveReference(tokenContent, base || documentUri); | ||||
|         } | ||||
|         return tokenContent; | ||||
|     } | ||||
|     function createLink(document, documentContext, attributeValue, startOffset, endOffset, base) { | ||||
|         const tokenContent = normalizeRef(attributeValue); | ||||
|         if (!validateRef(tokenContent, document.languageId)) { | ||||
|             return undefined; | ||||
|         } | ||||
|         if (tokenContent.length < attributeValue.length) { | ||||
|             startOffset++; | ||||
|             endOffset--; | ||||
|         } | ||||
|         const workspaceUrl = getWorkspaceUrl(document.uri, tokenContent, documentContext, base); | ||||
|         if (!workspaceUrl || !isValidURI(workspaceUrl)) { | ||||
|             return undefined; | ||||
|         } | ||||
|         return { | ||||
|             range: htmlLanguageTypes_1.Range.create(document.positionAt(startOffset), document.positionAt(endOffset)), | ||||
|             target: workspaceUrl | ||||
|         }; | ||||
|     } | ||||
|     function isValidURI(uri) { | ||||
|         try { | ||||
|             vscode_uri_1.URI.parse(uri); | ||||
|             return true; | ||||
|         } | ||||
|         catch (e) { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|     class HTMLDocumentLinks { | ||||
|         constructor(dataManager) { | ||||
|             this.dataManager = dataManager; | ||||
|         } | ||||
|         findDocumentLinks(document, documentContext) { | ||||
|             const newLinks = []; | ||||
|             const scanner = (0, htmlScanner_1.createScanner)(document.getText(), 0); | ||||
|             let token = scanner.scan(); | ||||
|             let lastAttributeName = undefined; | ||||
|             let lastTagName = undefined; | ||||
|             let afterBase = false; | ||||
|             let base = void 0; | ||||
|             const idLocations = {}; | ||||
|             while (token !== htmlLanguageTypes_1.TokenType.EOS) { | ||||
|                 switch (token) { | ||||
|                     case htmlLanguageTypes_1.TokenType.StartTag: | ||||
|                         lastTagName = scanner.getTokenText().toLowerCase(); | ||||
|                         if (!base) { | ||||
|                             afterBase = lastTagName === 'base'; | ||||
|                         } | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.AttributeName: | ||||
|                         lastAttributeName = scanner.getTokenText().toLowerCase(); | ||||
|                         break; | ||||
|                     case htmlLanguageTypes_1.TokenType.AttributeValue: | ||||
|                         if (lastTagName && lastAttributeName && this.dataManager.isPathAttribute(lastTagName, lastAttributeName)) { | ||||
|                             const attributeValue = scanner.getTokenText(); | ||||
|                             if (!afterBase) { // don't highlight the base link itself
 | ||||
|                                 const link = createLink(document, documentContext, attributeValue, scanner.getTokenOffset(), scanner.getTokenEnd(), base); | ||||
|                                 if (link) { | ||||
|                                     newLinks.push(link); | ||||
|                                 } | ||||
|                             } | ||||
|                             if (afterBase && typeof base === 'undefined') { | ||||
|                                 base = normalizeRef(attributeValue); | ||||
|                                 if (base && documentContext) { | ||||
|                                     base = documentContext.resolveReference(base, document.uri); | ||||
|                                 } | ||||
|                             } | ||||
|                             afterBase = false; | ||||
|                             lastAttributeName = undefined; | ||||
|                         } | ||||
|                         else if (lastAttributeName === 'id') { | ||||
|                             const id = normalizeRef(scanner.getTokenText()); | ||||
|                             idLocations[id] = scanner.getTokenOffset(); | ||||
|                         } | ||||
|                         break; | ||||
|                 } | ||||
|                 token = scanner.scan(); | ||||
|             } | ||||
|             // change local links with ids to actual positions
 | ||||
|             for (const link of newLinks) { | ||||
|                 const localWithHash = document.uri + '#'; | ||||
|                 if (link.target && strings.startsWith(link.target, localWithHash)) { | ||||
|                     const target = link.target.substring(localWithHash.length); | ||||
|                     const offset = idLocations[target]; | ||||
|                     if (offset !== undefined) { | ||||
|                         const pos = document.positionAt(offset); | ||||
|                         link.target = `${localWithHash}${pos.line + 1},${pos.character + 1}`; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return newLinks; | ||||
|         } | ||||
|     } | ||||
|     exports.HTMLDocumentLinks = HTMLDocumentLinks; | ||||
| }); | ||||
							
								
								
									
										39
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlMatchingTagPosition.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlMatchingTagPosition.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.findMatchingTagPosition = void 0; | ||||
|     function findMatchingTagPosition(document, position, htmlDocument) { | ||||
|         const offset = document.offsetAt(position); | ||||
|         const node = htmlDocument.findNodeAt(offset); | ||||
|         if (!node.tag) { | ||||
|             return null; | ||||
|         } | ||||
|         if (!node.endTagStart) { | ||||
|             return null; | ||||
|         } | ||||
|         // Within open tag, compute close tag
 | ||||
|         if (node.start + '<'.length <= offset && offset <= node.start + '<'.length + node.tag.length) { | ||||
|             const mirrorOffset = (offset - '<'.length - node.start) + node.endTagStart + '</'.length; | ||||
|             return document.positionAt(mirrorOffset); | ||||
|         } | ||||
|         // Within closing tag, compute open tag
 | ||||
|         if (node.endTagStart + '</'.length <= offset && offset <= node.endTagStart + '</'.length + node.tag.length) { | ||||
|             const mirrorOffset = (offset - '</'.length - node.endTagStart) + node.start + '<'.length; | ||||
|             return document.positionAt(mirrorOffset); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|     exports.findMatchingTagPosition = findMatchingTagPosition; | ||||
| }); | ||||
							
								
								
									
										65
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlRename.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlRename.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.doRename = void 0; | ||||
|     function doRename(document, position, newName, htmlDocument) { | ||||
|         const offset = document.offsetAt(position); | ||||
|         const node = htmlDocument.findNodeAt(offset); | ||||
|         if (!node.tag) { | ||||
|             return null; | ||||
|         } | ||||
|         if (!isWithinTagRange(node, offset, node.tag)) { | ||||
|             return null; | ||||
|         } | ||||
|         const edits = []; | ||||
|         const startTagRange = { | ||||
|             start: document.positionAt(node.start + '<'.length), | ||||
|             end: document.positionAt(node.start + '<'.length + node.tag.length) | ||||
|         }; | ||||
|         edits.push({ | ||||
|             range: startTagRange, | ||||
|             newText: newName | ||||
|         }); | ||||
|         if (node.endTagStart) { | ||||
|             const endTagRange = { | ||||
|                 start: document.positionAt(node.endTagStart + '</'.length), | ||||
|                 end: document.positionAt(node.endTagStart + '</'.length + node.tag.length) | ||||
|             }; | ||||
|             edits.push({ | ||||
|                 range: endTagRange, | ||||
|                 newText: newName | ||||
|             }); | ||||
|         } | ||||
|         const changes = { | ||||
|             [document.uri.toString()]: edits | ||||
|         }; | ||||
|         return { | ||||
|             changes | ||||
|         }; | ||||
|     } | ||||
|     exports.doRename = doRename; | ||||
|     function toLocString(p) { | ||||
|         return `(${p.line}, ${p.character})`; | ||||
|     } | ||||
|     function isWithinTagRange(node, offset, nodeTag) { | ||||
|         // Self-closing tag
 | ||||
|         if (node.endTagStart) { | ||||
|             if (node.endTagStart + '</'.length <= offset && offset <= node.endTagStart + '</'.length + nodeTag.length) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         return node.start + '<'.length <= offset && offset <= node.start + '<'.length + nodeTag.length; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										188
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlSelectionRange.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlSelectionRange.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,188 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../parser/htmlScanner", "../htmlLanguageTypes"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.HTMLSelectionRange = void 0; | ||||
|     const htmlScanner_1 = require("../parser/htmlScanner"); | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     class HTMLSelectionRange { | ||||
|         constructor(htmlParser) { | ||||
|             this.htmlParser = htmlParser; | ||||
|         } | ||||
|         getSelectionRanges(document, positions) { | ||||
|             const htmlDocument = this.htmlParser.parseDocument(document); | ||||
|             return positions.map(p => this.getSelectionRange(p, document, htmlDocument)); | ||||
|         } | ||||
|         getSelectionRange(position, document, htmlDocument) { | ||||
|             const applicableRanges = this.getApplicableRanges(document, position, htmlDocument); | ||||
|             let prev = undefined; | ||||
|             let current = undefined; | ||||
|             for (let index = applicableRanges.length - 1; index >= 0; index--) { | ||||
|                 const range = applicableRanges[index]; | ||||
|                 if (!prev || range[0] !== prev[0] || range[1] !== prev[1]) { | ||||
|                     current = htmlLanguageTypes_1.SelectionRange.create(htmlLanguageTypes_1.Range.create(document.positionAt(applicableRanges[index][0]), document.positionAt(applicableRanges[index][1])), current); | ||||
|                 } | ||||
|                 prev = range; | ||||
|             } | ||||
|             if (!current) { | ||||
|                 current = htmlLanguageTypes_1.SelectionRange.create(htmlLanguageTypes_1.Range.create(position, position)); | ||||
|             } | ||||
|             return current; | ||||
|         } | ||||
|         getApplicableRanges(document, position, htmlDoc) { | ||||
|             const currOffset = document.offsetAt(position); | ||||
|             const currNode = htmlDoc.findNodeAt(currOffset); | ||||
|             let result = this.getAllParentTagRanges(currNode); | ||||
|             // Self-closing or void elements
 | ||||
|             if (currNode.startTagEnd && !currNode.endTagStart) { | ||||
|                 // THe rare case of unmatching tag pairs like <div></div1>
 | ||||
|                 if (currNode.startTagEnd !== currNode.end) { | ||||
|                     return [[currNode.start, currNode.end]]; | ||||
|                 } | ||||
|                 const closeRange = htmlLanguageTypes_1.Range.create(document.positionAt(currNode.startTagEnd - 2), document.positionAt(currNode.startTagEnd)); | ||||
|                 const closeText = document.getText(closeRange); | ||||
|                 // Self-closing element
 | ||||
|                 if (closeText === '/>') { | ||||
|                     result.unshift([currNode.start + 1, currNode.startTagEnd - 2]); | ||||
|                 } | ||||
|                 // Void element
 | ||||
|                 else { | ||||
|                     result.unshift([currNode.start + 1, currNode.startTagEnd - 1]); | ||||
|                 } | ||||
|                 const attributeLevelRanges = this.getAttributeLevelRanges(document, currNode, currOffset); | ||||
|                 result = attributeLevelRanges.concat(result); | ||||
|                 return result; | ||||
|             } | ||||
|             if (!currNode.startTagEnd || !currNode.endTagStart) { | ||||
|                 return result; | ||||
|             } | ||||
|             /** | ||||
|              * For html like | ||||
|              * `<div class="foo">bar</div>` | ||||
|              */ | ||||
|             result.unshift([currNode.start, currNode.end]); | ||||
|             /** | ||||
|              * Cursor inside `<div class="foo">` | ||||
|              */ | ||||
|             if (currNode.start < currOffset && currOffset < currNode.startTagEnd) { | ||||
|                 result.unshift([currNode.start + 1, currNode.startTagEnd - 1]); | ||||
|                 const attributeLevelRanges = this.getAttributeLevelRanges(document, currNode, currOffset); | ||||
|                 result = attributeLevelRanges.concat(result); | ||||
|                 return result; | ||||
|             } | ||||
|             /** | ||||
|              * Cursor inside `bar` | ||||
|              */ | ||||
|             else if (currNode.startTagEnd <= currOffset && currOffset <= currNode.endTagStart) { | ||||
|                 result.unshift([currNode.startTagEnd, currNode.endTagStart]); | ||||
|                 return result; | ||||
|             } | ||||
|             /** | ||||
|              * Cursor inside `</div>` | ||||
|              */ | ||||
|             else { | ||||
|                 // `div` inside `</div>`
 | ||||
|                 if (currOffset >= currNode.endTagStart + 2) { | ||||
|                     result.unshift([currNode.endTagStart + 2, currNode.end - 1]); | ||||
|                 } | ||||
|                 return result; | ||||
|             } | ||||
|         } | ||||
|         getAllParentTagRanges(initialNode) { | ||||
|             let currNode = initialNode; | ||||
|             const result = []; | ||||
|             while (currNode.parent) { | ||||
|                 currNode = currNode.parent; | ||||
|                 this.getNodeRanges(currNode).forEach(r => result.push(r)); | ||||
|             } | ||||
|             return result; | ||||
|         } | ||||
|         getNodeRanges(n) { | ||||
|             if (n.startTagEnd && n.endTagStart && n.startTagEnd < n.endTagStart) { | ||||
|                 return [ | ||||
|                     [n.startTagEnd, n.endTagStart], | ||||
|                     [n.start, n.end] | ||||
|                 ]; | ||||
|             } | ||||
|             return [ | ||||
|                 [n.start, n.end] | ||||
|             ]; | ||||
|         } | ||||
|         ; | ||||
|         getAttributeLevelRanges(document, currNode, currOffset) { | ||||
|             const currNodeRange = htmlLanguageTypes_1.Range.create(document.positionAt(currNode.start), document.positionAt(currNode.end)); | ||||
|             const currNodeText = document.getText(currNodeRange); | ||||
|             const relativeOffset = currOffset - currNode.start; | ||||
|             /** | ||||
|              * Tag level semantic selection | ||||
|              */ | ||||
|             const scanner = (0, htmlScanner_1.createScanner)(currNodeText); | ||||
|             let token = scanner.scan(); | ||||
|             /** | ||||
|              * For text like | ||||
|              * <div class="foo">bar</div> | ||||
|              */ | ||||
|             const positionOffset = currNode.start; | ||||
|             const result = []; | ||||
|             let isInsideAttribute = false; | ||||
|             let attrStart = -1; | ||||
|             while (token !== htmlLanguageTypes_1.TokenType.EOS) { | ||||
|                 switch (token) { | ||||
|                     case htmlLanguageTypes_1.TokenType.AttributeName: { | ||||
|                         if (relativeOffset < scanner.getTokenOffset()) { | ||||
|                             isInsideAttribute = false; | ||||
|                             break; | ||||
|                         } | ||||
|                         if (relativeOffset <= scanner.getTokenEnd()) { | ||||
|                             // `class`
 | ||||
|                             result.unshift([scanner.getTokenOffset(), scanner.getTokenEnd()]); | ||||
|                         } | ||||
|                         isInsideAttribute = true; | ||||
|                         attrStart = scanner.getTokenOffset(); | ||||
|                         break; | ||||
|                     } | ||||
|                     case htmlLanguageTypes_1.TokenType.AttributeValue: { | ||||
|                         if (!isInsideAttribute) { | ||||
|                             break; | ||||
|                         } | ||||
|                         const valueText = scanner.getTokenText(); | ||||
|                         if (relativeOffset < scanner.getTokenOffset()) { | ||||
|                             // `class="foo"`
 | ||||
|                             result.push([attrStart, scanner.getTokenEnd()]); | ||||
|                             break; | ||||
|                         } | ||||
|                         if (relativeOffset >= scanner.getTokenOffset() && relativeOffset <= scanner.getTokenEnd()) { | ||||
|                             // `"foo"`
 | ||||
|                             result.unshift([scanner.getTokenOffset(), scanner.getTokenEnd()]); | ||||
|                             // `foo`
 | ||||
|                             if ((valueText[0] === `"` && valueText[valueText.length - 1] === `"`) || (valueText[0] === `'` && valueText[valueText.length - 1] === `'`)) { | ||||
|                                 if (relativeOffset >= scanner.getTokenOffset() + 1 && relativeOffset <= scanner.getTokenEnd() - 1) { | ||||
|                                     result.unshift([scanner.getTokenOffset() + 1, scanner.getTokenEnd() - 1]); | ||||
|                                 } | ||||
|                             } | ||||
|                             // `class="foo"`
 | ||||
|                             result.push([attrStart, scanner.getTokenEnd()]); | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 token = scanner.scan(); | ||||
|             } | ||||
|             return result.map(pair => { | ||||
|                 return [pair[0] + positionOffset, pair[1] + positionOffset]; | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|     exports.HTMLSelectionRange = HTMLSelectionRange; | ||||
| }); | ||||
							
								
								
									
										54
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlSymbolsProvider.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/htmlSymbolsProvider.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../htmlLanguageTypes"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.findDocumentSymbols = void 0; | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     function findDocumentSymbols(document, htmlDocument) { | ||||
|         const symbols = []; | ||||
|         htmlDocument.roots.forEach(node => { | ||||
|             provideFileSymbolsInternal(document, node, '', symbols); | ||||
|         }); | ||||
|         return symbols; | ||||
|     } | ||||
|     exports.findDocumentSymbols = findDocumentSymbols; | ||||
|     function provideFileSymbolsInternal(document, node, container, symbols) { | ||||
|         const name = nodeToName(node); | ||||
|         const location = htmlLanguageTypes_1.Location.create(document.uri, htmlLanguageTypes_1.Range.create(document.positionAt(node.start), document.positionAt(node.end))); | ||||
|         const symbol = { | ||||
|             name: name, | ||||
|             location: location, | ||||
|             containerName: container, | ||||
|             kind: htmlLanguageTypes_1.SymbolKind.Field | ||||
|         }; | ||||
|         symbols.push(symbol); | ||||
|         node.children.forEach(child => { | ||||
|             provideFileSymbolsInternal(document, child, name, symbols); | ||||
|         }); | ||||
|     } | ||||
|     function nodeToName(node) { | ||||
|         let name = node.tag; | ||||
|         if (node.attributes) { | ||||
|             const id = node.attributes['id']; | ||||
|             const classes = node.attributes['class']; | ||||
|             if (id) { | ||||
|                 name += `#${id.replace(/[\"\']/g, '')}`; | ||||
|             } | ||||
|             if (classes) { | ||||
|                 name += classes.replace(/[\"\']/g, '').split(/\s+/).map(className => `.${className}`).join(''); | ||||
|             } | ||||
|         } | ||||
|         return name || '?'; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										140
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/pathCompletion.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								node_modules/vscode-html-languageservice/lib/umd/services/pathCompletion.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,140 @@ | |||
| /*--------------------------------------------------------------------------------------------- | ||||
|  *  Copyright (c) Microsoft Corporation. All rights reserved. | ||||
|  *  Licensed under the MIT License. See License.txt in the project root for license information. | ||||
|  *--------------------------------------------------------------------------------------------*/ | ||||
| (function (factory) { | ||||
|     if (typeof module === "object" && typeof module.exports === "object") { | ||||
|         var v = factory(require, exports); | ||||
|         if (v !== undefined) module.exports = v; | ||||
|     } | ||||
|     else if (typeof define === "function" && define.amd) { | ||||
|         define(["require", "exports", "../htmlLanguageTypes", "../utils/strings"], factory); | ||||
|     } | ||||
| })(function (require, exports) { | ||||
|     "use strict"; | ||||
|     Object.defineProperty(exports, "__esModule", { value: true }); | ||||
|     exports.PathCompletionParticipant = void 0; | ||||
|     const htmlLanguageTypes_1 = require("../htmlLanguageTypes"); | ||||
|     const strings_1 = require("../utils/strings"); | ||||
|     class PathCompletionParticipant { | ||||
|         constructor(dataManager, readDirectory) { | ||||
|             this.dataManager = dataManager; | ||||
|             this.readDirectory = readDirectory; | ||||
|             this.atributeCompletions = []; | ||||
|         } | ||||
|         onHtmlAttributeValue(context) { | ||||
|             if (this.dataManager.isPathAttribute(context.tag, context.attribute)) { | ||||
|                 this.atributeCompletions.push(context); | ||||
|             } | ||||
|         } | ||||
|         async computeCompletions(document, documentContext) { | ||||
|             const result = { items: [], isIncomplete: false }; | ||||
|             for (const attributeCompletion of this.atributeCompletions) { | ||||
|                 const fullValue = stripQuotes(document.getText(attributeCompletion.range)); | ||||
|                 if (isCompletablePath(fullValue)) { | ||||
|                     if (fullValue === '.' || fullValue === '..') { | ||||
|                         result.isIncomplete = true; | ||||
|                     } | ||||
|                     else { | ||||
|                         const replaceRange = pathToReplaceRange(attributeCompletion.value, fullValue, attributeCompletion.range); | ||||
|                         const suggestions = await this.providePathSuggestions(attributeCompletion.value, replaceRange, document, documentContext); | ||||
|                         for (const item of suggestions) { | ||||
|                             result.items.push(item); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return result; | ||||
|         } | ||||
|         async providePathSuggestions(valueBeforeCursor, replaceRange, document, documentContext) { | ||||
|             const valueBeforeLastSlash = valueBeforeCursor.substring(0, valueBeforeCursor.lastIndexOf('/') + 1); // keep the last slash
 | ||||
|             let parentDir = documentContext.resolveReference(valueBeforeLastSlash || '.', document.uri); | ||||
|             if (parentDir) { | ||||
|                 try { | ||||
|                     const result = []; | ||||
|                     const infos = await this.readDirectory(parentDir); | ||||
|                     for (const [name, type] of infos) { | ||||
|                         // Exclude paths that start with `.`
 | ||||
|                         if (name.charCodeAt(0) !== CharCode_dot) { | ||||
|                             result.push(createCompletionItem(name, type === htmlLanguageTypes_1.FileType.Directory, replaceRange)); | ||||
|                         } | ||||
|                     } | ||||
|                     return result; | ||||
|                 } | ||||
|                 catch (e) { | ||||
|                     // ignore
 | ||||
|                 } | ||||
|             } | ||||
|             return []; | ||||
|         } | ||||
|     } | ||||
|     exports.PathCompletionParticipant = PathCompletionParticipant; | ||||
|     const CharCode_dot = '.'.charCodeAt(0); | ||||
|     function stripQuotes(fullValue) { | ||||
|         if ((0, strings_1.startsWith)(fullValue, `'`) || (0, strings_1.startsWith)(fullValue, `"`)) { | ||||
|             return fullValue.slice(1, -1); | ||||
|         } | ||||
|         else { | ||||
|             return fullValue; | ||||
|         } | ||||
|     } | ||||
|     function isCompletablePath(value) { | ||||
|         if ((0, strings_1.startsWith)(value, 'http') || (0, strings_1.startsWith)(value, 'https') || (0, strings_1.startsWith)(value, '//')) { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|     function pathToReplaceRange(valueBeforeCursor, fullValue, range) { | ||||
|         let replaceRange; | ||||
|         const lastIndexOfSlash = valueBeforeCursor.lastIndexOf('/'); | ||||
|         if (lastIndexOfSlash === -1) { | ||||
|             replaceRange = shiftRange(range, 1, -1); | ||||
|         } | ||||
|         else { | ||||
|             // For cases where cursor is in the middle of attribute value, like <script src="./s|rc/test.js">
 | ||||
|             // Find the last slash before cursor, and calculate the start of replace range from there
 | ||||
|             const valueAfterLastSlash = fullValue.slice(lastIndexOfSlash + 1); | ||||
|             const startPos = shiftPosition(range.end, -1 - valueAfterLastSlash.length); | ||||
|             // If whitespace exists, replace until there is no more
 | ||||
|             const whitespaceIndex = valueAfterLastSlash.indexOf(' '); | ||||
|             let endPos; | ||||
|             if (whitespaceIndex !== -1) { | ||||
|                 endPos = shiftPosition(startPos, whitespaceIndex); | ||||
|             } | ||||
|             else { | ||||
|                 endPos = shiftPosition(range.end, -1); | ||||
|             } | ||||
|             replaceRange = htmlLanguageTypes_1.Range.create(startPos, endPos); | ||||
|         } | ||||
|         return replaceRange; | ||||
|     } | ||||
|     function createCompletionItem(p, isDir, replaceRange) { | ||||
|         if (isDir) { | ||||
|             p = p + '/'; | ||||
|             return { | ||||
|                 label: p, | ||||
|                 kind: htmlLanguageTypes_1.CompletionItemKind.Folder, | ||||
|                 textEdit: htmlLanguageTypes_1.TextEdit.replace(replaceRange, p), | ||||
|                 command: { | ||||
|                     title: 'Suggest', | ||||
|                     command: 'editor.action.triggerSuggest' | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|         else { | ||||
|             return { | ||||
|                 label: p, | ||||
|                 kind: htmlLanguageTypes_1.CompletionItemKind.File, | ||||
|                 textEdit: htmlLanguageTypes_1.TextEdit.replace(replaceRange, p) | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
|     function shiftPosition(pos, offset) { | ||||
|         return htmlLanguageTypes_1.Position.create(pos.line, pos.character + offset); | ||||
|     } | ||||
|     function shiftRange(range, startOffset, endOffset) { | ||||
|         const start = shiftPosition(range.start, startOffset); | ||||
|         const end = shiftPosition(range.end, endOffset); | ||||
|         return htmlLanguageTypes_1.Range.create(start, end); | ||||
|     } | ||||
| }); | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 sindrekjelsrud
						sindrekjelsrud