diff --git a/accessible/src/base/nsAccessNode.cpp b/accessible/src/base/nsAccessNode.cpp index d33a4b0e8e39..5afe85fe49ff 100644 --- a/accessible/src/base/nsAccessNode.cpp +++ b/accessible/src/base/nsAccessNode.cpp @@ -66,7 +66,7 @@ #include "nsIStringBundle.h" #include "nsITimer.h" #include "nsRootAccessible.h" -#include "nsIFocusController.h" +#include "nsFocusManager.h" #include "nsIObserverService.h" #ifdef MOZ_ACCESSIBILITY_ATK @@ -776,33 +776,24 @@ already_AddRefed nsAccessNode::GetCurrentFocus() nsCOMPtr doc = shell->GetDocument(); NS_ENSURE_TRUE(doc, nsnull); - nsCOMPtr privateDOMWindow(do_QueryInterface(doc->GetWindow())); - if (!privateDOMWindow) { - return nsnull; - } - nsIFocusController *focusController = privateDOMWindow->GetRootFocusController(); - if (!focusController) { - return nsnull; - } + nsIDOMWindow* win = doc->GetWindow(); + + nsCOMPtr focusedWindow; nsCOMPtr focusedElement; - focusController->GetFocusedElement(getter_AddRefs(focusedElement)); + nsCOMPtr fm = do_GetService(FOCUSMANAGER_CONTRACTID); + if (fm) + fm->GetFocusedElementForWindow(win, PR_TRUE, getter_AddRefs(focusedWindow), + getter_AddRefs(focusedElement)); + nsIDOMNode *focusedNode = nsnull; - if (!focusedElement) { - // Document itself has focus - nsCOMPtr focusedWinInternal; - focusController->GetFocusedWindow(getter_AddRefs(focusedWinInternal)); - if (!focusedWinInternal) { - return nsnull; - } - nsCOMPtr focusedDOMDocument; - focusedWinInternal->GetDocument(getter_AddRefs(focusedDOMDocument)); - if (!focusedDOMDocument) { - return nsnull; - } - focusedDOMDocument->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&focusedNode); + if (focusedElement) { + CallQueryInterface(focusedElement, &focusedNode); } - else { - focusedElement->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&focusedNode); + else if (focusedWindow) { + nsCOMPtr doc; + focusedWindow->GetDocument(getter_AddRefs(doc)); + if (doc) + CallQueryInterface(doc, &focusedNode); } return focusedNode; diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index 3e31eb7def00..cd5fbdec201b 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -74,6 +74,7 @@ #include "nsIViewManager.h" #include "nsIDocShellTreeItem.h" #include "nsIScrollableFrame.h" +#include "nsFocusManager.h" #include "nsXPIDLString.h" #include "nsUnicharUtils.h" @@ -1469,14 +1470,11 @@ nsAccessible::TakeFocus() } } - nsCOMPtr htmlElement(do_QueryInterface(content)); - if (htmlElement) { - // HTML Elements also set the caret position - // in order to affect tabbing order - return htmlElement->Focus(); - } + nsCOMPtr element(do_QueryInterface(content)); + nsCOMPtr fm = do_GetService(FOCUSMANAGER_CONTRACTID); + if (fm) + fm->SetFocus(element, 0); - content->SetFocus(GetPresContext()); return NS_OK; } diff --git a/accessible/src/base/nsDocAccessible.cpp b/accessible/src/base/nsDocAccessible.cpp index 96d2290e10ea..219c8a134dcc 100644 --- a/accessible/src/base/nsDocAccessible.cpp +++ b/accessible/src/base/nsDocAccessible.cpp @@ -68,7 +68,7 @@ #include "nsUnicharUtils.h" #include "nsIURI.h" #include "nsIWebNavigation.h" -#include "nsIFocusController.h" +#include "nsFocusManager.h" #ifdef MOZ_XUL #include "nsIXULDocument.h" #endif @@ -350,6 +350,7 @@ nsDocAccessible::GetAttributes(nsIPersistentProperties **aAttributes) NS_IMETHODIMP nsDocAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) { + // XXXndeakin P3 accessibility shouldn't be caching the focus if (!gLastFocusedNode) { *aFocusedChild = nsnull; return NS_OK; @@ -371,25 +372,18 @@ NS_IMETHODIMP nsDocAccessible::TakeFocus() return NS_ERROR_FAILURE; // Not focusable } - nsCOMPtr treeItem = - nsCoreUtils::GetDocShellTreeItemFor(mDOMNode); - nsCOMPtr docShell = do_QueryInterface(treeItem); - NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); - - nsCOMPtr shell(GetPresShell()); - if (!shell) { - NS_WARNING("Was not shutdown properly via InvalidateCacheSubtree()"); - return NS_ERROR_FAILURE; + nsCOMPtr fm = do_GetService(FOCUSMANAGER_CONTRACTID); + if (fm) { + nsCOMPtr domDocument; + mDOMNode->GetOwnerDocument(getter_AddRefs(domDocument)); + nsCOMPtr document(do_QueryInterface(domDocument)); + if (document) { + // focus the document + nsCOMPtr newFocus; + fm->MoveFocus(document->GetWindow(), nsnull, nsIFocusManager::MOVEFOCUS_ROOT, 0, + getter_AddRefs(newFocus)); + } } - nsIEventStateManager *esm = shell->GetPresContext()->EventStateManager(); - NS_ENSURE_TRUE(esm, NS_ERROR_FAILURE); - - // Focus the document - nsresult rv = docShell->SetHasFocus(PR_TRUE); - NS_ENSURE_SUCCESS(rv, rv); - - // Clear out any existing focus state - return esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS); } // ------- nsIAccessibleDocument Methods (5) --------------- diff --git a/accessible/src/base/nsRootAccessible.cpp b/accessible/src/base/nsRootAccessible.cpp index da0658122330..ed71434f86ce 100644 --- a/accessible/src/base/nsRootAccessible.cpp +++ b/accessible/src/base/nsRootAccessible.cpp @@ -60,7 +60,6 @@ #include "nsIDOMXULPopupElement.h" #include "nsIDocument.h" #include "nsIEventListenerManager.h" -#include "nsIFocusController.h" #include "nsIFrame.h" #include "nsIMenuFrame.h" #include "nsIHTMLDocument.h" @@ -75,6 +74,7 @@ #include "nsRootAccessible.h" #include "nsIDOMNSEventTarget.h" #include "nsIDOMDocumentEvent.h" +#include "nsFocusManager.h" #ifdef MOZ_XUL #include "nsXULTreeAccessible.h" @@ -234,16 +234,18 @@ nsRootAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState) nsCOMPtr domWin; GetWindow(getter_AddRefs(domWin)); - nsCOMPtr privateDOMWindow(do_QueryInterface(domWin)); - if (privateDOMWindow) { - nsIFocusController *focusController = - privateDOMWindow->GetRootFocusController(); - if (focusController) { - PRBool isActive = PR_FALSE; - focusController->GetActive(&isActive); - if (isActive) { + nsCOMPtr dsti = do_GetInterface(domWin); + if (dsti) { + nsCOMPtr root; + dsti->GetRootTreeItem(getter_AddRefs(root)); + nsCOMPtr rootWindow = do_GetInterface(root); + + nsCOMPtr fm = do_GetService(FOCUSMANAGER_CONTRACTID); + if (fm && rootWindow) { + nsCOMPtr activeWindow; + fm->GetActiveWindow(getter_AddRefs(activeWindow)); + if (activeWindow == rootWindow) *aExtraState |= nsIAccessibleStates::EXT_STATE_ACTIVE; - } } } #ifdef MOZ_XUL diff --git a/accessible/tests/mochitest/grid.js b/accessible/tests/mochitest/grid.js index 5c8987cbc46b..7c4cf60b2edd 100644 --- a/accessible/tests/mochitest/grid.js +++ b/accessible/tests/mochitest/grid.js @@ -78,7 +78,7 @@ function grid(aTableIdentifier) this.handleKeyEvent = function handleKeyEvent(aEvent) { - if (aEvent.target.localName != "TD") + if (aEvent.target.localName != "td") return; var cell = aEvent.target; @@ -131,7 +131,7 @@ function grid(aTableIdentifier) this.handleClickEvent = function handleClickEvent(aEvent) { - if (aEvent.target.localName != "TD") + if (aEvent.target.localName != "td") return; var curCell = this.getCurrentCell(); diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css old mode 100644 new mode 100755 index af4adeaaac71..797196f02017 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -51,9 +51,16 @@ toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] { visibility: collapse; } -#identity-box > hbox { - max-width: 22em; - min-width: 1px; +#identity-icon-labels { + max-width: 18em; +} + +#identity-icon-country-label { + direction: ltr; +} + +#identity-box.verifiedIdentity > hbox > #identity-icon-labels > #identity-icon-label { + -moz-margin-end: 0.25em !important; } /* ::::: Unified Back-/Forward Button ::::: */ diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 0f0de3277b12..eabce963d4d5 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1237,7 +1237,7 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) { focusElement(content); if (gURLBar) - gURLBar.setAttribute("emptytext", gURLBarEmptyText.value); + gURLBar.emptyText = gURLBarEmptyText.value; gNavToolbox.customizeDone = BrowserToolboxCustomizeDone; gNavToolbox.customizeChange = BrowserToolboxCustomizeChange; @@ -6569,6 +6569,10 @@ var gIdentityHandler = { delete this._identityIconLabel; return this._identityIconLabel = document.getElementById("identity-icon-label"); }, + get _identityIconCountryLabel () { + delete this._identityIconCountryLabel; + return this._identityIconCountryLabel = document.getElementById("identity-icon-country-label"); + }, /** * Rebuild cache of the elements that may or may not exist depending @@ -6577,8 +6581,10 @@ var gIdentityHandler = { _cacheElements : function() { delete this._identityBox; delete this._identityIconLabel; + delete this._identityIconCountryLabel; this._identityBox = document.getElementById("identity-box"); this._identityIconLabel = document.getElementById("identity-icon-label"); + this._identityIconCountryLabel = document.getElementById("identity-icon-country-label"); }, /** @@ -6700,6 +6706,8 @@ var gIdentityHandler = { // let's just use that. Check the pref to determine how much of the verified // hostname to show var icon_label = ""; + var icon_country_label = ""; + var icon_labels_dir = "ltr"; switch (gPrefService.getIntPref("browser.identity.ssl_domain_display")) { case 2 : // Show full domain icon_label = this._lastLocation.hostname; @@ -6738,20 +6746,34 @@ var gIdentityHandler = { iData = this.getIdentityData(); tooltip = this._stringBundle.getFormattedString("identity.identified.verifier", [iData.caOrg]); + icon_label = iData.subjectOrg; if (iData.country) - icon_label = this._stringBundle.getFormattedString("identity.identified.title_with_country", - [iData.subjectOrg, iData.country]); - else - icon_label = iData.subjectOrg; + icon_country_label = "(" + iData.country + ")"; + // If the organization name starts with an RTL character, then + // swap the positions of the organization and country code labels. + // The Unicode ranges reflect the definition of the UCS2_CHAR_IS_BIDI + // macro in intl/unicharutil/util/nsBidiUtils.h. When bug 218823 gets + // fixed, this test should be replaced by one adhering to the + // Unicode Bidirectional Algorithm proper (at the paragraph level). + icon_labels_dir = /^[\u0590-\u08ff\ufb1d-\ufdff\ufe70-\ufefc]/.test(icon_label) ? + "rtl" : "ltr"; } else { tooltip = this._stringBundle.getString("identity.unknown.tooltip"); icon_label = ""; + icon_country_label = ""; + icon_labels_dir = "ltr"; } // Push the appropriate strings out to the UI this._identityBox.tooltipText = tooltip; this._identityIconLabel.value = icon_label; + this._identityIconCountryLabel.value = icon_country_label; + // Set cropping and direction + this._identityIconLabel.crop = icon_country_label ? "end" : "center"; + this._identityIconLabel.parentNode.style.direction = icon_labels_dir; + // Hide completely if the organization label is empty + this._identityIconLabel.parentNode.hidden = icon_label ? false : true; }, /** diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul old mode 100644 new mode 100755 index 32f6f38ae7be..a2f17f83107c --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -370,7 +370,7 @@ onsearchbegin="LocationBarHelpers._searchBegin();" onsearchcomplete="LocationBarHelpers._searchComplete();" onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'" - onblur="document.getElementById('identity-box').style.MozUserFocus = 'ignore';"> + onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);"> + + + + diff --git a/browser/components/search/content/search.xml b/browser/components/search/content/search.xml index 6b858d29db4a..9bf0745168c3 100644 --- a/browser/components/search/content/search.xml +++ b/browser/components/search/content/search.xml @@ -78,21 +78,23 @@ showcommentcolumn="true" tabscrolling="true" xbl:inherits="disabled,disableautocomplete,searchengine,src,newlines"> - - - - - - - - + + + + + + + + + + #back-forward-dropmarke /* ::::: nav-bar-inner ::::: */ #urlbar { - -moz-appearance: none; - direction: ltr !important; - border: none; - background: url("chrome://browser/skin/urlbar/endcap.png") transparent right center no-repeat; - margin: 0 3px 1px; - -moz-padding-end: 11px; - font: icon !important; + direction: ltr; +} + +.searchbar-textbox, +#urlbar { + font: icon; width: 7em; min-width: 7em; - height: 28px; + -moz-appearance: none; + -moz-background-clip: padding; + -moz-border-radius: 100%; + border: 1px solid; + -moz-border-top-colors: #666; + -moz-border-right-colors: #777; + -moz-border-bottom-colors: #888; + -moz-border-left-colors: #777; + -moz-box-shadow: 0 1px 1px rgba(0,0,0,.3) inset, + 0 1px 0 rgba(255,255,255,.3); + margin-top: 0; + margin-bottom: 1px; + -moz-padding-end: 6px; } +.searchbar-textbox[focused="true"], #urlbar[focused="true"] { - background: url("chrome://browser/skin/urlbar/endcap-focused.png") transparent right center no-repeat; + -moz-border-top-colors: rgba(0,0,0,.3); + -moz-border-right-colors: rgba(0,0,0,.2); + -moz-border-bottom-colors: rgba(0,0,0,.15); + -moz-border-left-colors: rgba(0,0,0,.2); + -moz-box-shadow: 0 1px 1px rgba(0,0,0,.3) inset, + 0 0 1px -moz-mac-focusring inset, + 0 0 4px 1px -moz-mac-focusring, + 0 0 2px 1px -moz-mac-focusring; } -#urlbar[focused="true"]:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/endcap-focused-graphite.png"); +.searchbar-engine-button, +#identity-box { + background: #fff url(navbar-textbox-button.png) bottom repeat-x; + -moz-background-clip: padding; + color: black; + -moz-padding-start: 6px; + -moz-padding-end: 16px; + -moz-border-radius: 100%; + border-top: 1px solid rgba(0,0,0,.35); + -moz-border-start: 1px solid rgba(0,0,0,.25); + border-bottom: 1px solid rgba(0,0,0,.2); + margin-top: -1px; + margin-bottom: -1px; + -moz-margin-start: -1px; + -moz-margin-end: 0; } -#urlbar .textbox-input-box, -#urlbar-icons { - margin: 0; - background: url("chrome://browser/skin/urlbar/textfield-mid.png") transparent left center repeat-x; +#identity-box:focus:not(:active):not([open="true"]) #page-proxy-stack { + -moz-border-radius: 4px; + -moz-box-shadow: 0 0 3px 1px -moz-mac-focusring inset, + 0 0 3px 2px -moz-mac-focusring; } -#urlbar[focused="true"] .textbox-input-box, -#urlbar[focused="true"] #urlbar-icons { - background-image: url("chrome://browser/skin/urlbar/textfield-mid-focused.png"); +.searchbar-textbox[focused="true"] .searchbar-engine-button, +#urlbar[focused="true"] > #identity-box { + -moz-box-shadow: 0 0 1px -moz-mac-focusring inset; } -#urlbar[focused="true"] .textbox-input-box:-moz-system-metric(mac-graphite-theme), -#urlbar[focused="true"] #urlbar-icons:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/textfield-mid-focused-graphite.png"); -} - -#urlbar .textbox-input-box { +.searchbar-engine-button[open="true"], +.searchbar-engine-button:hover:active, +#identity-box[open="true"], +#identity-box:hover:active { + border-style: none; padding-top: 1px; + padding-bottom: 1px; + -moz-padding-start: 7px; + -moz-box-shadow: 0 0 50px rgba(0,0,0,.3) inset, + 0 3px 3px rgba(0,0,0,.6) inset, + 2px 0 2px rgba(0,0,0,.3) inset, + 0 -2px 2px rgba(0,0,0,.1) inset !important; } -.autocomplete-textbox { - background-image: inherit !important; +#identity-box.verifiedDomain { + background-image: url(navbar-textbox-button-verifiedDomain.png); +} + +#identity-box.verifiedIdentity { + background-image: url(navbar-textbox-button-verifiedIdentity.png); +} + +#identity-icon-labels { + margin: 0 4px; +} + +.searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box, +#urlbar > .autocomplete-textbox-container > .textbox-input-box { + -moz-margin-end: 0; + -moz-margin-start: -16px; + background-color: -moz-field; + -moz-padding-start: 10px; +} + +.searchbar-textbox[chromedir="ltr"] > .autocomplete-textbox-container > .textbox-input-box, +#urlbar > .autocomplete-textbox-container > .textbox-input-box { + -moz-border-radius-topleft: 100%; + -moz-border-radius-bottomleft: 100%; + -moz-box-shadow: 1px 1px 1px rgba(0,0,0,.3) inset, + 1px 0 0 rgba(0,0,0,.2) inset; +} + +.searchbar-textbox[chromedir="rtl"] > .autocomplete-textbox-container > .textbox-input-box { + -moz-border-radius-topright: 100%; + -moz-border-radius-bottomright: 100%; + -moz-box-shadow: -1px 1px 1px rgba(0,0,0,.3) inset, + -1px 0 0 rgba(0,0,0,.2) inset; +} + +.searchbar-textbox[focused="true"][chromedir="ltr"] > .autocomplete-textbox-container > .textbox-input-box, +#urlbar[focused="true"] > .autocomplete-textbox-container > .textbox-input-box { + -moz-box-shadow: 1px 1px 1px rgba(0,0,0,.3) inset, + 1px 0 0 rgba(0,0,0,.2) inset, + 2px 0 0 -moz-field inset, + 1px 0 1px -moz-mac-focusring inset; +} + +.searchbar-textbox[focused="true"][chromedir="rtl"] > .autocomplete-textbox-container > .textbox-input-box { + -moz-box-shadow: -1px 1px 1px rgba(0,0,0,.3) inset, + -1px 0 0 rgba(0,0,0,.2) inset, + -2px 0 0 -moz-field inset, + -1px 0 1px -moz-mac-focusring inset; } #urlbar-icons { @@ -828,13 +911,10 @@ toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarke } #urlbar-search-splitter { - /* This is a bit of a mess, because the location bar and the search bar are bigger - than they look. For example, -moz-margin-start: -6px should really be -4px. - Bug 482086 and bug 482105 will solve this. */ min-width: 8px; width: 8px; background-image: none; - -moz-margin-start: -6px; + -moz-margin-start: -4px; } #urlbar-search-splitter + #urlbar-container > #urlbar, @@ -842,34 +922,6 @@ toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarke -moz-margin-start: 0; } -#wrapper-urlbar-container #urlbar, -#urlbar[readonly="true"] { - -moz-padding-end: 12px; -} - -#wrapper-urlbar-container[place="palette"] { - max-width: 20em; -} - -#wrapper-urlbar-container > #urlbar-container > #urlbar > #identity-box > hbox > #identity-icon-label, -#wrapper-urlbar-container #urlbar > .autocomplete-history-dropmarker { - display: none; -} - -#wrapper-urlbar-container > #urlbar-container > #urlbar > #identity-box.verifiedIdentity > hbox > #identity-icon-label, -#wrapper-urlbar-container > #urlbar-container > #urlbar > #identity-box.verifiedDomain > hbox > #identity-icon-label { - display: -moz-box; -} - -/* Keep the URL bar LTR */ - -#PopupAutoCompleteRichResult { - direction: ltr !important; - margin-top: -2px; -} - -/* ----- PAGE PROXY ICON ----- */ - #page-proxy-favicon, #urlbar-throbber { width: 16px; @@ -879,11 +931,14 @@ toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarke } #page-proxy-stack { - -moz-margin-start: 10px; width: 24px; height: 20px; padding: 2px 4px; - opacity: 1.0; +} + +#identity-box.verifiedIdentity > hbox > #page-proxy-stack, +#identity-box.verifiedDomain > hbox > #page-proxy-stack { + background: url(urlbar-favicon-glow.png) center center no-repeat; } #page-proxy-favicon:not([src]) { @@ -898,6 +953,19 @@ toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarke list-style-image: url("chrome://browser/skin/places/searching_16.png"); } +#wrapper-urlbar-container[place="palette"] { + max-width: 20em; +} + +#wrapper-urlbar-container #identity-icon-labels, +#wrapper-urlbar-container .autocomplete-history-dropmarker { + display: none; +} + +#PopupAutoCompleteRichResult { + direction: ltr !important; + margin-top: 2px; +} statusbarpanel#statusbar-display { -moz-padding-start: 0; @@ -1763,19 +1831,13 @@ tabbrowser > tabbox > tabpanels { } .tabs-closebutton { - padding-right: 4px; - list-style-image: url("chrome://global/skin/icons/closetab.png") !important; - list-style-image: none; + -moz-padding-end: 4px; + list-style-image: url("chrome://global/skin/icons/closetab.png"); border: none; - -moz-box-align: stretch; -} - -.tabs-closebutton:hover > .toolbarbutton-icon { - background-image: none !important; } .tabs-closebutton:hover:active { - list-style-image: url("chrome://global/skin/icons/closetab-active.png") !important; + list-style-image: url("chrome://global/skin/icons/closetab-active.png"); } tabpanels.plain { @@ -1833,179 +1895,6 @@ tabpanels.plain { -moz-border-left-colors: ThreeDLightShadow ThreeDHighlight !important; } -/* ::::: Identity Indicator Styling ::::: */ -/* Location bar visuals*/ - -#identity-box { - background: url("chrome://browser/skin/urlbar/startcap.png") left center no-repeat; - min-width: 45px; -} - -#urlbar[focused="true"] > #identity-box { - background-image: url("chrome://browser/skin/urlbar/startcap-focused.png"); -} - -#urlbar[focused="true"] > #identity-box:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-focused-graphite.png"); -} - -#identity-box:focus > hbox > #page-proxy-deck { - outline: 2px solid #4F8EC9; - -moz-outline-radius: 2px; -} - -#identity-box:hover:active, -#identity-box[open="true"] { - background-image: url("chrome://browser/skin/urlbar/startcap-active.png"); -} - -#identity-icon-label { - margin: 0; - color: black; - padding: 4px 6px 3px; - -moz-padding-end: 14px; -} - -#identity-box.unknownIdentity > hbox > #identity-icon-label { - display: none; -} - - -/* Verified domain */ -/* - Normal state */ -#identity-box.verifiedDomain { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-start.png"); - -moz-padding-start: 13px; -} - -#identity-box.verifiedDomain > hbox { - padding: 0; - background: url("chrome://browser/skin/urlbar/startcap-secure-mid.png") repeat-x center center; - -moz-box-pack: center; -} - -#identity-box.verifiedDomain > hbox > #identity-icon-label { - background: url("chrome://browser/skin/urlbar/startcap-secure-end.png") no-repeat center right; -} - -/* - Active state */ -#identity-box.verifiedDomain[open="true"], -#identity-box.verifiedDomain:hover:active { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-start-active.png"); -} - -#identity-box.verifiedDomain[open="true"] > hbox, -#identity-box.verifiedDomain:hover:active > hbox { - padding: 0; - background: url("chrome://browser/skin/urlbar/startcap-secure-mid-active.png") repeat-x center center; - -moz-box-pack: center; -} - -#identity-box.verifiedDomain[open="true"] > hbox > #identity-icon-label, -#identity-box.verifiedDomain:hover:active > hbox > #identity-icon-label { - background: url("chrome://browser/skin/urlbar/startcap-secure-end-active.png") no-repeat center right; -} - -/* - Focus state */ -#urlbar[focused="true"] > #identity-box.verifiedDomain { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-start-focused.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedDomain > hbox { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-mid-focused.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedDomain > hbox > #identity-icon-label { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-end-focused.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedDomain:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-start-focused-graphite.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedDomain > hbox:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-mid-focused-graphite.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedDomain > hbox > #identity-icon-label:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-secure-end-focused-graphite.png"); -} - -#identity-box.verifiedDomain > hbox > #identity-icon-label[value=""] { - -moz-padding-start: 3px !important; - -moz-padding-end: 8px !important; -} - - -/* Verified Identity */ -/* - Normal state */ -#identity-box.verifiedIdentity { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-start.png"); - -moz-padding-start: 13px; -} - -#identity-box.verifiedIdentity > hbox { - padding: 0; - background: url("chrome://browser/skin/urlbar/startcap-verified-mid.png") repeat-x center center; - -moz-box-pack: center; -} - -#identity-box.verifiedIdentity > hbox > #identity-icon-label { - background: url("chrome://browser/skin/urlbar/startcap-verified-end.png") no-repeat center right; -} - -/* - Active state */ -#identity-box.verifiedIdentity[open="true"], -#identity-box.verifiedIdentity:hover:active { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-start-active.png"); -} - -#identity-box.verifiedIdentity[open="true"] > hbox, -#identity-box.verifiedIdentity:hover:active > hbox { - background: url("chrome://browser/skin/urlbar/startcap-verified-mid-active.png") repeat-x center center; -} - -#identity-box.verifiedIdentity[open="true"] > hbox > #identity-icon-label, -#identity-box.verifiedIdentity:hover:active > hbox > #identity-icon-label { - background: url("chrome://browser/skin/urlbar/startcap-verified-end-active.png") no-repeat center right; -} - -/* - Focus state */ -#urlbar[focused="true"] > #identity-box.verifiedIdentity { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-start-focused.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedIdentity > hbox { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-mid-focused.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedIdentity > hbox > #identity-icon-label { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-end-focused.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedIdentity:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-start-focused-graphite.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedIdentity > hbox:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-mid-focused-graphite.png"); -} - -#urlbar[focused="true"] > #identity-box.verifiedIdentity > hbox > #identity-icon-label:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-verified-end-focused-graphite.png"); -} - -/* Favicon Glow */ -#identity-box.verifiedIdentity > hbox > #page-proxy-stack, -#identity-box.verifiedDomain > hbox > #page-proxy-stack { - -moz-margin-start: -3px; - width: 24px; - height: 20px; - padding: 2px 4px; - background: url("chrome://browser/skin/urlbar/urlbar-favicon-glow.png") center center no-repeat; -} - - /* Popup Icons */ #identity-popup-icon { height: 64px; @@ -2075,7 +1964,7 @@ tabpanels.plain { -moz-window-shadow: none; background-color: transparent; margin-top: -4px; - margin-left: -13px; + margin-left: -15px; min-width: 280px; -moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 18 22 50 / 26px 18px 22px 50px repeat; } diff --git a/browser/themes/pinstripe/browser/jar.mn b/browser/themes/pinstripe/browser/jar.mn index 311eacb7e480..8ffd59b568f1 100644 --- a/browser/themes/pinstripe/browser/jar.mn +++ b/browser/themes/pinstripe/browser/jar.mn @@ -32,6 +32,9 @@ classic.jar: skin/classic/browser/KUI-background.png skin/classic/browser/menu-back.png skin/classic/browser/menu-forward.png + skin/classic/browser/navbar-textbox-button.png + skin/classic/browser/navbar-textbox-button-verifiedDomain.png + skin/classic/browser/navbar-textbox-button-verifiedIdentity.png skin/classic/browser/page-livemarks.png skin/classic/browser/livemark-item.png skin/classic/browser/pageInfo.css @@ -50,6 +53,7 @@ classic.jar: skin/classic/browser/Secure-background.gif skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar-rtl.png + skin/classic/browser/urlbar-favicon-glow.png skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css) skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png) skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png) @@ -121,53 +125,5 @@ classic.jar: skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png (tabbrowser/tabbrowser-tabs-bkgnd.png) skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png) skin/classic/browser/tabbrowser/tab-bkgnd.png (tabbrowser/tab-bkgnd.png) - skin/classic/browser/urlbar/endcap.png (urlbar/endcap.png) - skin/classic/browser/urlbar/endcap-rtl.png (urlbar/endcap-rtl.png) - skin/classic/browser/urlbar/endcap-focused.png (urlbar/endcap-focused.png) - skin/classic/browser/urlbar/endcap-focused-graphite.png (urlbar/endcap-focused-graphite.png) - skin/classic/browser/urlbar/endcap-focused-graphite-rtl.png (urlbar/endcap-focused-graphite-rtl.png) - skin/classic/browser/urlbar/endcap-focused-rtl.png (urlbar/endcap-focused-rtl.png) - skin/classic/browser/urlbar/startcap.png (urlbar/startcap.png) - skin/classic/browser/urlbar/startcap-rtl.png (urlbar/startcap-rtl.png) - skin/classic/browser/urlbar/startcap-focused.png (urlbar/startcap-focused.png) - skin/classic/browser/urlbar/startcap-focused-graphite.png (urlbar/startcap-focused-graphite.png) - skin/classic/browser/urlbar/startcap-focused-graphite-rtl.png (urlbar/startcap-focused-graphite-rtl.png) - skin/classic/browser/urlbar/startcap-focused-rtl.png (urlbar/startcap-focused-rtl.png) - skin/classic/browser/urlbar/startcap-secure-start.png (urlbar/startcap-secure-start.png) - skin/classic/browser/urlbar/startcap-secure-mid.png (urlbar/startcap-secure-mid.png) - skin/classic/browser/urlbar/startcap-secure-end.png (urlbar/startcap-secure-end.png) - skin/classic/browser/urlbar/startcap-secure-start-active.png (urlbar/startcap-secure-start-active.png) - skin/classic/browser/urlbar/startcap-secure-mid-active.png (urlbar/startcap-secure-mid-active.png) - skin/classic/browser/urlbar/startcap-secure-end-active.png (urlbar/startcap-secure-end-active.png) - skin/classic/browser/urlbar/startcap-secure-start-focused.png (urlbar/startcap-secure-start-focused.png) - skin/classic/browser/urlbar/startcap-secure-start-focused-graphite.png (urlbar/startcap-secure-start-focused-graphite.png) - skin/classic/browser/urlbar/startcap-secure-mid-focused.png (urlbar/startcap-secure-mid-focused.png) - skin/classic/browser/urlbar/startcap-secure-mid-focused-graphite.png (urlbar/startcap-secure-mid-focused-graphite.png) - skin/classic/browser/urlbar/startcap-secure-end-focused.png (urlbar/startcap-secure-end-focused.png) - skin/classic/browser/urlbar/startcap-secure-end-focused-graphite.png (urlbar/startcap-secure-end-focused-graphite.png) - skin/classic/browser/urlbar/startcap-verified-start.png (urlbar/startcap-verified-start.png) - skin/classic/browser/urlbar/startcap-verified-mid.png (urlbar/startcap-verified-mid.png) - skin/classic/browser/urlbar/startcap-verified-end.png (urlbar/startcap-verified-end.png) - skin/classic/browser/urlbar/startcap-verified-start-active.png (urlbar/startcap-verified-start-active.png) - skin/classic/browser/urlbar/startcap-verified-mid-active.png (urlbar/startcap-verified-mid-active.png) - skin/classic/browser/urlbar/startcap-verified-end-active.png (urlbar/startcap-verified-end-active.png) - skin/classic/browser/urlbar/startcap-verified-start-focused.png (urlbar/startcap-verified-start-focused.png) - skin/classic/browser/urlbar/startcap-verified-start-focused-graphite.png (urlbar/startcap-verified-start-focused-graphite.png) - skin/classic/browser/urlbar/startcap-verified-mid-focused.png (urlbar/startcap-verified-mid-focused.png) - skin/classic/browser/urlbar/startcap-verified-mid-focused-graphite.png (urlbar/startcap-verified-mid-focused-graphite.png) - skin/classic/browser/urlbar/startcap-verified-end-focused.png (urlbar/startcap-verified-end-focused.png) - skin/classic/browser/urlbar/startcap-verified-end-focused-graphite.png (urlbar/startcap-verified-end-focused-graphite.png) - skin/classic/browser/urlbar/startcap-secure.png (urlbar/startcap-secure.png) - skin/classic/browser/urlbar/startcap-active.png (urlbar/startcap-active.png) - skin/classic/browser/urlbar/startcap-active-rtl.png (urlbar/startcap-active-rtl.png) - skin/classic/browser/urlbar/startcap-active-focused.png (urlbar/startcap-active-focused.png) - skin/classic/browser/urlbar/startcap-active-focused-graphite.png (urlbar/startcap-active-focused-graphite.png) - skin/classic/browser/urlbar/startcap-active-focused-graphite-rtl.png (urlbar/startcap-active-focused-graphite-rtl.png) - skin/classic/browser/urlbar/startcap-active-focused-rtl.png (urlbar/startcap-active-focused-rtl.png) - skin/classic/browser/urlbar/startcap-secure-active.png (urlbar/startcap-secure-active.png) - skin/classic/browser/urlbar/urlbar-favicon-glow.png (urlbar/urlbar-favicon-glow.png) - skin/classic/browser/urlbar/textfield-mid.png (urlbar/textfield-mid.png) - skin/classic/browser/urlbar/textfield-mid-focused.png (urlbar/textfield-mid-focused.png) - skin/classic/browser/urlbar/textfield-mid-focused-graphite.png (urlbar/textfield-mid-focused-graphite.png) icon.png preview.png diff --git a/browser/themes/pinstripe/browser/navbar-textbox-button-verifiedDomain.png b/browser/themes/pinstripe/browser/navbar-textbox-button-verifiedDomain.png new file mode 100755 index 000000000000..fddb8a5f4e06 Binary files /dev/null and b/browser/themes/pinstripe/browser/navbar-textbox-button-verifiedDomain.png differ diff --git a/browser/themes/pinstripe/browser/navbar-textbox-button-verifiedIdentity.png b/browser/themes/pinstripe/browser/navbar-textbox-button-verifiedIdentity.png new file mode 100755 index 000000000000..5f12a48ae341 Binary files /dev/null and b/browser/themes/pinstripe/browser/navbar-textbox-button-verifiedIdentity.png differ diff --git a/browser/themes/pinstripe/browser/navbar-textbox-button.png b/browser/themes/pinstripe/browser/navbar-textbox-button.png new file mode 100755 index 000000000000..9d509365f958 Binary files /dev/null and b/browser/themes/pinstripe/browser/navbar-textbox-button.png differ diff --git a/browser/themes/pinstripe/browser/searchbar.css b/browser/themes/pinstripe/browser/searchbar.css index ef80b3b52770..70080c09066a 100644 --- a/browser/themes/pinstripe/browser/searchbar.css +++ b/browser/themes/pinstripe/browser/searchbar.css @@ -1,31 +1,3 @@ -/* *** pinstripe *** */ - -.searchbar-textbox { - -moz-appearance: none; - font: icon; - height: 28px; - width: 5em; - margin: 0 3px 1px; - min-width: 5em; - border: none; - background-color: transparent; -} - -.searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box { - background: url("chrome://browser/skin/urlbar/textfield-mid.png") repeat-x; - padding: 0; - margin: 0; - -moz-margin-start: 45px; -} - -.searchbar-textbox[focused="true"] > .autocomplete-textbox-container > .textbox-input-box { - background-image: url("chrome://browser/skin/urlbar/textfield-mid-focused.png"); -} - -.searchbar-textbox[focused="true"] > .autocomplete-textbox-container > .textbox-input-box:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/textfield-mid-focused-graphite.png"); -} - .searchbar-engine-image { width: 16px; height: 16px; @@ -34,65 +6,8 @@ } .searchbar-engine-button { - background: url("chrome://browser/skin/urlbar/startcap.png") center center no-repeat; -moz-appearance: none; - height: 28px; - min-width: 45px; - border: 0; - -moz-box-align: center; - margin: 0; - -moz-margin-start: -45px; - padding: 0; -} - -.searchbar-engine-button[chromedir="rtl"] { - background-image: url("chrome://browser/skin/urlbar/startcap-rtl.png"); -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button { - background-image: url("chrome://browser/skin/urlbar/startcap-focused.png"); -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"] { - background-image: url("chrome://browser/skin/urlbar/startcap-focused-rtl.png"); -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-focused-graphite.png"); -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"]:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-focused-graphite-rtl.png"); -} - -.searchbar-engine-button:hover:active, -.searchbar-engine-button[open="true"] { - background-image: url("chrome://browser/skin/urlbar/startcap-active.png") !important; -} - -.searchbar-engine-button:hover:active[chromedir="rtl"], -.searchbar-engine-button[open="true"][chromedir="rtl"] { - background-image: url("chrome://browser/skin/urlbar/startcap-active-rtl.png") !important; -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button:active, -.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"] { - background-image: url("chrome://browser/skin/urlbar/startcap-active-focused.png") !important; -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"]:active, -.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"][chromedir="rtl"] { - background-image: url("chrome://browser/skin/urlbar/startcap-active-focused-rtl.png") !important; -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button:active:-moz-system-metric(mac-graphite-theme), -.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"]:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-active-focused-graphite.png") !important; -} - -.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"]:active:-moz-system-metric(mac-graphite-theme), -.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"][chromedir="rtl"]:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/startcap-active-focused-graphite-rtl.png") !important; + min-width: 0; } .searchbar-engine-button > .button-box { @@ -103,7 +18,11 @@ } .searchbar-engine-button[addengines="true"] > .button-box { - background: transparent url(chrome://browser/skin/Search-addengines.png) no-repeat 25px 50%; + background: transparent url(chrome://browser/skin/Search-addengines.png) no-repeat right center; +} + +.searchbar-textbox[chromedir="rtl"] .searchbar-engine-button[addengines="true"] > .button-box { + background-position: left center; } .searchbar-dropmarker-image { @@ -114,36 +33,10 @@ .search-go-container { -moz-box-align: center; - background: url("chrome://browser/skin/urlbar/endcap.png") no-repeat right top; - -moz-padding-end: 5px; -} - -.search-go-container[chromedir="rtl"] { - background-image: url("chrome://browser/skin/urlbar/endcap-rtl.png"); -} - -.searchbar-textbox[focused="true"] > .search-go-container { - background-image: url("chrome://browser/skin/urlbar/endcap-focused.png"); -} - -.searchbar-textbox[focused="true"] > .search-go-container[chromedir="rtl"] { - background: url("chrome://browser/skin/urlbar/endcap-focused-rtl.png") no-repeat left top; -} - -.searchbar-textbox[focused="true"] > .search-go-container:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/endcap-focused-graphite.png"); -} - -.searchbar-textbox[focused="true"] > .search-go-container[chromedir="rtl"]:-moz-system-metric(mac-graphite-theme) { - background-image: url("chrome://browser/skin/urlbar/endcap-focused-graphite-rtl.png"); } .search-go-button { - padding: 1px; list-style-image: url("chrome://browser/skin/Search.png"); - margin: 0; - padding: 0; - -moz-padding-end: 6px; } .searchbar-engine-menuitem[selected="true"] > .menu-iconic-text { diff --git a/browser/themes/pinstripe/browser/urlbar/urlbar-favicon-glow.png b/browser/themes/pinstripe/browser/urlbar-favicon-glow.png similarity index 100% rename from browser/themes/pinstripe/browser/urlbar/urlbar-favicon-glow.png rename to browser/themes/pinstripe/browser/urlbar-favicon-glow.png diff --git a/browser/themes/pinstripe/browser/urlbar/endcap-focused-graphite-rtl.png b/browser/themes/pinstripe/browser/urlbar/endcap-focused-graphite-rtl.png deleted file mode 100644 index 10c9e89529d3..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/endcap-focused-graphite-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/endcap-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/endcap-focused-graphite.png deleted file mode 100644 index 4e27f08439cb..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/endcap-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/endcap-focused-rtl.png b/browser/themes/pinstripe/browser/urlbar/endcap-focused-rtl.png deleted file mode 100644 index b7cb9c63c0f5..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/endcap-focused-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/endcap-focused.png b/browser/themes/pinstripe/browser/urlbar/endcap-focused.png deleted file mode 100644 index 786fd2979e57..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/endcap-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/endcap-rtl.png b/browser/themes/pinstripe/browser/urlbar/endcap-rtl.png deleted file mode 100644 index e26eaebf8a15..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/endcap-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/endcap-secure.png b/browser/themes/pinstripe/browser/urlbar/endcap-secure.png deleted file mode 100644 index 7e50ee4f6e11..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/endcap-secure.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/endcap.png b/browser/themes/pinstripe/browser/urlbar/endcap.png deleted file mode 100644 index 60069850d307..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/endcap.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-graphite-rtl.png b/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-graphite-rtl.png deleted file mode 100644 index 0cca6565c49e..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-graphite-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-graphite.png deleted file mode 100644 index 311cef8aefad..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-rtl.png b/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-rtl.png deleted file mode 100644 index ed2bb4403068..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-active-focused.png deleted file mode 100644 index 7076d1df6cd2..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-active-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-active-rtl.png b/browser/themes/pinstripe/browser/urlbar/startcap-active-rtl.png deleted file mode 100644 index 2047ada0fc5c..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-active-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-active.png deleted file mode 100644 index 33603dea2499..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-focused-graphite-rtl.png b/browser/themes/pinstripe/browser/urlbar/startcap-focused-graphite-rtl.png deleted file mode 100644 index 289c0fbd5d15..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-focused-graphite-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-focused-graphite.png deleted file mode 100644 index 5e5194d0204b..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-focused-rtl.png b/browser/themes/pinstripe/browser/urlbar/startcap-focused-rtl.png deleted file mode 100644 index 26909af696fc..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-focused-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-focused.png deleted file mode 100644 index 499d1c4df50b..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-rtl.png b/browser/themes/pinstripe/browser/urlbar/startcap-rtl.png deleted file mode 100644 index a73a41e50a63..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-rtl.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-active.png deleted file mode 100644 index df39fe20da43..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-active.png deleted file mode 100644 index aa4183cac7cc..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-focused-graphite.png deleted file mode 100644 index b85590b32d0f..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-focused.png deleted file mode 100644 index 9dc0637949be..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-end.png deleted file mode 100644 index 8fc0939b8b6f..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-end.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-active.png deleted file mode 100644 index 6bfe1260248f..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-focused-graphite.png deleted file mode 100644 index e26ee4decdc5..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-focused.png deleted file mode 100644 index ebe4f69e5bcc..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid.png deleted file mode 100644 index e9fc57660b22..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-mid.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-active.png deleted file mode 100644 index 8c8fd080b236..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-focused-graphite.png deleted file mode 100644 index 284f3b0a5b5b..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-focused.png deleted file mode 100644 index bc0e4064da20..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure-start.png deleted file mode 100644 index 46a282fee1e5..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure-start.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-secure.png b/browser/themes/pinstripe/browser/urlbar/startcap-secure.png deleted file mode 100644 index e7f85b9b1a29..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-secure.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-active.png deleted file mode 100644 index ca0bad20bd3f..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-focused-graphite.png deleted file mode 100644 index be03cdbc2d0e..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-focused.png deleted file mode 100644 index 65e097bb2701..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-invalid.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-invalid.png deleted file mode 100644 index bb84890a4729..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end-invalid.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-end.png deleted file mode 100644 index bcee816e211d..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-end.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-active.png deleted file mode 100644 index 853aa7d8407e..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-focused-graphite.png deleted file mode 100644 index 1250613dd15a..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-focused.png deleted file mode 100644 index b7c85e8f5ad5..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid.png deleted file mode 100644 index e135410df021..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-mid.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-active.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-active.png deleted file mode 100644 index 73e26174bc09..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-active.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-focused-graphite.png deleted file mode 100644 index 83a3d55929f8..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-focused.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-focused.png deleted file mode 100644 index 3e1a2f6c129e..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start.png b/browser/themes/pinstripe/browser/urlbar/startcap-verified-start.png deleted file mode 100644 index e5d3752a2016..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap-verified-start.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/startcap.png b/browser/themes/pinstripe/browser/urlbar/startcap.png deleted file mode 100644 index 5d822e9c0745..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/startcap.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/textfield-mid-focused-graphite.png b/browser/themes/pinstripe/browser/urlbar/textfield-mid-focused-graphite.png deleted file mode 100644 index 16be713c7446..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/textfield-mid-focused-graphite.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/textfield-mid-focused.png b/browser/themes/pinstripe/browser/urlbar/textfield-mid-focused.png deleted file mode 100644 index 0d8706580557..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/textfield-mid-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/textfield-mid-secure-focused.png b/browser/themes/pinstripe/browser/urlbar/textfield-mid-secure-focused.png deleted file mode 100644 index 13a4a669f176..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/textfield-mid-secure-focused.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/textfield-mid-secure.png b/browser/themes/pinstripe/browser/urlbar/textfield-mid-secure.png deleted file mode 100644 index 3f1cdcc3f2bd..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/textfield-mid-secure.png and /dev/null differ diff --git a/browser/themes/pinstripe/browser/urlbar/textfield-mid.png b/browser/themes/pinstripe/browser/urlbar/textfield-mid.png deleted file mode 100644 index b1ba5e9343a5..000000000000 Binary files a/browser/themes/pinstripe/browser/urlbar/textfield-mid.png and /dev/null differ diff --git a/browser/themes/winstripe/browser/browser.css b/browser/themes/winstripe/browser/browser.css old mode 100644 new mode 100755 index aaeb81080dc7..272d0eeb30af --- a/browser/themes/winstripe/browser/browser.css +++ b/browser/themes/winstripe/browser/browser.css @@ -1551,7 +1551,6 @@ tabpanels { } .tabs-newtab-button { - opacity: .8; list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png); -moz-image-region: rect(0, 18px, 18px, 0); } @@ -1868,13 +1867,8 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { outline: 1px dotted white; } -#identity-icon-label { +#identity-icon-labels { padding: 0 2px; - margin: 0; -} - -#identity-icon-label[value=""] { - display: none; } /* Popup Icons */ diff --git a/browser/themes/winstripe/browser/searchbar.css b/browser/themes/winstripe/browser/searchbar.css index 7684ba79fa6d..c855c4dd6641 100644 --- a/browser/themes/winstripe/browser/searchbar.css +++ b/browser/themes/winstripe/browser/searchbar.css @@ -4,6 +4,10 @@ min-width: 6em; } +.autocomplete-textbox-container { + -moz-box-align: stretch; +} + .searchbar-textbox:-moz-system-metric(windows-default-theme) { -moz-appearance: none; border-width: 1px; @@ -33,8 +37,6 @@ margin: 0; -moz-margin-end: 3px; padding: 0; - height: 1.23em; - min-height: 20px; -moz-box-align: center; background: -moz-dialog url(navbar-textbox-buttons.png) repeat-x; border: 0 solid; diff --git a/build/automation.py.in b/build/automation.py.in index 68bf1133da09..a9e59f6c403f 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -257,6 +257,7 @@ user_pref("svg.smil.enabled", true); // Needed for SMIL mochitests until bug 482 user_pref("media.cache_size", 100); user_pref("security.warn_viewing_mixed", false); +user_pref("geo.wifi.uri", "http://localhost:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"); user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others """ diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index 52af43260d67..f592c7fcfbfc 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -42,10 +42,10 @@ #include "nsCaseTreatment.h" #include "nsChangeHint.h" #include "nsINode.h" +#include "nsIDocument.h" // for IsInHTMLDocument // Forward declarations class nsIAtom; -class nsIDocument; class nsPresContext; class nsIDOMEvent; class nsIContent; @@ -63,8 +63,8 @@ class nsISMILAttr; // IID for the nsIContent interface #define NS_ICONTENT_IID \ -{ 0x3ca5afbe, 0x1052, 0x4682, \ - { 0x9f, 0xa0, 0x0e, 0x39, 0xe4, 0xf8, 0xef, 0x9d } } +{ 0x08dadcc4, 0x057a, 0x4b8d, \ + { 0x89, 0x43, 0x30, 0x0e, 0x61, 0xc6, 0x9d, 0x36 } } /** * A node of content in a document's content model. This interface @@ -202,6 +202,17 @@ public: return IsInNativeAnonymousSubtree() || GetBindingParent() != nsnull; } + /** + * Return true iff this node is in an HTML document (in the HTML5 sense of + * the term, i.e. not in an XHTML/XML document). + */ + inline PRBool IsInHTMLDocument() const + { + nsIDocument* doc = GetOwnerDoc(); + return doc && // XXX clean up after bug 335998 lands + !doc->IsCaseSensitive(); + } + /** * Get the namespace that this element's tag is defined in * @return the namespace @@ -456,36 +467,6 @@ public: */ virtual void AppendTextTo(nsAString& aResult) = 0; - /** - * Set the focus on this content. This is generally something for the event - * state manager to do, not ordinary people. Ordinary people should do - * something like nsGenericHTMLElement::SetElementFocus(). This method is - * the end result, the point where the content finds out it has been focused. - * - * All content elements are potentially focusable. - * - * @param aPresContext the pres context - * @see nsGenericHTMLElement::SetElementFocus() - */ - virtual void SetFocus(nsPresContext* aPresContext) - { - } - - /** - * Remove the focus on this content. This is generally something for the - * event state manager to do, not ordinary people. Ordinary people should do - * something like nsGenericHTMLElement::SetElementFocus(). This method is - * the end result, the point where the content finds out it has been focused. - * - * All content elements are potentially focusable. - * - * @param aPresContext the pres context - * @see nsGenericHTMLElement::SetElementFocus() - */ - virtual void RemoveFocus(nsPresContext* aPresContext) - { - } - /** * Check if this content is focusable and in the current tab order. * Note: most callers should use nsIFrame::IsFocusable() instead as it diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 2e2b9b813438..3115c506b89a 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -115,6 +115,7 @@ #include "nsIDOMWindowInternal.h" #include "nsPIDOMWindow.h" #include "nsIDOMElement.h" +#include "nsFocusManager.h" // for radio group stuff #include "nsIDOMHTMLInputElement.h" @@ -2493,28 +2494,15 @@ nsDocument::HasFocus(PRBool* aResult) { *aResult = PR_FALSE; - nsPIDOMWindow* window = GetWindow(); - nsIFocusController* focusController = window ? - window->GetRootFocusController() : nsnull; - if (!focusController) { - return NS_OK; - } - - // Does the top-level window have focus? - PRBool active; - nsresult rv = focusController->GetActive(&active); - NS_ENSURE_SUCCESS(rv, rv); - if (!active){ - return NS_OK; - } + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (!fm) + return NS_ERROR_NOT_AVAILABLE; // Is there a focused DOMWindow? - nsCOMPtr focusedWindow; - rv = focusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); - NS_ENSURE_SUCCESS(rv, rv); - if (!focusedWindow) { - return NS_ERROR_FAILURE; - } + nsCOMPtr focusedWindow; + fm->GetFocusedWindow(getter_AddRefs(focusedWindow)); + if (!focusedWindow) + return NS_OK; // Are we an ancestor of the focused DOMWindow? nsCOMPtr domDocument; @@ -2546,56 +2534,29 @@ nsDocument::GetActiveElement(nsIDOMElement **aElement) *aElement = nsnull; // Get the focused element. - nsPIDOMWindow* window = GetWindow(); + nsCOMPtr window = GetWindow(); if (!window) { return NS_ERROR_NOT_AVAILABLE; } - nsIFocusController* focusController = window->GetRootFocusController(); - if (!focusController) { - return NS_ERROR_FAILURE; - } + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (!fm) + return NS_ERROR_NOT_AVAILABLE; - nsCOMPtr focusedElement; - focusController->GetFocusedElement(getter_AddRefs(focusedElement)); - nsCOMPtr content = do_QueryInterface(focusedElement); - if (content) { - // Found a focused element. See if it's in this document. - nsIDocument* currentDoc = content->GetCurrentDoc(); - if (currentDoc == this) { - focusedElement.swap(*aElement); - return NS_OK; + nsCOMPtr focusedWindow; + nsIContent* focusedContent = + nsFocusManager::GetFocusedDescendant(window, PR_FALSE, getter_AddRefs(focusedWindow)); + + // an element in this document is focused, so return it + if (focusedContent) { + // be safe and make sure the element is from this document + if (focusedContent->GetOwnerDoc() != this) { + NS_WARNING("Focused element found from another document"); + return NS_ERROR_FAILURE; } - // Not in this document. If it's in a child document, return the iframe in - // this document that's an ancestor of the child. - if (currentDoc) { - *aElement = CheckAncestryAndGetFrame(currentDoc).get(); - if (*aElement) { - return NS_OK; - } - } - } - - // Couldn't find a focused element. Check if something like an IFRAME is - // focused, which will give us a focused window rather than a focused - // element. - nsCOMPtr focusedWindow; - focusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); - if (focusedWindow) { - // Found a focused window. See if it's in a child of this document. (If - // the window's document is this, then we should just fall through to - // returning the BODY below). - nsCOMPtr domDocument; - focusedWindow->GetDocument(getter_AddRefs(domDocument)); - nsCOMPtr document = do_QueryInterface(domDocument); - - if (document && (document != this)) { - *aElement = CheckAncestryAndGetFrame(document).get(); - if (*aElement) { - return NS_OK; - } - } + CallQueryInterface(focusedContent, aElement); + return NS_OK; } // No focused element anywhere in this document. Try to get the BODY. @@ -7502,8 +7463,13 @@ static void FireOrClearDelayedEvents(nsTArray >& aDocuments, PRBool aFireEvents) { + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (!fm) + return; + for (PRUint32 i = 0; i < aDocuments.Length(); ++i) { if (!aDocuments[i]->EventHandlingSuppressed()) { + fm->FireDelayedEvents(aDocuments[i]); nsPresShellIterator iter(aDocuments[i]); nsCOMPtr shell; while ((shell = iter.GetNextShell())) { diff --git a/content/base/src/nsFrameLoader.cpp b/content/base/src/nsFrameLoader.cpp index 29e85fca2442..7bf0b16ea448 100644 --- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -817,9 +817,7 @@ nsFrameLoader::EnsureDocShell() nsAutoString frameName; PRInt32 namespaceID = mOwnerContent->GetNameSpaceID(); - if (namespaceID == kNameSpaceID_XHTML - && mOwnerContent->GetOwnerDoc() // clean up after bug 335998 - && mOwnerContent->GetOwnerDoc()->IsCaseSensitive()) { + if (namespaceID == kNameSpaceID_XHTML && !mOwnerContent->IsInHTMLDocument()) { mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName); } else { mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName); diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 82143c3cc652..1e6054fbd8b0 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -54,7 +54,7 @@ #include "nsIDOMText.h" #include "nsIContentIterator.h" #include "nsIEventListenerManager.h" -#include "nsIFocusController.h" +#include "nsFocusManager.h" #include "nsILinkHandler.h" #include "nsIScriptGlobalObject.h" #include "nsIURL.h" @@ -124,7 +124,6 @@ #include "nsIEditorDocShell.h" #include "nsEventDispatcher.h" #include "nsContentCreatorFunctions.h" -#include "nsIFocusController.h" #include "nsIControllers.h" #include "nsLayoutUtils.h" #include "nsIView.h" @@ -3072,84 +3071,29 @@ nsGenericElement::IsLink(nsIURI** aURI) const return PR_FALSE; } -void -nsGenericElement::SetFocus(nsPresContext* aPresContext) -{ - // Traditionally focusable elements can take focus as long as they don't set - // the disabled attribute - - nsCOMPtr presShell = aPresContext->PresShell(); - if (!presShell) { - return; - } - nsIFrame* frame = presShell->GetPrimaryFrameFor(this); - if (frame && frame->IsFocusable() && - aPresContext->EventStateManager()->SetContentState(this, - NS_EVENT_STATE_FOCUS)) { - presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE, - NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE); - } -} - -// static -PRBool -nsGenericElement::ShouldFocus(nsIContent *aContent) -{ - // Default to false, since if the document is not attached to a window, - // we should not focus any of its content. - PRBool visible = PR_FALSE; - - // Figure out if we're focusing an element in an inactive (hidden) - // tab (whose docshell is not visible), if so, drop this focus - // request on the floor - - nsIDocument *document = aContent->GetDocument(); - - if (document) { - nsIScriptGlobalObject *sgo = document->GetScriptGlobalObject(); - - if (sgo) { - nsCOMPtr webNav(do_GetInterface(sgo)); - nsCOMPtr baseWin(do_QueryInterface(webNav)); - - if (baseWin) { - baseWin->GetVisibility(&visible); - } - } - } - - return visible; -} - // static PRBool nsGenericElement::ShouldBlur(nsIContent *aContent) { // Determine if the current element is focused, if it is not focused // then we should not try to blur - PRBool isFocused = PR_FALSE; - nsIDocument *document = aContent->GetDocument(); + if (!document) + return PR_FALSE; - if (document) { - nsPIDOMWindow *win = document->GetWindow(); + nsCOMPtr window = do_QueryInterface(document->GetWindow()); + if (!window) + return PR_FALSE; - if (win) { - nsCOMPtr focusController = - win->GetRootFocusController(); + nsCOMPtr focusedFrame; + nsIContent* contentToBlur = + nsFocusManager::GetFocusedDescendant(window, PR_FALSE, getter_AddRefs(focusedFrame)); + if (contentToBlur == aContent) + return PR_TRUE; - if (focusController) { - nsCOMPtr focusedElement; - focusController->GetFocusedElement(getter_AddRefs(focusedElement)); - nsCOMPtr domElement = do_QueryInterface(aContent); - //when the element is the same as the focused element, blur it - if (domElement == focusedElement) - isFocused = PR_TRUE; - } - } - } - - return isFocused; + // if focus on this element would get redirected, then check the redirected + // content as well when blurring. + return (contentToBlur && nsFocusManager::GetRedirectedFocus(aContent) == contentToBlur); } nsIContent* @@ -4999,28 +4943,15 @@ nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor) // don't make the link grab the focus if there is no link handler nsILinkHandler *handler = aVisitor.mPresContext->GetLinkHandler(); nsIDocument *document = GetCurrentDoc(); - if (handler && document && ShouldFocus(this)) { - // If the window is not active, do not allow the focus to bring the - // window to the front. We update the focus controller, but do nothing - // else. - nsPIDOMWindow *win = document->GetWindow(); - if (win) { - nsIFocusController *focusController = - win->GetRootFocusController(); - if (focusController) { - PRBool isActive = PR_FALSE; - focusController->GetActive(&isActive); - if (!isActive) { - nsCOMPtr domElement = do_QueryInterface(this); - if(domElement) - focusController->SetFocusedElement(domElement); - break; - } - } + if (handler && document) { + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) { + nsCOMPtr elem = do_QueryInterface(this); + fm->SetFocus(elem, nsIFocusManager::FLAG_BYMOUSE); } - + aVisitor.mPresContext->EventStateManager()-> - SetContentState(this, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS); + SetContentState(this, NS_EVENT_STATE_ACTIVE); } } } diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h index 70c7e27e78c6..b859aa1dd485 100644 --- a/content/base/src/nsGenericElement.h +++ b/content/base/src/nsGenericElement.h @@ -417,7 +417,6 @@ public: PRBool aNotify); virtual PRBool TextIsOnlyWhitespace(); virtual void AppendTextTo(nsAString& aResult); - virtual void SetFocus(nsPresContext* aContext); virtual nsIContent *GetBindingParent() const; virtual PRBool IsNodeOfType(PRUint32 aFlags) const; virtual already_AddRefed GetBaseURI() const; @@ -584,8 +583,6 @@ public: static already_AddRefed GetDOMFeatureFactory(const nsAString& aFeature, const nsAString& aVersion); - static PRBool ShouldFocus(nsIContent *aContent); - static PRBool ShouldBlur(nsIContent *aContent); /** diff --git a/content/events/public/nsIEventStateManager.h b/content/events/public/nsIEventStateManager.h index 46a03edd8470..70da1a0c7a6f 100644 --- a/content/events/public/nsIEventStateManager.h +++ b/content/events/public/nsIEventStateManager.h @@ -42,6 +42,7 @@ #include "nsISupports.h" class nsIContent; +class nsIDocument; class nsPresContext; class nsIDOMEvent; class nsIFrame; @@ -52,24 +53,16 @@ class imgIContainer; /* * Event state manager interface. */ -// {fb7516ff-2f01-4893-84e8-e4b282813023} +// {C224A806-A99F-4056-85C2-3B1970F94DB2} #define NS_IEVENTSTATEMANAGER_IID \ -{ 0x522d12ec, 0xde51, 0x4635, \ - { 0xb0, 0x10, 0x4, 0x2a, 0x6d, 0x5, 0xa0, 0x3e } } +{ 0xc224a806, 0xa99f, 0x4056, \ + { 0x85, 0xc2, 0x3b, 0x19, 0x70, 0xf9, 0x4d, 0xb2 } } #define NS_EVENT_NEEDS_FRAME(event) (!NS_IS_FOCUS_EVENT(event)) class nsIEventStateManager : public nsISupports { public: - enum EFocusedWithType { - eEventFocusedByUnknown, // focus gained via unknown method - eEventFocusedByMouse, // focus gained via mouse - eEventFocusedByKey, // focus gained via key press (like tab) - eEventFocusedByContextMenu, // focus gained via context menu - eEventFocusedByApplication // focus gained via Application (like script) - }; - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEVENTSTATEMANAGER_IID) NS_IMETHOD Init() = 0; @@ -108,29 +101,9 @@ public: */ virtual PRBool SetContentState(nsIContent *aContent, PRInt32 aState) = 0; - NS_IMETHOD GetFocusedContent(nsIContent **aContent) = 0; - NS_IMETHOD SetFocusedContent(nsIContent* aContent) = 0; - - // Get the previously-focused content node for this document - NS_IMETHOD GetLastFocusedContent(nsIContent **aContent) = 0; - - NS_IMETHOD GetFocusedFrame(nsIFrame **aFrame) = 0; - - NS_IMETHOD ContentRemoved(nsIContent* aContent) = 0; + NS_IMETHOD ContentRemoved(nsIDocument* aDocument, nsIContent* aContent) = 0; NS_IMETHOD EventStatusOK(nsGUIEvent* aEvent, PRBool *aOK) = 0; - // Return whether browse with caret is enabled or not - virtual PRBool GetBrowseWithCaret() = 0; - - // This is called after find text or when a cursor movement key is pressed - // If aCanFocusDoc == PR_TRUE, the current document will be focused if caret is not on a focusable element - NS_IMETHOD MoveFocusToCaret(PRBool aCanFocusDoc, PRBool *aIsSelectionWithFocus) = 0; - NS_IMETHOD MoveCaretToFocus() = 0; - - // Set focus on any element that can receive focus, or on document via aFocusContent == nsnull - // Must supply method that focus is being set with - NS_IMETHOD ChangeFocusWith(nsIContent *aFocusContent, EFocusedWithType aFocusedWith) = 0; - // Access Key Registration /** @@ -163,9 +136,6 @@ public: PRBool aHaveHotspot, float aHotspotX, float aHotspotY, nsIWidget* aWidget, PRBool aLockCursor) = 0; - // Method for moving the focus forward/back. - NS_IMETHOD ShiftFocus(PRBool aDirection, nsIContent* aStart)=0; - NS_IMETHOD NotifyDestroyPresContext(nsPresContext* aPresContext) = 0; /** diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp index dc92c5c0f52e..705b18a78175 100644 --- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -928,14 +928,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData() newEvent = new nsFormEvent(PR_FALSE, msg); break; } - case NS_FOCUS_EVENT: - { - newEvent = new nsFocusEvent(PR_FALSE, msg, nsnull); - NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY); - static_cast(newEvent)->isMozWindowTakingFocus = - static_cast(mEvent)->isMozWindowTakingFocus; - break; - } case NS_POPUP_EVENT: { newEvent = new nsInputEvent(PR_FALSE, msg, nsnull); diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 62a0f6bcd7cf..c1e5a37d525e 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -85,7 +85,7 @@ #include "nsIXPConnect.h" #include "nsDOMCID.h" #include "nsIScriptObjectOwner.h" // for nsIScriptEventHandlerOwner -#include "nsIFocusController.h" +#include "nsFocusManager.h" #include "nsIDOMElement.h" #include "nsIDOMNSDocument.h" #include "nsContentUtils.h" diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 7c0935279dea..8fbef857aff0 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -103,7 +103,7 @@ #include "nsIServiceManager.h" #include "nsIScriptSecurityManager.h" -#include "nsIFocusController.h" +#include "nsFocusManager.h" #include "nsIDOMXULElement.h" #include "nsIDOMDocument.h" @@ -168,19 +168,6 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); -nsIContent * gLastFocusedContent = 0; // Strong reference -nsIDocument * gLastFocusedDocument = 0; // Strong reference -nsPresContext* gLastFocusedPresContextWeak = 0; // Weak reference - -enum nsTextfieldSelectModel { - eTextfieldSelect_unset = -1, - eTextfieldSelect_manual = 0, - eTextfieldSelect_auto = 1 // select textfields when focused with keyboard -}; - -// Tab focus policy (static, constant across the app): -// Which types of elements are in the tab order? -static PRInt8 sTextfieldSelectModel = eTextfieldSelect_unset; static PRBool sLeftClickOnly = PR_TRUE; static PRBool sKeyCausesActivation = PR_TRUE; static PRUint32 sESMInstanceCount = 0; @@ -267,69 +254,6 @@ PrintDocTreeAll(nsIDocShellTreeItem* aItem) } #endif -static PRUint32 gMayNeedFocusSuppression = 0; - -class nsSuppressUserFocus -{ -public: - nsSuppressUserFocus() : mActive(PR_FALSE) {} - ~nsSuppressUserFocus() { - if (mActive) { - NS_ASSERTION(gMayNeedFocusSuppression, - "Trying to unsuppress too much!"); - --gMayNeedFocusSuppression; - } - } - void MaybeSuppress() - { - if (!mActive) { - mActive = PR_TRUE; - ++gMayNeedFocusSuppression; - } - } -private: - PRBool mActive; -}; - -static nsIDocument* -EventHandlingSuppressed(nsPIDOMEventTarget* aTarget) -{ - if (!gMayNeedFocusSuppression) { - return nsnull; - } - nsCOMPtr node = do_QueryInterface(aTarget); - nsCOMPtr doc; - if (node) { - doc = node->GetOwnerDoc(); - } else { - nsCOMPtr window = do_QueryInterface(aTarget); - if (window) { - doc = do_QueryInterface(window->GetExtantDocument()); - } - } - - return (doc && doc->EventHandlingSuppressed()) ? doc.get() : nsnull; -} - -static void -FireFocusOrBlurEvent(nsPIDOMEventTarget* aTarget, nsEvent* aEvent, nsPresContext* aContext) -{ - NS_ASSERTION(aEvent->message == NS_BLUR_CONTENT || - aEvent->message == NS_FOCUS_CONTENT, - "Wrong event!"); - nsIDocument* doc = EventHandlingSuppressed(aTarget); - if (doc) { - if (aContext) { - nsIPresShell* shell = aContext->GetPresShell(); - if (shell) { - shell->NeedsFocusOrBlurAfterSuppression(aTarget, aEvent->message); - } - } - } else if (aTarget) { - nsEventDispatcher::Dispatch(aTarget, aContext, aEvent); - } -} - class nsUITimerCallback : public nsITimerCallback { public: @@ -375,8 +299,6 @@ enum { #define NS_MODIFIER_ALT 4 #define NS_MODIFIER_META 8 -static PRBool GetWindowShowCaret(nsIDocument *aDocument); - static nsIDocument * GetDocumentFromWindow(nsIDOMWindow *aWindow) { @@ -697,17 +619,12 @@ nsEventStateManager::nsEventStateManager() mLastDragOverFrame(nsnull), // init d&d gesture state machine variables mGestureDownPoint(0,0), - mCurrentFocusFrame(nsnull), - mCurrentTabIndex(0), - mLastFocusedWith(eEventFocusedByUnknown), mPresContext(nsnull), mLClickCount(0), mMClickCount(0), mRClickCount(0), mNormalLMouseEventInProcess(PR_FALSE), m_haveShutdown(PR_FALSE), - mBrowseWithCaret(PR_FALSE), - mTabbedThroughDocument(PR_FALSE), mLastLineScrollConsumedX(PR_FALSE), mLastLineScrollConsumedY(PR_FALSE) { @@ -749,14 +666,8 @@ nsEventStateManager::Init() GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeChrome); sContentAccessModifier = GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeContent); - - nsIContent::sTabFocusModelAppliesToXUL = - nsContentUtils::GetBoolPref("accessibility.tabfocus_applies_to_xul", - nsIContent::sTabFocusModelAppliesToXUL); } prefBranch->AddObserver("accessibility.accesskeycausesactivation", this, PR_TRUE); - prefBranch->AddObserver("accessibility.browsewithcaret", this, PR_TRUE); - prefBranch->AddObserver("accessibility.tabfocus_applies_to_xul", this, PR_TRUE); prefBranch->AddObserver("nglayout.events.dispatchLeftClickOnly", this, PR_TRUE); prefBranch->AddObserver("ui.key.generalAccessKey", this, PR_TRUE); prefBranch->AddObserver("ui.key.chromeAccess", this, PR_TRUE); @@ -779,15 +690,6 @@ nsEventStateManager::Init() prefBranch->AddObserver("dom.popup_allowed_events", this, PR_TRUE); } - if (sTextfieldSelectModel == eTextfieldSelect_unset) { - nsCOMPtr lookNFeel(do_GetService(kLookAndFeelCID)); - PRInt32 selectTextfieldsOnKeyFocus = 0; - lookNFeel->GetMetric(nsILookAndFeel::eMetric_SelectTextfieldsOnKeyFocus, - selectTextfieldsOnKeyFocus); - sTextfieldSelectModel = selectTextfieldsOnKeyFocus ? eTextfieldSelect_auto: - eTextfieldSelect_manual; - } - return rv; } @@ -800,8 +702,6 @@ nsEventStateManager::~nsEventStateManager() --sESMInstanceCount; if(sESMInstanceCount == 0) { nsMouseWheelTransaction::Shutdown(); - NS_IF_RELEASE(gLastFocusedContent); - NS_IF_RELEASE(gLastFocusedDocument); if (gUserInteractionTimerCallback) { gUserInteractionTimerCallback->Notify(nsnull); NS_RELEASE(gUserInteractionTimerCallback); @@ -838,8 +738,6 @@ nsEventStateManager::Shutdown() if (prefBranch) { prefBranch->RemoveObserver("accessibility.accesskeycausesactivation", this); - prefBranch->RemoveObserver("accessibility.browsewithcaret", this); - prefBranch->RemoveObserver("accessibility.tabfocus_applies_to_xul", this); prefBranch->RemoveObserver("nglayout.events.dispatchLeftClickOnly", this); prefBranch->RemoveObserver("ui.key.generalAccessKey", this); prefBranch->RemoveObserver("ui.key.chromeAccess", this); @@ -882,12 +780,6 @@ nsEventStateManager::Observe(nsISupports *aSubject, sKeyCausesActivation = nsContentUtils::GetBoolPref("accessibility.accesskeycausesactivation", sKeyCausesActivation); - } else if (data.EqualsLiteral("accessibility.browsewithcaret")) { - ResetBrowseWithCaret(); - } else if (data.EqualsLiteral("accessibility.tabfocus_applies_to_xul")) { - nsIContent::sTabFocusModelAppliesToXUL = - nsContentUtils::GetBoolPref("accessibility.tabfocus_applies_to_xul", - nsIContent::sTabFocusModelAppliesToXUL); } else if (data.EqualsLiteral("nglayout.events.dispatchLeftClickOnly")) { sLeftClickOnly = nsContentUtils::GetBoolPref("nglayout.events.dispatchLeftClickOnly", @@ -949,12 +841,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEventStateManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mHoverContent); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDragOverContent); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mURLTargetContent); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCurrentFocus); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastFocus); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastContentFocus); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstBlurEvent); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstDocumentBlurEvent); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstFocusEvent); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstMouseOverEventElement); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstMouseOutEventElement); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument); @@ -973,12 +859,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEventStateManager) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mHoverContent); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDragOverContent); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mURLTargetContent); - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCurrentFocus); - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastFocus); - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastContentFocus); - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstBlurEvent); - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstDocumentBlurEvent); - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstFocusEvent); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstMouseOverEventElement); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstMouseOutEventElement); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument); @@ -1032,8 +912,6 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, nsMouseWheelTransaction::OnEvent(aEvent); - nsSuppressUserFocus userFocus; - switch (aEvent->message) { case NS_MOUSE_BUTTON_DOWN: switch (static_cast(aEvent)->button) { @@ -1121,452 +999,6 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, // the enter/exit events before NS_DRAGDROP_DROP. GenerateDragDropEnterExit(aPresContext, (nsGUIEvent*)aEvent); break; - case NS_GOTFOCUS: - { -#ifdef DEBUG_smaug - printf("nsEventStateManager::PreHandleEvent, NS_GOTFOCUS \n"); -#endif - userFocus.MaybeSuppress(); - // This is called when a child widget has received focus. - // We need to take care of sending a blur event for the previously - // focused content and document, then dispatching a focus - // event to the target content, its document, and its window. - - EnsureDocument(aPresContext); - - // If the document didn't change, then the only thing that could have - // changed is the focused content node. That's handled elsewhere - // (SetContentState and SendFocusBlur). - - if (gLastFocusedDocument == mDocument) - break; - - if (mDocument) { - nsIMEStateManager::OnTextStateBlur(mPresContext, mCurrentFocus); - - if (gLastFocusedDocument && gLastFocusedPresContextWeak) { - nsCOMPtr ourWindow = - gLastFocusedDocument->GetWindow(); - - // If the focus controller is already suppressed, it means that we - // are in the middle of an activate sequence. In this case, we do - // _not_ want to fire a blur on the previously focused content, since - // we will be focusing it again later when we receive the NS_ACTIVATE - // event. See bug 120209. - - // Hold a strong ref to the focus controller, since we need - // it after event dispatch. - nsCOMPtr focusController; - PRBool isAlreadySuppressed = PR_FALSE; - - if (ourWindow) { - focusController = ourWindow->GetRootFocusController(); - if (focusController) { - focusController->GetSuppressFocus(&isAlreadySuppressed); - focusController->SetSuppressFocus(PR_TRUE, - "NS_GOTFOCUS ESM Suppression"); - } - } - - if (!isAlreadySuppressed) { - - // Fire the blur event on the previously focused document. - nsEvent blurEvent(PR_TRUE, NS_BLUR_CONTENT); - blurEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - FireFocusOrBlurEvent(gLastFocusedDocument, &blurEvent, - gLastFocusedPresContextWeak); - - nsCOMPtr esm; - if (!mCurrentFocus && gLastFocusedContent) { - // We also need to blur the previously focused content node here, - // if we don't have a focused content node in this document. - // (SendFocusBlur isn't called in this case). - if (gLastFocusedContent) { - nsCOMPtr doc = gLastFocusedContent->GetCurrentDoc(); - if (doc) { - nsIPresShell *shell = doc->GetPrimaryShell(); - if (shell) { - nsCOMPtr oldPresContext = shell->GetPresContext(); - esm = oldPresContext->EventStateManager(); - if (esm) { - esm->SetFocusedContent(gLastFocusedContent); - } - } - } - } - nsCOMPtr blurContent = gLastFocusedContent; - blurEvent.target = nsnull; - FireFocusOrBlurEvent(gLastFocusedContent, &blurEvent, - gLastFocusedPresContextWeak); - } - if (ourWindow) { - // Clear the target so that Dispatch can set it back correctly. - blurEvent.target = nsnull; - nsCOMPtr win = do_QueryInterface(ourWindow); - FireFocusOrBlurEvent(win, &blurEvent, gLastFocusedPresContextWeak); - } - - if (esm) { - esm->SetFocusedContent(nsnull); - } - NS_IF_RELEASE(gLastFocusedContent); - } - - if (focusController) - focusController->SetSuppressFocus(PR_FALSE, - "NS_GOTFOCUS ESM Suppression"); - } - - // Now we should fire the focus event. We fire it on the document, - // then the content node, then the window. - - nsCOMPtr window(mDocument->GetWindow()); - - if (window) { - // We don't want there to be a focused content node while we're - // dispatching the focus event. - - nsCOMPtr currentFocus = mCurrentFocus; - // "leak" this reference, but we take it back later - SetFocusedContent(nsnull); - - nsIMEStateManager::OnChangeFocus(mPresContext, currentFocus); - - nsEvent focusEvent(PR_TRUE, NS_FOCUS_CONTENT); - focusEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - if (gLastFocusedDocument != mDocument) { - FireFocusOrBlurEvent(mDocument, &focusEvent, aPresContext); - if (currentFocus && currentFocus != gLastFocusedContent) { - // Clear the target so that Dispatch can set it back correctly. - focusEvent.target = nsnull; - FireFocusOrBlurEvent(currentFocus, &focusEvent, aPresContext); - } - } - - // Clear the target so that Dispatch can set it back correctly. - focusEvent.target = nsnull; - nsCOMPtr win = do_QueryInterface(window); - FireFocusOrBlurEvent(win, &focusEvent, aPresContext); - - SetFocusedContent(currentFocus); // we kept this reference above - NS_IF_RELEASE(gLastFocusedContent); - gLastFocusedContent = mCurrentFocus; - NS_IF_ADDREF(gLastFocusedContent); - - nsIMEStateManager::OnTextStateFocus(mPresContext, mCurrentFocus); - } - - // Try to keep the focus controllers and the globals in synch - if (gLastFocusedDocument && gLastFocusedDocument != mDocument) { - - nsIFocusController *lastController = nsnull; - nsPIDOMWindow* lastWindow = gLastFocusedDocument->GetWindow(); - if (lastWindow) - lastController = lastWindow->GetRootFocusController(); - - nsIFocusController *nextController = nsnull; - nsPIDOMWindow* nextWindow = mDocument->GetWindow(); - if (nextWindow) - nextController = nextWindow->GetRootFocusController(); - - if (lastController != nextController && lastController && nextController) - lastController->SetActive(PR_FALSE); - } - - NS_IF_RELEASE(gLastFocusedDocument); - gLastFocusedDocument = mDocument; - gLastFocusedPresContextWeak = aPresContext; - NS_IF_ADDREF(gLastFocusedDocument); - } - - ResetBrowseWithCaret(); - } - - break; - - case NS_LOSTFOCUS: - { -#ifdef DEBUG_smaug - printf("nsEventStateManager::PreHandleEvent, NS_LOSTFOCUS \n"); -#endif - userFocus.MaybeSuppress(); - // Hide the caret if it's visible. - if (mPresContext) { - nsIPresShell *presShell = mPresContext->GetPresShell(); - if (presShell) { - nsRefPtr caret; - presShell->GetCaret(getter_AddRefs(caret)); - if (caret) { - PRBool caretVisible = PR_FALSE; - caret->GetCaretVisible(&caretVisible); - if (caretVisible) { - SetContentCaretVisible(presShell, mCurrentFocus, PR_FALSE); - } - } - } - } - - // If focus is going to another mozilla window, we wait for the - // focus event and fire a blur on the old focused content at that time. - // This allows "-moz-user-focus: ignore" to work. - -#if defined(XP_WIN) || defined(XP_OS2) - //XXXsmaug Change all the NS_LOSTFOCUS/GOTFOCUS events to use - // the same event struct type! - if (aEvent->eventStructType == NS_FOCUS_EVENT && - !static_cast(aEvent)->isMozWindowTakingFocus) { - - // This situation occurs when focus goes to a non-gecko child window - // in an embedding application. In this case we do fire a blur - // immediately. - - EnsureDocument(aPresContext); - - if (gLastFocusedContent && !gLastFocusedContent->IsInDoc()) { - NS_RELEASE(gLastFocusedContent); - } - - nsIMEStateManager::OnTextStateBlur(nsnull, nsnull); - - // Now fire blurs. We fire a blur on the focused document, element, - // and window. - nsEvent blurEvent(PR_TRUE, NS_BLUR_CONTENT); - blurEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - if (gLastFocusedDocument && gLastFocusedPresContextWeak) { - if (gLastFocusedContent) { - // Retrieve this content node's pres context. it can be out of sync - // in the Ender widget case. - nsCOMPtr doc = gLastFocusedContent->GetDocument(); - if (doc) { - nsIPresShell *shell = doc->GetPrimaryShell(); - if (shell) { - nsCOMPtr oldPresContext = - shell->GetPresContext(); - - nsCOMPtr esm = - oldPresContext->EventStateManager(); - esm->SetFocusedContent(gLastFocusedContent); - FireFocusOrBlurEvent(gLastFocusedContent, &blurEvent, oldPresContext); - esm->SetFocusedContent(nsnull); - NS_IF_RELEASE(gLastFocusedContent); - } - } - } - - // Clear our global variables before firing the event to prevent - // duplicate blur events (bug 112294). - nsCOMPtr lastFocusedDocument; - lastFocusedDocument.swap(gLastFocusedDocument); - nsCOMPtr lastFocusedPresContext = gLastFocusedPresContextWeak; - gLastFocusedPresContextWeak = nsnull; - mCurrentTarget = nsnull; - - // fire blur on document and window - if (lastFocusedDocument) { - // get the window here, in case the event causes - // gLastFocusedDocument to change. - - nsCOMPtr window(lastFocusedDocument->GetWindow()); - - blurEvent.target = nsnull; - FireFocusOrBlurEvent(lastFocusedDocument, &blurEvent, lastFocusedPresContext); - - if (window) { - blurEvent.target = nsnull; - nsCOMPtr win = do_QueryInterface(window); - FireFocusOrBlurEvent(win, &blurEvent ,lastFocusedPresContext); - } - } - } - } -#endif - } - break; - - case NS_ACTIVATE: - { -#ifdef DEBUG_smaug - printf("nsEventStateManager::PreHandleEvent, NS_ACTIVATE \n"); -#endif - userFocus.MaybeSuppress(); - // If we have a focus controller, and if it has a focused window and a - // focused element in its focus memory, then restore the focus to those - // objects. - - EnsureDocument(aPresContext); - - nsCOMPtr win = mDocument->GetWindow(); - - if (!win) { - // NS_ERROR("win is null. this happens [often on xlib builds]. see bug #79213"); - return NS_ERROR_NULL_POINTER; - } - - // Hold a strong ref to the focus controller, since we need - // it after event dispatch. - nsCOMPtr focusController = - win->GetRootFocusController(); - nsCOMPtr focusedElement; - nsCOMPtr focusedWindow; - nsFocusScrollSuppressor scrollSuppressor; - - if (focusController) { - // Obtain focus info from the focus controller. - focusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); - focusController->GetFocusedElement(getter_AddRefs(focusedElement)); - - scrollSuppressor.Init(focusController); - focusController->SetActive(PR_TRUE); - } - - if (!focusedWindow) - focusedWindow = win; - - NS_ASSERTION(focusedWindow,"check why focusedWindow is null!!!"); - - // Focus the DOM window. - if (focusedWindow) { - focusedWindow->Focus(); - - nsCOMPtr document = GetDocumentFromWindow(focusedWindow); - - if (document) { - // Use a strong ref to make sure that the shell is alive still - // when calling FrameSelection(). - nsCOMPtr shell = document->GetPrimaryShell(); - NS_ASSERTION(shell, "Focus events should not be getting thru when this is null!"); - if (shell) { - nsPresContext* context = shell->GetPresContext(); - nsIMEStateManager::OnActivate(context); - if (focusedElement) { - nsCOMPtr focusContent = do_QueryInterface(focusedElement); - focusContent->SetFocus(context); - } else { - nsIMEStateManager::OnChangeFocus(context, nsnull); - } - - // disable selection mousedown state on activation - nsCOMPtr frameSelection = shell->FrameSelection(); - frameSelection->SetMouseDownState(PR_FALSE); - } - } - } - - if (focusController) { - // Make sure the focus controller is up-to-date, since restoring - // focus memory may have caused focus to go elsewhere. - - if (gLastFocusedDocument && gLastFocusedDocument == mDocument) { - nsCOMPtr focusElement = do_QueryInterface(mCurrentFocus); - focusController->SetFocusedElement(focusElement); - } - - PRBool isSuppressed; - focusController->GetSuppressFocus(&isSuppressed); - while (isSuppressed) { - // Unsuppress and let the focus controller listen again. - focusController->SetSuppressFocus(PR_FALSE, - "Activation Suppression"); - - focusController->GetSuppressFocus(&isSuppressed); - } - } - } - break; - - case NS_DEACTIVATE: - { -#ifdef DEBUG_smaug - printf("nsEventStateManager::PreHandleEvent, NS_DEACTIVATE \n"); -#endif - userFocus.MaybeSuppress(); - EnsureDocument(aPresContext); - - nsIMEStateManager::OnDeactivate(aPresContext); - - nsCOMPtr ourWindow(mDocument->GetWindow()); - - // Suppress the focus controller for the duration of the - // de-activation. This will cause it to remember the last - // focused sub-window and sub-element for this top-level - // window. - - nsCOMPtr focusController = - GetFocusControllerForDocument(mDocument); - - if (focusController) - focusController->SetSuppressFocus(PR_TRUE, "Deactivate Suppression"); - - nsIMEStateManager::OnTextStateBlur(nsnull, nsnull); - - // Now fire blurs. Blur the content, then the document, then the window. - - if (gLastFocusedDocument && gLastFocusedDocument == mDocument && - gLastFocusedDocument != mFirstDocumentBlurEvent) { - - PRBool clearFirstDocumentBlurEvent = PR_FALSE; - if (!mFirstDocumentBlurEvent) { - mFirstDocumentBlurEvent = gLastFocusedDocument; - clearFirstDocumentBlurEvent = PR_TRUE; - } - - nsEvent blurEvent(PR_TRUE, NS_BLUR_CONTENT); - blurEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - if (gLastFocusedContent) { - nsIPresShell *shell = gLastFocusedDocument->GetPrimaryShell(); - if (shell) { - nsCOMPtr oldPresContext = shell->GetPresContext(); - - nsCOMPtr focusedElement; - if (focusController) - focusController->GetFocusedElement(getter_AddRefs(focusedElement)); - - nsCOMPtr esm; - esm = oldPresContext->EventStateManager(); - esm->SetFocusedContent(gLastFocusedContent); - - nsCOMPtr focusedContent = do_QueryInterface(focusedElement); - if (focusedContent) { - // Blur the element. - FireFocusOrBlurEvent(focusedContent, &blurEvent, oldPresContext); - } - - esm->SetFocusedContent(nsnull); - NS_IF_RELEASE(gLastFocusedContent); - } - } - - // Clear our global variables before firing the event to prevent - // duplicate blur events (bug 112294). - mCurrentTarget = nsnull; - NS_IF_RELEASE(gLastFocusedDocument); - gLastFocusedPresContextWeak = nsnull; - - // fire blur on document and window - blurEvent.target = nsnull; - FireFocusOrBlurEvent(mDocument, &blurEvent, aPresContext); - - if (ourWindow) { - blurEvent.target = nsnull; - nsCOMPtr win = do_QueryInterface(ourWindow); - FireFocusOrBlurEvent(win, &blurEvent, aPresContext); - } - if (clearFirstDocumentBlurEvent) { - mFirstDocumentBlurEvent = nsnull; - } - } - - if (focusController) { - focusController->SetActive(PR_FALSE); - focusController->SetSuppressFocus(PR_FALSE, "Deactivate Suppression"); - } - } - - break; case NS_KEY_PRESS: { @@ -1592,16 +1024,16 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, case NS_KEY_DOWN: case NS_KEY_UP: { - if (mCurrentFocus) { - mCurrentTargetContent = mCurrentFocus; - } + nsIContent* content = GetFocusedContent(); + if (content) + mCurrentTargetContent = content; } break; case NS_MOUSE_SCROLL: { - if (mCurrentFocus) { - mCurrentTargetContent = mCurrentFocus; - } + nsIContent* content = GetFocusedContent(); + if (content) + mCurrentTargetContent = content; nsMouseScrollEvent* msEvent = static_cast(aEvent); @@ -1659,9 +1091,9 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, break; case NS_MOUSE_PIXEL_SCROLL: { - if (mCurrentFocus) { - mCurrentTargetContent = mCurrentFocus; - } + nsIContent* content = GetFocusedContent(); + if (content) + mCurrentTargetContent = content; nsMouseScrollEvent *msEvent = static_cast(aEvent); @@ -1845,10 +1277,11 @@ nsEventStateManager::ExecuteAccessKey(nsTArray& aAccessCharCodes, PRBool aIsTrustedEvent) { PRInt32 count, start = -1; - if (mCurrentFocus) { - start = mAccessKeys.IndexOf(mCurrentFocus); - if (start == -1 && mCurrentFocus->GetBindingParent()) - start = mAccessKeys.IndexOf(mCurrentFocus->GetBindingParent()); + nsIContent* focusedContent = GetFocusedContent(); + if (focusedContent) { + start = mAccessKeys.IndexOf(focusedContent); + if (start == -1 && focusedContent->GetBindingParent()) + start = mAccessKeys.IndexOf(focusedContent->GetBindingParent()); } nsIContent *content; nsIFrame *frame; @@ -1870,8 +1303,13 @@ nsEventStateManager::ExecuteAccessKey(nsTArray& aAccessCharCodes, } if (shouldActivate) content->PerformAccesskey(shouldActivate, aIsTrustedEvent); - else if (frame && frame->IsFocusable()) - ChangeFocusWith(content, eEventFocusedByKey); + else { + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) { + nsCOMPtr element = do_QueryInterface(content); + fm->SetFocus(element, nsIFocusManager::FLAG_BYKEY); + } + } return PR_TRUE; } } @@ -2648,9 +2086,13 @@ nsEventStateManager::GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv) { *aMv = nsnull; - if(!gLastFocusedDocument) return NS_ERROR_FAILURE; + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if(!fm) return NS_ERROR_FAILURE; - nsPIDOMWindow* ourWindow = gLastFocusedDocument->GetWindow(); + nsCOMPtr focusedWindow; + fm->GetFocusedWindow(getter_AddRefs(focusedWindow)); + + nsCOMPtr ourWindow = do_QueryInterface(focusedWindow); if(!ourWindow) return NS_ERROR_FAILURE; nsIDOMWindowInternal *rootWindow = ourWindow->GetPrivateRoot(); @@ -2820,7 +2262,7 @@ nsEventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame, { nsCOMPtr targetContent = aTargetFrame->GetContent(); if (!targetContent) - GetFocusedContent(getter_AddRefs(targetContent)); + targetContent = GetFocusedContent(); if (!targetContent) return; @@ -2850,10 +2292,11 @@ nsEventStateManager::SendPixelScrollEvent(nsIFrame* aTargetFrame, nsEventStatus* aStatus) { nsCOMPtr targetContent = aTargetFrame->GetContent(); - if (!targetContent) - GetFocusedContent(getter_AddRefs(targetContent)); - if (!targetContent) - return; + if (!targetContent) { + targetContent = GetFocusedContent(); + if (!targetContent) + return; + } while (targetContent->IsNodeOfType(nsINode::eTEXT)) { targetContent = targetContent->GetParent(); @@ -3140,19 +2583,18 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, if (nsEventStatus_eConsumeNoDefault != *aStatus) { nsCOMPtr newFocus; + nsIContent* activeContent = nsnull; PRBool suppressBlur = PR_FALSE; if (mCurrentTarget) { mCurrentTarget->GetContentForEvent(mPresContext, aEvent, getter_AddRefs(newFocus)); const nsStyleUserInterface* ui = mCurrentTarget->GetStyleUserInterface(); suppressBlur = (ui->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE); + activeContent = mCurrentTarget->GetContent(); } + // When the mouse is pressed, the default action is to focus the + // target. Look for the nearest enclosing focusable frame. nsIFrame* currFrame = mCurrentTarget; - nsIContent* activeContent = nsnull; - if (mCurrentTarget) - activeContent = mCurrentTarget->GetContent(); - - // Look for the nearest enclosing focusable frame. while (currFrame) { // If the mousedown happened inside a popup, don't // try to set focus on one of its containing elements @@ -3172,10 +2614,34 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, currFrame = currFrame->GetParent(); } - if (newFocus && currFrame) - ChangeFocusWith(newFocus, eEventFocusedByMouse); - else if (!suppressBlur) { - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) { + // if something was found to focus, focus it. Otherwise, if the + // element that was clicked doesn't have -moz-user-focus: ignore, + // clear the existing focus. For -moz-user-focus: ignore, the focus + // is just left as is. + // Another effect of mouse clicking, handled in nsSelection, is that + // it should update the caret position to where the mouse was + // clicked. Because the focus is cleared when clicking on a + // non-focusable node, the next press of the tab key will cause + // focus to be shifted from the caret position instead of the root. + if (newFocus && currFrame) { + // use the mouse flag and the noscroll flag so that the content + // doesn't unexpectedly scroll when clicking an element that is + // only hald visible + nsCOMPtr newFocusElement = do_QueryInterface(newFocus); + fm->SetFocus(newFocusElement, nsIFocusManager::FLAG_BYMOUSE | + nsIFocusManager::FLAG_NOSCROLL); + } + else if (!suppressBlur) { + // clear the focus within the frame and then set it as the + // focused frame + EnsureDocument(mPresContext); + if (mDocument) { + fm->ClearFocus(mDocument->GetWindow()); + fm->SetFocusedWindow(mDocument->GetWindow()); + } + } } // The rest is left button-specific. @@ -3452,18 +2918,23 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, if (!keyEvent->isAlt) { switch(keyEvent->keyCode) { case NS_VK_TAB: - if (!((nsInputEvent*)aEvent)->isControl) { - //Shift focus forward or back depending on shift key - ShiftFocus(!((nsInputEvent*)aEvent)->isShift); - } else { - ShiftFocusByDoc(!((nsInputEvent*)aEvent)->isShift); - } - *aStatus = nsEventStatus_eConsumeNoDefault; - break; - case NS_VK_F6: - //Shift focus forward or back depending on shift key - ShiftFocusByDoc(!((nsInputEvent*)aEvent)->isShift); + EnsureDocument(mPresContext); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm && mDocument) { + // Shift focus forward or back depending on shift key + PRBool isDocMove = ((nsInputEvent*)aEvent)->isControl || + (keyEvent->keyCode == NS_VK_F6); + PRUint32 dir = ((nsInputEvent*)aEvent)->isShift ? + (isDocMove ? nsIFocusManager::MOVEFOCUS_BACKWARDDOC : + nsIFocusManager::MOVEFOCUS_BACKWARD) : + (isDocMove ? nsIFocusManager::MOVEFOCUS_FORWARDDOC : + nsIFocusManager::MOVEFOCUS_FORWARD); + nsCOMPtr result; + fm->MoveFocus(mDocument->GetWindow(), nsnull, dir, + nsIFocusManager::FLAG_BYKEY, + getter_AddRefs(result)); + } *aStatus = nsEventStatus_eConsumeNoDefault; break; @@ -3471,7 +2942,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, #if NON_KEYBINDING case NS_VK_PAGE_DOWN: case NS_VK_PAGE_UP: - if (!mCurrentFocus) { + if (!focusedContent) { nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical); if (sv) { nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent; @@ -3482,7 +2953,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, break; case NS_VK_HOME: case NS_VK_END: - if (!mCurrentFocus) { + if (!focusedContent) { nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical); if (sv) { nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent; @@ -3492,7 +2963,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, break; case NS_VK_DOWN: case NS_VK_UP: - if (!mCurrentFocus) { + if (!focusedContent) { nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical); if (sv) { nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent; @@ -3512,7 +2983,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, break; case NS_VK_LEFT: case NS_VK_RIGHT: - if (!mCurrentFocus) { + if (!focusedContent) { nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eHorizontal); if (sv) { nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent; @@ -3535,7 +3006,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, //Spacebar nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent; if (keyEvent->charCode == 0x20) { - if (!mCurrentFocus) { + if (!focusedContent) { nsIScrollableView* sv = nsLayoutUtils::GetNearestScrollingView(aView, nsLayoutUtils::eVertical); if (sv) { sv->ScrollByPages(0, 1, NS_VMREFRESH_SMOOTHSCROLL); @@ -3576,16 +3047,6 @@ nsEventStateManager::NotifyDestroyPresContext(nsPresContext* aPresContext) NS_IMETHODIMP nsEventStateManager::SetPresContext(nsPresContext* aPresContext) { - if (aPresContext == nsnull) { - // XXX should we move this block to |NotifyDestroyPresContext|? - // A pres context is going away. Make sure we do cleanup. - if (mPresContext == gLastFocusedPresContextWeak) { - gLastFocusedPresContextWeak = nsnull; - NS_IF_RELEASE(gLastFocusedDocument); - NS_IF_RELEASE(gLastFocusedContent); - } - } - mPresContext = aPresContext; return NS_OK; } @@ -4256,625 +3717,6 @@ nsEventStateManager::CheckForAndDispatchClick(nsPresContext* aPresContext, return ret; } -NS_IMETHODIMP -nsEventStateManager::ChangeFocusWith(nsIContent* aFocusContent, - EFocusedWithType aFocusedWith) -{ - mLastFocusedWith = aFocusedWith; - if (!aFocusContent) { - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - return NS_OK; - } - - // Get focus controller. - EnsureDocument(mPresContext); - nsCOMPtr focusController = nsnull; - nsCOMPtr window(mDocument->GetWindow()); - if (window) - focusController = window->GetRootFocusController(); - - // If this is called from mouse event, we lock to scroll. - // Because the part of element is always in view. See bug 105894. - nsFocusScrollSuppressor scrollSuppressor; - if (aFocusedWith == eEventFocusedByMouse) { - scrollSuppressor.Init(focusController); - } - - aFocusContent->SetFocus(mPresContext); - if (aFocusedWith != eEventFocusedByMouse) { - MoveCaretToFocus(); - // Select text fields when focused via keyboard (tab or accesskey) - if (sTextfieldSelectModel == eTextfieldSelect_auto && - mCurrentFocus && - mCurrentFocus->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) { - nsCOMPtr formControl(do_QueryInterface(mCurrentFocus)); - PRInt32 controlType = formControl->GetType(); - if (controlType == NS_FORM_INPUT_TEXT || - controlType == NS_FORM_INPUT_PASSWORD) { - nsCOMPtr inputElement = - do_QueryInterface(mCurrentFocus); - if (inputElement) { - inputElement->Select(); - } - } - } - } - return NS_OK; -} - - -NS_IMETHODIMP -nsEventStateManager::ShiftFocus(PRBool aForward, nsIContent* aStart) -{ - nsCOMPtr lookNFeel(do_GetService(kLookAndFeelCID)); - lookNFeel->GetMetric(nsILookAndFeel::eMetric_TabFocusModel, - nsIContent::sTabFocusModel); - - // We use mTabbedThroughDocument to indicate that we have passed - // the end (or beginning) of the document we started tabbing from, - // without finding anything else to focus. If we pass the end of - // the same document again (and the flag is set), we know that there - // is no focusable content anywhere in the tree, and should stop. - - mTabbedThroughDocument = PR_FALSE; - return ShiftFocusInternal(aForward, aStart); -} - -nsresult -nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart) -{ -#ifdef DEBUG_DOCSHELL_FOCUS - printf("[%p] ShiftFocusInternal: aForward=%d, aStart=%p, mCurrentFocus=%p\n", - static_cast(this), aForward, static_cast(aStart), - static_cast(mCurrentFocus.get())); -#endif - NS_ASSERTION(mPresContext, "no pres context"); - EnsureDocument(mPresContext); - NS_ASSERTION(mDocument, "no document"); - - nsCOMPtr rootContent = mDocument->GetRootContent(); - - nsCOMPtr pcContainer = mPresContext->GetContainer(); - nsCOMPtr docShell(do_QueryInterface(pcContainer)); - NS_ENSURE_STATE(docShell); - PRBool docHasFocus = PR_FALSE; - - // ignoreTabIndex allows the user to tab to the next link after clicking before it link in the page - // or using find text to get to the link. Without ignoreTabIndex in those cases, pages that - // use tabindex would still enforce that order in those situations. - PRBool ignoreTabIndex = PR_FALSE; - - if (!aStart && !mCurrentFocus) { - // mCurrentFocus is ambiguous for determining whether - // we're in document-focus mode, because it's nulled out - // when the document is blurred, and it's also nulled out - // when the document/canvas has focus. - // - // So, use the docshell focus state to disambiguate. - - docShell->GetHasFocus(&docHasFocus); - } - - nsIFrame* selectionFrame = nsnull; - nsIFrame* curFocusFrame = nsnull; // This will hold the location we're moving away from - - // If in content, navigate from last cursor position rather than last focus - // If we're in UI, selection location will return null - nsCOMPtr presShell = mPresContext->PresShell(); - - // We might use the selection position, rather than mCurrentFocus, as our position to shift focus from - PRInt32 itemType; - nsCOMPtr shellItem(do_QueryInterface(docShell)); - shellItem->GetItemType(&itemType); - - // Tab from the selection if it exists, but not if we're in chrome or an explicit starting - // point was given. - if (!aStart && itemType != nsIDocShellTreeItem::typeChrome) { - // We're going to tab from the selection position - if (!mCurrentFocus || (mLastFocusedWith != eEventFocusedByMouse && mCurrentFocus->Tag() != nsGkAtoms::area)) { - nsCOMPtr selectionContent, endSelectionContent; // We won't be using this, need arg for method call - PRUint32 selectionOffset; // We won't be using this either, need arg for method call - GetDocSelectionLocation(getter_AddRefs(selectionContent), getter_AddRefs(endSelectionContent), &selectionFrame, &selectionOffset); - if (selectionContent == rootContent) // If selection on rootContent, same as null -- we have no selection yet - selectionFrame = nsnull; - // Don't start from the selection if the selection is in a contentEditable - // region. - nsCOMPtr htmlDoc = do_QueryInterface(mDocument); - if (htmlDoc && - htmlDoc->GetEditingState() == nsIHTMLDocument::eContentEditable && - selectionContent && selectionContent->HasFlag(NODE_IS_EDITABLE)) - selectionFrame = nsnull; - // Only use tabindex if selection is synchronized with focus - // That way, if the user clicks in content, or does a find text that lands between focusable elements, - // they can then tab relative to that selection - if (selectionFrame) { - PRBool selectionWithFocus; - MoveFocusToCaret(PR_FALSE, &selectionWithFocus); - ignoreTabIndex = !selectionWithFocus; - // Refresh |selectionFrame| since MoveFocusToCaret() could have - // destroyed it. (bug 308086) - GetDocSelectionLocation(getter_AddRefs(selectionContent), - getter_AddRefs(endSelectionContent), - &selectionFrame, &selectionOffset); - } - } - } - - nsIContent *startContent = nsnull; - - if (aStart) { - curFocusFrame = presShell->GetPrimaryFrameFor(aStart); - - // If there is no frame, we can't navigate from this content node, and we - // fall back to navigating from the document root. - if (curFocusFrame) - startContent = aStart; - } else if (selectionFrame) { - // We moved focus to the caret location above, so mCurrentFocus - // reflects the starting content node. - startContent = mCurrentFocus; - curFocusFrame = selectionFrame; - } else if (!docHasFocus) { - startContent = mCurrentFocus; - GetFocusedFrame(&curFocusFrame); - } - - if (aStart) { - if (aStart->HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) { - aStart->IsFocusable(&mCurrentTabIndex); - } else { - ignoreTabIndex = PR_TRUE; // ignore current tabindex, bug 81481 - } - } else if (!mCurrentFocus) { // Get tabindex ready - if (aForward) { - mCurrentTabIndex = docHasFocus && selectionFrame ? 0 : 1; - } else if (!docHasFocus) { - mCurrentTabIndex = 0; - } else if (selectionFrame) { - mCurrentTabIndex = 1; // will keep it from wrapping around to end - } - } - - // when a popup is open, we want to ensure that tab navigation occurs only - // within the most recently opened panel. If a popup is open, its frame will - // be stored in popupFrame. - nsIFrame* popupFrame = nsnull; - if (curFocusFrame) { - // check if the focus is currently inside a popup. Elements such as the - // autocomplete widget use the noautofocus attribute to allow the focus to - // remain outside the popup when it is opened. - popupFrame = nsLayoutUtils::GetClosestFrameOfType(curFocusFrame, - nsGkAtoms::menuPopupFrame); - } -#ifdef MOZ_XUL - else { - // if there is no focus, yet a panel is open, focus the - // first item in the popup - nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); - if (pm) { - popupFrame = pm->GetTopPopup(ePopupTypePanel); - } - } -#endif - - if (popupFrame) { - // Don't navigate outside of a popup, so pretend that the - // root content is the popup itself - rootContent = popupFrame->GetContent(); - NS_ASSERTION(rootContent, "Popup frame doesn't have a content node"); - } - - nsCOMPtr nextFocus; - nsIFrame* nextFocusFrame; - if (aForward || !docHasFocus || selectionFrame) - GetNextTabbableContent(rootContent, startContent, curFocusFrame, - aForward, ignoreTabIndex || mCurrentTabIndex < 0, - getter_AddRefs(nextFocus), &nextFocusFrame); - - if (popupFrame && !nextFocus) { - // if no content was found to focus, yet we are inside a popup, try again - // from the beginning or end of the popup. Set the current tab index to - // the beginning or end. - mCurrentTabIndex = aForward ? 1 : 0; - GetNextTabbableContent(rootContent, rootContent, nsnull, - aForward, ignoreTabIndex, - getter_AddRefs(nextFocus), &nextFocusFrame); - // if the same node was found, don't change the focus - if (startContent == nextFocus) { - nextFocus = nsnull; - } - } - - // Clear out mCurrentTabIndex. It has a garbage value because of GetNextTabbableContent()'s side effects - // It will be set correctly when focus is changed via ChangeFocusWith() - mCurrentTabIndex = 0; - - if (nextFocus) { - // Check to see if the next focused element has a subshell. - // This is the case for an IFRAME or FRAME element. If it - // does, we send focus into the subshell. - - nsCOMPtr sub_shell; - nsCOMPtr doc = nextFocus->GetDocument(); - - if (doc) { - nsIDocument *sub_doc = doc->GetSubDocumentFor(nextFocus); - - if (sub_doc && !sub_doc->EventHandlingSuppressed()) { - nsCOMPtr container = sub_doc->GetContainer(); - sub_shell = do_QueryInterface(container); - } - } - - if (sub_shell) { - // Make sure to scroll before possibly dispatching focus/blur events. - presShell->ScrollContentIntoView(nextFocus, - NS_PRESSHELL_SCROLL_ANYWHERE, - NS_PRESSHELL_SCROLL_ANYWHERE); - - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - - // if we are in the middle of tabbing into - // sub_shell, bail out, to avoid recursion - // see bug #195011 and bug #137191 - if (mTabbingFromDocShells.IndexOf(sub_shell) != -1) - return NS_OK; - - TabIntoDocument(sub_shell, aForward); - } else { - // there is no subshell, so just focus nextFocus -#ifdef DEBUG_DOCSHELL_FOCUS - printf("focusing next focusable content: %p\n", - static_cast(nextFocus.get())); -#endif - mCurrentTarget = nextFocusFrame; - - nsCOMPtr oldFocus(mCurrentFocus); - ChangeFocusWith(nextFocus, eEventFocusedByKey); - if (!mCurrentFocus && oldFocus) { - // ChangeFocusWith failed to move focus to nextFocus because a blur handler - // made it unfocusable. (bug #118685) - // Try again unless it's from the same point, bug 232368. - if (oldFocus != aStart && oldFocus->GetDocument()) { - mCurrentTarget = nsnull; - return ShiftFocusInternal(aForward, oldFocus); - } else { - return NS_OK; - } - } else { - if (mCurrentFocus != nextFocus) { - // A focus or blur handler switched the focus from one of - // its focus/blur/change handlers, don't mess with what the - // page wanted... - - return NS_OK; - } - nsIFrame* focusedFrame = nsnull; - GetFocusedFrame(&focusedFrame); - mCurrentTarget = focusedFrame; - } - - // It's possible that the act of removing focus from our previously - // focused element caused nextFocus to be removed from the document. - // In this case, we can restart the frame traversal from our previously - // focused content. - - if (oldFocus && doc != nextFocus->GetDocument()) { - mCurrentTarget = nsnull; - return ShiftFocusInternal(aForward, oldFocus); - } - - if (!docHasFocus) - docShell->SetHasFocus(PR_TRUE); - } - } else { - - // If we're going backwards past the first content, - // focus the document. - - PRBool focusDocument; - if (itemType == nsIDocShellTreeItem::typeChrome) - focusDocument = PR_FALSE; - else { - // Check for a frameset document - focusDocument = !(IsFrameSetDoc(docShell)); - } - - if (!aForward && !docHasFocus && focusDocument) { -#ifdef DEBUG_DOCSHELL_FOCUS - printf("Focusing document\n"); -#endif - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - docShell->SetHasFocus(PR_TRUE); - docShell->SetCanvasHasFocus(PR_TRUE); - // Next time forward we start at the beginning of the document - // Next time backward we go to URL bar - // We need to move the caret to the document root, so that we don't - // tab from the most recently focused element next time around - SetFocusedContent(rootContent); - MoveCaretToFocus(); - SetFocusedContent(nsnull); - - } else { - // If there's nothing left to focus in this document, - // pop out to our parent document, and have it shift focus - // in the same direction starting at the content element - // corresponding to our docshell. - // Guard against infinite recursion (see explanation in ShiftFocus) - - if (mTabbedThroughDocument) - return NS_OK; - - SetFocusedContent(rootContent); - mCurrentTabIndex = 0; - MoveCaretToFocus(); - SetFocusedContent(nsnull); - - mTabbedThroughDocument = PR_TRUE; - - nsCOMPtr treeItem = do_QueryInterface(pcContainer); - nsCOMPtr treeParent; - treeItem->GetParent(getter_AddRefs(treeParent)); - if (treeParent) { - nsCOMPtr parentDS = do_QueryInterface(treeParent); - if (parentDS) { - nsCOMPtr parentShell; - parentDS->GetPresShell(getter_AddRefs(parentShell)); - - nsCOMPtr parent_doc = parentShell->GetDocument(); - nsCOMPtr docContent = parent_doc->FindContentForSubDocument(mDocument); - - nsCOMPtr parentPC = parentShell->GetPresContext(); - nsIEventStateManager *parentESM = parentPC->EventStateManager(); - - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - - nsCOMPtr parentContainer = parentPC->GetContainer(); - if (parentContainer && docContent && docContent->GetCurrentDoc() == parent_doc) { -#ifdef DEBUG_DOCSHELL_FOCUS - printf("popping out focus to parent docshell\n"); -#endif - parentESM->MoveCaretToFocus(); - parentESM->ShiftFocus(aForward, docContent); -#ifdef DEBUG_DOCSHELL_FOCUS - } else { - printf("can't pop out focus to parent docshell\n"); // bug 308025 -#endif - } - } - } else { - PRBool tookFocus = PR_FALSE; - nsCOMPtr subShell = do_QueryInterface(pcContainer); - if (subShell) { - subShell->TabToTreeOwner(aForward, &tookFocus); - } - -#ifdef DEBUG_DOCSHEL_FOCUS - printf("offered focus to tree owner, tookFocus=%d\n", - tookFocus); -#endif - - if (tookFocus) { - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - docShell->SetHasFocus(PR_FALSE); - } else { - // there is nowhere else to send the focus, so - // refocus ourself. - // Next time forward we start at the beginning of the document - -#ifdef DEBUG_DOCSHELL_FOCUS - printf("wrapping around within this document\n"); -#endif - - SetFocusedContent(nsnull); - docShell->SetHasFocus(PR_FALSE); - ShiftFocusInternal(aForward); - } - } - } - } - - return NS_OK; -} - -nsresult -nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, - nsIContent* aStartContent, - nsIFrame* aStartFrame, - PRBool forward, - PRBool aIgnoreTabIndex, - nsIContent** aResultNode, - nsIFrame** aResultFrame) -{ - *aResultNode = nsnull; - *aResultFrame = nsnull; - - nsresult rv; - nsCOMPtr trav(do_CreateInstance(kFrameTraversalCID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr frameTraversal; - - // --- Get frame to start with --- - if (!aStartFrame) { - // No frame means we need to start with the root content again. - NS_ENSURE_TRUE(mPresContext, NS_ERROR_FAILURE); - nsIPresShell *presShell = mPresContext->GetPresShell(); - NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); - aStartFrame = presShell->GetPrimaryFrameFor(aRootContent); - NS_ENSURE_TRUE(aStartFrame, NS_ERROR_FAILURE); - rv = trav->NewFrameTraversal(getter_AddRefs(frameTraversal), - mPresContext, aStartFrame, - ePreOrder, - PR_FALSE, // aVisual - PR_FALSE, // aLockInScrollView - PR_TRUE // aFollowOOFs - ); - NS_ENSURE_SUCCESS(rv, rv); - if (!forward) { - frameTraversal->Last(); - } - } - else { - rv = trav->NewFrameTraversal(getter_AddRefs(frameTraversal), - mPresContext, aStartFrame, - ePreOrder, - PR_FALSE, // aVisual - PR_FALSE, // aLockInScrollView - PR_TRUE // aFollowOOFs - ); - NS_ENSURE_SUCCESS(rv, rv); - if (!aStartContent || aStartContent->Tag() != nsGkAtoms::area || - !aStartContent->IsNodeOfType(nsINode::eHTML)) { - // Need to do special check in case we're in an imagemap which has multiple - // content per frame, so don't skip over the starting frame. - if (forward) - frameTraversal->Next(); - else - frameTraversal->Prev(); - } - } - - // -- Walk frames to find something tabbable matching mCurrentTabIndex -- - while (1) { - *aResultFrame = frameTraversal->CurrentItem(); - if (!*aResultFrame) { - break; - } - - // TabIndex not set defaults to 0 for form elements, anchors and other - // elements that are normally focusable. Tabindex defaults to -1 - // for elements that are not normally focusable. - // The returned computed tabindex from IsFocusable() is as follows: - // < 0 not tabbable at all - // == 0 in normal tab order (last after positive tabindex'd items) - // > 0 can be tabbed to in the order specified by this value - PRInt32 tabIndex; - nsIContent* currentContent = (*aResultFrame)->GetContent(); - (*aResultFrame)->IsFocusable(&tabIndex); - if (tabIndex >= 0) { - if (currentContent->Tag() == nsGkAtoms::img && - currentContent->HasAttr(kNameSpaceID_None, nsGkAtoms::usemap)) { - // Must be an image w/ a map -- it's tabbable but no tabindex is specified - // Special case for image maps: they don't get walked by nsIFrameTraversal - nsIContent *areaContent = GetNextTabbableMapArea(forward, currentContent); - if (areaContent) { - NS_ADDREF(*aResultNode = areaContent); - return NS_OK; - } - } - else if ((aIgnoreTabIndex || mCurrentTabIndex == tabIndex) && - currentContent != aStartContent) { - NS_ADDREF(*aResultNode = currentContent); - return NS_OK; - } - } - if (forward) - frameTraversal->Next(); - else - frameTraversal->Prev(); - } - - // -- Reached end or beginning of document -- - - // If already at lowest priority tab (0), end search completely. - // A bit counterintuitive but true, tabindex order goes 1, 2, ... 32767, 0 - if (mCurrentTabIndex == (forward? 0: 1)) { - return NS_OK; - } - - // else continue looking for next highest priority tabindex - mCurrentTabIndex = GetNextTabIndex(aRootContent, forward); - return GetNextTabbableContent(aRootContent, aStartContent, nsnull, forward, - aIgnoreTabIndex, aResultNode, aResultFrame); -} - -nsIContent* -nsEventStateManager::GetNextTabbableMapArea(PRBool aForward, - nsIContent *aImageContent) -{ - nsAutoString useMap; - aImageContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, useMap); - - nsCOMPtr doc = aImageContent->GetDocument(); - if (doc) { - nsCOMPtr imageMap = nsImageMapUtils::FindImageMap(doc, useMap); - if (!imageMap) - return nsnull; - nsCOMPtr mapContent = do_QueryInterface(imageMap); - PRUint32 count = mapContent->GetChildCount(); - // First see if mCurrentFocus is in this map - PRInt32 index = mapContent->IndexOf(mCurrentFocus); - PRInt32 tabIndex; - if (index < 0 || (mCurrentFocus->IsFocusable(&tabIndex) && - tabIndex != mCurrentTabIndex)) { - // If mCurrentFocus is in this map we must start iterating past it. - // We skip the case where mCurrentFocus has tabindex == mCurrentTabIndex - // since the next tab ordered element might be before it - // (or after for backwards) in the child list. - index = aForward ? -1 : (PRInt32)count; - } - - // GetChildAt will return nsnull if our index < 0 or index >= count - nsCOMPtr areaContent; - while ((areaContent = mapContent->GetChildAt(aForward? ++index : --index)) != nsnull) { - if (areaContent->IsFocusable(&tabIndex) && tabIndex == mCurrentTabIndex) { - return areaContent; - } - } - } - - return nsnull; -} - -PRInt32 -nsEventStateManager::GetNextTabIndex(nsIContent* aParent, PRBool forward) -{ - PRInt32 tabIndex, childTabIndex; - nsIContent *child; - - PRUint32 count = aParent->GetChildCount(); - - if (forward) { - tabIndex = 0; - for (PRUint32 index = 0; index < count; index++) { - child = aParent->GetChildAt(index); - childTabIndex = GetNextTabIndex(child, forward); - if (childTabIndex > mCurrentTabIndex && childTabIndex != tabIndex) { - tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex; - } - - nsAutoString tabIndexStr; - child->GetAttr(kNameSpaceID_None, nsGkAtoms::tabindex, tabIndexStr); - PRInt32 ec, val = tabIndexStr.ToInteger(&ec); - if (NS_SUCCEEDED (ec) && val > mCurrentTabIndex && val != tabIndex) { - tabIndex = (tabIndex == 0 || val < tabIndex) ? val : tabIndex; - } - } - } - else { /* !forward */ - tabIndex = 1; - for (PRUint32 index = 0; index < count; index++) { - child = aParent->GetChildAt(index); - childTabIndex = GetNextTabIndex(child, forward); - if ((mCurrentTabIndex == 0 && childTabIndex > tabIndex) || - (childTabIndex < mCurrentTabIndex && childTabIndex > tabIndex)) { - tabIndex = childTabIndex; - } - - nsAutoString tabIndexStr; - child->GetAttr(kNameSpaceID_None, nsGkAtoms::tabindex, tabIndexStr); - PRInt32 ec, val = tabIndexStr.ToInteger(&ec); - if (NS_SUCCEEDED (ec)) { - if ((mCurrentTabIndex == 0 && val > tabIndex) || - (val < mCurrentTabIndex && val > tabIndex) ) { - tabIndex = val; - } - } - } - } - return tabIndex; -} - NS_IMETHODIMP nsEventStateManager::GetEventTarget(nsIFrame **aFrame) { @@ -4907,8 +3749,7 @@ nsEventStateManager::GetEventTargetContent(nsEvent* aEvent, if (aEvent && (aEvent->message == NS_FOCUS_CONTENT || aEvent->message == NS_BLUR_CONTENT)) { - *aContent = mCurrentFocus; - NS_IF_ADDREF(*aContent); + NS_IF_ADDREF(*aContent = GetFocusedContent()); return NS_OK; } @@ -4958,8 +3799,15 @@ nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState) } } - if (aContent == mCurrentFocus) { - aState |= NS_EVENT_STATE_FOCUS; + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) { + nsCOMPtr focusedElement; + fm->GetFocusedElement(getter_AddRefs(focusedElement)); + + nsCOMPtr focusedContent = do_QueryInterface(focusedElement); + if (aContent == focusedContent) { + aState |= NS_EVENT_STATE_FOCUS; + } } if (aContent == mDragOverContent) { aState |= NS_EVENT_STATE_DRAGOVER; @@ -5033,8 +3881,6 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState) return PR_FALSE; } - PRBool didContentChangeAllStates = PR_TRUE; - if ((aState & NS_EVENT_STATE_DRAGOVER) && (aContent != mDragOverContent)) { notifyContent[3] = mDragOverContent; // notify dragover first, since more common case NS_IF_ADDREF(notifyContent[3]); @@ -5079,58 +3925,8 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState) } if ((aState & NS_EVENT_STATE_FOCUS)) { - EnsureDocument(mPresContext); - nsIMEStateManager::OnChangeFocus(mPresContext, aContent); - if (aContent && (aContent == mCurrentFocus) && gLastFocusedDocument == mDocument) { - // gLastFocusedDocument appears to always be correct, that is why - // I'm not setting it here. This is to catch an edge case. - NS_IF_RELEASE(gLastFocusedContent); - gLastFocusedContent = mCurrentFocus; - NS_IF_ADDREF(gLastFocusedContent); - //If this notification was for focus alone then get rid of aContent - //ref to avoid unnecessary notification. - if (!(aState & ~NS_EVENT_STATE_FOCUS)) { - aContent = nsnull; - } - } else { - // see comments in ShiftFocusInternal on mCurrentFocus overloading - PRBool fcActive = PR_FALSE; - if (mDocument) { - nsIFocusController *fc = GetFocusControllerForDocument(mDocument); - if (fc) - fc->GetActive(&fcActive); - } - notifyContent[2] = gLastFocusedContent; - NS_IF_ADDREF(gLastFocusedContent); - // only raise window if the the focus controller is active - SendFocusBlur(mPresContext, aContent, fcActive); - if (mCurrentFocus != aContent) { - didContentChangeAllStates = PR_FALSE; - } - -#ifdef DEBUG_aleventhal - nsPIDOMWindow *currentWindow = mDocument->GetWindow(); - if (currentWindow) { - nsIFocusController *fc = currentWindow->GetRootFocusController(); - if (fc) { - nsCOMPtr focusedElement; - fc->GetFocusedElement(getter_AddRefs(focusedElement)); - if (!SameCOMIdentity(mCurrentFocus, focusedElement)) { - printf("\n\nFocus out of whack!!!\n\n"); - } - } - } -#endif - // If we now have focused content, ensure that the canvas focus ring - // is removed. - if (mDocument) { - nsCOMPtr docShell = - do_QueryInterface(nsCOMPtr(mDocument->GetContainer())); - - if (docShell && mCurrentFocus) - docShell->SetCanvasHasFocus(PR_FALSE); - } - } + notifyContent[2] = aContent; + NS_IF_ADDREF(notifyContent[2]); } PRInt32 simpleStates = aState & ~(NS_EVENT_STATE_ACTIVE|NS_EVENT_STATE_HOVER); @@ -5270,400 +4066,17 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState) } } - return didContentChangeAllStates; -} - -static PRBool -IsFocusable(nsIPresShell* aPresShell, nsIContent* aContent) -{ - // Flush pending updates to the frame tree first (bug 305840). - aPresShell->FlushPendingNotifications(Flush_Frames); - - nsIFrame* focusFrame = aPresShell->GetPrimaryFrameFor(aContent); - if (!focusFrame) { - return PR_FALSE; - } - - // XUL frames in general have a somewhat confusing notion of - // focusability so we only require a visible frame and that - // the content is focusable (not disabled). - // We don't use nsIFrame::IsFocusable() because it defaults - // tabindex to -1 for -moz-user-focus:ignore (bug 305840). - if (aContent->IsNodeOfType(nsINode::eXUL)) { - // XXX Eventually we should have a better check, but for - // now checking for style visibility and focusability caused - // too many regressions. - return focusFrame->AreAncestorViewsVisible(); - } - - if (aContent->Tag() != nsGkAtoms::area) { - return focusFrame->IsFocusable(); - } - // HTML areas do not have their own frame, and the img frame we get from - // GetPrimaryFrameFor() is not relevant to whether it is focusable or not, - // so we have to do all the relevant checks manually for them. - return focusFrame->AreAncestorViewsVisible() && - focusFrame->GetStyleVisibility()->IsVisible() && - aContent->IsFocusable(); -} - -nsresult -nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext, - nsIContent *aContent, - PRBool aEnsureWindowHasFocus) -{ - // Keep a ref to presShell since dispatching the DOM event may cause - // the document to be destroyed. - nsCOMPtr presShell = aPresContext->GetPresShell(); - if (!presShell) - return NS_OK; - - nsCOMPtr previousFocus = mCurrentFocus; - - // Make sure previousFocus is in a document. If it's not, then - // we should never abort firing events based on what happens when we - // send it a blur. - - if (previousFocus && !previousFocus->GetDocument()) - previousFocus = nsnull; - - // Track the old focus controller if any focus suppressions is used on it. - nsFocusSuppressor oldFocusSuppressor; - - nsIMEStateManager::OnTextStateBlur(aPresContext, aContent); - - if (nsnull != gLastFocusedPresContextWeak) { - - nsCOMPtr focusAfterBlur; - - if (gLastFocusedContent && gLastFocusedContent != mFirstBlurEvent) { - - //Store the first blur event we fire and don't refire blur - //to that element while the first blur is still ongoing. - PRBool clearFirstBlurEvent = PR_FALSE; - if (!mFirstBlurEvent) { - mFirstBlurEvent = gLastFocusedContent; - clearFirstBlurEvent = PR_TRUE; - } - - // Retrieve this content node's pres context. it can be out of sync in - // the Ender widget case. - nsCOMPtr doc = gLastFocusedContent->GetDocument(); - if (doc) { - // The order of the nsIViewManager and nsIPresShell COM pointers is - // important below. We want the pres shell to get released before the - // associated view manager on exit from this function. - // See bug 53763. - nsCOMPtr kungFuDeathGrip; - nsIPresShell *shell = doc->GetPrimaryShell(); - if (shell) { - kungFuDeathGrip = shell->GetViewManager(); - - nsCOMPtr oldPresContext = shell->GetPresContext(); - - //fire blur - nsEvent blurEvent(PR_TRUE, NS_BLUR_CONTENT); - blurEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - EnsureDocument(presShell); - - // Make sure we're not switching command dispatchers, if so, - // surpress the blurred one - if(gLastFocusedDocument && mDocument) { - nsPIDOMWindow *newWindow = mDocument->GetWindow(); - if (newWindow) { - nsIFocusController *newFocusController = - newWindow->GetRootFocusController(); - nsPIDOMWindow *oldWindow = gLastFocusedDocument->GetWindow(); - if (oldWindow) { - nsIFocusController *suppressed = - oldWindow->GetRootFocusController(); - - if (suppressed != newFocusController) { - oldFocusSuppressor.Suppress(suppressed, "SendFocusBlur Window Switch #1"); - } - } - } - } - - nsCOMPtr esm; - esm = oldPresContext->EventStateManager(); - esm->SetFocusedContent(gLastFocusedContent); - nsCOMPtr temp = gLastFocusedContent; - NS_RELEASE(gLastFocusedContent); // nulls out gLastFocusedContent - - nsCxPusher pusher; - if (pusher.Push(temp)) { - FireFocusOrBlurEvent(temp, &blurEvent, oldPresContext); - pusher.Pop(); - } - - focusAfterBlur = mCurrentFocus; - if (!previousFocus || previousFocus == focusAfterBlur) - esm->SetFocusedContent(nsnull); - } - } - - if (clearFirstBlurEvent) { - mFirstBlurEvent = nsnull; - } - - if (previousFocus && previousFocus != focusAfterBlur) { - // The content node's blur handler focused something else. - // In this case, abort firing any more blur or focus events. - EnsureFocusSynchronization(); - return NS_OK; - } - } - - // Go ahead and fire a blur on the window. - nsCOMPtr window; - - if(gLastFocusedDocument) - window = gLastFocusedDocument->GetWindow(); - - EnsureDocument(presShell); - - if (gLastFocusedDocument && (gLastFocusedDocument != mDocument) && - window) { - nsEvent blurEvent(PR_TRUE, NS_BLUR_CONTENT); - blurEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - // Make sure we're not switching command dispatchers, if so, - // suppress the blurred one if it isn't already suppressed - if (mDocument && !oldFocusSuppressor.Suppressing()) { - nsCOMPtr newWindow(mDocument->GetWindow()); - - if (newWindow) { - nsCOMPtr oldWindow(gLastFocusedDocument->GetWindow()); - nsIFocusController *newFocusController = - newWindow->GetRootFocusController(); - if (oldWindow) { - nsIFocusController *suppressed = - oldWindow->GetRootFocusController(); - if (suppressed != newFocusController) { - oldFocusSuppressor.Suppress(suppressed, "SendFocusBlur Window Switch #2"); - } - } - } - } - - gLastFocusedPresContextWeak->EventStateManager()->SetFocusedContent(nsnull); - nsCOMPtr temp = gLastFocusedDocument; - NS_RELEASE(gLastFocusedDocument); - gLastFocusedDocument = nsnull; - - nsCxPusher pusher; - if (pusher.Push(temp)) { - FireFocusOrBlurEvent(temp, &blurEvent, gLastFocusedPresContextWeak); - pusher.Pop(); - } - - if (previousFocus && mCurrentFocus != previousFocus) { - // The document's blur handler focused something else. - // Abort firing any additional blur or focus events, and make sure - // nsFocusController:mFocusedElement is not nulled out, but agrees - // with our current concept of focus. - EnsureFocusSynchronization(); - return NS_OK; - } - - nsCOMPtr target = do_QueryInterface(window); - if (pusher.Push(target)) { - blurEvent.target = nsnull; - FireFocusOrBlurEvent(target, &blurEvent, gLastFocusedPresContextWeak); - - if (previousFocus && mCurrentFocus != previousFocus) { - // The window's blur handler focused something else. - // Abort firing any additional blur or focus events. - EnsureFocusSynchronization(); - return NS_OK; - } - } - } - } - - // Check if the nsEventDispatcher::Dispatch calls above destroyed our frame - // (bug #118685) or made it not focusable in any way. - if (aContent && !::IsFocusable(presShell, aContent)) { - aContent = nsnull; - } - - NS_IF_RELEASE(gLastFocusedContent); - gLastFocusedContent = aContent; - NS_IF_ADDREF(gLastFocusedContent); - SetFocusedContent(aContent); - EnsureFocusSynchronization(); - - // Moved widget focusing code here, from end of SendFocusBlur - // This fixes the order of accessibility focus events, so that - // the window focus event goes first, and then the focus event for the control - if (aEnsureWindowHasFocus) { - nsCOMPtr widget; - // Plug-ins with native widget need a special handling - nsIFrame* currentFocusFrame = nsnull; - if (mCurrentFocus) - currentFocusFrame = presShell->GetPrimaryFrameFor(mCurrentFocus); - if (!currentFocusFrame) - currentFocusFrame = mCurrentTarget; - nsIObjectFrame* objFrame = do_QueryFrame(currentFocusFrame); - if (objFrame) { - nsIView* view = currentFocusFrame->GetViewExternal(); - NS_ASSERTION(view, "Object frames must have views"); - widget = view->GetWidget(); - } - if (!widget) { - // This raises the window that has both content and scroll bars in it - // instead of the child window just below it that contains only the content - // That way we focus the same window that gets focused by a mouse click - nsIViewManager* vm = presShell->GetViewManager(); - if (vm) { - vm->GetWidget(getter_AddRefs(widget)); - } - } - if (widget) - widget->SetFocus(PR_TRUE); - } - - if (nsnull != aContent && aContent != mFirstFocusEvent && - !EventHandlingSuppressed(aContent)) { - - //Store the first focus event we fire and don't refire focus - //to that element while the first focus is still ongoing. - PRBool clearFirstFocusEvent = PR_FALSE; - if (!mFirstFocusEvent) { - mFirstFocusEvent = aContent; - clearFirstFocusEvent = PR_TRUE; - } - - //fire focus - nsEvent focusEvent(PR_TRUE, NS_FOCUS_CONTENT); - focusEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - if (nsnull != mPresContext) { - nsCxPusher pusher; - if (pusher.Push(aContent)) { - FireFocusOrBlurEvent(aContent, &focusEvent, mPresContext); - } - } - - nsAutoString tabIndex; - aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::tabindex, tabIndex); - PRInt32 ec, val = tabIndex.ToInteger(&ec); - if (NS_SUCCEEDED (ec)) { - mCurrentTabIndex = val; - } - - if (clearFirstFocusEvent) { - mFirstFocusEvent = nsnull; - } - - nsIMEStateManager::OnTextStateFocus(mPresContext, mCurrentFocus); - } else if (!aContent && !EventHandlingSuppressed(mDocument)) { - //fire focus on document even if the content isn't focusable (ie. text) - //see bugzilla bug 93521 - nsEvent focusEvent(PR_TRUE, NS_FOCUS_CONTENT); - focusEvent.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - - if (nsnull != mPresContext && mDocument) { - nsCxPusher pusher; - if (pusher.Push(mDocument)) { - FireFocusOrBlurEvent(mDocument, &focusEvent, mPresContext); - } - } - } - - if (mBrowseWithCaret || GetWindowShowCaret(mDocument)) - SetContentCaretVisible(presShell, aContent, PR_TRUE); - - return NS_OK; + return PR_TRUE; } NS_IMETHODIMP -nsEventStateManager::GetFocusedContent(nsIContent** aContent) +nsEventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent) { - *aContent = mCurrentFocus; - NS_IF_ADDREF(*aContent); - return NS_OK; -} - -void nsEventStateManager::EnsureFocusSynchronization() -{ - // Sometimes the focus can get out of whack due to a blur handler - // resetting focus. In addition, we fire onchange from the blur handler - // for some controls, which is another place where focus can be changed. - // XXX Ideally we will eventually store focus in one place instead of - // the focus controller, esm, tabbrowser and some frames, so that it - // cannot get out of sync. - // See Bug 304751, calling FireOnChange() inside - // nsComboboxControlFrame::SetFocus() is bad - nsPIDOMWindow *currentWindow = mDocument->GetWindow(); - if (currentWindow) { - nsIFocusController *fc = currentWindow->GetRootFocusController(); - if (fc) { - nsCOMPtr focusedElement = do_QueryInterface(mCurrentFocus); - fc->SetFocusedElement(focusedElement); - } - } -} - -NS_IMETHODIMP -nsEventStateManager::SetFocusedContent(nsIContent* aContent) -{ - - if (aContent && - (!mPresContext || mPresContext->Type() == nsPresContext::eContext_PrintPreview)) { - return NS_OK; - } - - mCurrentFocus = aContent; - if (mCurrentFocus) - mLastFocus = mCurrentFocus; - mCurrentFocusFrame = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsEventStateManager::GetLastFocusedContent(nsIContent** aContent) -{ - *aContent = mLastFocus; - NS_IF_ADDREF(*aContent); - return NS_OK; -} - -NS_IMETHODIMP -nsEventStateManager::GetFocusedFrame(nsIFrame** aFrame) -{ - if (!mCurrentFocusFrame && mCurrentFocus) { - nsIDocument* doc = mCurrentFocus->GetDocument(); - if (doc) { - nsIPresShell *shell = doc->GetPrimaryShell(); - if (shell) { - mCurrentFocusFrame = shell->GetPrimaryFrameFor(mCurrentFocus); - } - } - } - - *aFrame = mCurrentFocusFrame; - return NS_OK; -} - -NS_IMETHODIMP -nsEventStateManager::ContentRemoved(nsIContent* aContent) -{ - if (mCurrentFocus && - nsContentUtils::ContentIsDescendantOf(mCurrentFocus, aContent)) { - // Note that we don't use SetContentState() here because - // we don't want to fire a blur. Blurs should only be fired - // in response to clicks or tabbing. - nsIMEStateManager::OnRemoveContent(mPresContext, mCurrentFocus); - SetFocusedContent(nsnull); - } - - if (mLastFocus && - nsContentUtils::ContentIsDescendantOf(mLastFocus, aContent)) { - mLastFocus = nsnull; - } + // inform the focus manager that the content is being removed. If this + // content is focused, the focus will be removed without firing events. + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) + fm->ContentRemoved(aDocument, aContent); if (mHoverContent && nsContentUtils::ContentIsDescendantOf(mHoverContent, aContent)) { @@ -5751,13 +4164,6 @@ nsEventStateManager::EnsureDocument(nsPresContext* aPresContext) mDocument = aPresContext->Document(); } -void -nsEventStateManager::EnsureDocument(nsIPresShell* aPresShell) -{ - if (!mDocument && aPresShell) - mDocument = aPresShell->GetDocument(); -} - void nsEventStateManager::FlushPendingEvents(nsPresContext* aPresContext) { @@ -5768,610 +4174,16 @@ nsEventStateManager::FlushPendingEvents(nsPresContext* aPresContext) } } -nsresult -nsEventStateManager::GetDocSelectionLocation(nsIContent **aStartContent, - nsIContent **aEndContent, - nsIFrame **aStartFrame, - PRUint32* aStartOffset) +nsIContent* +nsEventStateManager::GetFocusedContent() { - // In order to return the nsIContent and nsIFrame of the caret's position, - // we need to get a pres shell, and then get the selection from it + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (!fm || !mDocument) + return nsnull; - *aStartOffset = 0; - *aStartFrame = nsnull; - *aStartContent = *aEndContent = nsnull; - nsresult rv = NS_ERROR_FAILURE; - - NS_ASSERTION(mPresContext, "mPresContent is null!!"); - EnsureDocument(mPresContext); - if (!mDocument) - return rv; - nsIPresShell *shell; - shell = mPresContext->GetPresShell(); - - nsCOMPtr frameSelection; - if (shell) - frameSelection = shell->FrameSelection(); - - nsCOMPtr domSelection; - if (frameSelection) { - domSelection = frameSelection-> - GetSelection(nsISelectionController::SELECTION_NORMAL); - } - - nsCOMPtr startNode, endNode; - PRBool isCollapsed = PR_FALSE; - nsCOMPtr startContent, endContent; - if (domSelection) { - domSelection->GetIsCollapsed(&isCollapsed); - nsCOMPtr domRange; - rv = domSelection->GetRangeAt(0, getter_AddRefs(domRange)); - if (domRange) { - domRange->GetStartContainer(getter_AddRefs(startNode)); - domRange->GetEndContainer(getter_AddRefs(endNode)); - domRange->GetStartOffset(reinterpret_cast(aStartOffset)); - - nsIContent *childContent = nsnull; - - startContent = do_QueryInterface(startNode); - if (startContent && startContent->IsNodeOfType(nsINode::eELEMENT)) { - NS_ASSERTION(*aStartOffset >= 0, "Start offset cannot be negative"); - childContent = startContent->GetChildAt(*aStartOffset); - if (childContent) { - startContent = childContent; - } - } - - endContent = do_QueryInterface(endNode); - if (endContent && endContent->IsNodeOfType(nsINode::eELEMENT)) { - PRInt32 endOffset = 0; - domRange->GetEndOffset(&endOffset); - NS_ASSERTION(endOffset >= 0, "End offset cannot be negative"); - childContent = endContent->GetChildAt(endOffset); - if (childContent) { - endContent = childContent; - } - } - } - } - else { - rv = NS_ERROR_INVALID_ARG; - } - - nsIFrame *startFrame = nsnull; - if (startContent) { - startFrame = shell->GetPrimaryFrameFor(startContent); - if (isCollapsed) { - // Next check to see if our caret is at the very end of a node - // If so, the caret is actually sitting in front of the next - // logical frame's primary node - so for this case we need to - // change caretContent to that node. - - nsCOMPtr domNode(do_QueryInterface(startContent)); - PRUint16 nodeType; - domNode->GetNodeType(&nodeType); - - if (nodeType == nsIDOMNode::TEXT_NODE) { - nsAutoString nodeValue; - domNode->GetNodeValue(nodeValue); - - PRBool isFormControl = - startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL); - - if (nodeValue.Length() == *aStartOffset && !isFormControl && - startContent != mDocument->GetRootContent()) { - // Yes, indeed we were at the end of the last node - nsCOMPtr frameTraversal; - - nsCOMPtr trav(do_CreateInstance(kFrameTraversalCID, - &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = trav->NewFrameTraversal(getter_AddRefs(frameTraversal), - mPresContext, startFrame, - eLeaf, - PR_FALSE, // aVisual - PR_FALSE, // aLockInScrollView - PR_FALSE // aFollowOOFs - ); - NS_ENSURE_SUCCESS(rv, rv); - - nsIFrame *newCaretFrame = nsnull; - nsCOMPtr newCaretContent = startContent; - PRBool endOfSelectionInStartNode(startContent == endContent); - do { - // Continue getting the next frame until the primary content for the frame - // we are on changes - we don't want to be stuck in the same place - frameTraversal->Next(); - newCaretFrame = frameTraversal->CurrentItem(); - if (nsnull == newCaretFrame) { - break; - } - newCaretContent = newCaretFrame->GetContent(); - } while (!newCaretContent || newCaretContent == startContent); - - if (newCaretFrame && newCaretContent) { - // If the caret is exactly at the same position of the new frame, - // then we can use the newCaretFrame and newCaretContent for our position - nsRefPtr caret; - shell->GetCaret(getter_AddRefs(caret)); - nsRect caretRect; - nsIView *caretView; - caret->GetCaretCoordinates(nsCaret::eClosestViewCoordinates, - domSelection, &caretRect, - &isCollapsed, &caretView); - nsPoint framePt; - nsIView *frameClosestView = newCaretFrame->GetClosestView(&framePt); - if (caretView == frameClosestView && caretRect.y == framePt.y && - caretRect.x == framePt.x) { - // The caret is at the start of the new element. - startFrame = newCaretFrame; - startContent = newCaretContent; - if (endOfSelectionInStartNode) { - endContent = newCaretContent; // Ensure end of selection is not before start - } - } - } - } - } - } - } - - *aStartFrame = startFrame; - *aStartContent = startContent; - *aEndContent = endContent; - NS_IF_ADDREF(*aStartContent); - NS_IF_ADDREF(*aEndContent); - - return rv; -} - -void -nsEventStateManager::FocusElementButNotDocument(nsIContent *aContent) -{ - // Focus an element in the current document, but don't switch document/window focus! - - if (gLastFocusedDocument == mDocument) { - // If we're already focused in this document, - // use normal focus method - if (mCurrentFocus != aContent) { - if (aContent) - aContent->SetFocus(mPresContext); - else - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - } - return; - } - - /** - * The last focus wasn't in this document, so we may be getting our position from the selection - * while the window focus is currently somewhere else such as the find dialog - */ - - nsIFocusController *focusController = - GetFocusControllerForDocument(mDocument); - if (!focusController) - return; - - // Get previous focus - nsCOMPtr oldFocusedElement; - focusController->GetFocusedElement(getter_AddRefs(oldFocusedElement)); - nsCOMPtr oldFocusedContent(do_QueryInterface(oldFocusedElement)); - - // Temporarily set mCurrentFocus so that esm::GetContentState() tells - // layout system to show focus on this element. - SetFocusedContent(aContent); // Reset back to null at the end of this method. - mDocument->BeginUpdate(UPDATE_CONTENT_STATE); - mDocument->ContentStatesChanged(oldFocusedContent, aContent, - NS_EVENT_STATE_FOCUS); - mDocument->EndUpdate(UPDATE_CONTENT_STATE); - - // Reset mCurrentFocus = nsnull for this doc, so when this document - // does get focus next time via preHandleEvent() NS_GOTFOCUS, - // the old document gets blurred - SetFocusedContent(nsnull); - -} - -NS_IMETHODIMP -nsEventStateManager::MoveFocusToCaret(PRBool aCanFocusDoc, - PRBool *aIsSelectionWithFocus) -{ - // mBrowseWithCaret equals the pref accessibility.browsewithcaret - // When it's true, the user can arrow around the browser as if it's a - // read only text editor. - - // If the user cursors over a focusable element or gets there with find text, then send focus to it - - *aIsSelectionWithFocus= PR_FALSE; - nsCOMPtr selectionContent, endSelectionContent; - nsIFrame *selectionFrame; - PRUint32 selectionOffset; - GetDocSelectionLocation(getter_AddRefs(selectionContent), getter_AddRefs(endSelectionContent), - &selectionFrame, &selectionOffset); - - if (!selectionContent) - return NS_ERROR_FAILURE; - - nsCOMPtr testContent(selectionContent); - nsCOMPtr nextTestContent(endSelectionContent); - - // We now have the correct start node in selectionContent! - // Search for focusable elements, starting with selectionContent - - // Method #1: Keep going up while we look - an ancestor might be focusable - // We could end the loop earlier, such as when we're no longer - // in the same frame, by comparing getPrimaryFrameFor(selectionContent) - // with a variable holding the starting selectionContent - while (testContent) { - // Keep testing while selectionContent is equal to something, - // eventually we'll run out of ancestors - - if (testContent == mCurrentFocus) { - *aIsSelectionWithFocus = PR_TRUE; - return NS_OK; // already focused on this node, this whole thing's moot - } - - nsIAtom *tag = testContent->Tag(); - - // Add better focusable test here later if necessary ... - if (tag == nsGkAtoms::a && - testContent->IsNodeOfType(nsINode::eHTML)) { - *aIsSelectionWithFocus = PR_TRUE; - } - else { - // Xlink must be type="simple" - *aIsSelectionWithFocus = - testContent->HasAttr(kNameSpaceID_XLink, nsGkAtoms::href) && - testContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type, - nsGkAtoms::simple, eCaseMatters); - } - - if (*aIsSelectionWithFocus) { - FocusElementButNotDocument(testContent); - return NS_OK; - } - - // Get the parent - testContent = testContent->GetParent(); - - if (!testContent) { - // We run this loop again, checking the ancestor chain of the selection's end point - testContent = nextTestContent; - nextTestContent = nsnull; - } - } - - // We couldn't find an anchor that was an ancestor of the selection start - // Method #2: look for anchor in selection's primary range (depth first search) - - // Turn into nodes so that we can use GetNextSibling() and GetFirstChild() - nsCOMPtr selectionNode(do_QueryInterface(selectionContent)); - nsCOMPtr endSelectionNode(do_QueryInterface(endSelectionContent)); - nsCOMPtr testNode; - - do { - testContent = do_QueryInterface(selectionNode); - - // We're looking for any focusable item that could be part of the - // main document's selection. - // Right now we only look for elements with the tag. - // Add better focusable test here later if necessary ... - if (testContent) { - if (testContent->Tag() == nsGkAtoms::a && - testContent->IsNodeOfType(nsINode::eHTML)) { - *aIsSelectionWithFocus = PR_TRUE; - FocusElementButNotDocument(testContent); - return NS_OK; - } - } - - selectionNode->GetFirstChild(getter_AddRefs(testNode)); - if (testNode) { - selectionNode = testNode; - continue; - } - - if (selectionNode == endSelectionNode) - break; - selectionNode->GetNextSibling(getter_AddRefs(testNode)); - if (testNode) { - selectionNode = testNode; - continue; - } - - do { - selectionNode->GetParentNode(getter_AddRefs(testNode)); - if (!testNode || testNode == endSelectionNode) { - selectionNode = nsnull; - break; - } - testNode->GetNextSibling(getter_AddRefs(selectionNode)); - if (selectionNode) - break; - selectionNode = testNode; - } while (PR_TRUE); - } - while (selectionNode && selectionNode != endSelectionNode); - - if (aCanFocusDoc) - FocusElementButNotDocument(nsnull); - - return NS_OK; // no errors, but caret not inside focusable element other than doc itself -} - - - -NS_IMETHODIMP -nsEventStateManager::MoveCaretToFocus() -{ - // If in HTML content and the pref accessibility.browsewithcaret is TRUE, - // then always move the caret to beginning of a new focus - - PRInt32 itemType = nsIDocShellTreeItem::typeChrome; - - if (mPresContext) { - nsCOMPtr pcContainer = mPresContext->GetContainer(); - nsCOMPtr treeItem(do_QueryInterface(pcContainer)); - if (treeItem) - treeItem->GetItemType(&itemType); - nsCOMPtr editorDocShell(do_QueryInterface(treeItem)); - if (editorDocShell) { - PRBool isEditable; - editorDocShell->GetEditable(&isEditable); - if (isEditable) { - return NS_OK; // Move focus to caret only if browsing, not editing - } - } - } - - if (itemType != nsIDocShellTreeItem::typeChrome) { - nsIPresShell *shell = mPresContext->GetPresShell(); - if (shell) { - // rangeDoc is a document interface we can create a range with - nsCOMPtr rangeDoc(do_QueryInterface(mDocument)); - - if (rangeDoc) { - nsCOMPtr frameSelection = shell->FrameSelection(); - nsCOMPtr domSelection = frameSelection-> - GetSelection(nsISelectionController::SELECTION_NORMAL); - if (domSelection) { - nsCOMPtr currentFocusNode(do_QueryInterface(mCurrentFocus)); - // First clear the selection - domSelection->RemoveAllRanges(); - if (currentFocusNode && !mCurrentFocus->IsNodeOfType(nsINode::eXUL)) { - nsCOMPtr newRange; - nsresult rv = rangeDoc->CreateRange(getter_AddRefs(newRange)); - if (NS_SUCCEEDED(rv)) { - // Set the range to the start of the currently focused node - // Make sure it's collapsed - newRange->SelectNodeContents(currentFocusNode); - nsCOMPtr firstChild; - currentFocusNode->GetFirstChild(getter_AddRefs(firstChild)); - if (!firstChild || - mCurrentFocus->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) { - // If current focus node is a leaf, set range to before the - // node by using the parent as a container. - // This prevents it from appearing as selected. - newRange->SetStartBefore(currentFocusNode); - newRange->SetEndBefore(currentFocusNode); - } - domSelection->AddRange(newRange); - domSelection->CollapseToStart(); - } - } - } - } - } - } - return NS_OK; -} - -nsresult -nsEventStateManager::SetCaretEnabled(nsIPresShell *aPresShell, PRBool aEnabled) -{ - nsRefPtr caret; - aPresShell->GetCaret(getter_AddRefs(caret)); - - nsCOMPtr selCon(do_QueryInterface(aPresShell)); - if (!selCon || !caret) - return NS_ERROR_FAILURE; - - selCon->SetCaretEnabled(aEnabled); - caret->SetCaretVisible(aEnabled); - caret->SetIgnoreUserModify(aEnabled); - - return NS_OK; -} - -nsresult -nsEventStateManager::SetContentCaretVisible(nsIPresShell* aPresShell, - nsIContent *aFocusedContent, - PRBool aVisible) -{ - // When browsing with caret, make sure caret is visible after new focus - nsRefPtr caret; - aPresShell->GetCaret(getter_AddRefs(caret)); - - nsCOMPtr frameSelection; - if (aFocusedContent) { - nsIFrame *focusFrame = aPresShell->GetPrimaryFrameFor(aFocusedContent); - - if (focusFrame) - frameSelection = focusFrame->GetFrameSelection(); - } - - nsCOMPtr docFrameSelection = aPresShell->FrameSelection(); - - if (docFrameSelection && caret && - (frameSelection == docFrameSelection || !aFocusedContent)) { - nsISelection* domSelection = docFrameSelection-> - GetSelection(nsISelectionController::SELECTION_NORMAL); - if (domSelection) { - // First, tell the caret which selection to use - caret->SetCaretDOMSelection(domSelection); - - // In content, we need to set the caret - // the only other case is edit fields, where they have a different frame selection from the doc's - // in that case they'll take care of making the caret visible themselves - - // Then make sure it's visible - return SetCaretEnabled(aPresShell, aVisible); - } - } - - return NS_OK; -} - -PRBool -nsEventStateManager::GetBrowseWithCaret() -{ - return mBrowseWithCaret; -} - -// Checks if the window corresponding to |aDocument| has the -// showcaret="true" attribute set. -static PRBool -GetWindowShowCaret(nsIDocument *aDocument) -{ - if (!aDocument) return PR_FALSE; - - nsPIDOMWindow* window = aDocument->GetWindow(); - if (!window) return PR_FALSE; - - nsCOMPtr docContent = - do_QueryInterface(window->GetFrameElementInternal()); - if (!docContent) return PR_FALSE; - - return docContent->AttrValueIs(kNameSpaceID_None, - nsGkAtoms::showcaret, - NS_LITERAL_STRING("true"), - eCaseMatters); -} - -void -nsEventStateManager::ResetBrowseWithCaret() -{ - // This is called when browse with caret changes on the fly - // or when a document gets focused - - if (!mPresContext) - return; - - nsCOMPtr pcContainer = mPresContext->GetContainer(); - PRInt32 itemType; - nsCOMPtr shellItem(do_QueryInterface(pcContainer)); - if (!shellItem) - return; - - shellItem->GetItemType(&itemType); - - if (itemType == nsIDocShellTreeItem::typeChrome) - return; // Never browse with caret in chrome - - PRPackedBool browseWithCaret = - nsContentUtils::GetBoolPref("accessibility.browsewithcaret"); - mBrowseWithCaret = browseWithCaret; - - nsIPresShell *presShell = mPresContext->GetPresShell(); - - // If we're in an editable document which isn't contentEditable, or we're - // in a contentEditable document which whose focus is contentEditable, - // return, so that we don't mess with caret visibility. - nsCOMPtr editorDocShell(do_QueryInterface(shellItem)); - if (editorDocShell) { - PRBool isEditable; - editorDocShell->GetEditable(&isEditable); - if (presShell && isEditable) { - nsCOMPtr doc = - do_QueryInterface(presShell->GetDocument()); - - PRBool isContentEditableDoc = - doc && doc->GetEditingState() == nsIHTMLDocument::eContentEditable; - - PRBool isFocusEditable = - mCurrentFocus && mCurrentFocus->HasFlag(NODE_IS_EDITABLE); - - if (!isContentEditableDoc || isFocusEditable) - return; - } - } - - // Make caret visible or not, depending on what's appropriate. - // Set caret visibility for focused document only, - // others will be set when they get focused again - if (presShell && gLastFocusedDocument && gLastFocusedDocument == mDocument) { - - PRBool caretShouldBeVisible = browseWithCaret || - GetWindowShowCaret(mDocument); - - SetContentCaretVisible(presShell, mCurrentFocus, caretShouldBeVisible); - } -} - -//-------------------------------------------------------------------------------- -//-- DocShell Focus Traversal Methods -//-------------------------------------------------------------------------------- - -//---------------------------------------- -// Returns PR_TRUE if this doc contains a frameset -PRBool -nsEventStateManager::IsFrameSetDoc(nsIDocShell* aDocShell) -{ - NS_ASSERTION(aDocShell, "docshell is null"); - PRBool isFrameSet = PR_FALSE; - - // a frameset element will always be the immediate child - // of the root content (the HTML tag) - nsCOMPtr presShell; - aDocShell->GetPresShell(getter_AddRefs(presShell)); - if (presShell) { - nsIDocument *doc = presShell->GetDocument(); - nsCOMPtr htmlDoc = do_QueryInterface(doc); - if (htmlDoc) { - nsIContent *rootContent = doc->GetRootContent(); - if (rootContent) { - PRUint32 childCount = rootContent->GetChildCount(); - for (PRUint32 i = 0; i < childCount; ++i) { - nsIContent *childContent = rootContent->GetChildAt(i); - - nsINodeInfo *ni = childContent->NodeInfo(); - - if (childContent->IsNodeOfType(nsINode::eHTML) && - ni->Equals(nsGkAtoms::frameset)) { - isFrameSet = PR_TRUE; - break; - } - } - } - } - } - - return isFrameSet; -} - -//---------------------------------------- -// Returns PR_TRUE if this doc is an IFRAME - -PRBool -nsEventStateManager::IsIFrameDoc(nsIDocShell* aDocShell) -{ - NS_ASSERTION(aDocShell, "docshell is null"); - - nsCOMPtr domWindow(do_GetInterface(aDocShell)); - if (!domWindow) { - NS_ERROR("We're a child of a docshell without a window?"); - return PR_FALSE; - } - - nsCOMPtr docContent = - do_QueryInterface(domWindow->GetFrameElementInternal()); - - if (!docContent) { - return PR_FALSE; - } - - return docContent->Tag() == nsGkAtoms::iframe; + nsCOMPtr focusedWindow; + return nsFocusManager::GetFocusedDescendant(mDocument->GetWindow(), PR_FALSE, + getter_AddRefs(focusedWindow)); } //------------------------------------------------------- @@ -6394,258 +4206,3 @@ nsEventStateManager::IsShellVisible(nsIDocShell* aShell) return isVisible; } - -//------------------------------------------------ -// This method should be called when tab or F6/ctrl-tab -// traversal wants to focus a new document. It will focus -// the docshell, traverse into the document if this type -// of document does not get document focus (i.e. framsets -// and chrome), and update the canvas focus state on the docshell. - -void -nsEventStateManager::TabIntoDocument(nsIDocShell* aDocShell, - PRBool aForward) -{ - NS_ASSERTION(aDocShell, "null docshell"); - nsCOMPtr domwin = do_GetInterface(aDocShell); - if (domwin) - domwin->Focus(); - - PRInt32 itemType; - nsCOMPtr treeItem = do_QueryInterface(aDocShell); - treeItem->GetItemType(&itemType); - - nsCOMPtr presContext; - aDocShell->GetPresContext(getter_AddRefs(presContext)); - PRBool focusDocument; - if (presContext && - presContext->Type() == nsPresContext::eContext_PrintPreview) { - // Don't focus any content in print preview mode, bug 244128. - focusDocument = PR_TRUE; - } else { - if (!aForward || (itemType == nsIDocShellTreeItem::typeChrome)) - focusDocument = PR_FALSE; - else { - // Check for a frameset document - focusDocument = !(IsFrameSetDoc(aDocShell)); - } - } - - if (focusDocument) { - // make sure we're in view - aDocShell->SetCanvasHasFocus(PR_TRUE); - } - else { - aDocShell->SetHasFocus(PR_FALSE); - - if (presContext) { - nsIEventStateManager *docESM = presContext->EventStateManager(); - - // we are about to shift focus to aDocShell - // keep track of the document, so we don't try to go back into it. - mTabbingFromDocShells.AppendObject(aDocShell); - - // clear out any existing focus state - docESM->SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - // now focus the first (or last) focusable content - docESM->ShiftFocus(aForward, nsnull); - - // remove the document from the list - mTabbingFromDocShells.RemoveObject(aDocShell); - } - } -} - -void -nsEventStateManager::GetLastChildDocShell(nsIDocShellTreeItem* aItem, - nsIDocShellTreeItem** aResult) -{ - NS_ASSERTION(aItem, "null docshell"); - NS_ASSERTION(aResult, "null out pointer"); - - nsCOMPtr curItem = do_QueryInterface(aItem); - while (1) { - nsCOMPtr curNode = do_QueryInterface(curItem); - PRInt32 childCount = 0; - curNode->GetChildCount(&childCount); - if (!childCount) { - *aResult = curItem; - NS_ADDREF(*aResult); - return; - } - - curNode->GetChildAt(childCount - 1, getter_AddRefs(curItem)); - } -} - -void -nsEventStateManager::GetNextDocShell(nsIDocShellTreeNode* aNode, - nsIDocShellTreeItem** aResult) -{ - NS_ASSERTION(aNode, "null docshell"); - NS_ASSERTION(aResult, "null out pointer"); - - *aResult = nsnull; - - PRInt32 childCount = 0; - aNode->GetChildCount(&childCount); - if (childCount) { - aNode->GetChildAt(0, aResult); - if (*aResult) - return; - } - - nsCOMPtr curNode = aNode; - while (curNode) { - nsCOMPtr curItem = do_QueryInterface(curNode); - nsCOMPtr parentItem; - curItem->GetParent(getter_AddRefs(parentItem)); - if (!parentItem) { - *aResult = nsnull; - return; - } - - // Note that we avoid using GetChildOffset() here because docshell - // child offsets can't be trusted to be correct. bug 162283. - nsCOMPtr parentNode = do_QueryInterface(parentItem); - nsCOMPtr iterItem; - childCount = 0; - parentNode->GetChildCount(&childCount); - for (PRInt32 index = 0; index < childCount; ++index) { - parentNode->GetChildAt(index, getter_AddRefs(iterItem)); - if (iterItem == curItem) { - ++index; - if (index < childCount) { - parentNode->GetChildAt(index, aResult); - if (*aResult) - return; - } - break; - } - } - - curNode = do_QueryInterface(parentItem); - } -} - -void -nsEventStateManager::GetPrevDocShell(nsIDocShellTreeNode* aNode, - nsIDocShellTreeItem** aResult) -{ - NS_ASSERTION(aNode, "null docshell"); - NS_ASSERTION(aResult, "null out pointer"); - - nsCOMPtr curItem = do_QueryInterface(aNode); - nsCOMPtr parentItem; - - curItem->GetParent(getter_AddRefs(parentItem)); - if (!parentItem) { - *aResult = nsnull; - return; - } - - // Note that we avoid using GetChildOffset() here because docshell - // child offsets can't be trusted to be correct. bug 162283. - nsCOMPtr parentNode = do_QueryInterface(parentItem); - PRInt32 childCount = 0; - parentNode->GetChildCount(&childCount); - nsCOMPtr prevItem, iterItem; - for (PRInt32 index = 0; index < childCount; ++index) { - parentNode->GetChildAt(index, getter_AddRefs(iterItem)); - if (iterItem == curItem) - break; - prevItem = iterItem; - } - - if (prevItem) { - curItem = prevItem; - nsCOMPtr curNode; - // Get the last child recursively of this node. - while (1) { - curNode = do_QueryInterface(curItem); - childCount = 0; - curNode->GetChildCount(&childCount); - if (!childCount) - break; - - curNode->GetChildAt(childCount - 1, getter_AddRefs(curItem)); - } - - *aResult = curItem; - NS_ADDREF(*aResult); - return; - } - - *aResult = parentItem; - NS_ADDREF(*aResult); - return; -} - -//------------------------------------------------- -// Traversal by document/DocShell only -// this does not include any content inside the doc -// or IFrames -void -nsEventStateManager::ShiftFocusByDoc(PRBool aForward) -{ - // Note that we use the docshell tree here instead of iteratively calling - // ShiftFocus. The docshell tree should be kept in depth-first frame tree - // order, the same as we use for tabbing, so the effect should be the same, - // but this is much faster. - - NS_ASSERTION(mPresContext, "no prescontext"); - - nsCOMPtr pcContainer = mPresContext->GetContainer(); - nsCOMPtr curNode = do_QueryInterface(pcContainer); - if (!curNode) { - return; - } - - // perform a depth first search (preorder) of the docshell tree - // looking for an HTML Frame or a chrome document - - nsCOMPtr nextItem; - nsCOMPtr nextShell; - do { - if (aForward) { - GetNextDocShell(curNode, getter_AddRefs(nextItem)); - if (!nextItem) { - nsCOMPtr curItem = do_QueryInterface(pcContainer); - // wrap around to the beginning, which is the top of the tree - curItem->GetRootTreeItem(getter_AddRefs(nextItem)); - } - } - else { - GetPrevDocShell(curNode, getter_AddRefs(nextItem)); - if (!nextItem) { - nsCOMPtr curItem = do_QueryInterface(pcContainer); - // wrap around to the end, which is the last node in the tree - nsCOMPtr rootItem; - curItem->GetRootTreeItem(getter_AddRefs(rootItem)); - GetLastChildDocShell(rootItem, getter_AddRefs(nextItem)); - } - } - - curNode = do_QueryInterface(nextItem); - nextShell = do_QueryInterface(nextItem); - } while (IsFrameSetDoc(nextShell) || IsIFrameDoc(nextShell) || !IsShellVisible(nextShell)); - - if (nextShell) { - // NOTE: always tab forward into the document, this ensures that we - // focus the document itself, not its last focusable content. - // chrome documents will get their first focusable content focused. - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - TabIntoDocument(nextShell, PR_TRUE); - } -} - -// Get the FocusController given an nsIDocument -nsIFocusController* -nsEventStateManager::GetFocusControllerForDocument(nsIDocument* aDocument) -{ - nsCOMPtr container = aDocument->GetContainer(); - nsCOMPtr windowPrivate = do_GetInterface(container); - - return windowPrivate ? windowPrivate->GetRootFocusController() : nsnull; -} - diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index e4b0f51f7df4..bcbd70c21a4d 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -121,11 +121,7 @@ public: NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState); virtual PRBool SetContentState(nsIContent *aContent, PRInt32 aState); - NS_IMETHOD GetFocusedContent(nsIContent **aContent); - NS_IMETHOD SetFocusedContent(nsIContent* aContent); - NS_IMETHOD GetLastFocusedContent(nsIContent **aContent); - NS_IMETHOD GetFocusedFrame(nsIFrame **aFrame); - NS_IMETHOD ContentRemoved(nsIContent* aContent); + NS_IMETHOD ContentRemoved(nsIDocument* aDocument, nsIContent* aContent); NS_IMETHOD EventStatusOK(nsGUIEvent* aEvent, PRBool *aOK); // Access Key Registration @@ -137,15 +133,6 @@ public: PRBool aHaveHotspot, float aHotspotX, float aHotspotY, nsIWidget* aWidget, PRBool aLockCursor); - NS_IMETHOD ShiftFocus(PRBool aForward, nsIContent* aStart=nsnull); - - virtual PRBool GetBrowseWithCaret(); - void ResetBrowseWithCaret(); - - NS_IMETHOD MoveFocusToCaret(PRBool aCanFocusDoc, PRBool *aIsSelectionWithFocus); - NS_IMETHOD MoveCaretToFocus(); - NS_IMETHOD ChangeFocusWith(nsIContent* aFocus, EFocusedWithType aFocusedWith); - static void StartHandlingUserInput() { ++sUserInputEventDepth; @@ -167,14 +154,6 @@ public: nsIEventStateManager) protected: - /** - * In certain situations the focus controller's concept of focus gets out of - * whack with mCurrentFocus. This is used in known cases to reset the focus - * controller's focus. At some point we should probably move to a single - * focus storage mechanism because tracking it in several places is error-prone. - */ - void EnsureFocusSynchronization(); - void UpdateCursor(nsPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus); /** * Turn a GUI mouse event into a mouse event targeted at the specified @@ -221,20 +200,8 @@ protected: nsWeakFrame& aTargetFrame); nsresult SetClickCount(nsPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus); nsresult CheckForAndDispatchClick(nsPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus); - nsresult GetNextTabbableContent(nsIContent* aRootContent, - nsIContent* aStartContent, - nsIFrame* aStartFrame, - PRBool forward, PRBool ignoreTabIndex, - nsIContent** aResultNode, - nsIFrame** aResultFrame); - nsIContent *GetNextTabbableMapArea(PRBool aForward, nsIContent *imageContent); - - PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward); - nsresult SendFocusBlur(nsPresContext* aPresContext, nsIContent *aContent, PRBool aEnsureWindowHasFocus); - void EnsureDocument(nsIPresShell* aPresShell); void EnsureDocument(nsPresContext* aPresContext); void FlushPendingEvents(nsPresContext* aPresContext); - nsIFocusController* GetFocusControllerForDocument(nsIDocument* aDocument); /** * The phases of HandleAccessKey processing. See below. @@ -278,18 +245,8 @@ protected: // DocShell Focus Traversal Methods //--------------------------------------------- - nsresult ShiftFocusInternal(PRBool aForward, nsIContent* aStart = nsnull); - void TabIntoDocument(nsIDocShell* aDocShell, PRBool aForward); - void ShiftFocusByDoc(PRBool forward); - PRBool IsFrameSetDoc(nsIDocShell* aDocShell); - PRBool IsIFrameDoc(nsIDocShell* aDocShell); + nsIContent* GetFocusedContent(); PRBool IsShellVisible(nsIDocShell* aShell); - void GetLastChildDocShell(nsIDocShellTreeItem* aItem, - nsIDocShellTreeItem** aResult); - void GetNextDocShell(nsIDocShellTreeNode* aNode, - nsIDocShellTreeItem** aResult); - void GetPrevDocShell(nsIDocShellTreeNode* aNode, - nsIDocShellTreeItem** aResult); // These functions are for mousewheel and pixel scrolling nsresult GetParentScrollingView(nsInputEvent* aEvent, @@ -369,16 +326,6 @@ protected: */ void FillInEventFromGestureDown(nsMouseEvent* aEvent); - PRBool mSuppressFocusChange; // Used only for Ender text fields to suppress a focus firing on mouse down - - nsresult SetCaretEnabled(nsIPresShell *aPresShell, PRBool aVisibility); - nsresult SetContentCaretVisible(nsIPresShell* aPresShell, nsIContent *aContent, PRBool aVisible); - void FocusElementButNotDocument(nsIContent *aElement); - - // Return the location of the caret - nsresult GetDocSelectionLocation(nsIContent **start, nsIContent **end, - nsIFrame **startFrame, PRUint32 *startOffset); - PRInt32 mLockCursor; nsWeakFrame mCurrentTarget; @@ -409,20 +356,6 @@ protected: nsCOMPtr mHoverContent; nsCOMPtr mDragOverContent; nsCOMPtr mURLTargetContent; - nsCOMPtr mCurrentFocus; - nsCOMPtr mLastFocus; - nsWeakFrame mCurrentFocusFrame; - PRInt32 mCurrentTabIndex; - EFocusedWithType mLastFocusedWith; - - // DocShell Traversal Data Memebers - nsCOMPtr mLastContentFocus; - - //Anti-recursive stack controls - - nsCOMPtr mFirstBlurEvent; - nsCOMPtr mFirstDocumentBlurEvent; - nsCOMPtr mFirstFocusEvent; // The last element on which we fired a mouseover event, or null if // the last mouseover event we fired has finished processing. @@ -443,17 +376,9 @@ protected: PRPackedBool m_haveShutdown; - // So we don't have to keep checking accessibility.browsewithcaret pref - PRPackedBool mBrowseWithCaret; - - // Recursion guard for tabbing - PRPackedBool mTabbedThroughDocument; - // Array for accesskey support nsCOMArray mAccessKeys; - nsCOMArray mTabbingFromDocShells; - // Unlocks pixel scrolling PRPackedBool mLastLineScrollConsumedX; PRPackedBool mLastLineScrollConsumedY; diff --git a/content/events/src/nsIMEStateManager.cpp b/content/events/src/nsIMEStateManager.cpp index f7c5fa9566eb..59a43fe39493 100644 --- a/content/events/src/nsIMEStateManager.cpp +++ b/content/events/src/nsIMEStateManager.cpp @@ -51,7 +51,6 @@ #include "nsIContent.h" #include "nsIDocument.h" #include "nsPresContext.h" -#include "nsIFocusController.h" #include "nsIDOMWindow.h" #include "nsContentUtils.h" #include "nsINode.h" @@ -71,7 +70,6 @@ nsIContent* nsIMEStateManager::sContent = nsnull; nsPresContext* nsIMEStateManager::sPresContext = nsnull; -nsPIDOMWindow* nsIMEStateManager::sActiveWindow = nsnull; PRBool nsIMEStateManager::sInstalledMenuKeyboardListener = PR_FALSE; nsTextStateManager* nsIMEStateManager::sTextStateObserver = nsnull; @@ -118,11 +116,6 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext, { NS_ENSURE_ARG_POINTER(aPresContext); - if (!IsActive(aPresContext)) { - // The actual focus isn't changing, because this presContext isn't active. - return NS_OK; - } - nsCOMPtr widget = GetWidget(aPresContext); if (!widget) { return NS_OK; @@ -171,29 +164,6 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext, return NS_OK; } -nsresult -nsIMEStateManager::OnActivate(nsPresContext* aPresContext) -{ - NS_ENSURE_ARG_POINTER(aPresContext); - sActiveWindow = aPresContext->Document()->GetWindow(); - NS_ENSURE_TRUE(sActiveWindow, NS_ERROR_FAILURE); - sActiveWindow = sActiveWindow->GetPrivateRoot(); - return NS_OK; -} - -nsresult -nsIMEStateManager::OnDeactivate(nsPresContext* aPresContext) -{ - NS_ENSURE_ARG_POINTER(aPresContext); - NS_ENSURE_TRUE(aPresContext->Document()->GetWindow(), NS_ERROR_FAILURE); - if (sActiveWindow != - aPresContext->Document()->GetWindow()->GetPrivateRoot()) - return NS_OK; - - sActiveWindow = nsnull; - return NS_OK; -} - void nsIMEStateManager::OnInstalledMenuKeyboardListener(PRBool aInstalling) { @@ -201,37 +171,6 @@ nsIMEStateManager::OnInstalledMenuKeyboardListener(PRBool aInstalling) OnChangeFocus(sPresContext, sContent); } -PRBool -nsIMEStateManager::IsActive(nsPresContext* aPresContext) -{ - NS_ENSURE_TRUE(aPresContext, PR_FALSE); - nsPIDOMWindow* window = aPresContext->Document()->GetWindow(); - NS_ENSURE_TRUE(window, PR_FALSE); - if (!sActiveWindow || sActiveWindow != window->GetPrivateRoot()) { - // This root window is not active. - return PR_FALSE; - } - - nsIPresShell* shell = aPresContext->GetPresShell(); - NS_ENSURE_TRUE(shell, PR_FALSE); - nsIViewManager* vm = shell->GetViewManager(); - NS_ENSURE_TRUE(vm, PR_FALSE); - nsCOMPtr observer; - vm->GetViewObserver(*getter_AddRefs(observer)); - NS_ENSURE_TRUE(observer, PR_FALSE); - return observer->IsVisible(); -} - -nsIFocusController* -nsIMEStateManager::GetFocusController(nsPresContext* aPresContext) -{ - nsCOMPtr container = - aPresContext->Document()->GetContainer(); - nsCOMPtr windowPrivate = do_GetInterface(container); - - return windowPrivate ? windowPrivate->GetRootFocusController() : nsnull; -} - PRUint32 nsIMEStateManager::GetNewIMEState(nsPresContext* aPresContext, nsIContent* aContent) diff --git a/content/events/src/nsIMEStateManager.h b/content/events/src/nsIMEStateManager.h index 1c80693643fd..9fddcc49dc78 100644 --- a/content/events/src/nsIMEStateManager.h +++ b/content/events/src/nsIMEStateManager.h @@ -61,8 +61,6 @@ public: nsIContent* aContent); static nsresult OnChangeFocus(nsPresContext* aPresContext, nsIContent* aContent); - static nsresult OnActivate(nsPresContext* aPresContext); - static nsresult OnDeactivate(nsPresContext* aPresContext); static void OnInstalledMenuKeyboardListener(PRBool aInstalling); // These two methods manage focus and selection/text observers. @@ -90,14 +88,10 @@ protected: static PRUint32 GetNewIMEState(nsPresContext* aPresContext, nsIContent* aContent); - static PRBool IsActive(nsPresContext* aPresContext); - - static nsIFocusController* GetFocusController(nsPresContext* aPresContext); static nsIWidget* GetWidget(nsPresContext* aPresContext); static nsIContent* sContent; static nsPresContext* sPresContext; - static nsPIDOMWindow* sActiveWindow; static PRBool sInstalledMenuKeyboardListener; static nsTextStateManager* sTextStateObserver; diff --git a/content/events/test/test_bug450876.html b/content/events/test/test_bug450876.html index 77b922d7b239..0f291a9edbbe 100644 --- a/content/events/test/test_bug450876.html +++ b/content/events/test/test_bug450876.html @@ -27,8 +27,10 @@ function doTest() { is(document.activeElement, document.getElementById('a'), "link should have focus"); var wu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); + is(document.hasFocus(), true, "document should be focused"); wu.sendKeyEvent('keypress', 9, 0, 0); - is(document.activeElement, document.body, "body element should be focused"); + is(document.activeElement, document.getElementById('a'), "body element should be focused"); + is(document.hasFocus(), false, "document should not be focused"); SimpleTest.finish(); } diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index f36c798d82cd..52f599eb8b38 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -76,6 +76,7 @@ #include "nsIPresShell.h" #include "nsPresContext.h" #include "nsIDocShell.h" +#include "nsIDocShellTreeItem.h" #include "nsINameSpaceManager.h" #include "nsDOMError.h" #include "nsScriptLoader.h" @@ -97,6 +98,7 @@ #include "nsIForm.h" #include "nsIFormControl.h" #include "nsIDOMHTMLFormElement.h" +#include "nsFocusManager.h" #include "nsMutationEvent.h" @@ -305,8 +307,7 @@ nsGenericHTMLElement::SetAttribute(const nsAString& aName, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr nameAtom; - if (GetOwnerDoc() // XXX clean up after bug 335998 lands - && !(GetOwnerDoc()->IsCaseSensitive())) { + if (IsInHTMLDocument()) { nsAutoString lower; ToLowerCase(aName, lower); nameAtom = do_GetAtom(lower); @@ -328,8 +329,7 @@ nsGenericHTMLElement::GetNodeName(nsAString& aNodeName) { mNodeInfo->GetQualifiedName(aNodeName); - if (GetOwnerDoc() // XXX clean up after bug 335998 lands - && !(GetOwnerDoc()->IsCaseSensitive())) + if (IsInHTMLDocument()) ToUpperCase(aNodeName); return NS_OK; @@ -342,8 +342,7 @@ nsGenericHTMLElement::GetElementsByTagName(const nsAString& aTagname, nsAutoString tagName(aTagname); // Only lowercase the name if this is an HTML document. - if (GetOwnerDoc() // XXX clean up after bug 335998 lands - && !(GetOwnerDoc()->IsCaseSensitive())) + if (IsInHTMLDocument()) ToLowerCase(tagName); return nsGenericHTMLElementBase::GetElementsByTagName(tagName, aReturn); @@ -641,8 +640,7 @@ nsGenericHTMLElement::GetInnerHTML(nsAString& aInnerHTML) nsresult rv = NS_OK; nsAutoString contentType; - if (!doc->IsCaseSensitive()) { - // All case-insensitive documents are HTML as far as we're concerned + if (IsInHTMLDocument()) { contentType.AssignLiteral("text/html"); } else { doc->GetContentType(contentType); @@ -1170,8 +1168,6 @@ nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, already_AddRefed nsGenericHTMLElement::GetBaseURI() const { - nsIDocument* doc = GetOwnerDoc(); // XXX clean up after bug 335998 lands - void* prop; if (HasFlag(NODE_HAS_PROPERTIES) && (prop = GetProperty(nsGkAtoms::htmlBaseHref))) { nsIURI* uri = static_cast(prop); @@ -1182,8 +1178,9 @@ nsGenericHTMLElement::GetBaseURI() const // If we are a plain old HTML element (not XHTML), don't bother asking the // base class -- our base URI is determined solely by the document base. - if (doc && !(doc->IsCaseSensitive())) { - nsIURI *uri = doc->GetBaseURI(); + if (IsInHTMLDocument()) { + // If we got here, GetOwnerDoc() is not null + nsIURI *uri = GetOwnerDoc()->GetBaseURI(); NS_IF_ADDREF(uri); return uri; @@ -2601,6 +2598,35 @@ nsGenericHTMLFormElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, aValue, aNotify); } +nsresult +nsGenericHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) +{ + if (NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) { + switch (aVisitor.mEvent->message) { + case NS_FOCUS_CONTENT: + { + // Check to see if focus has bubbled up from a form control's + // child textfield or button. If that's the case, don't focus + // this parent file control -- leave focus on the child. + nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); + if (formControlFrame && + aVisitor.mEvent->originalTarget == static_cast(this)) + formControlFrame->SetFocus(PR_TRUE, PR_TRUE); + break; + } + case NS_BLUR_CONTENT: + { + nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); + if (formControlFrame) + formControlFrame->SetFocus(PR_FALSE, PR_FALSE); + break; + } + } + } + + return nsGenericHTMLElement::PreHandleEvent(aVisitor); +} + PRBool nsGenericHTMLFormElement::CanBeDisabled() const { @@ -2656,37 +2682,6 @@ nsGenericHTMLFormElement::IntrinsicState() const return state; } -void -nsGenericHTMLFormElement::SetFocusAndScrollIntoView(nsPresContext* aPresContext) -{ - nsIEventStateManager *esm = aPresContext->EventStateManager(); - if (esm->SetContentState(this, NS_EVENT_STATE_FOCUS)) { - // XXXldb once bug 43114 is fixed, we don't need to flush here. - aPresContext->Document()-> - FlushPendingNotifications(Flush_InterruptibleLayout); - nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE); - if (formControlFrame) { - formControlFrame->SetFocus(PR_TRUE, PR_TRUE); - nsCOMPtr presShell = aPresContext->GetPresShell(); - if (presShell) { - presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE, - NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE); - } - } - } -} - -void -nsGenericHTMLFormElement::DoSetFocus(nsPresContext* aPresContext) -{ - if (!aPresContext) - return; - - if (FocusState() == eActiveWindow) { - SetFocusAndScrollIntoView(aPresContext); - } -} - nsGenericHTMLFormElement::FocusTristate nsGenericHTMLFormElement::FocusState() { @@ -2703,24 +2698,23 @@ nsGenericHTMLFormElement::FocusState() // If the window is not active, do not allow the focus to bring the // window to the front. We update the focus controller, but do // nothing else. - nsCOMPtr win = doc->GetWindow(); - if (win) { - nsIFocusController *focusController = win->GetRootFocusController(); - if (focusController) { - PRBool isActive = PR_FALSE; - focusController->GetActive(&isActive); - if (!isActive) { - focusController->SetFocusedWindow(win); - nsCOMPtr el = - do_QueryInterface(static_cast(this)); - focusController->SetFocusedElement(el); + nsCOMPtr dsti = do_GetInterface(doc->GetWindow()); + if (dsti) { + nsCOMPtr root; + dsti->GetRootTreeItem(getter_AddRefs(root)); + nsCOMPtr rootWindow = do_GetInterface(root); - return eInactiveWindow; + nsCOMPtr fm = do_GetService(FOCUSMANAGER_CONTRACTID); + if (fm && rootWindow) { + nsCOMPtr activeWindow; + fm->GetActiveWindow(getter_AddRefs(activeWindow)); + if (activeWindow == rootWindow) { + return eActiveWindow; } } } - return eActiveWindow; + return eInactiveWindow; } //---------------------------------------------------------------------- @@ -2912,34 +2906,19 @@ nsGenericHTMLFrameElement::DestroyContent() //---------------------------------------------------------------------- -void -nsGenericHTMLElement::SetElementFocus(PRBool aDoFocus) -{ - nsCOMPtr presContext = GetPresContext(); - if (!presContext) - return; - - if (aDoFocus) { - if (IsInDoc()) { - // Make sure that our frames are up to date so we focus the right thing. - GetCurrentDoc()->FlushPendingNotifications(Flush_Frames); - } - - SetFocus(presContext); - - presContext->EventStateManager()->MoveCaretToFocus(); - return; - } - - RemoveFocus(presContext); -} - nsresult nsGenericHTMLElement::Blur() { - if (ShouldBlur(this)) { - SetElementFocus(PR_FALSE); - } + if (!ShouldBlur(this)) + return NS_OK; + + nsIDocument* doc = GetCurrentDoc(); + if (!doc) + return NS_OK; + + nsIDOMWindow* win = doc->GetWindow(); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + return (win && fm) ? fm->ClearFocus(win) : NS_OK; return NS_OK; } @@ -2947,33 +2926,9 @@ nsGenericHTMLElement::Blur() nsresult nsGenericHTMLElement::Focus() { - // Generic HTML elements are focusable only if tabindex explicitly set. - // SetFocus() will check to see if we're focusable and then - // call into esm to do the work of focusing. - if (ShouldFocus(this)) { - SetElementFocus(PR_TRUE); - } - - return NS_OK; -} - -void -nsGenericHTMLElement::RemoveFocus(nsPresContext *aPresContext) -{ - if (!aPresContext) - return; - - if (IsNodeOfType(eHTML_FORM_CONTROL)) { - nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); - if (formControlFrame) { - formControlFrame->SetFocus(PR_FALSE, PR_FALSE); - } - } - - if (IsInDoc()) { - aPresContext->EventStateManager()->SetContentState(nsnull, - NS_EVENT_STATE_FOCUS); - } + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + nsCOMPtr elem = do_QueryInterface(this); + return fm ? fm->SetFocus(elem, 0) : NS_OK; } PRBool @@ -2994,14 +2949,13 @@ nsGenericHTMLElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex) PRInt32 tabIndex = 0; // Default value for non HTML elements with -moz-user-focus GetTabIndex(&tabIndex); - PRBool override, disabled; + PRBool override, disabled = PR_FALSE; if (IsEditableRoot()) { // Editable roots should always be focusable. override = PR_TRUE; // Ignore the disabled attribute in editable contentEditable/designMode // roots. - disabled = PR_FALSE; if (!HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) { // The default value for tabindex should be 0 for editable // contentEditable roots. @@ -3011,7 +2965,7 @@ nsGenericHTMLElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex) else { override = PR_FALSE; - // Just check for disabled attribute on all HTML elements + // Just check for disabled attribute on form controls disabled = HasAttr(kNameSpaceID_None, nsGkAtoms::disabled); if (disabled) { tabIndex = -1; @@ -3062,12 +3016,12 @@ nsGenericHTMLElement::PerformAccesskey(PRBool aKeyCausesActivation, if (!presContext) return; - nsIEventStateManager *esm = presContext->EventStateManager(); - if (!esm) - return; - // It's hard to say what HTML4 wants us to do in all cases. - esm->ChangeFocusWith(this, nsIEventStateManager::eEventFocusedByKey); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) { + nsCOMPtr elem = do_QueryInterface(this); + fm->SetFocus(elem, nsIFocusManager::FLAG_BYKEY); + } if (aKeyCausesActivation) { // Click on it if the users prefs indicate to do so. @@ -3427,8 +3381,7 @@ nsGenericHTMLElement::GetHashFromHrefURI(nsAString& aHash) const nsAttrName* nsGenericHTMLElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const { - if (GetOwnerDoc() // XXX clean up after bug 335998 lands - && !(GetOwnerDoc()->IsCaseSensitive())) { + if (IsInHTMLDocument()) { nsAutoString lower; ToLowerCase(aStr, lower); return mAttrsAndChildren.GetExistingAttrNameFromQName( diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index 205f21b20f7b..fe42ac82eb62 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -172,7 +172,6 @@ public: virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify); virtual PRBool IsNodeOfType(PRUint32 aFlags) const; - virtual void RemoveFocus(nsPresContext *aPresContext); virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull) { PRBool isFocusable = PR_FALSE; @@ -544,13 +543,6 @@ public: NS_HIDDEN_(nsresult) GetEditorInternal(nsIEditor** aEditor); protected: - /** - * Focus or blur the element. This is what you should call if you want to - * *cause* a focus or blur on your element. SetFocus / SetBlur are the - * methods where you want to catch what occurs on your element. - * @param aDoFocus true to focus, false to blur - */ - void SetElementFocus(PRBool aDoFocus); /** * Register or unregister an access key to this element based on the * accesskey attribute. @@ -832,6 +824,8 @@ public: virtual PRUint32 GetDesiredIMEState(); virtual PRInt32 IntrinsicState() const; + virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor); + protected: virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, const nsAString* aValue, PRBool aNotify); @@ -846,11 +840,6 @@ protected: void UpdateEditableFormControlState(); - void SetFocusAndScrollIntoView(nsPresContext* aPresContext); - - // A sane SetFocus implementation for focusable form controls - void DoSetFocus(nsPresContext* aPresContext); - // The focusability state of this form control. eUnfocusable means that it // shouldn't be focused at all, eInactiveWindow means it's in an inactive // window, eActiveWindow means it's in an active window. diff --git a/content/html/content/src/nsHTMLAnchorElement.cpp b/content/html/content/src/nsHTMLAnchorElement.cpp index aa07c4ecd38f..7c619cfba765 100644 --- a/content/html/content/src/nsHTMLAnchorElement.cpp +++ b/content/html/content/src/nsHTMLAnchorElement.cpp @@ -113,7 +113,6 @@ public: PRBool aCompileEventHandlers); virtual void UnbindFromTree(PRBool aDeep = PR_TRUE, PRBool aNullParent = PR_TRUE); - virtual void SetFocus(nsPresContext* aPresContext); virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex); virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor); @@ -240,40 +239,13 @@ nsHTMLAnchorElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) NS_IMETHODIMP nsHTMLAnchorElement::Blur() { - if (ShouldBlur(this)) { - SetElementFocus(PR_FALSE); - } - - return NS_OK; + return nsGenericHTMLElement::Blur(); } NS_IMETHODIMP nsHTMLAnchorElement::Focus() { - if (ShouldFocus(this)) { - SetElementFocus(PR_TRUE); - } - - return NS_OK; -} - -void -nsHTMLAnchorElement::SetFocus(nsPresContext* aPresContext) -{ - if (!aPresContext) { - return; - } - - // don't make the link grab the focus if there is no link handler - nsILinkHandler *handler = aPresContext->GetLinkHandler(); - if (handler && aPresContext->EventStateManager()-> - SetContentState(this, NS_EVENT_STATE_FOCUS)) { - nsCOMPtr presShell = aPresContext->GetPresShell(); - if (presShell) { - presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE, - NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE); - } - } + return nsGenericHTMLElement::Focus(); } PRBool @@ -283,6 +255,19 @@ nsHTMLAnchorElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex) return PR_TRUE; } + // cannot focus links if there is no link handler + nsIDocument* doc = GetCurrentDoc(); + if (doc) { + nsIPresShell* presShell = doc->GetPrimaryShell(); + if (presShell) { + nsPresContext* presContext = presShell->GetPresContext(); + if (presContext && !presContext->GetLinkHandler()) { + *aIsFocusable = PR_FALSE; + return PR_FALSE; + } + } + } + if (IsEditable()) { if (aTabIndex) { *aTabIndex = -1; diff --git a/content/html/content/src/nsHTMLAreaElement.cpp b/content/html/content/src/nsHTMLAreaElement.cpp index 39b442704bed..fe9ade6ba93a 100644 --- a/content/html/content/src/nsHTMLAreaElement.cpp +++ b/content/html/content/src/nsHTMLAreaElement.cpp @@ -92,8 +92,6 @@ public: virtual PRBool IsLink(nsIURI** aURI) const; virtual void GetLinkTarget(nsAString& aTarget); - virtual void SetFocus(nsPresContext* aPresContext); - virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, PRBool aCompileEventHandlers); @@ -200,21 +198,6 @@ nsHTMLAreaElement::GetLinkTarget(nsAString& aTarget) } } -void -nsHTMLAreaElement::SetFocus(nsPresContext* aPresContext) -{ - if (!aPresContext || - !aPresContext->EventStateManager()->SetContentState(this, - NS_EVENT_STATE_FOCUS)) { - return; - } - nsCOMPtr presShell = aPresContext->GetPresShell(); - if (presShell) { - presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_ANYWHERE, - NS_PRESSHELL_SCROLL_ANYWHERE); - } -} - nsresult nsHTMLAreaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, diff --git a/content/html/content/src/nsHTMLButtonElement.cpp b/content/html/content/src/nsHTMLButtonElement.cpp index 2a0dba84dc25..7df47786deb8 100644 --- a/content/html/content/src/nsHTMLButtonElement.cpp +++ b/content/html/content/src/nsHTMLButtonElement.cpp @@ -60,6 +60,7 @@ #include "nsEventDispatcher.h" #include "nsPresState.h" #include "nsLayoutErrors.h" +#include "nsFocusManager.h" #define NS_IN_SUBMIT_CLICK (1 << 0) #define NS_OUTER_ACTIVATE_EVENT (1 << 1) @@ -110,7 +111,6 @@ public: const nsAString* aValue, PRBool aNotify); // nsIContent overrides... - virtual void SetFocus(nsPresContext* aPresContext); virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex); virtual PRBool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, @@ -193,21 +193,13 @@ NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLButtonElement, Type, type, "submit") NS_IMETHODIMP nsHTMLButtonElement::Blur() { - if (ShouldBlur(this)) { - SetElementFocus(PR_FALSE); - } - - return NS_OK; + return nsGenericHTMLElement::Blur(); } NS_IMETHODIMP nsHTMLButtonElement::Focus() { - if (ShouldFocus(this)) { - SetElementFocus(PR_TRUE); - } - - return NS_OK; + return nsGenericHTMLElement::Focus(); } NS_IMETHODIMP @@ -254,17 +246,11 @@ nsHTMLButtonElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex) *aTabIndex = -1; } - *aIsFocusable = PR_TRUE; + *aIsFocusable = !HasAttr(kNameSpaceID_None, nsGkAtoms::disabled); return PR_FALSE; } -void -nsHTMLButtonElement::SetFocus(nsPresContext* aPresContext) -{ - DoSetFocus(aPresContext); -} - static const nsAttrValue::EnumTable kButtonTypeTable[] = { { "button", NS_FORM_BUTTON_BUTTON }, { "reset", NS_FORM_BUTTON_RESET }, @@ -404,7 +390,11 @@ nsHTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) if (static_cast(aVisitor.mEvent)->button == nsMouseEvent::eLeftButton) { aVisitor.mPresContext->EventStateManager()-> - SetContentState(this, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS); + SetContentState(this, NS_EVENT_STATE_ACTIVE); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) + fm->SetFocus(this, nsIFocusManager::FLAG_BYMOUSE | + nsIFocusManager::FLAG_NOSCROLL); aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; } else if (static_cast(aVisitor.mEvent)->button == nsMouseEvent::eMiddleButton || diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 3de9f4b64485..5957b8cf2b0c 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -46,6 +46,7 @@ #include "nsIPhonetic.h" #include "nsIControllers.h" +#include "nsFocusManager.h" #include "nsPIDOMWindow.h" #include "nsContentCID.h" #include "nsIComponentManager.h" @@ -86,6 +87,8 @@ #include "nsUnicharUtils.h" #include "nsEventDispatcher.h" #include "nsLayoutUtils.h" +#include "nsWidgetsCID.h" +#include "nsILookAndFeel.h" #include "nsIDOMMutationEvent.h" #include "nsIDOMEventTarget.h" @@ -116,6 +119,8 @@ // XXX align=left, hspace, vspace, border? other nav4 attrs static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID); +static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); + // // Accessors for mBitField // @@ -148,6 +153,10 @@ static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID); static const char kWhitespace[] = "\n\r\t\b"; +// whether textfields should be selected once focused: +// -1: no, 1: yes, 0: uninitialized +static PRInt32 gSelectTextFieldOnFocus; + #define NS_INPUT_ELEMENT_STATE_IID \ { /* dc3b3d14-23e2-4479-b513-7b369343e3a0 */ \ 0xdc3b3d14, \ @@ -260,7 +269,6 @@ public: virtual PRBool AllowDrop(); // nsIContent - virtual void SetFocus(nsPresContext* aPresContext); virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex); virtual PRBool ParseAttribute(PRInt32 aNamespaceID, @@ -280,7 +288,7 @@ public: PRBool aCompileEventHandlers); virtual void UnbindFromTree(PRBool aDeep = PR_TRUE, PRBool aNullParent = PR_TRUE); - + virtual void DoneCreatingElement(); virtual PRInt32 IntrinsicState() const; @@ -348,6 +356,11 @@ protected: virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, const nsAString* aValue, PRBool aNotify); + /** + * Dispatch a select event. Returns true if the event was not cancelled. + */ + PRBool DispatchSelectEvent(nsPresContext* aPresContext); + void SelectAll(nsPresContext* aPresContext); PRBool IsImage() const { @@ -1335,27 +1348,36 @@ nsHTMLInputElement::FireOnChange() NS_IMETHODIMP nsHTMLInputElement::Blur() { - if (ShouldFocus(this)) { - SetElementFocus(PR_FALSE); - } - - return NS_OK; + return nsGenericHTMLElement::Blur(); } NS_IMETHODIMP nsHTMLInputElement::Focus() { - if (ShouldFocus(this)) { - SetElementFocus(PR_TRUE); + if (mType == NS_FORM_INPUT_FILE) { + // for file inputs, focus the button instead + nsIFrame* frame = GetPrimaryFrame(); + if (frame) { + nsIFrame* childFrame = frame->GetFirstChild(nsnull); + while (childFrame) { + // see if the child is a button control + nsCOMPtr formCtrl = + do_QueryInterface(childFrame->GetContent()); + if (formCtrl && formCtrl->GetType() == NS_FORM_INPUT_BUTTON) { + nsCOMPtr element(do_QueryInterface(formCtrl)); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm && element) + fm->SetFocus(element, 0); + } + + childFrame = childFrame->GetNextSibling(); + } + } + + return NS_OK; } - return NS_OK; -} - -void -nsHTMLInputElement::SetFocus(nsPresContext* aPresContext) -{ - DoSetFocus(aPresContext); + return nsGenericHTMLElement::Focus(); } NS_IMETHODIMP @@ -1373,51 +1395,23 @@ nsHTMLInputElement::Select() return NS_OK; } + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + nsCOMPtr presContext = GetPresContext(); if (state == eInactiveWindow) { + if (fm) + fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL); SelectAll(presContext); return NS_OK; } - // Just like SetFocus() but without the ScrollIntoView()! - nsEventStatus status = nsEventStatus_eIgnore; - - //If already handling select event, don't dispatch a second. - if (!GET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT)) { - nsEvent event(nsContentUtils::IsCallerChrome(), NS_FORM_SELECTED); - - SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_TRUE); - nsEventDispatcher::Dispatch(static_cast(this), - presContext, &event, nsnull, &status); - SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_FALSE); - } - - // If the DOM event was not canceled (e.g. by a JS event handler - // returning false) - if (status == nsEventStatus_eIgnore) { - PRBool shouldFocus = ShouldFocus(this); - - if (presContext && shouldFocus) { - nsIEventStateManager *esm = presContext->EventStateManager(); - // XXX Fix for bug 135345 - ESM currently does not check to see if we - // have focus before attempting to set focus again and may cause - // infinite recursion. For now check if we have focus and do not set - // focus again if already focused. - PRInt32 currentState; - esm->GetContentState(this, currentState); - if (!(currentState & NS_EVENT_STATE_FOCUS) && - !esm->SetContentState(this, NS_EVENT_STATE_FOCUS)) { - return NS_OK; // We ended up unfocused, e.g. due to a DOM event handler. - } - } - - nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); - - if (formControlFrame) { - if (shouldFocus) { - formControlFrame->SetFocus(PR_TRUE, PR_TRUE); - } + if (DispatchSelectEvent(presContext) && fm) { + fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL); + // ensure that the element is actually focused + nsCOMPtr focusedElement; + fm->GetFocusedElement(getter_AddRefs(focusedElement)); + if (SameCOMIdentity(static_cast(this), focusedElement)) { // Now Select all the text! SelectAll(presContext); } @@ -1426,6 +1420,26 @@ nsHTMLInputElement::Select() return NS_OK; } +PRBool +nsHTMLInputElement::DispatchSelectEvent(nsPresContext* aPresContext) +{ + nsEventStatus status = nsEventStatus_eIgnore; + + // If already handling select event, don't dispatch a second. + if (!GET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT)) { + nsEvent event(nsContentUtils::IsCallerChrome(), NS_FORM_SELECTED); + + SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_TRUE); + nsEventDispatcher::Dispatch(static_cast(this), + aPresContext, &event, nsnull, &status); + SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_FALSE); + } + + // If the DOM event was not canceled (e.g. by a JS event handler + // returning false) + return (status == nsEventStatus_eIgnore); +} + void nsHTMLInputElement::SelectAll(nsPresContext* aPresContext) { @@ -1638,7 +1652,26 @@ nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) } } - return nsGenericHTMLElement::PreHandleEvent(aVisitor); + return nsGenericHTMLFormElement::PreHandleEvent(aVisitor); +} + +static PRBool +SelectTextFieldOnFocus() +{ + if (!gSelectTextFieldOnFocus) { + nsCOMPtr lookNFeel(do_GetService(kLookAndFeelCID)); + if (lookNFeel) { + PRInt32 selectTextfieldsOnKeyFocus = -1; + lookNFeel->GetMetric(nsILookAndFeel::eMetric_SelectTextfieldsOnKeyFocus, + selectTextfieldsOnKeyFocus); + gSelectTextFieldOnFocus = selectTextfieldsOnKeyFocus != 0 ? 1 : -1; + } + else { + gSelectTextFieldOnFocus = -1; + } + } + + return gSelectTextFieldOnFocus == 1; } nsresult @@ -1747,15 +1780,24 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) case NS_FOCUS_CONTENT: { - // Check to see if focus has bubbled up from a form control's - // child textfield or button. If that's the case, don't focus - // this parent file control -- leave focus on the child. - nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE); - if (formControlFrame && ShouldFocus(this) && - aVisitor.mEvent->originalTarget == static_cast(this)) - formControlFrame->SetFocus(PR_TRUE, PR_TRUE); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm && (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) && + SelectTextFieldOnFocus()) { + // select the text if the field was focused by the keyboard. + nsIDocument* document = GetCurrentDoc(); + if (document) { + PRUint32 lastFocusMethod; + fm->GetLastFocusMethod(document->GetWindow(), &lastFocusMethod); + if (lastFocusMethod & nsIFocusManager::FLAG_BYKEY) { + nsCOMPtr presContext = GetPresContext(); + if (DispatchSelectEvent(presContext)) { + SelectAll(presContext); + } + } + } + } + break; } - break; // NS_FOCUS_CONTENT case NS_KEY_PRESS: case NS_KEY_UP: @@ -2955,13 +2997,25 @@ nsHTMLInputElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex) return PR_TRUE; } + if (HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) { + *aIsFocusable = PR_FALSE; + return PR_TRUE; + } + if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) { *aIsFocusable = PR_TRUE; return PR_FALSE; } - if (mType == NS_FORM_INPUT_HIDDEN || mType == NS_FORM_INPUT_FILE) { - // Sub controls of file input are tabbable, not the file input itself. + if (mType == NS_FORM_INPUT_FILE) { + if (aTabIndex) { + *aTabIndex = -1; + } + *aIsFocusable = PR_TRUE; + return PR_TRUE; + } + + if (mType == NS_FORM_INPUT_HIDDEN) { if (aTabIndex) { *aTabIndex = -1; } diff --git a/content/html/content/src/nsHTMLLabelElement.cpp b/content/html/content/src/nsHTMLLabelElement.cpp index 8bd1ff6965a4..67b1d7e4f44d 100644 --- a/content/html/content/src/nsHTMLLabelElement.cpp +++ b/content/html/content/src/nsHTMLLabelElement.cpp @@ -51,6 +51,7 @@ #include "nsIEventStateManager.h" #include "nsEventDispatcher.h" #include "nsPIDOMWindow.h" +#include "nsFocusManager.h" class nsHTMLLabelElement : public nsGenericHTMLFormElement, public nsIDOMHTMLLabelElement @@ -80,6 +81,8 @@ public: NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission, nsIContent* aSubmitElement); + NS_IMETHOD Focus(); + // nsIContent virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, @@ -89,7 +92,6 @@ public: virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor); - virtual void SetFocus(nsPresContext* aContext); nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, const nsAString& aValue, PRBool aNotify) { @@ -110,7 +112,6 @@ protected: // XXX It would be nice if we could use an event flag instead. PRPackedBool mHandlingEvent; - PRPackedBool mInSetFocus; }; // construction, destruction @@ -122,7 +123,6 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Label) nsHTMLLabelElement::nsHTMLLabelElement(nsINodeInfo *aNodeInfo) : nsGenericHTMLFormElement(aNodeInfo) , mHandlingEvent(PR_FALSE) - , mInSetFocus(PR_FALSE) { } @@ -161,6 +161,21 @@ nsHTMLLabelElement::GetForm(nsIDOMHTMLFormElement** aForm) NS_IMPL_STRING_ATTR(nsHTMLLabelElement, AccessKey, accesskey) NS_IMPL_STRING_ATTR(nsHTMLLabelElement, HtmlFor, _for) +NS_IMETHODIMP +nsHTMLLabelElement::Focus() +{ + // retarget the focus method at the for content + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) { + nsCOMPtr content = GetForContent(); + nsCOMPtr elem = do_QueryInterface(content); + if (elem) + fm->SetFocus(elem, 0); + } + + return NS_OK; +} + nsresult nsHTMLLabelElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, @@ -222,7 +237,6 @@ nsHTMLLabelElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) { if (mHandlingEvent || (!NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent) && - aVisitor.mEvent->message != NS_FOCUS_CONTENT && aVisitor.mEvent->message != NS_MOUSE_BUTTON_DOWN) || aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault || !aVisitor.mPresContext) { @@ -276,10 +290,14 @@ nsHTMLLabelElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) break; } - if (ShouldFocus(this)) { - // Focus the for content. - aVisitor.mPresContext->EventStateManager()-> - ChangeFocusWith(content, nsIEventStateManager::eEventFocusedByKey); + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm) { + // Use FLAG_BYKEY here so that the label is scrolled to. Also, + // within nsHTMLInputElement::PostHandleEvent, inputs will be + // selected only when focused via a key and we want to select + // the text on label clicks as well. + nsCOMPtr elem = do_QueryInterface(content); + fm->SetFocus(elem, nsIFocusManager::FLAG_BYKEY); } // Dispatch a new click event to |content| @@ -297,40 +315,12 @@ nsHTMLLabelElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) // Do we care about the status this returned? I don't think we do... } break; - case NS_FOCUS_CONTENT: - // Since we don't have '-moz-user-focus: normal', the only time - // the event type will be NS_FOCUS_CONTENT will be when the accesskey - // is activated. We've already redirected the |SetFocus| call in that - // case. - // Since focus doesn't bubble, this is basically the second part - // of redirecting |SetFocus|. - { - nsEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_FOCUS_CONTENT); - event.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - nsEventStatus status = aVisitor.mEventStatus; - DispatchEvent(aVisitor.mPresContext, &event, - content, PR_TRUE, &status); - // Do we care about the status this returned? I don't think we do... - } - break; } mHandlingEvent = PR_FALSE; } return NS_OK; } -void -nsHTMLLabelElement::SetFocus(nsPresContext* aContext) -{ - if (mInSetFocus) - return; - mInSetFocus = PR_TRUE; - nsCOMPtr content = GetForContent(); - if (content) - content->SetFocus(aContext); - mInSetFocus = PR_FALSE; -} - nsresult nsHTMLLabelElement::Reset() { diff --git a/content/html/content/src/nsHTMLLegendElement.cpp b/content/html/content/src/nsHTMLLegendElement.cpp index 05fe85f1c6f0..0a5bece5dd0e 100644 --- a/content/html/content/src/nsHTMLLegendElement.cpp +++ b/content/html/content/src/nsHTMLLegendElement.cpp @@ -45,10 +45,10 @@ #include "nsIForm.h" #include "nsIFormControl.h" #include "nsIEventStateManager.h" -#include "nsIFocusController.h" #include "nsIDocument.h" #include "nsPIDOMWindow.h" - +#include "nsFocusManager.h" +#include "nsIFrame.h" class nsHTMLLegendElement : public nsGenericHTMLFormElement, public nsIDOMHTMLLegendElement @@ -78,13 +78,17 @@ public: NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission, nsIContent* aSubmitElement); + NS_IMETHODIMP Focus(); + + virtual void PerformAccesskey(PRBool aKeyCausesActivation, + PRBool aIsTrustedEvent); + // nsIContent virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, PRBool aCompileEventHandlers); virtual void UnbindFromTree(PRBool aDeep = PR_TRUE, PRBool aNullParent = PR_TRUE); - virtual void SetFocus(nsPresContext* aPresContext); virtual PRBool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, @@ -103,9 +107,6 @@ public: PRBool aNotify); virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; - -protected: - PRPackedBool mInSetFocus; }; @@ -114,7 +115,6 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Legend) nsHTMLLegendElement::nsHTMLLegendElement(nsINodeInfo *aNodeInfo) : nsGenericHTMLFormElement(aNodeInfo) - , mInSetFocus(PR_FALSE) { } @@ -253,32 +253,34 @@ nsHTMLLegendElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent); } -void -nsHTMLLegendElement::SetFocus(nsPresContext* aPresContext) +NS_IMETHODIMP +nsHTMLLegendElement::Focus() { - nsIDocument *document = GetCurrentDoc(); - if (!aPresContext || !document || mInSetFocus) { - return; - } + nsIFrame* frame = GetPrimaryFrame(); + if (!frame) + return NS_OK; - mInSetFocus = PR_TRUE; - if (IsFocusable()) { - nsGenericHTMLFormElement::SetFocus(aPresContext); - } else { - // If the legend isn't focusable (no tabindex) we focus whatever is - // focusable following the legend instead, bug 81481. - nsCOMPtr ourWindow = document->GetWindow(); - if (ourWindow) { - nsIFocusController* focusController = - ourWindow->GetRootFocusController(); - nsCOMPtr domElement = - do_QueryInterface(static_cast(this)); - if (focusController && domElement) { - focusController->MoveFocus(PR_TRUE, domElement); - } - } - } - mInSetFocus = PR_FALSE; + PRInt32 tabIndex; + if (frame->IsFocusable(&tabIndex)) + return nsGenericHTMLElement::Focus(); + + // If the legend isn't focusable, focus whatever is focusable following + // the legend instead, bug 81481. + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (!fm) + return NS_OK; + + nsCOMPtr result; + return fm->MoveFocus(nsnull, this, nsIFocusManager::MOVEFOCUS_FORWARD, 0, + getter_AddRefs(result)); +} + +void +nsHTMLLegendElement::PerformAccesskey(PRBool aKeyCausesActivation, + PRBool aIsTrustedEvent) +{ + // just use the same behaviour as the focus method + Focus(); } NS_IMETHODIMP diff --git a/content/html/content/src/nsHTMLSelectElement.cpp b/content/html/content/src/nsHTMLSelectElement.cpp index 5aaaa94c260f..f21d164e6791 100644 --- a/content/html/content/src/nsHTMLSelectElement.cpp +++ b/content/html/content/src/nsHTMLSelectElement.cpp @@ -1209,27 +1209,13 @@ NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLSelectElement, TabIndex, tabindex, 0) NS_IMETHODIMP nsHTMLSelectElement::Blur() { - if (ShouldBlur(this)) { - SetElementFocus(PR_FALSE); - } - - return NS_OK; + return nsGenericHTMLElement::Blur(); } NS_IMETHODIMP nsHTMLSelectElement::Focus() { - if (ShouldFocus(this)) { - SetElementFocus(PR_TRUE); - } - - return NS_OK; -} - -void -nsHTMLSelectElement::SetFocus(nsPresContext* aPresContext) -{ - DoSetFocus(aPresContext); + return nsGenericHTMLElement::Focus(); } PRBool @@ -1241,7 +1227,7 @@ nsHTMLSelectElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex) if (aTabIndex && (sTabFocusModel & eTabFocus_formElementsMask) == 0) { *aTabIndex = -1; } - *aIsFocusable = PR_TRUE; + *aIsFocusable = !HasAttr(kNameSpaceID_None, nsGkAtoms::disabled); return PR_FALSE; } @@ -1449,17 +1435,7 @@ nsHTMLSelectElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) } } - // Must notify the frame that the blur event occurred - // NOTE: At this point EventStateManager has not yet set the - // new content as having focus so this content is still considered - // the focused element. So the ComboboxControlFrame tracks the focus - // at a class level (Bug 32920) - if (nsEventStatus_eIgnore == aVisitor.mEventStatus && - (aVisitor.mEvent->message == NS_BLUR_CONTENT) && formControlFrame) { - formControlFrame->SetFocus(PR_FALSE, PR_TRUE); - } - - return nsGenericHTMLElement::PreHandleEvent(aVisitor); + return nsGenericHTMLFormElement::PreHandleEvent(aVisitor); } // nsIFormControl diff --git a/content/html/content/src/nsHTMLSelectElement.h b/content/html/content/src/nsHTMLSelectElement.h index 9310f8c30cf5..1dabe71fe096 100644 --- a/content/html/content/src/nsHTMLSelectElement.h +++ b/content/html/content/src/nsHTMLSelectElement.h @@ -268,7 +268,6 @@ public: // nsIContent virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor); - virtual void SetFocus(nsPresContext* aPresContext); virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex); virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex, PRBool aNotify); diff --git a/content/html/content/src/nsHTMLStyleElement.cpp b/content/html/content/src/nsHTMLStyleElement.cpp index 76b4db48fe07..0e0a4d9f7a54 100644 --- a/content/html/content/src/nsHTMLStyleElement.cpp +++ b/content/html/content/src/nsHTMLStyleElement.cpp @@ -321,8 +321,7 @@ nsHTMLStyleElement::GetStyleSheetURL(PRBool* aIsInline, if (*aIsInline) { return; } - if (GetOwnerDoc() && // XXX clean up after bug 335998 lands - !(GetOwnerDoc()->IsCaseSensitive())) { + if (!IsInHTMLDocument()) { // We stopped supporting