Skip to content

Commit

Permalink
Merge branch 'next' into validatepartial
Browse files Browse the repository at this point in the history
  • Loading branch information
ryansolid authored Sep 23, 2024
2 parents 4961085 + 3fbad1f commit 7cb55e0
Show file tree
Hide file tree
Showing 32 changed files with 6,016 additions and 4,122 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"packages": [
"packages/*"
],
"version": "0.38.5"
"version": "0.38.6"
}
91 changes: 83 additions & 8 deletions packages/babel-plugin-jsx-dom-expressions/src/dom/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ export function transformElement(path, info) {
config = getConfig(path),
wrapSVG = info.topLevel && tagName != "svg" && SVGElements.has(tagName),
voidTag = VoidElements.indexOf(tagName) > -1,
isCustomElement = tagName.indexOf("-") > -1 || !!path.get("openingElement").get("attributes").find(a => a.node.name?.name === "is"),
isCustomElement = tagName.indexOf("-") > -1 || path.get("openingElement").get("attributes").some(a => a.node?.name?.name === "is" || a.name?.name === "is"),
isImportNode = (tagName === 'img'||tagName === 'iframe') && path.get("openingElement").get("attributes").some(a => a.node.name?.name === "loading" && a.node.value?.value === "lazy"
),
results = {
template: `<${tagName}`,
templateWithClosingTags: `<${tagName}`,
Expand All @@ -71,6 +73,7 @@ export function transformElement(path, info) {
postExprs: [],
isSVG: wrapSVG,
hasCustomElement: isCustomElement,
isImportNode,
tagName,
renderer: "dom",
skipTemplate: false
Expand Down Expand Up @@ -225,6 +228,13 @@ export function setAttr(path, elem, name, value, { isSVG, dynamic, prevId, isCE,
return t.assignmentExpression("=", t.memberExpression(elem, t.identifier("data")), value);
}

if(namespace === 'bool') {
return t.callExpression(
registerImportMethod(path, "setBoolAttribute", getRendererConfig(path, "dom").moduleName),
[elem, t.stringLiteral(name), value]
);
}

const isChildProp = ChildProperties.has(name);
const isProp = Properties.has(name);
const alias = getPropAlias(name, tagName.toUpperCase());
Expand Down Expand Up @@ -279,7 +289,7 @@ function transformAttributes(path, results) {
attributes = path.get("openingElement").get("attributes");
const tagName = getTagName(path.node),
isSVG = SVGElements.has(tagName),
isCE = tagName.includes("-"),
isCE = tagName.includes("-") || attributes.some(a => a.node.name?.name === 'is'),
hasChildren = path.node.children.length > 0,
config = getConfig(path);

Expand Down Expand Up @@ -551,15 +561,29 @@ function transformAttributes(path, results) {
children = value;
} else if (key.startsWith("on")) {
const ev = toEventName(key);
if (key.startsWith("on:") || key.startsWith("oncapture:")) {
const listenerOptions = [t.stringLiteral(key.split(":")[1]), value.expression];
if (key.startsWith("on:")) {
const args = [elem, t.stringLiteral(key.split(":")[1]), value.expression];

results.exprs.unshift(
t.expressionStatement(
t.callExpression(
registerImportMethod(
path,
"addEventListener",
getRendererConfig(path, "dom").moduleName,
),
args,
),
),
);
} else if (key.startsWith("oncapture:")) {
// deprecated see above condition
const args = [t.stringLiteral(key.split(":")[1]), value.expression, t.booleanLiteral(true)];
results.exprs.push(
t.expressionStatement(
t.callExpression(
t.memberExpression(elem, t.identifier("addEventListener")),
key.startsWith("oncapture:")
? listenerOptions.concat(t.booleanLiteral(true))
: listenerOptions
args
)
)
);
Expand Down Expand Up @@ -706,6 +730,54 @@ function transformAttributes(path, results) {
isCE,
tagName
});
} else if(key.slice(0, 5) === 'bool:'){

// inline it on the template when possible
let content = value;

if (t.isJSXExpressionContainer(content)) content = content.expression;

function addBoolAttribute() {
results.template += `${needsSpacing ? " " : ""}${key.slice(5)}`;
needsSpacing = true;
}

switch (content.type) {
case "StringLiteral": {
if (content.value.length && content.value !== "0") {
addBoolAttribute();
}
return;
}
case "NullLiteral": {
return;
}
case "BooleanLiteral": {
if (content.value) {
addBoolAttribute();
}
return;
}
case "Identifier": {
if (content.name === "undefined") {
return;
}
break;
}
}

// when not possible to inline it in the template
results.exprs.push(
t.expressionStatement(
setAttr(
attribute,
elem,
key,
t.isJSXExpressionContainer(value) ? value.expression : value,
{ isSVG, isCE, tagName },
),
),
);
} else {
results.exprs.push(
t.expressionStatement(
Expand Down Expand Up @@ -845,6 +917,8 @@ function transformChildren(path, results, config) {

results.template += child.template;
results.templateWithClosingTags += child.templateWithClosingTags || child.template ;
results.isImportNode = results.isImportNode || child.isImportNode;

if (child.id) {
if (child.tagName === "head") {
if (config.hydratable) {
Expand Down Expand Up @@ -893,6 +967,7 @@ function transformChildren(path, results, config) {
childPostExprs.push(...child.postExprs);
results.hasHydratableEvent = results.hasHydratableEvent || child.hasHydratableEvent;
results.hasCustomElement = results.hasCustomElement || child.hasCustomElement;
results.isImportNode = results.isImportNode || child.isImportNode;
tempPath = child.id.name;
nextPlaceholder = null;
i++;
Expand Down Expand Up @@ -996,7 +1071,7 @@ function detectExpressions(children, index, config) {
} else if (t.isJSXElement(child)) {
const tagName = getTagName(child);
if (isComponent(tagName)) return true;
if (config.contextToCustomElements && (tagName === "slot" || tagName.indexOf("-") > -1))
if (config.contextToCustomElements && (tagName === "slot" || tagName.indexOf("-") > -1 || child.openingElement.attributes.some(a => a.name?.name === 'is')))
return true;
if (
child.openingElement.attributes.some(
Expand Down
8 changes: 6 additions & 2 deletions packages/babel-plugin-jsx-dom-expressions/src/dom/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ export function appendTemplates(path, templates) {
cooked: template.template,
raw: escapeStringForTemplate(template.template)
};

const shouldUseImportNode = template.isCE || template.isImportNode

return t.variableDeclarator(
template.id,
t.addComment(
t.callExpression(
registerImportMethod(path, "template", getRendererConfig(path, "dom").moduleName),
[t.templateLiteral([t.templateElement(tmpl, true)], [])].concat(
template.isSVG || template.isCE
? [t.booleanLiteral(template.isCE), t.booleanLiteral(template.isSVG)]
template.isSVG || shouldUseImportNode
? [t.booleanLiteral(!!shouldUseImportNode), t.booleanLiteral(template.isSVG)]
: []
)
),
Expand Down Expand Up @@ -78,6 +81,7 @@ function registerTemplate(path, results) {
templateWithClosingTags: results.templateWithClosingTags,
isSVG: results.isSVG,
isCE: results.hasCustomElement,
isImportNode: results.isImportNode,
renderer: "dom"
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const JSXValidator = {
JSXElement(path) {
const elName = path.node.openingElement.name;
const parent = path.parent;

if (!t.isJSXElement(parent) || !t.isJSXIdentifier(elName)) return;
const elTagName = elName.name;
if (isComponent(elTagName)) return;
Expand Down
5 changes: 3 additions & 2 deletions packages/babel-plugin-jsx-dom-expressions/src/shared/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const reservedNameSpaces = new Set([
"style",
"use",
"prop",
"attr"
"attr",
"bool"
]);

export const nonSpreadNameSpaces = new Set(["class", "style", "use", "prop", "attr"]);
export const nonSpreadNameSpaces = new Set(["class", "style", "use", "prop", "attr", "bool"]);

export function getConfig(path) {
return path.hub.file.metadata.config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,43 @@ const template41 = (
<option value={Color.Blue}>Blue</option>
</select>
);

// bool:
function boolTest(){return true}
const boolTestBinding = false
const boolTestObjBinding = {value:false}

const template42 = <div bool:quack="">empty string</div>;
const template43 = <div bool:quack={""}>js empty</div>;
const template44 = <div bool:quack="hola">hola</div>;
const template45 = <div bool:quack={"hola js"}>"hola js"</div>;
const template46 = <div bool:quack={true}>true</div>;
const template47 = <div bool:quack={false}>false</div>;
const template48 = <div bool:quack={1}>1</div>;
const template49 = <div bool:quack={0}>0</div>;
const template50 = <div bool:quack={"1"}>"1"</div>;
const template51 = <div bool:quack={"0"}>"0"</div>;
const template52 = <div bool:quack={undefined}>undefined</div>;
const template53 = <div bool:quack={null}>null</div>;
const template54 = <div bool:quack={boolTest()}>boolTest()</div>;
const template55 = <div bool:quack={boolTest}>boolTest</div>;
const template56 = <div bool:quack={boolTestBinding}>boolTestBinding</div>;
const template57 = <div bool:quack={boolTestObjBinding.value}>boolTestObjBinding.value</div>;
const template58 = <div bool:quack={()=>false}>fn</div>;

const template59 = <div before bool:quack="true">should have space before</div>;
const template60 = <div before bool:quack="true" after>should have space before/after</div>;
const template61 = <div bool:quack="true" after>should have space before/after</div>;
// this crash it for some reason- */ const template62 = <div bool:quack>really empty</div>;

const template63 = <img src="" />;
const template64 = <div><img src=""/></div>;

const template65 = <img src="" loading="lazy"/>;
const template66 = <div><img src="" loading="lazy"/></div>;

const template67 = <iframe src=""></iframe>;
const template68 = <div><iframe src=""></iframe></div>;

const template69 = <iframe src="" loading="lazy"></iframe>;
const template70 = <div><iframe src="" loading="lazy"></iframe></div>;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { template as _$template } from "r-dom";
import { delegateEvents as _$delegateEvents } from "r-dom";
import { setBoolAttribute as _$setBoolAttribute } from "r-dom";
import { insert as _$insert } from "r-dom";
import { memo as _$memo } from "r-dom";
import { addEventListener as _$addEventListener } from "r-dom";
Expand Down Expand Up @@ -32,7 +33,35 @@ var _tmpl$ = /*#__PURE__*/ _$template(`<div id=main><h1 class=base id=my-h1><a h
),
_tmpl$18 = /*#__PURE__*/ _$template(`<button>`),
_tmpl$19 = /*#__PURE__*/ _$template(`<input value=10>`),
_tmpl$20 = /*#__PURE__*/ _$template(`<select><option>Red</option><option>Blue`);
_tmpl$20 = /*#__PURE__*/ _$template(`<select><option>Red</option><option>Blue`),
_tmpl$21 = /*#__PURE__*/ _$template(`<div>empty string`),
_tmpl$22 = /*#__PURE__*/ _$template(`<div>js empty`),
_tmpl$23 = /*#__PURE__*/ _$template(`<div quack>hola`),
_tmpl$24 = /*#__PURE__*/ _$template(`<div quack>"hola js"`),
_tmpl$25 = /*#__PURE__*/ _$template(`<div quack>true`),
_tmpl$26 = /*#__PURE__*/ _$template(`<div>false`),
_tmpl$27 = /*#__PURE__*/ _$template(`<div quack>1`),
_tmpl$28 = /*#__PURE__*/ _$template(`<div>0`),
_tmpl$29 = /*#__PURE__*/ _$template(`<div quack>"1"`),
_tmpl$30 = /*#__PURE__*/ _$template(`<div>"0"`),
_tmpl$31 = /*#__PURE__*/ _$template(`<div>undefined`),
_tmpl$32 = /*#__PURE__*/ _$template(`<div>null`),
_tmpl$33 = /*#__PURE__*/ _$template(`<div>boolTest()`),
_tmpl$34 = /*#__PURE__*/ _$template(`<div>boolTest`),
_tmpl$35 = /*#__PURE__*/ _$template(`<div>boolTestBinding`),
_tmpl$36 = /*#__PURE__*/ _$template(`<div>boolTestObjBinding.value`),
_tmpl$37 = /*#__PURE__*/ _$template(`<div>fn`),
_tmpl$38 = /*#__PURE__*/ _$template(`<div before quack>should have space before`),
_tmpl$39 = /*#__PURE__*/ _$template(`<div before quack after>should have space before/after`),
_tmpl$40 = /*#__PURE__*/ _$template(`<div quack after>should have space before/after`),
_tmpl$41 = /*#__PURE__*/ _$template(`<img src="">`),
_tmpl$42 = /*#__PURE__*/ _$template(`<div><img src="">`),
_tmpl$43 = /*#__PURE__*/ _$template(`<img src=""loading=lazy>`, true, false),
_tmpl$44 = /*#__PURE__*/ _$template(`<div><img src=""loading=lazy>`, true, false),
_tmpl$45 = /*#__PURE__*/ _$template(`<iframe src="">`),
_tmpl$46 = /*#__PURE__*/ _$template(`<div><iframe src="">`),
_tmpl$47 = /*#__PURE__*/ _$template(`<iframe src=""loading=lazy>`, true, false),
_tmpl$48 = /*#__PURE__*/ _$template(`<div><iframe src=""loading=lazy>`, true, false);
import * as styles from "./styles.module.css";
const selected = true;
let id = "my-h1";
Expand Down Expand Up @@ -426,4 +455,63 @@ const template41 = (() => {
_$effect(() => (_el$57.value = state.color));
return _el$57;
})();

// bool:
function boolTest() {
return true;
}
const boolTestBinding = false;
const boolTestObjBinding = {
value: false
};
const template42 = _tmpl$21();
const template43 = _tmpl$22();
const template44 = _tmpl$23();
const template45 = _tmpl$24();
const template46 = _tmpl$25();
const template47 = _tmpl$26();
const template48 = _tmpl$27();
const template49 = _tmpl$28();
const template50 = _tmpl$29();
const template51 = _tmpl$30();
const template52 = _tmpl$31();
const template53 = _tmpl$32();
const template54 = (() => {
var _el$72 = _tmpl$33();
_$effect(() => _$setBoolAttribute(_el$72, "quack", boolTest()));
return _el$72;
})();
const template55 = (() => {
var _el$73 = _tmpl$34();
_$setBoolAttribute(_el$73, "quack", boolTest);
return _el$73;
})();
const template56 = (() => {
var _el$74 = _tmpl$35();
_$setBoolAttribute(_el$74, "quack", boolTestBinding);
return _el$74;
})();
const template57 = (() => {
var _el$75 = _tmpl$36();
_$effect(() => _$setBoolAttribute(_el$75, "quack", boolTestObjBinding.value));
return _el$75;
})();
const template58 = (() => {
var _el$76 = _tmpl$37();
_$setBoolAttribute(_el$76, "quack", () => false);
return _el$76;
})();
const template59 = _tmpl$38();
const template60 = _tmpl$39();
const template61 = _tmpl$40();
// this crash it for some reason- */ const template62 = <div bool:quack>really empty</div>;

const template63 = _tmpl$41();
const template64 = _tmpl$42();
const template65 = _tmpl$43();
const template66 = _tmpl$44();
const template67 = _tmpl$45();
const template68 = _tmpl$46();
const template69 = _tmpl$47();
const template70 = _tmpl$48();
_$delegateEvents(["click", "input"]);
Loading

0 comments on commit 7cb55e0

Please sign in to comment.