Package detail

r2-navigator-js

readium6.2kBSD-3-Clause1.24.0

Readium 2 'navigator' for NodeJS (TypeScript)

readium, readium2, navigator, EPUB

readme

NodeJS / TypeScript Readium-2 "navigator" component

NodeJS implementation (written in TypeScript) for the navigator module of the Readium2 architecture ( https://github.com/readium/architecture/ ).

License

Build status

NPM David

Changelog

Prerequisites

1) https://nodejs.org NodeJS >= 8, NPM >= 5 (check with command line node --version and npm --version) 2) OPTIONAL: https://yarnpkg.com Yarn >= 1.0 (check with command line yarn --version)

GitHub repository

https://github.com/readium/r2-navigator-js

There is no github.io site for this project (no gh-pages branch).

NPM package

https://www.npmjs.com/package/r2-navigator-js

Command line install:

npm install r2-navigator-js OR yarn add r2-navigator-js

...or manually add in your package.json:

  "dependencies": {
    "r2-navigator-js": "latest"
  }

The JavaScript code distributed in the NPM package is usable as-is (no transpilation required), as it is automatically-generated from the TypeScript source.

Several ECMAScript flavours are provided out-of-the-box: ES5, ES6-2015, ES7-2016, ES8-2017:

https://unpkg.com/r2-navigator-js/dist/

