Backout patch for c7562242f88e due to bustage

This commit is contained in:
Blair McBride 2010-03-11 16:35:37 +13:00
parent 8274492c49
commit bd0b32abc1
31 changed files with 51 additions and 783 deletions

View File

@ -240,7 +240,6 @@ pref("browser.urlbar.delay", 50);
pref("browser.urlbar.restrict.history", "^");
pref("browser.urlbar.restrict.bookmark", "*");
pref("browser.urlbar.restrict.tag", "+");
pref("browser.urlbar.restrict.openpage", "%");
pref("browser.urlbar.restrict.typed", "~");
pref("browser.urlbar.match.title", "#");
pref("browser.urlbar.match.url", "@");
@ -248,8 +247,7 @@ pref("browser.urlbar.match.url", "@");
// The default behavior for the urlbar can be configured to use any combination
// of the restrict or match filters with each additional filter restricting
// more (intersection). Add the following values to set the behavior as the
// default: 1: history, 2: bookmark, 4: tag, 8: title, 16: url, 32: typed,
// 64: javascript, 128: tabs
// default: 1: history, 2: bookmark, 4: tag, 8: title, 16: url, 32: typed
// E.g., 0 = show all results (no filtering), 1 = only visited pages in history,
// 2 = only bookmarks, 3 = visited bookmarks, 1+16 = history matching in the url
pref("browser.urlbar.default.behavior", 0);

View File

@ -43,26 +43,6 @@ toolbar[mode="icons"] > #reload-button[displaystop] {
-moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
}
/* Some child nodes want to be ordered based on the locale's direction, while
everything else should be ltr. */
#urlbar:-moz-locale-dir(rtl) > .autocomplete-textbox-container > .textbox-input-box {
direction: rtl;
}
#urlbar html|*.autocomplete-textbox {
direction: ltr;
}
/* For results that are actions, their description text is shown instead of
the URL - this needs to follow the locale's direction, unlike URLs. */
richlistitem[type="action"]:-moz-locale-dir(rtl) > .ac-url-box {
direction: rtl;
}
#urlbar:not([actiontype]) > #urlbar-display {
display: none;
}
#wrapper-urlbar-container > #urlbar-container > #urlbar {
-moz-user-input: disabled;
cursor: -moz-grab;
@ -76,8 +56,6 @@ richlistitem[type="action"]:-moz-locale-dir(rtl) > .ac-url-box {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
}
#urlbar-throbber:not([busy="true"]),
#urlbar-throbber[busy="true"] + #page-proxy-favicon {
display: none;

View File

@ -3835,6 +3835,7 @@ var XULBrowserWindow = {
overLink: "",
startTime: 0,
statusText: "",
lastURI: null,
isBusy: false,
_progressCollapseTimer: 0,
@ -3898,6 +3899,7 @@ var XULBrowserWindow = {
delete this.statusTextField;
delete this.securityButton;
delete this.statusText;
delete this.lastURI;
},
setJSStatus: function (status) {
@ -4112,6 +4114,7 @@ var XULBrowserWindow = {
nBox.removeTransientNotifications();
}
}
selectedBrowser.lastURI = aLocationURI;
// Disable menu entries for images, enable otherwise
if (content.document && mimeTypeIsTextBased(content.document.contentType))
@ -7483,44 +7486,3 @@ var LightWeightThemeWebInstaller = {
node.baseURI);
}
}
function switchToTabHavingURI(aURI) {
function switchIfURIInWindow(aWindow) {
if (!("gBrowser" in aWindow))
return false;
let browsers = aWindow.gBrowser.browsers;
for (let i = 0; i < browsers.length; i++) {
let browser = browsers[i];
if (browser.currentURI.equals(aURI)) {
gURLBar.handleRevert();
aWindow.focus();
aWindow.gBrowser.tabContainer.selectedIndex = i;
return true;
}
}
return false;
}
// This can be passed either nsIURI or a string.
if (!(aURI instanceof Ci.nsIURI))
aURI = makeURI(aURI);
// Prioritise this window.
if (switchIfURIInWindow(window))
return true;
let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
let winEnum = windowMediator.getEnumerator("navigator:browser");
while (winEnum.hasMoreElements()) {
let browserWin = winEnum.getNext();
// Skip closed (but not yet destroyed) windows,
// and the current window (which was checked earlier).
if (browserWin.closed || browserWin == window)
continue;
if (switchIfURIInWindow(browserWin))
return true;
}
// No opened tab has that url.
return false;
}

View File

@ -405,7 +405,6 @@
noneplaceholder="&urlbar.none.emptyText;"
type="autocomplete"
autocompletesearch="history"
autocompletesearchparam="enable-actions"
autocompletepopup="PopupAutoCompleteRichResult"
completeselectedindex="true"
tabscrolling="true"
@ -444,7 +443,6 @@
</hbox>
</hbox>
</box>
<label id="urlbar-display" value="&urlbar.switchToTab.label;"/>
<hbox id="urlbar-icons">
<button type="menu"
style="-moz-user-focus: none"

View File

