vaderjs 1.2.8 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "1.2.8",
4
- "description": "A Reactive Framework for Single-Page Applications (SPA)",
3
+ "version": "1.3.0",
4
+ "description": "A Reactive Framework for Building Content Rich Single-Page Applications (SPA)",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "tsc --noEmit "
package/vader.js CHANGED
@@ -1,5 +1,6 @@
1
1
  let dom = /**@type {Obect} **/ {};
2
2
  let states = {};
3
+ let worker = new Worker(new URL('./worker.js', import.meta.url));
3
4
  /**
4
5
  * @function markdown
5
6
  * @param {String} content
@@ -219,8 +220,7 @@ export class Component {
219
220
  * @description Allows you to use a web worker to compile html code on the fly - client fly rendering
220
221
 
221
222
  */
222
- // @ts-ignore
223
- this.worker = new Worker(new URL('./worker.js', import.meta.url));
223
+
224
224
  }
225
225
 
226
226
  /**
@@ -846,7 +846,6 @@ export class Component {
846
846
  element.setAttribute("hidden", "true");
847
847
  // if window.lcoation.pathname includes a html file remove it and only use the path
848
848
  let url = window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '') + '/public/' + element.getAttribute("src");
849
- // @ts-ignore
850
849
  let image = new Image();
851
850
  image.src = url;
852
851
  image.onerror = () => {
@@ -1008,26 +1007,20 @@ export class Component {
1008
1007
 
1009
1008
  if(this.cfr){
1010
1009
 
1011
- this.worker.postMessage({strings, args, location: window.location.href, name: this.name})
1010
+ worker.postMessage({strings, args, location: window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '') + '/public/', name: this.name})
1012
1011
  let promise = new Promise((resolve, reject)=>{
1013
- this.worker.onmessage = (e)=>{
1012
+ worker.onmessage = (e)=>{
1014
1013
  if(e.data.error){
1015
1014
  throw new Error(e.data.error)
1016
1015
  }
1017
1016
 
1018
- let d = ""
1019
- if(new Function("useRef", `return \`${e.data}\``)(useRef).includes('#')){
1020
- d = markdown(new Function("useRef", `return \`${e.data}\``)(useRef))
1021
- }else{
1022
- d = new Function("useRef", `return \`${e.data}\``)(useRef)
1023
- }
1024
-
1025
- resolve(d)
1017
+
1018
+ resolve(new Function("useRef", `return \`${e.data}\``)(useRef))
1026
1019
 
1027
1020
 
1028
1021
 
1029
1022
  }
1030
- this.worker.onerror = (e)=>{
1023
+ worker.onerror = (e)=>{
1031
1024
  reject(e)
1032
1025
  }
1033
1026
  })
@@ -1131,12 +1124,90 @@ export const rf = (name, fn) => {
1131
1124
  window[name] = fn;
1132
1125
  };
1133
1126
  let cache = {};
1127
+ async function handletemplate(data){
1128
+ let dom = new DOMParser().parseFromString(data, "text/html");
1129
+ let elements = dom.documentElement.querySelectorAll("*");
1130
+
1131
+ if (elements.length > 0) {
1132
+ for (var i = 0; i < elements.length; i++) {
1133
+
1134
+ if (elements[i].nodeName === "INCLUDE") {
1135
+ if(!elements[i].getAttribute("src") || elements[i].getAttribute("src") === ""){
1136
+ throw new Error("Include tag must have src attribute")
1137
+ }
1138
+
1139
+ let componentName = elements[i].getAttribute("src")?.split("/").pop()?.split(".")[0]
1140
+ // @ts-ignore
1141
+ let filedata = await include(elements[i].getAttribute("src"))
1142
+ // replace ` with \`\` to allow for template literals
1143
+ filedata = filedata.replace(/`/g, "\\`")
1144
+ cache[elements[i].getAttribute("src")] = filedata
1145
+ filedata = new Function(`return \`${filedata}\`;`)();
1146
+ let newdom = new DOMParser().parseFromString(filedata, "text/html");
1147
+
1148
+ newdom.querySelectorAll("include").forEach((el)=>{
1149
+ el.remove()
1150
+ })
1151
+ // @ts-ignore
1152
+
1153
+ let els = dom.querySelectorAll(componentName)
1154
+
1155
+ els.forEach((el)=>{
1156
+
1157
+ if(el.attributes.length > 0){
1158
+ for(var i = 0; i < el.attributes.length; i++){
1159
+ newdom.body.outerHTML = newdom.body.outerHTML.replace(`{{${el.attributes[i].name}}}`, el.attributes[i].value)
1160
+ }
1161
+
1162
+ }
1163
+ if(el.children.length > 0 && newdom.body.querySelector('slot')){
1164
+ for(var i = 0; i < el.children.length; i++){
1165
+ let slots = newdom.body.querySelectorAll("slot")
1166
+ slots.forEach((slot)=>{
1167
+ let id = slot.getAttribute("id")
1168
+ if(id === el.nodeName.toLowerCase()){
1169
+ slot.outerHTML = `<div>${el.innerHTML}</div>`
1170
+ }
1171
+ })
1172
+
1173
+
1174
+ }
1175
+
1176
+ }
1177
+
1178
+ dom.body.querySelectorAll('include').forEach((el)=>{
1179
+ el.remove()
1180
+ })
1181
+ // replace ` with \`\` to allow for template literals
1182
+ dom.body.outerHTML = dom.body.outerHTML.replace(/`/g, "\\`")
1183
+ dom.body.outerHTML = dom.body.outerHTML.replace(el.outerHTML, new Function(`return \`${newdom.body.outerHTML}\`;`)())
1184
+
1185
+
1186
+ })
1187
+
1188
+
1189
+
1190
+
1191
+ }
1192
+ }
1193
+
1194
+
1195
+ }
1196
+
1197
+ // replace ` with \`\` to allow for template literals
1198
+ dom.body.outerHTML = dom.body.outerHTML.replace(/`/g, "\\`")
1199
+ data = new Function(`return \`${dom.body.outerHTML}\`;`)();
1200
+
1201
+ return data;
1202
+ }
1134
1203
  /**
1135
1204
  * @function include
1136
1205
  * @description Allows you to include html file
1137
1206
  * @returns {Promise} - modified string with html content
1138
1207
  * @param {string} path
1139
1208
  */
