Repository navigation
v2.0.0
npm install shortcodes.js pulled down a demo page, its Quill and Prism
wiring, a Sass build and — in 1.0.1 — an entire copy of book-of-spells, docs
and webfonts included. The package had no files field, and npm publishes
whatever is lying in the tree. The library was the smallest part of what you
got. The demo now lives in site/, the build in dist/, and the tarball
carries those two and nothing else: 10 files where 1.0.1 had 33. The library
itself ran only as that built IIFE: two variables were never declared, and
strict mode — every ES module — turned them into a ReferenceError on the
first shortcode that bound anything. Under that, the sorting ate content: a
sentence that mentioned a tag, a paragraph with a link in it.
Added
- A descriptor is checked at
register(). A key that is not one, or one
from the old per-element api —extract_fn,bind_fn,extract_attr—
extract: 'attr',bind_extracted: 'before', acountthat is neither a
number nor'many', a repeater with noitem_anchor: each gets a console
line with the path and what it should be. A descriptor carried over from a
single-file copy of the 2016–2023 years used to register fine and render
nothing. Nothing throws; the descriptor is used as given.
Changed
-
mainisdist/shortcodes.js. Resolution throughmainfollows it, so
bundlers and a bareunpkg.com/shortcodes.jsare unaffected. A URL that
spelled out the old root path —unpkg.com/shortcodes.js/shortcodes.js— is
not. -
The package is
"type": "module". The source has always been ESM inside
.jsfiles, which is why the tests could only run through theesmshim,
and that shim stopped working on current Node.require('shortcodes.js')now
throwsERR_REQUIRE_ESM.mainis a browser IIFE that assigns
window.Shortcodes, so there was never anything to destructure off it. -
book-of-spells is
^2.8.0, and attribute values arrive typed.
parseAttributesreturns3where it returned"3",falsewhere it
returned"false", and decodes HTML entities on the way, so
background-image="…?a=1&b=2"reaches a parser with a real&. A
customattribute_parsersentry that assumed a string has to say so now. -
@glidejs/glideis a devDependency. The library never imported it — only
the demo page does. Installing shortcodes.js no longer drags Glide along. -
A paragraph is a tag only when the tag is all it says. The tag was found
anywhere in an element's text, so<p>My favourite is [hero] by far</p>was
removed and a hero opened in its place. The sentence is content now; a tag
stands on a line of its own. -
A closing tag that closes nothing stays on the page.
[/hero]after a
[text]opened a second hero. It now closes the open shortcode, or stays
put as content where the author sees it. -
A wrapper is unwrapped only when the element is all it holds. Each key
was searched for inside a paragraph, so<p>Read the <a>docs</a> first</p>
reached theaentry as the link alone and the sentence was gone. It stays
a paragraph now and goes torest;<p><a>docs</a></p>is still the
link, and a line break beside it does not count. Keys are tried in
descriptor order as before, so<p><a><img></a></p>is still the image
under a descriptor that listsimgfirst. -
In a repeater,
countcaps a key per item, not across items.count: 1
on a title gave the first slide one and sent every later title to text. Each
item now takes one element per key, and a repeat — a second image — starts
the next item, as a subtag does. -
A subtag after content starts a new item, and may name several classes.
The first subtag only ever named the item already open, whatever it held.
{ red big }threwInvalidCharacterErroron its way into the class list;
it now sets both classes. -
placement_class_prefixworks. The option was read into the engine and
never handed to the shortcode, soplacement="left"always looked for
.shortcode-landing-left. It now looks for.<prefix>-left. A site that
passed the option and built its landings on the default prefix has to rename
them, or drop the option. -
shopify_full_sizeoption, on by default. The_600x600size Shopify's
editor puts on an inserted image has always been stripped from thesrc
bound to a template, unconditionally. It is an option now;falsekeeps the
size the author picked.
Fixed
-
An attribute whose value types to
0orfalsereaches its parser. The
gate tested the value for truthiness, which was correct only while every
value was a string. Under typed values,placement="0"andopen="false"
fell through to the class list and their parsers never ran.nullis
parseAttributes' mark for a valueless attribute, and that is what the gate
tests now. -
detachElementis imported from the package root. It was reached through
book-of-spells/src/dom.mjs, a deep path into another package's internals
that would break the day book-of-spells declares anexportsmap. It has
been exported from the root since 1.0.4. -
The published
mainbundle is built from the current source. It had been
committed two commits behindsrc/, so the bundle was missingisEmptyand
anyone using the package throughmaingot older code than anyone using
module. -
The
moduleentry runs. Two variables were never declared, which the
built IIFE let slide as globals and strict mode did not: the first shortcode
with abind_extractedthrewReferenceError: finalDestination is not defined, and any repeaterReferenceError: res is not defined. A bundler
resolvesmodulefirst, so a bundled shortcodes.js could not render a
thing. A test now runs the demo page through the source. -
Relative imports name their
.js. The source imported./lib/parsers
without an extension, which a bundler resolves and a browser or Node does
not — a<script type="module">importing it failed with
ERR_MODULE_NOT_FOUND. -
An object in
extractworks. Both the{ name, extract_fn }and the
{ name: 'style', properties }forms threwReferenceError: hasOwnProperties is not defined; past that, the style form compared the
wrong thing and never returned a style. -
parse_extractedgiven as a function is called. It was looked up under
the wrong name and threwTypeError: props.parse is not a function. -
An element entry without
extractrenders. It threwTypeError: Cannot read properties of undefined (reading 'length')while the content was
collected. The entry is collected and binds nothing. -
An element past its key's
countis reported. A second image under a
hero that takes one was left where it stood and nothing said so — a missing
picture with no trace. It is still left in place, and the console now says
which shortcode was full and which element stayed behind. -
A missing template names its selector.
TypeError: Cannot read properties of null (reading 'cloneNode')is nowshortcodes.js: no template matches "section.nope". -
placement="content"and a repeater work without atemplate. The
anchor element was handed toquerySelectorAlland threwSyntaxError; a
repeater with no outer template threwReferenceError: descriptor is not defined. -
A top-level inline tag lands in
rest, not in a key it is a substring
of. Buckets were matched by tag name as a substring of the key, so a bare
<i>counted asimgand<b>asblockquote, and hit the cut-off when
that key was full. Keys are selectors and are matched as such. -
clear()removes the anchors of the class you configured. It removed
.self-anchorwhateverself_anchor_classsaid, so a custom class left one
anchor behind perreinitialize. -
Content comes back when a callback throws.
execute()hides the source
while it works and showed it again only on the way out the front door; a
throwingpreorcallbackleft the page blank. -
A landing nothing matches is reported.
placement="nowhere", ananchor
the page lacks, an elementanchorthe template lacks or anitem_anchor
matching nothing rendered into the void without a word. The console now
names the shortcode and the selector. -
An attribute the source lacks is not written.
bind_extracted: ['href', 'target']on a link without a target wrotetarget="undefined", which
opens a new tab — a window by that name. The attribute is skipped. -
The first shortcode's anchor carries its
-sc-0class. The counter
class was skipped for0, so the first anchor on a page was
self-anchor shortcode-heroand every later one had its number. -
A
srcwith a quote or a parenthesis in it still becomes a background.
url(…)was built unquoted, so a)ended it early and the style was
dropped. It is quoted and escaped now, in thebackground-imageattribute
and in the style binder alike.
Full Changelog: v.1.0.1...v2.0.0