@ -154,10 +154,6 @@
Components.classes["@mozilla.org/browser/favicon-service;1"]
.getService(Components.interfaces.nsIFaviconService);
</field>
<field name="mBrowserHistory">
Components.classes["@mozilla.org/browser/nav-history-service;1"]
.getService(Components.interfaces.nsIBrowserHistory);
</field>
<field name="mTabBox" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "tabbox");
</field>
@ -531,30 +527,15 @@
// changing location, clear out the missing plugins list
this.mBrowser.missingPlugins = null;
var browserHistory = this.mTabBrowser.mBrowserHistory;
if ("lastURI" in this.mBrowser && this.mBrowser.lastURI)
browserHistory.unregisterOpenPage(this.mBrowser.lastURI);
browserHistory.registerOpenPage(aLocation);
if (this.mBlank)
return;
if (!this.mBlank) {
if (this.mTabBrowser.mCurrentTab == this.mTab) {
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
let p = this.mTabBrowser.mProgressListeners[i];
if (p)
try {
p.onLocationChange(aWebProgress, aRequest, aLocation);
} catch (e) {
// don't inhibit other listeners
Components.utils.reportError(e);
}
}
}
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
let p = this.mTabBrowser.mTabsProgressListeners[i];
if (this.mTabBrowser.mCurrentTab == this.mTab) {
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
let p = this.mTabBrowser.mProgressListeners[i];
if (p)
try {
p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
p.onLocationChange(aWebProgress, aRequest, aLocation);
} catch (e) {
// don't inhibit other listeners
Components.utils.reportError(e);
@ -562,8 +543,16 @@
}
}
this.mBrowser.lastURI = aLocation;
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
let p = this.mTabBrowser.mTabsProgressListeners[i];
if (p)
try {
p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
} catch (e) {
// don't inhibit other listeners
Components.utils.reportError(e);
}
}
},
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
@ -1576,10 +1565,6 @@
filter.removeProgressListener(this.mTabListeners[aTab._tPos]);
this.mTabListeners[aTab._tPos].destroy();
let closedBrowser = this.getBrowserForTab(aTab);
if (closedBrowser.currentURI)
this.mBrowserHistory.unregisterOpenPage(closedBrowser.currentURI);
// We are no longer the primary content area.
browser.setAttribute("type", "content-targetable");
@ -2834,8 +2819,6 @@
this.mTabFilters[i] = null;
this.mTabListeners[i].destroy();
this.mTabListeners[i] = null;
let browser = this.getBrowserAtIndex(i);
this.mBrowserHistory.unregisterOpenPage(browser.currentURI);
}
document.removeEventListener("keypress", this, false);
]]>

View File

@ -149,7 +149,6 @@ _BROWSER_FILES = \
alltabslistener.html \
zoom_test.html \
dummy_page.html \
browser_tabMatchesInAwesomebar.js \
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))

View File

@ -1,179 +0,0 @@
const TEST_URL_BASES = [
"http://example.org/browser/browser/base/content/test/dummy_page.html#tabmatch",
"http://example.org/browser/browser/base/content/test/moz.png#tabmatch"
];
var gIOService = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var gWindowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
var gPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
var gObserverService = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
var gTabWaitCount = 0;
var gTabCounter = 0;
var gNewWindow = null;
var gTestSteps = [
function() {
for (let i = 0; i < 10; i++) {
let tab = gBrowser.addTab();
loadTab(tab, TEST_URL_BASES[0] + (++gTabCounter));
}
},
function() {
gBrowser.selectTabAtIndex(1);
gBrowser.removeCurrentTab();
gBrowser.selectTabAtIndex(1);
gBrowser.removeCurrentTab();
for (let i = 1; i < gBrowser.mTabs.length; i++)
loadTab(gBrowser.mTabs[i], TEST_URL_BASES[1] + (++gTabCounter));
},
function() {
for (let i = 1; i < gBrowser.mTabs.length; i++)
loadTab(gBrowser.mTabs[i], TEST_URL_BASES[0] + gTabCounter);
},
function() {
gNewWindow = openNewWindowWith("about:blank");
gNewWindow.addEventListener("load", function () {
gNewWindow.removeEventListener("load", arguments.callee, false);
var delayedStartup = gNewWindow.delayedStartup;
gNewWindow.delayedStartup = function() {
delayedStartup.apply(gNewWindow, arguments);
loadTab(gNewWindow.gBrowser.mTabs[0], TEST_URL_BASES[0] + gTabCounter);
}
}, false);
},
function() {
gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
gNewWindow.close();
if (gPrefService.prefHasUserValue("browser.tabs.warnOnClose"))
gPrefService.clearUserPref("browser.tabs.warnOnClose");
ensure_opentabs_match_db();
executeSoon(nextStep);
},
function() {
gPrivateBrowsing.privateBrowsingEnabled = true;
executeSoon(function() {
ensure_opentabs_match_db();
nextStep();
});
},
function() {
gPrivateBrowsing.privateBrowsingEnabled = false;
setTimeout(function() {
ensure_opentabs_match_db();
nextStep();
}, 100);
}
];
function test() {
waitForExplicitFinish();
nextStep();
}
function loadTab(tab, url) {
tab.linkedBrowser.addEventListener("load", function (event) {
event.currentTarget.removeEventListener("load", arguments.callee, true);
if (--gTabWaitCount > 0)
return;
is(gTabWaitCount, 0,
"sanity check, gTabWaitCount should not be decremented below 0");
try {
ensure_opentabs_match_db();
} catch (e) {
ok(false, "exception from ensure_openpages_match_db: " + e);
}
executeSoon(nextStep);
}, true);
gTabWaitCount++;
tab.linkedBrowser.loadURI(url);
}
function nextStep() {
if (gTestSteps.length == 0) {
while (gBrowser.mTabs.length > 1) {
gBrowser.selectTabAtIndex(1);
gBrowser.removeCurrentTab();
}
PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
finish();
return;
}
var stepFunc = gTestSteps.shift();
stepFunc();
}
function ensure_opentabs_match_db() {
var tabs = {};
var winEnum = gWindowMediator.getEnumerator("navigator:browser");
while (winEnum.hasMoreElements()) {
let browserWin = winEnum.getNext();
// skip closed-but-not-destroyed windows
if (browserWin.closed)
continue;
for (let i = 0; i < browserWin.gBrowser.mTabContainer.childElementCount; i++) {
let browser = browserWin.gBrowser.getBrowserAtIndex(i);
let url = browser.currentURI.spec;
if (!(url in tabs))
tabs[url] = 1;
else
tabs[url]++;
}
}
var db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
.DBConnection;
try {
var stmt = db.createStatement(
"SELECT IFNULL(p_t.url, p.url) AS url, open_count, place_id " +
"FROM moz_openpages_temp " +
"LEFT JOIN moz_places p ON p.id=place_id " +
"LEFT JOIN moz_places_temp p_t ON p_t.id=place_id");
} catch (e) {
ok(false, "error creating db statement: " + e);
return;
}
var dbtabs = [];
try {
while (stmt.executeStep()) {
ok(stmt.row.url in tabs,
"url is in db, should be in tab: " + stmt.row.url);
is(tabs[stmt.row.url], stmt.row.open_count,
"db count (" + stmt.row.open_count + ") " +
"should match actual open tab count " +
"(" + tabs[stmt.row.url] + "): " + stmt.row.url);
dbtabs.push(stmt.row.url);
}
} finally {
stmt.finalize();
}
for (let url in tabs) {
// ignore URLs that should never be in the places db
if (!is_expected_in_db(url))
continue;
ok(dbtabs.indexOf(url) > -1,
"tab is open (" + tabs[url] + " times) and should recorded in db: " + url);
}
}
function is_expected_in_db(url) {
var uri = gIOService.newURI(url, null, null);
return PlacesUtils.history.canAddURI(uri);
}

