vaderjs 1.2.7 → 1.2.9

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/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
@@ -39,12 +40,16 @@ function markdown(content) {
39
40
  }
40
41
  if (bold) {
41
42
  bold.forEach((b) => {
42
- line = line.replace(b, `<strong>${b.replace(/\*\*/g, "")}</strong>`);
43
+ line = line.replace(b, `<strong
44
+ className="$vader_markdown_bold"
45
+ >${b.replace(/\*\*/g, "")}</strong>`);
43
46
  });
44
47
  }
45
48
  if (italic) {
46
49
  italic.forEach((i) => {
47
- line = line.replace(i, `<em>${i.replace(/\*/g, "")}</em>`);
50
+ line = line.replace(i, `<em
51
+ className="$vader_markdown_italic"
52
+ >${i.replace(/\*/g, "")}</em>`);
48
53
  });
49
54
  }
50
55
 
@@ -55,22 +60,30 @@ function markdown(content) {
55
60
  let text = l.match(/\[(.*?)\]/g)[0].replace(/\[|\]/g, "");
56
61
  // @ts-ignore
57
62
  let href = l.match(/\((.*?)\)/g)[0].replace(/\(|\)/g, "");
58
- line = line.replace(l, `<a href="${href}">${text}</a>`);
63
+ line = line.replace(l, `<a
64
+ className="$vader_markdown_link"
65
+ href="${href}">${text}</a>`);
59
66
  });
60
67
  }
61
68
  if (ul) {
62
- line = line.replace(ul[0], `<li style="list-style-type: disc;">`);
69
+ line = line.replace(ul[0], `<li
70
+ className="$vader_markdown_ul"
71
+ style="list-style-type: disc;">`);
63
72
  line += `</li>`;
64
73
  }
65
74
  if (ol) {
66
- line = line.replace(ol[0], `<li style="list-style-type: decimal;">`);
75
+ line = line.replace(ol[0], `<li
76
+ className="$vader_markdown_ol"
77
+ style="list-style-type: decimal;">`);
67
78
  line += `</li>`;
68
79
  }
69
80
  if (hr) {
70
81
  line = line.replace(hr[0], `<hr/>`);
71
82
  }
72
83
  if (blockquote) {
73
- line = line.replace(blockquote[0], `<blockquote>`);
84
+ line = line.replace(blockquote[0], `<blockquote
85
+ className="$vader_markdown_blockquote"
86
+ >`);
74
87
  line += `</blockquote>`;
75
88
  }
76
89
  if (image) {
@@ -80,7 +93,9 @@ function markdown(content) {
80
93
  // @ts-ignore
81
94
  let src = i.match(/\((.*?)\)/g)[0].replace(/\(|\)/g, "");
82
95
  i.replace(i, `<img src="${src}" alt="${alt}"/>`);
83
- line = line.replace(i, `<img src="${src}" alt="${alt}"/>`).replace('!','')
96
+ line = line.replace(i, `<img
97
+ className="$vader_markdown_image"
98
+ src="${src}" alt="${alt}"/>`).replace('!','')
84
99
  });
85
100
  }
86
101
  if (li) {
@@ -88,7 +103,7 @@ function markdown(content) {
88
103
  line += `</li>`;
89
104
  }
90
105
  if (codeBlock) {
91
- line = line.replace(codeBlock[0], `<pre><code>`);
106
+ line = line.replace(codeBlock[0], `<pre className="$vader_markdown_code_block" ><code>`);
92
107
  }
93
108
  if (codeBlockEnd) {
94
109
  line = line.replace(codeBlockEnd[0], `</code></pre>`);
@@ -97,8 +112,8 @@ function markdown(content) {
97
112
  if (code) {
98
113
  code.forEach((c) => {
99
114
  line = line.replace(c, `<code
115
+ className="$vader_markdown_code"
100
116
  style="background-color: #f5f5f5; padding: 5px; border-radius: 5px;
101
-
102
117
  "
103
118
  >${c.replace(/\`/g, "")}</code>`);
104
119
  });
@@ -194,6 +209,18 @@ export class Component {
194
209
  });
195
210
  this.snapshots = [];
196
211
 
212
+ /**
213
+ * @property {Boolean} cfr
214
+ * @description Allows you to compile html code on the fly - client fly rendering
215
+ *
216
+ */
217
+ this.cfr = false
218
+ /**
219
+ * @property {Boolean} worker
220
+ * @description Allows you to use a web worker to compile html code on the fly - client fly rendering
221
+
222
+ */
223
+
197
224
  }
198
225
 
199
226
  /**
@@ -207,6 +234,7 @@ export class Component {
207
234
  }
208
235
  init() {
209
236
  this.registerComponent();
237
+
210
238
  }
211
239
 
212
240
  registerComponent() {
@@ -775,92 +803,11 @@ export class Component {
775
803
  return /^[a-zA-Z0-9-_]+$/.test(className);
776
804
  }
777
805
 
778
- /**
779
- * The `html` method generates and processes HTML content for a component, performing various validations and tasks.
780
- *
781
- * @param {String} strings - The HTML content to be processed.
782
- * @param {...any} args - Dynamic values to be inserted into the template.
783
- * @returns {string} - The processed HTML content as a string.
784
- *
785
- * @throws {SyntaxError} - Throws a `SyntaxError` if image-related attributes are missing or invalid.
786
- * @throws {Error} - Throws an `Error` if there are issues with class names or relative paths.
787
- *
788
- * @example
789
- * // Example usage within a component:
790
- * const myComponent = new Component();
791
- * const htmlContent = myComponent.html`
792
- * <div>
793
- * <img src="/images/example.jpg" alt="Example Image" />
794
- * </div>
795
- * `;
796
- * document.body.innerHTML = htmlContent;
797
- *
798
- * @remarks
799
- * The `html` method is a core function used in component rendering. It allows you to define and generate HTML content within your component while enforcing best practices and accessibility standards. The method performs several essential tasks:
800
- *
801
- * 1. **Image Validation**: It checks images for the presence of 'alt' attributes and their validity.
802
- * - Throws a `SyntaxError` if an image is missing the 'alt' attribute.
803
- * - Throws a `SyntaxError` if the 'alt' attribute is empty.
804
- * - Checks for an 'aria-hidden' attribute for image elements.
805
- *
806
- * 2. **Class Attribute Handling**: It enforces class attribute usage and allows optional configuration via comments.
807
- * - Throws an `Error` if 'class' attributes are used without permission.
808
- * - Supports 'className' attributes for class definitions.
809
- * - Allows or disallows class-related comments based on your configuration.
810
- *
811
- * 3. **Relative Path Handling**: It processes relative paths in 'href' and 'src' attributes, ensuring proper routing.
812
- * - Converts relative 'href' attributes to anchor links with appropriate routing.
813
- * - Converts relative 'src' attributes to absolute paths with 'public' directories.
814
- *
815
- * 4. **Custom Component Attributes**: It supports adding a 'data-component' attribute to the root element.
816
- * - Ensures that the 'data-component' attribute is present for component identification.
817
- *
818
- * 5. **Lifecycle Method Invocation**: It invokes the `componentDidMount` method if called from a 'render' context.
819
- * - Executes `componentDidMount` to handle component initialization once the DOM is ready.
820
- *
821
- * @see {@link Component}
822
- * @see {@link Component#componentDidMount}
823
- */
824
-
825
- html(strings, ...args) {
826
- // @ts-ignore
827
- if (
828
- // @ts-ignore
829
- new Error().stack &&
830
- // @ts-ignore
831
- new Error().stack.split("\n").length > 0 &&
832
- // @ts-ignore
833
- new Error().stack.split("\n")[2] &&
834
- // @ts-ignore
835
- new Error().stack.split("\n")[2].includes("render") &&
836
- !this.componentMounted
837
- ) {
838
- this.componentMounted = true;
839
- this.componentDidMount();
840
- console.log("component mounted");
841
- }
842
-
843
- let result = "";
844
- for (let i = 0; i < strings.length; i++) {
845
- result += strings[i];
846
- if (i < args.length) {
847
- result += args[i];
848
- }
849
- }
850
-
851
- result = result.replace(/\\n/g, '\n').trim()
852
- // replace `
853
- result = result.replace(/`/g, '\`').trim()
854
-
855
- result = new Function("useRef", `return \`${result}\``)(useRef)
856
806
 
857
- if (!result.trim().startsWith("<body>")) {
858
- console.warn(
859
- "You should wrap your html in a body tag, vader may not grab all html!"
860
- );
861
- }
862
-
807
+ parseHTML(result) {
808
+
863
809
  const dom = new DOMParser().parseFromString(result, "text/html");
810
+ console.log(dom)
864
811
  const elements = dom.documentElement.querySelectorAll("*");
865
812
 
866
813
  elements.forEach((element) => {
@@ -941,27 +888,6 @@ export class Component {
941
888
  );
942
889
  }
943
890
  } else if (element.hasAttribute("className")) {
944
- const isLocalhost = window.location.href.includes("localhost");
945
- const is127001 = window.location.href.includes("127.0.0.1");
946
- const ignoreClassComments = document.documentElement.outerHTML
947
- .trim()
948
- .includes("<!-- #vader-class-ignore -->");
949
- const allowClassComments = document.documentElement.outerHTML
950
- .trim()
951
- .includes("<!-- #vader-allow_class -->");
952
-
953
- if (
954
- // @ts-ignore
955
- (!this.validateClassName(element.getAttribute("className")) &&
956
- isLocalhost) ||
957
- (is127001 && !ignoreClassComments && !allowClassComments)
958
- ) {
959
- throw new Error(
960
- `Invalid className ${element.getAttribute(
961
- "className"
962
- )}, please use camelCase instead - example: myClass`
963
- );
964
- }
965
891
  // @ts-ignore
966
892
  element.setAttribute("class", element.getAttribute("className"));
967
893
  element.removeAttribute("className");
@@ -998,6 +924,7 @@ export class Component {
998
924
  }
999
925
  break;
1000
926
  }
927
+
1001
928
  });
1002
929
 
1003
930
  result = dom.body.innerHTML;
@@ -1005,12 +932,122 @@ export class Component {
1005
932
  this.Componentcontent = result;
1006
933
 
1007
934
  if (!result.includes("<div data-component")) {
1008
- result = `<div
1009
-
1010
- data-component="${this.name}">${result}</div>`;
935
+ result = `<div data-component="${this.name}">${result}</div>`;
1011
936
  }
937
+ return markdown(result.replace(/\\n/g, '\n').trim())
1012
938
 
1013
- return result;
939
+ }
940
+
941
+ /**
942
+ * The `html` method generates and processes HTML content for a component, performing various validations and tasks.
943
+ *
944
+ * @param {String} strings - The HTML content to be processed.
945
+ * @param {...any} args - Dynamic values to be inserted into the template.
946
+ * @returns {string} - The processed HTML content as a string.
947
+ *
948
+ * @throws {SyntaxError} - Throws a `SyntaxError` if image-related attributes are missing or invalid.
949
+ * @throws {Error} - Throws an `Error` if there are issues with class names or relative paths.
950
+ *
951
+ * @example
952
+ * // Example usage within a component:
953
+ * const myComponent = new Component();
954
+ * const htmlContent = myComponent.html`
955
+ * <div>
956
+ * <img src="/images/example.jpg" alt="Example Image" />
957
+ * </div>
958
+ * `;
959
+ * document.body.innerHTML = htmlContent;
960
+ *
961
+ * @remarks
962
+ * The `html` method is a core function used in component rendering. It allows you to define and generate HTML content within your component while enforcing best practices and accessibility standards. The method performs several essential tasks:
963
+ *
964
+ * 1. **Image Validation**: It checks images for the presence of 'alt' attributes and their validity.
965
+ * - Throws a `SyntaxError` if an image is missing the 'alt' attribute.
966
+ * - Throws a `SyntaxError` if the 'alt' attribute is empty.
967
+ * - Checks for an 'aria-hidden' attribute for image elements.
968
+ *
969
+ * 2. **Class Attribute Handling**: It enforces class attribute usage and allows optional configuration via comments.
970
+ * - Throws an `Error` if 'class' attributes are used without permission.
971
+ * - Supports 'className' attributes for class definitions.
972
+ * - Allows or disallows class-related comments based on your configuration.
973
+ *
974
+ * 3. **Relative Path Handling**: It processes relative paths in 'href' and 'src' attributes, ensuring proper routing.
975
+ * - Converts relative 'href' attributes to anchor links with appropriate routing.
976
+ * - Converts relative 'src' attributes to absolute paths with 'public' directories.
977
+ *
978
+ * 4. **Custom Component Attributes**: It supports adding a 'data-component' attribute to the root element.
979
+ * - Ensures that the 'data-component' attribute is present for component identification.
980
+ *
981
+ * 5. **Lifecycle Method Invocation**: It invokes the `componentDidMount` method if called from a 'render' context.
982
+ * - Executes `componentDidMount` to handle component initialization once the DOM is ready.
983
+ *
984
+ * @see {@link Component}
985
+ * @see {@link Component#componentDidMount}
986
+ */
987
+
988
+
989
+
990
+ html(strings, ...args) {
991
+ // @ts-ignore
992
+ if (
993
+ // @ts-ignore
994
+ new Error().stack &&
995
+ // @ts-ignore
996
+ new Error().stack.split("\n").length > 0 &&
997
+ // @ts-ignore
998
+ new Error().stack.split("\n")[2] &&
999
+ // @ts-ignore
1000
+ new Error().stack.split("\n")[2].includes("render") &&
1001
+ !this.componentMounted
1002
+ ) {
1003
+ this.componentMounted = true;
1004
+ this.componentDidMount();
1005
+ }
1006
+
1007
+
1008
+ if(this.cfr){
1009
+
1010
+ worker.postMessage({strings, args, location: window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '') + '/public/', name: this.name})
1011
+ let promise = new Promise((resolve, reject)=>{
1012
+ worker.onmessage = (e)=>{
1013
+ if(e.data.error){
1014
+ throw new Error(e.data.error)
1015
+ }
1016
+
1017
+
1018
+ resolve(new Function("useRef", `return \`${e.data}\``)(useRef))
1019
+
1020
+
1021
+
1022
+ }
1023
+ worker.onerror = (e)=>{
1024
+ reject(e)
1025
+ }
1026
+ })
1027
+ // @ts-ignore
1028
+ return promise;
1029
+ }else{
1030
+ let result = "";
1031
+ for (let i = 0; i < strings.length; i++) {
1032
+ result += strings[i];
1033
+ if (i < args.length) {
1034
+ result += args[i];
1035
+ }
1036
+ }
1037
+ result = new Function("useRef", `return \`${result}\``)(useRef)
1038
+
1039
+ if (!result.trim().startsWith("<body>")) {
1040
+ console.warn(
1041
+ "You should wrap your html in a body tag, vader may not grab all html!"
1042
+ );
1043
+ }
1044
+
1045
+
1046
+
1047
+ return this.parseHTML(result);
1048
+ }
1049
+
1050
+
1014
1051
  }
1015
1052
  // write types to ensure it returns a string
1016
1053
  /**
@@ -1087,12 +1124,90 @@ export const rf = (name, fn) => {
1087
1124
  window[name] = fn;
1088
1125
  };
1089
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
+ }
1090
1203
  /**
1091
1204
  * @function include
1092
1205
  * @description Allows you to include html file
1093
1206
  * @returns {Promise} - modified string with html content
1094
1207
  * @param {string} path
1095
1208
  */
1209
+
1210
+
1096
1211
 
1097
1212
  export const include = async (path) => {
1098
1213
 
@@ -1106,10 +1221,10 @@ export const include = async (path) => {
1106
1221
  path = "/src/" + path;
1107
1222
  }
1108
1223
  if (cache[path]) {
1109
- return new Function(`return \`${cache[path]}\`;`)();
1110
- }
1111
-
1112
- return fetch(`./${path}`)
1224
+ return await handletemplate(new Function(`return \`${cache[path]}\`;`)())
1225
+
1226
+ }else{
1227
+ return fetch(`./${path}`)
1113
1228
  .then((res) => {
1114
1229
  if (res.status === 404) {
1115
1230
  throw new Error(`No file found at ${path}`);
@@ -1117,39 +1232,14 @@ export const include = async (path) => {
1117
1232
  return res.text();
1118
1233
  })
1119
1234
  .then(async (data) => {
1120
- // Handle includes
1121
- let includes = data.match(/<include src="(.*)"\/>/g);
1122
- if (includes) {
1123
-
1124
- const includePromises = includes.map((e) => {
1125
-
1126
- // @ts-ignore
1127
- let includePath = e.match(/<include src="(.*)"\/>/)[1];
1128
-
1129
- if (
1130
- includePath.startsWith("/") &&
1131
- !document.documentElement.outerHTML
1132
- .trim()
1133
- .includes("<!-- #vader-disable_relative-paths -->")
1134
- ) {
1135
- includePath = "/src" + includePath;
1136
- }
1137
- return include(includePath).then((includeData) => {
1138
- data = data.replace(e, includeData);
1139
- });
1140
- });
1141
-
1142
- // Wait for all includes to be fetched and replaced
1143
- return Promise.all(includePromises).then(() => {
1144
- cache[path] = data;
1145
-
1146
- return data
1147
- });
1148
- } else {
1149
- cache[path] = data;
1150
- return data;
1151
- }
1235
+ cache[path] = data
1236
+
1237
+ data = await handletemplate(new Function(`return \`${data}\`;`)())
1238
+
1239
+ return data
1152
1240
  });
1241
+ }
1242
+
1153
1243
  };
1154
1244
 
1155
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
+