EpubScriptSession
Runs the scripts of a book's chapters over the library's own parse and layout (#41).
Each chapter is a window of its own, with its own engine from engineFor. Its scripts see a DOM over the chapter: the document and its elements, events, timers, console and an in-memory localStorage for the book. They run the first time the chapter opens, in document order, and a script that changes the chapter has it laid out again from the changed tree once the script returns, with the pages that it gains or loses.
The document that an iframe of a chapter shows from the book is a window of its own too, with an engine from engineFor for the chapter, opened and closed with the chapter's (#528). The chapter and its frames see each other as windows of another origin, so a frame's scripts cannot reach the chapter. They talk through postMessage and message ports, which the session carries between the engines (#613). With liveChapters at one, frames run no script, since their engines would share the thread with the chapter's.
Nothing a script does reaches outside the book: there is no fetch or XMLHttpRequest, a script at an address outside the book does not run, and a change of location goes to onNavigate listeners as a link would.
val session = EpubScriptSession(book, engineFor = { MyEngine() })
session.chapterOpened(0)
session.tap(book.page(KiteLocation(0, 0)), x = 52.5, y = 90.0)The session calls its engines on the caller's thread, so call it from the one thread they belong to. EpubScriptRunner of kitepdf-javascript opens KiteJS engines on a thread of its own and does that for a viewer, which calls from many threads.
The scripts' changes belong to the book: another document over it, at another font size, lays the changed chapters out too. They last as long as the book is open; close closes the engines but leaves the changed chapters as they are.
At most liveChapters chapters keep their scripts running, as a reading system unloads the chapters the reader left (#498). Opening one more closes the engine of the chapter used least recently, whose pages keep what its scripts made of them. When that chapter opens again, its scripts start over from its own markup, as a page does when it loads again, and so does a chapter that an earlier session's scripts changed. unloadChapters closes them all at once.
Parameters
opens the engine of one chapter's scripts, the first time it opens. The session closes it in close, or when it makes room for another chapter. An engine that will not open is a failure of that chapter, whose scripts then do not run. The first script the session evaluates in it is always the session's own DOM, before any of the book's, so a host that limits how long the book's scripts run can leave that one out (#554).
how many chapters' engines may be open at once, at least one. One suits engines that cannot share a thread with another open engine.
gets what scripts print with console, and what alert, confirm and prompt would have shown, with the level or the dialog's name.
milliseconds on a clock that only goes forward, for the timers and performance.now(). Leave it unset for the system's own.
a value the app keeps for its reader, such as an install id, which goes into the book's origin. EPUB 3.3 asks for an origin of each reader's copy, so another reader's copy of the book cannot reach this one's storage. Without one the session makes a random key, and the origin lasts as long as the session.
the outline of a run of text in a host font, in glyph space as KiteCanvas.hostGlyphOutline answers it. A canvas's getImageData and toDataURL draw text with it. Without it, text reads back as blank.
Constructors
Properties
The scripts that failed since the session opened, newest last: a throw, a parse error or the engine's limit. It keeps the last MAX_FAILURES, since a timer that throws each time it runs would otherwise grow it for as long as the book is open.
Functions
The reader reached a page of chapter: run its scripts, the first time only, then fire DOMContentLoaded and load. A viewer calls this for a chapter that EpubDocument.isScripted says has scripts.
Calls listener when a script asks to go somewhere: it set location, called open, or clicked a link itself. A place in the book comes as a zip path with its fragment, as EpubLink.href gives one, and anything else as written. Returns a function that stops the listening.
Calls listener when a script sets or clears a timer, from the thread the script runs on, and returns a function that stops the listening.
Runs the timers and animation frames that scripts set and that are due, and answers how long to wait before the next one in milliseconds, or null when none waits. nowMillis is the viewer's frame time; a handler may measure its timers on a clock of its own.
The reader tapped page at (x, y), in display space: the scripts of its chapter get a click on the element there, after pointerdown, mousedown, pointerup and mouseup. Runs the chapter's scripts first when it has not opened. Returns true when a script prevented the default of the click, so that the viewer does not follow a link there.
Closes every chapter's engine and keeps the session open, as a reading system unloads the chapters it has to. Each keeps what its scripts made of it, and when it is next used its scripts start over from its markup, as when it makes room for another chapter. A host whose engines share one thread with another session's calls it to make room there.