View File

@ -61,8 +61,8 @@
this.inputField.addEventListener("mousedown", this, false);
this.inputField.addEventListener("mousemove", this, false);
this.inputField.addEventListener("mouseout", this, false);
this.inputField.addEventListener("overflow", this, false);
this.inputField.addEventListener("underflow", this, false);
this.inputField.addEventListener("overflow", this, false);
this.inputField.addEventListener("underflow", this, false);
]]></constructor>
<destructor><![CDATA[
@ -72,45 +72,10 @@
this.inputField.removeEventListener("mousedown", this, false);
this.inputField.removeEventListener("mousemove", this, false);
this.inputField.removeEventListener("mouseout", this, false);
this.inputField.removeEventListener("overflow", this, false);
this.inputField.removeEventListener("underflow", this, false);
this.inputField.removeEventListener("overflow", this, false);
this.inputField.removeEventListener("underflow", this, false);
]]></destructor>
<field name="_value"></field>
<!--
onBeforeValueGet is called by the base-binding's .value getter.
It can return an object with a "value" property, to override the
return value of the getter.
-->
<method name="onBeforeValueGet">
<body><![CDATA[
if (this.hasAttribute("actiontype"))
return {value: this._value};
return null;
]]></body>
</method>
<!--
onBeforeValueSet is called by the base-binding's .value setter.
It should return the value that the setter should use.
-->
<method name="onBeforeValueSet">
<parameter name="aValue"/>
<body><![CDATA[
this._value = aValue;
var returnValue = aValue;
var action = this._parseActionUrl(aValue);
if (action) {
returnValue = action.param;
this.setAttribute("actiontype", action.type);
} else {
this.removeAttribute("actiontype");
}
return returnValue;
]]></body>
</method>
<method name="handleRevert">
<body><![CDATA[
var isScrolling = this.popupOpen;
@ -143,13 +108,6 @@
if (!url)
return;
var action = this._parseActionUrl(url);
if (action) {
if (action.type == "switchtab")
switchToTabHavingURI(action.param);
return;
}
this.value = url;
gBrowser.userTypedValue = url;
try {
@ -258,12 +216,12 @@
return [url, postData.value];
]]></body>
</method>
<field name="_contentIsCropped">false</field>
<field name="_contentIsCropped">false</field>
<method name="_initURLTooltip">
<body><![CDATA[
if (this.focused || !this._contentIsCropped)
if (this.focused || !this._contentIsCropped)
return;
if (this._tooltipTimer)
clearTimeout(this._tooltipTimer);
@ -431,13 +389,13 @@
case "mouseout":
this._hideURLTooltip();
break;
case "overflow":
this._contentIsCropped = true;
break;
case "underflow":
this._contentIsCropped = false;
this._hideURLTooltip();
break;
case "overflow":
this._contentIsCropped = true;
break;
case "underflow":
this._contentIsCropped = false;
this._hideURLTooltip();
break;
}
]]></body>
</method>
@ -484,21 +442,6 @@
this.placeholder = this.getAttribute(type + "placeholder");
]]></body>
</method>
<method name="_parseActionUrl">
<parameter name="aUrl"/>
<body>
<![CDATA[
if (!/^moz-action:/.test(aUrl))
return null;
// url is in the format moz-action:ACTION,PARAM
let [, action, param] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
return {type: action, param: param};
]]>
</body>
</method>
</implementation>
<handlers>
@ -670,15 +613,6 @@
this.closePopup();
controller.handleEscape();
// Check if this is meant to be an action
let action = this.mInput._parseActionUrl(url);
if (action) {
if (action.type == "switchtab")
url = action.param;
else
return;
}
// respect the usual clicking subtleties
openUILink(url, aEvent);
}
@ -706,5 +640,4 @@
</implementation>
</binding>
</bindings>

View File

@ -207,7 +207,6 @@
<!ENTITY urlbar.history.emptyText "Search History">
<!ENTITY urlbar.none.emptyText "Type a Web address">
<!ENTITY urlbar.accesskey "d">
<!ENTITY urlbar.switchToTab.label "Switch to tab:">
<!--
Comment duplicated from browser-sets.inc:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

View File

