Static Range

Editor’s Draft,

This version:
https://w3c.github.io/staticrange/
Latest published version:
http://www.w3.org/TR/staticrange/
Previous Versions:
<none>
Feedback:
public-webapps@w3.org with subject line “[staticrange] … message topic …” (archives)
Issue Tracking:
GitHub
Editor:
(Google)
Tests:
web-platform-tests staticrange/

Abstract

This specification defines a lightweight StaticRange that can be used in place of a Range when the complexity of a full Range is not necessary.

Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

Changes to this document may be tracked at https://github.com/w3c/staticrange.

If you wish to make comments regarding this document, please send them to this specification’s GitHub repository or (archived) public mailing list public-webapps@w3.org (see instructions). When sending e-mail, please put the text “staticrange” in the subject, preferably like this: “[staticrange] …summary of comment…. All comments are welcome.

This document was produced by the Web Platform Working Group.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

This document is an editor’s draft proposed as a First Public Working Draft. It has been developed in the editing task force of the Web platform working group.

1. Introduction

DOM4 defines a Range object (originally from DOM2 Traversal/Range) which can be used to represent a sequence of content in the DOM tree. A Range consists of a start boundary (a node and an offset) and an end boundary (also a node and an offset). A key benefit of using a Range is that once it is created, it will maintain the integrity of the range as best it can even in the face of DOM mutations.

A problem with Range is that whenever a DOM mutation occurs, all of the active Range objects affected by the mutation need to be updated. This can be an expensive operation, especially if there are a large number of active Range objects. This cost may be acceptable if all of these Range objects are actually needed by the application, but Range is used whenever we need to record start- and end-positions. Because of this, many of the Range objects that are created are not actually used by the application, and many of the Range objects that are being used don’t actually need their range start and end to be resilient to DOM mutations.

This problem is exacerbated when an application caches an object that happens to contain a Range along with other data that the application needs. As long as this object is active, the Range will be active and it will need to be updated for every DOM mutation. In this manner, an application can end up with many active Range objects even if none of them are being used.

A StaticRange is a simple, lightweight range that contains only a start and an end boundary (node + offset) and does not update when the DOM is mutated.

1.1. Interface StaticRange

The StaticRange interface provides readonly attributes that track the start and end position of the range, and a readonly boolean attribute that indicates whether or not the current range is collapsed to a single position (where the start equals the end position).

dictionary StaticRangeInit {
  required Node startContainer;
  required unsigned long startOffset;
  required Node endContainer;
  required unsigned long endOffset;
};

[Constructor(StaticRangeInit initDict),
  Exposed=Window]
interface StaticRange {
  attribute Node startContainer;
  attribute unsigned long startOffset;
		
  attribute Node endContainer;
  attribute unsigned long endOffset;
		
  readonly attribute boolean collapsed;

  [NewObject] Range toRange();
};

startContainer

The start Node for the range.

startOffset

The offset into the start node identifying the start position for the range.

endContainer

The end Node for the range.

endOffset

The offset into the start node identifying the end position for the range.

collapsed

True if the range’s start position and end position are the same, as determined by executing is collapsed.

2. Algorithms

A StaticRange position is the combination of a Node position node and an unsigned long position offset into that node. The position offset is the offset from the start of the position node to the desired position.

The start position of a StaticRange r is the position defined by r’s startContainer and startOffset.

The end position of a StaticRange r is the position defined by r’s endContainer and endOffset.

2.1. a position p1 is less than another position p2

Input

p1, a StaticRange position

p2, a StaticRange position

Output

Boolean

  1. If p1’s position node precedes p2’s position node in the DOM tree, return True.

  2. If p1’s position node is the same as p2’s position node,

    1. If p1’s position offset is less than p2’s position offset, return True.

    2. Else, return False.

  3. Return False.

2.2. a position p1 is equal to another position p2

Input

p1, a StaticRange position

p2, a StaticRange position

Output

Boolean

  1. If p1’s position node is the same as p2’s position node,

    1. If p1’s position offset is equal to p2’s position offset,

      1. Return True.

  2. Return False.

2.3. a StaticRange is collapsed

Input

sr, a StaticRange

Output

Boolean

  1. If sr’s start position is equal to sr’s end position,

    1. Return True

  2. Return False

2.4. a StaticRange is valid

Input

sr, a StaticRange to be validated

Output

Boolean

  1. If sr’s startContainer and endContainer do not share the same ancestor,

    1. Return False

  2. If sr’s end position is less than sr’s start position,

    1. Return False

  3. If sr’s startOffset is greater than the node length of the startContainer,

    1. Return False

  4. If sr’s endOffset is greater than the node length of the endContainer,

    1. Return False

  5. Return True

3. Acknowledgements

Thanks to the following people for the discussions that lead to the creation of this proposal:

Enrica Casucci (Apple), Bo Cupp (Microsoft), Emil Eklund (Google), Wenson Hsieh (Apple), Gary Kacmarcik (Google), Ian Kilpatrick (Google), Grisha Lyukshin (Microsoft), Miles Maxfield (Apple), Ryosuke Niwa (Apple), Olli Pettay (Mozilla), Dave Tapuska (Google), Ojan Vafai (Google), Johannes Wilm (Fidus), Chong Zhang (Gooogle)

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WebIDL]
Cameron McCormack; Boris Zbarsky; Tobie Langel. Web IDL. URL: https://heycam.github.io/webidl/
[WHATWG-DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/

IDL Index

dictionary StaticRangeInit {
  required Node startContainer;
  required unsigned long startOffset;
  required Node endContainer;
  required unsigned long endOffset;
};

[Constructor(StaticRangeInit initDict),
  Exposed=Window]
interface StaticRange {
  attribute Node startContainer;
  attribute unsigned long startOffset;
		
  attribute Node endContainer;
  attribute unsigned long endOffset;
		
  readonly attribute boolean collapsed;

  [NewObject] Range toRange();
};