Bug 1042199 - Show a search box on error pages. r=margaret

This commit is contained in:
Wes Johnston 2014-09-16 16:34:52 -07:00
parent 7e8040ba9f
commit 0dbf84857e
8 changed files with 119 additions and 33 deletions

View File

@ -1813,11 +1813,11 @@ public class BrowserApp extends GeckoApp
final Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null) {
final String userSearch = tab.getUserSearch();
final String userRequested = tab.getUserRequested();
// Check to see if there's a user-entered search term,
// which we save whenever the user performs a search.
url = (TextUtils.isEmpty(userSearch) ? tab.getURL() : userSearch);
url = (TextUtils.isEmpty(userRequested) ? tab.getURL() : userRequested);
}
enterEditingMode(url);

View File

@ -38,7 +38,7 @@ public class Tab {
private long mLastUsed;
private String mUrl;
private String mBaseDomain;
private String mUserSearch;
private String mUserRequested; // The original url requested. May be typed by the user or sent by an extneral app for example.
private String mTitle;
private Bitmap mFavicon;
private String mFaviconUrl;
@ -97,7 +97,7 @@ public class Tab {
mId = id;
mUrl = url;
mBaseDomain = "";
mUserSearch = "";
mUserRequested = "";
mExternal = external;
mParentId = parentId;
mTitle = title == null ? "" : title;
@ -147,9 +147,9 @@ public class Tab {
return mUrl;
}
// mUserSearch should never be null, but it may be an empty string
public synchronized String getUserSearch() {
return mUserSearch;
// mUserRequested should never be null, but it may be an empty string
public synchronized String getUserRequested() {
return mUserRequested;
}
// mTitle should never be null, but it may be an empty string
@ -268,8 +268,8 @@ public class Tab {
}
}
private synchronized void updateUserSearch(String userSearch) {
mUserSearch = userSearch;
public synchronized void updateUserRequested(String userRequested) {
mUserRequested = userRequested;
}
public void setErrorType(String type) {
@ -654,7 +654,7 @@ public class Tab {
}
setContentType(message.getString("contentType"));
updateUserSearch(message.getString("userSearch"));
updateUserRequested(message.getString("userRequested"));
mBaseDomain = message.optString("baseDomain");
setHasFeeds(false);

View File

@ -488,6 +488,7 @@ public class Tabs implements GeckoEventListener {
notifyListeners(tab, Tabs.TabEvents.LOAD_ERROR);
} else if (event.equals("Content:PageShow")) {
notifyListeners(tab, TabEvents.PAGE_SHOW);
tab.updateUserRequested(message.getString("userRequested"));
} else if (event.equals("DOMContentLoaded")) {
tab.handleContentLoaded();
String backgroundColor = message.getString("bgColor");

View File

@ -961,7 +961,8 @@ var BrowserApp = {
let tab = this.getTabForBrowser(aBrowser);
if (tab) {
if ("userSearch" in aParams) tab.userSearch = aParams.userSearch;
if ("userRequested" in aParams) tab.userRequested = aParams.userRequested;
tab.isSearch = ("isSearch" in aParams) ? aParams.isSearch : false;
}
try {
@ -1585,13 +1586,15 @@ var BrowserApp = {
desktopMode: (data.desktopMode === true)
};
params.userRequested = url;
if (data.engine) {
let engine = Services.search.getEngineByName(data.engine);
if (engine) {
params.userSearch = url;
let submission = engine.getSubmission(url);
url = submission.uri.spec;
params.postData = submission.postData;
params.isSearch = true;
}
}
@ -1623,7 +1626,7 @@ var BrowserApp = {
// This event refers to a search via the URL bar, not a bookmarks
// keyword search. Note that this code assumes that the user can only
// perform a keyword search on the selected tab.
this.selectedTab.userSearch = aData;
this.isSearch = true;
// Don't store queries in private browsing mode.
let isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.selectedTab.browser.contentWindow);
@ -3265,7 +3268,8 @@ Tab.prototype = {
let charset = "charset" in aParams ? aParams.charset : null;
// The search term the user entered to load the current URL
this.userSearch = "userSearch" in aParams ? aParams.userSearch : "";
this.userRequested = "userRequested" in aParams ? aParams.userRequested : "";
this.isSearch = "isSearch" in aParams ? aParams.isSearch : false;
try {
this.browser.loadURIWithFlags(aURL, flags, referrerURI, charset, postData);
@ -3794,16 +3798,6 @@ Tab.prototype = {
else if (docURI.startsWith("about:neterror"))
errorType = "neterror";
Messaging.sendRequest({
type: "DOMContentLoaded",
tabID: this.id,
bgColor: backgroundColor,
errorType: errorType,
metadata: this.metatags
});
this.metatags = null;
// Attach a listener to watch for "click" events bubbling up from error
// pages and other similar page. This lets us fix bugs like 401575 which
// require error page UI to do privileged things, without letting error
@ -3812,6 +3806,17 @@ Tab.prototype = {
NetErrorHelper.attachToBrowser(this.browser);
}
Messaging.sendRequest({
type: "DOMContentLoaded",
tabID: this.id,
bgColor: backgroundColor,
errorType: errorType,
metadata: this.metatags,
});
// Reset isSearch so that the userRequested term will be erased on next page load
this.metatags = null;
if (docURI.startsWith("about:certerror") || docURI.startsWith("about:blocked")) {
this.browser.addEventListener("click", ErrorPageEventHandler, true);
let listener = function() {
@ -4081,11 +4086,21 @@ Tab.prototype = {
if (aEvent.originalTarget.defaultView != this.browser.contentWindow)
return;
let target = aEvent.originalTarget;
let docURI = target.documentURI;
if (!docURI.startsWith("about:neterror") && !this.isSearch) {
// If this wasn't an error page and the user isn't search, don't retain the typed entry
this.userRequested = "";
}
Messaging.sendRequest({
type: "Content:PageShow",
tabID: this.id
tabID: this.id,
userRequested: this.userRequested
});
this.isSearch = false;
if (!aEvent.persisted && Services.prefs.getBoolPref("browser.ui.linkify.phone")) {
if (!this._linkifier)
this._linkifier = new Linkifier();
@ -4268,7 +4283,7 @@ Tab.prototype = {
type: "Content:LocationChange",
tabID: this.id,
uri: truncate(fixedURI.spec, MAX_URI_LENGTH),
userSearch: this.userSearch || "",
userRequested: this.userRequested || "",
baseDomain: baseDomain,
contentType: (contentType ? contentType : ""),
sameDocument: sameDocument
@ -4276,9 +4291,6 @@ Tab.prototype = {
Messaging.sendRequest(message);
// The search term is only valid for this location change event, so reset it here.
this.userSearch = "";
if (!sameDocument) {
// XXX This code assumes that this is the earliest hook we have at which
// browser.contentDocument is changed to the new document we're loading

View File

@ -299,9 +299,9 @@
</div>
<div id="errorDescriptionsContainer">
<div id="ed_generic">&generic.longDesc;</div>
<div id="ed_dnsNotFound">&dnsNotFound.longDesc3;</div>
<div id="ed_dnsNotFound">&dnsNotFound.longDesc4;</div>
<div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
<div id="ed_malformedURI">&malformedURI.longDesc;</div>
<div id="ed_malformedURI">&malformedURI.longDesc2;</div>
<div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
<div id="ed_connectionFailure">&connectionFailure.longDesc2;</div>
<div id="ed_netTimeout">&netTimeout.longDesc2;</div>

View File

@ -62,6 +62,36 @@ NetErrorHelper.prototype = {
},
}
handlers.searchbutton = {
onPageShown: function(browser) {
let search = browser.contentDocument.querySelector("#searchbox");
if (!search) {
return;
}
let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
let tab = browserWin.BrowserApp.getTabForBrowser(browser);
// If there is no stored userRequested, just hide the searchbox
if (!tab.userRequested) {
search.style.display = "none";
} else {
let text = browser.contentDocument.querySelector("#searchtext");
text.value = tab.userRequested;
}
},
handleClick: function(event) {
let engine = Services.search.defaultEngine;
let value = event.target.previousElementSibling.value;
let uri = engine.getSubmission(value).uri;
let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
// Reset the user search to whatever the new search term was
browserWin.BrowserApp.loadURI(uri.spec, undefined, { isSearch: true, userRequested: value });
}
};
handlers.wifi = {
// This registers itself with the nsIObserverService as a weak ref,
// so we have to implement GetWeakReference as well.

View File

@ -199,3 +199,28 @@ div[collapsed="true"] > .expander + * {
}
}
}
#searchbox {
padding: 0;
display: flex;
margin: var(--moz-vertical-spacing) -1em;
}
#searchbox > input {
flex: 3;
padding: 0em 3em 0em 1em;
width: 100%;
border: none;
font-family: sans-serif;
background-image: none;
background-color: white;
border-radius-top-right: none;
border-radius-bottom-right: none;
}
#searchbox > button {
flex: 1;
margin: 0;
width: auto;
}

View File

@ -17,11 +17,17 @@
<!ENTITY deniedPortAccess.longDesc "">
<!ENTITY dnsNotFound.title "Server not found">
<!ENTITY dnsNotFound.longDesc3 "
<!-- LOCALIZATION NOTE (dnsNotFound.longDesc4) This string contains markup including widgets for searching
or enabling wifi connections. The text inside tags should be localized. Do not change the ids. -->
<!ENTITY dnsNotFound.longDesc4 "
<ul>
<li>Check the address for typing errors such as
<strong>ww</strong>.example.com instead of
<strong>www</strong>.example.com</li>
<div id='searchbox'>
<input id='searchtext' type='search'></input>
<button id='searchbutton'>Search</button>
</div>
<li>If you are unable to load any pages, check your device's data or Wi-Fi connection.
<button id='wifi'>Enable Wi-Fi</button>
</li>
@ -43,10 +49,16 @@
">
<!ENTITY malformedURI.title "The address isn't valid">
<!ENTITY malformedURI.longDesc "
<!-- LOCALIZATION NOTE (malformedURI.longDesc2) This string contains markup including widgets for searching
or enabling wifi connections. The text inside the tags should be localized. Do not touch the ids. -->
<!ENTITY malformedURI.longDesc2 "
<ul>
<li>Web addresses are usually written like
<strong>http://www.example.com/</strong></li>
<div id='searchbox'>
<input id='searchtext' type='search'></input>
<button id='searchbutton'>Search</button>
</div>
<li>Make sure that you're using forward slashes (i.e.
<strong>/</strong>).</li>
</ul>
@ -59,6 +71,8 @@
<!ENTITY notCached.longDesc "<p>The requested document is not available in &brandShortName;'s cache.</p><ul><li>As a security precaution, &brandShortName; does not automatically re-request sensitive documents.</li><li>Click Try Again to re-request the document from the website.</li></ul>">
<!ENTITY netOffline.title "Offline mode">
<!-- LOCALIZATION NOTE (netOffline.longDesc3) This string contains markup including widgets enabling wifi connections.
The text inside the tags should be localized. Do not touch the ids. -->
<!ENTITY netOffline.longDesc3 "
<ul>
<li>Try again. &brandShortName; will attempt to open a connection and reload the page.
@ -104,6 +118,8 @@
">
<!ENTITY proxyResolveFailure.title "Unable to find the proxy server">
<!-- LOCALIZATION NOTE (proxyResolveFailure.longDesc3) This string contains markup including widgets for enabling wifi connections.
The text inside the tags should be localized. Do not touch the ids. -->
<!ENTITY proxyResolveFailure.longDesc3 "
<ul>
<li>Check the proxy settings to make sure that they are correct.</li>
@ -148,6 +164,8 @@ be temporary, and you can try again later.</li>
</ul>
">
<!-- LOCALIZATION NOTE (sharedLongDesc3) This string contains markup including widgets for enabling wifi connections.
The text inside the tags should be localized. Do not touch the ids. -->
<!ENTITY sharedLongDesc3 "
<ul>
<li>The site could be temporarily unavailable or too busy. Try again in a few moments.</li>