mirror of
https://gitlab.com/nightlycommit/twing.git
synced 2025-01-18 08:46:50 +02:00
Clean TwingNode API
This commit is contained in:
parent
c94bd15a47
commit
2aaf14c6da
28
src/lib.ts
28
src/lib.ts
@ -46,6 +46,7 @@ export type {
|
||||
export type {TwingApplyNode, TwingApplyNodeAttributes, TwingApplyNodeChildren} from "./lib/node/apply";
|
||||
export type {TwingAutoEscapeNode, TwingAutoEscapeNodeAttributes} from "./lib/node/auto-escape";
|
||||
export type {TwingBlockNode, TwingBlockNodeAttributes} from "./lib/node/block";
|
||||
export type {TwingBlockReferenceNode, TwingBlockReferenceNodeAttributes} from "./lib/node/block-reference";
|
||||
export type {TwingBodyNode} from "./lib/node/body";
|
||||
export type {TwingCheckSecurityNode, TwingCheckSecurityNodeAttributes} from "./lib/node/check-security";
|
||||
export type {TwingCheckToStringNode} from "./lib/node/check-to-string";
|
||||
@ -65,17 +66,21 @@ export type {
|
||||
} from "./lib/node/include";
|
||||
export type {TwingLineNode, TwingLineNodeAttributes} from "./lib/node/line";
|
||||
export type {TwingMacroNode, TwingMacroNodeAttributes} from "./lib/node/macro";
|
||||
export type {TwingBaseOutputNode} from "./lib/node/output";
|
||||
export type {TwingTemplateNode, TwingTemplateNodeAttributes, TwingTemplateNodeChildren} from "./lib/node/template";
|
||||
export type {TwingPrintNode} from "./lib/node/print";
|
||||
export type {TwingSandboxNode} from "./lib/node/sandbox";
|
||||
export type {TwingSpacelessNode} from "./lib/node/spaceless";
|
||||
export type {TwingTemplateNode, TwingTemplateNodeAttributes, TwingTemplateNodeChildren} from "./lib/node/template";
|
||||
export type {TwingSetNode, TwingSetNodeAttributes} from "./lib/node/set";
|
||||
export type {TwingTextNode, TwingBaseTextNode, TwingBaseTextNodeAttributes} from "./lib/node/text";
|
||||
export type {TwingTraitNode} from "./lib/node/trait";
|
||||
export type {TwingVerbatimNode} from "./lib/node/verbatim";
|
||||
export type {TwingWithNode, TwingWithNodeAttributes, TwingWithNodeChildren} from "./lib/node/with";
|
||||
export type {TwingWrapperNode, TwingWrapperNodeChildren} from "./lib/node/wrapper";
|
||||
|
||||
export {createApplyNode} from "./lib/node/apply";
|
||||
export {createAutoEscapeNode} from "./lib/node/auto-escape";
|
||||
export {createBlockNode} from "./lib/node/block";
|
||||
export {createBlockReferenceNode} from "./lib/node/block-reference";
|
||||
export {createBodyNode} from "./lib/node/body";
|
||||
export {createCheckSecurityNode} from "./lib/node/check-security";
|
||||
export {createCheckToStringNode} from "./lib/node/check-to-string";
|
||||
@ -90,10 +95,14 @@ export {createImportNode} from "./lib/node/import";
|
||||
export {createBaseIncludeNode} from "./lib/node/include";
|
||||
export {createLineNode} from "./lib/node/line";
|
||||
export {createMacroNode} from "./lib/node/macro";
|
||||
export {createTemplateNode} from "./lib/node/template";
|
||||
export {createPrintNode} from "./lib/node/print";
|
||||
export {createSandboxNode} from "./lib/node/sandbox";
|
||||
export {createSetNode} from "./lib/node/set";
|
||||
export {createSpacelessNode} from "./lib/node/spaceless";
|
||||
export {createTemplateNode} from "./lib/node/template";
|
||||
export {createTextNode} from "./lib/node/text";
|
||||
export {createTraitNode} from "./lib/node/trait";
|
||||
export {createVerbatimNode} from "./lib/node/verbatim";
|
||||
export {createWithNode} from "./lib/node/with";
|
||||
export {createWrapperNode} from "./lib/node/wrapper";
|
||||
|
||||
@ -228,19 +237,6 @@ export type {TwingIncludeNode, TwingIncludeNodeChildren} from "./lib/node/includ
|
||||
export {createEmbedNode} from "./lib/node/include/embed";
|
||||
export {createIncludeNode} from "./lib/node/include/include";
|
||||
|
||||
// node/output
|
||||
export type {TwingBlockReferenceNode, TwingBlockReferenceNodeAttributes} from "./lib/node/output/block-reference";
|
||||
export type {TwingPrintNode} from "./lib/node/output/print";
|
||||
export type {TwingSpacelessNode} from "./lib/node/output/spaceless";
|
||||
export type {TwingTextNode, TwingBaseTextNode, TwingBaseTextNodeAttributes} from "./lib/node/output/text";
|
||||
export type {TwingVerbatimNode} from "./lib/node/output/verbatim";
|
||||
|
||||
export {createBlockReferenceNode} from "./lib/node/output/block-reference";
|
||||
export {createPrintNode} from "./lib/node/output/print";
|
||||
export {createSpacelessNode} from "./lib/node/output/spaceless";
|
||||
export {createTextNode} from "./lib/node/output/text";
|
||||
export {createVerbatimNode} from "./lib/node/output/verbatim";
|
||||
|
||||
// tag handlers
|
||||
export type {TwingTagHandler, TwingTokenParser} from "./lib/tag-handler";
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {TwingBaseNode, TwingNode} from "../node";
|
||||
import {createPrintNode, TwingPrintNode} from "../node/output/print";
|
||||
import {createPrintNode, TwingPrintNode} from "../node/print";
|
||||
import {createDoNode} from "../node/do";
|
||||
import {createConditionalNode, TwingConditionalNode} from "../node/expression/conditional";
|
||||
import {createEscapeNode, TwingEscapeNode} from "../node/expression/escape";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type {TwingExpressionNode} from "./node/expression";
|
||||
import type {TwingPrintNode} from "./node/output/print";
|
||||
import type {TwingBlockReferenceNode} from "./node/output/block-reference";
|
||||
import type {TwingTextNode} from "./node/output/text";
|
||||
import type {TwingPrintNode} from "./node/print";
|
||||
import type {TwingBlockReferenceNode} from "./node/block-reference";
|
||||
import type {TwingTextNode} from "./node/text";
|
||||
import type {TwingAutoEscapeNode} from "./node/auto-escape";
|
||||
import type {TwingBodyNode} from "./node/body";
|
||||
import type {TwingCheckSecurityNode} from "./node/check-security";
|
||||
@ -21,9 +21,9 @@ import type {TwingTemplateNode} from "./node/template";
|
||||
import type {TwingBlockNode} from "./node/block";
|
||||
import type {TwingTraitNode} from "./node/trait";
|
||||
import type {TwingSetNode} from "./node/set";
|
||||
import type {TwingVerbatimNode} from "./node/output/verbatim";
|
||||
import type {TwingVerbatimNode} from "./node/verbatim";
|
||||
import type {TwingSandboxNode} from "./node/sandbox";
|
||||
import type {TwingSpacelessNode} from "./node/output/spaceless";
|
||||
import type {TwingSpacelessNode} from "./node/spaceless";
|
||||
import type {TwingWithNode} from "./node/with";
|
||||
import type {TwingIfNode} from "./node/if";
|
||||
import type {TwingMethodCallNode} from "./node/expression/method-call";
|
||||
@ -82,8 +82,6 @@ export interface TwingBaseNode<
|
||||
readonly attributes: Attributes;
|
||||
readonly children: Children;
|
||||
readonly column: number;
|
||||
readonly isACaptureNode: boolean;
|
||||
readonly isAnOutputNode: boolean;
|
||||
readonly line: number;
|
||||
readonly tag: string | null;
|
||||
readonly type: Type;
|
||||
@ -123,8 +121,7 @@ export const createBaseNode = <
|
||||
column,
|
||||
line,
|
||||
tag,
|
||||
isACaptureNode: false,
|
||||
isAnOutputNode: false,
|
||||
type,
|
||||
execute: async (executionContext) => {
|
||||
const output: Array<any> = [];
|
||||
|
||||
@ -133,7 +130,6 @@ export const createBaseNode = <
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
type
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,12 +1,11 @@
|
||||
import {TwingBaseNodeAttributes} from "../../node";
|
||||
import {TwingBaseOutputNode, createBaseOutputNode} from "../output";
|
||||
import {getTraceableMethod} from "../../helpers/traceable-method";
|
||||
import {createBaseNode, TwingBaseNode, TwingBaseNodeAttributes} from "../node";
|
||||
import {getTraceableMethod} from "../helpers/traceable-method";
|
||||
|
||||
export type TwingBlockReferenceNodeAttributes = TwingBaseNodeAttributes & {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export interface TwingBlockReferenceNode extends TwingBaseOutputNode<"block_reference", TwingBlockReferenceNodeAttributes, {}> {
|
||||
export interface TwingBlockReferenceNode extends TwingBaseNode<"block_reference", TwingBlockReferenceNodeAttributes, {}> {
|
||||
}
|
||||
|
||||
export const createBlockReferenceNode = (
|
||||
@ -15,7 +14,7 @@ export const createBlockReferenceNode = (
|
||||
column: number,
|
||||
tag: string
|
||||
): TwingBlockReferenceNode => {
|
||||
const outputNode = createBaseOutputNode("block_reference", {
|
||||
const outputNode = createBaseNode("block_reference", {
|
||||
name
|
||||
}, {}, line, column, tag);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {TwingBaseNodeAttributes} from "../../node";
|
||||
import {TwingBaseNodeAttributes, TwingBaseNode} from "../../node";
|
||||
import {TwingBaseExpressionNode, createBaseExpressionNode} from "../expression";
|
||||
import {TwingBaseOutputNode} from "../output";
|
||||
import {getTraceableMethod} from "../../helpers/traceable-method";
|
||||
|
||||
export interface TwingEscapeNodeAttributes extends TwingBaseNodeAttributes {
|
||||
@ -8,12 +7,12 @@ export interface TwingEscapeNodeAttributes extends TwingBaseNodeAttributes {
|
||||
}
|
||||
|
||||
export interface TwingEscapeNode extends TwingBaseExpressionNode<"escape", TwingEscapeNodeAttributes, {
|
||||
body: TwingBaseOutputNode<any>;
|
||||
body: TwingBaseNode;
|
||||
}> {
|
||||
}
|
||||
|
||||
export const createEscapeNode = (
|
||||
body: TwingBaseOutputNode<any>,
|
||||
body: TwingBaseNode,
|
||||
strategy: string
|
||||
): TwingEscapeNode => {
|
||||
const baseNode = createBaseExpressionNode("escape", {
|
||||
|
@ -1,25 +0,0 @@
|
||||
import {TwingBaseNode, TwingBaseNodeAttributes, TwingBaseNodeChildren, createBaseNode} from "../node";
|
||||
|
||||
export interface TwingBaseOutputNode<
|
||||
Type extends string,
|
||||
Attributes extends TwingBaseNodeAttributes = TwingBaseNodeAttributes,
|
||||
Children extends TwingBaseNodeChildren = TwingBaseNodeChildren
|
||||
> extends TwingBaseNode<Type, Attributes, Children> {
|
||||
|
||||
}
|
||||
|
||||
export const createBaseOutputNode = <Type extends string, Attributes extends TwingBaseNodeAttributes, Children extends TwingBaseNodeChildren>(
|
||||
type: Type,
|
||||
attributes: Attributes,
|
||||
children: Children,
|
||||
line: number,
|
||||
column: number,
|
||||
tag: string | null
|
||||
): TwingBaseOutputNode<Type, Attributes, Children> => {
|
||||
const baseNode = createBaseNode(type, attributes, children, line, column, tag);
|
||||
|
||||
return {
|
||||
...baseNode,
|
||||
isAnOutputNode: true
|
||||
};
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
import {TwingBaseOutputNode, createBaseOutputNode} from "../output";
|
||||
import {TwingBaseExpressionNode} from "../expression";
|
||||
import {TwingBaseExpressionNode} from "./expression";
|
||||
import {createBaseNode, TwingBaseNode} from "../node";
|
||||
|
||||
export interface TwingPrintNode extends TwingBaseOutputNode<"print", {}, {
|
||||
export interface TwingPrintNode extends TwingBaseNode<"print", {}, {
|
||||
expression: TwingBaseExpressionNode;
|
||||
}> {
|
||||
}
|
||||
@ -11,7 +11,7 @@ export const createPrintNode = (
|
||||
line: number,
|
||||
column: number
|
||||
): TwingPrintNode => {
|
||||
const outputNode: TwingPrintNode = createBaseOutputNode("print", {}, {
|
||||
const outputNode: TwingPrintNode = createBaseNode("print", {}, {
|
||||
expression: expression
|
||||
}, line, column, null);
|
||||
|
@ -76,8 +76,7 @@ export const createSetNode = (
|
||||
index++;
|
||||
}
|
||||
}
|
||||
},
|
||||
isACaptureNode: true
|
||||
}
|
||||
};
|
||||
|
||||
return setNode;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import {TwingBaseNode, TwingBaseNodeAttributes} from "../../node";
|
||||
import {TwingBaseOutputNode, createBaseOutputNode} from "../output";
|
||||
import {TwingBaseNode, TwingBaseNodeAttributes, createBaseNode} from "../node";
|
||||
|
||||
export interface TwingSpacelessNode extends TwingBaseOutputNode<"spaceless", TwingBaseNodeAttributes, {
|
||||
export interface TwingSpacelessNode extends TwingBaseNode<"spaceless", TwingBaseNodeAttributes, {
|
||||
body: TwingBaseNode;
|
||||
}> {
|
||||
}
|
||||
@ -12,7 +11,7 @@ export const createSpacelessNode = (
|
||||
column: number,
|
||||
tag: string
|
||||
): TwingSpacelessNode => {
|
||||
const baseNode = createBaseOutputNode("spaceless", {}, {
|
||||
const baseNode = createBaseNode("spaceless", {}, {
|
||||
body
|
||||
}, line, column, tag);
|
||||
|
@ -1,11 +1,10 @@
|
||||
import {TwingBaseNodeAttributes} from "../../node";
|
||||
import {TwingBaseOutputNode, createBaseOutputNode} from "../output";
|
||||
import {createBaseNode, TwingBaseNodeAttributes, TwingBaseNode} from "../node";
|
||||
|
||||
export type TwingBaseTextNodeAttributes = TwingBaseNodeAttributes & {
|
||||
data: string;
|
||||
};
|
||||
|
||||
export interface TwingBaseTextNode<Type extends string> extends TwingBaseOutputNode<Type, TwingBaseTextNodeAttributes> {
|
||||
export interface TwingBaseTextNode<Type extends string> extends TwingBaseNode<Type, TwingBaseTextNodeAttributes> {
|
||||
}
|
||||
|
||||
export interface TwingTextNode extends TwingBaseTextNode<"text"> {
|
||||
@ -18,7 +17,7 @@ export const createBaseTextNode = <Type extends string>(
|
||||
column: number,
|
||||
tag: string | null = null
|
||||
): TwingBaseTextNode<Type> => {
|
||||
const outputNode = createBaseOutputNode(type, {
|
||||
const outputNode = createBaseNode(type, {
|
||||
data
|
||||
}, {}, line, column, tag);
|
||||
|
@ -3,8 +3,8 @@ import {TwingTagHandler, TwingTokenParser} from "./tag-handler";
|
||||
import {TwingNodeVisitor} from "./node-visitor";
|
||||
import {createParsingError, TwingParsingError} from "./error/parsing";
|
||||
import {TwingBaseNode, createBaseNode, getChildren, TwingNode} from "./node";
|
||||
import {createTextNode} from "./node/output/text";
|
||||
import {createPrintNode} from "./node/output/print";
|
||||
import {createTextNode} from "./node/text";
|
||||
import {createPrintNode} from "./node/print";
|
||||
import {TwingBaseExpressionNode, TwingExpressionNode} from "./node/expression";
|
||||
import {createBodyNode} from "./node/body";
|
||||
import {createTemplateNode, TwingTemplateNode} from "./node/template";
|
||||
@ -265,10 +265,10 @@ export const createParser = (
|
||||
// checks that the node only contains "constant" elements
|
||||
const checkConstantExpression = (stackEntry: TwingTokenStream, node: TwingBaseNode): TwingBaseNode | null => {
|
||||
if (!(
|
||||
(node as TwingNode).type === "constant"
|
||||
|| (node as TwingNode).type === "array"
|
||||
|| (node as TwingNode).type === "hash"
|
||||
|| (node as TwingNode).type === "negative"
|
||||
(node as TwingNode).type === "constant"
|
||||
|| (node as TwingNode).type === "array"
|
||||
|| (node as TwingNode).type === "hash"
|
||||
|| (node as TwingNode).type === "negative"
|
||||
|| (node as TwingNode).type === "positive"
|
||||
)) {
|
||||
return node;
|
||||
@ -292,7 +292,7 @@ export const createParser = (
|
||||
const filterChildBodyNode = (stream: TwingTokenStream, node: TwingBaseNode, nested: boolean = false): TwingBaseNode | null => {
|
||||
// non-empty text nodes are not allowed as direct child of a
|
||||
const testedNode = node as TwingNode;
|
||||
|
||||
|
||||
if (testedNode.type === "text" && !isMadeOfWhitespaceOnly(testedNode.attributes.data)) {
|
||||
const {data} = testedNode.attributes;
|
||||
|
||||
@ -312,21 +312,22 @@ export const createParser = (
|
||||
);
|
||||
}
|
||||
|
||||
const {type} = (node as TwingNode);
|
||||
|
||||
// bypass nodes that "capture" the output
|
||||
if (node.isACaptureNode) {
|
||||
// a "block" tag in such a node will serve as a block definition AND be displayed in place as well
|
||||
if (type === "set") {
|
||||
return node;
|
||||
}
|
||||
|
||||
// to be removed completely in Twig 3.0
|
||||
if (!nested && (node.type === "spaceless")) {
|
||||
if (!nested && (type === "spaceless")) {
|
||||
console.warn(`Using the spaceless tag at the root level of a child template in "${stream.source.name}" at line ${node.line} is deprecated since Twig 2.5.0 and will become a syntax error in Twig 3.0.`);
|
||||
}
|
||||
|
||||
// "block" tags that are not capturing (see above) are only used for defining
|
||||
// the content of the block. In such a case, nesting it does not work as
|
||||
// expected as the definition is not part of the default template code flow.
|
||||
if (nested && (node.type === "block_reference")) {
|
||||
if (nested && (type === "block_reference")) {
|
||||
if (level >= 3) {
|
||||
throw createParsingError(`A block definition cannot be nested under non-capturing nodes.`, node, stream.source.name);
|
||||
}
|
||||
@ -336,17 +337,18 @@ export const createParser = (
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.isAnOutputNode && (node.type !== "spaceless")) {
|
||||
|
||||
if (type === "block_reference" || type === "print" || type === "text") {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// here, nested means "being at the root level of a child template"
|
||||
// we need to discard the wrapping node for the "body" node
|
||||
nested = nested || (node.type !== "wrapper");
|
||||
nested = nested || (type !== "wrapper");
|
||||
|
||||
for (const [key, child] of getChildren(node)) {
|
||||
if (child !== null && (filterChildBodyNode(stream, child, nested) === null)) {
|
||||
|
||||
delete (node.children as any)[key];
|
||||
}
|
||||
}
|
||||
@ -895,7 +897,7 @@ export const createParser = (
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return createWrapperNode(targets, line, column);
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {createBaseNode} from "../node";
|
||||
import {createParsingError} from "../error/parsing";
|
||||
import {createBlockNode} from "../node/block";
|
||||
import {createPrintNode} from "../node/output/print";
|
||||
import {createBlockReferenceNode} from "../node/output/block-reference";
|
||||
import {createPrintNode} from "../node/print";
|
||||
import {createBlockReferenceNode} from "../node/block-reference";
|
||||
import {Token} from "twig-lexer";
|
||||
import {TwingTagHandler} from "../tag-handler";
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {createBlockFunctionNode} from "../node/expression/block-function";
|
||||
import {createConstantNode} from "../node/expression/constant";
|
||||
import {createBlockNode} from "../node/block";
|
||||
import {createPrintNode} from "../node/output/print";
|
||||
import {createPrintNode} from "../node/print";
|
||||
import {Token} from "twig-lexer";
|
||||
import {TwingTagHandler} from "../tag-handler";
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {createSpacelessNode} from "../node/output/spaceless";
|
||||
import {createSpacelessNode} from "../node/spaceless";
|
||||
import {Token} from "twig-lexer";
|
||||
import {TwingTagHandler} from "../tag-handler";
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {createVerbatimNode} from "../node/output/verbatim";
|
||||
import {createVerbatimNode} from "../node/verbatim";
|
||||
import {Token} from "twig-lexer";
|
||||
import {TwingTagHandler} from "../tag-handler";
|
||||
import {TwingNode} from "../node";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as tape from 'tape';
|
||||
import {SinonStub, stub} from 'sinon';
|
||||
import {createEnvironment, TwingEnvironmentOptions} from "../../../src/lib/environment";
|
||||
import {createPrintNode} from "../../../src/lib/node/output/print";
|
||||
import {createPrintNode} from "../../../src/lib/node/print";
|
||||
import {createConstantNode} from "../../../src/lib/node/expression/constant";
|
||||
import {TwingExtension} from "../../../src/lib/extension";
|
||||
import {createFilter} from "../../../src/lib/filter";
|
||||
|
Loading…
Reference in New Issue
Block a user