diff --git a/toolkit/components/autocomplete/public/nsIAutoCompleteSearch.idl b/toolkit/components/autocomplete/public/nsIAutoCompleteSearch.idl index cbf34c7609ba..4b09c6527d2b 100644 --- a/toolkit/components/autocomplete/public/nsIAutoCompleteSearch.idl +++ b/toolkit/components/autocomplete/public/nsIAutoCompleteSearch.idl @@ -63,7 +63,7 @@ interface nsIAutoCompleteSearch : nsISupports void stopSearch(); }; -[scriptable, uuid(18C36504-9A4C-4ac3-8494-BD05E00AE27F)] +[scriptable, uuid(8bd1dbbc-dcce-4007-9afa-b551eb687b61)] interface nsIAutoCompleteObserver : nsISupports { /* @@ -73,4 +73,12 @@ interface nsIAutoCompleteObserver : nsISupports * @param result - The search result object */ void onSearchResult(in nsIAutoCompleteSearch search, in nsIAutoCompleteResult result); + + /* + * Called to update with new results + * + * @param search - The search object that processed this search + * @param result - The search result object + */ + void onUpdateSearchResult(in nsIAutoCompleteSearch search, in nsIAutoCompleteResult result); }; diff --git a/toolkit/components/autocomplete/src/nsAutoCompleteController.cpp b/toolkit/components/autocomplete/src/nsAutoCompleteController.cpp index 300174be0a55..c0b94d2407a0 100644 --- a/toolkit/components/autocomplete/src/nsAutoCompleteController.cpp +++ b/toolkit/components/autocomplete/src/nsAutoCompleteController.cpp @@ -691,6 +691,13 @@ nsAutoCompleteController::GetSearchString(nsAString &aSearchString) //////////////////////////////////////////////////////////////////////// //// nsIAutoCompleteObserver +NS_IMETHODIMP +nsAutoCompleteController::OnUpdateSearchResult(nsIAutoCompleteSearch *aSearch, nsIAutoCompleteResult* aResult) +{ + ClearResults(); + return OnSearchResult(aSearch, aResult); +} + NS_IMETHODIMP nsAutoCompleteController::OnSearchResult(nsIAutoCompleteSearch *aSearch, nsIAutoCompleteResult* aResult) { diff --git a/toolkit/components/satchel/src/nsFormFillController.cpp b/toolkit/components/satchel/src/nsFormFillController.cpp index f5882974c045..5cb5b035c408 100644 --- a/toolkit/components/satchel/src/nsFormFillController.cpp +++ b/toolkit/components/satchel/src/nsFormFillController.cpp @@ -72,6 +72,7 @@ #include "nsEmbedCID.h" #include "nsIDOMNSEditableElement.h" #include "nsIDOMNSEvent.h" +#include "mozilla/dom/Element.h" NS_INTERFACE_MAP_BEGIN(nsFormFillController) NS_INTERFACE_MAP_ENTRY(nsIFormFillController) @@ -83,6 +84,7 @@ NS_INTERFACE_MAP_BEGIN(nsFormFillController) NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener) NS_INTERFACE_MAP_ENTRY(nsIDOMCompositionListener) NS_INTERFACE_MAP_ENTRY(nsIDOMContextMenuListener) + NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFormFillController) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMFocusListener) NS_INTERFACE_MAP_END @@ -119,6 +121,79 @@ nsFormFillController::~nsFormFillController() } } +//////////////////////////////////////////////////////////////////////// +//// nsIMutationObserver +// + +void +nsFormFillController::AttributeChanged(nsIDocument* aDocument, + mozilla::dom::Element* aElement, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, PRInt32 aModType) +{ + RevalidateDataList(); +} + +void +nsFormFillController::ContentAppended(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + RevalidateDataList(); +} + +void +nsFormFillController::ContentInserted(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + RevalidateDataList(); +} + +void +nsFormFillController::ContentRemoved(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer, + nsIContent* aPreviousSibling) +{ + RevalidateDataList(); +} + +void +nsFormFillController::CharacterDataWillChange(nsIDocument* aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ +} + +void +nsFormFillController::CharacterDataChanged(nsIDocument* aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ +} + +void +nsFormFillController::AttributeWillChange(nsIDocument* aDocument, + mozilla::dom::Element* aElement, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, PRInt32 aModType) +{ +} + +void +nsFormFillController::ParentChainChanged(nsIContent* aContent) +{ +} + +void +nsFormFillController::NodeWillBeDestroyed(const nsINode* aNode) +{ +} + //////////////////////////////////////////////////////////////////////// //// nsIFormFillController @@ -526,6 +601,10 @@ nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAStrin NS_ENSURE_SUCCESS(rv, rv); } + mLastSearchResult = formHistoryResult; + mLastListener = aListener; + mLastSearchString = aSearchString; + nsCOMPtr inputListAutoComplete = do_GetService("@mozilla.org/satchel/inputlist-autocomplete;1", &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -534,6 +613,16 @@ nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAStrin aSearchString, mFocusedInput, getter_AddRefs(result)); + + if (mFocusedInput) { + nsCOMPtr list; + mFocusedInput->GetList(getter_AddRefs(list)); + + nsCOMPtr node = do_QueryInterface(list); + if(node) { + node->AddMutationObserverUnlessExists(this); + } + } } NS_ENSURE_SUCCESS(rv, rv); @@ -542,6 +631,21 @@ nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAStrin return NS_OK; } +void nsFormFillController::RevalidateDataList() +{ + nsresult rv; + nsCOMPtr inputListAutoComplete = + do_GetService("@mozilla.org/satchel/inputlist-autocomplete;1", &rv); + + nsCOMPtr result; + + rv = inputListAutoComplete->AutoCompleteSearch(mLastSearchResult, + mLastSearchString, + mFocusedInput, + getter_AddRefs(result)); + mLastListener->OnUpdateSearchResult(this, result); +} + NS_IMETHODIMP nsFormFillController::StopSearch() { @@ -1156,6 +1260,16 @@ nsFormFillController::StopControllingInput() { RemoveKeyListener(); + if(mFocusedInput) { + nsCOMPtr list; + mFocusedInput->GetList(getter_AddRefs(list)); + + nsCOMPtr node = do_QueryInterface(list); + if (node) { + node->RemoveMutationObserver(this); + } + } + // Reset the controller's input, but not if it has been switched // to another input already, which might happen if the user switches // focus by clicking another autocomplete textbox diff --git a/toolkit/components/satchel/src/nsFormFillController.h b/toolkit/components/satchel/src/nsFormFillController.h index e98281d26fea..48af7a30442d 100644 --- a/toolkit/components/satchel/src/nsFormFillController.h +++ b/toolkit/components/satchel/src/nsFormFillController.h @@ -58,6 +58,7 @@ #include "nsIDOMWindow.h" #include "nsIDOMHTMLInputElement.h" #include "nsILoginManager.h" +#include "nsIMutationObserver.h" class nsFormHistory; @@ -69,7 +70,8 @@ class nsFormFillController : public nsIFormFillController, public nsIDOMCompositionListener, public nsIDOMFormListener, public nsIDOMMouseListener, - public nsIDOMContextMenuListener + public nsIDOMContextMenuListener, + public nsIMutationObserver { public: NS_DECL_ISUPPORTS @@ -77,6 +79,7 @@ public: NS_DECL_NSIAUTOCOMPLETESEARCH NS_DECL_NSIAUTOCOMPLETEINPUT NS_DECL_NSIDOMEVENTLISTENER + NS_DECL_NSIMUTATIONOBSERVER // nsIDOMFocusListener NS_IMETHOD Focus(nsIDOMEvent* aEvent); @@ -122,6 +125,7 @@ protected: void StartControllingInput(nsIDOMHTMLInputElement *aInput); void StopControllingInput(); + void RevalidateDataList(); PRBool RowMatch(nsFormHistory *aHistory, PRUint32 aIndex, const nsAString &aInputName, const nsAString &aInputValue); inline nsIDocShell *GetDocShellForInput(nsIDOMHTMLInputElement *aInput); @@ -143,6 +147,11 @@ protected: nsCOMPtr mDocShells; nsCOMPtr mPopups; + //these are used to dynamically update the autocomplete + nsCOMPtr mLastSearchResult; + nsCOMPtr mLastListener; + nsString mLastSearchString; + nsDataHashtable mPwmgrInputs; PRUint32 mTimeout;