mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(compiler): implement final instruction generation for interaction triggers (#51830)
Updates the logic that generates the instructions for the `on interaction` and `prefetch on interaction` triggers to their final shape. Now the instructions take two arguments: 1. `triggerIndex` - index at which to find the trigger in the view where it will be rendered. 2. `walkUpTimes` - tells the runtime how many views up it needs to go to find the trigger element. If the argument is omitted, it means that the trigger is in the same view as the deferred block. A positive number means that the runtime needs to go up X amount of times to find the trigger. A negative number means that the trigger is inside the root view of the placeholder block. Negative numbers are capped at -1 since the placeholder is always in the same position at runtime. PR Close #51830
This commit is contained in:
committed by
Dylan Hunn
parent
7cce28ae9c
commit
00e6013661
+153
@@ -511,3 +511,156 @@ export declare class MyApp {
|
||||
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, true, never>;
|
||||
}
|
||||
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: deferred_interaction_same_view_trigger.js
|
||||
****************************************************************************************************/
|
||||
import { Component } from '@angular/core';
|
||||
import * as i0 from "@angular/core";
|
||||
export class MyApp {
|
||||
constructor() {
|
||||
this.message = 'hello';
|
||||
}
|
||||
}
|
||||
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
|
||||
{{message}}
|
||||
{#defer on interaction(button); prefetch on interaction(button)}{/defer}
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<button #button>Click me</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`, isInline: true });
|
||||
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
|
||||
type: Component,
|
||||
args: [{
|
||||
template: `
|
||||
{{message}}
|
||||
{#defer on interaction(button); prefetch on interaction(button)}{/defer}
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<button #button>Click me</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
}]
|
||||
}] });
|
||||
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: deferred_interaction_same_view_trigger.d.ts
|
||||
****************************************************************************************************/
|
||||
import * as i0 from "@angular/core";
|
||||
export declare class MyApp {
|
||||
message: string;
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
|
||||
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
|
||||
}
|
||||
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: deferred_interaction_parent_view_trigger.js
|
||||
****************************************************************************************************/
|
||||
import { Component } from '@angular/core';
|
||||
import * as i0 from "@angular/core";
|
||||
export class MyApp {
|
||||
constructor() {
|
||||
this.message = 'hello';
|
||||
}
|
||||
}
|
||||
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
|
||||
<ng-template>
|
||||
{{message}}
|
||||
<button #button>Click me</button>
|
||||
|
||||
<ng-template>
|
||||
<ng-template>
|
||||
{#defer on interaction(button); prefetch on interaction(button)}{/defer}
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
`, isInline: true });
|
||||
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
|
||||
type: Component,
|
||||
args: [{
|
||||
template: `
|
||||
<ng-template>
|
||||
{{message}}
|
||||
<button #button>Click me</button>
|
||||
|
||||
<ng-template>
|
||||
<ng-template>
|
||||
{#defer on interaction(button); prefetch on interaction(button)}{/defer}
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
`,
|
||||
}]
|
||||
}] });
|
||||
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: deferred_interaction_parent_view_trigger.d.ts
|
||||
****************************************************************************************************/
|
||||
import * as i0 from "@angular/core";
|
||||
export declare class MyApp {
|
||||
message: string;
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
|
||||
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
|
||||
}
|
||||
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: deferred_interaction_placeholder_trigger.js
|
||||
****************************************************************************************************/
|
||||
import { Component } from '@angular/core';
|
||||
import * as i0 from "@angular/core";
|
||||
export class MyApp {
|
||||
constructor() {
|
||||
this.message = 'hello';
|
||||
}
|
||||
}
|
||||
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
|
||||
{{message}}
|
||||
{#defer on interaction(button); prefetch on interaction(button)}
|
||||
Main
|
||||
{:placeholder}
|
||||
<div>
|
||||
<div>
|
||||
<button #button>Click me</button>
|
||||
</div>
|
||||
</div>
|
||||
{/defer}
|
||||
`, isInline: true });
|
||||
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
|
||||
type: Component,
|
||||
args: [{
|
||||
template: `
|
||||
{{message}}
|
||||
{#defer on interaction(button); prefetch on interaction(button)}
|
||||
Main
|
||||
{:placeholder}
|
||||
<div>
|
||||
<div>
|
||||
<button #button>Click me</button>
|
||||
</div>
|
||||
</div>
|
||||
{/defer}
|
||||
`,
|
||||
}]
|
||||
}] });
|
||||
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: deferred_interaction_placeholder_trigger.d.ts
|
||||
****************************************************************************************************/
|
||||
import * as i0 from "@angular/core";
|
||||
export declare class MyApp {
|
||||
message: string;
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
|
||||
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
|
||||
}
|
||||
|
||||
|
||||
+63
@@ -192,6 +192,69 @@
|
||||
}
|
||||
],
|
||||
"skipForTemplatePipeline": true
|
||||
},
|
||||
{
|
||||
"description": "should generate a deferred block with an interaction trigger in the same view",
|
||||
"angularCompilerOptions": {
|
||||
"_enabledBlockTypes": ["defer"]
|
||||
},
|
||||
"inputFiles": [
|
||||
"deferred_interaction_same_view_trigger.ts"
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"expected": "deferred_interaction_same_view_trigger_template.js",
|
||||
"generated": "deferred_interaction_same_view_trigger.js"
|
||||
}
|
||||
],
|
||||
"failureMessage": "Incorrect template"
|
||||
}
|
||||
],
|
||||
"skipForTemplatePipeline": true
|
||||
},
|
||||
{
|
||||
"description": "should generate a deferred block with an interaction trigger in a parent view",
|
||||
"angularCompilerOptions": {
|
||||
"_enabledBlockTypes": ["defer"]
|
||||
},
|
||||
"inputFiles": [
|
||||
"deferred_interaction_parent_view_trigger.ts"
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"expected": "deferred_interaction_parent_view_trigger_template.js",
|
||||
"generated": "deferred_interaction_parent_view_trigger.js"
|
||||
}
|
||||
],
|
||||
"failureMessage": "Incorrect template"
|
||||
}
|
||||
],
|
||||
"skipForTemplatePipeline": true
|
||||
},
|
||||
{
|
||||
"description": "should generate a deferred block with an interaction trigger inside the placeholder",
|
||||
"angularCompilerOptions": {
|
||||
"_enabledBlockTypes": ["defer"]
|
||||
},
|
||||
"inputFiles": [
|
||||
"deferred_interaction_placeholder_trigger.ts"
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"expected": "deferred_interaction_placeholder_trigger_template.js",
|
||||
"generated": "deferred_interaction_placeholder_trigger.js"
|
||||
}
|
||||
],
|
||||
"failureMessage": "Incorrect template"
|
||||
}
|
||||
],
|
||||
"skipForTemplatePipeline": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ng-template>
|
||||
{{message}}
|
||||
<button #button>Click me</button>
|
||||
|
||||
<ng-template>
|
||||
<ng-template>
|
||||
{#defer on interaction(button); prefetch on interaction(button)}{/defer}
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
`,
|
||||
})
|
||||
export class MyApp {
|
||||
message = 'hello';
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
function MyApp_ng_template_0_ng_template_4_ng_template_0_Template(rf, ctx) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵɵtemplate(0, MyApp_ng_template_0_ng_template_4_ng_template_0_Defer_0_Template, 0, 0);
|
||||
$r3$.ɵɵdefer(1, 0);
|
||||
$r3$.ɵɵdeferOnInteraction(1, 2);
|
||||
$r3$.ɵɵdeferPrefetchOnInteraction(1, 2);
|
||||
}
|
||||
}
|
||||
…
|
||||
function MyApp_ng_template_0_Template(rf, ctx) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵɵtext(0);
|
||||
$r3$.ɵɵelementStart(1, "button", null, 0);
|
||||
$r3$.ɵɵtext(3, "Click me");
|
||||
$r3$.ɵɵelementEnd();
|
||||
$r3$.ɵɵtemplate(4, MyApp_ng_template_0_ng_template_4_Template, 1, 0, "ng-template");
|
||||
}
|
||||
if (rf & 2) {
|
||||
const ctx_r0 = $r3$.ɵɵnextContext();
|
||||
$r3$.ɵɵtextInterpolate1(" ", ctx_r0.message, " ");
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
{{message}}
|
||||
{#defer on interaction(button); prefetch on interaction(button)}
|
||||
Main
|
||||
{:placeholder}
|
||||
<div>
|
||||
<div>
|
||||
<button #button>Click me</button>
|
||||
</div>
|
||||
</div>
|
||||
{/defer}
|
||||
`,
|
||||
})
|
||||
export class MyApp {
|
||||
message = 'hello';
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
function MyApp_DeferPlaceholder_2_Template(rf, ctx) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵɵelementStart(0, "div")(1, "div")(2, "button", null, 0);
|
||||
$r3$.ɵɵtext(4, "Click me");
|
||||
$r3$.ɵɵelementEnd()()();
|
||||
}
|
||||
}
|
||||
…
|
||||
function MyApp_Template(rf, ctx) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵɵtext(0);
|
||||
$r3$.ɵɵtemplate(1, MyApp_Defer_1_Template, 1, 0)(2, MyApp_DeferPlaceholder_2_Template, 5, 0);
|
||||
$r3$.ɵɵdefer(3, 1, null, null, 2);
|
||||
$r3$.ɵɵdeferOnInteraction(2, -1);
|
||||
$r3$.ɵɵdeferPrefetchOnInteraction(2, -1);
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵtextInterpolate1(" ", ctx.message, " ");
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
{{message}}
|
||||
{#defer on interaction(button); prefetch on interaction(button)}{/defer}
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<button #button>Click me</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class MyApp {
|
||||
message = 'hello';
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
function MyApp_Template(rf, ctx) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵɵtext(0);
|
||||
$r3$.ɵɵtemplate(1, MyApp_Defer_1_Template, 0, 0);
|
||||
$r3$.ɵɵdefer(2, 1);
|
||||
$r3$.ɵɵdeferOnInteraction(7);
|
||||
$r3$.ɵɵdeferPrefetchOnInteraction(7);
|
||||
$r3$.ɵɵelementStart(4, "div")(5, "div")(6, "div")(7, "button", null, 0);
|
||||
$r3$.ɵɵtext(9, "Click me");
|
||||
$r3$.ɵɵelementEnd()()()();
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵtextInterpolate1(" ", ctx.message, " ");
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ function MyApp_Template(rf, ctx) {
|
||||
$r3$.ɵɵdeferPrefetchOnImmediate();
|
||||
$r3$.ɵɵdeferPrefetchOnTimer(1337);
|
||||
$r3$.ɵɵdeferPrefetchOnHover();
|
||||
$r3$.ɵɵdeferPrefetchOnInteraction("button");
|
||||
$r3$.ɵɵdeferPrefetchOnInteraction(0, -1);
|
||||
$r3$.ɵɵdeferPrefetchOnViewport("button");
|
||||
}
|
||||
if (rf & 2) {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ function MyApp_Template(rf, ctx) {
|
||||
$r3$.ɵɵdeferOnImmediate();
|
||||
$r3$.ɵɵdeferOnTimer(1337);
|
||||
$r3$.ɵɵdeferOnHover();
|
||||
$r3$.ɵɵdeferOnInteraction("button");
|
||||
$r3$.ɵɵdeferOnInteraction(0, -1);
|
||||
$r3$.ɵɵdeferOnViewport("button");
|
||||
}
|
||||
if (rf & 2) {
|
||||
|
||||
Reference in New Issue
Block a user