mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Upgrade <await> tag to use tag parameters and attribute tags. Add migration from old syntax. (#1244)
This commit is contained in:
parent
681ba112cd
commit
24753a7674
@ -228,8 +228,13 @@ performance](http://www.ebaytechblog.com/2014/12/08/async-fragments-rediscoverin
|
||||
```marko
|
||||
$ const searchResultsPromise = searchService.performSearch(keywords);
|
||||
|
||||
<await(person from searchResultsPromise)>
|
||||
<div>Hello ${person.name}!</div>
|
||||
<await(searchResultsPromise)>
|
||||
<@then|person|>
|
||||
Hello ${person.name}!
|
||||
</@then>
|
||||
<@catch|err|>
|
||||
The error was: ${err.message}.
|
||||
</@catch>
|
||||
</await>
|
||||
```
|
||||
|
||||
|
||||
@ -385,9 +385,8 @@ sample template shows how to use macro functions inside expressions:
|
||||
|
||||
### `<await>`
|
||||
|
||||
The `<await>` tag is used to dynamically load in content from a data provider. The data provider can be a `Promise` or a `callback`. Once the provider returns it's results the children are rendered.
|
||||
|
||||
await-example.marko
|
||||
The `<await>` tag is used to render a template asynchronously with the results of a Promise.
|
||||
The `<@then>` and `<@catch>` attribute tags can optionally receive the value of the resolved and rejected promise respectively as [tag parameters](./syntax.md#tag-body-parameters). You can also provide a `<@placeholder>` attribute tag which will be displayed while the promise is pending.
|
||||
|
||||
```marko
|
||||
$ var personPromise = new Promise((resolve, reject) => {
|
||||
@ -398,34 +397,49 @@ $ var personPromise = new Promise((resolve, reject) => {
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
<await(person from personPromise)>
|
||||
<div>Hello ${person.name}!</div>
|
||||
<await(personPromise)>
|
||||
<@placeholder>
|
||||
<!-- Displayed while promise is pending -->
|
||||
|
||||
Loading...
|
||||
</@placeholder>
|
||||
|
||||
<@then|person|>
|
||||
<!-- Displayed if promise resolves -->
|
||||
|
||||
<div>Hello ${person.name}!</div>
|
||||
<@then>
|
||||
|
||||
<@catch|err|>
|
||||
<!-- Displayed if promise rejects -->
|
||||
|
||||
Caught error: ${err.name}.
|
||||
</@catch>
|
||||
</await>
|
||||
```
|
||||
|
||||
Advanced implementation:
|
||||
Optional Attributes:
|
||||
|
||||
- `<await>` tag signature
|
||||
- Basic usage: `<await(results from dataProvider)>...</await>`
|
||||
- Optional attributes
|
||||
- client-reorder `boolean`
|
||||
- arg `expression`
|
||||
- arg-\* `string`
|
||||
- method `string`
|
||||
- timeout `integer`
|
||||
- timeout-message `string`
|
||||
- error-message `string`
|
||||
- placeholder `string`
|
||||
- renderTimeout `function`
|
||||
- renderError `function`
|
||||
- renderPlaceholder `function`
|
||||
- name `string`
|
||||
- scope `expression`
|
||||
- show-after `string`
|
||||
- Optional child tags
|
||||
- `<await-placeholder>Loading...</await-placeholder>`
|
||||
- `<await-timeout>Request timed out</await-timeout>`
|
||||
- `<await-error>Request errored</await-error>`
|
||||
- **timeout** `integer`: An optional timeout that when reached will cause the promise to reject with a `TimeoutError`.
|
||||
- **name** `string`: Used to improve debugging and also to ensure promise ordering with the `show-after` attribute.
|
||||
- **show-after** `string`: This attribute will ensure that (with client-reorder) this `await` block will always show after another `await` block with the provided name.
|
||||
- **client-reorder** `boolean`: If set anything after this promise will be sent out immediately, and reordered using JS in the browser.
|
||||
|
||||
> **Pro Tip**: With the `timeout` attribute set you can differentiate `TimeoutError`s from promise rejections by checking the `name` property of the error.
|
||||
>
|
||||
> ```marko
|
||||
> <await(slowPromise) timeout=5000>
|
||||
> <@then>Done</@then>
|
||||
> <@catch|err|>
|
||||
> <if(err.name === "TimeoutError)>
|
||||
> Took too long to fetch the data!
|
||||
> </if>
|
||||
> <else>
|
||||
> Promise failed with ${err.message}.
|
||||
> </else>
|
||||
> </@catch>
|
||||
> </await>
|
||||
> ```
|
||||
|
||||
## Comments
|
||||
|
||||
|
||||
@ -1104,8 +1104,10 @@ Given a template like this:
|
||||
**New:**
|
||||
|
||||
```marko
|
||||
<await(foo from data.provider)>
|
||||
${foo}
|
||||
<await(data.provider)>
|
||||
<@then|foo|>
|
||||
${foo}
|
||||
</@then>
|
||||
</await>
|
||||
```
|
||||
|
||||
|
||||
@ -720,10 +720,10 @@ import fsp from 'fs-promise';
|
||||
$ var filePath = __dirname + '/hello.txt';
|
||||
$ var readPromise = fsp.readFile(filePath, {encoding: 'utf8'});
|
||||
|
||||
<await(helloText from readPromise)>
|
||||
<p>
|
||||
${helloText}
|
||||
</p>
|
||||
<await(readPromise)>
|
||||
<@then|helloText|>
|
||||
<p>${helloText}</p>
|
||||
</@then>
|
||||
</await>
|
||||
```
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ if (target === "src") {
|
||||
|
||||
if (shouldBuildSrc) {
|
||||
buildDir("src", "dist", {
|
||||
babelExclude: ["/taglibs/async/client-reorder-runtime.min.js"],
|
||||
babelExclude: ["/taglibs/core/async/client-reorder-runtime.min.js"],
|
||||
babelOptions
|
||||
});
|
||||
}
|
||||
|
||||
@ -145,7 +145,13 @@ class Normalizer {
|
||||
}
|
||||
}
|
||||
|
||||
if (elNode.params.length) {
|
||||
if (
|
||||
elNode.params.length &&
|
||||
!(
|
||||
(elNode.tagName === "@then" || elNode.tagName === "@catch") &&
|
||||
elNode.parentNode.tagName === "await"
|
||||
)
|
||||
) {
|
||||
context.setFlag("hasTagParams");
|
||||
context.exampleTagParam = newNode;
|
||||
}
|
||||
|
||||
@ -275,10 +275,6 @@ function registerCoreTaglibs() {
|
||||
require("../taglibs/svg/marko.json"),
|
||||
require.resolve("../taglibs/svg/marko.json")
|
||||
);
|
||||
registerTaglib(
|
||||
require("../taglibs/async/marko.json"),
|
||||
require.resolve("../taglibs/async/marko.json")
|
||||
);
|
||||
registerTaglib(
|
||||
require("../taglibs/cache/marko.json"),
|
||||
require.resolve("../taglibs/cache/marko.json")
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function transform(el, context) {
|
||||
var parentNode = el.parentNode;
|
||||
|
||||
if (parentNode.tagName !== "await") {
|
||||
context.addError(
|
||||
"The <" + el.tagName + "> should be nested within an <await> tag."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var targetProp;
|
||||
|
||||
if (el.tagName === "await-error") {
|
||||
targetProp = "renderError";
|
||||
} else if (el.tagName === "await-timeout") {
|
||||
targetProp = "renderTimeout";
|
||||
} else if (el.tagName === "await-placeholder") {
|
||||
targetProp = "renderPlaceholder";
|
||||
}
|
||||
|
||||
var builder = context.builder;
|
||||
|
||||
parentNode.setAttributeValue(
|
||||
targetProp,
|
||||
builder.renderBodyFunction(el.body)
|
||||
);
|
||||
el.detach();
|
||||
};
|
||||
@ -1,108 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var isObjectEmpty = require("raptor-util/isObjectEmpty");
|
||||
|
||||
module.exports = function transform(el, context) {
|
||||
if (!el.argument) {
|
||||
context.addError(
|
||||
"Invalid <await> tag. Argument is missing. Example: <await(user from data.userProvider)>"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var match = /^([$A-Z_][0-9A-Z_$]*) from (.*)$/i.exec(el.argument);
|
||||
|
||||
if (!match) {
|
||||
context.addError(
|
||||
"Invalid <await> tag. Argument is malformed. Example: <await(user from data.userProvider)>"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var varName = match[1];
|
||||
var dataProviderAttr = match[2];
|
||||
|
||||
if (!context.util.isValidJavaScriptIdentifier(varName)) {
|
||||
context.addError(
|
||||
"Invalid <await> tag. Argument's variable name should be a valid JavaScript identifier. Example: user, as in <await(user from data.userProvider)>"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var builder = context.builder;
|
||||
|
||||
el.setAttributeValue("_var", builder.literal(varName));
|
||||
el.setAttributeValue(
|
||||
"_dataProvider",
|
||||
builder.parseExpression(dataProviderAttr)
|
||||
);
|
||||
el.argument = null;
|
||||
|
||||
////////////////////
|
||||
|
||||
var attrs = el.getAttributes().concat([]);
|
||||
var arg = {};
|
||||
|
||||
attrs.forEach(attr => {
|
||||
var attrName = attr.name;
|
||||
if (attrName.startsWith("arg-")) {
|
||||
let argName = attrName.substring("arg-".length);
|
||||
arg[argName] = attr.value;
|
||||
el.removeAttribute(attrName);
|
||||
}
|
||||
});
|
||||
|
||||
var name = el.getAttributeValue("name");
|
||||
if (name == null) {
|
||||
el.setAttributeValue("_name", builder.literal(dataProviderAttr));
|
||||
}
|
||||
|
||||
if (el.hasAttribute("arg")) {
|
||||
if (isObjectEmpty(arg)) {
|
||||
arg = el.getAttributeValue("arg");
|
||||
} else {
|
||||
let mergeVar = context.helper("merge");
|
||||
arg = builder.functionCall(mergeVar, [
|
||||
builder.literal(arg), // Input props from the attributes take precedence
|
||||
el.getAttributeValue("arg")
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if (isObjectEmpty(arg)) {
|
||||
arg = null;
|
||||
} else {
|
||||
arg = builder.literal(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (arg) {
|
||||
el.setAttributeValue("arg", arg);
|
||||
}
|
||||
|
||||
var timeoutMessage = el.getAttributeValue("timeout-message");
|
||||
if (timeoutMessage) {
|
||||
el.removeAttribute("timeout-message");
|
||||
el.setAttributeValue(
|
||||
"renderTimeout",
|
||||
builder.renderBodyFunction([builder.text(timeoutMessage)])
|
||||
);
|
||||
}
|
||||
|
||||
var errorMessage = el.getAttributeValue("error-message");
|
||||
if (errorMessage) {
|
||||
el.removeAttribute("error-message");
|
||||
el.setAttributeValue(
|
||||
"renderError",
|
||||
builder.renderBodyFunction([builder.text(errorMessage)])
|
||||
);
|
||||
}
|
||||
|
||||
var placeholder = el.getAttributeValue("placeholder");
|
||||
if (placeholder) {
|
||||
el.removeAttribute("placeholder");
|
||||
el.setAttributeValue(
|
||||
"renderPlaceholder",
|
||||
builder.renderBodyFunction([builder.text(placeholder)])
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -1,104 +0,0 @@
|
||||
{
|
||||
"<await>": {
|
||||
"renderer": "./await-tag",
|
||||
"@_var": "identifier",
|
||||
"@_dataProvider": "expression",
|
||||
|
||||
"@arg": {
|
||||
"type": "expression",
|
||||
"preserve-name": true
|
||||
},
|
||||
"@arg-*": {
|
||||
"pattern": true,
|
||||
"type": "string",
|
||||
"preserve-name": true
|
||||
},
|
||||
|
||||
"@method": "string",
|
||||
|
||||
"@timeout": "integer",
|
||||
|
||||
"@timeout-message": "string",
|
||||
"@error-message": "string",
|
||||
"@placeholder": "string",
|
||||
|
||||
"@renderTimeout": "function",
|
||||
"@renderError": "function",
|
||||
"@renderPlaceholder": "function",
|
||||
|
||||
"@name": {
|
||||
"type": "string",
|
||||
"description": "Name of await",
|
||||
"autocomplete": [
|
||||
{
|
||||
"snippet": "name=\"${1:name}\""
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"@_name": "string",
|
||||
"@client-reorder": {
|
||||
"type": "boolean",
|
||||
"description": "Use JavaScript on client to move async fragment into the proper place."
|
||||
},
|
||||
"@scope": {
|
||||
"type": "expression",
|
||||
"description": "The value of 'this' when invoking the data provider function (N/A with promises)"
|
||||
},
|
||||
"@show-after": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
"vars": [
|
||||
{
|
||||
"name-from-attribute": "_var"
|
||||
}
|
||||
],
|
||||
"transformer": "./await-tag-transformer",
|
||||
"autocomplete": [
|
||||
{
|
||||
"snippet": "await(${1:varName} from ${2:data.myDataProvider})",
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await><code>"
|
||||
},
|
||||
{
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await><code>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"<await-reorderer>": {
|
||||
"renderer": "./await-reorderer-tag",
|
||||
"autocomplete": [
|
||||
{
|
||||
"snippet": "await-reorderer",
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await-reorderer><code>"
|
||||
},
|
||||
{
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await-reorderer><code>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"<await-placeholder>": {
|
||||
"transformer": "./await-nested-tag-transformer",
|
||||
"autocomplete": [
|
||||
{
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await-placeholder><code>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"<await-timeout>": {
|
||||
"transformer": "./await-nested-tag-transformer",
|
||||
"autocomplete": [
|
||||
{
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await-timeout><code>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"<await-error>": {
|
||||
"transformer": "./await-nested-tag-transformer",
|
||||
"autocomplete": [
|
||||
{
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await-error><code>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
var nextTick = require("../../runtime/nextTick");
|
||||
var nextTick = require("../../../runtime/nextTick");
|
||||
|
||||
function AsyncValue() {
|
||||
/**
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"browser": {
|
||||
"./client-reorder.js": "./client-reorder-browser.js",
|
||||
"./await-reorderer-tag.js": "./noop-render.js"
|
||||
"./reorderer-renderer.js": "./noop-render.js"
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
"use strict";
|
||||
var complain = "MARKO_DEBUG" && require("complain");
|
||||
var isClientReorderSupported = require("./client-reorder").isSupported;
|
||||
var AsyncValue = require("./AsyncValue");
|
||||
|
||||
@ -10,10 +11,17 @@ function safeRenderBody(renderBody, targetOut, data) {
|
||||
}
|
||||
}
|
||||
|
||||
function requestData(provider, args, thisObj, timeout) {
|
||||
function requestData(provider, timeout) {
|
||||
var asyncValue = new AsyncValue();
|
||||
|
||||
if (typeof provider === "function") {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
if ("MARKO_DEBUG") {
|
||||
complain(
|
||||
"Passing a callback function to the <await> tag has been deprecated, please use a promise instead."
|
||||
);
|
||||
}
|
||||
|
||||
var callback = function(err, data) {
|
||||
if (err) {
|
||||
asyncValue.___reject(err);
|
||||
@ -25,9 +33,9 @@ function requestData(provider, args, thisObj, timeout) {
|
||||
var value =
|
||||
provider.length === 1
|
||||
? // one argument so only provide callback to function call
|
||||
provider.call(thisObj, callback)
|
||||
provider(callback)
|
||||
: // two arguments so provide args and callback to function call
|
||||
provider.call(thisObj, args, callback);
|
||||
provider(null, callback);
|
||||
|
||||
if (value !== undefined) {
|
||||
asyncValue.___resolve(value);
|
||||
@ -46,6 +54,7 @@ function requestData(provider, args, thisObj, timeout) {
|
||||
timeoutId = null;
|
||||
var error = new Error("Timed out after " + timeout + "ms");
|
||||
error.code = "ERR_AWAIT_TIMEDOUT";
|
||||
error.name = "TimeoutError";
|
||||
asyncValue.___reject(error);
|
||||
}, timeout);
|
||||
|
||||
@ -62,22 +71,16 @@ function requestData(provider, args, thisObj, timeout) {
|
||||
const LAST_OPTIONS = { last: true, name: "await:finish" };
|
||||
|
||||
module.exports = function awaitTag(input, out) {
|
||||
var arg = input.arg || {};
|
||||
arg.out = out;
|
||||
|
||||
var clientReorder =
|
||||
isClientReorderSupported && input.clientReorder === true && !out.isVDOM;
|
||||
|
||||
var name = input.name || input._name;
|
||||
var scope = input.scope || this;
|
||||
var method = input.method;
|
||||
var timeout = input.timeout;
|
||||
var dataProvider = input._dataProvider;
|
||||
if (method) {
|
||||
dataProvider = dataProvider[method].bind(dataProvider);
|
||||
}
|
||||
|
||||
var asyncValue = requestData(dataProvider, arg, scope, timeout);
|
||||
var provider = input._provider;
|
||||
var asyncValue = requestData(provider, timeout);
|
||||
var placeholderRenderer = input.placeholder && input.placeholder.renderBody;
|
||||
var resultRenderer = input.then && input.then.renderBody;
|
||||
var errorRenderer = input.catch && input.catch.renderBody;
|
||||
|
||||
if (asyncValue.___settled) {
|
||||
// No point in using client-reordering if the data was fetched
|
||||
@ -91,7 +94,7 @@ module.exports = function awaitTag(input, out) {
|
||||
var awaitInfo = {
|
||||
name: name,
|
||||
clientReorder: clientReorder,
|
||||
dataProvider: dataProvider
|
||||
dataProvider: provider
|
||||
};
|
||||
|
||||
if (clientReorder) {
|
||||
@ -107,9 +110,9 @@ module.exports = function awaitTag(input, out) {
|
||||
var id = (awaitInfo.id = input.name || clientReorderContext.nextId++);
|
||||
var placeholderIdAttrValue = "afph" + id;
|
||||
|
||||
if (input.renderPlaceholder) {
|
||||
if (placeholderRenderer) {
|
||||
out.write('<span id="' + placeholderIdAttrValue + '">');
|
||||
input.renderPlaceholder(out);
|
||||
placeholderRenderer(out);
|
||||
out.write("</span>");
|
||||
} else {
|
||||
out.write(
|
||||
@ -173,26 +176,19 @@ module.exports = function awaitTag(input, out) {
|
||||
}
|
||||
|
||||
if (err) {
|
||||
if (err.code === "ERR_AWAIT_TIMEDOUT" && input.renderTimeout) {
|
||||
input.renderTimeout(asyncOut);
|
||||
} else if (input.renderError) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
"Await (" + name + ") failed. Error:",
|
||||
err.stack || err
|
||||
);
|
||||
input.renderError(asyncOut);
|
||||
if (errorRenderer) {
|
||||
errorRenderer(asyncOut, err);
|
||||
} else {
|
||||
asyncOut.error(err);
|
||||
}
|
||||
} else {
|
||||
var renderBodyFunc = input.renderBody;
|
||||
if (renderBodyFunc) {
|
||||
if (resultRenderer) {
|
||||
var renderBodyErr = safeRenderBody(
|
||||
renderBodyFunc,
|
||||
resultRenderer,
|
||||
asyncOut,
|
||||
data
|
||||
);
|
||||
|
||||
if (renderBodyErr) {
|
||||
return renderBody(renderBodyErr);
|
||||
}
|
||||
15
src/taglibs/core/await/transformer.js
Normal file
15
src/taglibs/core/await/transformer.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = function(elNode, context) {
|
||||
const builder = context.builder;
|
||||
const provider = elNode.argument;
|
||||
elNode.argument = undefined;
|
||||
|
||||
if (!provider) {
|
||||
context.addError(
|
||||
'You must provide a promise argument to the "<await>" tag, eg: "<await(promise)>".'
|
||||
);
|
||||
return elNode;
|
||||
}
|
||||
|
||||
elNode.setAttributeValue("_provider", builder.parseExpression(provider));
|
||||
elNode.setAttributeValue("_name", builder.literal(provider));
|
||||
};
|
||||
@ -166,6 +166,45 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"<await>": {
|
||||
"transformer": "./await/transformer",
|
||||
"renderer": "./await/renderer",
|
||||
"@_provider": "expression",
|
||||
"@_name": "string",
|
||||
"@timeout": "integer",
|
||||
"@name": {
|
||||
"type": "string",
|
||||
"description": "Name of await",
|
||||
"autocomplete": [
|
||||
{
|
||||
"snippet": "name=\"${1:name}\""
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"@client-reorder": {
|
||||
"type": "boolean",
|
||||
"description": "Use JavaScript on client to move async fragment into the proper place."
|
||||
},
|
||||
"@show-after": {
|
||||
"type": "string"
|
||||
},
|
||||
"autocomplete": [
|
||||
{
|
||||
"snippet": "await(${1:promise})",
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await><code>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"<await-reorderer>": {
|
||||
"renderer": "./await/reorderer-renderer",
|
||||
"autocomplete": [
|
||||
{
|
||||
"snippet": "await-reorderer",
|
||||
"descriptionMoreURL": "http://markojs.com/docs/marko/async-taglib/#<code><await-reorderer><code>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"<*>": {
|
||||
"@body-only-if": {
|
||||
"type": "statement",
|
||||
|
||||
@ -1,59 +1,49 @@
|
||||
const commonTagMigrator = require("./all-tags");
|
||||
const awaitTagMigration = require("./await-tag");
|
||||
const newTags = {
|
||||
"async-fragment": "await",
|
||||
"async-fragments": "await-reorderer",
|
||||
"async-fragment-placeholder": "await-placeholder",
|
||||
"async-fragment-timeout": "await-timeout",
|
||||
"async-fragment-error": "await-error"
|
||||
};
|
||||
module.exports = function migrator(oldNode, context) {
|
||||
const oldTag = oldNode.tagName;
|
||||
const newTag = newTags[oldTag];
|
||||
let provider;
|
||||
let varName;
|
||||
let argument;
|
||||
const attributes = oldNode.attributes;
|
||||
module.exports = function migrator(elNode, context) {
|
||||
const builder = context.builder;
|
||||
commonTagMigrator(oldNode, context);
|
||||
oldNode.setTransformerApplied(commonTagMigrator);
|
||||
const attributes = elNode.attributes;
|
||||
|
||||
context.deprecate(
|
||||
`The "<${oldTag}>" tag is deprecated. Please use "<${newTag}>" instead. See: https://github.com/marko-js/marko/wiki/Deprecation:-async-fragment`
|
||||
`The "<async-fragment>" tag is deprecated. Please use "<await>" instead. See: https://github.com/marko-js/marko/wiki/Deprecation:-async-fragment`
|
||||
);
|
||||
|
||||
if (oldTag == "async-fragment" /* new: <await> */) {
|
||||
if (!attributes || !attributes.length) {
|
||||
context.addError(
|
||||
'Invalid <aync-fragment> tag. Argument is missing. Example; <async-fragment data-provider=data.userInfo var="userInfo" />'
|
||||
);
|
||||
return oldNode;
|
||||
}
|
||||
|
||||
// need to convert data-provider and var attributes
|
||||
// to an argument: <await(var from dataProvider)>
|
||||
varName = oldNode.getAttributeValue("var").value;
|
||||
provider = oldNode.getAttributeValue("data-provider").toString();
|
||||
argument = varName + " from " + provider;
|
||||
|
||||
if (!context.util.isValidJavaScriptIdentifier(varName)) {
|
||||
context.addError(
|
||||
'Invalid <aync-fragment> tag. Argument\'s variable name should be a valid JavaScript identifier. Example: user, as in <async-fragment data-provider=data.userInfo var="userInfo" />'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
oldNode.removeAttribute("var");
|
||||
oldNode.removeAttribute("data-provider");
|
||||
if (!attributes || !attributes.length) {
|
||||
context.addError(
|
||||
'Invalid <async-fragment> tag. Argument is missing. Example; <async-fragment data-provider=data.userInfo var="userInfo" />'
|
||||
);
|
||||
return elNode;
|
||||
}
|
||||
|
||||
if (oldTag == "async-fragments" /* new: <await-reorderer> */) {
|
||||
// all this tag ever did was handling of client reordering
|
||||
// we'll remove the attribute as that's all this new tag does
|
||||
oldNode.removeAttribute("client-reorder");
|
||||
// need to convert data-provider and var attributes
|
||||
// to an argument: <await(var from dataProvider)>
|
||||
const varName = elNode.getAttributeValue("var").value;
|
||||
const provider = elNode.getAttributeValue("data-provider").toString();
|
||||
const argument = varName + " from " + provider;
|
||||
elNode.removeAttribute("var");
|
||||
elNode.removeAttribute("data-provider");
|
||||
|
||||
if (!context.util.isValidJavaScriptIdentifier(varName)) {
|
||||
context.addError(
|
||||
'Invalid <async-fragment> tag. Argument\'s variable name should be a valid JavaScript identifier. Example: user, as in <async-fragment data-provider=data.userInfo var="userInfo" />'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const newNode = builder.htmlElement(newTag, attributes, [], argument);
|
||||
elNode.forEachChild(child => {
|
||||
const newTag = newTags[child.tagName];
|
||||
if (newTag) {
|
||||
child.tagName = newTag;
|
||||
child.tagNameExpression = builder.literal(newTag);
|
||||
}
|
||||
});
|
||||
|
||||
oldNode.replaceWith(newNode);
|
||||
oldNode.moveChildrenTo(newNode);
|
||||
elNode.tagName = "await";
|
||||
elNode.tagNameExpression = builder.literal(elNode.tagName);
|
||||
elNode.argument = argument;
|
||||
awaitTagMigration(elNode, context);
|
||||
};
|
||||
|
||||
17
src/taglibs/migrate/async-fragments-tag.js
Normal file
17
src/taglibs/migrate/async-fragments-tag.js
Normal file
@ -0,0 +1,17 @@
|
||||
const commonTagMigrator = require("./all-tags");
|
||||
|
||||
module.exports = function migrator(elNode, context) {
|
||||
const builder = context.builder;
|
||||
commonTagMigrator(elNode, context);
|
||||
elNode.setTransformerApplied(commonTagMigrator);
|
||||
|
||||
context.deprecate(
|
||||
`The "<async-fragments>" tag is deprecated. Please use "<await-reorderer>" instead. See: https://github.com/marko-js/marko/wiki/Deprecation:-async-fragment`
|
||||
);
|
||||
|
||||
// all this tag ever did was handling of client reordering
|
||||
// we'll remove the attribute as that's all this new tag does
|
||||
elNode.removeAttribute("client-reorder");
|
||||
elNode.tagName = "await-reorderer";
|
||||
elNode.tagNameExpression = builder.literal(elNode.tagName);
|
||||
};
|
||||
235
src/taglibs/migrate/await-tag.js
Normal file
235
src/taglibs/migrate/await-tag.js
Normal file
@ -0,0 +1,235 @@
|
||||
const printJS = require("./util/printJS");
|
||||
|
||||
module.exports = function migrator(elNode, context) {
|
||||
const builder = context.builder;
|
||||
const argument = elNode.argument;
|
||||
const match =
|
||||
argument && /^([$A-Z_][0-9A-Z_$]*) from (.*)$/i.exec(argument);
|
||||
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.deprecate(
|
||||
'The "<await(result from promise)>" syntax has been deprecated, please use the modern syntax of "<await(promise)><@then|result|>". See: https://github.com/marko-js/marko/wiki/Deprecation:-async-tag'
|
||||
);
|
||||
|
||||
elNode.argument = undefined;
|
||||
let provider = builder.expression(match[2]);
|
||||
const varName = match[1];
|
||||
const methodExpression = elNode.getAttributeValue("method");
|
||||
const scopeExpression =
|
||||
elNode.getAttributeValue("scope") ||
|
||||
(methodExpression ? provider : null);
|
||||
const argAssignments = elNode.attributes
|
||||
.filter(attr => attr.name && attr.name.startsWith("arg-"))
|
||||
.map(attr => {
|
||||
elNode.removeAttribute(attr.name);
|
||||
return [attr.name.slice(4), attr.value];
|
||||
});
|
||||
let argExpression = elNode.getAttributeValue("arg");
|
||||
|
||||
elNode.removeAttribute("method");
|
||||
elNode.removeAttribute("scope");
|
||||
elNode.removeAttribute("arg");
|
||||
|
||||
if (methodExpression) {
|
||||
provider = builder.memberExpression(provider, methodExpression, true);
|
||||
}
|
||||
|
||||
if (argExpression) {
|
||||
if (argAssignments.length) {
|
||||
const argIdentifier = builder.identifier("arg");
|
||||
if (argExpression.type !== "ObjectExpression") {
|
||||
argExpression = builder.binaryExpression(
|
||||
argExpression,
|
||||
"||",
|
||||
builder.objectExpression([])
|
||||
);
|
||||
}
|
||||
|
||||
elNode.insertSiblingBefore(
|
||||
builder.scriptlet({
|
||||
value: printJS(
|
||||
builder.vars({
|
||||
arg: argExpression
|
||||
}),
|
||||
context
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
argAssignments.forEach(assignment => {
|
||||
elNode.insertSiblingBefore(
|
||||
builder.scriptlet({
|
||||
value: printJS(
|
||||
builder.assignment(
|
||||
builder.memberExpression(
|
||||
argIdentifier,
|
||||
builder.literal(assignment[0]),
|
||||
true
|
||||
),
|
||||
assignment[1],
|
||||
"="
|
||||
),
|
||||
context
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
argExpression = argIdentifier;
|
||||
}
|
||||
} else if (argAssignments.length) {
|
||||
argExpression = builder.objectExpression(
|
||||
argAssignments.reduce((obj, parts) => {
|
||||
obj[parts[0]] = parts[1];
|
||||
return obj;
|
||||
}, {})
|
||||
);
|
||||
}
|
||||
|
||||
if (argExpression || scopeExpression) {
|
||||
const callArgs = [scopeExpression || builder.literal(null)];
|
||||
if (argExpression) {
|
||||
callArgs.push(argExpression);
|
||||
}
|
||||
provider = builder.functionCall(
|
||||
builder.memberExpression(provider, builder.identifier("bind")),
|
||||
callArgs
|
||||
);
|
||||
}
|
||||
|
||||
elNode.argument = printJS(provider, context);
|
||||
|
||||
let placeholderBody;
|
||||
if (elNode.hasAttribute("placeholder")) {
|
||||
context.deprecate(
|
||||
'The "placeholder" attribute on the "<await>" tag is deprecated. Please use the "<@placeholder>" nested tag instead.'
|
||||
);
|
||||
|
||||
placeholderBody = [
|
||||
builder.text(elNode.getAttributeValue("placeholder"))
|
||||
];
|
||||
elNode.removeAttribute("placeholder");
|
||||
}
|
||||
|
||||
let timeoutBody;
|
||||
if (elNode.hasAttribute("timeout-message")) {
|
||||
context.deprecate(
|
||||
'The "timeout-message" attribute on the "<await>" tag is deprecated. Please use the "<@catch|err|>" nested tag instead with a check for "err.name === "TimeoutError".'
|
||||
);
|
||||
|
||||
timeoutBody = [
|
||||
builder.text(elNode.getAttributeValue("timeout-message"))
|
||||
];
|
||||
elNode.removeAttribute("timeout-message");
|
||||
}
|
||||
|
||||
let errorBody;
|
||||
if (elNode.hasAttribute("error-message")) {
|
||||
context.deprecate(
|
||||
'The "error-message" attribute on the "<await>" tag is deprecated. Please use the "<@catch>" nested tag instead.'
|
||||
);
|
||||
errorBody = [builder.text(elNode.getAttributeValue("error-message"))];
|
||||
elNode.removeAttribute("error-message");
|
||||
}
|
||||
|
||||
elNode.forEachChild(childNode => {
|
||||
if (childNode.type !== "HtmlElement") {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (childNode.tagName) {
|
||||
case "await-placeholder":
|
||||
placeholderBody = childNode.body;
|
||||
break;
|
||||
case "await-timeout":
|
||||
timeoutBody = childNode.body;
|
||||
break;
|
||||
case "await-error":
|
||||
errorBody = childNode.body;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
childNode.detach();
|
||||
});
|
||||
|
||||
const renderPlaceholderAttr = elNode.getAttributeValue("renderPlaceholder");
|
||||
const renderTimeoutAttr = elNode.getAttributeValue("renderTimeout");
|
||||
const renderErrorAttr = elNode.getAttributeValue("renderError");
|
||||
elNode.removeAttribute("renderPlaceholder");
|
||||
elNode.removeAttribute("renderTimeout");
|
||||
elNode.removeAttribute("renderError");
|
||||
|
||||
if (renderPlaceholderAttr && !placeholderBody) {
|
||||
context.deprecate(
|
||||
'The "renderPlaceholder" attribute on the "<await>" tag is deprecated and will be removed in a future version of Marko.'
|
||||
);
|
||||
placeholderBody = [buildDynamicTag(renderPlaceholderAttr, context)];
|
||||
}
|
||||
|
||||
if (renderTimeoutAttr && !timeoutBody) {
|
||||
context.deprecate(
|
||||
'The "renderTimeout" attribute on the "<await>" tag is deprecated and will be removed in a future version of Marko.'
|
||||
);
|
||||
timeoutBody = [buildDynamicTag(renderTimeoutAttr, context)];
|
||||
}
|
||||
|
||||
if (renderErrorAttr && !errorBody) {
|
||||
context.deprecate(
|
||||
'The "renderError" attribute on the "<await>" tag is deprecated and will be removed in a future version of Marko.'
|
||||
);
|
||||
errorBody = [buildDynamicTag(renderErrorAttr, context)];
|
||||
}
|
||||
|
||||
elNode._normalizeChildTextNodes(context);
|
||||
|
||||
if (elNode.body.length) {
|
||||
const thenNode = builder.htmlElement("@then");
|
||||
thenNode.params = [varName];
|
||||
elNode.moveChildrenTo(thenNode);
|
||||
elNode.appendChild(thenNode);
|
||||
}
|
||||
|
||||
if (placeholderBody) {
|
||||
elNode.appendChild(
|
||||
builder.htmlElement("@placeholder", undefined, placeholderBody)
|
||||
);
|
||||
}
|
||||
|
||||
if (timeoutBody) {
|
||||
const originalErrorBody = errorBody;
|
||||
errorBody = [
|
||||
builder.htmlElement(
|
||||
"if",
|
||||
undefined,
|
||||
timeoutBody,
|
||||
'err.name === "TimeoutError"'
|
||||
)
|
||||
];
|
||||
|
||||
if (originalErrorBody) {
|
||||
errorBody.push(
|
||||
builder.htmlElement("else", undefined, originalErrorBody)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (errorBody) {
|
||||
const catchNode = builder.htmlElement("@catch", undefined, errorBody);
|
||||
if (timeoutBody) {
|
||||
catchNode.params = ["err"];
|
||||
}
|
||||
|
||||
elNode.appendChild(catchNode);
|
||||
}
|
||||
};
|
||||
|
||||
function buildDynamicTag(expression, context) {
|
||||
const node = context.builder.htmlElement();
|
||||
node.rawTagNameExpression = printJS(expression, context);
|
||||
return node;
|
||||
}
|
||||
@ -117,19 +117,16 @@
|
||||
"deprecated": true
|
||||
},
|
||||
"<async-fragments>": {
|
||||
"migrator": "./async-fragment-tag",
|
||||
"migrator": "./async-fragments-tag",
|
||||
"deprecated": true
|
||||
},
|
||||
"<async-fragment-placeholder>": {
|
||||
"migrator": "./async-fragment-tag",
|
||||
"deprecated": true
|
||||
},
|
||||
"<async-fragment-timeout>": {
|
||||
"migrator": "./async-fragment-tag",
|
||||
"deprecated": true
|
||||
},
|
||||
"<async-fragment-error>": {
|
||||
"migrator": "./async-fragment-tag",
|
||||
"deprecated": true
|
||||
},
|
||||
"<include>": {
|
||||
@ -182,6 +179,18 @@
|
||||
"migrator": "./unless-tag",
|
||||
"deprecated": true
|
||||
},
|
||||
"<await>": {
|
||||
"migrator": "./await-tag"
|
||||
},
|
||||
"<await-placeholder>": {
|
||||
"deprecated": true
|
||||
},
|
||||
"<await-timeout>": {
|
||||
"deprecated": true
|
||||
},
|
||||
"<await-error>": {
|
||||
"deprecated": true
|
||||
},
|
||||
"<script>": {
|
||||
"@marko-init": "boolean",
|
||||
"@template-helpers": "boolean"
|
||||
|
||||
@ -5,22 +5,28 @@ var marko_template = module.exports = require("marko/src/html").t(__filename),
|
||||
components_helpers = require("marko/src/components/helpers"),
|
||||
marko_renderer = components_helpers.r,
|
||||
marko_defineComponent = components_helpers.c,
|
||||
hasRenderBodyKey = Symbol.for("hasRenderBody"),
|
||||
marko_helpers = require("marko/src/runtime/html/helpers"),
|
||||
marko_loadTag = marko_helpers.t,
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/async/await-tag"));
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/core/await/renderer"));
|
||||
|
||||
function render(input, out, __component, component, state) {
|
||||
var data = input;
|
||||
|
||||
await_tag({
|
||||
_dataProvider: data.userInfo,
|
||||
_provider: data.userInfo,
|
||||
_name: "data.userInfo",
|
||||
renderError: function renderBody(out) {
|
||||
out.w("something went wrong!");
|
||||
},
|
||||
renderBody: function renderBody(out, userInfo) {
|
||||
out.w("Success!");
|
||||
}
|
||||
then: {
|
||||
renderBody: function renderBody(out, userInfo) {
|
||||
out.w("Success!");
|
||||
}
|
||||
},
|
||||
catch: {
|
||||
renderBody: function renderBody(out) {
|
||||
out.w("something went wrong!");
|
||||
}
|
||||
},
|
||||
[hasRenderBodyKey]: true
|
||||
}, out, __component, "0");
|
||||
}
|
||||
|
||||
@ -34,6 +40,6 @@ marko_template.Component = marko_defineComponent({}, marko_template._);
|
||||
marko_template.meta = {
|
||||
id: "/marko-test$1.0.0/compiler/fixtures-html/async-fragment-error/template.marko",
|
||||
tags: [
|
||||
"marko/src/taglibs/async/await-tag"
|
||||
"marko/src/taglibs/core/await/renderer"
|
||||
]
|
||||
};
|
||||
|
||||
@ -7,7 +7,7 @@ exports.checkError = function(e) {
|
||||
expect(e.errors.length).to.equal(1);
|
||||
|
||||
var message = e.toString();
|
||||
expect(message).to.contain("Invalid <aync-fragment> tag");
|
||||
expect(message).to.contain("Invalid <async-fragment> tag");
|
||||
expect(message).to.contain("should be a valid JavaScript identifier");
|
||||
expect(message).to.contain(
|
||||
'<async-fragment data-provider=data.userInfo var="userInfo" />'
|
||||
|
||||
@ -7,7 +7,7 @@ exports.checkError = function(e) {
|
||||
expect(e.errors.length).to.equal(1);
|
||||
|
||||
var message = e.toString();
|
||||
expect(message).to.contain("Invalid <aync-fragment> tag");
|
||||
expect(message).to.contain("Invalid <async-fragment> tag");
|
||||
expect(message).to.contain("Argument is missing");
|
||||
expect(message).to.contain(
|
||||
'<async-fragment data-provider=data.userInfo var="userInfo" />'
|
||||
|
||||
@ -7,23 +7,29 @@ var marko_template = module.exports = require("marko/src/html").t(__filename),
|
||||
marko_defineComponent = components_helpers.c,
|
||||
marko_helpers = require("marko/src/runtime/html/helpers"),
|
||||
marko_escapeXml = marko_helpers.x,
|
||||
hasRenderBodyKey = Symbol.for("hasRenderBody"),
|
||||
marko_loadTag = marko_helpers.t,
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/async/await-tag"));
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/core/await/renderer"));
|
||||
|
||||
function render(input, out, __component, component, state) {
|
||||
var data = input;
|
||||
|
||||
await_tag({
|
||||
_dataProvider: data.userInfo,
|
||||
_provider: data.userInfo,
|
||||
_name: "data.userInfo",
|
||||
renderPlaceholder: function renderBody(out) {
|
||||
out.w("Loading name...");
|
||||
},
|
||||
renderBody: function renderBody(out, userInfo) {
|
||||
out.w("Hello " +
|
||||
marko_escapeXml(testData.name) +
|
||||
"!");
|
||||
}
|
||||
then: {
|
||||
renderBody: function renderBody(out, userInfo) {
|
||||
out.w("Hello " +
|
||||
marko_escapeXml(testData.name) +
|
||||
"!");
|
||||
}
|
||||
},
|
||||
placeholder: {
|
||||
renderBody: function renderBody(out) {
|
||||
out.w("Loading name...");
|
||||
}
|
||||
},
|
||||
[hasRenderBodyKey]: true
|
||||
}, out, __component, "0");
|
||||
}
|
||||
|
||||
@ -37,6 +43,6 @@ marko_template.Component = marko_defineComponent({}, marko_template._);
|
||||
marko_template.meta = {
|
||||
id: "/marko-test$1.0.0/compiler/fixtures-html/async-fragment-placeholder/template.marko",
|
||||
tags: [
|
||||
"marko/src/taglibs/async/await-tag"
|
||||
"marko/src/taglibs/core/await/renderer"
|
||||
]
|
||||
};
|
||||
|
||||
@ -5,9 +5,10 @@ var marko_template = module.exports = require("marko/src/html").t(__filename),
|
||||
components_helpers = require("marko/src/components/helpers"),
|
||||
marko_renderer = components_helpers.r,
|
||||
marko_defineComponent = components_helpers.c,
|
||||
hasRenderBodyKey = Symbol.for("hasRenderBody"),
|
||||
marko_helpers = require("marko/src/runtime/html/helpers"),
|
||||
marko_loadTag = marko_helpers.t,
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/async/await-tag"));
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/core/await/renderer"));
|
||||
|
||||
function render(input, out, __component, component, state) {
|
||||
var data = input;
|
||||
@ -15,13 +16,21 @@ function render(input, out, __component, component, state) {
|
||||
await_tag({
|
||||
timeout: 100,
|
||||
name: "userInfo4",
|
||||
_dataProvider: data.userInfo,
|
||||
renderTimeout: function renderBody(out) {
|
||||
out.w("Timeout has occurred!");
|
||||
},
|
||||
renderBody: function renderBody(out, userInfo) {
|
||||
out.w("4");
|
||||
}
|
||||
_provider: data.userInfo,
|
||||
_name: "data.userInfo",
|
||||
then: {
|
||||
renderBody: function renderBody(out, userInfo) {
|
||||
out.w("4");
|
||||
}
|
||||
},
|
||||
catch: {
|
||||
renderBody: function renderBody(out, err) {
|
||||
if (err.name === "TimeoutError") {
|
||||
out.w("Timeout has occurred!");
|
||||
}
|
||||
}
|
||||
},
|
||||
[hasRenderBodyKey]: true
|
||||
}, out, __component, "0");
|
||||
}
|
||||
|
||||
@ -35,6 +44,6 @@ marko_template.Component = marko_defineComponent({}, marko_template._);
|
||||
marko_template.meta = {
|
||||
id: "/marko-test$1.0.0/compiler/fixtures-html/async-fragment-timeout/template.marko",
|
||||
tags: [
|
||||
"marko/src/taglibs/async/await-tag"
|
||||
"marko/src/taglibs/core/await/renderer"
|
||||
]
|
||||
};
|
||||
|
||||
@ -7,13 +7,13 @@ var marko_template = module.exports = require("marko/src/html").t(__filename),
|
||||
marko_defineComponent = components_helpers.c,
|
||||
marko_helpers = require("marko/src/runtime/html/helpers"),
|
||||
marko_loadTag = marko_helpers.t,
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/async/await-tag"));
|
||||
await_tag = marko_loadTag(require("marko/src/taglibs/core/await/renderer"));
|
||||
|
||||
function render(input, out, __component, component, state) {
|
||||
var data = input;
|
||||
|
||||
await_tag({
|
||||
_dataProvider: data.userInfo,
|
||||
_provider: data.userInfo,
|
||||
_name: "data.userInfo"
|
||||
}, out, __component, "0");
|
||||
}
|
||||
@ -28,6 +28,6 @@ marko_template.Component = marko_defineComponent({}, marko_template._);
|
||||
marko_template.meta = {
|
||||
id: "/marko-test$1.0.0/compiler/fixtures-html/async-fragment/template.marko",
|
||||
tags: [
|
||||
"marko/src/taglibs/async/await-tag"
|
||||
"marko/src/taglibs/core/await/renderer"
|
||||
]
|
||||
};
|
||||
|
||||
@ -7,7 +7,7 @@ var marko_template = module.exports = require("marko/src/html").t(__filename),
|
||||
marko_defineComponent = components_helpers.c,
|
||||
marko_helpers = require("marko/src/runtime/html/helpers"),
|
||||
marko_loadTag = marko_helpers.t,
|
||||
await_reorderer_tag = marko_loadTag(require("marko/src/taglibs/async/await-reorderer-tag"));
|
||||
await_reorderer_tag = marko_loadTag(require("marko/src/taglibs/core/await/reorderer-renderer"));
|
||||
|
||||
function render(input, out, __component, component, state) {
|
||||
var data = input;
|
||||
@ -25,6 +25,6 @@ marko_template.Component = marko_defineComponent({}, marko_template._);
|
||||
marko_template.meta = {
|
||||
id: "/marko-test$1.0.0/compiler/fixtures-html/async-fragments/template.marko",
|
||||
tags: [
|
||||
"marko/src/taglibs/async/await-reorderer-tag"
|
||||
"marko/src/taglibs/core/await/reorderer-renderer"
|
||||
]
|
||||
};
|
||||
|
||||
@ -13,7 +13,7 @@ var marko_template = module.exports = require("marko/src/vdom").t(__filename),
|
||||
marko_loadTag = marko_helpers.t,
|
||||
component_globals_tag = marko_loadTag(require("marko/src/components/taglib/component-globals-tag")),
|
||||
init_components_tag = marko_loadTag(require("marko/src/components/taglib/init-components-tag")),
|
||||
await_reorderer_tag = marko_loadTag(require("marko/src/taglibs/async/await-reorderer-tag")),
|
||||
await_reorderer_tag = marko_loadTag(require("marko/src/taglibs/core/await/reorderer-renderer")),
|
||||
marko_createElement = marko_helpers.e,
|
||||
marko_const = marko_helpers.const,
|
||||
marko_const_nextId = marko_const("5b1bc3"),
|
||||
@ -61,6 +61,6 @@ marko_template.meta = {
|
||||
tags: [
|
||||
"marko/src/components/taglib/component-globals-tag",
|
||||
"marko/src/components/taglib/init-components-tag",
|
||||
"marko/src/taglibs/async/await-reorderer-tag"
|
||||
"marko/src/taglibs/core/await/reorderer-renderer"
|
||||
]
|
||||
};
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
<!-- test/migrate/fixtures/async-fragment-tag/template.marko -->
|
||||
|
||||
<await(userInfo from data.userInfo)>
|
||||
Success!
|
||||
<await-placeholder>loading...</await-placeholder>
|
||||
<await-timeout>took too long!</await-timeout>
|
||||
<await-error>something went wrong!</await-error>
|
||||
<await(data.userInfo)>
|
||||
<@then|userInfo|>Success!</@then>
|
||||
<@placeholder>loading...</@placeholder>
|
||||
<@catch|err|>
|
||||
<if(err.name === "TimeoutError")>took too long!</if>
|
||||
<else>something went wrong!</else>
|
||||
</@catch>
|
||||
</await>
|
||||
<await-reorderer/>
|
||||
|
||||
@ -10,4 +10,6 @@
|
||||
<async-fragment-error>
|
||||
something went wrong!
|
||||
</async-fragment-error>
|
||||
</async-fragment>
|
||||
</async-fragment>
|
||||
|
||||
<async-fragments client-reorder=true/>
|
||||
@ -0,0 +1,90 @@
|
||||
<!-- test/migrate/fixtures/legacy-await-syntax/template.marko -->
|
||||
|
||||
<await(getUserInfo())>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
<await(getUserInfo())>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
<@placeholder>
|
||||
<${renderPlaceholderFn}/>
|
||||
</@placeholder>
|
||||
<@catch>
|
||||
<${renderErrorFn}/>
|
||||
</@catch>
|
||||
</await>
|
||||
<await(getUserInfo())>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
<@placeholder>
|
||||
<${renderPlaceholderFn}/>
|
||||
</@placeholder>
|
||||
<@catch|err|>
|
||||
<if(err.name === "TimeoutError")>
|
||||
<${renderTimeoutFn}/>
|
||||
</if>
|
||||
<else>
|
||||
<${renderErrorFn}/>
|
||||
</else>
|
||||
</@catch>
|
||||
</await>
|
||||
<await(getUserInfo())>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
<@placeholder>Placeholder Attr</@placeholder>
|
||||
<@catch|err|>
|
||||
<if(err.name === "TimeoutError")>Timeout Message Attr</if>
|
||||
<else>Error Message Attr</else>
|
||||
</@catch>
|
||||
</await>
|
||||
<await(getUserInfo())>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
<@placeholder>nested placeholder</@placeholder>
|
||||
<@catch|err|>
|
||||
<if(err.name === "TimeoutError")>nested timeout</if>
|
||||
<else>nested error</else>
|
||||
</@catch>
|
||||
</await>
|
||||
<await(getters["user"].bind(getters))>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
<await(
|
||||
getters.bind(null, {
|
||||
hello: "world"
|
||||
})
|
||||
)>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
<await(getters.bind(null, something))>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
$ var arg = {
|
||||
hello: "world"
|
||||
};
|
||||
$ arg["x"] = 1;
|
||||
$ arg["y"] = 2;
|
||||
<await(getters.bind(null, arg))>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
$ var arg = something || {};
|
||||
$ arg["x"] = 1;
|
||||
$ arg["y"] = 2;
|
||||
<await(getters.bind(null, arg))>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
<await(
|
||||
getters.bind(null, {
|
||||
x: 1,
|
||||
y: 2
|
||||
})
|
||||
)>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
<await(getters.bind(window))>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
$ var arg = {
|
||||
data: true
|
||||
};
|
||||
$ arg["x"] = 1;
|
||||
$ arg["y"] = 2;
|
||||
<await(getters["user"].bind(window, arg))>
|
||||
<@then|user|>Hello ${user.name}</@then>
|
||||
</await>
|
||||
54
test/migrate/fixtures/legacy-await-syntax/template.marko
Normal file
54
test/migrate/fixtures/legacy-await-syntax/template.marko
Normal file
@ -0,0 +1,54 @@
|
||||
<await(user from getUserInfo())>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getUserInfo()) renderPlaceholder=renderPlaceholderFn renderError=renderErrorFn>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getUserInfo()) renderPlaceholder=renderPlaceholderFn renderError=renderErrorFn renderTimeout=renderTimeoutFn>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getUserInfo()) renderPlaceholder=renderPlaceholderFn placeholder="Placeholder Attr" renderError=renderErrorFn error-message="Error Message Attr" renderTimeout=renderTimeoutFn timeout-message="Timeout Message Attr">
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getUserInfo()) renderPlaceholder=renderPlaceholderFn placeholder="Placeholder Attr" renderError=renderErrorFn error-message="Error Message Attr" renderTimeout=renderTimeoutFn timeout-message="Timeout Message Attr">
|
||||
Hello ${user.name}
|
||||
<await-placeholder>nested placeholder</await-placeholder>
|
||||
<await-timeout>nested timeout</await-timeout>
|
||||
<await-error>nested error</await-error>
|
||||
</await>
|
||||
|
||||
<await(user from getters) method="user">
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getters) arg={ hello: "world" }>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getters) arg=something>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getters) arg={ hello: "world" } arg-x=1 arg-y=2>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getters) arg=something arg-x=1 arg-y=2>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getters) arg-x=1 arg-y=2>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getters) scope=window>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
|
||||
<await(user from getters) method="user" arg={ data: true } arg-x=1 arg-y=2 scope=window>
|
||||
Hello ${user.name}
|
||||
</await>
|
||||
@ -33,7 +33,8 @@
|
||||
"name": "userInfo1",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -43,7 +44,8 @@
|
||||
"name": "userInfo1",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
@ -54,7 +56,8 @@
|
||||
"name": "userInfo2",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -64,7 +67,8 @@
|
||||
"name": "userInfo2",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
@ -75,7 +79,8 @@
|
||||
"name": "userInfo3",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -85,7 +90,8 @@
|
||||
"name": "userInfo3",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
@ -96,7 +102,8 @@
|
||||
"name": "userInfo4",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -106,7 +113,8 @@
|
||||
"name": "userInfo4",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
|
||||
@ -33,7 +33,8 @@
|
||||
"name": "userInfo1",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -43,7 +44,8 @@
|
||||
"name": "userInfo1",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
@ -54,7 +56,8 @@
|
||||
"name": "userInfo2",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -64,7 +67,8 @@
|
||||
"name": "userInfo2",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
@ -75,7 +79,8 @@
|
||||
"name": "userInfo3",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -85,7 +90,8 @@
|
||||
"name": "userInfo3",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
@ -96,7 +102,8 @@
|
||||
"name": "userInfo4",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -106,9 +113,10 @@
|
||||
"name": "userInfo4",
|
||||
"clientReorder": false,
|
||||
"error": {
|
||||
"code": "ERR_AWAIT_TIMEDOUT"
|
||||
"code": "ERR_AWAIT_TIMEDOUT",
|
||||
"name": "TimeoutError"
|
||||
},
|
||||
"finished": true
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
@ -1 +1 @@
|
||||
<html><body><!--FLUSH--><div class="inner"><div class="inner-inner"><!--M^s0-6 s0 6--><div>Hello inner-inner</div><!--M/--></div><!--M^s0-7 s0 7--><div>Hello inner</div><!--M/--></div><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-6",0,{"name":"inner-inner"},{"f":1}],["s0-7",0,{"name":"inner"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await-beginAsync/components/hello/index.marko"]})||w.$components})()</script><!--M^s0-8 s0 8--><div>Hello outer</div><!--M/--><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-8",0,{"name":"outer"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await-beginAsync/components/hello/index.marko"]})||w.$components})()</script><!--FLUSH--></body></html>
|
||||
<html><body><!--FLUSH--><div class="inner"><div class="inner-inner"><!--M^s0-7 s0 7--><div>Hello inner-inner</div><!--M/--></div><!--M^s0-8 s0 8--><div>Hello inner</div><!--M/--></div><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-7",0,{"name":"inner-inner"},{"f":1}],["s0-8",0,{"name":"inner"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await-beginAsync/components/hello/index.marko"]})||w.$components})()</script><!--M^s0-9 s0 9--><div>Hello outer</div><!--M/--><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-9",0,{"name":"outer"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await-beginAsync/components/hello/index.marko"]})||w.$components})()</script><!--FLUSH--></body></html>
|
||||
@ -1 +1 @@
|
||||
<html><head><title><!--FLUSH-->Welcome Frank</title></head><body><!--M^s0-0-5-4 s0 4--><div>Hello</div><!--M/--><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-0-5-4",0,{},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await-title/components/hello/index.marko"]})||w.$components})()</script><!--FLUSH--></body></html>
|
||||
<html><head><title><!--FLUSH-->Welcome Frank</title></head><body><!--M^s0-0-5-5 s0 5--><div>Hello</div><!--M/--><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-0-5-5",0,{},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await-title/components/hello/index.marko"]})||w.$components})()</script><!--FLUSH--></body></html>
|
||||
@ -1 +1 @@
|
||||
<html><body><!--FLUSH--><div class="inner"><div class="inner-inner"><!--M^s0-6 s0 6--><div>Hello inner-inner</div><!--M/--></div><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-6",0,{"name":"inner-inner"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await/components/hello/index.marko"]})||w.$components})()</script><!--M^s0-7 s0 7--><div>Hello inner</div><!--M/--></div><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-7",0,{"name":"inner"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await/components/hello/index.marko"]})||w.$components})()</script><!--M^s0-8 s0 8--><div>Hello outer</div><!--M/--><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-8",0,{"name":"outer"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await/components/hello/index.marko"]})||w.$components})()</script><!--FLUSH--></body></html>
|
||||
<html><body><!--FLUSH--><div class="inner"><div class="inner-inner"><!--M^s0-8 s0 8--><div>Hello inner-inner</div><!--M/--></div><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-8",0,{"name":"inner-inner"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await/components/hello/index.marko"]})||w.$components})()</script><!--M^s0-9 s0 9--><div>Hello inner</div><!--M/--></div><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-9",0,{"name":"inner"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await/components/hello/index.marko"]})||w.$components})()</script><!--M^s0-10 s0 10--><div>Hello outer</div><!--M/--><script>(function(){var w=window;w.$components=(w.$components||[]).concat({"r":"M","w":[["s0-10",0,{"name":"outer"},{"f":1}]],"t":["/marko-test$1.0.0/render/fixtures-async/components-await/components/hello/index.marko"]})||w.$components})()</script><!--FLUSH--></body></html>
|
||||
@ -16,6 +16,10 @@
|
||||
"layout-use",
|
||||
"layout-placeholder",
|
||||
"unless",
|
||||
"await",
|
||||
"await-placeholder",
|
||||
"await-timeout",
|
||||
"await-error",
|
||||
"script",
|
||||
"class",
|
||||
"else",
|
||||
@ -32,6 +36,7 @@
|
||||
"module-code",
|
||||
"static",
|
||||
"while",
|
||||
"await-reorderer",
|
||||
"html-comment",
|
||||
"a",
|
||||
"abbr",
|
||||
@ -227,11 +232,6 @@
|
||||
"use",
|
||||
"view",
|
||||
"vkern",
|
||||
"await",
|
||||
"await-reorderer",
|
||||
"await-placeholder",
|
||||
"await-timeout",
|
||||
"await-error",
|
||||
"cached-fragment",
|
||||
"_component",
|
||||
"component-globals",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user