Core library code for a DOM Anchoring Framework
This document describes the concepts, components and processes making up the DOM Anchoring Framework.
We are are trying to describe segments
of documents
by sets of selectors
, in order to be able to anchor some payloads
to specific parts (a.k.a. segments
) of the document
.
There are two main directions: in the first, we start with a segment
, and end up with a set of selectors
describing the segment, which can then be serialized and stored, independently of the document. In the reverse direction, we start with a set of selectors
, and (hopefully) end up with an anchor
, which encapsulates the results of our attempts to determine where the wanted segment
of the document
might be, based on the information stored in the selectors
. The anchors
are made visible to the user by using highlights
.
We can simultaneously support different types of anchors
, indicated by different types highlights
. We can support different types of documents
(a.k.a. platforms
) by different document access strategies
. We can use many different selector creators
to capture various pieces of information about the segments
in different selector
types, and we can have many different anchoring strategies
to try to reconstruct the location of the segment
based on the information captured in the selectors
. Also, we can have different highlighter engines
, capable of rendering highlights
for different types of anchors
.
Some of the documents
are composed of multiple pages
. In those cases, we have to dynamically render and remove the highlights
for the anchors
, as the pages are rendered / removed by the platform
. (For example, pdf.js, which uses lazy rendering for the pages.)
All of this is managed by the anchoring manager
, which interacts with the client code, and the various pluggable components (document access strategies
, selector creators
, anchoring strategies
, highlighter engines
), and manages the various data objects ('payloads', documents
, pages
, segments
, selectors
, anchors
, highlights
.)
Any object that we want to anchor to a document. These are passed in by client code, and are stored together with the anchor
created for them, for the convenience of the client code.
A payload
might have more than one ports
, and therefore more than one anchors
.
The document we are currently working with, in the given lifecycle of the DOM anchoring framework.
The framework itself does not do any kind of identification of the document.
In theory, we could work over any kind of document, but in practice, there are some modules which are tied to the DOM. (Fortunately, not in the core library itself.)
The documents are usually presented to the user by rendering them into HTML, the this rendered form is not the document itself.
When speaking of the document, we mean the underlying data structure, not the generated HTML representation.
Currently supported document types are
- Generic HTML documents
- PDF documents rendered using PDF.js (via the dom-anchor-pdfjs module)
Later we plan to support scribd, and google docs, and several others formats, too.
A page
is a piece of the document
which is known to be rendered into HTML at the same time.
A static HTML page is simply handled as a one-page document.
Many other document formats / platforms use lazy rendering (which means that they only render a few pages at a time, and the rest is only rendered on demand, when the user needs to see them); this practice is useful for conserving memory and CPU resources.
Our system needs to know about which pages are rendered, and which are not, so that we can react properly.
The handling of the pages is the responsibility of the Document accesss strategies
.
Any part of any document
.
A segment
can intersect with several pages
.
A raw description of a segment
.
- All
segment descriptions
carry atype
field, for easy recognition of the type ofsegment
. Segments descriptions
are typically produced by the UI code.Segment descriptions
are supposed to be raw and unprocessed, to avoid loss of any potentially useful information. Typically, they carry DOM (or similar) objects; in many cases, they carry the originalsegment
itself.Segment descriptions
do not have to be serializable.- Examples:
- a browser native Range object, describing a part of the document the user has selected.
- a NormalizedRange object, as used in Annotator, describing the same.
A piece of serializable data conveying some information hopefully useful for identify a segment
.
- See also the definition in the Open Annotation Data Model.
Selectors
are created byselector creators
, based onsegment descriptions
.Selectors
must be serializable, so no DOM object references (or similar) are allowed here.Selectors
do not have to be all-encompassing; it's permissible to conveys only partial information.- All
selectors
have atype
field.
A piece of information representing the results of a previous attempt to identify a segment
in a document
.
- Every
anchor
is created by ananchoring strategy
. Anchors
might or might not be serializable. (Can use DOM objects, etc.)Anchors
can also store extra information about how the current content of thedocument
compares to the state captured in theselectors
.- All
anchors
have atype
field. Anchors
are represented byhighlights
in the DOM.- If and
anchor
intersects with severalpages
, then it will have differenthighlights
for each page. Anchors
keep a per-page
list of theirhighlights
.Anchors
can bevirtual
,real
orpartially real
, depending on whether or not the correspondinghighlights
are rendered. (virtual
: no highlights are rendered;real
: all highlights are rendered;partially real
: some highlights are rendered.)Anchors
can carry links to apayload
, if so desired by the client code using them.
A payload
for which no anchor
could be created for.
A payload
which was mentioned by more than one anchoring attempts, but not all the requested anchor
could be created.
Visual representation of an anchor
in the DOM.
Highlights
are rendered by aHighlighter engine
.Highlights
have some representation in the DOM, thus they are visible to the user.- `Highlights are active objects, and can indicate some state changes, and can interact with the user.
This part is not actually part of our system, but we must know about it.
If we are not working with a static HTML document, but with an application displaying a given document type (like, for example, PDF.js, which we support for PDF documents), then we call this application the platform
.
The platforms
interact with, and are handled by the Document access strategies
.
Responsible for interacting with the platform
.
- Each
document access strategy
can support one or moreplatforms
. - The
document access strategy
determines whether or not it supports the currently loadeddocument
. - Only one
document access strategy
is active during one session of the framework. - The main tasks of the
document access strategies
are:- Provide a way to access the contents of the document. (Also called
corpus
.) - Notify the
manager
about document content changes. - Answer questions about the relations between given DOM elements, and the
corpus
of the document. (Where does DOM node X start and end in thecorpus
? Which DOM nodes are responsible for the content of the corpus between character positions X and Y?) - Respond to page-related questions and queries. (How many pages are there? Which pages are we on now? Let's go to to page X! Is page Y rendered? Which page does DOM node X belong to? Which page does character position Y in the corpus belong to? Where does page X start and end in the
corpus
?) - Notify the manager about page rendering and un-rendering events.
- Provide a way to access the contents of the document. (Also called
Responsible for describing a segment
with [a set of] selectors
.
- Input: a
segment description
. - Output: zero or more
selectors
. - Typically, the
manager
works with manyselector creators
loaded simultaneously, each responsible only for translating a given type ofsegment description
into a given type ofselector
. - Typically, more than one
selector creators
will react to any given type ofsegment description
, describing the segment with differentselectors
. - It's also allowed to respond with a promise, which will be resolved with a list of
selectors
later.
Responsible for identifying segments
of the document
(using the available selectors
), and also to verify the validity of the resulting anchor
after a document
change.
Anchor
creation:
- Input:
- a list of
selectors
describing thesegment
- the data extracted from the
document
using the activedocument access strategy
- a list of
- Output: an
anchor
- Can also respond with a promise, which will be resolved with an
anchor
later. - Typically, the
manager
works with severalanchoring strategies
loaded simultaneously, each responsible only for identifing thesegment
using a given method. It's perfectly OK to fail, if the theselctors
required by the given strategy are unavailable, or if the data stored in the receivedselectors
does not match with the data provided by thedocument access strategy
about thedocument
.
Anchor
verification:
- Input:
- the
anchor
- the data extracted from the
document
using the activedocument access strategy
- the
- Output:
- A yes-no decision signaling whether or not the
anchor
is still valid.
- A yes-no decision signaling whether or not the
Responsible for creating the highlights
- Input: an
anchor
- Output: a
highlight
- Several
highlighter engines
can be loaded at the same time; typically, each is only reaponsible for handling a given type ofanchor
, and might be restricted to work with a given set ofplatforms
. - The rendering of the highlights can be an asynchronous process.
- The generated highlight objects must implement the standard Highlight interface:
- Get/set/reset the
temporary
/active
/focused
flags - Get information about the position and size of the highlight inside the DOM
- Scroll the browser to this highlight
- Get/set/reset the
Responsible for controlling all the anchoring-related processes.
Keeps lists of:
- Current
Anchors
(per-page
) - Current
Orphan payloads
- Current
Half-orphan payloads
- Available
document access strategies
- Available
selector creators
- Available
anchoring strategies
- Available
highlighter engines
Interfaces provided for document access strategies
:
- Notify the manager about page rendering and un-rendering events
- Notify the manager about document content changes
Interfaces provided for highlights
:
- Notify the manager about user interactions involving
highlights
. (Mouse over, out, down, click, etc)
Interfaces provided for client code:
- Register
document access strategies
- Register
selector creators
- Register
anchoring strategies
- Register
highlighter engines
- Initialize the
manager
- Describe a given
segment description
withselectors
- Create an
anchor
from a given list ofselectors
(and optionally, store apayload
with it) - Remove an
anchor
- Get all
anchors
(for a given page) - Get all the
orphan
orhalf-orphan
loads
- Get all
highlights
(for a given set ofloads
) - Subscribe to various notifications (
anchors
created or removed,highlights
created or removed, user interacting with thehighlights
, etc.)
- The client code creates the
manager
object. - The client code loads and registers any wanted
document access strategies
,selector creators
,anchoring strategies
andhighlightter engines
. (Typically, these will be shipped in separate NPM modules.)
- The client code tells the
manager
to init. - The
manager
chooses adocument access strategy
, going through the registered strategies, according to the configured priority.
- The client code passes a
segment description
to themanager
. - The
manager
will ask all registeredselector creators
about thesegment description
. - The
selector creators
will attempt to describe thesegment description
byselectors
, relying on the data provided by thedocument access strategy
. - When all registered
selector creators
have responded, themanager
will compile a list of all the createdselectors
, and return it to the client code.
- The client code passes the list of
selectors
to themanager
, optionally together with apayload
. - The
manager
with consult with all the registeredanchoring strategies
, and ask each of them whether or not they can come up with ananchor
. (It will try them according to their configured priority.) - If one of the
anchoring strategies
manages to come up with andanchor
, and thisanchor
is returned to the client code. - Additionally, an attempt is made to immediately
realize
the newly createdanchor
. - If no
anchoring strategy
can create ananchor
, then thepayload
will be identified as anorphan
(or ahalf-orphan
, if an otheranchor
has successfully been created for the samepayload
elsewhere.)
- TODO
- The
platform
renders a page. - The active
document access strategy
recognizes the event, does the necessary parsing, and notifies themanager
. - The
manager
realizes
the page. realizing
apage
means that themanager
tries torealize
all theanchors
intersecting with the givenpage
.Realizing
ananchor
means that we identify thepages
which are now rendered, but for which nohighlight
exists, and we try to create those highlights.- The creation of a
highlight
is done by passing theanchor
(and the required page index) to all the registeredhighlight engines
, and asking them to render a highlight for it. (They are consulted according to their configured priority) - Depending on the result, the previously
virtual
orpartially real
anchor
might becomereal
orpartially real
, depending the existence and status of other pages intersecting with this anchor.
- The
platform
un-renders a page - The active
document access strategy
recognizes the event, and notifies themanager
. - The
manager
virtualizes
the page. Virtualizing
apage
means that themanager
tries tovirtualize
all theanchors
intersecting with the given page.Virtualizing
ananchor
for a given page means removing the correspondinghighlight
from the givenpage
, and marking theanchor
asvirtual
(orpartially real
, depending the existence of other pages intersecting with this anchor).
- The
platform
changes the content of thedocuemnt
- The active
document access strategy
recognizes the content changes, and notifies themanager
. - The
manager
will go over the currently existinganchors
, and try toverify
them, using theanchoring strategy
that originally created the givenanchor
. - The
manager
removes theanchors
which were invalidated by the document content change, thus turning someloads
intoorphans
(orhalf-orphans
). - The
manager
will try to create all the missinganchors
for the currentlyorphan
orhalf-orphan
loads
.