Closed Bug 186540 Opened 22 years ago Closed 21 years ago

document.createRange() should create a usable Range object

Categories

(Core :: DOM: Core & HTML, defect, P4)

defect

Tracking

()

VERIFIED FIXED

People

(Reporter: Laurens, Assigned: caillon)

References

Details

(Keywords: dom2, fixed-aviary1.0, fixed1.7.5)

Attachments

(1 file)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3b) Gecko/20021222 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3b) Gecko/20021222 If there is no selection, reading any property on the range object returned by document.createRange() will generate an error. Reproducible: Always Steps to Reproduce: 1. Enter the following url in the address bar: javascript:document.createRange().commonAncestorContainer; 2. See javascript console for the error. Actual Results: Error: uncaught exception: [Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMRange.commonAncestorContainer]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)" location: "JS frame :: javascript:document.createRange().commonAncestorContainer; :: <TOP_LEVEL> :: line 1" data: no] Expected Results: IE will return a range of length 0 positioned before the body element. I'm not sure if this behaviour is desired, but at least it returns a queryable range object. I would be happy if the commonAncestorContainer == null or if there would be some clean way to find out that the range object is invalid.
Blocks: oscom
caillon, you know anything about this code?
Um, this is a glaring fault in our range implementation. Our impl has it so that ranges must first be initialized ("positioned") before they can be used. However this is not the case per the spec. The initial state of the Range returned from [document.createRange()] is such that both of its boundary-points are positioned at the beginning of the corresponding Document, before any content. In other words, the container of each boundary-point is the Document node and the offset within that node is 0. http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level-2-Range-Creating I found one particular comment quite interesting in nsRange.cpp: 202 PRBool isPositioned; 203 nsresult err = ((nsRange*)aRange)->GetIsPositioned(&isPositioned); 204 // Why do I have to cast above? Because GetIsPositioned() is 205 // mysteriously missing from the nsIDOMRange interface. dunno why. The "why" is because all ranges are positioned: they start out that way and unless I misread something in the spec, cannot become unpositioned. setStart() and friends all take non-null arguments, which I might add seem to not throw if the node is null (which is IMO the only thing that is mysterious about this portion of the spec). So this method should really be returning true all the time. Anyway.... the real bug is that document.createRange() does not create a usable Range object. All you can do once you have created the range is a few things which "initialize" it, though that is not necessary per the spec. It should be usable out of the box. The fix is to update the callers of NS_NewRange and friends to pass in an nsIDOMDocument, and that sent on to the nsRange constructor where the proper defaults per the spec are set up. GetIsPositioned(), mIsPositioned, etc. can then be removed from the class, as well as a bunch of checks throughout the file. I am tentatively taking this for now since I will try and work on it after the new year, but if anyone (kin, jfrancis?) wants to grab this bug, by all means go ahead since it may be a while before I get to it.
Assignee: anthonyd → caillon
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: dom2
Summary: document.createRange().commonAncestorContainer generates an error if there is no selection. → document.createRange() should create a usable Range object
OS: Windows 2000 → All
Hardware: PC → All
hmmm. I'm pretty sure that the range spec wasn't this way back when we wrote the code in nsRange.cpp. One thing we don't want to do is to change the Range implementation to require a document passed in. Ranges work on things that aren't documents, and that is very useful. It is createRange in DocumentRange that needs to change, not anything in Range. createRange should create a range, and then fetch the document root and initialize the created range appropriately. Don't change Range itself to require a document: it shouldn't.
*** Bug 158182 has been marked as a duplicate of this bug. ***
Priority: -- → P4
QA Contact: nobody → ian
Attachment #148102 - Flags: superreview?(jst)
Attachment #148102 - Flags: review?(jst)
Comment on attachment 148102 [details] [diff] [review] Make this work from DOM calls r+sr=jst
Attachment #148102 - Flags: superreview?(jst)
Attachment #148102 - Flags: superreview+
Attachment #148102 - Flags: review?(jst)
Attachment #148102 - Flags: review+
*** Bug 245668 has been marked as a duplicate of this bug. ***
Chris, what remains to be done here?
Comment on attachment 148102 [details] [diff] [review] Make this work from DOM calls I think this should go on the branch.. it's very safe and makes createRange much more usable.
Attachment #148102 - Flags: approval1.7?
Nothing else needs to be done. I just forgot to mark it fixed. I don't mind landing it on the branch. The backend work I outlined in comment 2 should be done at some point, but can be shifted to a different bug. (In reply to comment #3) > One thing we don't want to do is to change the Range implementation to > require a document passed in. Ranges work on things that aren't documents, > and that is very useful. Yes, those "things that aren't documents" (assuming you meant that aren't _in_ documents) are in document fragments, and those also must have a document associated with them. They do most of the time currently in Mozilla. I think there is one caller which does not provide a document (at least there was only one when I looked last year). We could save some code forkage/duplication if we just did this the right way and always created fragments and ranges with the correct parentage. And as a bonus, we will ensure we follow the relevant specs. ;-)
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Comment on attachment 148102 [details] [diff] [review] Make this work from DOM calls a=asa (on behalf of drivers) for checkin to 1.7
Attachment #148102 - Flags: approval1.7? → approval1.7+
Did this land on the branch? Time is nearly up.
(In reply to comment #12) > Did this land on the branch? Time is nearly up. Based on bonsai graph, it did not: it only went into Trunk r3.498 (= Mv1.8a1). Christopher (or anyone): Could you check it in Mv1.7 branch too ?
bz, jst: Could one of you land this on the branch? I think this should be done by someone who understands this patch and caillon doesn't seem to be available at the moment.
Comment on attachment 148102 [details] [diff] [review] Make this work from DOM calls It seems that it's a little too late to take this for 1.7... we may still want this for 1.7.x, though (note it was approved for 1.7 but not one managed to land it on the branch...)
Attachment #148102 - Flags: approval1.7.2?
Comment on attachment 148102 [details] [diff] [review] Make this work from DOM calls a=mkaply for 1.7.2
Attachment #148102 - Flags: approval1.7.2? → approval1.7.2+
Fixed on the 1.7 branch.
Keywords: fixed1.7.2
Status: RESOLVED → VERIFIED
Component: DOM: Traversal-Range → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: