feat: add an onClick option for a form field's mouse-up action - #1790
feat: add an onClick option for a form field's mouse-up action#1790KaiPressmar wants to merge 1 commit into
Conversation
105406c to
dde6b58
Compare
|
Updated: on reflection this shouldn't widen the discouraged raw |
dde6b58 to
cea74ed
Compare
|
Updated again: onClick now calls the function with app/getField/display/event as parameters (this bound to the Document) instead of relying on ambient TypeScript globals — a plain global |
cea74ed to
8732f59
Compare
pdfkit deliberately restricted AcroForm options to documented mappings and a small set of raw escape hatches (Ff, MK.CA, and AA only together with a format option), with a stated intent to shrink and eventually remove even those. A mouse-up JavaScript action on a field -- most useful on a push button, e.g. to drive custom client-side logic -- had no supported way to reach the API at all outside that discouraged, format-only AA path. Add a dedicated onClick option instead, consistent with the project's stated direction of adding purpose-built options rather than widening raw dictionary access: it needs no PDF dictionary knowledge, works on its own, and still combines with format-validation actions exactly as the old AA + format combination did. Replaces the raw AA escape hatch: options.AA is no longer read at all, only options.onClick.
8732f59 to
6e700f0
Compare
|
Note: the aa-before.pdf/aa-after.pdf attached above were built against an earlier version of this PR (the raw |
blikblum
left a comment
There was a problem hiding this comment.
Besides onClick, is there other event that can be set?
| doc.formPushButton('btn1', 10, 200, 100, 30, opts); | ||
| ``` | ||
|
|
||
| `onClick` also accepts a plain function, called with Acrobat's own `app`, |
There was a problem hiding this comment.
Simplify the description. Be objective hiding internal details, just with enough information to user create correct functions
| onClick: function (app, getField) { | ||
| app.alert('clicked'); | ||
| this.getField('otherField').value = 'updated from btn1'; | ||
| } |
There was a problem hiding this comment.
param getField is not used. Is really necessary?
| TypeScript projects can import `AcrobatOnClick` and the other types this | ||
| signature uses from `pdfkit/types/acrobat-js` — a small, best-effort set of | ||
| types for the handful of Acrobat globals most `onClick` handlers need, kept | ||
| separate from pdfkit's own types so nothing is declared globally: |
There was a problem hiding this comment.
Nop. Types will be handled separately. Do not expose it for now. It can be documented internally
| ### Advanced Form Field Use | ||
|
|
||
| Older implementations used to pass all unknown options to the internal PDF object structure. A small set of direct PDF dictionary escape hatches is still recognized: `Ff`, `MK.CA`, and `AA` when a `format` option is used but its use is discouraged and likely will be removed in future versions. | ||
| Older implementations used to pass all unknown options to the internal PDF object structure. A small set of direct PDF dictionary escape hatches is still recognized: `Ff` and `MK.CA`, but their use is discouraged and they may be removed in future versions. A previously-recognized `AA` escape hatch (only reachable together with a `format` option) has been replaced by the `onClick` option above, which needs no PDF dictionary knowledge and works on its own. |
There was a problem hiding this comment.
Nop. This is not a changelog and no need to justify
| // generated, so it can't close over outside variables, and only plain | ||
| // function syntax (not arrow functions or other syntax Acrobat's engine | ||
| // may not support) should be relied on. | ||
| const js = |
There was a problem hiding this comment.
Keep it simple, pass the base minimum arguments to get it working
| "require": "./js/output.cjs", | ||
| "default": "./js/output.mjs" | ||
| }, | ||
| "./types/acrobat-js": { |
What kind of change does this PR introduce?
Feature. Fixes #1792.
A small, purpose-built option, along the lines invited in
docs/forms.md's Advanced Form Field Use section ("If an option is not supported, open an issue on Github and it will be considered for addition to the API").Context
There's no supported way to attach a mouse-up JavaScript action to a form field — most usefully, a push button that runs custom logic when clicked. The only path that ever reaches
AAismapFormat(), and only together with aformatoption, which is meant for keystroke/format validation, not arbitrary actions.That's deliberate, not an oversight: pdfkit's docs explicitly say the handful of raw dictionary escape hatches still recognized (
Ff,MK.CA,AA-with-format) are discouraged and may be removed. So rather than widening that raw access further, this adds a dedicated option instead.The change
Adds an
onClickoption, accepted by all form annotation methods, mapped by a newmapActions(options, pdfObject)step (mirroring the other unconditional mappers) that sets the field'sAA.Umouse-up action.mapFormat()still runs afterward and extends the sameAAdictionary with format-validation actions when aformatoption is also given, so that combination keeps working.onClickaccepts either a plain string or a function. A function is stringified and invoked withthisbound to the Document (exactly as Acrobat itself binds it in any field action) and Acrobat's ownapp,getField,displayandeventpassed in as arguments — the same pattern tools like Puppeteer use forpage.evaluate(fn). It still runs inside the PDF viewer's own JavaScript engine, not wherever the PDF was generated, so it can't close over outside variables.Passing the globals as parameters, rather than the more obvious route of declaring them as ambient TypeScript globals, is deliberate: a global
eventcollides with the DOM lib's own deprecatedwindow.eventin any project with"dom"in itslibarray, which I only found by actually trying it. Parameters sidestep that entirely — nothing is declared globally, so there's nothing to collide with.A new
types/acrobat-js.d.ts(exported viapackage.json'sexportsmap) gives TypeScript projects real types for this signature, kept separate from pdfkit's own types so nothing is pulled in just by installing pdfkit:This is deliberately a minimal, best-effort common subset (
app,getField,display,event, the Documentthis), not a full Acrobat SDK type surface — documented as such, with contributions welcome to extend it.Demo
Attached: a minimal PDF pair (a push button with an
onClickaction, before/after this change) plus screenshots from Adobe Acrobat/Reader. Before: clicking the button does nothing. After: it shows an alert.Testing
yarn test:unit— all existing tests pass unchanged, plus new ones: a push button with a stringonClick, one with a functiononClick, and the combinedonClick+formatcase.yarn lint/yarn format— clean.node) andnode16TypeScript module resolution, and against a project with"dom"inlib, using a throwaway project outside this repo (not part of the diff).Checklist:
cc @blikblum for review.