1209
+
1210
+
1140
1211
 
1141
1212
  export const include = async (path) => {
1142
1213
 
@@ -1150,10 +1221,10 @@ export const include = async (path) => {
1150
1221
  path = "/src/" + path;
1151
1222
  }
1152
1223
  if (cache[path]) {
1153
- return new Function(`return \`${cache[path]}\`;`)();
1154
- }
1155
-
1156
- return fetch(`./${path}`)
1224
+ return await handletemplate(new Function(`return \`${cache[path]}\`;`)())
1225
+
1226
+ }else{
1227
+ return fetch(`./${path}`)
1157
1228
  .then((res) => {
1158
1229
  if (res.status === 404) {
1159
1230
  throw new Error(`No file found at ${path}`);
@@ -1161,81 +1232,14 @@ export const include = async (path) => {
1161
1232
  return res.text();
1162
1233
  })
1163
1234
  .then(async (data) => {
1164
- data = new Function(`return \`${data}\`;`)();
1165
-
1166
- let dom = new DOMParser().parseFromString(data, "text/html");
1167
- let elements = dom.documentElement.querySelectorAll("*");
1168
- let conccurentIncludes = [];
1169
- if(cache[path]){
1170
- return new Function(`return \`${cache[path]}\`;`)();
1171
- }
1172
- if (elements.length > 0) {
1173
- for (var i = 0; i < elements.length; i++) {
1174
-
1175
- if (elements[i].nodeName === "INCLUDE") {
1176
- if(!elements[i].getAttribute("src") || elements[i].getAttribute("src") === ""){
1177
- throw new Error("Include tag must have src attribute")
1178
- }
1179
-
1180
- let componentName = elements[i].getAttribute("src")?.split("/").pop()?.split(".")[0]
1181
- // @ts-ignore
1182
- let filedata = await include(elements[i].getAttribute("src"));
1183
- filedata = new Function(`return \`${filedata}\`;`)();
1184
- let newdom = new DOMParser().parseFromString(filedata, "text/html");
1185
-
1186
- newdom.querySelectorAll("include").forEach((el)=>{
1187
- el.remove()
1188
- })
1189
- // @ts-ignore
1190
-
1191
- let els = dom.querySelectorAll(componentName)
1192
-
1193
- els.forEach((el)=>{
1194
-
1195
- console.log(el)
1196
- if(el.attributes.length > 0){
1197
- for(var i = 0; i < el.attributes.length; i++){
1198
- newdom.body.outerHTML = newdom.body.outerHTML.replace(`{{${el.attributes[i].name}}}`, el.attributes[i].value)
1199
- }
1200
-
1201
- }
1202
- if(el.children.length > 0 && newdom.body.querySelector('slot')){
1203
- for(var i = 0; i < el.children.length; i++){
1204
- let slots = newdom.body.querySelectorAll("slot")
1205
- slots.forEach((slot)=>{
1206
- let id = slot.getAttribute("id")
1207
- if(id === el.nodeName.toLowerCase()){
1208
- slot.outerHTML = `<div>${el.innerHTML}</div>`
1209
- }
1210
- })
1211
-
1212
-
1213
- }
1214
-
1215
- }
1216
-
1217
- dom.body.querySelectorAll('include').forEach((el)=>{
1218
- el.remove()
1219
- })
1220
-
1221
- dom.body.outerHTML = dom.body.outerHTML.replace(el.outerHTML, newdom.body.innerHTML)
1222
-
1223
-
1224
- })
1225
-
1226
-
1227
-
1228
-
1229
- }
1230
- }
1231
-
1232
-
1233
- }
1234
-
1235
- data = dom.body.outerHTML
1236
-
1237
- return data;
1235
+ cache[path] = data
1236
+
1237
+ data = await handletemplate(new Function(`return \`${data}\`;`)())
1238
+
1239
+ return data
1238
1240
  });
1241
+ }
1242
+
1239
1243
  };
1240
1244
 
1241
1245
  export default Vader;
package/vaderRouter.js CHANGED
@@ -53,7 +53,7 @@ class VaderRouter{
53
53
 
54
54
  /**
55
55
  * @method listen
56
- * @param {String} port - unique id for the listener
56
+ * @param {*} port - unique id for the listener
57
57
  * @param {Function} callback - callback function
58
58
  * @description This method is used to start listening to the routes
59
59
  * @returns {void}
@@ -226,4 +226,6 @@ class VaderRouter{
226
226
 
227
227
  }
228
228
 
229
- export default VaderRouter;
229
+ export default VaderRouter;
230
+
231
+
package/worker.js CHANGED
@@ -1,8 +1,9 @@
1
+
1
2
  onmessage = (e)=>{
2
3
  let time_started = Date.now()
3
4
  let strings = e.data.strings
4
5
  let args = e.data.args
5
- let l = e.data.location.split('/#/')[0]
6
+ let l = e.data.location.split('/').slice(0,-1).join('/')
6
7
  let result = "";
7
8
  for (let i = 0; i < strings.length; i++) {
8
9
  result += strings[i];
@@ -21,15 +22,78 @@ onmessage = (e)=>{
21
22
  }
22
23
  }
23
24
 
24
- let code = result.match(/<code([^>]*)>/g)
25
- if(code){
26
- while(code.length){
27
- let c = code.pop()
28
- // @ts-ignore
29
- c = c.replace('<code','').replace('>','')
30
- result = result.replace(`<code${c}>`,`<code${c} style="background:#000;color:#fff;padding:5px;border-radius:5px;font-size:12px;font-weight:bold">`)
25
+
26
+ // Convert headings (e.g., #1-6 Heading => <h1-6>Heading</h1-6>)
27
+ // @ts-ignore
28
+ result = result.replace(/(#+)(.*)/g, (match, hashes, text) => {
29
+ if(!match.includes('<')){
30
+ let level = hashes.length;
31
+ return `<h ${level} class="markdown_heading">${text}</h${level}>`;
31
32
  }
32
- }
33
+ });
34
+
35
+
36
+ // Convert bold (e.g., **Bold** => <b>Bold</b>)
37
+ result = result.replace(/\*\*(.*?)\*\*/g, (match, text) => {
38
+ return `<b class="markdown_bold">${text}</b>`;
39
+ });
40
+
41
+ // Convert italic (e.g., *Italic* => <i>Italic</i>)
42
+ result = result.replace(/\*(.*?)\*/g, (match, text) => {
43
+ return `<i class="markdown_italic">${text}</i>`;
44
+ });
45
+
46
+ // Convert code (e.g., `code` => <code>code</code>)
47
+ result = result.replace(/`(.*?)`/g, (match, text) => {
48
+ return `<code>${text}</code>`;
49
+ });
50
+
51
+ // Convert links (e.g., [Text](URL) => <a href="URL">Text</a>)
52
+ result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, text, url) => {
53
+ return `<a class="markdown_link" href="${url}">${text}</a>`;
54
+ });
55
+
56
+ // Convert images (e.g., ![Alt](URL) => <img src="URL" alt="Alt" />)
57
+ result = result.replace(/!\[([^\]]+)\]\(([^)]+)\)/g, (match, alt, src) => {
58
+ return `<img class="markdown_image" src="${src}" alt="${alt}" />`;
59
+ });
60
+
61
+ // Convert unordered lists (e.g., * Item => <ul><li>Item</li></ul>)
62
+ result.split('\n').forEach((line, index, arr) => {
63
+ if (line.match(/^\s*-\s+(.*?)$/gm)) {
64
+ if (index === 0 || !arr[index - 1].match(/^\s*-\s+(.*?)$/gm)) {
65
+ result = result.replace(line, `<ul class="markdown_unordered" style="list-style-type:disc;list-style:inside;"><li>${line.replace(/^\s*-\s+(.*?)$/gm, '$1')}</li>`);
66
+ } else if (index === arr.length - 1 || !arr[index + 1].match(/^\s*-\s+(.*?)$/gm)) {
67
+ result = result.replace(line, `<li>${line.replace(/^\s*-\s+(.*?)$/gm, '$1')}</li></ul>`);
68
+ } else {
69
+ result = result.replace(line, `<li>${line.replace(/^\s*-\s+(.*?)$/gm, '$1')}</li>`);
70
+ }
71
+ }
72
+ });
73
+
74
+
75
+ // Convert ordered lists (e.g., 1. Item => <ol><li>Item</li></ol>) in order
76
+
77
+ result.split('\n').forEach((line, index, arr) => {
78
+ if (line.match(/^\s*\d+\.\s+(.*?)$/gm)) {
79
+ if (index === 0 || !arr[index - 1].match(/^\s*\d+\.\s+(.*?)$/gm)) {
80
+ result = result.replace(line, `<ol class="markdown_ordered" style="list-style-type:decimal;"><li>${line.replace(/^\s*\d+\.\s+(.*?)$/gm, '$1')}</li>`);
81
+ } else if (index === arr.length - 1 || !arr[index + 1].match(/^\s*\d+\.\s+(.*?)$/gm)) {
82
+ result = result.replace(line, `<li>${line.replace(/^\s*\d+\.\s+(.*?)$/gm, '$1')}</li></ol>`);
83
+ } else {
84
+ result = result.replace(line, `<li>${line.replace(/^\s*\d+\.\s+(.*?)$/gm, '$1')}</li>`);
85
+ }
86
+ }
87
+ });
88
+
89
+
90
+ result = result.replace(/^\s*-\s+(.*?)$/gm, (match, text) => {
91
+ return `<li class="markdown_list_item">${text}</li>`;
92
+ });
93
+ result = result.replace(/^\s*---\s*$/gm, '<hr class="markdown_horizontal" />');
94
+
95
+
96
+
33
97
 
