WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
88793
Implement undoscope attribute.
https://bugs.webkit.org/show_bug.cgi?id=88793
Summary
Implement undoscope attribute.
Rakesh
Reported
2012-06-11 11:12:43 PDT
Implement undoscope attribute specified at
http://dvcs.w3.org/hg/undomanager/raw-file/tip/undomanager.html
.
Attachments
Proposed patch
(8.52 KB, patch)
2012-06-11 11:34 PDT
,
Rakesh
rniwa
: review-
Details
Formatted Diff
Diff
Updated patch
(12.23 KB, patch)
2012-06-14 04:30 PDT
,
Rakesh
rniwa
: review-
Details
Formatted Diff
Diff
patch3
(12.44 KB, patch)
2012-06-19 07:24 PDT
,
Rakesh
rniwa
: review-
Details
Formatted Diff
Diff
Patch
(14.13 KB, patch)
2012-07-24 18:38 PDT
,
Sukolsak Sakshuwong
no flags
Details
Formatted Diff
Diff
Patch
(14.16 KB, patch)
2012-07-24 19:00 PDT
,
Sukolsak Sakshuwong
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from gce-cr-linux-05
(1.03 MB, application/zip)
2012-07-24 20:00 PDT
,
WebKit Review Bot
no flags
Details
Patch
(14.74 KB, patch)
2012-07-25 09:00 PDT
,
Sukolsak Sakshuwong
no flags
Details
Formatted Diff
Diff
Patch
(15.41 KB, patch)
2012-07-25 13:12 PDT
,
Sukolsak Sakshuwong
no flags
Details
Formatted Diff
Diff
Patch
(19.39 KB, patch)
2012-07-25 19:34 PDT
,
Sukolsak Sakshuwong
no flags
Details
Formatted Diff
Diff
Patch
(22.70 KB, patch)
2012-07-26 00:30 PDT
,
Sukolsak Sakshuwong
no flags
Details
Formatted Diff
Diff
Patch
(22.68 KB, patch)
2012-07-26 14:02 PDT
,
Sukolsak Sakshuwong
no flags
Details
Formatted Diff
Diff
Show Obsolete
(8)
View All
Add attachment
proposed patch, testcase, etc.
Rakesh
Comment 1
2012-06-11 11:34:06 PDT
Created
attachment 146883
[details]
Proposed patch Initial patch.
Ryosuke Niwa
Comment 2
2012-06-11 12:02:07 PDT
Comment on
attachment 146883
[details]
Proposed patch View in context:
https://bugs.webkit.org/attachment.cgi?id=146883&action=review
> Source/WebCore/dom/Element.idl:146 > + attribute [Conditional=UNDO_MANAGER] boolean undoScope;
This should just "reflect".
> Source/WebCore/dom/Element.cpp:2126 > +void Element::setUndoScope(bool undoScope) > +{ > + setAttribute(undoscopeAttr, undoScope ? "true" : "false"); > + if (!undoScope) { > + if (undoManager()) > + rareData()->m_undoManager.clear(); > + return; > + } > + > + if (!isRootEditableElement()) > + return; > + createUndoManager(); > +}
I think this is backwards. parsedAttribute should be calling this function instead.
> Source/WebCore/html/HTMLElement.cpp:218 > + if (attribute.name() == undoscopeAttr && equalIgnoringCase(attribute.value(), "true") && isRootEditableElement())
undoscope attribute doesn't take boolean values. It's a boolean attribute, meaning that it's set iff we have undoscope=undoscope or undoscope.
> Source/WebCore/html/HTMLElement.cpp:221 > + if (attribute.name() == contenteditableAttr && (attribute.isEmpty() || !equalIgnoringCase(attribute.value(), "false")) && equalIgnoringCase(fastGetAttribute(HTMLNames::undoscopeAttr), "true")) > + createUndoManager();
When contenteditable attribute is set, we need to disconnect existing undo manager in the subtree.
Rakesh
Comment 3
2012-06-14 04:30:04 PDT
Created
attachment 147552
[details]
Updated patch
Ryosuke Niwa
Comment 4
2012-06-14 11:14:47 PDT
Comment on
attachment 147552
[details]
Updated patch View in context:
https://bugs.webkit.org/attachment.cgi?id=147552&action=review
> Source/WebCore/dom/Element.cpp:2111 > +void Element::createUndoManager() > +{ > + if (!ensureRareData()->m_undoManager) > + rareData()->m_undoManager = UndoManager::create(this); > +}
This function is only called in setUndoScope. I'm failing to see why we need to have a separate function for this.
> Source/WebCore/dom/Element.cpp:2121 > + if (!fastHasAttribute(undoscopeAttr)) {
Why does a function called setUndoScope checks if it has undoscope attribute or not? I would have merged this function into createUndoManager and checked the existence of undoscope attribute in restoreDescendentsUndoManagers.
> Source/WebCore/dom/Element.cpp:2124 > + undoManager()->disconnect(); > + clearUndoManager();
Instead of forcing users to call disconnect before clearUndoManager. I would have just made clearUndoManager() automatically call disconnect. In fact, I would have added disconnectUndoManager() instead of clearUndoManager.
> Source/WebCore/dom/Element.cpp:2137 > + for (Node* node = firstChild(); node && node->isElementNode(); node = node->traverseNextNode(this)) { > + Element* element = toElement(node);
This is not right. You can certainly encounter a text node before seeing the first element. e.g. <div>hello<div undoScope></div></div> r- because of this bug.
> Source/WebCore/dom/Element.cpp:2148 > + for (Node* node = firstChild(); node && node->isElementNode(); node = node->traverseNextNode(this)) { > + Element* element = toElement(node);
Ditto.
> Source/WebCore/editing/UndoManager.cpp:58 > + // FIXME Set INVALID_ACCESS_ERR exception.
Missing : after FIXME.
> LayoutTests/editing/undomanager/undoscope-attribute.html:5 > +<meta charset="utf-8"> > +<script src="../../fast/js/resources/js-test-pre.js"></script>
For undo manager tests, we're going to use testharness.js instead of js-test-pre.js so that we may submit them to W3C later.
> LayoutTests/editing/undomanager/undoscope-attribute.html:37 > +shouldBe('div2.contentEditable = false; Object.prototype.toString.call(document.getElementById("newlyAdded").undoManager)', "'[object UndoManager]'");
The name newlyAdded is inappropriate here. Also, we need to test a case where we have multiple undo scope hosts, and a case where we have a bunch of text nodes, and other random nodes around them.
> LayoutTests/editing/undomanager/undoscope-attribute-expected.txt:7 > +PASS div1.undoScope is true > +PASS Object.prototype.toString.call(div1.undoManager) is '[object UndoManager]'
This output isn't helpful because I can't see what div1 is. I would have added a function like createElement and used evalAndLog like this: evalAndLog("div1 = createElement('div', {'undoscope':null, 'contenteditable: 'true'});"); Also, why do we need to use Object.prototype.toString.call? Can't we just do div1.undoManager.toString() ?
Rakesh
Comment 5
2012-06-15 03:57:31 PDT
(In reply to
comment #4
) Thanks for reviewing this patch.
> This function is only called in setUndoScope. > I'm failing to see why we need to have a separate function for this.
> Why does a function called setUndoScope checks if it has undoscope attribute or not? > I would have merged this function into createUndoManager and checked the existence of undoscope attribute in restoreDescendentsUndoManagers.
May be I will merge createUndoManager and setUndoScope into a fucntion with name handleUndoScopeAttributeChange.
> Instead of forcing users to call disconnect before clearUndoManager. > I would have just made clearUndoManager() automatically call disconnect. > In fact, I would have added disconnectUndoManager() instead of clearUndoManager.
Will do.
> > Source/WebCore/dom/Element.cpp:2137 > > + for (Node* node = firstChild(); node && node->isElementNode(); node = node->traverseNextNode(this)) { > > + Element* element = toElement(node); > > This is not right. You can certainly encounter a text node before seeing the first element. e.g. <div>hello<div undoScope></div></div> > r- because of this bug. >
My bad, will change this.
> > Source/WebCore/editing/UndoManager.cpp:58 > > + // FIXME Set INVALID_ACCESS_ERR exception. > > Missing : after FIXME. >
Will add ':'.
> > LayoutTests/editing/undomanager/undoscope-attribute.html:5 > > +<meta charset="utf-8"> > > +<script src="../../fast/js/resources/js-test-pre.js"></script> > > For undo manager tests, we're going to use testharness.js instead of js-test-pre.js so that we may submit them to W3C later.
Initially I tried with testharness.js, some how I could not get the output, will give a try once again.
> The name newlyAdded is inappropriate here. > Also, we need to test a case where we have multiple undo scope hosts, and a case where we have a bunch of text nodes, and other random nodes around them. > > This output isn't helpful because I can't see what div1 is. I would have added a function like createElement and used evalAndLog like this: > evalAndLog("div1 = createElement('div', {'undoscope':null, 'contenteditable: 'true'});"); > Also, why do we need to use Object.prototype.toString.call? Can't we just do div1.undoManager.toString() ?
Will try all these in the new test.
Ryosuke Niwa
Comment 6
2012-06-15 06:51:04 PDT
(In reply to
comment #5
)
> (In reply to
comment #4
) > Thanks for reviewing this patch. > > > This function is only called in setUndoScope. > > I'm failing to see why we need to have a separate function for this. > > > Why does a function called setUndoScope checks if it has undoscope attribute or not? > > I would have merged this function into createUndoManager and checked the existence of undoscope attribute in restoreDescendentsUndoManagers. > > May be I will merge createUndoManager and setUndoScope into a fucntion with name handleUndoScopeAttributeChange.
I don't think that's a good name. These two functions together create a new undo manager, but does not destroy the existing undo managers. If a function is named like handleUndoScopeAttributeChange, I would expect it to handle both. Note I'm not saying that you should add handleUndoScopeAttributeChange. I'm just objecting to the name. createUndoManager is a much better name here.
Rakesh
Comment 7
2012-06-19 07:24:31 PDT
Created
attachment 148329
[details]
patch3 Addressed review comments.
> This output isn't helpful because I can't see what div1 is. I would have added a function like createElement and used evalAndLog like this: > evalAndLog("div1 = createElement('div', {'undoscope':null, 'contenteditable: 'true'});");
Do we have any way in testharness.js to log something like this. As of now I have added some description to each step.
Ryosuke Niwa
Comment 8
2012-06-19 13:08:52 PDT
Comment on
attachment 148329
[details]
patch3 View in context:
https://bugs.webkit.org/attachment.cgi?id=148329&action=review
> Source/WebCore/dom/Element.idl:146 > + // Undo Manager
This comment is a pure noise. Please remove.
> Source/WebCore/dom/Element.cpp:2111 > + return fastHasAttribute(HTMLNames::undoscopeAttr) && undoManager();
The call to fastHasAttribute(HTMLNames::undoscopeAttr) is redundant here because undoManager() returns false when undoscope is not set.
> Source/WebCore/dom/Element.cpp:2118 > + if (hasRareData()) > + return rareData()->m_undoManager; > + return 0;
Why don't we use ternary operator here?
> Source/WebCore/dom/Element.cpp:2121 > +void Element::createUndoManager()
createUndoManager is a misnomer here it doesn't always create undo manager. Maybe createUndoManagerIfPossible? I think it would be cleaner if the check for isContentEditable() && !isRootEditableElement() was in the caller instead.
> Source/WebCore/dom/Element.cpp:2143 > + if (!node->isElementNode() || !toElement(node)->undoManager()) > + continue; > + toElement(node)->disconnectUndoManager();
Here, you're obtaining the node rare data twice by calling undoManager() before calling disconnectUndoManager(). Since disconnectUndoManager bails out when there isn't undo manager, it's probably better to always call disconnectUndoManager instead. Also, it would have been cleaner if the call to disconnectUndoManager as in the if statement as in: if (node->isElementNode()) toElement(node)->disconnectUndoManager();
> Source/WebCore/html/HTMLElement.cpp:226 > + if (equalIgnoringCase(attribute.value(), "false")) > + return restoreDescendentsUndoManagers(); > + return disconnectDescendentsUndoManagers();
I don't think this works. contenteditable could also be set to "inherent". Also, value() could be null when the attribute had been removed. See
http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#contenteditable
r- because of this.
> LayoutTests/editing/undomanager/undoscope-attribute.html:22 > +var div1 = document.getElementById("divid1"); > +var div2 = document.getElementById("divid2"); > +var div3 = document.getElementById("divid3");
Instead of 1-3, use some descriptive name instead.
Caio Marcelo de Oliveira Filho
Comment 9
2012-06-19 17:46:45 PDT
We should also consider the case when a node with undoscope is removed from an editing host that also has undoscope. It seems to me that in this case the undomanager of the removed node must be recreated.
Rakesh
Comment 10
2012-06-21 04:23:09 PDT
(In reply to
comment #8
) Thanks for review.
> > I think it would be cleaner if the check for isContentEditable() && !isRootEditableElement() was in the caller instead. >
I am not sure if the present check for isContentEditable() or isRootEditableElement() in parsing code is fine. Even if updateLayoutIgnoringPendingStylesheets (as discussed on IRC) is called before checking, the present renderer may still be not created and we may not get the correct result for isContentEditable/isRootEditableElement. Correct me if I am missing something. Can we check for editing host/editable by checking for contenteditable attribute in the tree or something else we can do?
Rakesh
Comment 11
2012-06-22 00:59:11 PDT
For the following example: <div id=divCE contenteditable=true > <div id=divUS undoscope > </div> </div> when undoscope is being parsed we need to know if divUS is editable element or root editable element to decide if we have to create an UndoManager for div2 or not. The issue is when isContentEditable() and isRootEditableElement() are based on renderers of the node and at time of parsing we are not sure if renderers are created. I tried invoking updateLayoutIgnorePendingStylesheets() before the above checks but it does not help, renderer's still not created. Please suggest what could be the better approach for solving this?
Ryosuke Niwa
Comment 12
2012-07-12 12:40:36 PDT
(In reply to
comment #11
)
> For the following example: > > <div id=divCE contenteditable=true > > <div id=divUS undoscope > </div> > </div> > > when undoscope is being parsed we need to know if divUS is editable element or root editable element to decide if we have to create an UndoManager for div2 or not. > > The issue is when isContentEditable() and isRootEditableElement() are based on renderers of the node and at time of parsing we are not sure if renderers are created. > > I tried invoking updateLayoutIgnorePendingStylesheets() before the above checks but it does not help, renderer's still not created.
Yeah... I don't know how to solve that problem. Maybe we can wait until the parser yields? We layout & paint when the parse yields. Eric might have some idea on this.
Eric Seidel (no email)
Comment 13
2012-07-16 23:04:37 PDT
(In reply to
comment #12
)
> (In reply to
comment #11
) > > For the following example: > > > > <div id=divCE contenteditable=true > > > <div id=divUS undoscope > </div> > > </div> > > > > when undoscope is being parsed we need to know if divUS is editable element or root editable element to decide if we have to create an UndoManager for div2 or not. > > > > The issue is when isContentEditable() and isRootEditableElement() are based on renderers of the node and at time of parsing we are not sure if renderers are created. > > > > I tried invoking updateLayoutIgnorePendingStylesheets() before the above checks but it does not help, renderer's still not created. > > Yeah... I don't know how to solve that problem. Maybe we can wait until the parser yields? We layout & paint when the parse yields. Eric might have some idea on this.
Oh noes. Please don't depend on renderers during parsing. You'll slow down parsing:
https://bugs.webkit.org/show_bug.cgi?id=70009
In any case, you should design for the dynamic case, and then that tends to not be any different than parsing. I'm happy to answer further questions if you need? I fear I wasn't very helpful.
Sukolsak Sakshuwong
Comment 14
2012-07-24 18:38:14 PDT
Created
attachment 154214
[details]
Patch
Sukolsak Sakshuwong
Comment 15
2012-07-24 19:00:07 PDT
Created
attachment 154217
[details]
Patch
WebKit Review Bot
Comment 16
2012-07-24 20:00:32 PDT
Comment on
attachment 154217
[details]
Patch
Attachment 154217
[details]
did not pass chromium-ews (chromium-xvfb): Output:
http://queues.webkit.org/results/13342083
New failing tests: fast/loader/loadInProgress.html fast/inline/positionedLifetime.html fast/loader/unload-form-post-about-blank.html
WebKit Review Bot
Comment 17
2012-07-24 20:00:37 PDT
Created
attachment 154226
[details]
Archive of layout-test-results from gce-cr-linux-05 The attached test failures were seen while running run-webkit-tests on the chromium-ews. Bot: gce-cr-linux-05 Port: <class 'webkitpy.common.config.ports.ChromiumXVFBPort'> Platform: Linux-2.6.39-gcg-201203291735-x86_64-with-Ubuntu-10.04-lucid
Sukolsak Sakshuwong
Comment 18
2012-07-25 09:00:37 PDT
Created
attachment 154370
[details]
Patch
Ryosuke Niwa
Comment 19
2012-07-25 10:43:44 PDT
Comment on
attachment 154370
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154370&action=review
> Source/WebCore/dom/Element.cpp:2211 > + if (!undoScope() || (isContentEditable() && !isRootEditableElement())) > + return 0;
Since we're doing this lazily for -webkit-user-modify, we need to disconnect the undo manager as needed here. Also, each method of undo manager needs to check whether undo manager had been disconnected or not upfront and throw & disconnect itself as needed.
> Source/WebCore/dom/Element.cpp:2241 > + if (node->isContentEditable()) > + element->disconnectUndoManager();
This is not right. It's possible to have an editable element within a non-editable element within an editable element. e.g. <div undoscope><span contenteditable=false><span contenteditable=true undoscope>hello</span></span></div> div.contentEditable=true should NOT disconnect the undoManager on the inner-most span because the inner most element had always been editable. r- because of this.
Sukolsak Sakshuwong
Comment 20
2012-07-25 13:12:45 PDT
Created
attachment 154422
[details]
Patch
Ryosuke Niwa
Comment 21
2012-07-25 16:13:19 PDT
Comment on
attachment 154422
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154422&action=review
> LayoutTests/editing/undomanager/undoscope-attribute-expected.txt:3 > +PASS Element d has the undoscope attribute set to true.
Please use more descriptive name than "d".
Daniel Bates
Comment 22
2012-07-25 16:38:28 PDT
Comment on
attachment 154422
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154422&action=review
I know that this patch has already been reviewed. I noticed some minor notes and had some questions.
> Source/WebCore/WebCore.gypi:2713 > + 'editing/UndoManager.cpp', > + 'editing/UndoManager.h',
I take it that this change is only applicable to Chromium?
> Source/WebCore/dom/Element.cpp:2205 > + setAttribute(undoscopeAttr, "");
Would it be sufficient to construct a null AtomicString() (i.e. call the AtomicString() constructor with no arguments) instead of an AtomicString with an empty string?
> Source/WebCore/editing/UndoManager.h:57 > + inline unsigned long length() const { return m_undoStack.size() + m_redoStack.size(); }
From my understanding, a member function defined within a class definition is implicitly an inline function. So, it's unnecessary to explicitly add the inline keyword to this function signature.
Daniel Bates
Comment 23
2012-07-25 17:10:14 PDT
Comment on
attachment 154422
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154422&action=review
>> Source/WebCore/dom/Element.cpp:2205 >> + setAttribute(undoscopeAttr, ""); > > Would it be sufficient to construct a null AtomicString() (i.e. call the AtomicString() constructor with no arguments) instead of an AtomicString with an empty string?
Disregard this comment. Passing a null AtomicString would remove the attribute by <
http://trac.webkit.org/browser/trunk/Source/WebCore/dom/Element.cpp?rev=123636#L674
>. Can we use emptyAtom?
Ryosuke Niwa
Comment 24
2012-07-25 17:12:36 PDT
Comment on
attachment 154422
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154422&action=review
Sorry, I wasn't thinking straight when I reviewed this patch. Please add a test cases where you modify content attribute by calling setAttribute. As is, it won't do the right thing.
> Source/WebCore/dom/Element.cpp:2199 > + return fastHasAttribute(HTMLNames::undoscopeAttr);
Ugh... we shouldn't be storing states in attribute like this. What we need to store it in Element (probably rare data instead).
> Source/WebCore/dom/Element.idl:147 > + attribute [Conditional=UNDO_MANAGER] boolean undoScope;
We should have [Reflect] on this.
Sukolsak Sakshuwong
Comment 25
2012-07-25 19:34:49 PDT
Created
attachment 154527
[details]
Patch
Ryosuke Niwa
Comment 26
2012-07-25 19:47:00 PDT
Comment on
attachment 154527
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154527&action=review
> Source/WebCore/dom/Element.cpp:2215 > + if (!undoScope() || (isContentEditable() && !isRootEditableElement())) { > + disconnectUndoManager(); > + return 0; > + }
We need to do this on every method of undo manager since scripts can keep a reference to it.
> Source/WebCore/dom/Element.cpp:2236 > +void Element::disconnectEditableDescendentsUndoManagers()
I would prefer calling it disconnectUndoManagersInSubtree.
> Source/WebCore/editing/UndoManager.h:57 > + unsigned long length() const { return m_undoStack.size() + m_redoStack.size(); }
This can just be "unsigned length()".
> LayoutTests/editing/undomanager/undoscope-attribute.html:44 > + element.removeAttribute('undoscope');
We should explicitly set the attribute first.
> LayoutTests/editing/undomanager/undoscope-attribute.html:59 > +test(function() { > + element.setAttribute('undoscope', ''); > + > + assert_equals(element.undoManager.toString(), "[object UndoManager]"); > +}, "After element.setAttribute('undoscope', ''), element.undoManager returns an UndoManager object."); > + > +test(function() { > + element.setAttribute('undoscope', 'undoscope'); > + > + assert_equals(element.undoManager.toString(), "[object UndoManager]"); > +}, "After element.setAttribute('undoscope', 'undoscope'), element.undoManager returns an UndoManager object.");
I would like to see test cases where undoScope IDL attribute and undoscope content attributes are set in turn.
Sukolsak Sakshuwong
Comment 27
2012-07-26 00:30:53 PDT
Created
attachment 154562
[details]
Patch
Ryosuke Niwa
Comment 28
2012-07-26 10:41:02 PDT
Comment on
attachment 154562
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154562&action=review
> Source/WebCore/editing/UndoManager.cpp:111 > + if (!m_undoScopeHost->isElementNode()) > + return true;
host can't become a non-element so this check is superfluous.
> Source/WebCore/editing/UndoManager.cpp:113 > + if (!element->undoScope() || (element->isContentEditable() && !element->isRootEditableElement())) {
undoscope attribute can't be changed by CSS so we should ASSERT(element->undoScope()) instead of disconnecting undo manager when undoScope evaluates to true.
Sukolsak Sakshuwong
Comment 29
2012-07-26 13:49:48 PDT
(In reply to
comment #28
)
> > Source/WebCore/editing/UndoManager.cpp:111 > > + if (!m_undoScopeHost->isElementNode()) > > + return true; > > host can't become a non-element so this check is superfluous.
Host can be a Document, which is a non-element.
Sukolsak Sakshuwong
Comment 30
2012-07-26 14:02:17 PDT
Created
attachment 154743
[details]
Patch
Adam Barth
Comment 31
2012-07-26 16:25:15 PDT
Comment on
attachment 154743
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=154743&action=review
> Source/WebCore/editing/UndoManager.cpp:111 > + return true;
Should we add ASSERT(m_undoScopeHost->isDocument()) in this branch?
> Source/WebCore/editing/UndoManager.cpp:115 > + element->disconnectUndoManager();
It's strange for a function like UndoManager::isConnected to have side-effects. I might call this function something like disconnectIfNecessary()...
WebKit Review Bot
Comment 32
2012-07-26 18:29:13 PDT
Comment on
attachment 154743
[details]
Patch Clearing flags on attachment: 154743 Committed
r123827
: <
http://trac.webkit.org/changeset/123827
>
WebKit Review Bot
Comment 33
2012-07-26 18:29:20 PDT
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug