Changeset 280718 in webkit
- Timestamp:
- Aug 5, 2021, 8:10:40 PM (5 years ago)
- Location:
- trunk/Source
- Files:
-
- 12 edited
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/dom/Document.cpp (modified) (1 diff)
-
WebCore/dom/Element.h (modified) (1 diff)
-
WebCore/html/FormController.cpp (modified) (3 diffs)
-
WebCore/html/FormController.h (modified) (2 diffs)
-
WebCore/html/HTMLFormControlElementWithState.cpp (modified) (3 diffs)
-
WebCore/html/HTMLFormControlElementWithState.h (modified) (3 diffs)
-
WebCore/page/Frame.h (modified) (1 diff)
-
WebCore/page/ios/FrameIOS.mm (modified) (1 diff)
-
WebKitLegacy/mac/ChangeLog (modified) (1 diff)
-
WebKitLegacy/mac/WebView/WebFrame.mm (modified) (1 diff)
-
WebKitLegacy/mac/WebView/WebFramePrivate.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r280715 r280718 1 2021-08-05 Cameron McCormack <heycam@apple.com> 2 3 Stop tracking form elements with FormController 4 https://bugs.webkit.org/show_bug.cgi?id=228724 5 <rdar://problem/81435095> 6 7 Reviewed by Darin Adler. 8 9 FormController currently tracks the insertion order of 10 HTMLFormElementWithState objects in the document. But we don't need 11 to know this list of form controls until the time we need to save 12 form state for the document (e.g. on pagehide). So we instead 13 traverse the document to find those elements at the point we need 14 them, rather than maintain FormController::m_formElementsWithState. 15 16 This is a small speedup (1-2%) on a few of the Speedometer subtests 17 that insert and remove many input elements. 18 19 A future optimization could record on the Document whether there are 20 any input elements that have had their value changed, since it's 21 probably common for pages with form controls to never be changed. 22 23 * dom/Document.cpp: 24 (WebCore::Document::formElementsState const): Traverse the document to 25 find all the HTMLFormElementWithState objects. 26 * dom/Element.h: 27 (WebCore::Element::isFormControlElementWithState const): 28 * html/FormController.cpp: 29 (WebCore::FormController::createSavedFormStateMap): 30 (WebCore::FormController::formElementsState const): 31 * html/FormController.h: 32 * html/HTMLFormControlElementWithState.cpp: 33 (WebCore::HTMLFormControlElementWithState::insertedIntoAncestor): 34 Track the order that HTMLFormControlElementWithState objects are 35 inserted into the document. 36 (WebCore::HTMLFormControlElementWithState::removedFromAncestor): 37 * html/HTMLFormControlElementWithState.h: 38 (WebCore::HTMLFormControlElementWithState::insertionIndex const): 39 (isType): 40 * page/Frame.h: Remove unused formElementsCharacterCount. 41 * page/ios/FrameIOS.mm: 42 1 43 2021-08-05 Tim Horton <timothy_horton@apple.com> 2 44 -
trunk/Source/WebCore/dom/Document.cpp
r280700 r280718 1910 1910 if (!m_formController) 1911 1911 return Vector<String>(); 1912 return m_formController->formElementsState( );1912 return m_formController->formElementsState(*this); 1913 1913 } 1914 1914 -
trunk/Source/WebCore/dom/Element.h
r279054 r280718 469 469 470 470 virtual bool isFormControlElement() const { return false; } 471 virtual bool isFormControlElementWithState() const { return false; } 471 472 virtual bool isSpinButtonElement() const { return false; } 472 473 virtual bool isTextFormControlElement() const { return false; } -
trunk/Source/WebCore/html/FormController.cpp
r279439 r280718 343 343 FormController::~FormController() = default; 344 344 345 unsigned FormController::formElementsCharacterCount() const346 {347 unsigned count = 0;348 for (auto& element : m_formElementsWithState) {349 if (element->isTextField())350 count += element->saveFormControlState()[0].length();351 }352 return count;353 }354 355 345 static String formStateSignature() 356 346 { … … 362 352 } 363 353 364 std::unique_ptr<FormController::SavedFormStateMap> FormController::createSavedFormStateMap(const Form ElementListHashSet& controlList)354 std::unique_ptr<FormController::SavedFormStateMap> FormController::createSavedFormStateMap(const FormControlVector& controlList) 365 355 { 366 356 FormKeyGenerator keyGenerator; 367 357 auto stateMap = makeUnique<SavedFormStateMap>(); 368 for ( auto& control : controlList) {369 if (!control ->shouldSaveAndRestoreFormControlState())370 continue; 371 auto& formState = stateMap->add(keyGenerator.formKey( *control).impl(), nullptr).iterator->value;358 for (const HTMLFormControlElementWithState& control : controlList) { 359 if (!control.shouldSaveAndRestoreFormControlState()) 360 continue; 361 auto& formState = stateMap->add(keyGenerator.formKey(control).impl(), nullptr).iterator->value; 372 362 if (!formState) 373 363 formState = makeUnique<SavedFormState>(); 374 formState->appendControlState(control ->name(), control->type(), control->saveFormControlState());364 formState->appendControlState(control.name(), control.type(), control.saveFormControlState()); 375 365 } 376 366 return stateMap; 377 367 } 378 368 379 Vector<String> FormController::formElementsState() const 380 { 381 std::unique_ptr<SavedFormStateMap> stateMap = createSavedFormStateMap(m_formElementsWithState); 369 Vector<String> FormController::formElementsState(const Document& document) const 370 { 371 // FIXME: We should be saving the state of form controls in shadow trees, too. 372 FormControlVector controls; 373 for (auto& control : descendantsOfType<HTMLFormControlElementWithState>(document)) { 374 ASSERT(control.insertionIndex()); 375 controls.append(control); 376 } 377 378 std::sort(controls.begin(), controls.end(), [](auto a, auto b) { 379 return a.get().insertionIndex() < b.get().insertionIndex(); 380 }); 381 382 auto stateMap = createSavedFormStateMap(controls); 382 383 Vector<String> stateVector; 383 stateVector.reserveInitialCapacity( m_formElementsWithState.size() * 4);384 stateVector.reserveInitialCapacity(controls.size() * 4); 384 385 stateVector.append(formStateSignature()); 385 386 for (auto& state : *stateMap) { … … 485 486 } 486 487 487 void FormController::registerFormElementWithState(HTMLFormControlElementWithState& control)488 {489 ASSERT(!m_formElementsWithState.contains(&control));490 m_formElementsWithState.add(&control);491 }492 493 void FormController::unregisterFormElementWithState(HTMLFormControlElementWithState& control)494 {495 ASSERT(m_formElementsWithState.contains(&control));496 m_formElementsWithState.remove(&control);497 }498 499 488 } // namespace WebCore -
trunk/Source/WebCore/html/FormController.h
r250708 r280718 43 43 ~FormController(); 44 44 45 void registerFormElementWithState(HTMLFormControlElementWithState&); 46 void unregisterFormElementWithState(HTMLFormControlElementWithState&); 47 48 unsigned formElementsCharacterCount() const; 49 50 Vector<String> formElementsState() const; 45 Vector<String> formElementsState(const Document&) const; 51 46 void setStateForNewFormElements(const Vector<String>&); 52 47 … … 59 54 60 55 private: 61 typedef ListHashSet<RefPtr<HTMLFormControlElementWithState>> FormElementListHashSet;62 typedef HashMap<RefPtr<AtomStringImpl>, std::unique_ptr<SavedFormState>> SavedFormStateMap;56 using FormControlVector = Vector<std::reference_wrapper<const HTMLFormControlElementWithState>>; 57 using SavedFormStateMap = HashMap<RefPtr<AtomStringImpl>, std::unique_ptr<SavedFormState>>; 63 58 64 static std::unique_ptr<SavedFormStateMap> createSavedFormStateMap(const Form ElementListHashSet&);59 static std::unique_ptr<SavedFormStateMap> createSavedFormStateMap(const FormControlVector&); 65 60 FormControlState takeStateForFormElement(const HTMLFormControlElementWithState&); 66 61 static void formStatesFromStateVector(const Vector<String>&, SavedFormStateMap&); 67 62 68 FormElementListHashSet m_formElementsWithState;69 63 SavedFormStateMap m_savedFormStateMap; 70 64 std::unique_ptr<FormKeyGenerator> m_formKeyGenerator; -
trunk/Source/WebCore/html/HTMLFormControlElementWithState.cpp
r229694 r280718 44 44 Node::InsertedIntoAncestorResult HTMLFormControlElementWithState::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree) 45 45 { 46 if (insertionType.connectedToDocument && !containingShadowRoot()) 47 document().formController().registerFormElementWithState(*this); 46 m_insertionIndex = ++lastInsertionIndex; 48 47 return HTMLFormControlElement::insertedIntoAncestor(insertionType, parentOfInsertedTree); 49 48 } … … 51 50 void HTMLFormControlElementWithState::removedFromAncestor(RemovalType removalType, ContainerNode& oldParentOfRemovedTree) 52 51 { 53 if (removalType.disconnectedFromDocument && !containingShadowRoot() && !oldParentOfRemovedTree.containingShadowRoot()) 54 document().formController().unregisterFormElementWithState(*this); 52 m_insertionIndex = 0; 55 53 HTMLFormControlElement::removedFromAncestor(removalType, oldParentOfRemovedTree); 56 54 } … … 85 83 } 86 84 85 uint64_t HTMLFormControlElementWithState::lastInsertionIndex { 0 }; 86 87 87 } // namespace Webcore -
trunk/Source/WebCore/html/HTMLFormControlElementWithState.h
r229694 r280718 39 39 virtual void restoreFormControlState(const FormControlState&) { } // Called only if state is not empty. 40 40 41 uint64_t insertionIndex() const { return m_insertionIndex; } 42 41 43 protected: 42 44 HTMLFormControlElementWithState(const QualifiedName& tagName, Document&, HTMLFormElement*); … … 51 53 private: 52 54 bool isFormControlElementWithState() const final; 55 56 uint64_t m_insertionIndex { 0 }; 57 static uint64_t lastInsertionIndex; 53 58 }; 54 59 … … 56 61 57 62 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLFormControlElementWithState) 63 static bool isType(const WebCore::Element& element) { return element.isFormControlElementWithState(); } 64 static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); } 58 65 static bool isType(const WebCore::FormAssociatedElement& element) { return element.isFormControlElementWithState(); } 59 66 SPECIALIZE_TYPE_TRAITS_END() -
trunk/Source/WebCore/page/Frame.h
r280504 r280718 283 283 WEBCORE_EXPORT NSRect caretRect(); 284 284 WEBCORE_EXPORT NSRect rectForScrollToVisible(); 285 WEBCORE_EXPORT unsigned formElementsCharacterCount() const;286 285 287 286 // This function is used by Legacy WebKit. -
trunk/Source/WebCore/page/ios/FrameIOS.mm
r279918 r280718 628 628 } 629 629 630 unsigned Frame::formElementsCharacterCount() const631 {632 Document* document = this->document();633 if (!document)634 return 0;635 return document->formController().formElementsCharacterCount();636 }637 638 630 void Frame::setTimersPaused(bool paused) 639 631 { -
trunk/Source/WebKitLegacy/mac/ChangeLog
r280467 r280718 1 2021-08-05 Cameron McCormack <heycam@apple.com> 2 3 Stop tracking form elements with FormController 4 https://bugs.webkit.org/show_bug.cgi?id=228724 5 <rdar://problem/81435095> 6 7 Reviewed by Darin Adler. 8 9 formElementsCharacterCount is unused and can be removed. 10 11 * WebView/WebFrame.mm: 12 * WebView/WebFramePrivate.h: 13 1 14 2021-07-29 Myles C. Maxfield <mmaxfield@apple.com> 2 15 -
trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm
r278542 r280718 1164 1164 #if PLATFORM(IOS_FAMILY) 1165 1165 1166 - (unsigned)formElementsCharacterCount1167 {1168 return core(self)->formElementsCharacterCount();1169 }1170 1171 1166 - (void)setTimeoutsPaused:(BOOL)flag 1172 1167 { -
trunk/Source/WebKitLegacy/mac/WebView/WebFramePrivate.h
r260366 r280718 96 96 - (void)_setLoadsSynchronously:(BOOL)flag; 97 97 - (BOOL)_loadsSynchronously; 98 - (unsigned)formElementsCharacterCount;99 98 - (void)setTimeoutsPaused:(BOOL)flag; 100 99
Note:
See TracChangeset
for help on using the changeset viewer.