34
98
 
35
99
  if(!result.includes('<body>')){
@@ -47,13 +111,15 @@ onmessage = (e)=>{
47
111
  */
48
112
  // @ts-ignore
49
113
  let images = result.match(/<img([^>]*)>/g)
50
- for(let i = 0; i < images.length; i++){
114
+ if(images){
115
+ for(let i = 0; i < images.length; i++){
51
116
  let image = images[i]
52
117
  let src = image.match(/src="([^"]*)"/)
53
118
  let alt = image.match(/alt="([^"]*)"/)
54
119
  if(src){
55
120
  if(!src[1].includes('http') || !result.includes('<!-- #vader-disable_relative-paths -->')){
56
- result = result.replace(src[0],`src="${l}/public/${src[1]}"`)
121
+ // @ts-ignore
122
+ result = result.replace(src[1],`${l}/${src[1]}`)
57
123
  }else{
58
124
  throw new Error(`Vader Error: You cannot use relative paths in the src attribute of ${src[0]}. Use absolute paths instead. \n\n${src[0]}`)
59
125
  }
@@ -63,20 +129,21 @@ onmessage = (e)=>{
63
129
  }
64
130
 
65
131
  // @ts-ignore
66
- if(!caches.match(`${l}/public/${src[1]}`)){
132
+ if(!caches.match(`${l}/${src[1]}`)){
67
133
  caches.open('vader').then((cache)=>{
68
134
  // @ts-ignore
69
- cache.add(`${l}/public/${src[1]}`)
135
+ cache.add(`${l}/${src[1]}`)
70
136
  // @ts-ignore
71
- console.log('cached', `${l}/public/${src[1]}`)
137
+ console.log('cached', `${l}/${src[1]}`)
72
138
  }).catch((err)=>{
73
139
  console.log(err)
74
140
  })
75
141
  }else{
76
142
  // @ts-ignore
77
- console.log('already cached', caches.match(`${l}/public/${src[1]}`))
143
+ console.log('already cached', caches.match(`${l}/${src[1]}`))
78
144
  }
79
145
  }
146
+ }
80
147
 
81
148
  let href = result.match(/href="([^"]*)"/g)
82
149
  if(href){
@@ -1,17 +0,0 @@
1
- // A launch configuration that launches the extension inside a new window
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- {
6
- "version": "0.2.0",
7
- "configurations": [
8
- {
9
- "name": "Extension",
10
- "type": "extensionHost",
11
- "request": "launch",
12
- "args": [
13
- "--extensionDevelopmentPath=${workspaceFolder}"
14
- ]
15
- }
16
- ]
17
- }
@@ -1,4 +0,0 @@
1
- .vscode/**
2
- .vscode-test/**
3
- .gitignore
4
- vsc-extension-quickstart.md
@@ -1,9 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to the "vader" extension will be documented in this file.
4
-
5
- Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
6
-
7
- ## [Unreleased]
8
-
9
- - Initial release
@@ -1,26 +0,0 @@
1
- # vader README
2
-
3
-
4
- ## Features
5
-
6
- HTML syntax highlighting for vader files & intellisense / autocomplete for html elements and vader.js methods
7
-
8
- Shows deprecated methods as deprecated in the intellisense - and shows suggestions for alternatives
9
-
10
- ## Requirements
11
-
12
- Common knowlege of HTML and vader.js!
13
-
14
-
15
- ## Known Issues
16
-
17
-
18
-
19
- ## Release Notes
20
-
21
- Users appreciate release notes as you update your extension.
22
-
23
- ### 1.0.0
24
-
25
- Initial release of vader
26
-
@@ -1,70 +0,0 @@
1
- const vscode = require('vscode');
2
- const html_completes = require('./html_completion/html_completion');
3
- function activate(context) {
4
-
5
- let completes = []
6
- const include = vscode.languages.registerCompletionItemProvider(
7
- 'vader',
8
- {
9
- provideCompletionItems(document, position) {
10
- const linePrefix = document.lineAt(position).text.trim();
11
- if(!linePrefix.startsWith('in')) {
12
- return undefined;
13
- }
14
- let complete = new vscode.CompletionItem('include()', vscode.CompletionItemKind.Function);
15
- complete.insertText = new vscode.SnippetString('include("${1:file}")');
16
-
17
- complete.tags = [vscode.CompletionItemTag.Deprecated]
18
-
19
- complete.documentation = new vscode.MarkdownString(`Include a view file into your template\n - @param \`\string\`\ file - The file to include\n- @returns {string} - the parsed html code to client`, true)
20
- return [complete]
21
- }
22
- },
23
- )
24
-
25
- const comment = vscode.languages.registerCompletionItemProvider('vader', {
26
- provideCompletionItems(document, position) {
27
- const linePrefix = document.lineAt(position).text.slice(0, position.character);
28
- if(!linePrefix.includes('-')) {
29
- return undefined;
30
- }
31
- let complete = new vscode.CompletionItem('-', vscode.CompletionItemKind.Property);
32
- complete.insertText = new vscode.SnippetString('-- \n ${1:comment} \n--');
33
- complete.documentation = new vscode.MarkdownString(`Create a multi line comment`, true)
34
- return [complete]
35
-
36
- },
37
- }, )
38
-
39
- const syntaxeror = vscode.languages.registerCompletionItemProvider('vader', {
40
- provideCompletionItems(document, position) {
41
- let firstline = document.lineAt(0).text.trim();
42
- let lastline = document.lineAt(document.lineCount - 1).text.trim();
43
- if(!firstline.includes('body') || !lastline.includes('body')) {
44
-
45
- vscode.window.showWarningMessage('Syntax error: missing <body> tag in template\n vader may cut off your code if not present')
46
-
47
- return undefined;
48
- }
49
- },
50
- })
51
-
52
-
53
-
54
-
55
- const includehover = vscode.languages.registerHoverProvider('vader', {
56
- provideHover(document, position) {
57
- const linePrefix = document.lineAt(position).text.slice(0, position.character);
58
- if (!linePrefix.startsWith('in')) {
59
- return undefined;
60
- }
61
- let complete = new vscode.Hover(new vscode.MarkdownString(`Include a view file into your template\n - @param {string} file - The file to include\n- @returns {string} - the parsed html code to client`, true))
62
- return complete
63
- }
64
- })
65
-
66
-
67
- context.subscriptions.push(include, html_completes, comment, includehover, syntaxeror,completes);
68
- }
69
-
70
- module.exports.activate = activate;
@@ -1,91 +0,0 @@
1
- const vscode = require('vscode');
2
- let completes = []
3
- const html_completes = vscode.languages.registerCompletionItemProvider('vader', {
4
- provideCompletionItems(document, position) {
5
- let line = document.lineAt(position).text.trim();
6
-
7
- let {tags, attributes} = JSON.parse(require('fs').readFileSync(require('path').join(__dirname, 'html_completion.json'), 'utf8'))
8
-
9
- let items = []
10
-
11
-
12
-
13
- for(tag in tags){
14
-
15
- if(!line.startsWith('<') && !line.endsWith('>')){
16
- continue
17
- }
18
- let complete = new vscode.CompletionItem(tag, tags[tag].type && tags[tag].type === "keyword" ? vscode.CompletionItemKind.Keyword : vscode.CompletionItemKind.Module);
19
- // make sure its not in range between a entering < and closing > with a space in between
20
- if(line.startsWith('<') && line.endsWith('>') && line.includes(' ')){
21
- // remove the tag from the completion
22
- let line = document.lineAt(position).text.trim();
23
- complete.range = new vscode.Range(new vscode.Position(position.line, line.indexOf('<')), new vscode.Position(position.line, line.indexOf('<') + tag.length))
24
- }
25
- complete.insertText = new vscode.SnippetString(tags[tag].body);
26
- if(tags[tag].deprecated){
27
- complete.tags = [vscode.CompletionItemTag.Deprecated]
28
- }
29
- complete.documentation = new vscode.MarkdownString(tags[tag].description, true)
30
- items.push(complete)
31
- }
32
- for(attribute in attributes){
33
- let line = document.lineAt(position).text.trim();
34
- if(line.includes('<') || line.includes('>') ){
35
- let tag = line.split('<')[1] ? line.split('<')[1].split('>')[0].split(' ')[0] : line.split('>')[0]
36
- let valid_in = attributes[attribute].valid_in
37
- if(valid_in.includes(tag) || valid_in.includes('*')){
38
- let complete = new vscode.CompletionItem(attribute, vscode.CompletionItemKind.Property);
39
- if(attributes[attribute].deprecated){
40
- complete.tags = [vscode.CompletionItemTag.Deprecated]
41
- }
42
- complete.insertText = new vscode.SnippetString(attributes[attribute].body);
43
- complete.documentation = new vscode.MarkdownString(attributes[attribute].description, true)
44
- items.push(complete)
45
- }
46
-
47
-
48
-
49
- }
50
- }
51
- return items
52
- },
53
- } , )
54
-
55
- const hovercompletes = vscode.languages.registerHoverProvider('vader', {
56
- provideHover(document, position) {
57
- let selection = document.getText(document.getWordRangeAtPosition(position));
58
-
59
-
60
- let {tags, attributes} = JSON.parse(require('fs').readFileSync(require('path').join(__dirname, 'html_completion.json'), 'utf8'))
61
- let line = document.lineAt(position.line).text.trim();
62
-
63
- // make sure no attributes are in the hover position
64
- if (selection === line.split('<')[1].split('>')[0].split(' ')[0]) {
65
- let tag = line.split('<')[1].split('>')[0].split(' ')[0]
66
- if (tags[tag]) {
67
- return new vscode.Hover(new vscode.MarkdownString(tags[tag].description, true))
68
- }
69
- }
70
- // get the parent tag
71
- let parent_tag = line.split('<')[1].split('>')[0].split(' ')[0]
72
- // get the attribute
73
- let tag_attributes = line.split('<')[1].split('>')[0].split(' ')
74
- for (let i = 0; i < tag_attributes.length; i++) {
75
- let attribute = tag_attributes[i]
76
- if (attribute.includes('=')) {
77
- attribute = attribute.split('=')[0]
78
- }
79
- if (attribute === selection) {
80
- if (attributes[attribute]) {
81
- return new vscode.Hover(new vscode.MarkdownString(attributes[attribute].description, true))
82
- }
83
- }
84
- }
85
-
86
- return null; // Return null if no matching tag or attribute is found.
87
- }
88
- });
89
- completes.push(html_completes, hovercompletes)
90
-
91
- module.exports = completes