251 return frame->editor()->shouldBeginEditing(rangeOfContents(root).get()); |
251 return frame->editor()->shouldBeginEditing(rangeOfContents(root).get()); |
252 } |
252 } |
253 |
253 |
254 DeprecatedPtrList<Document>* Document::changedDocuments = 0; |
254 DeprecatedPtrList<Document>* Document::changedDocuments = 0; |
255 |
255 |
|
256 struct cleanupChangedDocuments { |
|
257 ~cleanupChangedDocuments() { |
|
258 if(Document::changedDocuments) |
|
259 { |
|
260 delete Document::changedDocuments; |
|
261 Document::changedDocuments = NULL; |
|
262 } |
|
263 } |
|
264 }; |
|
265 static cleanupChangedDocuments deleteChangedDocuments; |
|
266 |
256 // FrameView might be 0 |
267 // FrameView might be 0 |
257 Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML) |
268 Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML) |
258 : ContainerNode(0) |
269 : ContainerNode(0) |
259 , m_implementation(impl) |
270 , m_implementation(impl) |
260 , m_domtree_version(0) |
271 , m_domtree_version(0) |
819 return static_cast<Element*>(n); |
830 return static_cast<Element*>(n); |
820 } |
831 } |
821 |
832 |
822 void Document::addElementById(const AtomicString& elementId, Element* element) |
833 void Document::addElementById(const AtomicString& elementId, Element* element) |
823 { |
834 { |
824 if (!m_elementsById.contains(elementId.impl())) |
835 typedef HashMap<AtomicStringImpl*, Element*>::iterator iterator; |
825 m_elementsById.set(elementId.impl(), element); |
836 if (!m_duplicateIds.contains(elementId.impl())) { |
826 else |
837 // Fast path. The ID is not already in m_duplicateIds, so we assume that it's |
827 m_duplicateIds.add(elementId.impl()); |
838 // also not already in m_elementsById and do an add. If that add succeeds, we're done. |
|
839 pair<iterator, bool> addResult = m_elementsById.add(elementId.impl(), element); |
|
840 if (addResult.second) |
|
841 return; |
|
842 // The add failed, so this ID was already cached in m_elementsById. |
|
843 // There are multiple elements with this ID. Remove the m_elementsById |
|
844 // cache for this ID so getElementById searches for it next time it is called. |
|
845 m_elementsById.remove(addResult.first); |
|
846 m_duplicateIds.add(elementId.impl()); |
|
847 } else { |
|
848 // There are multiple elements with this ID. If it exists, remove the m_elementsById |
|
849 // cache for this ID so getElementById searches for it next time it is called. |
|
850 iterator cachedItem = m_elementsById.find(elementId.impl()); |
|
851 if (cachedItem != m_elementsById.end()) { |
|
852 m_elementsById.remove(cachedItem); |
|
853 m_duplicateIds.add(elementId.impl()); |
|
854 } |
|
855 } |
|
856 m_duplicateIds.add(elementId.impl()); |
828 } |
857 } |
829 |
858 |
830 void Document::removeElementById(const AtomicString& elementId, Element* element) |
859 void Document::removeElementById(const AtomicString& elementId, Element* element) |
831 { |
860 { |
832 if (m_elementsById.get(elementId.impl()) == element) |
861 if (m_elementsById.get(elementId.impl()) == element) |