Skip to content

Commit 45b451a

Browse files
committed
Mangle optimizations
1 parent b0ee116 commit 45b451a

9 files changed

Lines changed: 68 additions & 49 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ AngularTS builds on that foundation and adds:
1414
- a fully reactive change-detection model without digests or virtual DOMs, like `Vue`
1515
- access to native DOM APIs at component and directive level (no `JQuery`or `JQLite`)
1616
- access to native Promises API (no `$q` or `$timetout`)
17-
- built-in enterprise-level router (`ui-router` ported as `ng-router`)
17+
- built-in enterprise-level router (`ng-router`, ported from `ui-router`)
1818
- built-in animations (`animate`)
1919
- new directives, inspired by `HTMX`
2020
- new injectables for REST resources, persistent stores, Web Workers, EventSources, WebSockets and WASM modules

src/router/directives/state-directives.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,29 @@ function clickHook(
139139
el.getAttribute("target");
140140

141141
if (!res) {
142-
// HACK: This is to allow ng-clicks to be processed before the transition is initiated:
143-
const transition = setTimeout(function () {
142+
const originalPreventDefault = event.preventDefault.bind(event);
143+
144+
let cancelled = false;
145+
146+
let ignorePreventDefaultCount = type._isAnchor && !target._href ? 1 : 0;
147+
148+
event.preventDefault = function () {
149+
originalPreventDefault();
150+
151+
if (ignorePreventDefaultCount-- <= 0) {
152+
cancelled = true;
153+
}
154+
};
155+
156+
originalPreventDefault();
157+
158+
queueMicrotask(() => {
159+
event.preventDefault = originalPreventDefault;
160+
161+
if (cancelled) {
162+
return;
163+
}
164+
144165
if (!el.getAttribute("disabled")) {
145166
$state
146167
.go(
@@ -153,14 +174,6 @@ function clickHook(
153174
});
154175
}
155176
});
156-
157-
event.preventDefault();
158-
// if the state has no URL, ignore one preventDefault from the <a> directive.
159-
let ignorePreventDefaultCount = type._isAnchor && !target._href ? 1 : 0;
160-
161-
event.preventDefault = function () {
162-
if (ignorePreventDefaultCount-- <= 0) clearTimeout(transition);
163-
};
164177
} else {
165178
// ignored
166179
event.preventDefault();
@@ -217,7 +230,7 @@ StateRefDirective.$inject = [
217230
];
218231

219232
/**
220-
* Generates `ui-sref` links and keeps their href/state data in sync.
233+
* Generates `ng-sref` links and keeps their href/state data in sync.
221234
*/
222235
export function StateRefDirective(
223236
$stateService: ng.StateService,

src/router/params/interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ export interface ParamDeclaration {
329329
* `mode: 'list' is inherited, but refresh: true is not inherited.
330330
* // The param values are thus: `{ fooId: 4567, mode: 'list' }`
331331
* ```
332-
* <ui-sref="foo({ fooId: 4567 })">4567</ui-sref>
332+
* <ng-sref="foo({ fooId: 4567 })">4567</ng-sref>
333333
* ```
334334
*
335335
* ---

src/router/state/interface.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,8 @@ export interface StateDeclaration extends ViewDeclarationCommon {
387387
* Normally, a state's parent is implied from the state's [[name]], e.g., `"parentstate.childstate"`.
388388
*
389389
* Alternatively, you can explicitly set the parent state using this property.
390-
* This allows shorter state names, e.g., `<a ui-sref="childstate">Child</a>`
391-
* instead of `<a ui-sref="parentstate.childstate">Child</a>
390+
* This allows shorter state names, e.g., `<a ng-sref="childstate">Child</a>`
391+
* instead of `<a ng-sref="parentstate.childstate">Child</a>
392392
*
393393
* When using this property, the state's name should not have any dots in it.
394394
*
@@ -844,7 +844,7 @@ export interface StateDeclaration extends ViewDeclarationCommon {
844844
* - The `lazyLoad` function is invoked if a transition is going to enter the state.
845845
* - The function is invoked before the transition starts (using an `onBefore` transition hook).
846846
* - The function is only invoked once; while the `lazyLoad` function is loading code, it will not be invoked again.
847-
* For example, if the user double clicks a ui-sref, `lazyLoad` is only invoked once even though there were two transition attempts.
847+
* For example, if the user double clicks an `ng-sref`, `lazyLoad` is only invoked once even though there were two transition attempts.
848848
* Instead, the existing lazy load promise is re-used.
849849
* - When the promise resolves successfully, the `lazyLoad` property is deleted from the state declaration.
850850
* - If the promise resolves to a [[LazyLoadResult]] which has an array of `states`, those states are registered.

src/router/state/state-service.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,19 @@ export class StateProvider {
151151
$get = [
152152
$injectTokens._injector,
153153
$injectTokens._url,
154+
$injectTokens._view,
154155
/**
155156
* @param {ng.InjectorService} $injector
156157
* @param {ng.UrlService} $url
158+
* @param {ng.ViewService} _viewService
157159
* @returns {StateProvider}
158160
*/
159-
($injector: ng.InjectorService, $url: ng.UrlService) => {
161+
(
162+
$injector: ng.InjectorService,
163+
$url: ng.UrlService,
164+
_viewService: ng.ViewService,
165+
) => {
166+
void _viewService;
160167
this.urlService = $url;
161168
this.$injector = $injector;
162169

src/router/state/views.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,9 @@ import type { TemplateFactoryProvider } from "../template-factory.ts";
1313
/**
1414
* @return {(path: PathNode[], view: ViewDeclaration) => ViewConfig}
1515
*/
16-
export function getViewConfigFactory() {
17-
/**
18-
* Lazily resolved to avoid a direct bootstrap-time dependency on the ng1 injector.
19-
* The factory is cached after first use.
20-
* @type {TemplateFactoryProvider | null}
21-
*/
22-
let templateFactory: TemplateFactoryProvider | null = null;
23-
24-
return (path: PathNode[], view: ViewDeclaration): ViewConfig => {
25-
templateFactory =
26-
templateFactory || window.angular.$injector.get("$templateFactory"); // TODO: remove static injector
27-
28-
return new ViewConfig(
29-
path,
30-
view,
31-
templateFactory as TemplateFactoryProvider,
32-
);
33-
};
16+
export function getViewConfigFactory(templateFactory: TemplateFactoryProvider) {
17+
return (path: PathNode[], view: ViewDeclaration): ViewConfig =>
18+
new ViewConfig(path, view, templateFactory);
3419
}
3520

3621
const hasAnyKey = (keys: string[], obj: Record<string, any>): boolean =>

src/router/transition/interface.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export type DeregisterFn = () => void;
1919
* The TransitionOptions object can be used to change the behavior of a transition.
2020
*
2121
* It is passed as the third argument to [[StateService.go]], [[StateService.transitionTo]].
22-
* It can also be used with a `uiSref`.
22+
* It can also be used with an `ngSref`.
2323
*/
2424
export interface TransitionOptions {
2525
/**
@@ -84,7 +84,7 @@ export interface TransitionOptions {
8484

8585
/**
8686
* This option may be used to cancel the active transition (if one is active) in favour of the this one.
87-
* This is the default behaviour or ui-router.
87+
* This is the default behaviour of ng-router.
8888
*
8989
*
9090
* - When `true`, the active transition will be canceled and new transition will begin.

src/router/view/view.spec.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { StateObject } from "../state/state-object.ts";
77
import { ViewService } from "./view.ts";
88
import { PathNode } from "../path/path-node.ts";
99
import { PathUtils } from "../path/path-utils.ts";
10+
import { getViewConfigFactory } from "../state/views.ts";
1011
import { tail } from "../../shared/common.ts";
1112
import { wait } from "../../shared/test-utils.ts";
1213

@@ -76,7 +77,11 @@ describe("view", () => {
7677
};
7778

7879
state = register(stateDeclaration);
79-
const $view = new ViewService(null);
80+
const $view = new ViewService();
81+
82+
$view._viewConfigFactory = getViewConfigFactory(
83+
$injector.get("$templateFactory"),
84+
);
8085

8186
const _states = [root, state];
8287
path = _states.map((_state) => new PathNode(_state));
@@ -98,7 +103,7 @@ describe("view", () => {
98103
});
99104

100105
describe("matching", () => {
101-
it("matches root default ng-view targets using the active ui-view fqn format", () => {
106+
it("matches root default ng-view targets using the active ng-view fqn format", () => {
102107
const uiView = {
103108
fqn: "$default",
104109
name: "$default",
@@ -168,7 +173,7 @@ describe("view", () => {
168173
});
169174

170175
describe("service helpers", () => {
171-
it("normalizes relative ui-view targets", () => {
176+
it("normalizes relative ng-view targets", () => {
172177
const parentContext = register({ name: "parent", parent: root });
173178
const childContext = register({
174179
name: "child",

src/router/view/view.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { equals, removeFrom } from "../../shared/common.ts";
2+
import { $injectTokens as $t } from "../../injection-tokens.ts";
23
import { trace } from "../common/trace.ts";
34
import { getViewConfigFactory, type ViewConfig } from "../state/views.ts";
45
import type { PathNode } from "../path/path-node.ts";
56
import type { ViewDeclaration } from "../state/interface.ts";
67
import type { StateObject } from "../state/state-object.ts";
8+
import type { TemplateFactoryProvider } from "../template-factory.ts";
79

810
/** The context ref can be anything that has a `name` and a `parent` reference to another IContextRef */
911
export interface ViewContext {
@@ -26,7 +28,7 @@ export interface ActiveUIView {
2628
configUpdated: (config: ViewConfig | undefined) => void;
2729
}
2830

29-
// A uiView and its matching viewConfig
31+
// An ngView and its matching viewConfig
3032
export interface ViewTuple {
3133
ngView: ActiveUIView | undefined;
3234
viewConfig: ViewConfig | undefined;
@@ -42,7 +44,7 @@ type ViewConfigFactory = (
4244
) => ViewConfig;
4345

4446
/**
45-
* Tracks active `ui-view` instances and matches them with registered
47+
* Tracks active `ng-view` instances and matches them with registered
4648
* view configs produced during state transitions.
4749
*/
4850
export class ViewService {
@@ -58,20 +60,27 @@ export class ViewService {
5860
_rootContext: StateObject | null | undefined;
5961

6062
/**
61-
* Creates an empty view registry ready to track active `ui-view` instances.
63+
* Creates an empty view registry ready to track active `ng-view` instances.
6264
*/
6365
constructor() {
6466
this._ngViews = [];
6567
this._viewConfigs = [];
6668
this._listeners = [];
67-
this._viewConfigFactory = getViewConfigFactory();
69+
this._viewConfigFactory = undefined;
6870
this._rootContext = undefined;
6971
}
7072

7173
/**
7274
* Returns the singleton view service instance.
7375
*/
74-
$get = (): ViewService => this;
76+
$get = [
77+
$t._templateFactory,
78+
($templateFactory: TemplateFactoryProvider): ViewService => {
79+
this._viewConfigFactory = getViewConfigFactory($templateFactory);
80+
81+
return this;
82+
},
83+
];
7584

7685
onSync(listener: (tuples: ViewTuple[]) => void): () => void {
7786
this._listeners.push(listener);
@@ -80,7 +89,7 @@ export class ViewService {
8089
}
8190

8291
/**
83-
* Gets or sets the root view context used for relative `ui-view` targeting.
92+
* Gets or sets the root view context used for relative `ng-view` targeting.
8493
*/
8594
rootViewContext(
8695
context?: StateObject | null,
@@ -119,7 +128,7 @@ export class ViewService {
119128
}
120129

121130
/**
122-
* Re-matches active `ui-view` instances against currently registered view configs
131+
* Re-matches active `ng-view` instances against currently registered view configs
123132
* and notifies both the views and registered listeners of the new assignments.
124133
*/
125134
sync(): void {
@@ -240,7 +249,7 @@ export class ViewService {
240249
}
241250

242251
/**
243-
* Registers one active `ui-view` and returns a deregistration function.
252+
* Registers one active `ng-view` and returns a deregistration function.
244253
*/
245254
registerUIView(ngView: ActiveUIView): () => void {
246255
trace.traceViewServiceUIViewEvent("-> Registering", ngView);
@@ -300,7 +309,7 @@ export class ViewService {
300309

301310
/**
302311
* Builds a predicate that determines whether a view config matches
303-
* a specific active `ui-view`.
312+
* a specific active `ng-view`.
304313
*/
305314
static matches(
306315
ngViewsByFqn: Record<string, ActiveUIView>,

0 commit comments

Comments
 (0)