Skip to content

Commit fb87bf5

Browse files
committed
feat(handlers): explain the tagName convention, and take app ids with underscores
Like the files sidebar tabs: how the element gets defined, when the viewer waits for it, and why the name starts with the app id. App ids like files_pdfviewer have an underscore, which the custom element spec allows but the tag name check refused. Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: John Molakvoæ <14975046+skjnldsv@users.noreply.github.com>
1 parent 6609667 commit fb87bf5

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

‎README.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,11 @@ The full handler shape (see the `IHandler` interface):
335335

336336
Gotchas:
337337

338-
- `tagName` must be lowercase, contain a hyphen, and have no leading, trailing
339-
or consecutive hyphens (e.g. `my-app-viewer`). An invalid one throws.
338+
- `tagName` must be lowercase (letters, digits, `_` and `-`), contain a hyphen,
339+
and have no leading, trailing or consecutive hyphens. An invalid one throws.
340+
Custom elements share one registry for the whole page, so start it with your
341+
app id to avoid clashing with another app's: for the app `your_app`, a good
342+
name is `your_app-viewer-handler`.
340343
- `id` must be unique **across every app on the page**, not just your own:
341344
it is not namespaced for you. A collision does not throw: the second
342345
registration is silently dropped with a console warning, so pick something

‎__tests__/fileActions.spec.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ describe('registerHandler validation', () => {
118118
.toThrow('Handler tagName must not start or end with a hyphen (-)')
119119
})
120120

121+
it('takes a tagName starting with an app id that has an underscore', () => {
122+
expect(() => registerHandler(makeHandler({ id: 'pdf', tagName: 'files_pdfviewer-viewer-handler' })))
123+
.not.toThrow()
124+
})
125+
126+
it('throws on a tagName with any other character', () => {
127+
expect(() => registerHandler(makeHandler({ tagName: 'oca-viewer.pdf' })))
128+
.toThrow('Handler tagName must only contain lowercase letters, numbers, underscores (_) and hyphens (-)')
129+
})
130+
121131
it('throws on a tagName ending with a hyphen', () => {
122132
expect(() => registerHandler(makeHandler({ tagName: 'oca-viewer-' })))
123133
.toThrow('Handler tagName must not start or end with a hyphen (-)')

‎lib/handlers.ts‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,19 @@ export interface IHandler {
3434
iconSvgInline?: string
3535

3636
/**
37-
* The custom element tag name to use for this handler.
37+
* The tag name of the custom element that shows the file.
38+
*
39+
* The element must be defined under this name with
40+
* `CustomElementRegistry.define()`, either when the handler is registered
41+
* or within the `onInit` callback (preferred, as it keeps the view out of
42+
* the script that runs on every page). With `onInit`, the viewer waits for
43+
* the element to be defined (`customElements.whenDefined()`) before
44+
* rendering it.
45+
*
46+
* Custom elements share one registry for the whole page, so to avoid name
47+
* clashes the name has to start with your app id (e.g. `your_app`). In
48+
* addition to the custom element naming rules (lowercase, with a hyphen),
49+
* a good name would be `your_app-viewer-handler`.
3850
*/
3951
tagName: string
4052

@@ -344,7 +356,7 @@ function validateCustomElementName(tagName: string): void {
344356
if (tagName.startsWith('-') || tagName.endsWith('-')) {
345357
throw new Error('Handler tagName must not start or end with a hyphen (-)')
346358
}
347-
if (!/^[a-z][a-z0-9-]*$/.test(tagName)) {
348-
throw new Error('Handler tagName must only contain lowercase letters, numbers, and hyphens (-)')
359+
if (!/^[a-z][a-z0-9_-]*$/.test(tagName)) {
360+
throw new Error('Handler tagName must only contain lowercase letters, numbers, underscores (_) and hyphens (-)')
349361
}
350362
}

0 commit comments

Comments
 (0)