@motifx/compiler 1.2.0-rc.4 → 1.2.0-rc.5

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/dist/index.esm.js CHANGED
@@ -509,11 +509,64 @@ const makeHtmlAttr = (prop, name, value, path) => {
509
509
  }
510
510
  return null;
511
511
  };
512
+ function classKeyOf(p) {
513
+ if (p.computed)
514
+ return p.key;
515
+ if (t.isIdentifier(p.key))
516
+ return t.stringLiteral(p.key.name);
517
+ if (t.isStringLiteral(p.key))
518
+ return t.stringLiteral(p.key.value);
519
+ if (t.isNumericLiteral(p.key))
520
+ return t.stringLiteral(String(p.key.value));
521
+ return null;
522
+ }
523
+ function literalTruthOf(val) {
524
+ if (t.isBooleanLiteral(val))
525
+ return val.value;
526
+ if (t.isStringLiteral(val))
527
+ return val.value !== '';
528
+ if (t.isNumericLiteral(val))
529
+ return val.value !== 0 && !Number.isNaN(val.value);
530
+ if (t.isNullLiteral(val))
531
+ return false;
532
+ if (t.isIdentifier(val) && val.name === 'undefined')
533
+ return false;
534
+ if (t.isTemplateLiteral(val) && val.expressions.length === 0)
535
+ return val.quasis.some(q => (q.value.cooked ?? q.value.raw) !== '');
536
+ return undefined;
537
+ }
538
+ function splitClassObject(obj, staticNames, live) {
539
+ const props = [];
540
+ obj.properties.forEach(p => {
541
+ if (!t.isObjectProperty(p)) {
542
+ props.push(p);
543
+ return;
544
+ }
545
+ const key = classKeyOf(p);
546
+ if (key === null || !t.isExpression(p.value))
547
+ return;
548
+ const truth = literalTruthOf(p.value);
549
+ if (truth === false)
550
+ return;
551
+ if (truth === true) {
552
+ if (t.isStringLiteral(key))
553
+ staticNames.push(key);
554
+ else
555
+ props.push(t.objectProperty(key, t.booleanLiteral(true), true));
556
+ return;
557
+ }
558
+ const getter = t.isFunctionExpression(p.value) || t.isArrowFunctionExpression(p.value)
559
+ ? p.value
560
+ : t.arrowFunctionExpression([], p.value);
561
+ props.push(t.objectProperty(key, getter, p.computed));
562
+ });
563
+ if (props.length > 0)
564
+ live.push(t.objectExpression(props));
565
+ }
512
566
  const mergeHtmlAttributes = (htmlAttrlist) => {
513
567
  const htmlProps = [];
514
568
  if (htmlAttrlist.length > 0) {
515
569
  var totalAttr = [];
516
- var totalClass = [];
517
570
  var totalBindClass = [];
518
571
  var totalStringClass = [];
519
572
  htmlAttrlist.forEach(attr => {
@@ -523,38 +576,7 @@ const mergeHtmlAttributes = (htmlAttrlist) => {
523
576
  : attr.key.quasis.map(q => q.value.raw).join("").toLowerCase();
524
577
  if (keyValue === "class" || keyValue === "classname") {
525
578
  if (t.isObjectExpression(attr.value)) {
526
- const objectProperties = [];
527
- attr.value.properties.forEach(p => {
528
- if (t.isObjectProperty(p)) {
529
- const val = p.value;
530
- if (t.isStringLiteral(val)) {
531
- totalStringClass.push(p.key);
532
- }
533
- else if (t.isBooleanLiteral(val)) {
534
- totalStringClass.push(p.key);
535
- }
536
- else if (t.isFunctionExpression(val) || t.isArrowFunctionExpression(val)) {
537
- objectProperties.push(p);
538
- }
539
- else if (t.isTemplateLiteral(val)) {
540
- if (val.expressions.length === 0) {
541
- totalStringClass.push(t.stringLiteral(val.quasis.map(q => q.value.raw).join("")));
542
- }
543
- else {
544
- totalBindClass.push(t.arrowFunctionExpression([], val));
545
- }
546
- }
547
- else {
548
- totalClass.push(p);
549
- }
550
- }
551
- else if (t.isFunctionExpression(p) || t.isArrowFunctionExpression(p)) {
552
- totalBindClass.push(p);
553
- }
554
- });
555
- if (objectProperties.length > 0) {
556
- totalBindClass.push(t.objectExpression(objectProperties));
557
- }
579
+ splitClassObject(attr.value, totalStringClass, totalBindClass);
558
580
  }
559
581
  else if (t.isMemberExpression(attr.value) || t.isCallExpression(attr.value)) {
560
582
  totalBindClass.push(attr.value);
@@ -581,34 +603,7 @@ const mergeHtmlAttributes = (htmlAttrlist) => {
581
603
  if (!element)
582
604
  return;
583
605
  if (t.isObjectExpression(element)) {
584
- element.properties.forEach(p => {
585
- if (t.isObjectProperty(p)) {
586
- const val = p.value;
587
- if (t.isStringLiteral(val)) {
588
- totalStringClass.push(p.key);
589
- }
590
- else if (t.isBooleanLiteral(val)) {
591
- totalStringClass.push(p.key);
592
- }
593
- else if (t.isFunctionExpression(val) || t.isArrowFunctionExpression(val)) {
594
- totalBindClass.push(val);
595
- }
596
- else if (t.isTemplateLiteral(val)) {
597
- if (val.expressions.length === 0) {
598
- totalStringClass.push(t.stringLiteral(val.quasis.map(q => q.value.raw).join("")));
599
- }
600
- else {
601
- totalBindClass.push(t.arrowFunctionExpression([], val));
602
- }
603
- }
604
- else {
605
- totalClass.push(p);
606
- }
607
- }
608
- else if (t.isFunctionExpression(p) || t.isArrowFunctionExpression(p)) {
609
- totalBindClass.push(p);
610
- }
611
- });
606
+ splitClassObject(element, totalStringClass, totalBindClass);
612
607
  }
613
608
  else if (t.isStringLiteral(element)) {
614
609
  totalStringClass.push(element);
@@ -697,9 +692,6 @@ const mergeHtmlAttributes = (htmlAttrlist) => {
697
692
  if (totalBindClass.length > 0) {
698
693
  htmlProps.push(t.expressionStatement(t.callExpression(t.identifier('sender.class.add'), [t.arrayExpression(totalBindClass)])));
699
694
  }
700
- if (totalClass.length > 0) {
701
- htmlProps.push(t.expressionStatement(t.callExpression(t.identifier('sender.class.add'), [t.objectExpression(totalClass)])));
702
- }
703
695
  if (totalStringClass.length > 0) {
704
696
  htmlProps.push(t.expressionStatement(t.callExpression(t.identifier('sender.class.add'), [...totalStringClass])));
705
697
  }
@@ -1397,6 +1389,19 @@ function lifecycleHookOf(name) {
1397
1389
  hook = lower.slice(2);
1398
1390
  return hook !== null && LIFECYCLE_HOOKS.has(hook) ? hook : null;
1399
1391
  }
1392
+ const HOOK_KEYS = {
1393
+ built: 'onBuilt', building: 'onBuilding', mounted: 'onMounted', config: 'onConfig', configured: 'onConfigured',
1394
+ initializing: 'onInitializing', initialized: 'onInitialized', disposing: 'onDisposing', disposed: 'onDisposed',
1395
+ visibilitychanged: 'onVisibilityChanged', activated: 'onActivated', deactivated: 'onDeactivated',
1396
+ };
1397
+ function hookKey(name) {
1398
+ const hook = lifecycleHookOf(name);
1399
+ if (hook !== null)
1400
+ return HOOK_KEYS[hook];
1401
+ if (name.toLowerCase() === 'oninitializecomponent')
1402
+ return 'oninitializeComponent';
1403
+ return name;
1404
+ }
1400
1405
  /** `.some/.every/.find/...` gibi KISA DEVRE yapan dizi yüklemleri (MJX004). */
1401
1406
  const SHORT_CIRCUIT_ARRAY_METHODS = new Set(['some', 'every', 'find', 'findindex', 'findlast', 'findlastindex']);
1402
1407
  /** Bir üye zincirinin kökü `this` mi? (`this.state.rows.some(...)` → evet) */
@@ -1706,14 +1711,14 @@ const getProps = (props, path, state) => {
1706
1711
  if (value != null) {
1707
1712
  var ce = makeComponentTraps(prop, name, value);
1708
1713
  if (ce !== null) {
1714
+ ce.key = id(hookKey(name));
1709
1715
  componentEvents.push(ce);
1710
1716
  explainProp(prop, 'component-event', 'lifecycle', ce, 'n/a', DEPS.none, 'lifecycle hook; called once during component setup/build/dispose');
1711
1717
  }
1712
1718
  }
1713
1719
  }
1714
1720
  else if (!plainTag && mergedHook !== null && value != null && t.isExpression(value)) {
1715
- const key = name.toLowerCase().startsWith('on') ? name : 'on' + mergedHook;
1716
- const lifecycleProp = t.objectProperty(t.isValidIdentifier(key) ? id(key) : t.stringLiteral(key), value);
1721
+ const lifecycleProp = t.objectProperty(id(HOOK_KEYS[mergedHook]), value);
1717
1722
  componentEvents.push(lifecycleProp);
1718
1723
  explainProp(prop, 'component-event', 'lifecycle', lifecycleProp, 'n/a', DEPS.none, 'lifecycle hook; on a component tag it is applied via runover to the tag\'s component (the returned root for a function component)');
1719
1724
  }
@@ -1846,7 +1851,7 @@ const getProps = (props, path, state) => {
1846
1851
  warn('MJX007', `Unknown directive "${name}": it is passed on as the prop "on${clearedName}". Supported: ${supportedDirectivesText()}.`, prop, fileName);
1847
1852
  }
1848
1853
  if (t.isExpression(value)) {
1849
- objectExpression.push(t.objectProperty(id("on" + clearedName), value));
1854
+ objectExpression.push(t.objectProperty(id(hookKey("on" + clearedName)), value));
1850
1855
  }
1851
1856
  else {
1852
1857
  objectProps.push(value);
@@ -1899,10 +1904,17 @@ const getProps = (props, path, state) => {
1899
1904
  if (atr !== null) {
1900
1905
  htmlAttrlist.push(atr);
1901
1906
  const lname = name.toLowerCase();
1902
- const c = classifyAttrValue(prop, value, atr);
1903
- const call = lname === 'class' || lname === 'classname' ? 'sender.class.add' : lname === 'style' ? 'sender.style' : 'sender.attr.add';
1904
- const shown = call === 'sender.attr.add' ? `${call}({ "${name}": ${codeOf(atr.value)} })` : `${call}(${codeOf(atr.value)})`;
1905
- explainProp(prop, 'attr', c.shape, shown, c.reactive, c.deps, c.note);
1907
+ if ((lname === 'class' || lname === 'classname') && (t.isObjectExpression(atr.value) || t.isArrayExpression(atr.value))) {
1908
+ const lowered = mergeHtmlAttributes([atr]);
1909
+ const live = lowered.some(s => t.isCallExpression(s.expression) && t.isArrayExpression(s.expression.arguments[0]));
1910
+ explainProp(prop, 'attr', 'class.object', lowered.map(s => codeOf(s.expression)).join('; '), live ? 'live' : 'static', live ? DEPS.getter : DEPS.none, live ? 'each key toggles its class; values other than literals are wrapped in getters' : undefined);
1911
+ }
1912
+ else {
1913
+ const c = classifyAttrValue(prop, value, atr);
1914
+ const call = lname === 'class' || lname === 'classname' ? 'sender.class.add' : lname === 'style' ? 'sender.style' : 'sender.attr.add';
1915
+ const shown = call === 'sender.attr.add' ? `${call}({ "${name}": ${codeOf(atr.value)} })` : `${call}(${codeOf(atr.value)})`;
1916
+ explainProp(prop, 'attr', c.shape, shown, c.reactive, c.deps, c.note);
1917
+ }
1906
1918
  }
1907
1919
  }
1908
1920
  else {
@@ -1932,7 +1944,7 @@ const getProps = (props, path, state) => {
1932
1944
  objectExpression.push(t.objectProperty(t.stringLiteral(name), value));
1933
1945
  }
1934
1946
  else {
1935
- objectExpression.push(t.objectProperty(id(name), value));
1947
+ objectExpression.push(t.objectProperty(id(hookKey(name)), value));
1936
1948
  }
1937
1949
  {
1938
1950
  const c = classifyPropValue(prop, value);
@@ -1961,7 +1973,7 @@ const getProps = (props, path, state) => {
1961
1973
  mergedHooks.forEach((entries, hook) => {
1962
1974
  if (entries.length === 0)
1963
1975
  return;
1964
- const merged = t.objectProperty(id('on' + hook), t.arrayExpression(entries.map(e => e.value)));
1976
+ const merged = t.objectProperty(id(HOOK_KEYS[hook]), t.arrayExpression(entries.map(e => e.value)));
1965
1977
  componentEvents.push(merged);
1966
1978
  entries.forEach(e => explainProp(e.prop, 'component-event', 'lifecycle', merged, 'n/a', DEPS.none, 'all spellings of the same hook on this tag are merged into one list; each is called once, in source order'));
1967
1979
  });