@ -800,17 +800,6 @@ toolbar[iconsize="small"] #fullscreen-button {
display: none;
}
#urlbar-display {
margin-top: -2px;
margin-bottom: -2px;
padding-top: 3px;
padding-bottom: 2px;
-moz-padding-end: 3px;
color: GrayText;
-moz-border-end: 1px solid #AAA;
-moz-margin-end: 3px;
}
#PopupAutoComplete,
#PopupAutoCompleteRichResult {
direction: ltr !important;
@ -1009,10 +998,6 @@ toolbar[iconsize="small"] #fullscreen-button {
color: -moz-nativehyperlinktext;
}
richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
list-style-image: url("chrome://browser/skin/actionicon-tab.png");
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
}

View File

@ -6,7 +6,6 @@ browser.jar:
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/browser/aboutSessionRestore-window-icon.png
skin/classic/browser/aboutCertError.css (aboutCertError.css)
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

View File

@ -841,17 +841,6 @@ toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarke
-moz-box-align: center;
}
#urlbar-display {
margin-top: -2px;
margin-bottom: -2px;
padding-top: 3px;
padding-bottom: 2px;
-moz-padding-end: 3px;
color: GrayText;
-moz-border-end: 1px solid #AAA;
-moz-margin-end: 3px;
}
#urlbar-search-splitter {
min-width: 8px;
width: 8px;
@ -969,10 +958,6 @@ richlistitem[selected="true"][current="true"] > hbox > .ac-result-type-bookmark,
font-size: 0.95em;
}
richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
list-style-image: url("chrome://browser/skin/actionicon-tab.png");
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
}

View File

@ -5,7 +5,6 @@ browser.jar:
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/browser/aboutSessionRestore-window-icon.png
skin/classic/browser/aboutCertError.css (aboutCertError.css)
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/feed-icons.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

View File

@ -601,17 +601,6 @@ toolbar:not([iconsize="small"])[mode="icons"] #forward-button:not([disabled="tru
display: none;
}
#urlbar-display {
margin-top: -2px;
margin-bottom: -2px;
padding-top: 3px;
padding-bottom: 2px;
-moz-padding-end: 3px;
color: GrayText;
-moz-border-end: 1px solid #AAA;
-moz-margin-end: 3px;
}
#urlbar > .autocomplete-textbox-container {
direction: ltr;
-moz-box-align: stretch;
@ -774,10 +763,6 @@ toolbar:not([iconsize="small"])[mode="icons"] #forward-button:not([disabled="tru
color: #006600;
}
richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
list-style-image: url("chrome://browser/skin/actionicon-tab.png");
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
}

View File

@ -8,7 +8,6 @@ browser.jar:
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon.png)
skin/classic/browser/aboutCertError.css (aboutCertError.css)
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css
@ -96,7 +95,6 @@ browser.jar:
* skin/classic/aero/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/aero/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon-aero.png)
skin/classic/aero/browser/aboutCertError.css (aboutCertError.css)
skin/classic/aero/browser/actionicon-tab.png (actionicon-tab.png)
* skin/classic/aero/browser/browser.css (browser-aero.css)
* skin/classic/aero/browser/engineManager.css (engineManager.css)
skin/classic/aero/browser/fullscreen-video.css

View File

@ -107,13 +107,4 @@ interface mozIPlacesAutoComplete : nsISupports
* Search javascript: URLs.
*/
const long BEHAVIOR_JAVASCRIPT = 1 << 6;
/**
* Search for pages that have been marked as being opened, such as a tab
* in a tabbrowser, via:
* nsIBrowserHistory.registerOpenPage(url)
*
* @see nsIBrowserHistory.idl
*/
const long BEHAVIOR_OPENPAGE = 1 << 7;
};

View File

@ -42,7 +42,7 @@
#include "nsISupports.idl"
#include "nsIGlobalHistory2.idl"
[scriptable, uuid(540aca25-1e01-467f-b24c-df89cbe40f8d)]
[scriptable, uuid(124a8db3-59da-48ac-a563-6dcf58e035b4)]
interface nsIBrowserHistory : nsIGlobalHistory2
{
/**
@ -156,18 +156,4 @@ interface nsIBrowserHistory : nsIGlobalHistory2
* the user (for example by clicking on it).
*/
void markPageAsFollowedLink(in nsIURI aURI);
/**
* Mark a page as being currently open.
*/
void registerOpenPage(in nsIURI aURI);
/**
* Mark a page as no longer being open (either by closing the window or tab,
* or by navigating away from that page).
*
* Note that when Private Browsing mode is entered/exited, pages need to be
* manually unregistered/registered.
*/
void unregisterOpenPage(in nsIURI aURI);
};

View File

