Skip to content

Commit

Permalink
fix: add more doc, add id to errors, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
bigopon committed May 10, 2024
1 parent 8926aed commit 251236c
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 53 deletions.
31 changes: 31 additions & 0 deletions docs/user-docs/components/bindable-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,37 @@ Then the value of the `first` property in `NameTag` with `id=1` will be `Jane`,
- An exception of this order is when bindables spreading is used together with [`...$attrs`](#attributes-transferring), `...$attrs` will always result in bindings after `...$bindables`/`$bindables.spread`/`...expression`.
{% endhint %}

### Observation behavior

Bindings will be created based on the keys available in the object evaluated from the `expression` of a spread binding. The following example illustrate the behavior:

For the `NameTag` component above:
```html
<let item.bind="{ first: 'John' }">
<name-tag ...item></name-tag>
<button click.trigger="item.last = 'Doe'">Change last name</button>
```

The rendered HTML of `<name-tag>` will be
```html
<b>JOHN</b>
```

When clicking on the button with text `Change last name`, the rendered html of `<name-tag>` won't be changed,
as the original object given to `<name-tag>` doesn't contain `last`, hence it wasn't observed, which ignore our new value set from the button click.
If it's desirable to reset the observation, give a new object to the spread binding, like the following example:

```html
<let item.bind="{ first: 'John' }">
<name-tag ...item></name-tag>
<button click.trigger="item = { first: item.name, last: 'Doe' }">Change last name</button>
```

{% hint style="success" %}
With the above behavior of non-eager binding, applications can have the opportunity to leave some bindable properties alone,
while with the opposite of always observing all properties on the given object based on the number of bindable properties,
missing value (`null`/`undefined`) will start flowing in in an unwanted way.
{% endhint %}

## Attributes Transferring

Expand Down
8 changes: 0 additions & 8 deletions packages-tooling/rollup-utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,6 @@ export function getRollupConfig(pkg, configure = identity) {
};
// const isDevMode = /^true$/.test(process.env.DEV_MODE);
const inputFile = 'src/index.ts';
// const esmDevDist = 'dist/esm/index.dev.mjs';
// const cjsDevDist = 'dist/cjs/index.dev.cjs';
// const esmDist = 'dist/esm/index.mjs';
// const cjsDist = 'dist/cjs/index.cjs';
// const typingsDist = 'dist/types/index.d.ts';
/** @type {import('rollup').WarningHandlerWithDefault} */
const onWarn = (warning, warn) => {
if (warning.code === 'CIRCULAR_DEPENDENCY') return;
Expand All @@ -125,14 +120,12 @@ export function getRollupConfig(pkg, configure = identity) {
{
dir: 'dist',
entryFileNames: 'esm/index.mjs',
// file: esmDist,
format: 'es',
sourcemap: true,
},
{
dir: 'dist',
entryFileNames: 'cjs/index.cjs',
// file: cjsDist,
format: 'cjs',
sourcemap: true,
externalLiveBindings: false,
Expand All @@ -148,7 +141,6 @@ export function getRollupConfig(pkg, configure = identity) {
declarationMap: true,
}
}),
// runPostbuildScript(...postBuildScript),
],
onwarn: onWarn,
}, false, envVars);
Expand Down
48 changes: 10 additions & 38 deletions packages/runtime-html/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,6 @@ export const enum ErrorNames {
node_observer_mapping_existed = 653,
select_observer_array_on_non_multi_select = 654,

compiler_root_is_local = 701,
compiler_invalid_surrogate_attr = 702,
compiler_no_tc_on_surrogate = 703,
compiler_invalid_let_command = 704,
compiler_au_slot_on_non_element = 706,
compiler_binding_to_non_bindable = 707,
compiler_template_only_local_template = 708,
compiler_local_el_not_under_root = 709,
compiler_local_el_bindable_not_under_root = 710,
compiler_local_el_bindable_name_missing = 711,
compiler_local_el_bindable_duplicate = 712,
compiler_unknown_binding_command = 713,
compiler_primary_already_existed = 714,
compiler_local_name_empty = 715,
compiler_duplicate_local_name = 716,
compiler_slot_without_shadowdom = 717,
compiler_no_spread_tc = 718,
compiler_attr_mapper_duplicate_mapping = 719,

root_not_found = 767,
aurelia_instance_existed_in_container = 768,
invalid_platform_impl = 769,
Expand Down Expand Up @@ -109,6 +90,8 @@ export const enum ErrorNames {
repeat_non_countable = 778,
repeat_mismatch_length = 814,

portal_invalid_insert_position = 779,

self_behavior_invalid_usage = 801,
update_trigger_behavior_no_triggers = 802,
update_trigger_invalid_usage = 803,
Expand All @@ -126,6 +109,9 @@ export const enum ErrorNames {
signal_behavior_invalid_usage = 817,
signal_behavior_no_signals = 818,

spreading_bindable_onto_non_component = 819,
spreading_invalid_target = 820,

no_spread_scope_context_found = 9999,
no_spread_template_controller = 9998,
marker_malformed = 9997,
Expand Down Expand Up @@ -197,25 +183,6 @@ const errorsMap: Record<ErrorNames, string> = {
[ErrorNames.node_observer_mapping_existed]: `Mapping for property {{0}} of <{{1}} /> already exists`,
[ErrorNames.select_observer_array_on_non_multi_select]: `Array values can only be bound to a multi-select.`,

[ErrorNames.compiler_root_is_local]: `Template compilation error in element "{{0:name}}": the root <template> cannot be a local element template.`,
[ErrorNames.compiler_invalid_surrogate_attr]: `Template compilation error: attribute "{{0}}" is invalid on element surrogate.`,
[ErrorNames.compiler_no_tc_on_surrogate]: `Template compilation error: template controller "{{0}}" is invalid on element surrogate.`,
[ErrorNames.compiler_invalid_let_command]: `Template compilation error: Invalid command "{{0:.command}}" for <let>. Only to-view/bind supported.`,
[ErrorNames.compiler_au_slot_on_non_element]: `Template compilation error: detected projection with [au-slot="{{0}}"] attempted on a non custom element {{1}}.`,
[ErrorNames.compiler_binding_to_non_bindable]: `Template compilation error: creating binding to non-bindable property {{0}} on {{1}}.`,
[ErrorNames.compiler_template_only_local_template]: `Template compilation error: the custom element "{{0}}" does not have any content other than local template(s).`,
[ErrorNames.compiler_local_el_not_under_root]: `Template compilation error: local element template needs to be defined directly under root of element "{{0}}".`,
[ErrorNames.compiler_local_el_bindable_not_under_root]: `Template compilation error: bindable properties of local element "{{0}}" template needs to be defined directly under <template>.`,
[ErrorNames.compiler_local_el_bindable_name_missing]: `Template compilation error: the attribute 'property' is missing in {{0:outerHTML}} in local element "{{1}}"`,
[ErrorNames.compiler_local_el_bindable_duplicate]: `Template compilation error: Bindable property and attribute needs to be unique; found property: {{0}}, attribute: {{1}}`,
[ErrorNames.compiler_unknown_binding_command]: `Template compilation error: unknown binding command: "{{0}}".{{0:bindingCommandHelp}}`,
[ErrorNames.compiler_primary_already_existed]: `Template compilation error: primary already exists on element/attribute "{{0}}"`,
[ErrorNames.compiler_local_name_empty]: `Template compilation error: the value of "as-custom-element" attribute cannot be empty for local element in element "{{0}}"`,
[ErrorNames.compiler_duplicate_local_name]: `Template compilation error: duplicate definition of the local template named "{{0}} in element {{1}}"`,
[ErrorNames.compiler_slot_without_shadowdom]: `Template compilation error: detected a usage of "<slot>" element without specifying shadow DOM options in element: {{0}}`,
[ErrorNames.compiler_attr_mapper_duplicate_mapping]: `Attribute {{0}} has been already registered for {{1:element}}`,
[ErrorNames.compiler_no_spread_tc]: `Spreading template controller "{{0}}" is not supported.`,

[ErrorNames.root_not_found]: `Aurelia.root was accessed without a valid root.`,
[ErrorNames.aurelia_instance_existed_in_container]: `An instance of Aurelia is already registered with the container or an ancestor of it.`,
[ErrorNames.invalid_platform_impl]: `Failed to initialize the platform object. The host element's ownerDocument does not have a defaultView, did you create the host from a DOMParser and forget to call adoptNode()?`,
Expand All @@ -242,6 +209,8 @@ const errorsMap: Record<ErrorNames, string> = {
[ErrorNames.repeat_non_countable]: `Unsupported: [repeat] cannot count {{0:toString}}`,
[ErrorNames.repeat_mismatch_length]: `[repeat] encountered an error: number of views != number of items {{0:join(!=)}}`,

[ErrorNames.portal_invalid_insert_position]: 'Invalid portal insertion position: {{0}}',

[ErrorNames.self_behavior_invalid_usage]: `"& self" binding behavior only supports listener binding via trigger/capture command.`,
[ErrorNames.update_trigger_behavior_no_triggers]: `"& updateTrigger" invalid usage. This binding behavior requires at least one event name argument: eg <input value.bind="firstName & updateTrigger:'blur'">`,
[ErrorNames.update_trigger_invalid_usage]: `"& updateTrigger" invalid usage. This binding behavior can only be applied to two-way/ from-view bindings.`,
Expand All @@ -259,6 +228,9 @@ const errorsMap: Record<ErrorNames, string> = {
[ErrorNames.signal_behavior_invalid_usage]: `"& signal" binding behavior can only be used with bindings that have a "handleChange" method`,
[ErrorNames.signal_behavior_no_signals]: `"& signal" invalid usage. At least one signal name must be passed to the signal behavior, e.g. "expr & signal:'my-signal'"`,

[ErrorNames.spreading_bindable_onto_non_component]: 'Spreading to bindables onto non custom element',
[ErrorNames.spreading_invalid_target]: `Invalid spread target {{0}}`,

[ErrorNames.no_spread_scope_context_found]: 'No scope context for spread binding.',
[ErrorNames.no_spread_template_controller]: 'Spread binding does not support spreading custom attributes/template controllers. Did you build the spread instruction manually?',
[ErrorNames.marker_malformed]: `Marker is malformed. This likely happens when a compiled template has been modified.`
Expand Down
4 changes: 2 additions & 2 deletions packages/runtime-html/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ export const SpreadValueRenderer = /*@__PURE__*/ renderer(class SpreadValueRende
const instructionTarget = instruction.target;
if (instructionTarget === '$bindables') {
if ('nodeType' in target) {
throw new Error('Spreading to bindables onto non custom element');
throw createMappedError(ErrorNames.spreading_bindable_onto_non_component);
}
renderingCtrl.addBinding(new SpreadValueBinding(
renderingCtrl,
Expand All @@ -777,7 +777,7 @@ export const SpreadValueRenderer = /*@__PURE__*/ renderer(class SpreadValueRende
platform.domWriteQueue
));
} else {
throw new Error(`Invalid spread target ${instructionTarget}`);
throw createMappedError(ErrorNames.spreading_invalid_target, instructionTarget);
}
}
}, null!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export class Portal implements ICustomAttributeViewModel {
insertManyBefore(parent, target.nextSibling, nodes);
break;
default:
throw new Error('Invalid portal insertion position');
throw createMappedError(ErrorNames.portal_invalid_insert_position, position);
}
}

Expand Down
8 changes: 7 additions & 1 deletion packages/template-compiler/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ export const enum ErrorNames {
compiler_slot_without_shadowdom = 717,
compiler_no_spread_tc = 718,
compiler_attr_mapper_duplicate_mapping = 719,
compiler_no_reserved_spread_syntax = 720,
compiler_no_reserved_$bindable = 721,
compiler_no_dom_api = 722,
no_spread_template_controller = 9998,
}
_END_CONST_ENUM();
Expand All @@ -56,8 +59,11 @@ const errorsMap: Record<ErrorNames, string> = {
[ErrorNames.compiler_local_name_empty]: `Template compilation error: the value of "as-custom-element" attribute cannot be empty for local element in element "{{0}}"`,
[ErrorNames.compiler_duplicate_local_name]: `Template compilation error: duplicate definition of the local template named "{{0}} in element {{1}}"`,
[ErrorNames.compiler_slot_without_shadowdom]: `Template compilation error: detected a usage of "<slot>" element without specifying shadow DOM options in element: {{0}}`,
[ErrorNames.compiler_attr_mapper_duplicate_mapping]: `Attribute {{0}} has been already registered for {{1:element}}`,
[ErrorNames.compiler_no_spread_tc]: `Spreading template controller "{{0}}" is not supported.`,
[ErrorNames.compiler_attr_mapper_duplicate_mapping]: `Attribute {{0}} has been already registered for {{1:element}}`,
[ErrorNames.compiler_no_reserved_spread_syntax]: `Spreading syntax "...xxx" is reserved. Encountered "...{{0}}"`,
[ErrorNames.compiler_no_reserved_$bindable]: `Usage of $bindables is only allowed on custom element. Encountered: <{{0}} {{1}}="{{2}}">`,
[ErrorNames.compiler_no_dom_api]: 'Invalid platform object provided to the compilation, no DOM API found.',

[ErrorNames.no_spread_template_controller]: 'Spread binding does not support spreading custom attributes/template controllers. Did you build the spread instruction manually?',
};
Expand Down
6 changes: 3 additions & 3 deletions packages/template-compiler/src/template-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ export class TemplateCompiler implements ITemplateCompiler {
continue;
}

throw new Error(`Spreading syntax "...xxx" is reserved. Encountered "...${realAttrTarget}"`);
throw createMappedError(ErrorNames.compiler_no_reserved_spread_syntax, realAttrTarget);
}

// reaching here means:
Expand Down Expand Up @@ -849,7 +849,7 @@ export class TemplateCompiler implements ITemplateCompiler {
}

if (realAttrTarget === '$bindables') {
throw new Error(`Usage of $bindables is only allowed on custom element. Encountered: <${el.nodeName} ${realAttrTarget}="${realAttrValue}">`);
throw createMappedError(ErrorNames.compiler_no_reserved_$bindable, el.nodeName, realAttrTarget, realAttrValue);
}

// reaching here means:
Expand Down Expand Up @@ -1745,7 +1745,7 @@ class CompilationContext {
this._attrMapper = hasParent ? parent._attrMapper : container.get(IAttrMapper);
this._logger = hasParent ? parent._logger : container.get(ILogger);
if (typeof (this.p = hasParent ? parent.p : container.get(IPlatform) as unknown as IDomPlatform).document?.nodeType !== 'number') {
throw new Error('Invalid platform');
throw createMappedError(ErrorNames.compiler_no_dom_api);
}
this.localEls = hasParent ? parent.localEls : new Set();
this.rows = instructions ?? [];
Expand Down

0 comments on commit 251236c

Please sign in to comment.