@yr-lang/yr 0.3.5 → 0.3.7

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/lib/%gh-pages.yr CHANGED
@@ -18,7 +18,9 @@ gh-pages() {
18
18
 
19
19
  git add .
20
20
  git commit -m "# DEPLOY"
21
+
21
22
  git push -f origin main
23
+ if [[ ! -d "$1" ]]; then exit 1; fi
22
24
 
23
25
  git branch -D gh-pages
24
26
  git checkout -b gh-pages
@@ -34,6 +36,8 @@ gh-pages() {
34
36
  git commit -m "# DEPLOY"
35
37
  git push -f origin gh-pages
36
38
  git checkout main
39
+
40
+ rm -rf "$1"
37
41
  }
38
42
 
39
43
  gh-pages_fix() {
package/lib/element.yr CHANGED
@@ -14,10 +14,6 @@ _@elementListener(#query, #parent=document, #listener='click') {
14
14
  });
15
15
  @}
16
16
 
17
- _@eqs(#name, #container, #query, #type='') {
18
- const #name = #container.querySelector(#query);
19
- @}
20
-
21
17
  @>
22
18
 
23
19
  function eventListener(element, action, callback) {
@@ -50,8 +46,9 @@ function createElement(options={}, listener=false) {
50
46
  if (options.selected) element.selected = options.selected;
51
47
 
52
48
  if (!options.attributes) options.attributes = {};
53
- for (let key of Object.keys(options.attributes)) {
54
- element.setAttribute(key, options.attributes[key]);
49
+ for (let key in options.attributes) {
50
+ if (key === 'value') element.value = options.attributes[key];
51
+ else element.setAttribute(key, options.attributes[key]);
55
52
  }
56
53
 
57
54
  if (!options.style) options.style = {};
@@ -61,8 +58,8 @@ function createElement(options={}, listener=false) {
61
58
 
62
59
  if (listener) eventListener(element,
63
60
  (options.selector === 'form') ? 'submit'
64
- : ((options.selector === 'input' || options.selector === 'select')
65
- ? 'change' : 'click'),
61
+ : ((options.selector === 'input' || options.selector === 'select'
62
+ || options.selector === 'textarea') ? 'change' : 'click'),
66
63
  listener
67
64
  );
68
65
 
package/node.js CHANGED
@@ -382,17 +382,11 @@ module.exports = {
382
382
  app[value] = [...new Set([...app[value], ...item.output[value]])];
383
383
  }
384
384
 
385
- let ext = item?.outputs?.devops;
386
- if (!ext) ext = [];
387
- if (!devops) devops = [];
388
- devops = [...ext, ...devops];
385
+ devops = [...item.output.devops, ...devops];
389
386
  result.macros = { ...item.output.macros, ...result.macros };
390
387
 
391
- let mods = item?.outputs?.modules;
392
- if (!mods) mods = [];
393
-
394
388
  result.modules = [...new Set([
395
- ...mods, ...result.modules
389
+ ...item.output.modules, ...result.modules
396
390
  ])];
397
391
 
398
392
  views.push(item);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yr-lang/yr",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Yr is a modern structural language and parser",
5
5
  "main": "./node.js",
6
6
  "exports": {
package/yr.js CHANGED
@@ -149,50 +149,185 @@ function getElementAttributes(line) {
149
149
  return { ...attributes, ...parse };
150
150
  }
151
151
 
152
+ function splitRespectingQuotes(line) {
153
+ const tokens = [];
154
+ let current = '';
155
+ let inQuote = false;
156
+ let quoteChar = '';
157
+ for (let i = 0; i < line.length; i++) {
158
+ const ch = line[i];
159
+ if (!inQuote && (ch === '"' || ch === "'")) {
160
+ inQuote = true;
161
+ quoteChar = ch;
162
+ current += ch;
163
+ } else if (inQuote && ch === quoteChar) {
164
+ inQuote = false;
165
+ quoteChar = '';
166
+ current += ch;
167
+ } else if (!inQuote && ch === ' ') {
168
+ if (current) tokens.push(current);
169
+ current = '';
170
+ } else {
171
+ current += ch;
172
+ }
173
+ }
174
+ if (current) tokens.push(current);
175
+ return tokens;
176
+ }
177
+
152
178
  function addIdToElement(line, config, elementId=false) {
153
179
  let tag = line.trim().split(' ')[0];
154
-
155
180
  if (tag.startsWith('_')) {
156
181
  tag = tag.replace(/^_/, '');
157
-
158
182
  if ((VOID_TAGS.has(tag) && !['input', 'img'].includes(tag))
159
183
  || ['title', 'script', 'style'].includes(tag)) return line;
160
184
  }
161
-
162
185
  if (config.preview && !line.includes('.__') && !line.includes('.{{__')) {
163
186
  if (!elementId) elementId = '__' + crypto.generateToken(8);
164
187
  if (!line.trim().startsWith('_')) elementId = '{{' + elementId;
165
-
166
- let openCase, newLine = '', addedClass;
167
- for (let item of line.split(' ')) {
168
- if (item.endsWith('{{')) {
169
- openCase = true;
170
- newLine += item + ' ';
171
- continue;
172
- }
173
-
174
- if (item.endsWith('}}') && openCase) {
175
- openCase = false;
176
- newLine += item + ' ';
188
+ let openCase, newLine = '', addedClass, attContent = '';
189
+ for (let item of splitRespectingQuotes(line)) {
190
+ if (!openCase) {
191
+ if (item.endsWith('{{')) {
192
+ openCase = '}}';
193
+ attContent += (attContent ? ', ' : '') + item.slice(item.indexOf('{{') + 2).trim();
194
+ continue;
195
+ }
196
+ } else if (openCase === '}}') {
197
+ if (item === '}}') {
198
+ openCase = null;
199
+ } else if (item.endsWith('}}')) {
200
+ attContent += ' ' + item.slice(0, -2).trim();
201
+ openCase = null;
202
+ } else {
203
+ attContent += ' ' + item;
204
+ }
177
205
  continue;
178
206
  }
179
-
180
207
  if (!openCase && item.startsWith('.') && !addedClass) {
181
208
  addedClass = true;
182
- item = item.replace(/\./, `.${elementId}.`);
209
+ item = item.replace(/^\./, `.${elementId}.`);
183
210
  }
184
-
185
211
  newLine += item + ' ';
186
212
  }
187
-
188
213
  newLine = newLine.trimEnd();
189
214
  if (!addedClass) newLine += ` .${elementId}`;
215
+ if (attContent) {
216
+ // Rebuild att={{ from parsed attributes: normalize to double-quoted strings,
217
+ // bare values for non-strings (e.g. redirect-success: / instead of '/')
218
+ const parsedAttrs = getElementAttributes(`_ att={{ ${attContent.trim()} }}`);
219
+ const rebuiltParts = Object.entries(parsedAttrs).map(([k, v]) => {
220
+ const needsQuotes = /[\s,{}]/.test(v);
221
+ return `${k}: ${needsQuotes ? `"${v}"` : v}`;
222
+ });
223
+ newLine += ` att={{ ${rebuiltParts.join(', ')} }}`;
224
+ }
190
225
  line = newLine;
191
226
  }
192
-
193
227
  return line;
194
228
  }
195
229
 
230
+ //function addIdToElement(line, config, elementId=false) {
231
+ // let tag = line.trim().split(' ')[0];
232
+ //
233
+ // if (tag.startsWith('_')) {
234
+ // tag = tag.replace(/^_/, '');
235
+ //
236
+ // if ((VOID_TAGS.has(tag) && !['input', 'img'].includes(tag))
237
+ // || ['title', 'script', 'style'].includes(tag)) return line;
238
+ // }
239
+ //
240
+ // if (config.preview && !line.includes('.__') && !line.includes('.{{__')) {
241
+ // if (!elementId) elementId = '__' + crypto.generateToken(8);
242
+ // if (!line.trim().startsWith('_')) elementId = '{{' + elementId;
243
+ //
244
+ // let openCase, newLine = '', addedClass, attContent = '';
245
+ // for (let item of line.split(' ')) {
246
+ // if (!openCase) {
247
+ // if (item.endsWith('{{')) {
248
+ // openCase = '}}';
249
+ // attContent += (attContent ? ', ' : '') + item.slice(item.indexOf('{{') + 2).trim();
250
+ // continue;
251
+ // } else if (item.includes('="') && !item.endsWith('"')) {
252
+ // openCase = '"';
253
+ // } else if (item.includes("='") && !item.endsWith("'")) {
254
+ // openCase = "'";
255
+ // }
256
+ // } else if (openCase === '}}') {
257
+ // if (item === '}}') {
258
+ // openCase = null;
259
+ // } else if (item.endsWith('}}')) {
260
+ // attContent += ' ' + item.slice(0, -2).trim();
261
+ // openCase = null;
262
+ // } else {
263
+ // attContent += ' ' + item;
264
+ // }
265
+ // continue;
266
+ // } else if (item.endsWith(openCase)) {
267
+ // openCase = null;
268
+ // } else if (!openCase && item.startsWith('.') && !addedClass) {
269
+ // addedClass = true;
270
+ // item = item.replace(/^\./, `.${elementId}.`);
271
+ // }
272
+ //
273
+ // newLine += item + ' ';
274
+ // }
275
+ //
276
+ // newLine = newLine.trimEnd();
277
+ // if (!addedClass) newLine += ` .${elementId}`;
278
+ // if (attContent) newLine += ` att={{ ${attContent} }}`;
279
+ // line = newLine;
280
+ // }
281
+ //
282
+ // return line;
283
+ //}
284
+
285
+ //function addIdToElement(line, config, elementId=false) {
286
+ // let tag = line.trim().split(' ')[0];
287
+ //
288
+ // if (tag.startsWith('_')) {
289
+ // tag = tag.replace(/^_/, '');
290
+ //
291
+ // if ((VOID_TAGS.has(tag) && !['input', 'img'].includes(tag))
292
+ // || ['title', 'script', 'style'].includes(tag)) return line;
293
+ // }
294
+ //
295
+ // if (config.preview && !line.includes('.__') && !line.includes('.{{__')) {
296
+ // if (!elementId) elementId = '__' + crypto.generateToken(8);
297
+ // if (!line.trim().startsWith('_')) elementId = '{{' + elementId;
298
+ //
299
+ // let openCase, newLine = '', addedClass;
300
+ // for (let item of line.split(' ')) {
301
+ // if (!openCase) {
302
+ // if (item.endsWith('{{')) {
303
+ // openCase = '}}';
304
+ // } else if (item.includes('="') && !item.endsWith('"')) {
305
+ // openCase = '"';
306
+ // } else if (item.includes("='") && !item.endsWith("'")) {
307
+ // openCase = "'";
308
+ // }
309
+ // } else if (item.endsWith(openCase)) {
310
+ // openCase = null;
311
+ // newLine += item + ' ';
312
+ // continue;
313
+ // }
314
+ //
315
+ // if (!openCase && item.startsWith('.') && !addedClass) {
316
+ // addedClass = true;
317
+ // item = item.replace(/^\./, `.${elementId}.`);
318
+ // }
319
+ //
320
+ // newLine += item + ' ';
321
+ // }
322
+ //
323
+ // newLine = newLine.trimEnd();
324
+ // if (!addedClass) newLine += ` .${elementId}`;
325
+ // line = newLine;
326
+ // }
327
+ //
328
+ // return line;
329
+ //}
330
+
196
331
  const VOID_TAGS = new Set([
197
332
  'area','base','br','col','embed','hr','img','input',
198
333
  'link','meta','param','source','track','wbr'
@@ -322,10 +457,12 @@ const parserFns = {
322
457
  }
323
458
  if (parsedLine.line[0] === '_') {
324
459
  const elementAttributes = getElementAttributes(parsedLine.line);
325
- const attSplit = parsedLine.line.split(' att={{');
326
- if (attSplit.length > 1)
460
+ let attSplit = parsedLine.line.split(' att={{');
461
+ while (attSplit.length > 1) {
327
462
  parsedLine.line = attSplit[0] + attSplit[1].split('}}')[1];
328
- const lineSplit = parsedLine.line.split(' ');
463
+ attSplit = parsedLine.line.split(' att={{');
464
+ }
465
+ const lineSplit = splitRespectingQuotes(parsedLine.line);
329
466
  let tag = lineSplit.shift().substring(1);
330
467
  if (tag === '') tag = 'div';
331
468
  if (tag[0] === '_') {
@@ -406,7 +543,9 @@ const parserFns = {
406
543
  for (let value of sections.wrappers[wrapperName]
407
544
  .yrwrapperbody.split('\n')) {
408
545
  if (value.trim() === '') continue;
409
- value = addIdToElement(value, config);
546
+ const valueIndent = value.search(/\S/);
547
+ const valueWhiteSpace = value.slice(0, valueIndent);
548
+ value = valueWhiteSpace + addIdToElement(value.trim(), config);
410
549
  if (yrIndentation % 2 !== 0) yrIndentation -= 1;
411
550
  if (newWrapper.reference % 2 !== 0) newWrapper.reference -= 1;
412
551
  if (newWrapper.new % 2 !== 0) newWrapper.new -= 1;
@@ -724,18 +863,6 @@ const core = {
724
863
  }
725
864
  },
726
865
  parse(code, config={}) {
727
- if (!isYrSyntax(code)) {
728
- const sections = { parsedhtml: code };
729
-
730
- if (config.name) sections.ui = [{
731
- name: (config.name.includes('.html'))
732
- ? config.name : `${config.name}.html`,
733
- content: sections.parsedhtml
734
- }];
735
-
736
- return sections;
737
- }
738
-
739
866
  if (config.opposite) {
740
867
  const file = code;
741
868
  const isProject = config.isProject;
@@ -1047,6 +1174,18 @@ const core = {
1047
1174
  return yrResult;
1048
1175
  }
1049
1176
 
1177
+ if (!isYrSyntax(code)) {
1178
+ const sections = { parsedhtml: code };
1179
+
1180
+ if (config.name) sections.ui = [{
1181
+ name: (config.name.includes('.html'))
1182
+ ? config.name : `${config.name}.html`,
1183
+ content: sections.parsedhtml
1184
+ }];
1185
+
1186
+ return sections;
1187
+ }
1188
+
1050
1189
  const sections = (config.sections) ? config.sections : parsers.defaults();
1051
1190
 
1052
1191
  const state = {
@@ -1,9 +0,0 @@
1
- @@
2
-
3
- function windowListener(callback) {
4
- if (typeof window.addEventListener != 'undefined') {
5
- window.addEventListener('message', callback);
6
- } else if (typeof window.attachEvent != 'undefined') {
7
- window.attachEvent('onmessage', callback);
8
- }
9
- }