[annotator-dev] About the future of the Range implementation
tilgovi at hypothes.is
Tue Jun 17 01:10:51 UTC 2014
On Wed, Jun 11, 2014 at 11:50 AM, Randall Leeds <tilgovi at hypothes.is> wrote:
> +1 to releasing Range as a separate module.
> The best thing around besides ours seems to be Rangy and it unfortunately
> seems to be acquiring more stuff, such as a highlighter.
> A good Range package would be a great thing for the web dev community.
I suggested to Kristof this morning that we create a "dom-range" repo under
There was some disagreement [see transcript below] about whether this is a
In an attempt to resolve the issue, I'm taking stock of what's in this
This module implements three Range objects: BrowserRange, SerializedRange,
This serves to just provide a wrapper around the DOM Range object with two
Its properties are the same as the DOM Range object, though it lacks
properties that aren't used in Annotator.
In addition to these properties, it provides a normalize() and serialize()
call. The serialize() method returns an object fit for serialization (duh).
The normalize() method returns a NormalizedRange instance after normalizing
the range. Normalization involves moving the start or end of the range
based on some rules.
This object provides different properties than the DOM Range, but
encapsulates the same concept. It also adds a few other methods.
The serialize() method is actually the serialization as described in
BrowserRange. The BrowserRange serialize() method actually calls
normalize() first to get a NormalizedRange and then calls serialize() on
Most of serialization is a simple XPath builder with the added detail that
a relative root can be passed in.
NormalizedRange objects also provide a function to get the text nodes they
contain, to get the string of text contained by those text nodes, and to
get a real DOM Range object.
It's worth noting that NormalizedRange#text() is probably the equivalent of
the DOM Range #toString() method.
A limit() method provides the ability to reduce the range to only the nodes
that fall inside the given container.
This serves as an OO wrapper around a serializable Range. It contains an
XPath expression for each of the DOM Range object's start- and endContainer
properties as well a the start and end offsets. Its normalize() method
first attempts to resolve to XPath to find this range in the document and,
having resolved the start- and endContainer nodes, returns a
Very little in this module actually deviates from the DOM Range spec.
- Mostly, we don't implement the methods.
- Serialization and deserialization could be kept in Annotator itself. This
avoids having to extract our xpath code. We can evaluate that separately.
- Normalization and limiting are potentially reasonable proposals for the
Range spec. It makes me wonder whether a normalization algorithm in the
spec would have saved us from a lot of interop woes. Rangy implements a
normalization algorithm, too.
I would support extracting the Range module from Annotator. However, I
don't see much value beyond normalization and limiting.
The only other library on the radar that we see in use is Rangy.
- Implements Range and Selection in one library.
- The core weighs ~43KB minified compared with Annotator.Range at ~8KB.
A think a library that just focuses on being a good compatibility wrapper
for Range and contains a cross browser CI suite would be great. It'd be
useful to uncover and document which browsers implement the newest whatwg
range calls, #createContextualFragment(), #getClientRects(), and
#getBoundingClientRect(). I think defining a normalization algorithm,
whether it's a new method or something browsers do implicitly, would be
great for HTML Editing.
Rangy does contain an implementation of Range#createContextualFragment().
So, I don't think there's much "magic" here:
- The sniff function is only a few lines to detect between the three Range
- Serialization is probably best left out (for instance, Rangy has a CRC32
- Normalization is the core contribution that seems to be missing from the
Mostly we'd gain a place to keep this neat and separate, add tests as we
go, and perhaps plug some browser incompatibilities. We also get a place to
define our normalization algorithm exactly and implement it with tests so
others can use it.
Therefore, I'm in favor of just calling it "dom-range" and making it
implement the spec. Depending on the required browser compatibility, most
of the implementation can be trusted to the browser built-in Range object.
16:30:11 <csillag1> let's call the new repo MagicRange
16:30:19 <tilgovi> No.
16:30:20 <tilgovi> I'd rather not.
16:30:28 <csillag1> Range sounds way too generic.
16:30:34 <csillag1> It's not a useful name to identify a piece of code.
16:30:35 <tilgovi> I actually think we should just call it dom-range
16:30:43 <csillag1> Please no.
16:30:48 <csillag1> It's not something which we want to
16:30:48 <tilgovi> For now it can be extracted unchanged
16:30:55 <csillag1> promote
16:30:56 <Treora> ah that repo, I was looking at the one in hypothe.is
which has only one line of documentation. :)
16:31:05 <csillag1> it's legacy code, which has only been created
16:31:08 <csillag1> because of historical reasons.
16:31:19 <csillag1> Don't name it in a way that indicates
16:31:24 <tilgovi> But the best would be if we made a library that actually
just impediments a standard Range with tests and maybe new calls for
16:31:24 <csillag1> that it's something generally useful
16:31:29 <csillag1> part of our framework for the future, etc.
16:31:31 <tilgovi> It should be generally useful
16:31:33 <csillag1> I would actually get rid of it.
16:31:58 <csillag1> I was created to work around problems
16:32:02 <csillag1> which are probably long gone now.
16:32:12 <tilgovi> That's not true or we wouldn't use it.
16:32:15 <csillag1> The original research should be done again.
16:32:23 <csillag1> We are using because much of our code depends on it.
16:32:30 <tilgovi> And Rangy wouldn't exist.
16:32:35 <csillag1> But we don't need to write new code around it.
16:32:50 <csillag1> I don't know about the history of Rangy;
16:33:02 <csillag1> I just know that the current Range implementation
16:33:12 <csillag1> brings a large set of oddities along with it.
16:33:17 <csillag1> It does solve other problems,
16:33:22 <csillag1> but according to Nick,
16:33:23 <tilgovi> What we see from IE issues is not that the MS team has
done something wrong, but that the HTML Editing specs are drafts. They are
vague. They have holes and requests for feedback.
16:33:37 <csillag1> those problems are already gone now.
16:33:41 <tilgovi> Rangy's stated goal is a spec compliant Range
16:33:54 <csillag1> Well ... sounds like a nice goal,
16:33:57 <csillag1> but it's not there yet.
16:34:01 <csillag1> crashes under IE.
16:34:05 <tilgovi> But the specs aren't even really compete
16:34:06 <csillag1> Has a huge performance penalty.
16:34:08 <tilgovi> Complete
> On Jun 11, 2014 8:18 AM, "Kristof Csillag" <csillag at hypothes.is> wrote:
>> Hi all,
>> As some of you already know, currently I am working on separating all
>> the anchoring-related work that which Annotator does (both in the
>> Upstream version, both in the Hypothes.is fork) into a separate library,
>> which Annotator and other projects could use, but which can be developed
>> As a part of this problem, I need to have the current Range
>> implementation (BrowserRange, NormalizedRange, SerializedRange) in that
>> library, too.
>> How would you feel like releasing this part (the Range implementation)
>> as a separate NPM package, so that it can be plugged in easily wherever
>> we need it?
>> annotator-dev mailing list
>> annotator-dev at lists.okfn.org
>> Unsubscribe: https://lists.okfn.org/mailman/options/annotator-dev
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the annotator-dev