Safari fail to access a second time an element whose content was dynamically modified.
- patch by Anders Carlsson <andersca@mac.com>.
Reviewed by mjs + darin.
Test cases added:
* layout-tests/fast/dom/ids/duplicate-ids-expected.txt: Added.
* layout-tests/fast/dom/ids/duplicate-ids.html: Added.
* khtml/xml/dom_docimpl.cpp:
(DocumentImpl::getElementById):
If no element in the id dict can be found and we know that there's
at least one other element with the same id around, then traverse the document
and insert the new element in the id table.
(DocumentImpl::addElementById):
(DocumentImpl::removeElementById):
Increment and decrement the id count accordingly.
* khtml/xml/dom_docimpl.h:
Add QDict for id counts. Make element QDict mutable.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@9764
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
--- /dev/null
+This tests that getElementById works as elements with duplicate ids are added and removed. If the test is successful, the text "success" should be shown below.
+This is the first duplicate div
+This is the second duplicate div
+Success!
--- /dev/null
+<html>
+<head>
+<script>
+function debug(str) {
+ console = document.getElementById('console');
+
+ li = document.createElement('li');
+ console.appendChild(li);
+ li.appendChild(document.createTextNode(str));
+}
+
+function runTests() {
+ if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ }
+ div = document.getElementById('duplicate');
+ dup1 = div.parentNode.removeChild(div);
+
+ div = document.getElementById('duplicate');
+ if (!div) {
+ debug('Failed: getElementById returned null');
+ return;
+ }
+
+ if (div.firstChild.nodeValue != 'This is the second duplicate div') {
+ debug('Failed: getElementById returned the wrong div');
+ return;
+ }
+
+ dup2 = div.parentNode.removeChild(div);
+ if (document.getElementById('duplicate')) {
+ debug('Failed: getElementById did not return null');
+ return;
+ }
+
+ // Now insert the nodes again
+ container = document.getElementById('container');
+ container.appendChild(dup1);
+ container.appendChild(dup2);
+
+ if (!document.getElementById('duplicate')) {
+ debug('Failed: getElementById returned null');
+ return;
+ }
+
+ debug('Success!');
+}
+</script>
+</head>
+<body onLoad="runTests()">
+This tests that getElementById works as elements with duplicate ids are added and removed. If the test is successful, the text "success" should be shown below.
+<div id="container">
+<div id="duplicate">This is the first duplicate div</div>
+<div id="duplicate">This is the second duplicate div</div>
+</div>
+<ul id="console">
+</li>
+</body>
+</html>
2005-07-14 Geoffrey Garen <ggaren@apple.com>
- -landed layout test for http://bugzilla.opendarwin.org/show_bug.cgi?id=3412
- Object.prototype is missing toLocaleString
+ - landed fix for <http://bugzilla.opendarwin.org/show_bug.cgi?id=3677>
+ Safari fail to access a second time an element whose content was dynamically modified.
+
+ - patch by Anders Carlsson <andersca@mac.com>.
+
+ Reviewed by mjs + darin.
+
+ Test cases added:
+ * layout-tests/fast/dom/ids/duplicate-ids-expected.txt: Added.
+ * layout-tests/fast/dom/ids/duplicate-ids.html: Added.
+
+ * khtml/xml/dom_docimpl.cpp:
+ (DocumentImpl::getElementById):
+ If no element in the id dict can be found and we know that there's
+ at least one other element with the same id around, then traverse the document
+ and insert the new element in the id table.
+
+ (DocumentImpl::addElementById):
+ (DocumentImpl::removeElementById):
+ Increment and decrement the id count accordingly.
+
+ * khtml/xml/dom_docimpl.h:
+ Add QDict for id counts. Make element QDict mutable.
+
+2005-07-14 Geoffrey Garen <ggaren@apple.com>
+
+ -landed layout test for http://bugzilla.opendarwin.org/show_bug.cgi?id=3412
+ Object.prototype is missing toLocaleString
Reviewed by mjs.
ElementImpl *DocumentImpl::getElementById( const DOMString &elementId ) const
{
+ ElementImpl *element;
+ QString qId = elementId.string();
+
if (elementId.length() == 0) {
- return 0;
+ return 0;
}
- return m_elementsById.find(elementId.string());
+ element = m_elementsById.find(qId);
+
+ if (element)
+ return element;
+
+ if (int idCount = (int)m_idCount.find(qId)) {
+ for (NodeImpl *n = traverseNextNode(); n != 0; n = n->traverseNextNode()) {
+ if (!n->isElementNode())
+ continue;
+
+ element = static_cast<ElementImpl *>(n);
+
+ if (element->hasID() && element->getAttribute(ATTR_ID) == elementId) {
+ if (idCount == 1)
+ m_idCount.remove(qId);
+ else
+ m_idCount.insert(qId, (char *)idCount - 1);
+
+ m_elementsById.insert(qId, element);
+ return element;
+ }
+ }
+ }
+ return 0;
}
ElementImpl *DocumentImpl::elementFromPoint( const int _x, const int _y ) const
void DocumentImpl::addElementById(const DOMString &elementId, ElementImpl *element)
{
QString qId = elementId.string();
-
+
if (m_elementsById.find(qId) == NULL) {
- m_elementsById.insert(qId, element);
+ m_elementsById.insert(qId, element);
m_accessKeyDictValid = false;
+ } else {
+ int idCount = (int)m_idCount.find(qId);
+ m_idCount.insert(qId, (char *)(idCount + 1));
}
}
QString qId = elementId.string();
if (m_elementsById.find(qId) == element) {
- m_elementsById.remove(qId);
+ m_elementsById.remove(qId);
m_accessKeyDictValid = false;
+ } else {
+ int idCount = (int)m_idCount.find(qId);
+ assert(idCount > 0);
+ if (idCount == 1)
+ m_idCount.remove(qId);
+ else
+ m_idCount.insert(qId, (char *)(idCount - 1));
}
}
khtml::Decoder *m_decoder;
- QDict<ElementImpl> m_elementsById;
+ mutable QDict<ElementImpl> m_elementsById;
+ mutable QDict<char> m_idCount;
QDict<ElementImpl> m_elementsByAccessKey;
bool m_accessKeyDictValid;