(alternatively, GitHub mirror with semantic-versioning release tags: https://github.com/edrlab/r2-navigator-js-dist/tree/develop/dist/ )

The JavaScript code is not bundled, and it uses require() statement for imports (NodeJS style).

More information about NodeJS compatibility:

http://node.green

Note that web-browser Javascript is currently not supported (only NodeJS runtimes).

The type definitions (aka "typings") are included as *.d.ts files in ./node_modules/r2-navigator-js/dist/**, so this package can be used directly in a TypeScript project.

Example usage:

// currently no index file
// import { * } from "r2-navigator-js";

// ES5 import (assuming node_modules/r2-navigator-js/):
import { trackBrowserWindow } from "r2-navigator-js/dist/es5/src/electron/main/browser-window-tracker";

// ... or alternatively using a convenient path alias in the TypeScript config (+ WebPack etc.):
import { trackBrowserWindow } from "@r2-navigator-js/electron/main/browser-window-tracker";

Dependencies

https://david-dm.org/readium/r2-navigator-js

A package-lock.json is provided (modern NPM replacement for npm-shrinkwrap.json).

A yarn.lock file is currently not provided at the root of the source tree.

Continuous Integration

TODO (unit tests?) https://travis-ci.org/readium/r2-navigator-js

Badge: [![Travis](https://travis-ci.org/readium/r2-navigator-js.svg?branch=develop)](https://travis-ci.org/readium/r2-navigator-js)

Version(s), Git revision(s)

NPM package (latest published):

https://unpkg.com/r2-navigator-js/dist/gitrev.json

Alternatively, GitHub mirror with semantic-versioning release tags:

https://raw.githack.com/edrlab/r2-navigator-js-dist/develop/dist/gitrev.json

Developer Primer

Quick Start

Command line steps (NPM, but similar with YARN):

1) cd r2-navigator-js 2) git status (please ensure there are no local changes, especially in package-lock.json and the dependency versions in package.json) 3) rm -rf node_modules (to start from a clean slate) 4) npm install, or alternatively npm ci (both commands initialize the node_modules tree of package dependencies, based on the strict package-lock.json definition) 5) npm run build:all (invoke the main build script: clean, lint, compile) 6) ls dist (that's the build output which gets published as NPM package)

Local Workflow (NPM packages not published yet)

Strictly-speaking, a developer needs to clone only the GitHub repository he/she wants to modify code in. However, for this documentation let's assume that all r2-xxx-js GitHub repositories are cloned, as siblings within the same parent folder. The dependency chain is as follows: r2-utils-js - r2-lcp-js - r2-shared-js - r2-opds-js - r2-streamer-js - r2-navigator-js - r2-testapp-js (for example, this means that r2-shared-js depends on r2-utils-js and r2-lcp-js to compile and function properly). Note that readium-desktop can be cloned in there too, and this project has the same level as r2-testapp-js in terms of its r2-XXX-js dependencies.

1) cd MY_CODE_FOLDER 2) git clone https://github.com/readium/r2-XXX-js.git (replace XXX for each repository name mentioned above) 3) cd r2-XXX-js && npm install && npm run build:all (the order of the XXX repositories does not matter here, as we are just pulling dependencies from NPM, and testing that the build works) 4) Now change some code in r2-navigator-js (for example), and invoke npm run build (for a quick ES8-2017 build) or npm run build:all (for all ECMAScript variants). 5) To update the r2-navigator-js package in r2-testapp-js without having to publish an official package with strict semantic versioning, simply invoke npm run copydist. This command is available in each r2-XXX-js package to "propagate" (compiled) code changes into all dependants. 6) From time to time, an r2-XXX-js package will have new package dependencies in node_modules (for example when npm install --save is used to fetch a new utility library). In this case ; using the r2-navigator-js example above ; the new package dependencies must be manually copied into the node_modules folder of r2-testapp-js, as these are not known and therefore not handled by the npm run copydist command (which only cares about propagating code changes specific to r2-XXX-js packages). Such mismatch may typically occur when working from the develop branch, as the formal package-lock.json definition of dependencies has not yet been published to NPM. 7) Lastly, once the r2-navigator-js code changes are built and copied across into r2-testapp-js, simply invoke npm run electron PATH_TO_EPUB to launch the test app and check your code modifications (or with readium-desktop use npm run start:dev).

Programmer Documentation

An Electron app has one main process, and potentially several renderer processes (one per BrowserWindow). In addition, there is a separate runtime for each webview embedded inside each BrowserWindow (this qualifies as a renderer process too). Communication between processes occurs via Electron's IPC asynchronous messaging system, as the runtime contexts are otherwise isolated from each other. Each process launches its own Javascript code bundle. There may be identical / shared code between bundles, but the current state of a given context may differ from the state of another. Internally, state synchronisation between isolated runtimes is performed using IPC, or sometimes by passing URL parameters as this achieves a more instant / synchronous behaviour.

Most of the navigator API surface (i.e. exposed functions) relies on the fact that each process is effectively a runtime "singleton", with a ongoing state during its lifecycle. For example, from the moment a BrowserWindow is opened (e.g. the "reader" view for a given publication), a renderer process is spawned, and this singleton runtime maintains the internal state of the navigator "instance" (this includes the DOM window itself). This explains why there is no object model in the navigator design pattern, i.e. no const nav = new Navigator() calls.

Electron main process

Session initialization

// ES5 import (assuming node_modules/r2-navigator-js/):
import { initSessions, secureSessions } from "r2-navigator-js/dist/es5/src/electron/main/sessions";

// ... or alternatively using a convenient path alias in the TypeScript config (+ WebPack etc.):
import { initSessions, secureSessions } from "@r2-navigator-js/electron/main/sessions";

// Calls Electron APIs to setup sessions/partitions so that local storage (etc.)
// for webviews are sandboxed adequately, and to ensure resources are freed when the
// application shuts down.
// Also initializes the custom URL protocol / scheme used under the hood to ensure
// that individual publications have unique origins (to avoid inadvertantly sharing
// localStorage, IndexedDB, etc.)
//  See `convertCustomSchemeToHttpUrl()` and `convertHttpUrlToCustomScheme()` below.
initSessions(); // uses app.on("ready", () => {}) internally

app.on("ready", () => {

  // `streamerServer` is an instance of the Server class, see:
  // https://github.com/readium/r2-streamer-js/blob/develop/README.md
  const streamerServer = new Server( ... ); // r2-streamer-js

  // This sets up the Electron hooks that protect the transport layer by adding encrypted headers
  // in every request (see `streamerServer.getSecureHTTPHeader()`).
  // This relies on the private encryption key managed by `r2-streamer-js` (in secure mode),
  // which is also used for the self-signed HTTPS certificate.
  if (streamerServer.isSecured()) {
    secureSessions(streamerServer);
  }
}

URL scheme conversion

import { READIUM2_ELECTRON_HTTP_PROTOCOL, convertHttpUrlToCustomScheme, convertCustomSchemeToHttpUrl }
  from "@r2-navigator-js/electron/common/sessions";

if (url.startsWith(READIUM2_ELECTRON_HTTP_PROTOCOL)) {

  // These functions convert back and forth between regular HTTP
  // (for example: https://127.0.0.1:3000/pub/PUB_ID/manifest.json)
  // and the custom URL protocol / scheme used under the hood to ensure
  // that individual publications have unique origins (to avoid inadvertantly sharing
  // localStorage, IndexedDB, etc.)
  const urlHTTP = convertCustomSchemeToHttpUrl(urlCustom);
} else {

  // Note that it is crucial that the passed URL has a properly-encoded base64 "PUB_ID",
  // which typically escapes `/` and `=` charaecters that are problematic in URL path component
  // as well as domain/authority (which the custom URL scheme leverages to create unique PUB_ID origins).
  const urlCustom = convertHttpUrlToCustomScheme(urlHTTP);
}

Electron browser window tracking

import { trackBrowserWindow } from "@r2-navigator-js/electron/main/browser-window-tracker";

app.on("ready", () => {

  const electronBrowserWindow = new BrowserWindow({
    // ...
  });
  // This tracks created Electron browser windows in order to
  // intercept / hijack clicked hyperlinks in embedded content webviews
  // (e.g. user navigation inside EPUB documents)
  // Note that hyperlinking can work without this low-level,
  // Electron-specific mechanism (using DOM events),
  // but this is a powerful "native" interceptor that will listen to
  // navigation events triggered by non-interactive links (e.g. scripted / programmatic redirections)
  trackBrowserWindow(electronBrowserWindow);
}

Readium CSS configuration (streamer-level injection)

import { IEventPayload_R2_EVENT_READIUMCSS } from "@r2-navigator-js/electron/common/events";
import {
    readiumCSSDefaults,
} from "@r2-navigator-js/electron/common/readium-css-settings";
import { setupReadiumCSS } from "@r2-navigator-js/electron/main/readium-css";

app.on("ready", () => {
  // `streamerServer` is an instance of the Server class, see:
  // https://github.com/readium/r2-streamer-js/blob/develop/README.md
  const streamerServer = new Server( ... ); // r2-streamer-js

  // `readiumCSSPath` is a local filesystem path where the folder that contains
  // ReadiumCSS assets can be found. `path.join(process.cwd(), ...)` or `path.join(__dirname, ...)`
  // can be used depending on integration / bundling context. The HTTP server will create a static hosting
  // route to this folder.
  setupReadiumCSS(streamerServer, readiumCSSPath, getReadiumCss);
  // `getReadiumCss` is a function "pointer" that will be called when the navigator
  // needs to obtain an up-to-date ReadiumCSS configuration (this is for initial injection in HTML documents,
  // via the streamer/server). Note that subsequent requests will originate from the renderer process,
  // whenever the webview needs to (see further below):
  const getReadiumCss = (publication: Publication, link: Link | undefined): IEventPayload_R2_EVENT_READIUMCSS => {

    // The built-in default values.
    // The ReadiumCSS app-level settings would typically be persistent in a store.
    const readiumCssKeys = Object.keys(readiumCSSDefaults);
    readiumCssKeys.forEach((key: string) => {
        const value = (readiumCSSDefaults as any)[key];
        console.log(key, " => ", value);
        // fetch values from app store ...
    });

    // See `electron/common/readium-css-settings.ts` for more information,
    // including links to the ReadiumCSS exhaustive documentation.
    return {
      setCSS: {
        ...
        fontSize: "100%",
        ...
        textAlign: readiumCSSDefaults.textAlign,
        ...
      } // setCSS can actually be undefined, in which case this disables ReadiumCSS completely.
    };
  };
}

Electron renderer process(es), for each Electron BrowserWindow

Navigator initial injection

import {
    installNavigatorDOM,
} from "@r2-navigator-js/electron/renderer/index";

// This function attaches the navigator HTML DOM and associated functionality
// to the app-controlled Electron `BrowserWindow`.
installNavigatorDOM(
    publication, // Publication object (see below for an example of how to create it)
    publicationURL, // For example: "https://127.0.0.1:3000/PUB_ID/manifest.json"
    rootHtmlElementID, // For example: "rootdiv", assuming <div id="rootdiv"></div> in the BrowserWindow HTML
    preloadPath, // See below.
    location); // A `Locator` object representing the initial reading bookmark (can be undefined/null)

// The string parameter `preloadPath` is the path to the JavaScript bundle created for
// `r2-navigator-js/src/electron/renderer/webview/preload.ts`,
// for example in development mode this could be (assuming EcmaScript-6 / ES-2015 is used):
// "node_modules/r2-navigator-js/dist/es6-es2015/src/electron/renderer/webview/preload.js",
// whereas in production mode this would be the copied JavaScript bundle inside the Electron app's ASAR:
// `"file://" + path.normalize(path.join((global as any).__dirname, preload.js))`
// (typically, the final application package contains the following JavaScript bundles:
// `main.js` alonside `renderer.js` and `preload.js`)

// Here is a typical example of how the Publication object (passed as first parameter) is created:
import { Publication } from "@r2-shared-js/models/publication";

import { TaJsonDeserialize } from "@r2-lcp-js/serializable";

const response = await fetch(publicationURL);
const publicationJSON = await response.json();
const publication = TaJsonDeserialize<Publication>(publicationJSON, Publication);

Readium CSS configuration (after stream-level injection)

import {
    setReadiumCssJsonGetter
} from "@r2-navigator-js/electron/renderer/index";
import {
    readiumCSSDefaults
} from "@r2-navigator-js/electron/common/readium-css-settings";
import {
    IEventPayload_R2_EVENT_READIUMCSS,
} from "@r2-navigator-js/electron/common/events";

// `getReadiumCss` is a function "pointer" (callback) that will be called when the navigator
// needs to obtain an up-to-date ReadiumCSS configuration ("pull" design pattern).
// Unlike the equivalent function in the main process
// (which is used for the initial injection in HTML documents, via the streamer/server), this one handles
// requests by the actual content viewport, in an on-demand fashion:
const getReadiumCss = (publication: Publication, link: Link | undefined): IEventPayload_R2_EVENT_READIUMCSS => {

  // The built-in default values.
  // The ReadiumCSS app-level settings would typically be persistent in a store.
  const readiumCssKeys = Object.keys(readiumCSSDefaults);
  readiumCssKeys.forEach((key: string) => {
      const value = (readiumCSSDefaults as any)[key];
      console.log(key, " => ", value);
      // fetch values from app store ...
  });

  // See `electron/common/readium-css-settings.ts` for more information,
  // including links to the ReadiumCSS exhaustive documentation.
  return {

    // `streamerServer` is an instance of the Server class, see:
    // https://github.com/readium/r2-streamer-js/blob/develop/README.md
    // This is actually an optional field (i.e. can be undefined/null),
    // if not provided, `urlRoot` defaults to `window.location.origin`
    // (typically, https://127.0.0.1:3000 or whatever the port number happens to be):
    urlRoot: streamerServer.serverUrl(),

    setCSS: {
      ...
      fontSize: "100%",
      ...
      textAlign: readiumCSSDefaults.textAlign,
      ...
    } // setCSS can actually be undefined, in which case this disables ReadiumCSS completely.
  };
};
setReadiumCssJsonGetter(getReadiumCss);
import {
    readiumCssOnOff,
} from "@r2-navigator-js/electron/renderer/index";

// This function simply tells the navigator that the ReadiumCSS settings have changed
// (for example when the user used the configuration panel to choose a font size).
// Following this call (in an asynchronous manner) the navigator will trigger a call
// to the function previously registered via `setReadiumCssJsonGetter()` (see above).
readiumCssOnOff();

EPUB reading system information

import {
    setEpubReadingSystemInfo
} from "@r2-navigator-js/electron/renderer/index";

// This sets the EPUB3 `navigator.epubReadingSystem` object with the provided `name` and `version` values:
setEpubReadingSystemInfo({ name: "My R2 Application", version: "0.0.1-alpha.1" });

Logging, redirection from web console to shell

// This should not be called explicitly on the application side,
// as this is already handled inside the navigator context! (this is currently not configurable)
// This automatically copies web console messages from the renderer process
// into the shell ouput (where logging messages from the main process are emitted):
import { consoleRedirect } from "@r2-navigator-js/electron/renderer/console-redirect";

// By default, the navigator calls the console redirector in both embedded webviews (iframes)
// and the central index (renderer process):
const releaseConsoleRedirect = consoleRedirect(loggingTag, process.stdout, process.stderr, true);
// loggingTag ===
// "r2:navigator#electron/renderer/webview/preload"
// and
// "r2:navigator#electron/renderer/index"

Reading location, linking with locators

import {
    LocatorExtended,
    getCurrentReadingLocation,
    setReadingLocationSaver
} from "@r2-navigator-js/electron/renderer/index";

// `saveReadingLocation` is a function "pointer" (callback) that will be called when the navigator
// needs to notify the host app that the user's reading location has changed ("push" design pattern).
// This function call is debounced inside the navigator, to avoid flooding the application with
// many calls (and consequently putting unnecessary strain on the store/messaging system required to
// handle the renderer/main process communication).
// A typical example of when this function is called is when the user scrolls the viewport using the mouse
// (debouncing is every 250ms on the trailing edge,
// so there is always a 250ms delay before the first notification).
const saveReadingLocation = (location: LocatorExtended) => {
  // Use an application store to make `location` persistent
  // ...
};
setReadingLocationSaver(saveReadingLocation);

// This returns the last reading location as a `LocatorExtended` object (can be undefined).
// This is equal to the last object received in the `setReadingLocationSaver()` callback (see above)
const loc = getCurrentReadingLocation();
// Typically, the `LocatorExtended` data structure will be used to store "bookmarks",
// to render a user interface that provides information about the document (e.g. page "numbers"),
// or to display an interactive "timeline" / linear scrub bar
// to rapidely navigate the publication spine / reading order.

// Here is a typical usage example for LocatorExtended.locator.href:
// (null/undefined sanity checks removed, for brevity)

let _publication: Publication; // set somewhere else
const locatorExtended = getCurrentReadingLocation();

// That's the HTML <title /> (inside the <head />)
console.log(locatorExtended.locator.title);

let foundLink = _publication.Spine.find((link, i) => {
    return link.Href === locatorExtended.locator.href;
});
if (!foundLink) {
    // a publication document is not necessarily the spine / reading order
    foundLink = _publication.Resources.find((link) => {
        return link.Href === locatorExtended.locator.href;
    });
}
// then, use `foundLink` as needed ...
// `LocatorExtended.locations.cssSelector` is a CSS Selector that points to an HTML element,
// (i.e. the reading location / bookmarked reference)
// and it can be used as-is to restore this using the `handleLinkLocator()` function (see below).

// `LocatorExtended.locations.cfi` is provided as "read-only" information,
// in the sense that it is not used when ingested back into the navigator via `handleLinkLocator()`.
// In other words, setting the CFI field to undefined or another string has no effects when passing the parameter.

// `LocatorExtended.locations.position` is not currently supported / implemented,
// and as with the CFI field, it can be ignored when feeding back into the navigator API.

// `LocatorExtended.locations.progression` is a percentage (floating point number [0, 1])
// representing the reading location inside a single document,
// so for fixed layout this has no effect. However, reflowable documents are either scrolled or paginated,
// so the progression percentage represents how much vertical scrolling / horizontal panning there is.
// This progression field can be used to ask the navigator to set a specific reading placement
// using `handleLinkLocator()` (see further below).
// Typically, for paginated reflowable documents,
// the calculation of a desired progression could be mapped to "page" information (columns). See below.
// When a reflowable document is currently presented in a paginated view,
// `LocatorExtended.paginationInfo` reports the current `totalColumns` (number of single "pages"),
// `currentColumn` (a zero-based index between [0, totalColumns-1]),
// and if `isTwoPageSpread` is true, then `spreadIndex` reports the zero-based index
// of the currently-visible two-page spread.
// `LocatorExtended.docInfo` reports `isFixedLayout`, `isRightToLeft` and `isVerticalWritingMode`
// which are self-explanatory.
// `LocatorExtended.docInfo` reports `isFixedLayout`, `isRightToLeft` and `isVerticalWritingMode`
// which are self-explanatory.
// Note that `LocatorExtended.selectionInfo` is currently a prototype concept, not a stable API.
// However, this already provides an accurate representation of user selection / character ranges,
// which will ; in a future release of r2-navigator-js ; be connected to a highlights / annotations
// subsystem (i.e. minimal, but stable / robust functionality).
// For convenience, here is the fully-expanded `LocatorExtended` data structure:
interface LocatorExtended {
    locator { //Locator
        href: string;
        title?: string;
        text?: { //LocatorLocations
            before?: string;
            highlight?: string;
            after?: string;
        };
        locations { //LocatorLocations
            cfi?: string;
            cssSelector?: string;
            position?: number;
            progression?: number;
        };
    };
    paginationInfo { //IPaginationInfo
        totalColumns: number | undefined;
        currentColumn: number | undefined;
        isTwoPageSpread: boolean | undefined;
        spreadIndex: number | undefined;
    };
    docInfo { //IDocInfo
        isFixedLayout: boolean;
        isRightToLeft: boolean;
        isVerticalWritingMode: boolean;
    };
    selectionInfo { //ISelectionInfo
        rangeInfo { //IRangeInfo
            startContainerElementCssSelector: string;
            startContainerChildTextNodeIndex: number;
            startOffset: number;

            endContainerElementCssSelector: string;
            endContainerChildTextNodeIndex: number;
            endOffset: number;

            cfi: string | undefined;
        };
        cleanText: string;
        rawText: string;
    };
}
import {
  handleLinkLocator,
  handleLinkUrl
} from "@r2-navigator-js/electron/renderer/index";

// The `handleLinkUrl` function is used to instruct the navigator to load
// an absolute URL, either internal to the current publication,
// or external. For example:
// const href = "https://127.0.0.1:3000/PUB_ID/contents/chapter1.html";
// or:
// const href = "https://external-domain.org/out-link";
handleLinkUrl(href);

// A typical use-case is the publication's Table Of Contents.
// Each spine/readingOrder item is a `Link` object with a relative href (see `r2-shared-js` models).
// The final absolute URL may be computed simply by concatenating the publication's manifest.json URL:
// (although it is recommended to use a URL/URI library in order to handle query parameters, etc.)
const href = publicationURL + "/../" + link.Href;
// For example:
// publicationURL === "https://127.0.0.1:3000/PUB_ID/manifest.json"
// link.Href === "contents/chapter1.html"

// This can be used to restore a bookmark previously saved via `getCurrentReadingLocation()` (see above).
handleLinkLocator(locator);

// `locator.href` is obviously required.
// `locator.locations.cssSelector` can be used as-is (as provided by a prior call to `getCurrentReadingLocation()`)
// in order to restore a saved reading location.
// Alternatively, `locator.locations.progression` (percentage) can be used to pan/shift to a desired reading location,
// based on pagination / scroll information (see description of `LocatorExtended.paginationInfo`, above).
import {
  getCurrentReadingLocation,
  isLocatorVisible
} from "@r2-navigator-js/electron/renderer/index";

const locEx = getCurrentReadingLocation();

// This function returns true (async promise) if the locator
// is fully or partially visible inside the viewport (scrolled or paginated).
// Always returns true for fixed layout publications / documents.
try {
    const visible = await isLocatorVisible(locEx.locator);
} catch (err) {
    console.log(err); // promise rejection
}

Navigating using arrow keys

import {
    navLeftOrRight
} from "@r2-navigator-js/electron/renderer/index";

// This function instructs the navigator to "turn the page" left or right.
// This is litterally in relation to the left-side or right-side of the display.
// In other words, the navigator automatically handles the fact that with Right-To-Left content,
// the left-hand-side "page turn" button (or associated left arrow keyboard key) means "progress forward".
// For example (no need to explicitly handle RTL conditions in this app code):
window.document.addEventListener("keydown", (ev: KeyboardEvent) => {
    if (ev.keyCode === 37) { // left
        navLeftOrRight(true);
    } else if (ev.keyCode === 39) { // right
        navLeftOrRight(false);
    }
});

Selection Highlighting

// The navigator maintains an ordered (visually-stacked) list of character-level highlights,
// during the lifespan of a loaded / rendered publication document. The app is responsible for instructing
// the navigator to instantiate these highlights, whenever a document is (re)loaded.
// There is no persistence at the level of the navigator, the state is constrained to the lifecycle
// of individual HTML documents. The navigator handles redrawing at the appropriate optimal times,
// for example when changing the font size. Highlights emit mouse click events which the app can listen to.

import {
    IHighlight,
    IHighlightDefinition,
} from "@r2-navigator-js/electron/common/highlight";
import {
    highlightsClickListen,
    highlightsCreate,
    highlightsRemove,
} from "@r2-navigator-js/electron/renderer/index";

// Use the setReadingLocationSaver() notification to detect when the user creates a new selection:
const saveReadingLocation = (location: LocatorExtended) => {

    if (location.selectionInfo && location.selectionIsNew) {
        // Note that a RGB `color` can be optionally specified in IHighlightDefinition (default is red-ish):
        const highlightToCreate = { selectionInfo: location.selectionInfo } as IHighlightDefinition;

        let createdHighlights: Array<IHighlight | null> | undefined;
        try {
            // The highlightsCreate() function takes an array of highlight definitions,
            // here we just pass a single one, derived from the user selection:
            createdHighlights = await highlightsCreate(location.locator.href, [highlightToCreate]);
        } catch (err) {
            console.log(err);
        }
        if (createdHighlights) {
            createdHighlights.forEach((highlight) => {
                if (highlight) {
                    // ...
                    // The visual highlight created in the navigator can be saved here in the app,
                    // so that it can be restored at a later stage, typically when reloading the document (href).
                }
            });
        }
    }
};
setReadingLocationSaver(saveReadingLocation);

// TIP: the app can detect when a new document has been loaded,
// in which case the saved / stored highlights (inside the app's persistence layer)
// must be re-instantiated inside the navigator:
let _lastSavedReadingLocationHref: string | undefined;
const saveReadingLocation = async (location: LocatorExtended) => {
    const hrefHasChanged = _lastSavedReadingLocationHref !== location.locator.href;
    _lastSavedReadingLocationHref = location.locator.href;

    // ...
    // here, invoke highlightsCreate() with the saved / stored highlights for this particular document (href)
};

// here we listen to mouse click events,
// and we destroy the clicked highlight:
highlightsClickListen((href: string, highlight: IHighlight) => {
    highlightsRemove(href, [highlight.id]);
    // ...
    // remove the persistent / stored / saved copy too!
});

Read aloud, TTS (Text To Speech), Synthetic Speech

import {
    TTSStateEnum,
    ttsClickEnable,
    ttsListen,
    ttsNext,
    ttsPause,
    ttsPlay,
    ttsPrevious,
    ttsResume,
    ttsStop,
} from "@r2-navigator-js/electron/renderer/index";

// When true, mouse clicks on text inside publication documents
// trigger TTS readaloud playback at the pointed location.
// The default is false. Once set to true, this setting persists
// for any new loading document within the same publication.
// This resets to false for any newly opened publication.
// The ALT key modifier triggers playback for the pointed DOM fragment only.
ttsClickEnable(false);

// Starts playing TTS read aloud for the entire document, from the begining of the document,
// or from the last-known reading location (i.e. currently visible in the viewport).
// This does not automatically move to the next document.
// If called when already playing, stops and starts again from the current location.
// Highlighted word-by-word synthetic speech is rendered inside a modal overlay
// with basic previous/next and timeline scrubber controls (which has instant text preview).
// The textual popup overlay receives mouse clicks to pause/resume playback.
// The main document text (in the background of the modal overlay) keeps track
// of the current playback position, and the top-level spoken fragment is highlighted.
// Note that long paragraphs/sections of text are automatically sentence-fragmented
// in order to generate short speech utterances.
// Also note that the engine parses DOM information in order to assign the correct language
// to utterances, thereby providing support for multilingual documents.
ttsPlay();

// Stops playback whilst maintaining the read aloud popup overlay,
// ready for playback to be resumed.
ttsPause();

// Resumes from a paused state, plays from the begining of the last-played utterance, and onwards.
ttsResume();

// Stops any ongoing playback and discards the popup modal TTS overlay.
// Cleans-up allocated resources.
ttsStops();

// Navigate backward / forward inside the stream of utterances scheduled for the current TTS playback.
// Equivalent to the command buttons left/right of the timeline scrubber located at the bottom of the read aloud overlay.
ttsPrevious();
ttsNext();

// Sets up a callback for event notifications from the read aloud state machine.
// Currently: TTS paused, stopped, and playing.
ttsListen((ttsState: TTSStateEnum) => {
  if (ttsState === TTSStateEnum.PAUSED) {
    // ...
  } else if (ttsState === TTSStateEnum.STOPPED) {
    // ...
  } else if (ttsState === TTSStateEnum.PLAYING) {
    // ...
  }
});

At this stage there are missing features: voice selection (depending on languages), volume, speech rate and pitch.

LCP

import { setLcpNativePluginPath } from "@r2-lcp-js/parser/epub/lcp";

// Registers the filesystem location of the native LCP library
const lcpPluginPath = path.join(process.cwd(), "LCP", "lcp.node");
setLcpNativePluginPath(lcpPluginPath);
import { IDeviceIDManager } from "@r2-lcp-js/lsd/deviceid-manager";
import { launchStatusDocumentProcessing } from "@r2-lcp-js/lsd/status-document-processing";
import { lsdLcpUpdateInject } from "@r2-navigator-js/electron/main/lsd-injectlcpl";

// App-level implementation of the LSD (License Status Document)
const deviceIDManager: IDeviceIDManager = {

    async checkDeviceID(key: string): Promise<string | undefined> {
        //...
    },

    async getDeviceID(): Promise<string> {
        //...
    },

    async getDeviceNAME(): Promise<string> {
        //...
    },

    async recordDeviceID(key: string): Promise<void> {
        //...
    },
};

// Assumes a `Publication` object already prepared in memory,
// loaded from `publicationFilePath`.
// This performs the LCP-compliant background operations to register the device,
// and to check for an updated license (as passed in the callback parameter).
// The lsdLcpUpdateInject() function can be used to immediately inject the updated
// LCP license (META-INF/license.lcpl) inside the EPUB container on the filesystem.
// Note that although the `launchStatusDocumentProcessing()` initializes `publication.LCP.LSD`,
// after `lsdLcpUpdateInject()` is invoked a fresh new `publication.LCP` object is created
// (which mirrors `META-INF/license.lcpl`), so `launchStatusDocumentProcessing()` must be called again (loop)
// to ensure the latest LSD is indeed loaded and verified.
// Below is an example of looping the `launchStatusDocumentProcessing()` calls in order to reset `publication.LCP.LSD`
// after `lsdLcpUpdateInject()` injects a fresh `publication.LCP` based on the downloaded `META-INF/license.lcpl`.
async function tryLSD(deviceIDManager: IDeviceIDManager, publication: Publication, publicationFilePath: string): Promise<boolean> {

    return new Promise(async (resolve, reject) => {
        try {
            await launchStatusDocumentProcessing(publication.LCP as LCP, deviceIDManager,
                async (licenseUpdateJson: string | undefined) => {

                    if (licenseUpdateJson) {
                        let res: string;
                        try {
                            res = await lsdLcpUpdateInject(
                                licenseUpdateJson,
                                publication as Publication,
                                publicationFilePath);

                            try {
                                await tryLSD(publication, publicationFilePath); // loop to re-init LSD
                                resolve(true);
                            } catch (err) {
                                debug(err);
                                reject(err);
                            }
                        } catch (err) {
                            debug(err);
                            reject(err);
                        }
                    } else {
                        resolve(true);
                    }
                });
        } catch (err) {
            debug(err);
            reject(err);
        }
    });
}
try {
    await tryLSD(publication, publicationFilePath);
} catch (err) {
    debug(err);
}

// A less-ideal alterative is to preserve the previous LSD,
// but in principle the new LCP may contain a LSD link that needs to be requested
// again in order to get the latest information available for this new license
// (e.g. associated LSD events list).
try {
    await launchStatusDocumentProcessing(publication.LCP, deviceIDManager,
        async (licenseUpdateJson: string | undefined) => {

            if (licenseUpdateJson) {
                const LSD_backup = publication.LCP.LSD; // LSD preservation, see comment above.

                let res: string;
                try {
                    res = await lsdLcpUpdateInject(
                        licenseUpdateJson,
                        publication as Publication,
                        publicationFilePath);

                    publication.LCP.LSD = LSD_backup; // LSD preservation, see comment above.
                } catch (err) {
                    debug(err);
                }
            }
        });
} catch (err) {
    debug(err);
}
import { downloadEPUBFromLCPL } from "@r2-lcp-js/publication-download";

// Downloads the EPUB publication referenced by given LCP license,
// injects the license at META-INF/license.lcpl inside the EPUB container,
// and returns the result as an array of two string values:
// first is the full destination filepath (should be path.join(destinationDirectory, destinationFileName))
// second is the URL where the EPUB was downloaded from ("publicatiion" link inside the LCP license)
try {
    let epub = await downloadEPUBFromLCPL(lcplFilePath, destinationDirectory, destinationFileName);
} catch (err) {
  debug(err);
}
import { doTryLcpPass } from "@r2-navigator-js/electron/main/lcp";

// This asks the LCP library to test an array of passphrases
// (or the SHA256 digest of the passphrases).
// The promise is rejected (try+catch) when no valid passphrase was found.
// The function returns the first valid passphrase.
try {
    const lcpPass = "my LCP passphrase";
    const validPass = await doTryLcpPass(
        publicationsServer,
        publicationFilePath,
        [lcpPass],
        isSha256Hex);

    let passSha256Hex: string | undefined;
    if (!isSha256Hex) {
        const checkSum = crypto.createHash("sha256");
        checkSum.update(lcpPass);
        passSha256Hex = checkSum.digest("hex");
    } else {
        passSha256Hex = lcpPass;
    }
} catch (err) {
    debug(err);
}
import { doLsdRenew } from "@r2-navigator-js/electron/main/lsd";
import { doLsdReturn } from "@r2-navigator-js/electron/main/lsd";

// LSD "renew" (with a specific end date)
try {
    const lsdJson = await doLsdRenew(
        publicationsServer,
        deviceIDManager,
        publicationFilePath,
        endDateStr);
} catch (err) {
    debug(err);
}

// LSD "return"
try {
    const lsdJson = await doLsdReturn(
        publicationsServer,
        deviceIDManager,
        publicationFilePath);
} catch (err) {
    debug(err);
}

// Both LSD "renew" and "return" interactions can return errors (i.e. Promise.reject => try/catch with async/await)
// when the server responds with HTTP statusCode < 200 || >= 300.
// The `err` object in the above code snippet can be a number (HTTP status code) when no response body is available.
// Otherwise, it can be an object with the `httpStatusCode` property (number) and httpResponseBody (string)
// when the response body cannot be parsed to JSON.
// Otherwise, it can be an object with the `httpStatusCode` property (number) and other arbitrary JSON properties,
// depending on the server response. Typically, compliant LCP/LSD servers are expected to return Problem Details JSON (RFC7807),
// which provides `title` `type` and `details` JSON properties.
// See https://readium.org/technical/readium-lsd-specification/#31-handling-errors

changelog

Next

Git diff:

Changes:

  • TODO

1.24.0

Build environment: NodeJS 22.17.0, NPM 11.5.2

Changes:

  • NPM package updates, (re)upgrading to Electron v37 which had to be downgraded to v36 in 1.23.0 due to audio/video streaming regression bug

Git revision info:

Git commit history:

Git diff:

1.23.2

Build environment: NodeJS 22.17.0, NPM 11.5.2

Changes:

  • Fix: popup footnotes trigger navigation history insert not only for originating hyperlink but also for "destination" which is the modal itself (just like when the actual HMTL target is accessed). This way, back/forward can trigger the modal instead of just uselessly landing on the hyperlink and doing nothing

Git revision info:

Git commit history:

Git diff:

1.23.1

Build environment: NodeJS 22.17.0, NPM 11.5.2

Changes:

  • Fixed-layout viewport meta width height can be float, not necessarily integer
  • Fixed-layout resize observer was triggered on scrollbar show/hide depending on CSS overflow auto/hidden of the scrolling publication viewport container of document webviews! (infinite loop)

Git revision info:

Git commit history:

Git diff:

1.23.0

Build environment: NodeJS 22.17.0, NPM 11.5.2

Changes:

  • NPM package updates ... unfortunately downgrade to Electron v36 (was v37) due to audio/video streak-seek regression bug

Git revision info:

Git commit history:

Git diff:

1.22.2

Build environment: NodeJS 22.17.0, NPM 11.4.2

Changes:

  • Fixed CSS Column pagination regression bug (Electron v37+)
  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.22.1

Build environment: NodeJS 22.14.0, NPM 11.4.2

Changes:

  • Fixed Japanese Ruby removed from selection text DOM Range (annotations, etc.)
  • Fixed scroll behaviour smooth must be forced to auto (fancy authored styles that mess up reading system behaviour)
  • Fixed focus in event which was triggered by programmatic element.focus() calls used internally to redirect keyboard focus and optionally to scroll into view (was interfering with fast scroll using space bar or arrow keys)
  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.22.0

Build environment: NodeJS 22.14.0, NPM 11.4.2

Changes:

  • Fixed Chinese RTL error
  • NPM package updates, notably Electron 37

Git revision info:

Git commit history:

Git diff:

1.21.1

Build environment: NodeJS 22.14.0, NPM 11.4.2

Changes:

  • Feature: added Colibrio CFI

Git revision info:

Git commit history:

Git diff:

1.21.0

Build environment: NodeJS 22.14.0, NPM 11.4.2

Changes:

  • NPM package updates, notably Electron v36

Git revision info:

Git commit history:

Git diff:

1.20.14

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fix: improved fixed-layout (EPUB FXL) rendering performance, opacity mask to blank out the temporary layout reset which is currently necessary to compute adjusted page slot positioning based on zoom level

Git revision info:

Git commit history:

Git diff:

1.20.13

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Locator rangeInfo becomes caretInfo with rangeInfo AND selectionInfo

Git revision info:

Git commit history:

Git diff:

1.20.12

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Removed left-over debug console logging!

Git revision info:

Git commit history:

Git diff:

1.20.11

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • NPM package updates
  • Fix: highlights edge case CSS column width-collapsed caret rectangles

Git revision info:

Git commit history:

Git diff:

1.20.10

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fix for empty inline or block page breaks with no content (only title / aria label) causing random layout shifts in CSS column paginated document when located before the initial block element in the DOM
  • Performance improvement: CSS Selector, CFI and XPath computation caching (lifetime = DOM, no invalidation, which is fine for short string attached to elements)
  • Fix: TTS play from element + textnode/char-offset now works not only on user click, but also from current reading location (rangeInfo)
  • Fixed concurrent page turn events and visibility calculations (random edge case hard to reproduce due to debounce timing)

Git revision info:

Git commit history:

Git diff:

1.20.9

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fixed EPUB3 Media Overlays: SMIL tree search for suitable start playback point based on current location HTML element ID ancestry as well as following IDs, also audio file with implicit clip-end based on natural stream ending

Git revision info:

Git commit history:

Git diff:

1.20.8

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • highlights floating popup: optional arrow (not used for bookmark indicators), margin indicator triggers inline highlight + associated floating popup, fixed innerHTML reset bug

Git revision info:

Git commit history:

Git diff:

1.20.7

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Feature: annotation and bookmark highlights with floating popup for meta text information on hover

Git revision info:

Git commit history:

Git diff:

1.20.6

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Hotfix: TTS centered scrolling highlight, making sure to avoid perfect centering with large non-TTS focus / scroll-into-view requests (e.g. images that don't fit the viewport, can cause yoyoing / jitter in edge cases)

Git revision info:

Git commit history:

Git diff:

1.20.5

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fix: ARIA-hidden highlights div
  • Fix: TTS centered scrolling highlight

Git revision info:

Git commit history:

Git diff:

1.20.4

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Feature: new bookmark-style margin indicators

Git revision info:

Git commit history:

Git diff:

1.20.3

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fix: RTL (arabic, hebrew, etc.) CSS columns pagination calculation of fragment visibility needed for hit-testing mouse click during TTS readaloud, when paragraph spans across page boundary (previous column)

Git revision info:

Git commit history:

Git diff:

1.20.2

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fix: scrolling viewport triggers same-locator events so that bookmark visibility can be adjusted, uses sequential event ID numerical value to track changes
  • Fix: TTS fine-grain word/sentence/element focus restoration to avoid page shifting when paragraph spans across page boundary (previous CSS column)
  • Fix: more discrete current reading location outline (dotted now, and gray / silver like the hyperlink target destination which remains solid)
  • Fix: support for partial visibility calculation in paginated mode, helps trigger TTS when click on paragraph that spans across page boundary (previous CSS column)
  • Fix: rangeInfo locator was incorrectly synch'ed (was remembering last click instead of adjusting to current scroll/pan x+y hittest)

Git revision info:

Git commit history:

Git diff:

1.20.1

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fix: Japanese vertical writing mode + right to left was incorrectly hit-testing when scrolling (bad current reading location, EPUB MO and TTS start, etc.)
  • Fix: ping+pong events now guaranteed coupling/matching via ID (concurrency)

Git revision info:

Git commit history:

Git diff:

1.20.0

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • NPM package updates, notably Electron v35
  • Fixed edge-case EPUB FXL bug with some publications (highlights SVG container width)

Git revision info:

Git commit history:

Git diff:

1.19.5

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Removed heavy console log inadvertantly leftover in previous release!

Git revision info:

Git commit history:

Git diff:

1.19.4

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • EPUB3 Media Overlays (and DAISY2.02 DAISY3.0) synchronised text-audio can have no prerecorded audio for SMIL par, fallback on TTS

Git revision info:

Git commit history:

Git diff:

1.19.3

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fixed keyboard focus handling, screen reader scroll trigger (current reading location notification), selection change event
  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.19.2

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • TTS Japanese Ruby handling: no TTS speak of baseline but DOM Range render nonetheless. Also increased gap between text and underline (hoping to eliminate texture rendering artefacts on Windows)

Git revision info:

Git commit history:

Git diff:

1.19.1

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Fix for TTS highlight settings which were not persisted correctly across webviews/iframes within the same BrowserWindow session

Git revision info:

Git commit history:

Git diff:

1.19.0

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • Updated AccessibleDfA typeface (dyslexic)
  • Fix font sizing issues by adopting zoom technique from ReadiumCSS v2
  • Fix following element IDs blacklist logic
  • Added document relative path (RWPM / EPUB zip) to image zoom/pan click event

Git revision info:

Git commit history:

Git diff:

1.18.0

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • NPM package updates
  • Image zoom/pan API improvements
  • TTS highlights based on annotations engine now with additional opacity mask and ruler styles
  • TTS voice now handled with language mapping to reflect user preferences

Git revision info:

Git commit history:

Git diff:

1.17.5

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • NPM package updates
  • Reduced window resize debounce from 1s to 500ms

Git revision info:

Git commit history:

Git diff:

1.17.4

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • NPM package updates
  • Feature: disable continuous play = do not automatically play the next item, pause immediately after the current item has finished playing.

Git revision info:

Git commit history:

Git diff:

1.17.3

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • NPM package updates
  • Fix: Japanese Ruby TTS logic now speaks annotation when shown, or base when hidden (no need to rely on skippability which is used for other unrelated constructs such as page breaks)

Git revision info:

Git commit history:

Git diff:

1.17.2

Build environment: NodeJS 22.12.0, NPM 11.1.0

Changes:

  • NPM package updates
  • Feature: image click now delegates to optional application-level event handler, image zoom/pan feature still used as fallback
  • Minor (unused code): alignment with latest GoogleChromeLabs/text-fragments-polyfill revision, hidden=until-found

Git revision info:

Git commit history:

Git diff:

1.17.1

Build environment: NodeJS 22.12.0, NPM 11.0.0

Changes:

  • Feature: boolean setting to disable the temporary outline of navigation targets

Git revision info:

Git commit history:

Git diff:

1.17.0

Build environment: NodeJS 22.12.0, NPM 11.0.0

Changes:

  • NPM package updates, notably Electron 34
  • file:// URL electron.shell.openExternal() skip

Git revision info:

Git commit history:

Git diff:

1.16.7

Build environment: NodeJS 22.11.0, NPM 11.0.0

Changes:

  • fix: UTF8 XML BOM parse
  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.16.6

Build environment: NodeJS 22.11.0, NPM 11.0.0

Changes:

  • fix: breaking change in keyboard focus handling, was push model (from navigator) with hybrid pulls (from Thorium), now completely passive (application pushes requests to focus, decides when best depending on GUI interactions)
  • fix: restore footnote backlinks visibility (reversed decision, see https://github.com/edrlab/thorium-reader/issues/2478#issuecomment-2304782942 )
  • feat(dev): added Flox/Nix
  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.16.5

Build environment: NodeJS 22.11.0, NPM 10.9.0

Changes:

  • Added support for XPath (generation only, no consumption) in Locators, Selection / DOM Ranges

Git revision info:

Git commit history:

Git diff:

1.16.4

Build environment: NodeJS 22.11.0, NPM 10.9.0

Changes:

  • NPM package updates
  • DOM Range normalization modernized to align with Apache Annotator
  • Fixed SVG deep text TTS utterance builder
  • TTS readaloud escapability (SVG, table, table row, MathML, etc.)
  • TextFragment polyfill experimental code ported to Typescript (inactive placeholder, needs further testing as there are bugs from the original official Javascript implementation)

Git revision info:

Git commit history:

Git diff:

1.16.3

> Build environment: NodeJS 20.17.0, NPM 10.8.3

Changes:

  • Updated the technique used to append a blank pagination column after an odd (non even) number of columns when 2-page spreads are rendered (this removes the complex viewport shifting transform)
  • Disabled the visibility mask technique which never delivered satisfactory results
  • Replaced the buggy (Chromium) pure CSS computation of high-contrast foreground colour over highlighted text background (fixed TTS, annotations, search, etc.) with a simpler luminance-based calculation

Git revision info:

Git commit history:

Git diff:

1.16.2

> Build environment: NodeJS 20.17.0, NPM 10.8.3

Changes:

  • Fixed text finger selection which now triggers notification of current reading location (mouse / trackpad cursor and stylus worked fine, but touchscreen interactions were failing)
  • Fixed the inversed finger touch swipe direction (horizontal axis RTL / LTR)
  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.16.1

> Build environment: NodeJS 20.17.0, NPM 10.8.3

Changes:

  • LocatorExtended followingElementIDs only for Media Overlays and with length limit to avoid spamming the reading location notifications with useless heavy data (also fixed in Thorium)

Git revision info:

Git commit history:

Git diff:

1.16.0

> Build environment: NodeJS 20.17.0, NPM 10.8.3

Changes:

  • NPM package updates, notably Electron v32
  • CSS Highlights API for solid background, underline and strikethrough (retains SVG polygons for hit-testing and hover outline interactions, including margin display, but the CSS Highlights API controls text foreground/background contrast in the case of solid background, note that outline style remains entirely based on SVG)
  • Fixed CSS column pagination edge case: when column count is 2 but because of column width in Readium CSS in fact a single column is displayed (for example when shrinking the window or increasing the font size, the bug is immediately observable when displaying annotation highlights)

Git revision info:

Git commit history:

Git diff:

1.15.10

> Build environment: NodeJS 20.12.2, NPM 10.8.1

Changes:

  • fix: ReadiumCSS override was aggressively affecting GUI chrome injected in documents (generic div styling)
  • fix: keyboard focus handling (notably, ReadiumCSS setter was restoring reading location with focus steal)

Git revision info:

Git commit history:

Git diff:

1.15.9

> Build environment: NodeJS 20.12.2, NPM 10.8.1

Changes:

Git revision info:

Git commit history:

Git diff:

1.15.8

> Build environment: NodeJS 20.12.2, NPM 10.7.0

Changes:

  • Footnotes backlinks are now hidden
  • Fixed incorrect default content margins

Git revision info:

Git commit history:

Git diff:

1.15.7

> Build environment: NodeJS 20.12.2, NPM 10.7.0

Changes:

  • Added API function to disable (and re-enable if necessary) focus steal when publication documents are hyperlinked into (webview / iframe keyboard grab)
  • Fixed highlights engine: default drawtype is background, CSS mix blend mode now works in dark mode

Git revision info:

Git commit history:

Git diff:

1.15.6

> Build environment: NodeJS 20.12.2, NPM 10.7.0

Changes:

  • NPM package updates, Electron 30
  • Added ReadiumCSS custom selection and link colors (theme handling)

Git revision info:

Git commit history:

Git diff:

1.15.5

> Build environment: NodeJS 20.12.0, NPM 10.5.0

Changes:

  • NPM package updates, breaking change in the polygon lib (API getters)

Git revision info:

Git commit history:

Git diff:

1.15.4

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • New option to disable / hide Japanese Ruby superscript text

Git revision info:

Git commit history:

Git diff:

1.15.3

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • TTS readaloud fix: Japanese Ruby superscript RT/RP must not be highlighted (orange underline forbidden, yellow background ok). This logic generally applies to annotation highlights too (when not solid background or outline, i.e. underline and strikethrough), but as this is currently an early prototype preview in Thorium we label this change as mostly a TTS fix.

Git revision info:

Git commit history:

Git diff:

1.15.2

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Improved the prototype EPUB3 Media Overlays sign language video player by allowing the user to detach the video frame overlay into its own system window (simply by clicking on it), which can then be moved and resized outside of Thorium's own window bounds.

Git revision info:

Git commit history:

Git diff:

1.15.1

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Added prototype MVP EPUB3 Media Overlays video player (simple draggable overlay, not separate window)

Git revision info:

Git commit history:

Git diff:

1.15.0

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • WBR Word Break Opportunity for Japanese text, alternative to word-space-transform:ideographic-space CSS, using custom DOM element instead so word-space CSS property can be used as normal from ReadiumCSS
  • NPM package updates (Electron29 + Node20)

Git revision info:

Git commit history:

Git diff:

1.14.19

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Japanese: enable CSS letter-spacing (override ReadiumCSS recommendation), TTS readaloud Ruby RT/RP are now both ignored
  • CSS Selectors (reading location, bookmarks, etc.) now handle SVG and MathML namespace-prefixed element names

Git revision info:

Git commit history:

Git diff:

1.14.18

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Highlights / visual annotations rendering engine: now with outline/border decoration (other drawing types are: solid/block/background, underline, strikethrough/crossed-over)

Git revision info:

Git commit history:

Git diff:

1.14.17

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Adds support for character-level bookmarking / reading location, prevents page jumps in paginated mode when referencing a partially-visible DOM element at the beginning of the page spread (fixes search results highlights, and annotations too).

Git revision info:

Git commit history:

Git diff:

1.14.16

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Fixes highlights rendering engine, line-dependent decorations (underline, strikethrough)

Git revision info:

Git commit history:

Git diff:

1.14.15

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Highlights rendering engine fixes and optimisations: polygon holes and bounding boxes in margin indicators

Git revision info:

Git commit history:

Git diff:

1.14.14

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • Highlights rendering engine fixes: outline stroke was redundant, opacity was inconsistent

Git revision info:

Git commit history:

Git diff:

1.14.13

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • SVG rendering in the highlights engine to work around performance issues and problems with annotations crossing over page boundaries (bounding boxes).

Git revision info:

Git commit history:

Git diff:

1.14.12

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • TTS readaloud fix: now previous/next commands move to the respective preceding/following documents (only auto play was moving to the next spine item)
  • Numerous performance improvements and bugfixes in the highlights engine

Git revision info:

Git commit history:

Git diff:

1.14.11

> Build environment: NodeJS 20.11.0, NPM 10.4.0

Changes:

  • TTS readloud in SVG (PDF-like) fixed-layout pages, based on inner 'text' elements (excluding 'tspan' fragmentation which breaks words and sentences), also fixed concurrent highlights rendering.
  • Highlights (e.g. search results) display correctly in fixed layout and reflowable hybrid publications, also fixed window resizing bug, also ensure highlights are backed-up and restored during webview refresh that does not involve the application's own state.

Git revision info:

Git commit history:

Git diff:

1.14.10

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Fixed regression: goto progression percentage (click on Thorium's bottom bar) was broken due to async location.href hash # set and scroll reset
  • Fixed TTS readaloud dark / night mode highlights
  • Fixed TTS whitespace handling (offset highlights)
  • Improved TTS performance by passing native DOM Ranges to the highlighing engine instead of serialised format
  • Fixed collapsible highlight handling (should not affect TTS's own highlights, which are not tactile / interactive)

Git revision info:

Git commit history:

Git diff:

1.14.9

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • TTS readaloud improvement: click-on-text now plays instantly instead of pausing and expecting the user to click a second time to resume
  • TTS readaloud fix: significant whitespace handling, space between span elements sometimes wasn't preserved (mostly visible in the captions/simple view, but also underlying utterances sent to TTS engine)

Git revision info:

Git commit history:

Git diff:

1.14.8

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Improved highlights rendering engine: better performance (CSS class factorisation), better UX (less flickering, more visual contrast, mouse cursors for "proactive feedback" to announce the interactive lightweight affordances)

Git revision info:

Git commit history:

Git diff:

1.14.7

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Fix (minor): TTS readaloud focus/scroll-into-view throttled function incorrectly queued the arguments

Git revision info:

Git commit history:

Git diff:

1.14.6

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Fix: ReadiumCSS body width/height extent bugs (background colour was cropped)
  • Fix: avoid scroll jump when navigating inside already loaded page
  • Added highlights margin indicators (alt click to trigger, but will be controlled via app in future updates, to implement a proper affordance model with special behaviour associated with collapsed margin highlights)

Git revision info:

Git commit history:

Git diff:

1.14.5

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Right To Left fixes, mostly for mixed document directions in spine, and inconsistent direction between script and vertical writing mode (EPUB has package-level page-progression-direction in addition to document-level possible ways to declare direction, HTML attributes and CSS styles)

Git revision info:

Git commit history:

Git diff:

1.14.4

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Fixed hyperlinks handling during TTS and Media Overlays
  • Fixed pagination visibility regression bug introduced in previous release

Git revision info:

Git commit history:

Git diff:

1.14.3

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Fixed TTS and Media Overlays scrolling content / bad UX (also applies to text-only rendering). Now minimised viewport shifts and more reliable discovery of reading location (virtual click pointer into DOM "beginning" of visible viewport).

Git revision info:

Git commit history:

Git diff:

1.14.2

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Fixed Right To Left "current reading location" calculation (virtual click in corner without user interaction)
  • Fixed TTS bugs (pausing without resuming when turning pages)

Git revision info:

Git commit history:

Git diff:

1.14.1

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • Much improved support for Japanese Vertical Writing Mode and Right To Left direction
  • Fixed Media Overlays and TTS readaloud edge case bugs (failure to play or jumping back to begining) related to images without text, excluded elements like Ruby RT, unsynchronised text fragments, etc.

Git revision info:

Git commit history:

Git diff:

1.14.0

Build environment: NodeJS 20.10.0, NPM 10.2.5

Changes:

  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.13.9

Build environment: NodeJS 18.17.0, NPM 9.8.1

Changes:

  • TTS readaloud now supports "skippability" (like EPUB3 Media Overlays), typically page breaks identified by epub:type or ARIA role
  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.13.8

Build environment: NodeJS 18.17.0, NPM 9.8.1

Changes:

  • fix: handle role attribute as well as epub:type (just in case the latter is ommitted)
  • TTS fixes / features: aria-label on img in addition to alt attribute, epub:type pagebreak (and role) title/label takes precedence over inner text, same with links, japanese ruby RT are ignored
  • fix: Media Overlays interact click on images or text without sync media now continues playback at current timestamp instead of resuming from begining
  • fix: ensure image zoom outline is deactivated when entering media overlay or TTS playback
  • fix: tabbable CJS import was broken!
  • fix: image zoom UI chrome controls now match colour scheme + fixed-size (like main GUI)
  • chore: switch to updated CSS selector lib (better performance)
  • updated NPM packages

Git revision info:

Git commit history:

Git diff:

1.13.7

Build environment: NodeJS 18.17.0, NPM 9.8.1

Changes:

  • fix: popup dialog GUI (footnotes, image zoom, TTS + Media Overlays "captions" mode) forced to horizontal writing mode for chrome controls
  • fix: TTS pause from click-on-text now syncs properly (state was incorrectly STOPPED instead of PAUSE)
  • fix: TTS playback engine / state machine now handles hyperlinks and image zoom click properly
  • updated NPM packages

Git revision info:

Git commit history:

Git diff:

1.13.6

Build environment: NodeJS 18.16.1, NPM 9.8.0

Changes:

  • Image zoom feature: support for SVG markup island (foreign HTML5 namespace), which like fixed layout and images-inside-link require SHIFT key modifier to avoid interfering with authored hyperlinking or interactives.

Git revision info:

Git commit history:

Git diff:

1.13.5

Build environment: NodeJS 18.16.1, NPM 9.8.0

Changes:

  • Improved image zoom feature: in addition to HTML img@src (possibly SVG file instead of raster/bitmap) now SVG image@xlink:href too (if nested inside link, same logic as HTML a@href with shift-click modifier to bypass hyperlink activation)

Git revision info:

Git commit history:

Git diff:

1.13.4

Build environment: NodeJS 18.16.1, NPM 9.8.0

Changes:

  • Feature: image zoom with mouse wheel, trackpad and touch gestures (pinch stretch), panning, keyboard support
  • Feature: finger touch swipe gesture to turn pages / navigate left/right in book contents
  • Fix: in DEV mode, web inspector context menu was registering multiple times
  • Fix: mouse wheel middle click was opening Electron browser window
  • Fix: Electron now stricter with uncaught exceptions / rejected promises across IPC messaging system, must code fence properly for webview dom-ready state

Git revision info:

Git commit history:

Git diff:

1.13.3

Build environment: NodeJS 18.16.1, NPM 9.8.0

Changes:

  • Fix: audio playback rate HTML select > option dark/night mode was white-on-white background+foreground colours
  • Fix: hyperlink activation now causes a recording in navigation history of the origination without triggering an actual navigation (only activates the link into the destination, not the source)
  • Fix: ReadiumCSS text alignment inherit did not work in some cases, must be forced on body not just HTML root

Git revision info:

Git commit history:

Git diff:

1.13.2

Build environment: NodeJS 18.16.0, NPM 9.8.0

Changes:

  • HOTFIX (for the previous hotfix!): postinstall script runs in embedding context, fails to patch offending node_module lib

Git revision info:

Git commit history:

Git diff:

1.13.1

Build environment: NodeJS 18.16.0, NPM 9.8.0

Changes:

  • HOTFIX: ReadiumCSS was not copied into NPM published dist folder

Git revision info:

Git commit history:

Git diff:

1.13.0

Build environment: NodeJS 18.16.0, NPM 9.8.0

Changes:

  • NPM package updates (Electron 25)

Git revision info:

Git commit history:

Git diff:

1.12.4

Build environment: NodeJS 18.16.0, NPM 9.6.5

Changes:

  • NPM package updates
  • Fix: when SVG a@href animVal doesn't resolve to full absolute URL we explicitly prefix the # hash fragment identifier with the document location

Git revision info:

Git commit history:

Git diff:

1.12.3

Build environment: NodeJS 18.15.0, NPM 9.6.1

Changes:

  • NPM package updates
  • Fix: mouse cursor double-click on trailing edge of debounce (instead of leading / immediate) in order to correctly capture user selection (for bookmarks and annotations)

Git revision info:

Git commit history:

Git diff:

1.12.2

Build environment: NodeJS 18.14.2, NPM 9.5.1

Changes:

  • Fix: TTS voice selected is user-forced unless strict and loose language mismatch (allows variants override like en-US vs. en-UK, user wins over authored lang)

Git revision info:

Git commit history:

Git diff:

1.12.1

Build environment: NodeJS 18.14.2, NPM 9.5.1

Changes:

  • NPM package updates
  • Fix: TTS caption/simple mode was not escaping ampersand characters on initial render (before word boundaries)
  • Fix: HTML5 audio controls with authored percentage dimensions were invisible, now using revert!important to not only override ReadiumCSS, but also authored dimensions

Git revision info:

Git commit history:

Git diff:

1.12.0

Build environment: NodeJS 18.14.2, NPM 9.5.1

Changes:

  • Electron major version update (22 -> 23)
  • Feat: support for before/previous text in highlighted / selected DOM range (as always, cleaned-up text is with collapsed whitespace, raw is as authored including line breaks, tabulations, etc.)

Git revision info:

Git commit history:

Git diff:

1.11.6

Build environment: NodeJS 18.12.1, NPM 9.1.2

Changes:

  • Fix: EPUB FXL Fixed-Layout pre-paginated publications can now render with single centered pages (override from authored spread rules, when aspect ratio is portrait instead of landscape)

Git revision info:

Git commit history:

Git diff:

1.11.5

Build environment: NodeJS 18.12.1, NPM 9.1.2

Changes:

  • Fix: pagebreak (role or epub:type) in EPUB HTML documents can have empty text, to be correlated later with authored pagelist in navigation document (if any) via the target element ID (if any). Also take into account first available page break in HTML markup that does not have significant preceding text, when no specific text cursor is placed in chapter yet.

Git revision info:

Git commit history:

Git diff:

1.11.4

Build environment: NodeJS 18.12.1, NPM 9.1.1

Changes:

  • Fixed Electron webview session partition handling (protocol handler can be default unamed)

Git revision info:

Git commit history:

Git diff:

1.11.3

Build environment: NodeJS 18.12.1, NPM 9.1.1

Changes:

  • NPM package updates
  • CSS fix for Chromium regression (broken overflow hidden/clip style, column pagination)

Git revision info:

Git commit history:

Git diff:

1.11.2

Build environment: NodeJS 16.17.0, NPM 8.19.1

Changes:

  • feature: internal document link handling now via IPC renderer process event emitter (local) so it can be intercepted for external additional logic (e.g. history state)

Git revision info:

Git commit history:

Git diff:

1.11.1

Build environment: NodeJS 16.15.0, NPM 8.10.0

Changes:

  • fix: aside footnotes were not hidden
  • fix: keyboard focus inside webview was causing scroll reset

Git revision info:

Git commit history:

Git diff:

1.11.0

Build environment: NodeJS 16.15.0, NPM 8.10.0

Changes:

  • Updated NPM packages, notably Electron v19
  • Bugfix for CSS regression in Chromium v102 (flex / flow-root reset breaking CSS columns layout)
  • Improved previous fix for CSS height:inherit, now using min-height in column pagination to allow full extent, but retain previous strategy in scrolling mode.

Git revision info:

Git commit history:

Git diff:

1.10.2

Build environment: NodeJS 16.15.0, NPM 8.9.0

Changes:

  • Improved fix for CSS body position:relative with height:inherit (paginated and scrolling views, excluding fixed layout)

Git revision info:

Git commit history:

Git diff:

1.10.1

Build environment: NodeJS 16.15.0, NPM 8.9.0

Changes:

  • NPM package updates
  • Fix CSS body position:relative with height:inherit

Git revision info:

Git commit history:

Git diff:

1.10.0

Build environment: NodeJS 16.14.2, NPM 8.5.5

Changes:

  • NPM package updates (including Electron 18)
  • Fix Readium CSS -webkit-perspective stacking context hack (CSS column layout performance)
  • Attempted fix for Electron window.localStorage regression (partition session)

Git revision info:

Git commit history:

Git diff:

1.9.14

Build environment: NodeJS 16.14.0, NPM 8.5.2

Changes:

Git revision info:

Git commit history:

Git diff:

1.9.13

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • NPM package updates
  • Workaround for ReadiumCSS audio width/height bug
  • Feature to popout images into full document viewport (SHIFT CLICK to initiate, and to zoom in further, ESC or CLICK to return to normal publication view)

Git revision info:

Git commit history:

Git diff:

1.9.12

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • NPM package updates

Git revision info:

Git commit history:

Git diff:

1.9.11

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • Screen reader support: fix for hyperlink activation which causes mouse interaction depending on which keyboard shortcut is used to trigger the link (regular Enter keystroke vs. control-option-space in VoiceOver, for example)

Git revision info:

Git commit history:

Git diff:

1.9.10

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • EPUB popup footnotes: fixed modal popup dialog positioning (bottom-aligned), fixed auto-hiding (only hide footnotes when they are referenced AND presented in the same document), added support for external popup footnotes (other HTML publication document)

Git revision info:

Git commit history:

Git diff:

1.9.9

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • Fix: headings trail leading to current reading location now supports missing ID by looking up to nearest linkable containing ancestor (common HTML authoring pattern: headings without ID have linkable section parent)

Git revision info:

Git commit history:

Git diff:

1.9.8

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • NPM package updates
  • Feature: headings trail leading to current reading location (similar to contextual EPUB page break reporting via locator extended event payload)

Git revision info:

Git commit history:

Git diff:

1.9.7

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • NPM package updates
  • Synthetic speech TTS readaloud improvements: skip "hidden" DOM fragments, handle deep MathML click-and-play, hit-test image x,y coordinates, ignore underscore special link in caption/simple view

Git revision info:

Git commit history:

Git diff:

1.9.6

Build environment: NodeJS 16.13.1, NPM 8.3.0

Changes:

  • NPM package updates
  • Fixed keyboard focus management in content webview, works with screen readers (accessible UI / UX tested with VoiceOver on MacOS), TOC, landmarks, bookmarks, page numbers, search matches

Git revision info:

Git commit history:

Git diff:

1.9.5

Build environment: NodeJS 16.13.1, NPM 8.2.0

Changes:

  • Fixed epub:type and role (doc)-pagebreak attributes XPath, now performing a union / pipe on separate matches ("or" combinator inside the single / combined assertion predicate was breaking on first match)

Git revision info:

Git commit history:

Git diff:

1.9.4

Build environment: NodeJS 16.13.1, NPM 8.2.0

Changes:

  • NPM package updates
  • TTS support for MathML (without MathJax) via alttext attribute or fallback to element textual contents

Git revision info:

Git commit history:

Git diff:

1.9.3

Build environment: NodeJS 16.13.0, NPM 8.1.4

Changes:

  • NPM package updates
  • TTS support for MathJax / MathML
  • TTS highlight of images / SVG etc. (when alt text source not children textnodes)

Git revision info:

Git commit history:

Git diff:

1.9.2

Build environment: NodeJS 16.13.0, NPM 8.1.4

Changes:

  • NPM package updates
  • NodeJS 16 + NPM 8
  • Electron 16
  • ESLINT (was TSLINT)
  • Improved EPUB Media Overlays playback when no audio (skip fragment, was stalling)
  • Fixed highlights CSS reset (styles leak from host document)

Git revision info:

Git commit history:

Git diff:

1.9.1

Build environment: NodeJS 14.18.1, NPM 6.14.15

Changes:

  • NPM package updates
  • Fixed Layout zoom factor now CSS transform scale on HTML root element, not enclosing WebView (to avoid raster pixelisation, now crisp text vector graphics / font magnification)

Git revision info:

Git commit history:

Git diff:

1.9.0

Build environment: NodeJS 14.18.1, NPM 6.14.15

Changes:

  • Electron v15 (NodeJS v16)

Git revision info:

Git commit history:

Git diff:

1.8.7

Build environment: NodeJS 14.18.1, NPM 6.14.15

Changes:

  • NPM package updates
  • NodeJS v14 minimum requirement

Git revision info:

Git commit history:

Git diff:

1.8.6

Build environment: NodeJS 14.17.5, NPM 6.14.15

Changes:

Git revision info:

Git commit history:

Git diff:

1.8.5

Build environment: NodeJS 14.17.5, NPM 6.14.14

Changes:

  • Electron v14

Git revision info:

Git commit history:

Git diff:

1.8.4

Build environment: NodeJS 14.17.5, NPM 6.14.14

Changes:

  • Fixed-layout zoom improved, now with arbitrary scaling (not just "fit into viewport")

Git revision info:

Git commit history:

Git diff:

1.8.3

Build environment: NodeJS 14.17.5, NPM 6.14.14

Changes:

  • NPM package updates
  • Fixed-layout documents now scaled and translated (CSS transform) on the webview container instead of the root HTML element within
  • Fix: handling of special custom URL protocol used to simulate HTTPs (pure Electron streamer, no HTTP / Express server)

Git revision info:

Git commit history:

Git diff:

1.8.2

Build environment: NodeJS 14.17.5, NPM 6.14.14

Changes:

  • NPM package updates
  • ReadiumCSS "default" zero values for spacing of words, paragraphs, line height, etc. ("publisher defaults")

Git revision info:

Git commit history:

Git diff:

1.8.1

Build environment: NodeJS 14.17.5, NPM 6.14.14

Changes:

  • NPM package updates
  • Scroll previous/next spine item with mouse wheel and touch pad (including kinetic two-finger flick gesture)

Git revision info:

Git commit history:

Git diff:

1.8.0

Build environment: NodeJS 14.17.5, NPM 6.14.14

Changes:

  • Electron v13
  • Programmatic hyperlinks (InDesign style): "will-navigate" event intercept now works where no-HTTP streamer is used (in which case there is no HTML base transform)
  • Fixed-layout workaround: CSS 2D transform (scale + translate) bleeds body background color, this is prevented using a transparent image on HTML root element
  • Check that webview is still mounted after the async timeout (show/hide content mask IPC event)

Git revision info:

Git commit history:

Git diff:

1.7.4

Build environment: NodeJS 14.17.0, NPM 6.14.13

Changes:

  • automatically hide mouse cursor during inactivity (mouse move event detection, 1 second time window)

Git revision info:

Git commit history:

Git diff:

1.7.3

Build environment: NodeJS 14.17.0, NPM 6.14.13

Changes:

  • NPM updates
  • TTS sentence detection enable/disable
  • TTS skip sentence previous/next
  • SVG aria-label and title parse + render in captions/simplified view

Git revision info:

Git commit history:

Git diff:

1.7.2

Build environment: NodeJS 14.17.0, NPM 6.14.13

Changes:

  • NPM updates
  • Fixed cross-origin audio/video track source when head>base URL is used ( see edrlab/thorium-reader#1487 )

Git revision info:

Git commit history:

Git diff:

1.7.1

Build environment: NodeJS 14.16.1, NPM 6.14.13

Changes:

  • NPM updates

Git revision info:

Git commit history:

Git diff:

1.7.0

Build environment: NodeJS 14.16.0, NPM 6.14.12

Changes:

  • TTS voice selection (override from default for language auto-detection)

Git revision info:

Git commit history:

Git diff:

1.6.0

Build environment: NodeJS 14.15.4, NPM 6.14.11

Changes:

  • Major NPM package update: Electron v11

Git revision info:

Git commit history:

Git diff:

1.5.3

Build environment: NodeJS 14.15.4, NPM 6.14.11

Changes:

  • NPM package updates
  • Removed dependency on remote Electron module (context menu and accessibility / screen reader detection)

Git revision info:

Git commit history:

Git diff:

1.5.2

Build environment: NodeJS 14.15.0, NPM 6.14.8

Changes:

  • NPM package updates
  • Fixed skippable page numbers edge case in Media Overlays SMIL playback

Git revision info:

Git commit history:

Git diff:

1.5.1

Build environment: NodeJS 14.15.0, NPM 6.14.8

Changes:

  • NPM package updates
  • Fixed popup footnotes, now checks that content is in current document
  • Fixed hyperlinking :target CSS style (DOM state during navigation)

Git revision info:

Git commit history:

Git diff:

1.5.0

Build environment: NodeJS 12.18.2, NPM 6.14.7

Changes:

  • NPM package updates, Electron 9

Git revision info:

Git commit history:

Git diff:

1.4.12

Build environment: NodeJS 12.18.2, NPM 6.14.5

Changes:

  • NPM package updates
  • TypeScript const enum safeguard (isolated modules)

Git revision info:

Git commit history:

Git diff:

1.4.11

Build environment: NodeJS 12.18.1, NPM 6.14.5

Changes:

  • Linking to CSS Selector element now supports "inner" bounding client rectangle for scroll-into-view of highlighted text range (annotations, search results, etc.)

Git revision info:

Git commit history:

Git diff:

1.4.10

Build environment: NodeJS 12.18.1, NPM 6.14.5

Changes:

  • Fixed TTS readaloud issues: paginated doc with odd number of columns, last page of spread is left-aligned, but TTS playback and highlight was unshifting the page spread. Also fixed: when large sections of text are single HTML element => scroll-into-view did not show current sentence / work highlight.

Git revision info:

Git commit history:

Git diff:

1.4.9

Build environment: NodeJS 12.18.1, NPM 6.14.5

Changes:

  • Fixed Media Overlays and TTS readaloud bugs (page turning, playback resume, play/pause state)

Git revision info:

Git commit history:

Git diff:

1.4.8

Build environment: NodeJS 12.18.1, NPM 6.14.5

Changes:

  • Improved CSS pixel tolerance for Windows "page turn" edge case

Git revision info:

Git commit history:

Git diff:

1.4.7

Build environment: NodeJS 12.18.1, NPM 6.14.5

Changes:

  • NPM package updates
  • CSS pixel tolerance for Windows "page turn" edge case

Git revision info:

Git commit history:

Git diff:

1.4.6

Build environment: NodeJS 12.18.0, NPM 6.14.5

Changes:

  • Audiobooks with no cover image were crashing
  • Minor NPM package updates

Git revision info:

Git commit history:

Git diff:

1.4.5

Build environment: NodeJS 12.18.0, NPM 6.14.5

Changes:

Git revision info:

Git commit history:

Git diff:

1.4.4

Build environment: NodeJS 12.16.3, NPM 6.14.5

Changes:

  • TTS readaloud new mode: in-document highlighting, with smooth scroll-into-view, word-by-word underline emphasis during playback, and sentence-level navigation granularity (i.e. individual atomic TTS utterances), created from larger paragraph blocks of text. TTS utterances can be clicked to start playback (hit testing based on fragmented strings of characters / DOM ranges).
  • TTS readaloud simplified "overlay" view is now opt-in, default is in-document highlighting.

Git revision info:

Git commit history:

Git diff:

1.4.3

Build environment: NodeJS 12.16.3, NPM 6.14.5

Changes:

  • Fixed bug which prevented resources from loading, when URL path starts with any first characters of "/manifest.json" (incorrect URL resolution routine, bad character offset calculation, erroneous common root string)

Git revision info:

Git commit history:

Git diff:

1.4.2

Build environment: NodeJS 12.16.3, NPM 6.14.5

Changes:

  • EPUB3 Media Overlays / sync-media: "caption style" view switch does not automatically trigger pause/resume.

Git revision info:

Git commit history:

Git diff:

1.4.1

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • NPM package updates.
  • EPUB3 Media Overlays / sync-media: new "caption style" view.
  • TTS readaloud: improved presentation styles for sepia, night and normal modes.
  • TTS readaloud: new features, emphasis on heading levels, and inline display of images with "alt" attribute.
  • Annotations / highlights: vastly improved rendering performance (DocumentFragment to build DOM, then batch-append highlights "layer" into actual document, also better mouse interaction / hover detection).
  • Annotation / highlights: display improvement, using "mix blend mode" with opacity, yield better text legibility.
  • Annotation / highlights: SVG and HTML renderers now default to "background" drawing style, with "underline" / "strikethrough" optional choices (was hard-coded before, now in API).

Git revision info:

Git commit history:

Git diff:

1.4.0

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • NPM package updates
  • Support for fixed-layout / FXL two-page spread in EPUB publications, works for Media Overlays synchronized text/audio playback, concurrent reading locations depending on "active" focused page, selection / highlights, etc. (TTS readloud is currently not polished in two-page mode, needs to be mutually-exclusive per page)
  • Fixed Media Overlays night and sepia highlights
  • Fixed SVG xlink:href relative URL handling
  • Disabled FXL scroll during element focusing (mouse, keyboard interactions)
  • Workaround for fixed layout documents that do not size the body correctly (force width + height dimensions)
  • Visibility mask improved for fixed layout documents (smooth fade effect)

Git revision info:

Git commit history:

Git diff:

1.3.2

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • EPUB Media Overlays skippables fix

Git revision info:

Git commit history:

Git diff:

1.3.1

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • EPUB Media Overlays / W3C Sync Media playback rate needed reset across audio files switch

Git revision info:

Git commit history:

Git diff:

1.3.0

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • NPM updates
  • EPUB Media Overlays / W3C Sync Media playback
  • Highlights fixes in scroll mode (incorrect visual offsets due to CSS margins)
  • Fixed focus / refresh bugs in scroll and paginated views (sync of reading location)
  • Crushed a fixed layout scroll bug

Git revision info:

Git commit history:

Git diff:

1.2.0

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • NPM updates
  • TTS read aloud UI improvements (active utterance presentation, smooth scroll), added speech rate control API
  • disabled "will-quit" Electron app event handler for clearSessions()

Git revision info:

Git commit history:

Git diff:

1.1.57

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • NPM updates
  • Fix: XML namespaces in popup footnotes (e.g. epub:type attributes, MathML elements)

Git revision info:

Git commit history:

Git diff:

1.1.56

Build environment: NodeJS 12.16.2, NPM 6.14.4

Changes:

  • NPM updates
  • Audiobooks: improved progress slider timeline (input type range)

Git revision info:

Git commit history:

Git diff:

1.1.55

Build environment: NodeJS 12.16.1, NPM 6.14.4

Changes:

  • NPM updates
  • Audiobooks: skip title when non-existent
  • Correct license.lcpl path for LCP injection in EPUB and Readium audiobooks

Git revision info:

Git commit history:

Git diff:

1.1.54

Build environment: NodeJS 12.16.1, NPM 6.14.4

Changes:

  • NPM updates (minor, including Electron)
  • Fixed CSON-2-JSON build script
  • audiobook player improvements: SVG icons, time indicators, placeholders for localization (translatable titles), cover image play/pause button now reacts on mouse up event and only for left mouse button click (otherwise interferes with right click for context menu), added rate speed control

Git revision info:

Git commit history:

Git diff:

1.1.53

Build environment: NodeJS 12.16.1, NPM 6.14.4

Changes:

  • NPM updates (minor)
  • Fixed 'will-navigate' infinite loop introduced by HTML injection of <base href="HTTP_URL" />
  • ReadiumCSS is not applied to iframes
  • Improved invisibility "mask" techique, default when ReadiumCSS is HTML-injected, disabled at window.load event
  • Fixed handling of base@href (HTTP URL) vs. the root URL of ReadiumCSS assets

Git revision info:

Git commit history:

Git diff:

1.1.52

Build environment: NodeJS 12.16.1, NPM 6.14.4

Changes:

  • NPM updates (minor)
  • workaround for application/xhtml+xml not handled correctly in xmldom lib
  • support for audio/video autoplay (Electron command line switch)
  • support for audio background looping track (epub:type = ibooks:soundtrack)
  • in order to bypass Electron registerStreamProtocol() bugs: instead of static DOM patching of audio and video src URLs (replacement of custom URL protocol/scheme with direct HTTP streamer address), we now inject <base href="HTTP_URL"/> (this benefits all resolved absolute URLs, including scripted ones from mutated dynamic DOM, and does not affect the sandboxing of localStorage, IndexedDB etc. which is afforded by the custom URL protocol/scheme)
  • fixed handling of iframes inside publication HTML documents (forwarding of query params, and allows same-origin scripting by bypassing the aforementioned <base href="HTTP_URL"/> of the host document, recursively)

Git revision info:

Git commit history:

Git diff:

1.1.51

Build environment: NodeJS 12.16.1, NPM 6.14.4

Changes:

  • NPM updates
  • Electron getWebContents() WebView API deprecation (upcoming breaking change)
  • replaced registerStreamProtocol() with registerHttpProtocol() as the latter was hanging on large resource requests from the HTTP server / streamer
  • registerStreamProtocol() with self-signed certificate passthrough, and encrypted HTTP headers

Git revision info:

Git commit history:

Git diff:

1.1.50

Build environment: NodeJS 12.16.1, NPM 6.14.3

Changes:

  • in debug / development mode: context menu for "inspect element" at x,y coordinates, with automatic forced-focus on devtools window
  • audiobook error event now console logged in normal non-debug mode
  • in development mode with special audio debug enabled: the buffering tracking element (HTML canvas) is now centered correctly

Git revision info:

Git commit history:

Git diff:

1.1.49

Build environment: NodeJS 12.16.1, NPM 6.14.2

Changes:

  • fix: when there is a text selection, the reading location is the start container of the selection. Also added CFI indicator for start/end selection containers (in addition to existing CSS selector)
  • fix: role=doc-pagebreak in addition to epub:type=pagebreak, and pagebreak label now obtained from title and aria-label attributes in addition to element's textual descendant

Git revision info:

Git commit history:

Git diff:

1.1.48

Build environment: NodeJS 12.16.1, NPM 6.14.2

Changes:

  • NPM package updates (minor semantic version increments)
  • ReadiumCSS upgrade + fixed a subtle bug related to 'null' origin in the case of audio book (HTML template with data: URL + base) + API updates to allow app host to pass configuration instead of navigator "pulling" data as needed (this change is required for contextual / per-publication ReadiumCSS presets)
  • Performance: significant improvements in annotations / highlights rendering, ReadiumCSS background-color override, animated page scroll
  • Audiobooks: added debugging UI and console messages to help troubleshoot random playback break problems
  • Usability: avoid unnecessary reading location recording when scrolling, if currently-recorded element is already in the visible viewport (scroll and paginated modes)
  • Accessibility: consider that CSS selector link is equivalent to hash fragment identifier (e.g. typical TOC heading), for the purpose of setting the destination for the top-level skip-hyperlink (which restores previously-linked bookmarks, etc.)

Git revision info:

Git commit history:

Git diff:

1.1.47

Build environment: NodeJS 12.16.1, NPM 6.14.1

Changes:

  • NPM updates (minor)
  • tabbables now handled via focusin (hyperlinks traversal) => better performance, fewer keyboard-tabbing flashes / visual "bugs"
  • added top-level "skip link" to quickly keyboard-access the current URL hash fragment identifier or "active" target element (the link is CFI and CSS selector blacklisted) ... we need this because the iframe/webview cannot force focus when keyboard is in the app UI (the user must explicitely trigger the navigation)
  • fixed CFI blacklisting (even number element indexing calculations)
  • fixed style animation restart for element target (hyperlinking), added CSS "target" class to mimic the actual pseudo-class (for when URL fragment identifier is not used)

Git revision info:

Git commit history:

Git diff:

1.1.46

Build environment: NodeJS 12.16.1, NPM 6.14.1

Changes:

  • NPM updates (minor)
  • Fixed the keyboard event handler callback signature to include the element name and attributes used for blacklisting on the API's client side
  • Added EPUB epub:type=pagebreak info in reading location (nearest preceeding ancestor/sibling in document order)

Git revision info:

Git commit history:

Git diff:

1.1.45

Build environment: NodeJS 12.16.1, NPM 6.14.0

Changes:

  • NPM updates, including minor Electron
  • Added key-up event listener (to existing key-down), and target element name (for optional client-side blacklisting). Also now ensures "capture" in top-level document event listen.

Git revision info:

Git commit history:

Git diff:

1.1.44

Build environment: NodeJS 12.15.0, NPM 6.13.7

Changes:

  • NPM updates, notably: removed unused UUID package (breaking API change in newer version, so must avoid unnecessarily import here)
  • CSS fix: ReadiumCSS was taking precedence due to selector specificity (button border colour in night mode, audio player)

Git revision info:

Git commit history:

Git diff:

1.1.43

Build environment: NodeJS 12.15.0, NPM 6.13.7

Changes:

  • NPM updates
  • Bugfix: protection against publications without Resources
  • API improvement: readiumCssUpdate(rcss) now replaces readiumCssOnOff() which was misnamed and required out-of-line callback to fetch ReadiumCSS info.
  • Content transformers now pass "session info" semantic-agnostic data (serialized string) so that anonymous HTTP requests can be correlated with specific publications and with their reading session (multiple readers scenario). Also see changes in r2-shared, and of course r2-streamer.
  • Support for AudioBook serving/streaming, local-packed (zipped), local-exploded (unzipped), and remote-exploded.
  • Electron v8 (was v7)

Git revision info:

Git commit history:

Git diff:

1.1.42

Build environment: NodeJS 12.13.1, NPM 6.13.4

Changes:

  • NPM updates
  • ReadiumCSS update

Git revision info:

Git commit history:

Git diff:

1.1.41

Build environment: NodeJS 12.13.0, NPM 6.13.0

Changes:

  • Clipboard copy interceptor for LCP rights

Git revision info:

Git commit history:

Git diff:

1.1.40

Build environment: NodeJS 12.13.0, NPM 6.13.0

NOTE: this was mistakenly tagged as 1.0.40!

Changes:

  • NPM package updates
  • TAJSON now parses/generates arbitrary JSON properties with typed object

Git revision info:

Git commit history:

Git diff:

1.1.39

Build environment: NodeJS 12.13.0, NPM 6.13.0

Changes:

  • NPM updates
  • MathJax "support" (blacklisting CSS selectors + CFI)
  • Added "refresh" function for webview (reloadContent()))

Git revision info:

Git commit history:

Git diff:

1.1.38

Build environment: NodeJS 12.13.0, NPM 6.12.0

Changes:

  • NPM updates
  • Removal of ResizeSensor, now using Chromium native Observer to detect HTML body dimensions changes (in order to re-paginate)

Git revision info:

Git commit history:

Git diff:

1.1.37

Build environment: NodeJS 12.13.0, NPM 6.12.0

Changes:

  • NPM updates, Electron v7

Git revision info:

Git commit history:

Git diff:

1.0.37

ELECTRON v6 moved to electron6 branch! (Electron v7 in develop)

Build environment: NodeJS 10.16.3, NPM 6.12.0

Changes:

  • NPM updates (including NodeJS v12 for Electron v6)

Git revision info:

Git commit history:

Git diff:

1.0.36

Build environment: NodeJS 10.16.3, NPM 6.11.3

Changes:

  • Now allowing javascript: hyperlinks

Git revision info:

Git commit history:

Git diff:

1.0.35

Build environment: NodeJS 10.16.3, NPM 6.11.3

Changes:

  • Screen reader detection optionally triggers webview hard refresh

Git revision info:

Git commit history:

Git diff:

1.0.34

Build environment: NodeJS 10.16.3, NPM 6.11.3

Changes:

  • Added safeguard against erroneous inner-publication links (badly-authored EPUBs)

Git revision info:

Git commit history:

Git diff:

1.0.33

Build environment: NodeJS 10.16.3, NPM 6.11.3

Changes:

  • NPM updates

Git revision info:

Git commit history:

Git diff:

1.0.32

Build environment: NodeJS 10.16.3, NPM 6.11.3

Changes:

  • NPM updates
  • TypeScript sort import

Git revision info:

Git commit history:

Git diff:

1.0.31

Build environment: NodeJS 10.16.3, NPM 6.11.3

Changes:

  • NPM updates
  • Added API to forward keyboard key down press event to consumer app, useful for previous/next navigation at page or spine -level

Git revision info:

Git commit history:

Git diff:

1.0.30

Build environment: NodeJS 10.16.0, NPM 6.10.2

Changes:

  • NPM updates
  • Buffer.from() API to remove deprecation messages

Git revision info:

Git commit history:

Git diff:

1.0.29

Build environment: NodeJS 10.16.0, NPM 6.9.0

Changes:

  • TTS readaloud improvements and fixes (full screen utterances view, support for RTL text)

Git revision info:

Git commit history:

Git diff:

1.0.28

Build environment: NodeJS 10.16.0, NPM 6.9.0

Changes:

  • Fixed URI vs. URL bug (percent-escaped Unicode characters in path, was failing to match spine/readingOrder resource)
  • Document selection: DOM Range normalization (algorithm from Apache Annotator, ported to TypeScript)

Git revision info:

Git commit history:

Git diff:

1.0.27

Build environment: NodeJS 10.16.0, NPM 6.9.0

Changes:

  • NPM updates
  • Document selection: window.getSelection().collapseToStart() replaced with .removeAllRanges() (was failing silently inside IPC event listener)
  • Document highlighting: working SVG implementation (background, underline, and strikethrough). Works with reflow scroll and paginated, as well as scaled fixed layout. Exact same visuals as with HTML divs, just with SVG instead. Note: no well-defined API to expose total functionality, still work in progress.

Git revision info:

Git commit history:

Git diff:

1.0.26

Build environment: NodeJS 10.15.3, NPM 6.9.0

Changes:

  • Fix Electron/Chromium regression due to breaking changes in WebView (Out Of Process iFrame) lifecycle: resize and load events were creating unnecessary scroll adjustments in reflow column-paginated and scroll views.

Git revision info:

Git commit history:

Git diff:

1.0.25

Build environment: NodeJS 10.15.3, NPM 6.9.0

Changes:

  • NPM update: the css-element-queries package (ResizeSensor) is now fetched from NPM rather than GitHub (was a forked/patched dependency, some time ago ...)

Git revision info:

Git commit history:

Git diff:

1.0.24

Build environment: NodeJS 10.15.3, NPM 6.9.0

Changes:

  • NPM updates (including the ResizeSensor)
  • TTS renaming to "readaloud" (non-breaking internal API change)

Git revision info:

Git commit history:

Git diff:

1.0.23

Build environment: NodeJS 10.15.3, NPM 6.9.0

Changes:

  • NPM updates
  • Fixed left/right arrow key for page switch, when keyboard focus inside webview (Electron post-v1 regression)
  • Added highlights API (with minimal UI / UX in r2-testapp-js)
  • Fixed-layout documents (FXL) sometimes did not emit the load event, and did not scale correctly (browser engine bugs / edge cases). There are still rendering issues in Electron v3-v5. To be continued...

Git revision info:

Git commit history:

Git diff:

1.0.22

Build environment: NodeJS 10.15.3, NPM 6.9.0

Changes:

  • NPM updates

Git revision info:

Git commit history:

Git diff:

1.0.21

Build environment: NodeJS 8.15.1, NPM 6.4.1

Changes:

  • LCP LSD TypeScript model instead of JSON "any"
  • Added implementation document for selections/highlights
  • NPM updates

Git revision info:

Git commit history:

Git diff:

1.0.20

Build environment: NodeJS 8.15.1, NPM 6.4.1

Changes:

  • Latest ReadiumCSS
  • Fixed Electron v1+ window.document.scrollingElement regression, as well as IPC event send() dom-ready event check, and scroll offset coordinates in selection/highlights (still todo: keyboard focus handling)
  • NPM update r2-shared-js

Git revision info:

Git commit history:

Git diff:

1.0.19

Build environment: NodeJS 8.15.1, NPM 6.4.1

Changes:

  • NPM updates

Git revision info:

Git commit history:

Git diff:

1.0.18

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • NPM updates
  • Updated documentation (README)
  • Added support for two-page spreads with odd number of columns => empty "virtual" page at end of document.
  • Fixed reading location progression reporting bugs (paginated reflowable documents, right to left)
  • Added debugging feature for arbitrary visual reading locations
  • New prototype code (incomplete API) for user text selections/annotations/highlights.
  • Fixed ReadiumCSS for RTL (Hebrew, Arabic), was skipping some configuration
  • Added information data structures to reading location (pagination and document information)
  • Improved and fixed TTS / read aloud graphical user interface (minimal, but core to the user experience: modal popup text presenter with word-level highlighting and full ReadiumCSS support)

Git revision info:

Git commit history:

Git diff:

1.0.17

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • Fixed hyperlinking bug: nested a@href DOM fragments
  • Improved footnote rendering (extraction of note content)

Git revision info:

Git commit history:

Git diff:

1.0.16

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • Reading locator can now be set with progression percentage (not just CSS selector/DOM element), which is useful for linear navigation / slider-scrub UI.
  • Fixed "compute visibility" bug: CSS computed style "hidden" reported for scrolled-out columns!

Git revision info:

Git commit history:

Git diff:

1.0.15

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • Improved visible element detection algorithm, to automatically create the most appropriate CSS selector in reflow paginated and scroll views (reading location for page / spread)
  • Blacklist resize sensor in DOM traversal operations
  • Handling of non-visual page breaks (invisible DOM spans)

Git revision info:

Git commit history:

Git diff:

1.0.14

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • NPM updates
  • Fixed reflowable pagination bugs, inconsistent element selection based on visibility (HTML body fallback)

Git revision info:

Git commit history:

Git diff:

1.0.13

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • NPM updates
  • Reflowable pagination improvement: two-page spread with odd number of columns (i.e. empty/blank "virtual" trailing page), and more accurate element-level position reporting
  • Accessibility user setting "reduce motion", to disable animated page transitions
  • Popup footnotes: aside with epub:type (rear|foot|end)note is normally automatically hidden, but shown when no targetting link is detected (e.g. dedicated standalone document appendix for notes)
  • Content Security Policy for webview: allowed data: HTTP(S) protocols
  • The "current reading location" getter now populates the document title, so client apps can use this to render info label

Git revision info:

Git commit history:

Git diff:

1.0.12

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • NPM updates
  • Added documentation (README)
  • Improved keyboard handling, tab navigation
  • Added support for TTS read aloud (WebSpeech API)
  • Added support for popup footnotes (EPUB3)
  • Fixed ReadiumCSS injection bug (edge cases with some bad DOM, doctype)
  • Enabled loading of remote publications (was filtering local URL)
  • Allow loading of Readium webpubmanifest with different URL syntax than default streamer implementation
  • Disabled window.alert/confirm/prompt to avoid publication documents blocking the renderer thread
  • Fixed arrow keys capture issues (no page turn when used for interaction with text input, video/audio, slider, etc.)
  • Fixed scroll-to-view in the scroll view (now centering, was top edge)
  • Added visibility mask when navigating back into previous publication spine item (to eliminate visual flash due to first-render of document top)
  • Added blacklist of CSS class names and HTML element IDs for locators (CSS Selectors and CFI), to skip navigator-injected DOM markup)
  • Fixed hash-fragment ID reset problem (::active pseudo CSS class)

Git revision info:

Git commit history:

Git diff:

1.0.11

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • Fixed regression bug that affected apps with custom URL protocol handlers (schemes) due to Content Security Policy (now narrow scope by filtering requests)

Git revision info:

Git commit history:

Git diff:

1.0.10

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • Added visibility testing for locators (updated README documentation)
  • Improved timing of reading location restore, in case of layout delay due to heavy font faces, etc.
  • Fixed issues related to Electron4 support (webview resizing, Content Security Policy via HTTP headers, security params in webview creation interceptor, priviledged URL scheme / protocol for fetch in renderer process)

Git revision info:

Git commit history:

Git diff:

1.0.9

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • Updated documentation
  • Web console logging + shell output redirection
  • Added window-attached debug(true/false) function to switch visual debugging (setting is persistent in localStorage)
  • Code cleanup, better debug messages

Git revision info:

Git commit history:

Git diff:

1.0.8

Build environment: NodeJS 8.14.1, NPM 6.4.1

Changes:

  • Updated documentation
  • NPM 6.5.* has regression bugs for global package installs, so revert back to NPM 6.4.1 (which is officially shipped with the NodeJS installer).

Git revision info:

Git commit history:

Git diff:

1.0.7

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • NPM updates
  • API to provide epubReadingSystem info (name and version) changed slightly, now push-once rather than pull-many design pattern
  • Improved documentation (in progress)
  • Moved ReadiumCSS boilerplate code to here
  • Removed unused DOM event code (legacy mechanism to cater for slow rendering performance)
  • Console logging redirect for renderer process (not just webview isolated process)
  • Minor internal code reorganisation

Git revision info:

Git commit history:

Git diff:

1.0.6

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • Fixed regression bug due to the previous base64 pub ID encoding bugfix (slashes). Depending on what lib is used, URLs and URLs components do not necessarilly get automatically decoded/encoded (percent escape for base64 chars, e.g. = and /). We must be very careful because we pass around both full URLs, and URLs components that require encoding (thus the double-encoding issues). In the navigator component we also have the compound issue of URI authority/domain/origin (derived from the based64 encoding of the pub ID).

Git revision info:

Git commit history:

Git diff:

1.0.5

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • NPM updates (r2-xxx-js)
  • Fixed nasty Base64 encoding edge case with slash character in URLs
  • Moved "secure" HTTP code from navigator to streamer

Git revision info:

Git commit history:

Git diff:

1.0.4

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • NPM updates (r2-xxx-js packages)
  • Replaced deprecated RawGit URLs
  • ReadiumCSS readme (GitHub commit hash / revision)

Git revision info:

Git commit history:

Git diff:

1.0.3

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • Performance improvements in layout/rendering logic, now ReadiumCSS injected at streamer level (optionally, still works with regular DOM injection too)
  • Fixed scroll view bug: fast-switching was making document jump up
  • Fixed issue with back-navigation inside spine (delay in resynchronizing document position, in both scroll and paginated view modes)

Git revision info:

Git commit history:

Git diff:

1.0.2

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • Fixed code typo which was breaking some ReadiumCSS functionality.

Git revision info:

Git commit history:

Git diff:

1.0.1

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • Disabled debug mode (visuals)
  • Added missing license header
  • Removed unnecessary import aliases

Git revision info:

Git commit history:

Git diff:

1.0.0

Build environment: NodeJS 8.14.0, NPM 6.5.0

Changes:

  • Locator support (CFI, CSS Selectors, Progression(percent ratio), Position(placeholder))
  • Various fixes in reflow column-based pagination and scroll view, LTR and RTL (arabic), due to box-model and offsetTop innaccuracy (now getBoundingClientRect() with floating point accuracy)
  • ReadiumCSS added missing parameters, complete review of model + default values, based on current doc
  • Fixed disappearing scroll view scrollbar when switching modes
  • Adjusted focus and target CSS styles to transient display (timeout outline)
  • CSS Selector lib replacement (more robust uniqueness strategy)
  • NPM updates (minor)
  • ReadiumCSS updated to latest (minor)
  • Git revision JSON info now includes NodeJS and NPM version (build environment)

Git revision info:

Git commit history:

Git diff:

1.0.0-alpha.7

Build environment: NodeJS 8.12.0, NPM 6.4.1

Changes:

  • NPM updates (minor)
  • ReadiumCSS updated to latest (minor)
  • Git revision JSON info now includes NodeJS and NPM version (build environment)

Git revision info:

Git commit history:

Git diff:

1.0.0-alpha.6

Changes:

  • Dependency "ta-json" GitHub semver dependency becomes "ta-json-x" NPM package (fixes https://github.com/readium/r2-testapp-js/issues/10 )
  • Fixed TypeScript regression bug (3.0.3 -> 3.1.1) related to XML / HTML DOM typings
  • Removed TypeScript linter warning message (checks for no unused variables)
  • NPM updates related to the Node TypeScript typings

Git revision info:

Git commit history:

Git diff:

1.0.0-alpha.5

Changes:

  • NPM package 'debug' with explicity 'node' vs. 'browser' fix (console redirect)

Git revision info:

Git commit history:

Git diff:

1.0.0-alpha.4

Changes:

  • NPM updates (external dependencies)

Git revision info:

Git commit history:

Git diff:

1.0.0-alpha.3

Changes:

  • correct version in package-lock.json

Git revision info:

Git commit history:

Git diff:

1.0.0-alpha.2

Changes (NPM updates):

  • @types/node
  • @types/uuid
  • r2-streamer-js
  • r2-lcp-js

Git revision info:

Git commit history:

Git diff:

1.0.0-alpha.1

Changes:

  • initial NPM publish

Git revision info:

Git commit history:

Git diff:

  • initial NPM publish