mirror of
https://github.com/marko-js/marko.git
synced 2026-02-01 16:07:13 +00:00
feat: support exclusive discovered tags folder as interop heuristic
This commit is contained in:
parent
a228ddc526
commit
d2f437bf71
6
.changeset/frank-lights-know.md
Normal file
6
.changeset/frank-lights-know.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"marko": patch
|
||||
"@marko/runtime-tags": patch
|
||||
---
|
||||
|
||||
Add style block as tag api interop heuristic.
|
||||
7
.changeset/quick-fans-cross.md
Normal file
7
.changeset/quick-fans-cross.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"marko": patch
|
||||
"@marko/runtime-tags": patch
|
||||
"@marko/compiler": patch
|
||||
---
|
||||
|
||||
Add support for "use class" comment to opt into to class api when exclusive `tags` folders prefer tags api.
|
||||
7
.changeset/tough-memes-camp.md
Normal file
7
.changeset/tough-memes-camp.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"marko": patch
|
||||
"@marko/runtime-tags": patch
|
||||
"@marko/compiler": patch
|
||||
---
|
||||
|
||||
Add exclusive `tags` folder discovery as a "prefer tags api" heuristic in interop mode.
|
||||
3
packages/compiler/babel-utils.d.ts
vendored
3
packages/compiler/babel-utils.d.ts
vendored
@ -75,7 +75,6 @@ export interface TagDefinition {
|
||||
}
|
||||
|
||||
export interface TaglibLookup {
|
||||
manualTagsDirs: Set<string>;
|
||||
getTagsSorted(): TagDefinition[];
|
||||
getTag(tagName: string): undefined | TagDefinition;
|
||||
getAttribute(
|
||||
@ -86,6 +85,8 @@ export interface TaglibLookup {
|
||||
tagName: string,
|
||||
callback: (attr: AttributeDefinition, tag: TagDefinition) => void,
|
||||
): void;
|
||||
exclusiveTagDiscoveryDirs: undefined | false | string;
|
||||
manualTagsDirs: undefined | Set<string>;
|
||||
}
|
||||
|
||||
export interface Attribute {
|
||||
|
||||
@ -51,27 +51,13 @@ function getAllDependencyNames(pkg) {
|
||||
}
|
||||
|
||||
function find(dirname, registeredTaglibs, tagDiscoveryDirs) {
|
||||
var found = findCache[dirname];
|
||||
if (found) {
|
||||
return found;
|
||||
var cached = findCache[dirname];
|
||||
if (cached) {
|
||||
return cached.taglibs;
|
||||
}
|
||||
|
||||
found = [];
|
||||
|
||||
var added = {};
|
||||
|
||||
var helper = {
|
||||
addTaglib: function (taglib) {
|
||||
if (added[taglib.id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
added[taglib.id] = true;
|
||||
found.push(taglib);
|
||||
},
|
||||
foundTaglibPackages: {},
|
||||
};
|
||||
|
||||
var taglibs = [];
|
||||
var added = new Set();
|
||||
var rootDirname = markoModules.cwd; // Don't search up past this directory
|
||||
var rootPkg = getModuleRootPackage(dirname);
|
||||
if (rootPkg) {
|
||||
@ -80,27 +66,41 @@ function find(dirname, registeredTaglibs, tagDiscoveryDirs) {
|
||||
|
||||
// First walk up the directory tree looking for marko.json files or components/ directories
|
||||
let curDirname = dirname;
|
||||
// exclusiveTagDiscoveryDirs is used for the interop to detect if `tags` directories are used exclusively when finding tags
|
||||
let exclusiveTagDiscoveryDirs = undefined;
|
||||
|
||||
while (true) {
|
||||
if (!excludedDirs[curDirname]) {
|
||||
let taglibPath = nodePath.join(curDirname, "marko.json");
|
||||
let taglib;
|
||||
let manualTagsDir;
|
||||
|
||||
if (existsSync(taglibPath)) {
|
||||
taglib = taglibLoader.loadTaglibFromFile(taglibPath);
|
||||
helper.addTaglib(taglib);
|
||||
manualTagsDir = taglib.tagsDir;
|
||||
addTaglib(taglib);
|
||||
}
|
||||
|
||||
if (!taglib || taglib.tagsDir === undefined) {
|
||||
if (manualTagsDir === undefined) {
|
||||
for (const tagDiscoveryDir of tagDiscoveryDirs) {
|
||||
const componentsPath = nodePath.join(curDirname, tagDiscoveryDir);
|
||||
|
||||
if (existsSync(componentsPath) && !excludedDirs[componentsPath]) {
|
||||
helper.addTaglib(
|
||||
if (exclusiveTagDiscoveryDirs !== false) {
|
||||
if (exclusiveTagDiscoveryDirs === undefined) {
|
||||
exclusiveTagDiscoveryDirs = tagDiscoveryDir;
|
||||
} else if (exclusiveTagDiscoveryDirs !== tagDiscoveryDir) {
|
||||
exclusiveTagDiscoveryDirs = false;
|
||||
}
|
||||
}
|
||||
|
||||
addTaglib(
|
||||
taglibLoader.loadTaglibFromDir(curDirname, tagDiscoveryDir),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (manualTagsDir) {
|
||||
exclusiveTagDiscoveryDirs = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,26 +120,41 @@ function find(dirname, registeredTaglibs, tagDiscoveryDirs) {
|
||||
getAllDependencyNames(rootPkg).forEach((name) => {
|
||||
if (!excludedPackages[name]) {
|
||||
let taglibPath = markoModules.tryResolve(
|
||||
nodePath.join(name, "marko.json"),
|
||||
name + "/marko.json",
|
||||
rootPkg.__dirname,
|
||||
);
|
||||
if (taglibPath) {
|
||||
var taglib = taglibLoader.loadTaglibFromFile(taglibPath, true);
|
||||
helper.addTaglib(taglib);
|
||||
addTaglib(taglib);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = registeredTaglibs.length; i--; ) {
|
||||
helper.addTaglib(registeredTaglibs[i]);
|
||||
addTaglib(registeredTaglibs[i]);
|
||||
}
|
||||
|
||||
findCache[dirname] = found;
|
||||
findCache[dirname] = { exclusiveTagDiscoveryDirs, taglibs };
|
||||
return taglibs;
|
||||
|
||||
return found;
|
||||
function addTaglib(taglib) {
|
||||
if (!added.has(taglib.id)) {
|
||||
added.add(taglib.id);
|
||||
taglibs.push(taglib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
find._withMeta = function findWithMeta(
|
||||
dirname,
|
||||
registeredTaglibs,
|
||||
tagDiscoveryDirs,
|
||||
) {
|
||||
find(dirname, registeredTaglibs, tagDiscoveryDirs);
|
||||
return findCache[dirname];
|
||||
};
|
||||
|
||||
function clearCache() {
|
||||
findCache = {};
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ export function buildLookup(dirname, requestedTranslator, onError) {
|
||||
}
|
||||
|
||||
let taglibsForDir = loadedTranslatorsTaglibs.get(translator);
|
||||
let exclusiveTagDiscoveryDirs = undefined;
|
||||
|
||||
if (!taglibsForDir) {
|
||||
loadedTranslatorsTaglibs.set(
|
||||
@ -45,11 +46,13 @@ export function buildLookup(dirname, requestedTranslator, onError) {
|
||||
}
|
||||
|
||||
runAndCatchErrors(() => {
|
||||
taglibsForDir = finder.find(
|
||||
const foundMeta = finder.find._withMeta(
|
||||
dirname,
|
||||
taglibsForDir,
|
||||
translator.tagDiscoveryDirs,
|
||||
);
|
||||
taglibsForDir = foundMeta.taglibs;
|
||||
exclusiveTagDiscoveryDirs = foundMeta.exclusiveTagDiscoveryDirs;
|
||||
}, onError);
|
||||
|
||||
const cacheKey = taglibsForDir
|
||||
@ -60,6 +63,7 @@ export function buildLookup(dirname, requestedTranslator, onError) {
|
||||
|
||||
if (!lookup) {
|
||||
lookup = lookupCache[cacheKey] = new Lookup();
|
||||
lookup.exclusiveTagDiscoveryDirs = exclusiveTagDiscoveryDirs;
|
||||
for (let i = taglibsForDir.length; i--; ) {
|
||||
const taglib = taglibsForDir[i];
|
||||
lookup.addTaglib(taglib);
|
||||
|
||||
@ -39,6 +39,7 @@ class Taglib {
|
||||
this.patternAttributes = [];
|
||||
this.imports = null;
|
||||
this.importsLookup = null;
|
||||
this.tagsDir = undefined;
|
||||
}
|
||||
|
||||
addAttribute(attribute) {
|
||||
|
||||
@ -52,7 +52,8 @@ class TaglibLookup {
|
||||
this.taglibsById = {};
|
||||
|
||||
this._sortedTags = undefined;
|
||||
this.manualTagsDirs = new Set();
|
||||
this.exclusiveTagDiscoveryDirs = undefined;
|
||||
this.manualTagsDirs = undefined;
|
||||
}
|
||||
|
||||
hasTaglib(taglib) {
|
||||
@ -103,7 +104,9 @@ class TaglibLookup {
|
||||
typeof taglib.tagsDir === "string" &&
|
||||
/[/\\]tags[/\\]?$/.test(taglib.tagsDir)
|
||||
) {
|
||||
this.manualTagsDirs.add(nodePath.resolve(taglib.dirname, taglib.tagsDir));
|
||||
(this.manualTagsDirs || (this.manualTagsDirs = new Set())).add(
|
||||
nodePath.resolve(taglib.dirname, taglib.tagsDir),
|
||||
);
|
||||
}
|
||||
|
||||
// console.log("TAGLIB:", taglib);
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
# Render
|
||||
```html
|
||||
<h1>
|
||||
Hello tags
|
||||
</h1>
|
||||
<h1>
|
||||
Hello components
|
||||
</h1>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT #text0, #text1, #text2, h10, #text3, #text4, #text5, h11, #text6, #text7
|
||||
```
|
||||
@ -0,0 +1,19 @@
|
||||
import { t as _t } from "marko/src/runtime/vdom/index.js";
|
||||
const _marko_componentType = "__tests__/components/hello-components.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
import { r as _marko_registerComponent } from "marko/src/runtime/components/registry.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_template);
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
out.be("h1", null, "0", _component, null, 0);
|
||||
out.t("Hello components", _component);
|
||||
out.ee();
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import _marko_defineComponent from "marko/src/runtime/components/defineComponent.js";
|
||||
_marko_template.Component = _marko_defineComponent(_marko_component, _marko_template._);
|
||||
@ -0,0 +1,5 @@
|
||||
export const $template = "<h1>Hello tags</h1>";
|
||||
export const $walks = /* over(1) */"b";
|
||||
export const $setup = () => {};
|
||||
import * as _ from "@marko/runtime-tags/debug/dom";
|
||||
export default /* @__PURE__ */_._template("__tests__/tags/hello-tags.marko", $template, $walks, $setup);
|
||||
@ -0,0 +1,4 @@
|
||||
import init6 from "virtual:./template.marko.hydrate-6.js import \"./tags/hello-tags.marko\";\nexport default () => {};";
|
||||
import init5 from "virtual:./template.marko.hydrate-5.js export default () => {};";
|
||||
init6();
|
||||
init5();
|
||||
@ -0,0 +1,23 @@
|
||||
import "marko/src/runtime/helpers/tags-compat/dom-debug.mjs";
|
||||
import { t as _t } from "marko/src/runtime/vdom/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _helloTags from "./tags/hello-tags.marko";
|
||||
import _marko_dynamic_tag from "marko/src/runtime/helpers/dynamic-tag.js";
|
||||
import _helloComponents from "./components/hello-components.marko";
|
||||
import _marko_tag from "marko/src/runtime/helpers/render-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
import { r as _marko_registerComponent } from "marko/src/runtime/components/registry.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_template);
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_dynamic_tag(out, _helloTags, null, null, null, null, _componentDef, "0");
|
||||
_marko_tag(_helloComponents, {}, out, _componentDef, "1");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import _marko_defineComponent from "marko/src/runtime/components/defineComponent.js";
|
||||
_marko_template.Component = _marko_defineComponent(_marko_component, _marko_template._);
|
||||
@ -0,0 +1,15 @@
|
||||
import { t as _t } from "marko/src/runtime/html/index.js";
|
||||
const _marko_componentType = "__tests__/components/hello-components.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
out.w("<h1>");
|
||||
out.w("Hello components");
|
||||
out.w("</h1>");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
@ -0,0 +1,5 @@
|
||||
import * as _ from "@marko/runtime-tags/debug/html";
|
||||
export default _._template("__tests__/tags/hello-tags.marko", input => {
|
||||
const $scope0_id = _._scope_id();
|
||||
_._html("<h1>Hello tags</h1>");
|
||||
});
|
||||
@ -0,0 +1,19 @@
|
||||
import "marko/src/runtime/helpers/tags-compat/html-debug.mjs";
|
||||
import { t as _t } from "marko/src/runtime/html/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _helloTags from "./tags/hello-tags.marko";
|
||||
import _marko_dynamic_tag from "marko/src/runtime/helpers/dynamic-tag.js";
|
||||
import _helloComponents from "./components/hello-components.marko";
|
||||
import _marko_tag from "marko/src/runtime/helpers/render-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_dynamic_tag(out, _helloTags, null, null, null, null, _componentDef, "0");
|
||||
_marko_tag(_helloComponents, {}, out, _componentDef, "1");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
@ -0,0 +1,14 @@
|
||||
# Render
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<h1>
|
||||
Hello tags
|
||||
</h1>
|
||||
<h1>
|
||||
Hello components
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@ -0,0 +1,28 @@
|
||||
# Write
|
||||
<h1>Hello tags</h1><h1>Hello components</h1>
|
||||
|
||||
# Render End
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<h1>
|
||||
Hello tags
|
||||
</h1>
|
||||
<h1>
|
||||
Hello components
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT html
|
||||
INSERT html/head
|
||||
INSERT html/body
|
||||
INSERT html/body/h10
|
||||
INSERT html/body/h10/#text
|
||||
INSERT html/body/h11
|
||||
INSERT html/body/h11/#text
|
||||
```
|
||||
@ -0,0 +1 @@
|
||||
<h1>Hello components</h1>
|
||||
@ -0,0 +1 @@
|
||||
<h1>Hello tags</h1>
|
||||
@ -0,0 +1,2 @@
|
||||
<hello-tags/>
|
||||
<hello-components/>
|
||||
@ -7,5 +7,5 @@
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT #text0, #text1, #text2, h1, #text3, #text4, #text5
|
||||
INSERT h1
|
||||
```
|
||||
@ -1,4 +1,2 @@
|
||||
import init6 from "virtual:./template.marko.hydrate-6.js import \"./tags/hello.marko\";\nexport default () => {};";
|
||||
import init5 from "virtual:./template.marko.hydrate-5.js export default () => {};";
|
||||
init6();
|
||||
init5();
|
||||
import "./template.marko";
|
||||
import "./tags/hello.marko";
|
||||
@ -1,20 +1,8 @@
|
||||
import "marko/src/runtime/helpers/tags-compat/dom-debug.mjs";
|
||||
import { t as _t } from "marko/src/runtime/vdom/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _hello from "./tags/hello.marko";
|
||||
import _marko_dynamic_tag from "marko/src/runtime/helpers/dynamic-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
import { r as _marko_registerComponent } from "marko/src/runtime/components/registry.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_template);
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_dynamic_tag(out, _hello, null, null, null, null, _componentDef, "0");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import _marko_defineComponent from "marko/src/runtime/components/defineComponent.js";
|
||||
_marko_template.Component = _marko_defineComponent(_marko_component, _marko_template._);
|
||||
export const $template = _hello_template;
|
||||
export const $walks = /* <hello> */`/${_hello_walks}&`;
|
||||
import { $setup as _hello, $template as _hello_template, $walks as _hello_walks } from "./tags/hello.marko";
|
||||
export function $setup($scope) {
|
||||
_hello($scope["#childScope/0"]);
|
||||
}
|
||||
import * as _ from "@marko/runtime-tags/debug/dom";
|
||||
export default /* @__PURE__ */_._template("__tests__/template.marko", $template, $walks, $setup);
|
||||
@ -1,16 +1,6 @@
|
||||
import "marko/src/runtime/helpers/tags-compat/html-debug.mjs";
|
||||
import { t as _t } from "marko/src/runtime/html/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _hello from "./tags/hello.marko";
|
||||
import _marko_dynamic_tag from "marko/src/runtime/helpers/dynamic-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_dynamic_tag(out, _hello, null, null, null, null, _componentDef, "0");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import * as _ from "@marko/runtime-tags/debug/html";
|
||||
export default _._template("__tests__/template.marko", input => {
|
||||
const $scope0_id = _._scope_id();
|
||||
_hello({});
|
||||
});
|
||||
@ -1,6 +1,10 @@
|
||||
Cannot mix Tags API and Class API features in the same file:
|
||||
|
||||
at packages/runtime-tags/src/__tests__/fixtures-interop/error-class-tags-dir/tags/hello.marko:1:1
|
||||
> 1 | class {}
|
||||
| ^^^^^ Unable to find entry point for [custom tag](https://markojs.com/docs/reference/custom-tag#relative-custom-tags) `<class>`.
|
||||
2 |
|
||||
3 | <h1>Hello world</h1>
|
||||
Template file within a tags directory at packages/runtime-tags/src/__tests__/fixtures-interop/error-class-tags-dir/tags/hello.marko:
|
||||
|
||||
|
||||
<class> tag at packages/runtime-tags/src/__tests__/fixtures-interop/error-class-tags-dir/tags/hello.marko(1,1):
|
||||
> 1 | class {}
|
||||
| ^^^^^
|
||||
2 |
|
||||
3 | <h1>Hello world</h1>
|
||||
@ -1,19 +1,9 @@
|
||||
import { t as _t } from "marko/src/runtime/vdom/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
export const $template = "<!><!><!>";
|
||||
export const $walks = /* over(1), replace, over(2) */"b%c";
|
||||
import _hello from "./tags/hello.marko";
|
||||
import _marko_tag from "marko/src/runtime/helpers/render-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
import { r as _marko_registerComponent } from "marko/src/runtime/components/registry.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_template);
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_tag(_hello, {}, out, _componentDef, "0");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import _marko_defineComponent from "marko/src/runtime/components/defineComponent.js";
|
||||
_marko_template.Component = _marko_defineComponent(_marko_component, _marko_template._);
|
||||
import * as _ from "@marko/runtime-tags/debug/dom";
|
||||
const $dynamicTag = /* @__PURE__ */_._dynamic_tag("#text/0");
|
||||
export function $setup($scope) {
|
||||
$dynamicTag($scope, _hello);
|
||||
}
|
||||
export default /* @__PURE__ */_._template("__tests__/template.marko", $template, $walks, $setup);
|
||||
@ -1,6 +1,10 @@
|
||||
Cannot mix Tags API and Class API features in the same file:
|
||||
|
||||
at packages/runtime-tags/src/__tests__/fixtures-interop/error-class-tags-dir/tags/hello.marko:1:1
|
||||
> 1 | class {}
|
||||
| ^^^^^ Unable to find entry point for [custom tag](https://markojs.com/docs/reference/custom-tag#relative-custom-tags) `<class>`.
|
||||
2 |
|
||||
3 | <h1>Hello world</h1>
|
||||
Template file within a tags directory at packages/runtime-tags/src/__tests__/fixtures-interop/error-class-tags-dir/tags/hello.marko:
|
||||
|
||||
|
||||
<class> tag at packages/runtime-tags/src/__tests__/fixtures-interop/error-class-tags-dir/tags/hello.marko(1,1):
|
||||
> 1 | class {}
|
||||
| ^^^^^
|
||||
2 |
|
||||
3 | <h1>Hello world</h1>
|
||||
@ -1,15 +1,6 @@
|
||||
import { t as _t } from "marko/src/runtime/html/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _hello from "./tags/hello.marko";
|
||||
import _marko_tag from "marko/src/runtime/helpers/render-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_tag(_hello, {}, out, _componentDef, "0");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import * as _ from "@marko/runtime-tags/debug/html";
|
||||
export default _._template("__tests__/template.marko", input => {
|
||||
const $scope0_id = _._scope_id();
|
||||
_._dynamic_tag($scope0_id, "#text/0", _hello, {}, 0, 0, 0);
|
||||
});
|
||||
@ -1,15 +1,17 @@
|
||||
# Render
|
||||
```html
|
||||
<!---->
|
||||
<!---->
|
||||
<h1>
|
||||
Hello world
|
||||
</h1>
|
||||
<!---->
|
||||
<!---->
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT #text0, #text1, #text2, #comment0, #text3, #text4, #comment1, #text5, #text6, #text7
|
||||
INSERT #comment0, #comment1, #text0, #text1, #comment2, #comment3
|
||||
INSERT h1
|
||||
INSERT h1/#text
|
||||
```
|
||||
@ -1,4 +1,4 @@
|
||||
import init6 from "virtual:./template.marko.hydrate-6.js import \"./tags/hello.marko\";\nexport default () => {};";
|
||||
import init6 from "virtual:./template.marko.hydrate-6.js import \"./template.marko\";\nimport \"./tags/hello.marko\";\nexport default () => {};";
|
||||
import init5 from "virtual:./template.marko.hydrate-5.js import { init } from \"marko/src/runtime/components/index.js\";\nimport \"./tags/components/hello-internal.marko\";\nexport default () => init();";
|
||||
init6();
|
||||
init5();
|
||||
@ -1,20 +1,8 @@
|
||||
import "marko/src/runtime/helpers/tags-compat/dom-debug.mjs";
|
||||
import { t as _t } from "marko/src/runtime/vdom/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _hello from "./tags/hello.marko";
|
||||
import _marko_dynamic_tag from "marko/src/runtime/helpers/dynamic-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
import { r as _marko_registerComponent } from "marko/src/runtime/components/registry.js";
|
||||
_marko_registerComponent(_marko_componentType, () => _marko_template);
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_dynamic_tag(out, _hello, null, null, null, null, _componentDef, "0");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import _marko_defineComponent from "marko/src/runtime/components/defineComponent.js";
|
||||
_marko_template.Component = _marko_defineComponent(_marko_component, _marko_template._);
|
||||
export const $template = `<!>${_hello_template}<!>`;
|
||||
export const $walks = /* over(1), <hello>, over(1) */`b/${_hello_walks}&b`;
|
||||
import { $setup as _hello, $template as _hello_template, $walks as _hello_walks } from "./tags/hello.marko";
|
||||
export function $setup($scope) {
|
||||
_hello($scope["#childScope/0"]);
|
||||
}
|
||||
import * as _ from "@marko/runtime-tags/debug/dom";
|
||||
export default /* @__PURE__ */_._template("__tests__/template.marko", $template, $walks, $setup);
|
||||
@ -1,16 +1,6 @@
|
||||
import "marko/src/runtime/helpers/tags-compat/html-debug.mjs";
|
||||
import { t as _t } from "marko/src/runtime/html/index.js";
|
||||
const _marko_componentType = "__tests__/template.marko",
|
||||
_marko_template = _t(_marko_componentType);
|
||||
export default _marko_template;
|
||||
import _hello from "./tags/hello.marko";
|
||||
import _marko_dynamic_tag from "marko/src/runtime/helpers/dynamic-tag.js";
|
||||
import _marko_renderer from "marko/src/runtime/components/renderer.js";
|
||||
const _marko_component = {};
|
||||
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
|
||||
_marko_dynamic_tag(out, _hello, null, null, null, null, _componentDef, "0");
|
||||
}, {
|
||||
t: _marko_componentType,
|
||||
i: true,
|
||||
d: true
|
||||
}, _marko_component);
|
||||
import * as _ from "@marko/runtime-tags/debug/html";
|
||||
export default _._template("__tests__/template.marko", input => {
|
||||
const $scope0_id = _._scope_id();
|
||||
_hello({});
|
||||
});
|
||||
@ -7,16 +7,17 @@
|
||||
Hello world
|
||||
</h1>
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("s");
|
||||
M.s.r = [_ => (_.a = [0, 1,
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.a = [0, 2,
|
||||
{
|
||||
m5c: "s1"
|
||||
}]), "$compat_setScope 2"];
|
||||
M.s.w();
|
||||
m5c: "_0"
|
||||
}])];
|
||||
M._.w();
|
||||
$MC = (window.$MC || []).concat(
|
||||
{
|
||||
"p": "_",
|
||||
"w": [
|
||||
["s1", 0,
|
||||
["_0", 0,
|
||||
{},
|
||||
{
|
||||
"f": 1
|
||||
@ -25,7 +26,9 @@
|
||||
"t": [
|
||||
"__tests__/tags/components/hello-internal.marko"
|
||||
]
|
||||
})
|
||||
});
|
||||
M._.r.push("$compat_setScope 3");
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,27 +1,28 @@
|
||||
# Write
|
||||
<!--M#s1--><h1>Hello world</h1><!--M/--><script>WALKER_RUNTIME("M")("s");M.s.r=[_=>(_.a=[0,1,{m5c:"s1"}]),"$compat_setScope 2"];M.s.w();$MC=(window.$MC||[]).concat({"w":[["s1",0,{},{"f":1}]],"t":["__tests__/tags/components/hello-internal.marko"]})</script>
|
||||
<!--M#_0--><h1>Hello world</h1><!--M/--><script>WALKER_RUNTIME("M")("_");M._.r=[_=>(_.a=[0,2,{m5c:"_0"}])];M._.w();$MC=(window.$MC||[]).concat({"p":"_","w":[["_0",0,{},{"f":1}]],"t":["__tests__/tags/components/hello-internal.marko"]});M._.r.push("$compat_setScope 3");M._.w()</script>
|
||||
|
||||
# Render End
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<!--M#s1-->
|
||||
<!--M#_0-->
|
||||
<h1>
|
||||
Hello world
|
||||
</h1>
|
||||
<!--M/-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("s");
|
||||
M.s.r = [_ => (_.a = [0, 1,
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.a = [0, 2,
|
||||
{
|
||||
m5c: "s1"
|
||||
}]), "$compat_setScope 2"];
|
||||
M.s.w();
|
||||
m5c: "_0"
|
||||
}])];
|
||||
M._.w();
|
||||
$MC = (window.$MC || []).concat(
|
||||
{
|
||||
"p": "_",
|
||||
"w": [
|
||||
["s1", 0,
|
||||
["_0", 0,
|
||||
{},
|
||||
{
|
||||
"f": 1
|
||||
@ -30,7 +31,9 @@
|
||||
"t": [
|
||||
"__tests__/tags/components/hello-internal.marko"
|
||||
]
|
||||
})
|
||||
});
|
||||
M._.r.push("$compat_setScope 3");
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
5
packages/runtime-tags/src/__tests__/package.json
Normal file
5
packages/runtime-tags/src/__tests__/package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "marko-test",
|
||||
"version": "1.0.0",
|
||||
"type": "commonjs"
|
||||
}
|
||||
@ -22,50 +22,49 @@ type FeatureState = {
|
||||
feature?: Feature;
|
||||
};
|
||||
|
||||
const DEFAULT_FEATURE_TYPE = FeatureType.Class;
|
||||
|
||||
export function isTagsAPI(file = getFile()) {
|
||||
const program = file.path;
|
||||
let featureType = program.node.extra?.featureType;
|
||||
const programExtra = (program.node.extra ??= {});
|
||||
let { featureType } = programExtra;
|
||||
|
||||
if (!featureType) {
|
||||
const lookup = getTaglibLookup(file);
|
||||
const tagsDir = getTagsDir(file.opts.filename);
|
||||
const programExtra = (program.node.extra ??= {});
|
||||
|
||||
if (tagsDir) {
|
||||
featureType = programExtra.featureType = getTaglibLookup(
|
||||
file,
|
||||
).manualTagsDirs.has(tagsDir)
|
||||
? FeatureType.Class
|
||||
: FeatureType.Tags;
|
||||
} else {
|
||||
const state = {} as FeatureState;
|
||||
scanBody(state, program.get("body"));
|
||||
featureType = programExtra.featureType =
|
||||
state.feature?.type || DEFAULT_FEATURE_TYPE;
|
||||
const state = {} as FeatureState;
|
||||
if (tagsDir && !lookup.manualTagsDirs?.has(tagsDir)) {
|
||||
addFeature(
|
||||
state,
|
||||
FeatureType.Tags,
|
||||
"Template file within a tags directory",
|
||||
program,
|
||||
);
|
||||
}
|
||||
|
||||
scanBody(state, program.get("body"));
|
||||
featureType = programExtra.featureType =
|
||||
state.feature?.type ||
|
||||
(lookup.exclusiveTagDiscoveryDirs === "tags"
|
||||
? FeatureType.Tags
|
||||
: FeatureType.Class);
|
||||
}
|
||||
|
||||
return featureType === FeatureType.Tags;
|
||||
}
|
||||
|
||||
const PATH_SEPARATOR_REGEX = /\/|\\/;
|
||||
const TAGS_LENGTH = "tags".length;
|
||||
const COMPONENTS_LENGTH = "components".length;
|
||||
function getTagsDir(filename: string) {
|
||||
const pathSeparator = PATH_SEPARATOR_REGEX.exec(filename)?.[0];
|
||||
const pathSeparator = /\/|\\/.exec(filename)?.[0];
|
||||
if (pathSeparator) {
|
||||
let previousIndex = filename.length - 1;
|
||||
while (previousIndex > 0) {
|
||||
const index = filename.lastIndexOf(pathSeparator, previousIndex);
|
||||
switch (previousIndex - index) {
|
||||
case TAGS_LENGTH: {
|
||||
case 4 /** "tags".length */: {
|
||||
if (filename.startsWith("tags", index + 1)) {
|
||||
return filename.slice(0, index + 5);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMPONENTS_LENGTH: {
|
||||
case 10 /** "components".length */: {
|
||||
if (filename.startsWith("components", index + 1)) {
|
||||
return false;
|
||||
}
|
||||
@ -97,6 +96,10 @@ function scanBody(
|
||||
case "MarkoComment":
|
||||
if (/^\s*use tags\s*$/.test((child.node as t.MarkoComment).value)) {
|
||||
addFeature(state, FeatureType.Tags, "<!-- use tags -->", child);
|
||||
} else if (
|
||||
/^\s*use class\s*$/.test((child.node as t.MarkoComment).value)
|
||||
) {
|
||||
addFeature(state, FeatureType.Class, "<!-- use class -->", child);
|
||||
}
|
||||
break;
|
||||
case "MarkoScriptlet":
|
||||
@ -148,10 +151,21 @@ function scanTag(state: FeatureState, tag: t.NodePath<t.MarkoTag>) {
|
||||
}
|
||||
|
||||
const tagDef = getTagDef(tag);
|
||||
if (tagDef?.taglibId === runtimeInfo.taglibId) {
|
||||
const feature = getFeatureTypeFromCoreTagName(tagDef.name);
|
||||
if (feature) {
|
||||
addFeature(state, feature, `<${tagDef.name}> tag`, tag.get("name"));
|
||||
|
||||
if (tagDef) {
|
||||
if (tagDef.name === "style") {
|
||||
if (
|
||||
/^style(?:(?:\.[^.\s\\/:*?"<>|({]+)+)?\s*\{/.test(
|
||||
tag.node.rawValue || "",
|
||||
)
|
||||
) {
|
||||
addFeature(state, FeatureType.Class, `style block`, tag.get("name"));
|
||||
}
|
||||
} else if (tagDef.taglibId === runtimeInfo.taglibId) {
|
||||
const feature = getFeatureTypeFromCoreTagName(tagDef.name);
|
||||
if (feature) {
|
||||
addFeature(state, feature, `<${tagDef.name}> tag`, tag.get("name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +211,7 @@ function addFeature(
|
||||
if (state.feature.type !== type) {
|
||||
throw buildAggregateError(
|
||||
path.hub.file,
|
||||
'Cannot mix "tags api" and "class api" features',
|
||||
"Cannot mix Tags API and Class API features in the same file",
|
||||
[state.feature.name, state.feature.path],
|
||||
[name, path],
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user