Skip to content

@marko/runtime-tags@6.1.14

Choose a tag to compare

@github-actions github-actions released this 21 Jun 23:55
· 3 commits to main since this release
b394f7e

Patch Changes

  • #3262 c467f09 Thanks @DylanPiercey! - Error in development when a <for> tag's by attribute returns an invalid key — a non-string/number value (e.g. an object, which collapses every item to [object Object]) or a duplicate value. These previously only logged a console.error warning while silently corrupting keyed reconciliation (state, focus, and animations attaching to the wrong items). The checks are MARKO_DEBUG-only and stripped from production.

  • #3253 ce92da6 Thanks @DylanPiercey! - Fix <for to>/<for until> range loops corrupting their DOM on the first update after an SSR resume. Without an explicit by, these loops are keyed by their iteration value, but the HTML writer decided whether to serialize the loop key by comparing the key against the iteration value rather than the positional index — so the key was never written. On resume the branches were keyed by position while the client re-keyed them by value, and any range loop where the value differs from the position (from other than 0, or a step other than 1) with resumable content (event handlers, <let>, etc.) would tear down and rebuild its branches. The writer now compares against the positional index, matching <for of>.

  • #3251 8fb0bd7 Thanks @DylanPiercey! - Error on native tags when an attribute name is a recognizable idiom from another framework (React, Svelte, Vue) that is not valid in Marko, with a suggestion for the correct syntax. These previously compiled but silently produced a junk attribute (HTML attribute names are case-insensitive, so e.g. className becomes the classname attribute, not class). Examples:

    • React: classNameclass, htmlForfor, defaultValuevalue, defaultCheckedchecked, acceptCharsetaccept-charset, httpEquivhttp-equiv
    • Svelte: class:activeclass={ active: condition }, style:colorstyle={ color: value }, on:clickonClick, bind:valuevalue:=state
    • Vue: v-if<if>, v-for<for>, v-modelvalue:=state, v-on:clickonClick, v-bind:classclass

    The check runs for both static attributes (compile error) and dynamic/spread attributes (MARKO_DEBUG-only runtime error in the server and client attribute runtimes). Only native tags are checked — custom components may still accept input props with these names. (Vue's :/@ and Angular's [/(/* shorthands already error as invalid attribute names.)

  • #3264 d3055ef Thanks @DylanPiercey! - Fix <lifecycle> onDestroy not running after resume when it is the only interactive feature of a component nested in control flow. The lifecycle cleanup is registered through $signal at runtime, which requires the scope to resume with its closest branch linked; the section is now marked so that link is serialized.

  • #3260 262f277 Thanks @DylanPiercey! - Error in development when a native tag attribute or text interpolation receives a value that can't meaningfully render (a plain object, a promise, a symbol, or a function). For example <div title={ ... }> or ${somePromise} previously rendered useless output like [object Object]. Object and function attribute literals are also caught at compile time. class/style, content, event handlers, and change handlers, as well as arrays and values with a meaningful toString, are unaffected.

  • #3261 e9f04e3 Thanks @DylanPiercey! - Warn in development when a controlled <select>'s value matches no <option>. A single select always forces one option selected, so an unmatched value cannot round-trip through SSR resume (the server serializes which option is selected, not the value) and the controlled value is lost on the client. Both the server and client runtimes now emit a MARKO_DEBUG console.error so the mistake is surfaced during development.

  • #3259 cbf7a49 Thanks @DylanPiercey! - Fix the SSR serializer emitting an own __proto__ data property as a prototype setter. A plain object with an own __proto__ key (e.g. produced by JSON.parse) was serialized as {__proto__: value}, which on deserialization sets the object's prototype instead of creating an own property — dropping the data and mutating the prototype. Such keys are now emitted as a computed key ({["__proto__"]: value}) so they round-trip as normal own properties.

  • #3252 e8c75db Thanks @DylanPiercey! - Fix a controlled form binding (value/checked/checkedValue/open together with its *Change handler) applied through a spread (<input ...attrs>) continuing to take effect after the spread drops it. The controlled handler and type were only written by the controllable setters and never cleared, so the persistent input listener kept firing the stale change handler and mutating state on an element that was no longer controlled. The binding is now reset each render and re-established only when the controlling attribute is still present.

  • #3254 e8b06b5 Thanks @DylanPiercey! - Fix text-only native tags (<title>, <style>, <html-comment>, etc.) corrupting dynamic text in the client build. When such a tag's body contained a placeholder, the compiler built the template literal's raw string escaping only backticks — not backslashes or ${. Babel emits code from raw, so a backslash in the static text became a JS escape sequence at runtime (e.g. \b → backspace) and a literal ${ became a stray interpolation; the server (HTML) build used the correct escaper, so SSR and the hydrated client diverged. The compiler now reuses the shared escapeTemplateRaw helper for these literals.