Upgrading
When a new version of Fudgel is released, you may need to make some changes to your existing components to ensure they continue to work correctly.
From 3.4.x to 4.0.x
Three behaviors changed on purpose.
- An attribute that is absent no longer sets the controller property to
null; the class field's default stays. Removing an attribute later still sets the property tonull, andonChange()is no longer called for an absent attribute at startup. Code that relied on a declared attribute beingnullwhen absent should give the field no initial value, or treatnullandundefinedalike. - The index a
*repeatprovides starts at 0, like every other index in JavaScript and like the keys of*forover an array. Add 1 where a template shows the number to people. - In the light DOM, a descendant named after
:hostin a style rule is scoped to the component, so:host pno longer styles a<p>inside a nested component, which it never did in the shadow DOM. To style content that another component provides, style it from that component.
Everything else needs no code changes. Several behaviors were bugs and now match what the documentation said; check anything that depended on the old behavior.
- Bindings and event listeners are cleaned up when a directive removes their element. Listeners on the window or document from
@event.window,.documentand.outsideused to stay attached forever. - A getter on the controller's prototype is read each time a binding runs instead of being copied once when the template linked. An accessor on the instance receives the instance as
thiswhen assigned. - A global such as
MathorDatein a binding resolves to the global. It used to be shadowed by an undefined controller property. - Expressions support the conditional operator,
a ? b : c, and parentheses,(a + b) * c. component()throws when the browser rejects the element name, such as a name without a hyphen. It used to fail silently. A name that is already defined is still skipped.- A kebab-case name in
attrorpropis accepted as the camelCase one. - Assigning
true,false,nullorundefinedto a property listed inattrreflects to the attribute, as documented. @keydown.arrow-leftand other dashed key modifiers work; they never matched before.@keydown.spacematches the space bar.@some-eventalso listens for the dashed namesome-event, so events from other libraries bind.*foraccepts an expression with spaces,*for="x of a ?? b", and atrackclause that keys rows by identity. A row that still exists is moved rather than rebuilt when the list is reordered.- A growing
*repeatappends new items after the existing ones instead of inserting them before. - Light DOM style scoping handles
:host(...),:host-context(...), pseudo-elements, and commas inside:is()and attribute selectors. Ap::beforerule no longer leaks to the whole page. A selector Fudgel cannot rewrite is reported in the console. - A structural directive at the end of a template no longer re-links the content it rendered, which could re-read braces in your data as expressions.
- The router routes on the resolved location, so
history.replaceState(state)without a URL keeps the current route and a relative URL is resolved. Clicks with a modifier key, another button, atarget,download,rel="external", or a fragment on the current page are left to the browser. History is patched once for the page rather than once per router.RouterComponentexposes its route elements asroutes. di()recovers after a service constructor throws; it used to report a circular dependency forever.- A property, object key, or route parameter named
entriesworks. fudgelcan be imported outside a browser, so services that usedi()can be unit tested under Node.require('fudgel')works, andpackage.jsonhas anexportsmap withfudgelandfudgel/dev.- The build is compiled to ES2018 and checked against it, so Safari 11.1 can parse it again.
- New:
import 'fudgel/dev'while developing prints warnings for common mistakes. See Getting Started. - New types:
StrictControllerandControllerHooks.Controllerno longer declares thewasAsyncparameter removed in 3.2.camelToDashanddashToCamelare exported.
From 3.3.x to 3.4.x
- The router now matches on the path alone. A URL carrying a query string or a fragment, such as
/orders?status=open, previously failed to match/ordersand fell through to the catch-all route. Both are still left on the URL; read them withlocation.searchandlocation.hash. See Routing. - Routes may now name query parameters to receive as attributes, using a
queryattribute on the route. See Routing. - The
routeChangeevent detail is now the matched path. It previously carried whatever URL was passed to the History API, query string and all. - The
@Component()decorator no longer returns a value. It defined the custom element and then returned it, which TypeScript rejects because a class decorator may only return the class it decorated. The decorated name has always referred to the controller at runtime; now the types agree. No code changes are required. - Only
distis published. If you were reaching intofudgel/srcorfudgel/docsfrom an installed copy, import from the package instead.
From 3.1.x to 3.2.x
onViewInit()andonParse()are now always asynchronous and their lifecycle stages no longer pass thewasAsyncargument.- Exposed
lifecyclefunction to allow for custom lifecycle stages.
From 3.0.x to 3.1.x
*forwas made faster. No code changes are required.
From 2.x.x to 3.x.x
- Parsing expressions changed.
parse()is nowparse.js()(one of several parsing functions available).parsed[0]now accepts a list of objects to search as opposed to an array.
nextTick()was removed.controllerToElement(),elementToController(), androotElement()has been removed. Usemetadata, as seen on the Utilities page instead.- All hooks have been removed and switched to events.
hookOnGlobal()is removed and mostly replaced withevents.on().componenthook changed to an event and has an additional argument.set:PROP_NAMEandset:hooks removed.changeandupdatefire instead, respectively.
- The
update()utility function no longer allows updating specific properties. - Lifecycle stages now fire events globally, fire events on the controller, and call methods on the controller.
- Created
updateandunlinkevents. parseandviewInithave been updated to potentially be synchronous, with a new argument indicating if this was called synchronously.
- Created
- Documentation reviewed and significant improvements made.
From 1.x.x to 2.x.x
- No changes. The internals changed significantly and additional information was exposed, but the API remained the same.
For AI assistants: llms.txt (the rules) and llms-full.txt (every page).