@ -991,13 +991,6 @@ nsNavHistory::InitTempTables()
rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_HISTORYVISITS_SYNC_TRIGGER);
NS_ENSURE_SUCCESS(rv, rv);
// moz_openpages_temp
rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_OPENPAGES_TEMP);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBConn->ExecuteSimpleSQL(CREATE_REMOVEOPENPAGE_CLEANUP_TRIGGER);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
@ -1224,25 +1217,6 @@ nsNavHistory::InitStatements()
"WHERE url = ?2"),
getter_AddRefs(mDBSetPlaceTitle));
NS_ENSURE_SUCCESS(rv, rv);
// mDBRegisterOpenPage
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"INSERT OR REPLACE INTO moz_openpages_temp (place_id, open_count) "
"VALUES (?1, "
"IFNULL("
"(SELECT open_count + 1 FROM moz_openpages_temp WHERE place_id = ?1), "
"1"
")"
")"),
getter_AddRefs(mDBRegisterOpenPage));
NS_ENSURE_SUCCESS(rv, rv);
// mDBUnregisterOpenPage
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"UPDATE moz_openpages_temp "
"SET open_count = open_count - 1 "
"WHERE place_id = ?1"),
getter_AddRefs(mDBUnregisterOpenPage));
NS_ENSURE_SUCCESS(rv, rv);
// mDBVisitsForFrecency
// NOTE: This is not limited to visits with "visit_type NOT IN (0,4,7,8)"
// because otherwise mDBVisitsForFrecency would return no visits
@ -5058,102 +5032,6 @@ nsNavHistory::MarkPageAsFollowedLink(nsIURI *aURI)
}
NS_IMETHODIMP
nsNavHistory::RegisterOpenPage(nsIURI* aURI)
{
NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
NS_ENSURE_ARG(aURI);
// Don't add any pages while in Private Browsing mode, so as to avoid leaking
// information about other windows that might otherwise stay hidden
// and private.
if (InPrivateBrowsingMode())
return NS_OK;
PRBool canAdd = PR_FALSE;
nsresult rv = CanAddURI(aURI, &canAdd);
NS_ENSURE_SUCCESS(rv, rv);
PRInt64 placeId;
// Note: If the URI has never been added to history (but can be added),
// LAZY_ADD will cause this to add an orphan page, until the visit is added.
rv = GetUrlIdFor(aURI, &placeId, canAdd);
NS_ENSURE_SUCCESS(rv, rv);
if (placeId == 0)
return NS_OK;
mozStorageStatementScoper scoper(mDBRegisterOpenPage);
rv = mDBRegisterOpenPage->BindInt64Parameter(0, placeId);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBRegisterOpenPage->Execute();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsNavHistory::UnregisterOpenPage(nsIURI* aURI)
{
NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
NS_ENSURE_ARG(aURI);
// Entering Private Browsing mode will unregister all open pages, therefore
// there shouldn't be anything in the moz_openpages_temp table. So we can stop
// now without doing any unnecessary work.
if (InPrivateBrowsingMode())
return NS_OK;
PRInt64 placeId;
nsresult rv = GetUrlIdFor(aURI, &placeId, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
if (placeId == 0)
return NS_OK;
mozStorageStatementScoper scoper(mDBUnregisterOpenPage);
rv = mDBUnregisterOpenPage->BindInt64Parameter(0, placeId);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBUnregisterOpenPage->Execute();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsNavHistory::UnregisterOpenPage(nsIURI* aURI)
{
NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
NS_ENSURE_ARG(aURI);
// Entering Private Browsing mode will unregister all open pages, therefore
// there shouldn't be anything in the moz_openpages_temp table. So we can stop
// now without doing any unnecessary work.
if (InPrivateBrowsingMode())
return NS_OK;
PRInt64 placeId;
nsresult rv = GetUrlIdFor(aURI, &placeId, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
if (placeId == 0)
return NS_OK;
mozStorageStatementScoper scoper(mDBUnregisterOpenPage);
rv = mDBUnregisterOpenPage->BindInt64Parameter(0, placeId);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBUnregisterOpenPage->Execute();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
// nsNavHistory::SetCharsetForURI
//
// Sets the character-set for a URI.
@ -8263,8 +8141,6 @@ nsNavHistory::FinalizeStatements() {
mDBUpdateFrecencyAndHidden,
mDBGetPlaceVisitStats,
mDBFullVisitCount,
mDBRegisterOpenPage,
mDBUnregisterOpenPage,
};
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(stmts); i++) {

View File

@ -402,8 +402,6 @@ protected:
nsCOMPtr<mozIStorageStatement> mDBGetTags; // used by GetTags
nsCOMPtr<mozIStorageStatement> mDBGetItemsWithAnno; // used by AutoComplete::StartSearch and FilterResultSet
nsCOMPtr<mozIStorageStatement> mDBSetPlaceTitle; // used by SetPageTitleInternal
nsCOMPtr<mozIStorageStatement> mDBRegisterOpenPage; // used by RegisterOpenPage
nsCOMPtr<mozIStorageStatement> mDBUnregisterOpenPage; // used by UnregisterOpenPage
// these are used by VisitIdToResultNode for making new result nodes from IDs
// Consumers need to use the getters since these statements are lazily created

View File

@ -94,7 +94,6 @@ const kQueryIndexVisitCount = 6;
const kQueryIndexTyped = 7;
const kQueryIndexPlaceId = 8;
const kQueryIndexQueryType = 9;
const kQueryIndexOpenPageCount = 10;
// AutoComplete query type constants. Describes the various types of queries
// that we can process.
@ -218,11 +217,9 @@ function nsPlacesAutoComplete()
// Note: h.frecency is only selected because we need it for ordering.
function sql_base_fragment(aTableName) {
return "SELECT h.url, h.title, f.url, " + kBookTagSQLFragment + ", " +
"h.visit_count, h.typed, h.id, :query_type, t.open_count, " +
"h.frecency " +
"h.visit_count, h.typed, h.id, :query_type, h.frecency " +
"FROM " + aTableName + " h " +
"LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " +
"LEFT OUTER JOIN moz_openpages_temp t ON t.place_id = h.id " +
"WHERE h.frecency <> 0 " +
"AND AUTOCOMPLETE_MATCH(:searchString, h.url, " +
"IFNULL(bookmark, h.title), tags, " +
@ -294,13 +291,6 @@ function nsPlacesAutoComplete()
);
});
XPCOMUtils.defineLazyGetter(this, "_openPagesQuery", function() {
let replacementText = "AND t.open_count > 0";
return this._db.createStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_typedQuery", function() {
let replacementText = "AND h.typed = 1";
return this._db.createStatement(
@ -321,7 +311,7 @@ function nsPlacesAutoComplete()
kBookTagSQLFragment + ", " +
"IFNULL(h_t.visit_count, h.visit_count) AS c_visit_count, " +
"IFNULL(h_t.typed, h.typed) AS c_typed, " +
"IFNULL(h_t.id, h.id), :query_type, t.open_count, rank " +
"IFNULL(h_t.id, h.id), :query_type, rank " +
"FROM ( " +
"SELECT ROUND(MAX(((i.input = :search_string) + " +
"(SUBSTR(i.input, 1, LENGTH(:search_string)) = :search_string)) * " +
@ -333,7 +323,6 @@ function nsPlacesAutoComplete()
"LEFT JOIN moz_places h ON h.id = i.place_id " +
"LEFT JOIN moz_places_temp h_t ON h_t.id = i.place_id " +
"LEFT JOIN moz_favicons f ON f.id = IFNULL(h_t.favicon_id, h.favicon_id) " +
"LEFT JOIN moz_openpages_temp t ON t.place_id = i.place_id " +
"WHERE c_url NOTNULL " +
"AND AUTOCOMPLETE_MATCH(:searchString, c_url, " +
"IFNULL(bookmark, c_title), tags, " +
@ -354,13 +343,12 @@ function nsPlacesAutoComplete()
best_favicon_for_revhost("moz_places") + "), b.parent, " +
"b.title, NULL, IFNULL(h_t.visit_count, h.visit_count), " +
"IFNULL(h_t.typed, h.typed), COALESCE(h_t.id, h.id, b.fk), " +
":query_type, t.open_count " +
":query_type " +
"FROM moz_keywords k " +
"JOIN moz_bookmarks b ON b.keyword_id = k.id " +
"LEFT JOIN moz_places AS h ON h.url = search_url " +
"LEFT JOIN moz_places_temp AS h_t ON h_t.url = search_url " +
"LEFT JOIN moz_favicons f ON f.id = IFNULL(h_t.favicon_id, h.favicon_id) " +
"LEFT JOIN moz_openpages_temp t ON t.place_id = IFNULL(h_t.id, h.id) " +
"WHERE LOWER(k.keyword) = LOWER(:keyword) " +
"ORDER BY IFNULL(h_t.frecency, h.frecency) DESC"
);
@ -399,9 +387,6 @@ nsPlacesAutoComplete.prototype = {
this._currentSearchString =
this._fixupSearchText(this._originalSearchString.toLowerCase());
var searchParamParts = aSearchParam.split(" ");
this._enableActions = searchParamParts.indexOf("enable-actions") != -1;
this._listener = aListener;
let result = Cc["@mozilla.org/autocomplete/simple-result;1"].
createInstance(Ci.nsIAutoCompleteSimpleResult);
@ -534,7 +519,6 @@ nsPlacesAutoComplete.prototype = {
"_historyQuery",
"_bookmarkQuery",
"_tagsQuery",
"_openPagesQuery",
"_typedQuery",
"_adaptiveQuery",
"_keywordQuery",
@ -614,7 +598,6 @@ nsPlacesAutoComplete.prototype = {
delete this._usedPlaceIds;
delete this._pendingQuery;
this._secondPass = false;
this._enableActions = false;
},
/**
@ -697,14 +680,13 @@ nsPlacesAutoComplete.prototype = {
this._restrictBookmarkToken = safeGetter("restrict.bookmark", "*");
this._restrictTypedToken = safeGetter("restrict.typed", "~");
this._restrictTagToken = safeGetter("restrict.tag", "+");
this._restrictOpenPageToken = safeGetter("restrict.openpage", "%");
this._matchTitleToken = safeGetter("match.title", "#");
this._matchURLToken = safeGetter("match.url", "@");
this._defaultBehavior = safeGetter("default.behavior", 0);
// Further restrictions to apply for "empty searches" (i.e. searches for "").
// By default we use (HISTORY | TYPED | OPENPAGE) = 161.
// By default we use (HISTORY | TYPED) = 33.
this._emptySearchDefaultBehavior = this._defaultBehavior |
safeGetter("default.behavior.emptyRestriction", 161);
safeGetter("default.behavior.emptyRestriction", 33);
// Validate matchBehavior; default to MATCH_BOUNDARY_ANYWHERE.
if (this._matchBehavior != MATCH_ANYWHERE &&
@ -745,11 +727,6 @@ nsPlacesAutoComplete.prototype = {
case this._restrictTagToken:
this._setBehavior("tag");
break;
case this._restrictOpenPageToken:
if (!this._enableActions)
continue;
this._setBehavior("openpage");
break;
case this._matchTitleToken:
this._setBehavior("title");
break;
@ -803,7 +780,6 @@ nsPlacesAutoComplete.prototype = {
this._hasBehavior("bookmark") ? this._bookmarkQuery :
this._hasBehavior("typed") ? this._typedQuery :
this._hasBehavior("history") ? this._historyQuery :
this._hasBehavior("openpage") ? this._openPagesQuery :
this._defaultQuery;
// Bind the needed parameters to the query so consumers can use it.
@ -904,7 +880,6 @@ nsPlacesAutoComplete.prototype = {
let entryBookmarkTitle = entryParentId ?
aRow.getResultByIndex(kQueryIndexBookmarkTitle) : null;
let entryTags = aRow.getResultByIndex(kQueryIndexTags) || "";
let openPageCount = aRow.getResultByIndex(kQueryIndexOpenPageCount) || 0;
// Always prefer the bookmark title unless it is empty
let title = entryBookmarkTitle || entryTitle;
@ -951,22 +926,8 @@ nsPlacesAutoComplete.prototype = {
style = "favicon";
}
// If actions aren't enabled, avoid doing any additional work.
if (!this._enableActions) {
this._addToResults(entryId, escapedEntryURL, title, entryFavicon, style);
return true;
}
// Add a special entry for an open-page match.
if ((this._hasBehavior("openpage") || this._hasBehavior("everything")) &&
openPageCount > 0)
this._addToResults(entryId, "moz-action:switchtab," + escapedEntryURL, title, entryFavicon, "action");
// If restricting to only open-page matches, there should only be the
// switch-to-tab results.
if (!this._onlyHasBehavior("openpage"))
this._addToResults(entryId, escapedEntryURL, title, entryFavicon, style);
// And finally add this to our results.
this._addToResults(entryId, escapedEntryURL, title, entryFavicon, style);
return true;
},
@ -1020,32 +981,15 @@ nsPlacesAutoComplete.prototype = {
* Determines if the specified AutoComplete behavior is set.
*
* @param aType
* The behavior type to test for, or "everything" to test if no
* specific behavior has been set.
* The behavior type to test for.
* @return true if the behavior is set, false otherwise.
*/
_hasBehavior: function PAC_hasBehavior(aType)
{
if (aType == "everything")
return this._behavior == 0;
return (this._behavior &
Ci.mozIPlacesAutoComplete["BEHAVIOR_" + aType.toUpperCase()]);
},
/**
* Determines if the specified AutoComplete behavior is the only behavior set.
*
* @param aType
* The behavior type to test for.
* @return true if the behavior is set and no other behaviors are set,
* false otherwise.
*/
_onlyHasBehavior: function PAC_onlyHasBehavior(aType)
{
return (this._behavior ==
Ci.mozIPlacesAutoComplete["BEHAVIOR_" + aType.toUpperCase()]);
},
/**
* Enables the desired AutoComplete behavior.
*

View File

@ -177,11 +177,4 @@
")" \
)
#define CREATE_MOZ_OPENPAGES_TEMP NS_LITERAL_CSTRING( \
"CREATE TEMP TABLE moz_openpages_temp (" \
" place_id INTEGER PRIMARY KEY" \
", open_count INTEGER" \
")" \
)
#endif // __nsPlacesTables_h__

View File

@ -94,8 +94,8 @@
/**
* This trigger allows for the deletion of a record in moz_places_view. It
* removes any entry in the temporary table, the permanent table, and any
* associated entry in moz_openpages_temp.
* removes any entry in the temporary table, and any entry in the permanent
* table as well.
*/
#define CREATE_PLACES_VIEW_DELETE_TRIGGER NS_LITERAL_CSTRING( \
"CREATE TEMPORARY TRIGGER moz_places_view_delete_trigger " \
@ -106,8 +106,6 @@
"WHERE id = OLD.id; " \
"DELETE FROM moz_places " \
"WHERE id = OLD.id; " \
"DELETE FROM moz_openpages_temp " \
"WHERE place_id = OLD.id; " \
"END" \
)
@ -260,18 +258,4 @@
#define CREATE_MOZ_HISTORYVISITS_SYNC_TRIGGER \
CREATE_TEMP_SYNC_TRIGGER_BASE("moz_historyvisits", MOZ_HISTORYVISITS_COLUMNS)
/**
* This trigger removes a row from moz_openpages_temp when open_count reaches 0.
*/
#define CREATE_REMOVEOPENPAGE_CLEANUP_TRIGGER NS_LITERAL_CSTRING( \
"CREATE TEMPORARY TRIGGER moz_openpages_temp_afterupdate_trigger " \
"AFTER UPDATE OF open_count ON moz_openpages_temp FOR EACH ROW " \
"WHEN NEW.open_count = 0 " \
"BEGIN " \
"DELETE FROM moz_openpages_temp " \
"WHERE place_id = NEW.place_id;" \
"END" \
)
#endif // __nsPlacesTriggers_h__

View File

@ -99,9 +99,6 @@ function ensure_results(aSearch, aExpected)
controller.input = input;
if (typeof kSearchParam == "string")
input.searchParam = kSearchParam;
let numSearchesStarted = 0;
input.onSearchBegin = function() {
numSearchesStarted++;

View File

@ -1,64 +0,0 @@
let gTabRestrictChar = prefs.getCharPref("browser.urlbar.restrict.openpage");
let kSearchParam = "enable-actions";
let kURIs = [
"http://abc.com/",
"moz-action:switchtab,http://abc.com/",
"http://xyz.net/",
"moz-action:switchtab,http://xyz.net/"
];
let kTitles = [
"ABC rocks",
"xyz.net - we're better than ABC"
];
addPageBook(0, 0);
gPages[1] = [1, 0];
addPageBook(2, 1);
gPages[3] = [3, 1];
addOpenPages(0, 1);
let gTests = [
["0: single result, that is also a tab match",
"abc.com", [0,1]],
["1: two results, one tab match",
"abc", [0,1,2]],
["2: two results, both tab matches",
"abc", [0,1,2,3],
function() {
addOpenPages(2, 1);
}],
["3: two results, both tab matches, one has multiple tabs",
"abc", [0,1,2,3],
function() {
addOpenPages(2, 5);
}],
["4: two results, no tab matches",
"abc", [0,2],
function() {
removeOpenPages(0, 1);
removeOpenPages(2, 6);
}],
["5: tab match search with restriction character",
gTabRestrictChar + " abc", [1],
function() {
addOpenPages(0, 1);
}]
];
function addOpenPages(aUri, aCount) {
let num = aCount || 1;
for (let i = 0; i < num; i++)
bhist.registerOpenPage(toURI(kURIs[aUri]));
}
function removeOpenPages(aUri, aCount) {
let num = aCount || 1;
for (let i = 0; i < num; i++)
bhist.unregisterOpenPage(toURI(kURIs[aUri]));
}

View File

@ -42,11 +42,6 @@
#
# ***** END LICENSE BLOCK *****
<!DOCTYPE bindings [
<!ENTITY % actionsDTD SYSTEM "chrome://global/locale/actions.dtd">
%actionsDTD;
]>
<bindings id="autocompleteBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml"
@ -258,21 +253,10 @@
<!-- =================== PUBLIC MEMBERS =================== -->
<property name="value">
<getter><![CDATA[
if (typeof this.onBeforeValueGet == "function") {
var result = this.onBeforeValueGet();
if (result)
return result.value;
}
return this.inputField.value;
]]></getter>
<property name="value"
onget="return this.inputField.value;">
<setter><![CDATA[
this.mIgnoreInput = true;
if (typeof this.onBeforeValueSet == "function")
val = this.onBeforeValueSet(val);
this.inputField.value = val;
this.mIgnoreInput = false;
var event = document.createEvent('Events');
@ -532,25 +516,11 @@
]]></body>
</method>
<method name="resetActionType">
<body><![CDATA[
if (this.mIgnoreInput)
return;
this.removeAttribute("actiontype");
]]></body>
</method>
</implementation>
<handlers>
<handler event="input">
<action><![CDATA[
if (!this.mIgnoreInput && this.mController.input == this) {
this.mController.handleText(true);
}
this.resetActionType();
]]></action>
</handler>
<handler event="input"
action="if (!this.mIgnoreInput &amp;&amp; this.mController.input == this) this.mController.handleText(true);"/>
<handler event="keypress" phase="capturing"
action="return this.onKeyPress(event);"/>
@ -1165,7 +1135,7 @@
<binding id="autocomplete-richlistitem" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content>
<xul:hbox align="center" class="ac-title-box">
<xul:hbox align="center">
<xul:image xbl:inherits="src=image" class="ac-site-icon"/>
<xul:hbox anonid="title-box" class="ac-title" flex="1"
onunderflow="_doUnderflow('_title');">
@ -1182,7 +1152,6 @@
</xul:hbox>
<xul:hbox align="center" class="ac-url-box">
<xul:spacer class="ac-site-icon"/>
<xul:image class="ac-action-icon"/>
<xul:hbox anonid="url-box" class="ac-url" flex="1"
onunderflow="_doUnderflow('_url');">
<xul:description anonid="url" class="ac-normal-text ac-url-text" xbl:inherits="selected"/>
@ -1356,19 +1325,12 @@
<method name="_setUpDescription">
<parameter name="aDescriptionElement"/>
<parameter name="aText"/>
<parameter name="aNoEmphasis"/>
<body>
<![CDATA[
// Get rid of all previous text
while (aDescriptionElement.hasChildNodes())
aDescriptionElement.removeChild(aDescriptionElement.firstChild);
// If aNoEmphasis is specified, don't add any emphasis
if (aNoEmphasis) {
aDescriptionElement.appendChild(document.createTextNode(aText));
return;
}
// Get the indices that separate match and non-match text
let search = this.getAttribute("text");
let tokens = this._getSearchTokens(search);
@ -1410,10 +1372,6 @@
var title = this.getAttribute("title");
var type = this.getAttribute("type");
this.removeAttribute("actiontype");
var setupUrl = true;
// If we have a tag match, show the tags and icon
if (type == "tag") {
// Configure the extra box for tags display
@ -1455,15 +1413,6 @@
// Don't emphasize keyword searches in the title or url
this.setAttribute("text", "");
} else if (type == "action") {
let [,action, param] = url.match(/^moz-action:([^,]+),(.*)$/);
this.setAttribute("actiontype", action);
url = param;
this._extraBox.hidden = true;
this._titleBox.flex = 1;
let desc = "]]>&action.switchToTab.label;<![CDATA[";
this._setUpDescription(this._url, desc, true);
setupUrl = false;
} else {
// Hide the title's extra box if we don't need extra stuff
this._extraBox.hidden = true;
@ -1480,8 +1429,7 @@
// Emphasize the matching search terms for the description
this._setUpDescription(this._title, title);
if (setupUrl)
this._setUpDescription(this._url, url);
this._setUpDescription(this._url, url);
// Set up overflow on a timeout because the contents of the box
// might not have a width yet even though we just changed them

View File

@ -623,9 +623,6 @@
<field name="mIconURL">null</field>
<!-- This is managed by the tabbrowser -->
<field name="lastURI">null</field>
<field name="mDestroyed">false</field>
<constructor>
@ -702,8 +699,6 @@
// The feeds cache can keep the document inside this browser alive.
this.feeds = null;
this.lastURI = null;
this.removeEventListener("pageshow", this.onPageShow, true);
this.removeEventListener("pagehide", this.onPageHide, true);
this.removeEventListener("DOMPopupBlocked", this.onPopupBlocked, true);

View File

@ -1 +0,0 @@
<!ENTITY action.switchToTab.label "Switch to tab">

View File

@ -6,7 +6,6 @@
locale/@AB_CD@/global/aboutAbout.dtd (%chrome/global/aboutAbout.dtd)
locale/@AB_CD@/global/aboutRights.dtd (%chrome/global/aboutRights.dtd)
locale/@AB_CD@/global/aboutRights.properties (%chrome/global/aboutRights.properties)
locale/@AB_CD@/global/actions.dtd (%chrome/global/actions.dtd)
locale/@AB_CD@/global/appPicker.dtd (%chrome/global/appPicker.dtd)
locale/@AB_CD@/global/brand.dtd (generic/chrome/global/brand.dtd)
+ locale/@AB_CD@/global/browser.properties (%chrome/global/browser.properties)