This commit is contained in:
Daniel Brooks 2008-09-26 05:32:11 -05:00
Родитель d5224b9c4e 821b2293cf
Коммит a90c7684af
53 изменённых файлов: 2820 добавлений и 617 удалений

7
mobile/.hgignore Normal file
Просмотреть файл

@ -0,0 +1,7 @@
# .hgignore - List of filenames hg should ignore
# Filenames that should be ignored wherever they appear
~$
\.pyc$
(^|/)TAGS$
\.DS_Store$

Просмотреть файл

@ -1 +1,3 @@
14bbac84b71cbb9d603ed571538c9c41b023d94e FENNEC_M4
7dbca6d7d5cf0a052c658b6ba3e89068b0772734 FENNEC_M7
eb17df1df284c8aa882ae626d6f8b298adc55c6b FENNEC_M8

Просмотреть файл

@ -42,6 +42,7 @@ pref("browser.chromeURL", "chrome://browser/content/");
pref("browser.startup.homepage", "http://www.mozilla.org/");
pref("browser.ui.cursor", false);
pref("browser.ui.panning.kinetic", true);
/* cache prefs */
pref("browser.cache.disk.enable", false);
@ -53,27 +54,25 @@ pref("browser.cache.memory.capacity", 1024);
pref("network.http.pipelining", true);
pref("network.http.pipelining.ssl", true);
pref("network.http.proxy.pipelining", true);
pref("network.http.pipelining.maxrequests" , 2);
pref("network.http.pipelining.maxrequests" , 6);
pref("network.http.keep-alive.timeout", 600);
pref("network.http.max-connections", 4);
pref("network.http.max-connections-per-server", 1);
pref("network.http.max-persistent-connections-per-server", 1);
pref("network.http.max-persistent-connections-per-proxy", 1);
pref("network.http.max-connections", 6);
pref("network.http.max-connections-per-server", 4);
pref("network.http.max-persistent-connections-per-server", 4);
pref("network.http.max-persistent-connections-per-proxy", 4);
/* session history */
pref("browser.sessionhistory.max_total_viewers", 0);
pref("browser.sessionhistory.max_entries", 50);
/* debugging prefs */
pref("browser.dom.window.dump.enabled", true);
pref("javascript.options.showInConsole", true);
pref("javascript.options.strict", true);
pref("nglayout.debug.disable_xul_cache", false);
pref("nglayout.debug.disable_xul_fastload", false);
/* these should help performance */
pref("mozilla.widget.force-24bpp", true);
pref("mozilla.widget.use-buffer-pixmap", true);
pref("mozilla.widget.disable-native-theme", true);
/* download manager (don't show the window or alert) */
pref("browser.download.useDownloadDir", true);
pref("browser.download.folderList", 0);
pref("browser.download.folderList", 1); // Default to ~/Downloads
pref("browser.download.manager.showAlertOnComplete", false);
pref("browser.download.manager.showAlertInterval", 2000);
pref("browser.download.manager.retention", 2);
@ -104,22 +103,41 @@ pref("layout.spellcheckDefault", 1);
/* extension manager and xpinstall */
pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul?type=themes");
pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul?type=extensions");
pref("xpinstall.dialog.progress.type.skin", "Extension:Manager-themes");
pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager-extensions");
pref("xpinstall.dialog.progress.skin", "chrome://browser/content/browser.xul");
pref("xpinstall.dialog.progress.chrome", "chrome://browser/content/browser.xul");
pref("xpinstall.dialog.progress.type.skin", "navigator:browser");
pref("xpinstall.dialog.progress.type.chrome", "navigator:browser");
pref("extensions.update.enabled", true);
pref("extensions.update.interval", 86400);
pref("extensions.dss.enabled", false);
pref("extensions.dss.switchPending", false);
pref("extensions.ignoreMTimeChanges", false);
pref("extensions.logging.enabled", false);
pref("extensions.hideInstallButton", true);
/* these point at AMO */
pref("extensions.update.url", "chrome://mozapps/locale/extensions/extensions.properties");
pref("extensions.getMoreExtensionsURL", "chrome://mozapps/locale/extensions/extensions.properties");
pref("extensions.getMoreThemesURL", "chrome://mozapps/locale/extensions/extensions.properties");
/* preferences for the Get Add-ons pane */
pref("extensions.getAddons.showPane", true);
pref("extensions.getAddons.browseAddons", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%");
pref("extensions.getAddons.maxResults", 5);
pref("extensions.getAddons.recommended.browseURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/recommended");
pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/list/featured/all/10/%OS%/%VERSION%");
pref("extensions.getAddons.search.browseURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/search?q=%TERMS%");
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/10/%OS%/%VERSION%");
/* blocklist preferences */
pref("extensions.blocklist.enabled", true);
pref("extensions.blocklist.interval", 86400);
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/2/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
pref("extensions.blocklist.detailsURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/blocklist/");
/* dictionary download preference */
pref("browser.dictionaries.download.url", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/firefox/%VERSION%/dictionaries/");
/* make clicking on links stand out a bit */
pref("browser.display.use_focus_colors", true);
pref("browser.display.focus_background_color", "#ffffa0");
@ -138,15 +156,18 @@ pref("accessibility.typeaheadfind", false);
pref("accessibility.typeaheadfind.timeout", 5000);
pref("accessibility.typeaheadfind.flashBar", 1);
pref("accessibility.typeaheadfind.linksonly", false);
pref("accessibility.typeaheadfind.casesensitive", false);
pref("accessibility.typeaheadfind.casesensitive", 0);
// pointer to the default engine name
pref("browser.search.defaultenginename", "chrome://browser/locale/region.properties");
// SSL error page behaviour
pref("browser.ssl_override_behavior", 2);
pref("browser.xul.error_pages.expert_bad_cert", false);
// disable logging for the search service by default
pref("browser.search.log", false);
// Ordering of Search Engines in the Engine list.
// Ordering of Search Engines in the Engine list.
pref("browser.search.order.1", "chrome://browser/locale/region.properties");
pref("browser.search.order.2", "chrome://browser/locale/region.properties");
@ -209,3 +230,27 @@ pref("places.frecency.tempRedirectVisitBonus", 0);
pref("places.frecency.defaultVisitBonus", 0);
pref("places.frecency.unvisitedBookmarkBonus", 140);
pref("places.frecency.unvisitedTypedBonus", 200);
// disable color management
pref("gfx.color_management.mode", 0);
// don't allow JS to move and resize existing windows
pref("dom.disable_window_move_resize", true);
// open in tab preferences
// 0=default window, 1=current window/tab, 2=new window, 3=new tab in most window
pref("browser.link.open_external", 3);
pref("browser.link.open_newwindow", 3);
// controls which bits of private data to clear. by default we clear them all.
pref("privacy.sanitize.promptOnSanitize", false);
pref("privacy.item.cache", true);
pref("privacy.item.cookies", true);
pref("privacy.item.offlineApps", true);
pref("privacy.item.history", true);
pref("privacy.item.formdata", true);
pref("privacy.item.downloads", true);
pref("privacy.item.passwords", true);
pref("privacy.item.sessions", true);
pref("plugins.enabled", false);

Просмотреть файл

@ -42,6 +42,13 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
vpath %.xml $(srcdir)/locale/$(MOZ_UI_LOCALE)/searchplugins
DEFINES += -DAB_CD=$(MOZ_UI_LOCALE) -DPACKAGE=browser
SEARCH_PLUGINS = $(shell cat $(srcdir)/locale/$(MOZ_UI_LOCALE)/searchplugins/list.txt)
libs:: $(addsuffix .xml,$(SEARCH_PLUGINS))
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/searchplugins
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -40,15 +40,17 @@ const TOOLBARSTATE_LOADING = 1;
const TOOLBARSTATE_LOADED = 2;
const TOOLBARSTATE_INDETERMINATE = 3;
const PANELMODE_NONE = 0;
const PANELMODE_URLVIEW = 1;
const PANELMODE_URLEDIT = 2;
const PANELMODE_BOOKMARK = 3;
const PANELMODE_BOOKMARKLIST = 4;
const PANELMODE_SIDEBAR = 5;
const PANELMODE_TABLIST = 6;
const PANELMODE_FULL = 7;
const PANELMODE_SHORTCUTS = 8;
const UIMODE_NONE = 0;
const UIMODE_URLVIEW = 1;
const UIMODE_URLEDIT = 2;
const UIMODE_BOOKMARK = 3;
const UIMODE_BOOKMARKLIST = 4;
const UIMODE_TABS = 5;
const UIMODE_CONTROLS = 6;
const UIMODE_PANEL = 7;
const kMaxEngines = 4;
const kDefaultFavIconURL = "chrome://browser/skin/images/default-favicon.png";
var BrowserUI = {
_panel : null,
@ -59,11 +61,18 @@ var BrowserUI = {
_favicon : null,
_faviconAdded : false,
_titleChanged : function(aEvent) {
if (aEvent.target != getBrowser().contentDocument)
_titleChanged : function(aDocument) {
var browser = Browser.currentBrowser;
if (browser && aDocument != browser.contentDocument)
return;
this._caption.value = aEvent.target.title;
this._caption.value = aDocument.title;
var docElem = document.documentElement;
var title = "";
if (aDocument.title)
title = aDocument.title + docElem.getAttribute("titleseparator");
document.title = title + docElem.getAttribute("titlemodifier");
},
_linkAdded : function(aEvent) {
@ -74,22 +83,48 @@ var BrowserUI = {
var rel = link.rel && link.rel.toLowerCase();
var rels = rel.split(/\s+/);
if (rels.indexOf("icon") != -1) {
this._throbber.setAttribute("src", "");
this._setIcon(link.href);
}
},
_tabSelect : function(aEvent) {
var browser = Browser.currentBrowser;
this.setURI();
this._titleChanged(browser.contentDocument);
this._favicon.src = browser.mIconURL || kDefaultFavIconURL;
let toolbar = document.getElementById("toolbar-main");
let browserBox = document.getElementById("browser");
if (Browser.content.currentTab.chromeTop) {
// Browser box was panned, so let's reset it
browserBox.top = Browser.content.currentTab.chromeTop;
browserBox.left = 0;
toolbar.top = browserBox.top - toolbar.boxObject.height;
}
else {
// Must be initial conditions
toolbar.top = 0;
browserBox.top = toolbar.boxObject.height;
browserBox.left = 0;
}
this.show(UIMODE_NONE);
},
_setIcon : function(aURI) {
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var faviconURI = ios.newURI(aURI, null, null);
if (faviconURI.schemeIs("javascript"))
return;
var fis = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
if (fis.isFailedFavicon(faviconURI))
faviconURI = ios.newURI("chrome://browser/skin/images/default-favicon.png", null, null);
fis.setAndLoadFaviconForPage(getBrowser().currentURI, faviconURI, true);
this._favicon.setAttribute("src", faviconURI.spec);
if (faviconURI.schemeIs("javascript") ||
fis.isFailedFavicon(faviconURI))
faviconURI = ios.newURI(kDefaultFavIconURL, null, null);
var browser = getBrowser();
browser.mIconURL = faviconURI.spec;
fis.setAndLoadFaviconForPage(browser.currentURI, faviconURI, true);
this._favicon.src = faviconURI.spec;
this._faviconAdded = true;
},
@ -137,6 +172,241 @@ var BrowserUI = {
return items;
},
_dragData : {
dragging : false,
startX : 0,
startY : 0,
dragX : 0,
dragY : 0,
lastX : 0,
lastY : 0,
sTop : 0,
sLeft : 0
},
_scrollToolbar : function bui_scrollToolbar(aEvent) {
var [scrollWidth, ] = Browser.content._contentAreaDimensions;
var [canvasW, ] = Browser.content._effectiveCanvasDimensions;
var pannedUI = false;
if (this._dragData.dragging && Browser.content.scrollY == 0) {
let toolbar = document.getElementById("toolbar-main");
let browser = document.getElementById("browser");
let dy = this._dragData.lastY - aEvent.screenY;
this._dragData.dragY += dy;
// NOTE: We should only be scrolling the toolbar if the sidebars are not
// visible (browser.left == 0)
let newTop = null;
if (dy > 0 && (toolbar.top > -toolbar.boxObject.height && browser.left == 0)) {
// Scroll the toolbar up unless it is already scrolled up
newTop = this._dragData.sTop - dy;
// Clip the adjustment to just enough to hide the toolbar
if (newTop < -toolbar.boxObject.height)
newTop = -toolbar.boxObject.height;
// Reset the browser start point
Browser.content.dragData.sX = aEvent.screenX;
Browser.content.dragData.sY = aEvent.screenY;
}
else if (dy < 0 && (toolbar.top < 0 && browser.left == 0)) {
// Scroll the toolbar down unless it is already down
newTop = this._dragData.sTop - dy;
// Clip the adjustment to just enough to fully show the toolbar
if (newTop > 0)
newTop = 0;
}
// Update the toolbar and browser tops. Stop the mousemove from
// getting to the deckbrowser.
if (newTop != null) {
toolbar.top = newTop;
browser.top = newTop + toolbar.boxObject.height;
// Cache the current top so we can use it when switching tabs
Browser.content.currentTab.chromeTop = browser.top;
pannedUI = true;
}
}
if (this._dragData.dragging && (Browser.content.scrollX == 0 || (Browser.content.scrollX + canvasW) == scrollWidth)) {
let tabbar = document.getElementById("tab-list-container");
let sidebar = document.getElementById("browser-controls");
let panelUI = document.getElementById("panel-container");
let toolbar = document.getElementById("toolbar-main");
let browser = document.getElementById("browser");
let dx = this._dragData.lastX - aEvent.screenX;
this._dragData.dragX += dx;
if (Math.abs(this._dragData.screenX - aEvent.screenX) > 30) {
let newLeft = this._dragData.sLeft - dx;
let oldLeft = tabbar.left;
let tabbarW = tabbar.boxObject.width;
let sidebarW = sidebar.boxObject.width;
let browserW = browser.boxObject.width;
// Limit the panning
if (newLeft > 0)
newLeft = 0;
else if (newLeft < -(tabbarW + sidebarW))
newLeft = -(tabbarW + sidebarW);
tabbar.left = newLeft;
// Never let the toolbar pan off the screen
let newToolbarLeft = newLeft;
if (newToolbarLeft < 0)
newToolbarLeft = 0;
toolbar.left = newToolbarLeft;
// Make the toolbar appear/disappear depending on the state of the sidebars
if (newLeft + tabbarW != 0)
toolbar.top = 0;
else
toolbar.top = browser.top - toolbar.boxObject.height;
browser.left = newLeft + tabbarW;
sidebar.left = newLeft + tabbarW + browserW;
panelUI.left = newLeft + tabbarW + browserW + sidebarW;
// Set the UI mode based on where we ended up
if (newLeft > -(tabbarW - tabbarW / 3) && newLeft <= 0)
this.mode = UIMODE_TABS;
else if (newLeft >= -(tabbarW + sidebarW) && newLeft < -(tabbarW + sidebarW / 3))
this.mode = UIMODE_CONTROLS;
else
this.mode = (browser.top == 0 ? UIMODE_NONE : UIMODE_URLVIEW);
pannedUI = true;
}
}
if (pannedUI) {
aEvent.stopPropagation();
// Force a sync redraw
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.processUpdates();
}
else {
// Reset our start point while the browser is doing its panning
this._dragData.lastX = aEvent.screenX;
this._dragData.lastY = aEvent.screenY;
}
},
_showToolbar : function(aShow) {
var toolbar = document.getElementById("toolbar-main");
var browser = document.getElementById("browser");
if (aShow) {
// Always show the toolbar, either by floating or panning
if (toolbar.top == -toolbar.boxObject.height) {
// Float the toolbar over content
toolbar.top = 0;
}
else if (toolbar.top < 0) {
// Partially showing, so show it completely
toolbar.top = 0;
browser.top = toolbar.boxObject.height;
}
}
else {
// If we are floating the toolbar, then hide it again
if (browser.top == 0) {
toolbar.top = -toolbar.boxObject.height;
}
}
},
_editToolbar : function(aEdit) {
var toolbar = document.getElementById("toolbar-main");
if (aEdit) {
toolbar.setAttribute("mode", "edit");
this._caption.hidden = true;
this._edit.hidden = false;
this._edit.inputField.focus();
}
else {
toolbar.setAttribute("mode", "view");
this._edit.hidden = true;
this._edit.reallyClosePopup();
this._caption.hidden = false;
}
},
_showPanel : function(aMode) {
let tabbar = document.getElementById("tab-list-container");
let sidebar = document.getElementById("browser-controls");
let panelUI = document.getElementById("panel-container");
let toolbar = document.getElementById("toolbar-main");
let browser = document.getElementById("browser");
let tabbarW = tabbar.boxObject.width;
let sidebarW = sidebar.boxObject.width;
let browserW = browser.boxObject.width;
let newLeft = -tabbarW;
switch (aMode) {
case UIMODE_PANEL:
newLeft = -browserW;
break;
case UIMODE_CONTROLS:
newLeft = -(tabbarW + sidebarW);
break;
case UIMODE_TABS:
newLeft = 0;
break;
}
tabbar.left = newLeft;
let newToolbarLeft = newLeft;
if (newToolbarLeft < 0 && aMode != UIMODE_PANEL)
newToolbarLeft = 0;
else if (newToolbarLeft < 0 && aMode == UIMODE_PANEL)
newToolbarLeft += tabbarW + sidebarW;
toolbar.left = newToolbarLeft;
browser.left = newLeft + tabbarW;
sidebar.left = newLeft + tabbarW + browserW;
panelUI.left = newLeft + tabbarW + browserW + sidebarW;
panelUI.width = browserW;
},
_sizeControls : function(aEvent) {
var rect = document.getElementById("browser-container").getBoundingClientRect();
var containerW = rect.right - rect.left;
var containerH = rect.bottom - rect.top;
var toolbar = document.getElementById("toolbar-main");
var toolbarH = toolbar.boxObject.height;
var browser = document.getElementById("browser");
browser.width = containerW;
browser.height = containerH;
var sidebar = document.getElementById("browser-controls");
var panelUI = document.getElementById("panel-container");
var tabbar = document.getElementById("tab-list-container");
if (window == aEvent.target) {
tabbar.left = -tabbar.boxObject.width;
panelUI.left = containerW + sidebar.boxObject.width;
sidebar.left = containerW;
sidebar.height = tabbar.height = (panelUI.height = containerH) - toolbarH;
}
panelUI.width = containerW - sidebar.boxObject.width - tabbar.boxObject.width;
var popup = document.getElementById("popup_autocomplete");
toolbar.width = containerW;
popup.height = containerH - toolbarH;
},
init : function() {
this._caption = document.getElementById("urlbar-caption");
this._caption.addEventListener("click", this, false);
@ -149,16 +419,21 @@ var BrowserUI = {
this._favicon.addEventListener("error", this, false);
this._autocompleteNavbuttons = document.getElementById("autocomplete_navbuttons");
getBrowser().addEventListener("DOMTitleChanged", this, true);
getBrowser().addEventListener("DOMLinkAdded", this, true);
Browser.content.addEventListener("DOMTitleChanged", this, true);
Browser.content.addEventListener("DOMLinkAdded", this, true);
document.getElementById("tab-list").addEventListener("TabSelect", this, true);
Browser.content.addEventListener("mousedown", this, true);
Browser.content.addEventListener("mouseup", this, true);
Browser.content.addEventListener("mousemove", this, true);
window.addEventListener("resize", this, false);
Shortcuts.restore();
Browser.content.addEventListener("overpan", this, false);
Browser.content.addEventListener("pan", this, true);
Shortcuts.test();
},
update : function(aState) {
update : function(aState, aBrowser) {
if (aState == TOOLBARSTATE_INDETERMINATE) {
this._faviconAdded = false;
aState = TOOLBARSTATE_LOADED;
@ -167,18 +442,26 @@ var BrowserUI = {
var toolbar = document.getElementById("toolbar-main");
if (aState == TOOLBARSTATE_LOADING) {
this.show(PANELMODE_URLVIEW);
this.show(UIMODE_URLVIEW);
Browser.content.setLoading(aBrowser);
toolbar.top = 0;
toolbar.setAttribute("mode", "loading");
this._throbber.setAttribute("src", "chrome://browser/skin/images/throbber.gif");
this._favicon.setAttribute("src", "");
document.getElementById("urlbar-image-deck").selectedIndex = 0;
this._favicon.src = "";
this._throbber.setAttribute("loading", "true");
this._faviconAdded = false;
}
else if (aState == TOOLBARSTATE_LOADED) {
var container = document.getElementById("browser");
container.top = toolbar.boxObject.height;
toolbar.setAttribute("mode", "view");
this._throbber.setAttribute("src", "");
document.getElementById("urlbar-image-deck").selectedIndex = 1;
this._throbber.removeAttribute("loading");
if (this._faviconAdded == false) {
var faviconURI = getBrowser().currentURI.prePath + "/favicon.ico";
var faviconURI = aBrowser.currentURI.prePath + "/favicon.ico";
this._setIcon(faviconURI);
}
}
@ -187,6 +470,11 @@ var BrowserUI = {
/* Set the location to the current content */
setURI : function() {
var browser = Browser.currentBrowser;
// FIXME: deckbrowser should not fire TebSelect on the initial tab (bug 454028)
if (!browser.currentURI)
return;
var back = document.getElementById("cmd_back");
var forward = document.getElementById("cmd_forward");
@ -216,7 +504,7 @@ var BrowserUI = {
var urlString = uri.spec;
if (urlString == "about:blank") {
urlString = "";
this.show(PANELMODE_URLEDIT);
this.show(UIMODE_URLEDIT);
}
this._caption.value = urlString;
@ -231,28 +519,21 @@ var BrowserUI = {
var flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
getBrowser().loadURIWithFlags(aURI, flags, null, null);
this.show(PANELMODE_URLVIEW);
this.show(UIMODE_URLVIEW);
},
search : function() {
var queryURI = "http://www.google.com/search?q=" + this._edit.value + "&hl=en&lr=&btnG=Search";
getBrowser().loadURI(queryURI, null, null, false);
this.show(PANELMODE_URLVIEW);
this.show(UIMODE_URLVIEW);
},
sizeAutocompletePopup : function () {
var rect = document.getElementById("browser-container").getBoundingClientRect();
var toolbar = document.getElementById("toolbar-main");
var popup = document.getElementById("popup_autocomplete");
popup.height = rect.bottom - rect.top - toolbar.boxObject.height;
},
openDefaultHistory : function () {
if (!this._edit.value) {
this._autocompleteNavbuttons.hidden = true;
updateAutoComplete : function(showDefault)
{
this.updateSearchEngines();
if (showDefault || this._edit.getAttribute("nomatch"))
this._edit.showHistoryPopup();
}
},
doButtonSearch : function(button)
@ -263,8 +544,6 @@ var BrowserUI = {
var urlbar = this._edit;
urlbar.open = false;
var value = urlbar.value;
if (!value)
return;
var submission = button.engine.getSubmission(value, null);
getBrowser().loadURI(submission.uri.spec, null, submission.postData, false);
@ -288,139 +567,106 @@ var BrowserUI = {
this.engines = engines;
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var container = this._autocompleteNavbuttons;
for (var e = 0; e < engines.length; e++) {
for (var e = 0; e < kMaxEngines && e < engines.length; e++) {
var button = document.createElementNS(kXULNS, "toolbarbutton");
var engine = engines[e];
button.id = engine.name;
button.setAttribute("label", engine.name);
button.className = "searchengine";
if (engine.iconURI)
button.setAttribute("image", engine.iconURI.spec);
container.insertBefore(button, container.firstChild);
container.appendChild(button);
button.engine = engine;
}
},
mode : PANELMODE_NONE,
mode : UIMODE_NONE,
show : function(aMode) {
if (this.mode == aMode)
return;
if (this.mode == UIMODE_BOOKMARKLIST && aMode != UIMODE_BOOKMARKLIST)
window.removeEventListener("keypress", BrowserUI.closePopup, false);
this.mode = aMode;
var toolbar = document.getElementById("toolbar-main");
var bookmark = document.getElementById("bookmark-container");
var urllist = document.getElementById("urllist-container");
var sidebar = document.getElementById("browser-controls");
var tablist = document.getElementById("tab-list-container");
var container = document.getElementById("browser-container");
// Make sure the UI elements are sized correctly since the window size can change
sidebar.left = toolbar.width = container.boxObject.width;
sidebar.height = tablist.height = container.boxObject.height - toolbar.boxObject.height;
function doTheStuff()
if (aMode == UIMODE_URLVIEW)
{
this._edit.hidden = true;
this._edit.reallyClosePopup();
this._caption.hidden = false;
}
function viewURL() { toolbar.setAttribute("mode", "view"); }
function editURL() { toolbar.setAttribute("mode", "edit"); }
function showToolbar() { toolbar.top = 0; }
function hideToolbar() { toolbar.top = -toolbar.boxobject.height; }
function showSidebar() { sidebar.left = toolbar.boxObject.width - sidebar.boxObject.width; }
function hideSidebar() { sidebar.left = toolbar.boxObject.width; }
function showTablist() { tablist.left = 0; }
function hideTablist() { tablist.left = -tablist.boxObject.width; }
function showPane(id)
{
var nodes = container.childNodes;
Array.forEach(container.childNodes, function(n)
{
var nid = n.getAttribute("id");
if (nid != "browser")
n.hidden = !(nid == id);
});
}
if (aMode == PANELMODE_URLVIEW || aMode == PANELMODE_SIDEBAR ||
aMode == PANELMODE_TABLIST || aMode == PANELMODE_FULL)
{
doTheStuff();
viewURL();
showToolbar();
if (aMode == PANELMODE_SIDEBAR || aMode == PANELMODE_FULL)
showSidebar();
if (aMode == PANELMODE_TABLIST || aMode == PANELMODE_FULL)
showTablist();
}
else if (aMode == PANELMODE_URLEDIT) {
toolbar.setAttribute("mode", "edit");
toolbar.top = 0;
this._caption.hidden = true;
this._edit.hidden = false;
this._edit.focus();
this._showToolbar(true);
this._editToolbar(false);
bookmark.hidden = true;
urllist.hidden = true;
sidebar.left = toolbar.boxObject.width;
tablist.left = -tablist.boxObject.width;
this._showPanel(UIMODE_NONE);
Shortcuts.dismiss();
}
else if (aMode == PANELMODE_BOOKMARK) {
toolbar.top = 0;
toolbar.setAttribute("mode", "view");
this._edit.hidden = true;
this._edit.reallyClosePopup();
this._caption.hidden = false;
else if (aMode == UIMODE_URLEDIT) {
this._showToolbar(true);
this._editToolbar(true);
bookmark.hidden = true;
urllist.hidden = true;
this._showPanel(UIMODE_NONE);
Shortcuts.dismiss();
}
else if (aMode == UIMODE_BOOKMARK) {
this._showToolbar(true);
this._editToolbar(false);
urllist.hidden = true;
sidebar.left = toolbar.boxObject.width;
tablist.left = -tablist.boxObject.width;
bookmark.hidden = false;
bookmark.width = container.boxObject.width;
this._showPanel(UIMODE_NONE);
Shortcuts.dismiss();
}
else if (aMode == PANELMODE_BOOKMARKLIST) {
toolbar.top = 0;
toolbar.setAttribute("mode", "view");
this._edit.hidden = true;
this._edit.reallyClosePopup();
this._caption.hidden = false;
else if (aMode == UIMODE_BOOKMARKLIST) {
this._showToolbar(false);
this._editToolbar(false);
window.addEventListener("keypress", this.closePopup, false);
bookmark.hidden = true;
sidebar.left = toolbar.boxObject.width;
tablist.left = -tablist.boxObject.width;
urllist.hidden = false;
urllist.width = container.boxObject.width;
urllist.height = container.boxObject.height - toolbar.boxObject.height;
urllist.height = container.boxObject.height;
this._showPanel(UIMODE_NONE);
Shortcuts.dismiss();
}
else if (aMode == PANELMODE_SHORTCUTS) {
this._edit.hidden = true;
this._edit.reallyClosePopup();
this._caption.hidden = false;
else if (aMode == UIMODE_PANEL) {
this._showToolbar(true);
this._editToolbar(false);
bookmark.hidden = true;
urllist.hidden = true;
toolbar.top = -toolbar.boxObject.height;
sidebar.left = toolbar.boxObject.width;
tablist.left = -tablist.boxObject.width;
document.getElementById("shortcuts-container").hidden = false;
let addons = document.getElementById("addons-container");
if (addons.getAttribute("src") == "")
addons.setAttribute("src", "chrome://mozapps/content/extensions/extensions.xul");
let dloads = document.getElementById("downloads-container");
if (dloads.getAttribute("src") == "")
dloads.setAttribute("src", "chrome://mozapps/content/downloads/downloads.xul");
Shortcuts.edit();
this._showPanel(aMode);
}
else if (aMode == PANELMODE_NONE) {
toolbar.top = -toolbar.boxObject.height;
sidebar.left = toolbar.boxObject.width;
tablist.left = -tablist.boxObject.width;
else if (aMode == UIMODE_TABS || aMode == UIMODE_CONTROLS) {
this._showPanel(aMode);
}
else if (aMode == UIMODE_NONE) {
this._showToolbar(false);
this._edit.reallyClosePopup();
urllist.hidden = true;
bookmark.hidden = true;
this._showPanel(aMode);
Shortcuts.dismiss();
}
},
@ -437,6 +683,7 @@ var BrowserUI = {
let node = aItems[i];
let listItem = document.createElement("richlistitem");
listItem.setAttribute("class", "urllist-item");
listItem.setAttribute("value", node.uri);
let box = document.createElement("vbox");
box.setAttribute("pack", "center");
@ -460,12 +707,18 @@ var BrowserUI = {
list.focus();
},
closePopup : function(aEvent)
{
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE)
BrowserUI.show(UIMODE_NONE);
},
showHistory : function() {
this._showPlaces(this._getHistory(6));
},
showBookmarks : function () {
this.show(PANELMODE_BOOKMARKLIST);
this.show(UIMODE_BOOKMARKLIST);
var bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
this._showPlaces(this._getBookmarks([bms.bookmarksMenuFolder]));
@ -473,61 +726,65 @@ var BrowserUI = {
newTab : function() {
Browser.content.newTab(true);
this.show(PANELMODE_URLEDIT);
this.show(UIMODE_URLEDIT);
},
selectTab : function(aTab) {
Browser.content.selectTab(aTab);
this.show(PANELMODE_NONE);
this.show(UIMODE_NONE);
},
handleEvent: function (aEvent) {
switch (aEvent.type) {
// Browser events
case "DOMTitleChanged":
this._titleChanged(aEvent);
this._titleChanged(aEvent.target);
break;
case "DOMLinkAdded":
this._linkAdded(aEvent);
break;
case "TabSelect":
this._tabSelect(aEvent);
break;
// URL textbox events
case "click":
this.show(PANELMODE_URLEDIT);
this.openDefaultHistory();
this.show(UIMODE_URLEDIT);
this.updateAutoComplete(true);
break;
case "input":
if (this._edit.value) {
this.updateSearchEngines();
this._autocompleteNavbuttons.hidden = false;
}
this.updateAutoComplete(false);
break;
case "keypress":
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
this._edit.reallyClosePopup();
this.show(PANELMODE_URLVIEW);
this.show(UIMODE_URLVIEW);
}
break;
// Favicon events
case "error":
this._favicon.setAttribute("src", "chrome://browser/skin/images/default-favicon.png");
this._favicon.src = "chrome://browser/skin/images/default-favicon.png";
break;
case "pan": {
// Default to hide the controls when user pans
let mode = PANELMODE_NONE;
// Open the urlbar controls if browser is at top of content
if (Browser.content.scrollY == 0)
mode = PANELMODE_URLVIEW
this.show(mode);
// UI panning events
case "mousedown":
this._dragData.dragging = true;
this._dragData.dragX = 0;
this._dragData.dragY = 0;
this._dragData.screenX = this._dragData.lastX = aEvent.screenX;
this._dragData.screenY = this._dragData.lastY = aEvent.screenY;
this._dragData.sTop = document.getElementById("toolbar-main").top;
this._dragData.sLeft = document.getElementById("tab-list-container").left;
break;
}
case "overpan":
// Open the sidebar controls if we get a right side overpan
if (aEvent.detail == 2)
this.show(PANELMODE_SIDEBAR);
// Close the sidebar controls if we get a left side overpan
else if (aEvent.detail == 1)
this.show(PANELMODE_TABLIST);
case "mouseup":
this._dragData.dragging = false;
// Cause the UI to snap, if needed
this._showPanel(this.mode);
break;
case "mousemove":
this._scrollToolbar(aEvent);
break;
// Window size events
case "resize":
this._sizeControls(aEvent);
break;
}
},
@ -547,6 +804,9 @@ var BrowserUI = {
case "cmd_menu":
case "cmd_newTab":
case "cmd_closeTab":
case "cmd_actions":
case "cmd_panel":
case "cmd_sanitize":
isSupported = true;
break;
default:
@ -598,10 +858,10 @@ var BrowserUI = {
var fis = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
fis.setAndLoadFaviconForPage(bookmarkURI, faviconURI, true);
this.show(PANELMODE_NONE);
this.show(UIMODE_NONE);
}
else {
this.show(PANELMODE_BOOKMARK);
this.show(UIMODE_BOOKMARK);
BookmarkHelper.edit(bookmarkURI);
}
break;
@ -614,16 +874,22 @@ var BrowserUI = {
Shortcuts.edit();
break;
case "cmd_menu":
if (this.mode == PANELMODE_FULL)
this.show(PANELMODE_NONE);
else
this.show(PANELMODE_FULL);
break;
case "cmd_newTab":
this.newTab();
break;
case "cmd_closeTab":
Browser.content.removeTab(Browser.content.browser);
break;
case "cmd_sanitize":
Sanitizer.sanitize();
break;
case "cmd_panel":
{
var mode = (this.mode != UIMODE_PANEL ? UIMODE_PANEL : UIMODE_CONTROLS);
this.show(mode);
break;
}
}
}
};
@ -661,6 +927,7 @@ var BookmarkHelper = {
document.getElementById("bookmark-name").value = this._bmksvc.getItemTitle(this._item);
var currentTags = this._tagsvc.getTagsForURI(this._uri, {});
document.getElementById("bookmark-tags").value = currentTags.join(", ");
document.getElementById("bookmark-folder").value = ""; // XXX either use this or remove it
}
window.addEventListener("keypress", this, true);
@ -708,7 +975,7 @@ var BookmarkHelper = {
close : function() {
window.removeEventListener("keypress", this, true);
this._item = null;
BrowserUI.show(PANELMODE_NONE);
BrowserUI.show(UIMODE_NONE);
},
handleEvent: function (aEvent) {

Просмотреть файл

@ -9,3 +9,28 @@ deckbrowser {
richlistitem[type="documenttab"] {
-moz-binding: url("chrome://browser/content/deckbrowser.xml#documenttab");
}
#prefs-container > scrollbox
{
overflow: auto;
}
richpref[type="bool"] {
-moz-binding: url("chrome://browser/content/preferences/richpref.xml#richpref-bool");
}
richpref[type="boolint"] {
-moz-binding: url("chrome://browser/content/preferences/richpref.xml#richpref-boolint");
}
richpref[type="button"] {
-moz-binding: url("chrome://browser/content/preferences/richpref.xml#richpref-button");
}
notification {
-moz-binding: url("chrome://browser/content/notification.xml#notification");
}
notification button {
-moz-binding: url("chrome://browser/content/notification.xml#notification-button");
}

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -53,6 +54,7 @@ Cu.import("resource://gre/modules/SpatialNavigation.js");
// in the style of bug 385809
__defineGetter__("gPrefService", function () {
delete gPrefService;
var gPrefService;
return gPrefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch2);
});
@ -64,18 +66,6 @@ function getBrowser() {
var Browser = {
_content : null,
_titleChanged : function(aEvent) {
var browser = this.content.browser;
if (!browser || aEvent.target != browser.contentDocument)
return;
var docElem = document.documentElement;
var title = "";
if (aEvent.target.title)
title = aEvent.target.title + docElem.getAttribute("titleseparator");
document.title = title + docElem.getAttribute("titlemodifier");
},
startup : function() {
window.controllers.appendController(this);
window.controllers.appendController(BrowserUI);
@ -101,13 +91,20 @@ var Browser = {
return new ProgressController(content, browser);
};
this._content.tabList = document.getElementById("tab-list");
this._content.newTab(true);
this._content.addEventListener("DOMTitleChanged", this, true);
this._content.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false);
os.addObserver(gXPInstallObserver, "xpinstall-download-started", false);
BrowserUI.init();
this._spatialNavigation = new SpatialNavigation(this.content);
window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = new nsBrowserAccess();
this._content.addEventListener("command", this._handleContentCommand, false);
this._content.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
this._content.tabList = document.getElementById("tab-list");
this._content.newTab(true);
SpatialNavigation.init(this.content);
this.setupGeolocationPrompt();
@ -154,6 +151,15 @@ var Browser = {
}
},
setPluginState: function(state)
{
var phs = Components.classes["@mozilla.org/plugin/host;1"]
.getService(Components.interfaces.nsIPluginHost);
var plugins = phs.getPluginTags({ });
for (i = 0; i < plugins.length; ++i)
plugins[i].disabled = state;
},
setupGeolocationPrompt: function() {
try {
var geolocationService = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationService);
@ -163,7 +169,6 @@ var Browser = {
}
geolocationService.prompt = function(request) {
var notificationBox = Browser.getNotificationBox();
var notification = notificationBox.getNotificationWithValue("geolocation");
@ -171,29 +176,33 @@ var Browser = {
var bundle_browser = document.getElementById("bundle_browser");
var buttons = [{
label: bundle_browser.getString("gelocation.exactLocation"),
subLabel: bundle_browser.getString("gelocation.exactLocation.subLabel"),
accessKey: bundle_browser.getString("gelocation.exactLocationKey"),
callback: function(){request.allow()},
callback: function(){request.allow()}
},
{
label: bundle_browser.getString("gelocation.neighborhoodLocation"),
subLabel: bundle_browser.getString("gelocation.neighborhoodLocation.subLabel"),
accessKey: bundle_browser.getString("gelocation.neighborhoodLocationKey"),
callback: function(){request.allowButFuzz()},
callback: function(){request.allowButFuzz()}
},
{
label: bundle_browser.getString("gelocation.nothingLocation"),
subLabel: "",
accessKey: bundle_browser.getString("gelocation.nothingLocationKey"),
callback: function(){request.cancel()},
callback: function(){request.cancel()}
}];
var message = bundle_browser.getFormattedString("geolocation.requestMessage", [request.requestingURI.spec]);
notificationBox.appendNotification(message,
"geolocation",
null, // todo "chrome://browser/skin/Info.png",
notificationBox.PRIORITY_INFO_HIGH,
buttons);
var notification = notificationBox.appendNotification(message,
"geolocation", null, // todo "chrome://browser/skin/Info.png",
notificationBox.PRIORITY_INFO_HIGH, buttons);
var children = notification.childNodes;
for (var b = 0; b < children.length; b++)
children[b].setAttribute("sublabel", children[b].buttonInfo.subLabel);
return 1;
}
};
}
},
get content() {
@ -208,19 +217,10 @@ var Browser = {
return this._content.browser;
},
handleEvent: function (aEvent) {
switch (aEvent.type) {
case "DOMTitleChanged":
this._titleChanged(aEvent);
break;
}
},
supportsCommand : function(cmd) {
var isSupported = false;
switch (cmd) {
case "cmd_fullscreen":
case "cmd_addons":
case "cmd_downloads":
isSupported = true;
break;
@ -242,34 +242,6 @@ var Browser = {
case "cmd_fullscreen":
window.fullScreen = !window.fullScreen;
break;
case "cmd_addons":
{
const EMTYPE = "Extension:Manager";
var aOpenMode = "extensions";
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var needToOpen = true;
var windowType = EMTYPE + "-" + aOpenMode;
var windows = wm.getEnumerator(windowType);
while (windows.hasMoreElements()) {
var theEM = windows.getNext().QueryInterface(Ci.nsIDOMWindowInternal);
if (theEM.document.documentElement.getAttribute("windowtype") == windowType) {
theEM.focus();
needToOpen = false;
break;
}
}
if (needToOpen) {
const EMURL = "chrome://mozapps/content/extensions/extensions.xul?type=" + aOpenMode;
const EMFEATURES = "chrome,dialog=no,resizable=yes";
window.openDialog(EMURL, "", EMFEATURES);
}
break;
}
case "cmd_downloads":
Cc["@mozilla.org/download-manager-ui;1"].getService(Ci.nsIDownloadManagerUI).show(window);
break;
}
},
@ -301,8 +273,9 @@ var Browser = {
findbar.onFindCommand();
else
findbar.onFindAgainCommand(Browser.findState == FINDSTATE_FIND_PREVIOUS);
},
translatePhoneNumbers: function(){
},
translatePhoneNumbers: function() {
let doc = getBrowser().contentDocument;
let textnodes = doc.evaluate("//text()",
doc,
@ -311,21 +284,76 @@ var Browser = {
null);
let s, node, lastLastIndex;
let re = /(\+?1? ?-?\(?\d{3}\)?[ +-\.]\d{3}[ +-\.]\d{4})/
for (var i = 0; i < textnodes.snapshotLength; i++) {
node = textnodes.snapshotItem(i);
s = node.data;
if(s.match(re)){
s = s.replace(re,"<a href='tel:$1'> $1 </a>");
try{
let replacement = doc.createElement("span");
replacement.innerHTML = s;
node.parentNode.insertBefore(replacement,node);
node.parentNode.removeChild(node);
}catch(e){
//do nothing, but continue
}
}
}
for (var i = 0; i < textnodes.snapshotLength; i++) {
node = textnodes.snapshotItem(i);
s = node.data;
if (s.match(re)) {
s = s.replace(re, "<a href='tel:$1'> $1 </a>");
try {
let replacement = doc.createElement("span");
replacement.innerHTML = s;
node.parentNode.insertBefore(replacement, node);
node.parentNode.removeChild(node);
} catch(e) {
//do nothing, but continue
}
}
}
},
/**
* Handle command event bubbling up from content. This allows us to do chrome-
* privileged things based on buttons in, e.g., unprivileged error pages.
* Obviously, care should be taken not to trust events that web pages could have
* synthesized.
*/
_handleContentCommand: function (aEvent) {
// Don't trust synthetic events
if (!aEvent.isTrusted)
return;
var ot = aEvent.originalTarget;
var errorDoc = ot.ownerDocument;
// If the event came from an ssl error page, it is probably either the "Add
// Exception…" or "Get me out of here!" button
if (/^about:neterror\?e=nssBadCert/.test(errorDoc.documentURI)) {
if (ot == errorDoc.getElementById('exceptionDialogButton')) {
var params = { exceptionAdded : false };
try {
switch (gPrefService.getIntPref("browser.ssl_override_behavior")) {
case 2 : // Pre-fetch & pre-populate
params.prefetchCert = true;
case 1 : // Pre-populate
params.location = errorDoc.location.href;
}
} catch (e) {
Components.utils.reportError("Couldn't get ssl_override pref: " + e);
}
window.openDialog('chrome://pippki/content/exceptionDialog.xul',
'','chrome,centerscreen,modal', params);
// If the user added the exception cert, attempt to reload the page
if (params.exceptionAdded)
errorDoc.location.reload();
}
else if (ot == errorDoc.getElementById('getMeOutOfHereButton')) {
// Get the start page from the *default* pref branch, not the user's
var defaultPrefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefService).getDefaultBranch(null);
var url = "about:blank";
try {
url = defaultPrefs.getCharPref("browser.startup.homepage");
// If url is a pipe-delimited set of pages, just take the first one.
if (url.indexOf("|") != -1)
url = url.split("|")[0];
} catch (e) { /* Fall back on about blank */ }
Browser.currentBrowser.loadURI(url, null, null, false);
}
}
}
};
@ -339,24 +367,16 @@ ProgressController.prototype = {
init : function(aBrowser) {
this._browser = aBrowser;
// FIXME: until we can get proper canvas repainting hooked up, update the canvas every 300ms
var tabbrowser = this._tabbrowser;
this._refreshInterval = setInterval(function () {
tabbrowser.updateCanvasState();
}, 400);
},
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
if (aRequest && aWebProgress.DOMWindow == this._browser.contentWindow) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
BrowserUI.update(TOOLBARSTATE_LOADING);
this._tabbrowser.updateCanvasState();
BrowserUI.update(TOOLBARSTATE_LOADING, this._browser);
}
else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
BrowserUI.update(TOOLBARSTATE_LOADED);
this._tabbrowser.updateCanvasState();
BrowserUI.update(TOOLBARSTATE_LOADED, this._browser);
}
}
}
@ -366,7 +386,7 @@ ProgressController.prototype = {
aWebProgress.DOMWindow.focus();
Browser.translatePhoneNumbers();
this._tabbrowser.updateBrowser(this._browser, true);
this._tabbrowser.updateCanvasState(true);
this._tabbrowser.updateCanvasState();
//aWebProgress.DOMWindow.scrollbars.visible = false;
}
}
@ -414,14 +434,12 @@ ProgressController.prototype = {
if (aWebProgress.DOMWindow == this._browser.contentWindow) {
BrowserUI.setURI();
this._tabbrowser.updateBrowser(this._browser, false);
this._tabbrowser.updateCanvasState();
}
},
// This method is called to indicate a status changes for the currently
// loading page. The message is already formatted for display.
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) {
this._tabbrowser.updateCanvasState();
},
// Properties used to cache security state used to update the UI
@ -476,6 +494,87 @@ ProgressController.prototype = {
}
};
function nsBrowserAccess()
{
}
nsBrowserAccess.prototype =
{
QueryInterface : function(aIID)
{
if (aIID.equals(Ci.nsIBrowserDOMWindow) ||
aIID.equals(Ci.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
openURI : function(aURI, aOpener, aWhere, aContext)
{
var isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
if (isExternal && aURI && aURI.schemeIs("chrome")) {
dump("use -chrome command-line option to load external chrome urls\n");
return null;
}
var loadflags = isExternal ?
Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
var location;
if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
switch (aContext) {
case Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL :
aWhere = gPrefService.getIntPref("browser.link.open_external");
break;
default : // OPEN_NEW or an illegal value
aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
}
}
var newWindow;
if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW) {
var url = aURI ? aURI.spec : "about:blank";
newWindow = openDialog("chrome://browser/content/browser.xul", "_blank",
"all,dialog=no", url, null, null, null);
}
else {
if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
var tab = Browser._content.newTab(true);
if (tab) {
var content = Browser._content;
var browser = content.getBrowserForDisplay(content.getDisplayForTab(tab));
newWindow = browser.contentWindow;
}
}
else {
newWindow = aOpener ? aOpener.top : browser.contentWindow;
}
}
try {
var referrer;
if (aURI) {
if (aOpener) {
location = aOpener.location;
referrer = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(location, null, null);
}
newWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.loadURI(aURI.spec, loadflags, referrer, null, null);
}
newWindow.focus();
} catch(e) { }
return newWindow;
},
isTabContentWindow : function(aWindow)
{
return Browser._content.browsers.some(function (browser) browser.contentWindow == aWindow);
}
}
/**
* Utility class to handle manipulations of the identity indicators in the UI
*/
@ -852,3 +951,69 @@ const gPopupBlockerObserver = {
Browser.getNotificationBox().removeCurrentNotification();
}
};
const gXPInstallObserver = {
observe: function (aSubject, aTopic, aData)
{
var brandBundle = document.getElementById("bundle_brand");
var browserBundle = document.getElementById("bundle_browser");
switch (aTopic) {
case "xpinstall-install-blocked":
var installInfo = aSubject.QueryInterface(Components.interfaces.nsIXPIInstallInfo);
var host = installInfo.originatingURI.host;
var brandShortName = brandBundle.getString("brandShortName");
var notificationName, messageString, buttons;
if (!gPrefService.getBoolPref("xpinstall.enabled")) {
notificationName = "xpinstall-disabled"
if (gPrefService.prefIsLocked("xpinstall.enabled")) {
messageString = browserBundle.getString("xpinstallDisabledMessageLocked");
buttons = [];
}
else {
messageString = browserBundle.getFormattedString("xpinstallDisabledMessage",
[brandShortName, host]);
buttons = [{
label: browserBundle.getString("xpinstallDisabledButton"),
accessKey: browserBundle.getString("xpinstallDisabledButton.accesskey"),
popup: null,
callback: function editPrefs() {
gPrefService.setBoolPref("xpinstall.enabled", true);
return false;
}
}];
}
}
else {
notificationName = "xpinstall"
messageString = browserBundle.getFormattedString("xpinstallPromptWarning",
[brandShortName, host]);
buttons = [{
label: browserBundle.getString("xpinstallPromptAllowButton"),
accessKey: browserBundle.getString("xpinstallPromptAllowButton.accesskey"),
popup: null,
callback: function() {
// Force the addon manager panel to appear
CommandUpdater.doCommand("cmd_addons");
var mgr = Cc["@mozilla.org/xpinstall/install-manager;1"].createInstance(Ci.nsIXPInstallManager);
mgr.initManagerWithInstallInfo(installInfo);
return false;
}
}];
}
var nBox = Browser.getNotificationBox();
if (!nBox.getNotificationWithValue(notificationName)) {
const priority = nBox.PRIORITY_WARNING_MEDIUM;
const iconURL = "chrome://mozapps/skin/update/update.png";
nBox.appendNotification(messageString, notificationName, iconURL, priority, buttons);
}
break;
}
}
};
function getNotificationBox(aWindow) {
return Browser.getNotificationBox();
}

Просмотреть файл

@ -46,12 +46,13 @@
%browserDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!ENTITY % prefsDTD SYSTEM "chrome://browser/locale/preferences.dtd">
%prefsDTD;
]>
<window id="main-window"
width="800" height="480"
onload="Browser.startup();"
onresize="BrowserUI.sizeAutocompletePopup();"
windowtype="navigator:browser"
title="&brandShortName;"
titlemodifier="&brandShortName;"
@ -62,6 +63,7 @@
<script type="application/x-javascript" src="chrome://browser/content/commandUtil.js"/>
<script type="application/x-javascript" src="chrome://browser/content/browser.js"/>
<script type="application/x-javascript" src="chrome://browser/content/browser-ui.js"/>
<script type="application/x-javascript" src="chrome://browser/content/sanitize.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
@ -99,9 +101,9 @@
<!-- misc -->
<command id="cmd_menu" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_fullscreen" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_addons" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_downloads" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_shortcuts" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_actions" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_panel" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_sanitize" oncommand="CommandUpdater.doCommand(this.id);"/>
<!-- scrolling -->
<command id="cmd_scrollPageUp" oncommand="CommandUpdater.doCommand(this.id);"/>
@ -138,12 +140,10 @@
<!-- misc -->
<key id="key_menu" keycode="VK_F4" command="cmd_menu"/>
<key id="key_fullscreen" keycode="VK_F6" command="cmd_fullscreen"/>
<key id="key_addons" key="E" command="cmd_addons" modifiers="accel"/>
<key id="key_downloads" key="J" command="cmd_downloads" modifiers="control"/>
<!-- tabs -->
<key id="key_newTab" keycode="T" modifiers="accel" command="cmd_newTab"/>
<key id="key_closeTab" keycode="W" modifiers="accel" command="cmd_closeTab"/>
<key id="key_newTab" key="T" modifiers="accel" command="cmd_newTab"/>
<key id="key_closeTab" key="W" modifiers="accel" command="cmd_closeTab"/>
<!-- find -->
<key id="key_find" key="&findOnCmd.commandkey;" command="cmd_find" modifiers="accel"/>
@ -191,61 +191,127 @@
</popupset>
<stack id="browser-container" flex="1" style="overflow: hidden;">
<vbox id="browser">
<vbox id="browser" style="-moz-stack-sizing: ignore; width: 800px; height: 480px;" top="60">
<notificationbox id="notifications" flex="1">
<deckbrowser id="content" autocompletepopup="popup_autocomplete_content" flex="1"
onnewtab="CommandUpdater.doCommand('cmd_newTab');"/>
</notificationbox>
</vbox>
<vbox id="browser-controls" style="-moz-stack-sizing: ignore; width: 80px;" top="60" left="0">
<toolbarbutton id="tool-back" class="browser-control-button" command="cmd_back"/>
<toolbarbutton id="tool-forward" class="browser-control-button" command="cmd_forward"/>
<toolbarbutton id="tool-star" class="browser-control-button" command="cmd_star"/>
<toolbarbutton id="tool-bookmarks" class="browser-control-button" command="cmd_bookmarks"/>
<toolbarbutton id="tool-actions" class="browser-control-button" command="cmd_actions"/>
<toolbarbutton id="tool-shortcuts" class="browser-control-button" command="cmd_shortcuts"/>
</vbox>
<vbox id="tab-list-container" style="-moz-stack-sizing: ignore;" top="60" left="0">
<richlistbox id="tab-list" onselect="BrowserUI.selectTab(this.selectedItem);"/>
<button id="newtab-button" label="+" command="cmd_newTab"/>
</vbox>
<toolbar id="toolbar-main" style="-moz-stack-sizing: ignore; height: 60px;" top="0" left="0">
<toolbar id="toolbar-main" style="-moz-stack-sizing: ignore; height: 60px" top="0" left="0">
<hbox id="urlbar-container" flex="1">
<box id="identity-box"
onclick="getIdentityHandler().handleIdentityButtonEvent(event);"
onkeypress="getIdentityHandler().handleIdentityButtonEvent(event);">
<stack id="urlbar-image-stack">
<image id="urlbar-throbber" src=""/>
<image id="urlbar-favicon" src=""/>
</stack>
<deck id="urlbar-image-deck">
<image id="urlbar-throbber"/>
<image id="urlbar-favicon"/>
</deck>
</box>
<description id="urlbar-caption" crop="end" flex="1"/>
<textbox id="urlbar-edit"
type="autocomplete"
autocompletesearch="history"
enablehistory="false"
maxrows="6"
completeselectedindex="true"
minresultsforpopup="0"
flex="1"
hidden="true"
autocompletepopup="popup_autocomplete"
ontextentered="BrowserUI.goToURI();"
clickSelectsAll="true"/>
</hbox>
<hbox id="urlbar-icons">
<toolbarbutton id="tool-reload" class="urlbar-icon-button" command="cmd_reload"/>
<toolbarbutton id="tool-stop" class="urlbar-icon-button" command="cmd_stop"/>
<toolbarbutton id="tool-go" class="urlbar-icon-button" command="cmd_go"/>
<hbox id="urlbar-editarea" flex="1">
<description id="urlbar-caption" crop="end" flex="1"/>
<textbox id="urlbar-edit"
type="autocomplete"
autocompletesearch="history"
enablehistory="false"
maxrows="6"
completeselectedindex="true"
minresultsforpopup="0"
flex="1"
hidden="true"
autocompletepopup="popup_autocomplete"
ontextentered="BrowserUI.goToURI();"
onsearchcomplete="BrowserUI.updateAutoComplete(false);"
clickSelectsAll="true"/>
</hbox>
<hbox id="urlbar-icons">
<toolbarbutton id="tool-reload" class="urlbar-icon-button" command="cmd_reload"/>
<toolbarbutton id="tool-stop" class="urlbar-icon-button" command="cmd_stop"/>
<toolbarbutton id="tool-go" class="urlbar-icon-button" command="cmd_go"/>
</hbox>
</hbox>
<toolbarbutton id="tool-bookmarks" class="urlbar-icon-button" command="cmd_bookmarks"/>
</toolbar>
<vbox id="urllist-container" hidden="true" style="-moz-stack-sizing: ignore;" top="60" left="0">
<vbox id="browser-controls" style="-moz-stack-sizing: ignore;" top="60" left="0">
<toolbarbutton id="tool-star" class="browser-control-button" command="cmd_star"/>
<toolbarbutton id="tool-back" class="browser-control-button" command="cmd_back"/>
<toolbarbutton id="tool-forward" class="browser-control-button" command="cmd_forward"/>
<toolbarspring/>
<toolbarbutton id="tool-actions" class="browser-control-button" command="cmd_actions"/>
<toolbarbutton id="tool-stuff" class="browser-control-button" command="cmd_panel"/>
</vbox>
<hbox id="panel-container" style="-moz-stack-sizing: ignore;" top="0" left="0">
<vbox id="panel-controls">
<toolbarbutton id="tool-addons" class="browser-control-button" oncommand="this.parentNode.nextSibling.selectedIndex=0;"/>
<toolbarbutton id="tool-downloads" class="browser-control-button" oncommand="this.parentNode.nextSibling.selectedIndex=1;"/>
<toolbarbutton id="tool-preferences" class="browser-control-button" oncommand="this.parentNode.nextSibling.selectedIndex=2;"/>
<toolbarbutton id="tool-shortcuts" class="browser-control-button" oncommand="this.parentNode.nextSibling.selectedIndex=3;"/>
</vbox>
<deck id="panel-items" flex="1">
<iframe id="addons-container" flex="1" src=""/>
<iframe id="downloads-container" flex="1" src=""/>
<vbox id="prefs-container">
<hbox pack="center" id="buttons"/>
<scrollbox orient="vertical" id="pref-list" seltype="single" flex="1">
<vbox class="prefsection">
<label value="&content.title;" crop="end" flex="1"/>
</vbox>
<richpref pref="permissions.default.image" title="&permissions.default.image.title;" type="boolint" on="1" off="2">
&permissions.default.image.description;
</richpref>
<richpref pref="javascript.enabled" type="bool" title="&javascript.enabled.title;">
&javascript.enabled.description;
</richpref>
<richpref pref="plugins.enabled" type="bool" title="&plugins.enabled.title;" onsyncfrompreference="Browser.setPluginState(this.value);">
&plugins.enabled.description;
</richpref>
<vbox class="prefsection">
<label value="&privacy.title;" crop="end" flex="1"/>
</vbox>
<richpref pref="network.cookie.cookieBehavior" title="&network.cookie.cookieBehavior.title;" type="boolint" on="1" off="3">
&network.cookie.cookieBehavior.description;
</richpref>
<richpref pref="signon.rememberSignons" title="&signon.rememberSignons.title;" type="bool">
&signon.rememberSignons.description;
</richpref>
<richpref title="&clear.private.data.title;" type="button">
&clear.private.data.description;
<button label="&clear.private.data.button;" command="cmd_sanitize"/>
</richpref>
</scrollbox>
</vbox>
<vbox id="shortcuts-container">
<tree id="shortcuts" flex="1" seltype="cell" hidecolumnpicker="true" editable="true" textboxtype="clearable">
<treecols>
<treecol id="name" flex="5" hideheader="true"/>
<treecol id="value" flex="3" hideheader="true" editable="true" primary="true"/>
</treecols>
<treechildren id="shortcuts-children"/>
</tree>
</vbox>
</deck>
</hbox>
<vbox id="tab-list-container" style="-moz-stack-sizing: ignore;" top="60" left="0">
<richlistbox id="tab-list" onselect="BrowserUI.selectTab(this.selectedItem);"/>
<hbox>
<toolbarbutton id="newtab-button" command="cmd_newTab"/>
<toolbarbutton id="retrievetab-button" command=""/>
</hbox>
</vbox>
<vbox id="urllist-container" hidden="true" style="-moz-stack-sizing: ignore;" top="0" left="0">
<hbox id="urllist-items-container" flex="1">
<richlistbox id="urllist-items" flex="1"/>
<richlistbox id="urllist-items" flex="1"
onkeypress="if (event.keyCode == event.DOM_VK_RETURN) BrowserUI.goToURI(this.selectedItem.value)"/>
</hbox>
<hbox pack="end">
<button id="urllist-close" oncommand="BrowserUI.show(UIMODE_NONE)"/>
</hbox>
</vbox>
@ -282,19 +348,6 @@
</hbox>
</vbox>
</vbox>
<vbox id="shortcuts-container" hidden="true" flex="1">
<tree id="shortcuts" flex="1" seltype="cell" hidecolumnpicker="true" editable="true" textboxtype="clearable">
<treecols>
<treecol id="name" flex="2" hideheader="true"/>
<treecol id="value" flex="1" hideheader="true" editable="true" primary="true"/>
</treecols>
<treechildren id="shortcuts-children"/>
</tree>
<hbox pack="end">
<button label="Dismiss" oncommand="Shortcuts.dismiss();"/>
</hbox>
</vbox>
</stack>
<vbox id="findpanel-placeholder" sizetopopup="always">

Просмотреть файл

@ -24,7 +24,7 @@
</resources>
<implementation implements="nsIObserver">
<constructor>
<constructor><![CDATA[
this._zoomLevel = 1;
// panning
@ -33,6 +33,11 @@
window.addEventListener("mouseup", this.stackEventHandler, true);
this._stack.addEventListener("mousemove", this.stackEventHandler, true);
var prefsvc = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch2);
this._allowKinetic = prefsvc.getBoolPref("browser.ui.panning.kinetic");
// zoom
// FIXME: dblclicks don't work on the device
// this._stack.addEventListener("dblclick", this.stackEventHandler, true);
@ -45,21 +50,32 @@
"memory-pressure", false);
this._dragStartTimeout = -1;
</constructor>
<field name="dragData">
({
dragging: false,
dragX: 0,
dragY: 0,
sX: 0,
sY: 0,
pageX: 0,
pageY: 0,
oldPageX: 0,
oldPageY: 0
})
</field>
this.PAN_EVENTS_TO_TRACK = 2;
this._panEventTracker = new Array(this.PAN_EVENTS_TO_TRACK);
this._panEventTrackerIndex = 0;
]]></constructor>
<property name="dragData" readonly="true">
<getter>
<![CDATA[
if (!this.currentTab.dragData) {
this.currentTab.dragData = {
dragging: false,
dragX: 0,
dragY: 0,
sX: 0,
sY: 0,
pageX: 0,
pageY: 0,
oldPageX: 0,
oldPageY: 0
}
}
return this.currentTab.dragData;
]]>
</getter>
</property>
<field name="_stack">
document.getAnonymousElementByAttribute(this, "anonid", "cstack");
@ -77,6 +93,18 @@
</getter>
</property>
<property name="browsers" readonly="true">
<getter>
<![CDATA[
var browsers = [];
var tabList = this.tabList.childNodes;
for (var t = 0; t < tabList.length; t++)
browsers.push(getBrowserForDisplay(this.displayList.childNodes[t]));
return browsers;
]]>
</getter>
</property>
<property name="displayList" readonly="true">
<getter>
return document.getAnonymousElementByAttribute(this, "anonid", "display-list");
@ -90,19 +118,12 @@
<field name="progressListenerCreator"/>
<method name="updateCanvasState">
<parameter name="aNewDoc"/>
<body><![CDATA[
if (aNewDoc)
this._updateViewState();
if (this._updateTimeout)
clearTimeout(this._updateTimeout);
var self = this;
this._updateTimeout = setTimeout(function () {
if (!self.dragData.dragging)
self._browserToCanvas();
}, 100);
this._updateViewState();
// clear the whole canvas and redraw
var ctx = this._canvas.getContext("2d");
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
this._browserToCanvas();
]]></body>
</method>
@ -164,6 +185,15 @@
</body>
</method>
<method name="setLoading">
<parameter name="browser"/>
<body><![CDATA[
var tab = this.getTabForDisplay(browser.parentNode);
if (tab)
tab.dragData = null;
]]></body>
</method>
<method name="updateBrowser">
<parameter name="browser"/>
<parameter name="done"/>
@ -188,6 +218,28 @@
]]></body>
</method>
<field name="browserRedrawHandler">
<![CDATA[
({
deckbrowser: this,
handleEvent: function (aEvent) {
let self = this.deckbrowser;
if (self.dragData.dragging || self.dragData.kineticId)
return;
for (let i = 0; i < aEvent.clientRects.length; i++) {
let e = aEvent.clientRects.item(i);
//dump(Math.floor(e.left) + ", " + Math.floor(e.top) + ", " + Math.ceil(e.width) + ", " + Math.ceil(e.height) + "\n");
self._browserToCanvas2(Math.floor(e.left), Math.floor(e.top), Math.ceil(e.width), Math.ceil(e.height));
}
}
});
]]>
</field>
<method name="selectTab">
<parameter name="tab"/>
<body><![CDATA[
@ -198,6 +250,9 @@
var currentDisplay = this.getDisplayForTab(currentTab);
var currentBrowser = this.getBrowserForDisplay(currentDisplay);
if (currentBrowser) {
// stop monitor paint events for this browser
currentBrowser.removeEventListener("MozAfterPaint", this.browserRedrawHandler, false);
currentDisplay.url = currentBrowser.contentWindow.location.toString();
currentBrowser.setAttribute("type", "content");
currentTab.updateTab(currentBrowser);
@ -214,6 +269,16 @@
browser.setAttribute("type", "content-primary");
this.displayList.selectedPanel = display;
// start monitoring paint events for this browser
browser.addEventListener("MozAfterPaint", this.browserRedrawHandler, false);
// force a repaint of the selected tab
this._browserToCanvas();
var event = document.createEvent("Events");
event.initEvent("TabSelect", true, false);
tab.dispatchEvent(event);
]]></body>
</method>
@ -221,7 +286,16 @@
<parameter name="makeFront"/>
<body><![CDATA[
var browser = this.createBrowser(makeFront, null, null);
return browser ? this.getTabForDisplay(browser.parentNode) : null;
if (!browser)
return null;
var tab = this.getTabForDisplay(browser.parentNode);
var evt = document.createEvent("Events");
evt.initEvent("TabOpen", true, false);
tab.dispatchEvent(evt);
return tab;
]]></body>
</method>
@ -235,6 +309,10 @@
if (display)
display.removeChild(display);
tab.parentNode.removeChild(tab);
var evt = document.createEvent("Events");
evt.initEvent("TabClose", true, false);
tab.dispatchEvent(evt);
]]></body>
</method>
@ -318,7 +396,7 @@
canvas.setAttribute("height", domWin.innerHeight);
var ctx = canvas.getContext("2d");
ctx.drawWindow(domWin, 0, 0, domWin.innerWidth, domWin.innerHeight, "rgba(0,0,0,0)");
ctx.drawWindow(domWin, 0, 0, domWin.innerWidth, domWin.innerHeight, "white");
display.insertBefore(canvas, display.firstChild);
display.lastAccess = Date.now();
@ -374,8 +452,8 @@
}
}
state._scrollX = window.scrollX;
state._scrollY = window.scrollY;
state._scrollX = browser.contentWindow.scrollX;
state._scrollY = browser.contentWindow.scrollY;
display.state = state;
]]></body>
@ -411,7 +489,10 @@
<method name="_browserToCanvas">
<body><![CDATA[
// FIXME: canvas needs to know it's actual width/height
// we should be able to use _canvas.width/_canvas.height here
// and can, most of the time
var rect = this._canvas.getBoundingClientRect();
var w = rect.right - rect.left;
var h = rect.bottom - rect.top;
@ -419,19 +500,84 @@
this._canvas.height = h;
var ctx = this._canvas.getContext("2d");
ctx.clearRect(0,0,w,h);
ctx.save();
ctx.scale(this._zoomLevel, this._zoomLevel);
ctx.drawWindow(this.browser.contentWindow,
this.dragData.pageX, this.dragData.pageY,
w / this._zoomLevel, h / this._zoomLevel,
this._screenToPage(w), this._screenToPage(h),
"white");
ctx.restore();
]]></body>
</method>
<method name="_browserToCanvas2">
<parameter name="x"/>
<parameter name="y"/>
<parameter name="width"/>
<parameter name="height"/>
<body><![CDATA[
function intersect(r1, r2) {
let xmost1 = r1.x + r1.width;
let ymost1 = r1.y + r1.height;
let xmost2 = r2.x + r2.width;
let ymost2 = r2.y + r2.height;
let x = Math.max(r1.x, r2.x);
let y = Math.max(r1.y, r2.y);
let temp = Math.min(xmost1, xmost2);
if (temp <= x)
return null;
let width = temp - x;
temp = Math.min(ymost1, ymost2);
if (temp <= y)
return null;
let height = temp - y;
return {
x: x,
y: y,
width: width,
height: height
};
}
let r1 = { x : x,
y : y,
width : width,
height: height };
// check to see if the input coordinates are inside the visiable destination
let r2 = { x : this.dragData.pageX,
y : this.dragData.pageY,
width : this._canvas.width / this._zoomLevel,
height: this._canvas.height / this._zoomLevel };
let dest = intersect(r1, r2);
if (!dest)
return;
var ctx = this._canvas.getContext("2d");
ctx.save();
ctx.scale(this._zoomLevel, this._zoomLevel);
ctx.translate(dest.x - this.dragData.pageX, dest.y - this.dragData.pageY);
ctx.drawWindow(this.browser.contentWindow,
dest.x, dest.y,
dest.width, dest.height,
"white");
ctx.restore();
]]></body>
</method>
<method name="_updateCanvasPosition">
<body><![CDATA[
this._canvas.style.marginLeft = this.dragData.dragX + "px";
@ -442,7 +588,7 @@
// Force a sync redraw
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.redraw();
.processUpdates();
]]></body>
</method>
@ -502,8 +648,8 @@
// scale to the element's width
var elRect = this._getPagePosition(aElement);
this._zoomLevel = Math.max((this.browser.boxObject.width) / (elRect.width + (2 * margin)),
2);
var zoomLevel = this.browser.boxObject.width / (elRect.width + (2 * margin));
this._zoomLevel = Math.min(zoomLevel, 10);
// pan to the element
this._panTo(Math.max(elRect.x - margin, 0),
@ -521,14 +667,8 @@
<body><![CDATA[
var cdoc = this.browser.contentDocument;
// Need to adjust for the toolbar height, etc.
var browserTop = this.browser.getBoundingClientRect().top;
// Scroll the browser so that elementFromPoint works properly
var [pageOffsetX, pageOffsetY] = this._scrollAndGetOffset();
var element = cdoc.elementFromPoint((aX / this._zoomLevel) + pageOffsetX,
(aY / this._zoomLevel) + pageOffsetY - browserTop);
var [x, y] = this._clientToContentCoords(aX, aY);
var element = cdoc.elementFromPoint(x, y);
// Reset scroll state
this.browser.contentWindow.scrollTo(0, 0);
@ -552,22 +692,6 @@
]]></body>
</method>
<method name="_scrollAndGetOffset">
<parameter name="aX"/>
<parameter name="aY"/>
<body><![CDATA[
var cwin = this.browser.contentWindow;
cwin.scrollTo(this.dragData.pageX, this.dragData.pageY);
// Might not have been able to scroll all the way if we're zoomed in,
// the caller might need to account for that difference.
var pageOffsetX = this.dragData.pageX - cwin.scrollX;
var pageOffsetY = this.dragData.pageY - cwin.scrollY;
return [pageOffsetX, pageOffsetY];
]]></body>
</method>
<method name="_redispatchMouseEvent">
<parameter name="aEvent"/>
<parameter name="aType"/>
@ -577,20 +701,13 @@
return;
}
// Scroll the browser so that the event is targeted properly
var [pageOffsetX, pageOffsetY] = this._scrollAndGetOffset();
// Need to adjust for the toolbar height, etc.
var browserTop = this.browser.getBoundingClientRect().top;
var clickOffsetX = aEvent.clientX / this._zoomLevel;
var clickOffsetY = (aEvent.clientY - browserTop) / this._zoomLevel;
var [x, y] = this._clientToContentCoords(aEvent.clientX, aEvent.clientY);
var cwin = this.browser.contentWindow;
var cwu = cwin.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
cwu.sendMouseEvent(aType || aEvent.type,
pageOffsetX + clickOffsetX,
pageOffsetY + clickOffsetY,
x, y,
aEvent.button || 0,
aEvent.detail || 1,
0);
@ -600,6 +717,35 @@
]]></body>
</method>
<!-- Given a set of client coordinates (relative to the app window),
scrolls the content window as close to the clicked on content item
as possible, and returns the remaining offsets into the content
window if the object isn't at 0, 0. Callers should be sure to reset
scroll state after calling this method.
-->
<method name="_clientToContentCoords">
<parameter name="aClientX"/>
<parameter name="aClientY"/>
<body><![CDATA[
// Need to adjust for the toolbar height, etc.
var browserTop = this.browser.getBoundingClientRect().top;
var clickOffsetX = this._screenToPage(aClientX) + this.dragData.pageX;
var clickOffsetY = this._screenToPage(aClientY - browserTop) + this.dragData.pageY;
// Scroll the browser so that the event is targeted properly
var cwin = this.browser.contentWindow;
cwin.scrollTo(clickOffsetX, clickOffsetY);
// Might not have been able to scroll all the way if we're zoomed in,
// so we need to account for that difference.
var pageOffsetX = clickOffsetX - cwin.scrollX;
var pageOffsetY = clickOffsetY - cwin.scrollY;
return [pageOffsetX, pageOffsetY];
]]></body>
</method>
<property name="_contentAreaDimensions" readonly="true">
<getter>
var cdoc = this.browser.contentDocument;
@ -617,7 +763,7 @@
var h = Math.max(body.scrollHeight, html.scrollHeight);
if (isNaN(w) || isNaN(h))
throw "Can't get content width/height";
return [this._canvas.width, this._canvas.height];
return [w, h];
</getter>
@ -625,27 +771,23 @@
<property name="_effectiveCanvasDimensions" readonly="true">
<getter><![CDATA[
return [this._canvas.width / this._zoomLevel,
this._canvas.height / this._zoomLevel];
return [this._screenToPage(this._canvas.width),
this._screenToPage(this._canvas.height)];
]]></getter>
</property>
<property name="scrollX" readonly="true">
<getter><![CDATA[
return this.dragData.pageX - this.dragData.dragX / this._zoomLevel;
return this.dragData.pageX - this._screenToPage(this.dragData.dragX);
]]></getter>
</property>
<property name="scrollY" readonly="true">
<getter><![CDATA[
return this.dragData.pageY - this.dragData.dragY / this._zoomLevel;
return this.dragData.pageY - this._screenToPage(this.dragData.dragY);
]]></getter>
</property>
<field name="_fireOverpan">
0
</field>
/**
* Given a set of page coordinates, constrain them such that they
* fit within the rect defined by [0,0] and [x,y], where x and y are
@ -657,15 +799,6 @@
<parameter name="aX"/>
<parameter name="aY"/>
<body><![CDATA[
const OVERPAN_LIMIT = 30;
const OVERPAN_LEFT = 1;
const OVERPAN_RIGHT = 2;
const OVERPAN_TOP = 3;
const OVERPAN_BOTTOM = 4;
var origX = aX;
var origY = aY;
var [contentAreaWidth, contentAreaHeight] = this._contentAreaDimensions;
var [canvasW, canvasH] = this._effectiveCanvasDimensions;
@ -673,68 +806,191 @@
if (offscreenWidth <= 0) {
// Content is narrower than viewport, no need to pan horizontally
aX = 0;
// Check for an overpan
if (origX < -OVERPAN_LIMIT)
this._fireOverpan = OVERPAN_LEFT;
else if (origX > OVERPAN_LIMIT)
this._fireOverpan = OVERPAN_RIGHT;
} else {
var newPageX = Math.min(this.dragData.pageX + aX, offscreenWidth);
// min of 0, max of contentAreaWidth - canvasW
var newPageX = Math.min(this.dragData.pageX + aX, offscreenWidth);
newPageX = Math.max(newPageX, 0);
aX = newPageX - this.dragData.pageX;
// Check for an overpan
if (origX < -OVERPAN_LIMIT && aX <= 0 && newPageX == 0)
this._fireOverpan = OVERPAN_LEFT;
else if (origX > OVERPAN_LIMIT && aX >= 0 && (offscreenWidth - newPageX) == 0)
this._fireOverpan = OVERPAN_RIGHT;
}
var offscreenHeight = contentAreaHeight - canvasH;
if (offscreenHeight <= 0) {
// Content is shorter than viewport, no need to pan vertically
aY = 0;
// Check for an overpan
if (origY < -OVERPAN_LIMIT)
this._fireOverpan = OVERPAN_TOP;
else if (origY > OVERPAN_LIMIT)
this._fireOverpan = OVERPAN_BOTTOM;
} else {
// min of 0, max of contentAreaHeight - canvasHeight
// min of 0, max of contentAreaHeight - canvasH
var newPageY = Math.min(this.dragData.pageY + aY, offscreenHeight);
newPageY = Math.max(newPageY, 0);
aY = newPageY - this.dragData.pageY;
// Check for an overpan
if (origY < -OVERPAN_LIMIT && aY <= 0 && newPageY == 0)
this._fireOverpan = OVERPAN_TOP;
else if (origY > OVERPAN_LIMIT && aY >= 0 && (offscreenHeight - newPageY) == 0)
this._fireOverpan = OVERPAN_BOTTOM;
}
return [aX, aY];
]]></body>
</method>
<method name="_screenToPage">
<parameter name="aValue"/>
<body><![CDATA[
return aValue / this._zoomLevel;
]]></body>
</method>
<method name="_pageToScreen">
<parameter name="aValue"/>
<body><![CDATA[
return aValue * this._zoomLevel;
]]></body>
</method>
<method name="_moveCanvas">
<parameter name="aDx"/>
<parameter name="aDy"/>
<body><![CDATA[
// Fire the panning event
var event = document.createEvent("UIEvents");
event.initUIEvent("pan", true, true, window, 0);
if (this.dispatchEvent(event)) {
// Constrain offsets to the actual scrollWidth/scrollHeight
var [x, y] = this._constrainPanCoords(aDx, aDy);
// Constrain offsets to the actual scrollWidth/scrollHeight
var [x, y] = this._constrainPanCoords(this._screenToPage(aDx), this._screenToPage(aDy));
// Canvas needs to move up for content to scroll down
this.dragData.dragX = -x;
this.dragData.dragY = -y;
// Canvas needs to move up for content to scroll down
this.dragData.dragX = -this._pageToScreen(x);
this.dragData.dragY = -this._pageToScreen(y);
this._updateCanvasPosition();
this._updateCanvasPosition();
]]></body>
</method>
<method name="_startKinetic">
<body><![CDATA[
// Get the first and last mouse move event
let p2 = this._panEventTracker[this._panEventTrackerIndex];
let p1 = this._panEventTracker[(this._panEventTrackerIndex + 1) % this.PAN_EVENTS_TO_TRACK];
if (p2 && p1) {
let dx = p2.x - p1.x;
let dy = p2.y - p1.y;
let dt = p2.t - p1.t;
if (dt > 0) { // dt should never be less than 0
this.dragData.velocityX = dx / dt;
this.dragData.velocityY = dy / dt;
// Save the original x.y we're starting from to make sure
// we don't go backwards
this.dragData.originalX = this.dragData.dragX;
this.dragData.originalY = this.dragData.dragY;
// s = S0 + 0.5 * v0^2 * 1/CoK); s = position, s0 = initial pos
// v0 = initial velocity, CoK = Coefficient of Kinetic friction
// All in page coords
let idealDestScreenX = this.dragData.dragX + Math.abs(this.dragData.velocityX)
* this.dragData.velocityX * 200;
let idealDestScreenY = this.dragData.dragY + Math.abs(this.dragData.velocityY)
* this.dragData.velocityY * 200
let [destPageX, destPageY] = this._constrainPanCoords(-this._screenToPage(idealDestScreenX),
-this._screenToPage(idealDestScreenY));
// Convert to screen coords
this.dragData.destinationX = -this._pageToScreen(destPageX);
this.dragData.destinationY = -this._pageToScreen(destPageY);
// If we have a kinetic timer, kill it. This shouldn't happen
if (this.dragData.kineticId)
window.clearInterval(this.dragData.kineticId);
// Start timer for kinetic movements
let interval = dt / (this.PAN_EVENTS_TO_TRACK - 1);
this.dragData.kineticId = window.setInterval(this._doKinetic, interval, this, interval);
} else {
// dt <= 0, this is bad
this._endPan();
}
} else {
// p1 or p2 is null, either we didn't pan enough, or something went wrong
this._endPan()
}
// Clear out the old events since they aren't needed anymore
for (var i = 0; i < this.PAN_EVENTS_TO_TRACK; i++) {
this._panEventTracker[i] = null;
}
]]></body>
</method>
<method name="_doKinetic">
<parameter name="self"/>
<parameter name="dt"/>
<body><![CDATA[
// record where we're starting so we can test how far we went later
let startX = self.dragData.dragX;
let startY = self.dragData.dragY;
const stopTheshold = 3; //Distance from the destination point that we'll consider to be "there"
let dx = 0;
let dy = 0;
if (Math.abs(self.dragData.destinationX - self.dragData.dragX) < stopTheshold) {
dx = self.dragData.destinationX - self.dragData.dragX;
self.dragData.velocityX = dx/dt;
} else {
// decelerate, this assumes we decelerate perfectly to our destination
// it gets skewed if we're hitting an edge since we're using our progress
// instead of the time
dx = self.dragData.velocityX * dt * (Math.sqrt(Math.abs(self.dragData.destinationX - self.dragData.dragX))
/ Math.sqrt(Math.abs(self.dragData.destinationX - self.dragData.originalX)));
// if we're already at the destination, we don't want to move anymore
dx = self.dragData.originalX == self.dragData.destinationX ? 0 : dx;
}
if (Math.abs(self.dragData.destinationY - self.dragData.dragY) < stopTheshold) {
dx = self.dragData.destinationY - self.dragData.dragY;
self.dragData.velocityY = dx/dt;
} else {
// decelerate, this assumes we decelerate perfectly to our destination
// it gets skewed if we're hitting an edge since we're using our progress
// instead of the time
dy = self.dragData.velocityY * dt * (Math.sqrt(Math.abs(self.dragData.destinationY - self.dragData.dragY))
/ Math.sqrt(Math.abs(self.dragData.destinationY - self.dragData.originalY)));
// if we're already at the destination, we don't want to move anymore
dy = self.dragData.originalY == self.dragData.destinationY ? 0 : dy;
}
// Calculate the next x, y in screen space
let nextX = self.dragData.dragX + dx;
let nextY = self.dragData.dragY + dy;
// make sure we're still between original and destination coords
if((self.dragData.originalX > nextX &&
nextX > self.dragData.destinationX) ||
(self.dragData.originalX < nextX &&
nextX < self.dragData.destinationX))
self.dragData.dragX = nextX;
else
self.dragData.dragX = self.dragData.destinationX;
if((self.dragData.originalY > nextY &&
nextY > self.dragData.destinationY) ||
(self.dragData.originalY < nextY &&
nextY < self.dragData.destinationY))
self.dragData.dragY = nextY;
else
self.dragData.dragY = self.dragData.destinationY;
self._updateCanvasPosition();
// calculate how much we've actually moved and end if less than 4px
let actualDx = startX - self.dragData.dragX;
let actualDy = startY - self.dragData.dragY;
if ((actualDx / (self.dragData.destinationX - self.dragData.originalX) < 0 &&
actualDy / (self.dragData.destinationY - self.dragData.originalY) < 0) ||
(Math.abs(actualDx) < 4 && Math.abs(actualDy) < 4)) {
self._endKinetic();
}
]]></body>
</method>
<method name="_endKinetic">
<body><![CDATA[
window.clearInterval(this.dragData.kineticId);
this.dragData.kineticId = 0;
this._endPan();
]]></body>
</method>
@ -754,7 +1010,6 @@
<method name="_dragStartTimer">
<body><![CDATA[
this.dragData.lastMouseEvent = Date.now() - 10;
this.dragData.dragging = true;
this._dragStartTimeout = -1;
]]></body>
@ -762,10 +1017,10 @@
<method name="_endPan">
<body><![CDATA[
// dragX/dragY are garanteed to be within the correct bounds, so just
// dragX/dragY are guaranteed to be within the correct bounds, so just
// update pageX/pageY directly.
this.dragData.pageX -= this.dragData.dragX / this._zoomLevel;
this.dragData.pageY -= this.dragData.dragY / this._zoomLevel;
this.dragData.pageX -= this._screenToPage(this.dragData.dragX);
this.dragData.pageY -= this._screenToPage(this.dragData.dragY);
// relocate the canvas to 0x0 in the window
this.dragData.dragX = 0;
@ -774,16 +1029,6 @@
// update canvas position and draw the canvas at the new location
this._browserToCanvas();
this._updateCanvasPosition();
this.dragData.dragging = false;
// Do we need to fire a content overpan event
if (this._fireOverpan > 0) {
var event = document.createEvent("UIEvents");
event.initUIEvent("overpan", true, false, window, this._fireOverpan);
this.dispatchEvent(event);
}
this._fireOverpan = 0;
]]></body>
</method>
@ -793,7 +1038,7 @@
deckbrowser: this,
handleEvent: function seh_handleEvent(aEvent) {
if (!aEvent.type in this) {
if (!(aEvent.type in this)) {
Components.reportError("MouseController called with unknown event type " + aEvent.type + "\n");
return;
}
@ -804,12 +1049,22 @@
if (aEvent.button != 0)
return;
// cancel any pending canvas updates, since we're going to update again
if (this._updateTimeout)
clearTimeout(this._updateTimeout);
// stop kinetic scrolling if it's in progress
// avoid setting _lastMouseDown in that case so that we don't
// redispatch it in mouseup
let dragData = this.deckbrowser.dragData;
if (dragData.kineticId) {
this.deckbrowser._endKinetic();
} else {
// Keep a reference to the event so that we can redispatch it
// on mouseup
this._lastMouseDown = aEvent;
}
var zoomLevel = this.deckbrowser._zoomLevel;
var dragData = this.deckbrowser.dragData;
// kinetic gets canceled above, so we should be guaranteed to not be
// in the panning state
if (dragData.dragging)
throw "Mousedown while panning - how'd this happen?";
// The start of the current portion drag
dragData.sX = aEvent.screenX;
@ -819,25 +1074,34 @@
dragData.dragX = 0;
dragData.dragY = 0;
//this.deckbrowser._updateCanvasPosition();
var self = this.deckbrowser;
this.deckbrowser._dragStartTimeout = setTimeout(function () {
self._dragStartTimer();
}, 200);
this._lastMouseDown = aEvent;
this.deckbrowser._dragStartTimeout = setTimeout(function (db) {
db._dragStartTimer();
}, 200, this.deckbrowser);
},
mouseup: function seh_mouseup(aEvent) {
if (aEvent.button == 0 && this.deckbrowser.dragData.dragging) {
this.deckbrowser._endPan();
} else if (aEvent.originalTarget == this.deckbrowser._canvas) {
// Mouseup on canvas that isn't releasing from a drag
// cancel scrollStart timer
clearTimeout(this.deckbrowser._dragStartTimeout);
this.deckbrowser._dragStartTimeout = -1;
if (aEvent.button != 0)
return;
// cancel scrollStart timer if it's pending
clearTimeout(this.deckbrowser._dragStartTimeout);
this.deckbrowser._dragStartTimeout = -1;
// If we're panning, stop dragging and start kinetic scrolling
if (this.deckbrowser.dragData.dragging) {
this.deckbrowser.dragData.dragging = false;
if (this.deckbrowser._allowKinetic)
this.deckbrowser._startKinetic();
else
this.deckbrowser._endPan();
return;
}
// Otherwise, dispatch the click event (if this mouseup was on the canvas)
if (this._lastMouseDown &&
aEvent.originalTarget == this.deckbrowser._canvas) {
// send mousedown & mouseup
this.deckbrowser._redispatchMouseEvent(this._lastMouseDown);
this._lastMouseDown = null;
@ -850,6 +1114,7 @@
Math.abs(aEvent.clientX - this._lastMouseUp.clientX) < 30 &&
Math.abs(aEvent.clientY - this._lastMouseUp.clientY) < 30) {
this.dblclick(aEvent);
return;
}
@ -883,16 +1148,18 @@
else if (Math.abs(dy/dx) < 0.3) // probably a horizontal drag
dy = 0;
}
let now = Date.now();
this.deckbrowser._panEventTrackerIndex = (this.deckbrowser._panEventTrackerIndex + 1) % this.deckbrowser.PAN_EVENTS_TO_TRACK;
var pt = {
x: aEvent.screenX,
y: aEvent.screenY,
t: now
};
this.deckbrowser._panEventTracker[this.deckbrowser._panEventTrackerIndex] = pt;
this.deckbrowser._moveCanvas(dx, dy);
if (Date.now() - this.deckbrowser.dragData.lastMouseEvent < 75) { // FIXME: make this a constant
//dump("dropping event\n");
return false;
}
this.deckbrowser.dragData.lastMouseEvent = Date.now();
aEvent.preventDefault();
return true;
},
@ -914,8 +1181,20 @@
this.deckbrowser._zoomed = false;
} else {
var element = this.deckbrowser.elementFromPoint(aEvent.clientX, aEvent.clientY);
if (!element)
return; //XXX when does this happen?
if (!element) {
Components.utils.reportError("elementFromPoint returned null\n");
return;
}
// Find the nearest non-inline ancestor
while (element.parentNode) {
var display = window.getComputedStyle(element, "").getPropertyValue("display");
var zoomable = /table/.test(display) || /block/.test(display);
if (zoomable)
break;
element = element.parentNode;
}
// Remember pageX/pageY
[dragData.oldPageX, dragData.oldPageY] = [dragData.pageX, dragData.pageY];
@ -953,11 +1232,12 @@
let height = domWin.innerHeight;
let ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, 80, 60);
ctx.restore(); // XXXndeakin remove this
ctx.save();
ctx.scale(80 / width, 60 / height);
ctx.drawWindow(domWin, 0, 0, width, height, "rgba(0,0,0,0)");
ctx.drawWindow(domWin, 0, 0, width, height, "white");
ctx.restore();
]]>
</body>

Просмотреть файл

@ -0,0 +1,44 @@
<?xml version="1.0"?>
<!DOCTYPE bindings PUBLIC "-//MOZILLA//DTD XBL V1.0//EN" "http://www.mozilla.org/xbl">
<bindings
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="notification" extends="chrome://global/content/bindings/notification.xml#notification">
<resources>
<stylesheet src="chrome://browser/skin/notification.css"/>
</resources>
<content>
<xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type">
<xul:vbox flex="1">
<xul:hbox anonid="details" align="center" flex="1">
<xul:image anonid="messageImage" class="messageImage" xbl:inherits="src=image"/>
<xul:description anonid="messageText" class="messageText" flex="1" xbl:inherits="xbl:text=label"/>
<xul:spacer flex="1"/>
</xul:hbox>
<xul:hbox pack="center"
oncommand="document.getBindingParent(this)._doButtonCommand(event);">
<children/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="notification-button"
extends="chrome://global/content/bindings/button.xml#button-base">
<resources>
<stylesheet src="chrome://browser/skin/notification.css"/>
</resources>
<content orient="vertical">
<xul:image class="sn-button-icon" xbl:inherits="src=image"/>
<xul:label class="sn-button-text" xbl:inherits="value=label,accesskey,crop"/>
<xul:label class="sn-button-extra-text" xbl:inherits="value=sublabel"/>
</content>
</binding>
</bindings>

Просмотреть файл

@ -0,0 +1,175 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Mozilla Mobile Browser.
-
- The Initial Developer of the Original Code is
- Mozilla Corporation.
- Portions created by the Initial Developer are Copyright (C) 2008
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Daniel Brooks <db48x@yahoo.com>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE bindings PUBLIC "-//MOZILLA//DTD XBL V1.0//EN" "http://www.mozilla.org/xbl">
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="richpref-base">
<implementation>
<constructor>
this.pref._setValue(this.pref.valueFromPreferences, false);
this.prefChanged();
</constructor>
<method name="fireEvent">
<parameter name="eventName"/>
<parameter name="funcStr"/>
<body>
<![CDATA[
var body = funcStr || this.getAttribute(eventName);
if (!body)
return;
try
{
var event = document.createEvent("Events");
event.initEvent(eventName, true, true);
var f = new Function("event", body);
f.call(this, event);
}
catch (e)
{
Components.utils.reportError(e);
}
]]>
</body>
</method>
<method name="inputChanged">
<body>
this.pref.value = this.value;
this.fireEvent("onsynctopreference");
</body>
</method>
<method name="prefChanged">
<body>
this.value = this.pref.value;
this.fireEvent("onsyncfrompreference");
</body>
</method>
<property name="value" onget="return this.input.value;" onset="return this.input.value = val;"/>
<field name="type">this.getAttribute("type");</field>
<field name="pref">document.getAnonymousElementByAttribute(this, "anonid", "pref");</field>
<field name="input">document.getAnonymousElementByAttribute(this, "anonid", "input");</field>
</implementation>
</binding>
<binding id="richpref-bool" extends="chrome://browser/content/preferences/richpref.xml#richpref-base">
<content>
<xul:hbox flex="1" class="prefbox">
<xul:vbox flex="1">
<xul:label class="preftitle" xbl:inherits="value=title" crop="end" flex="1"/>
<xul:label class="prefdesc" xbl:inherits="value=desc" crop="end" flex="1">
<children/>
</xul:label>
</xul:vbox>
<xul:hbox anonid="input-container">
<xul:checkbox anonid="input" oncommand="inputChanged();"/>
</xul:hbox>
</xul:hbox>
<xul:preferences>
<xul:preference anonid="pref" xbl:inherits="name=pref,type,inverted" instantApply="true" onchange="prefChanged();"/>
</xul:preferences>
</content>
<implementation>
<property name="value" onget="return this.input.checked;" onset="return this.input.setChecked(val);"/>
</implementation>
</binding>
<binding id="richpref-boolint" extends="chrome://browser/content/preferences/richpref.xml#richpref-base">
<content>
<xul:hbox flex="1" class="prefbox">
<xul:vbox flex="1">
<xul:label class="preftitle" xbl:inherits="value=title" crop="end" flex="1"/>
<xul:label class="prefdesc" xbl:inherits="value=desc" crop="end" flex="1">
<children/>
</xul:label>
</xul:vbox>
<xul:hbox anonid="input-container">
<xul:checkbox anonid="input" oncommand="inputChanged();"/>
</xul:hbox>
</xul:hbox>
<xul:preferences>
<xul:preference anonid="pref" xbl:inherits="name=pref,inverted" type="int" instantApply="true" onchange="prefChanged();"/>
</xul:preferences>
</content>
<implementation>
<method name="inputChanged">
<body>
this.pref.value = this.getAttribute(this.value ? "on" : "off");
this.fireEvent("onsynctopreference");
</body>
</method>
<method name="prefChanged">
<body>
this.value = this.pref.value == this.getAttribute("on");
this.fireEvent("onsyncfrompreference");
</body>
</method>
<property name="value" onget="return this.input.checked;" onset="return this.input.setChecked(val);"/>
</implementation>
</binding>
<binding id="richpref-button" extends="chrome://browser/content/preferences/richpref.xml#richpref-base">
<content>
<xul:hbox flex="1" class="prefbox">
<xul:vbox flex="1">
<xul:label class="preftitle" xbl:inherits="value=title" crop="end" flex="1"/>
<xul:label class="prefdesc" xbl:inherits="value=desc" crop="end" flex="1">
<children/>
</xul:label>
</xul:vbox>
<xul:hbox anonid="input-container">
<children includes="button"/>
</xul:hbox>
</xul:hbox>
<xul:preferences>
<xul:preference anonid="pref" xbl:inherits="name=pref,type,inverted" instantApply="true" onchange="prefChanged();"/>
</xul:preferences>
</content>
</binding>
</bindings>

Просмотреть файл

@ -0,0 +1,336 @@
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Firefox Sanitizer.
#
# The Initial Developer of the Original Code is
# Ben Goodger.
# Portions created by the Initial Developer are Copyright (C) 2005
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ben Goodger <ben@mozilla.org>
# Giorgio Maone <g.maone@informaction.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
function Sanitizer() {}
Sanitizer.prototype = {
// warning to the caller: this one may raise an exception (e.g. bug #265028)
clearItem: function (aItemName)
{
if (this.items[aItemName].canClear)
this.items[aItemName].clear();
},
canClearItem: function (aItemName)
{
return this.items[aItemName].canClear;
},
_prefDomain: "privacy.item.",
getNameFromPreference: function (aPreferenceName)
{
return aPreferenceName.substr(this._prefDomain.length);
},
/**
* Deletes privacy sensitive data in a batch, according to user preferences
*
* @returns null if everything's fine; an object in the form
* { itemName: error, ... } on (partial) failure
*/
sanitize: function ()
{
var psvc = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
var branch = psvc.getBranch(this._prefDomain);
var errors = null;
for (var itemName in this.items) {
var item = this.items[itemName];
if ("clear" in item && item.canClear && branch.getBoolPref(itemName)) {
// Some of these clear() may raise exceptions (see bug #265028)
// to sanitize as much as possible, we catch and store them,
// rather than fail fast.
// Callers should check returned errors and give user feedback
// about items that could not be sanitized
try {
item.clear();
} catch(er) {
if (!errors)
errors = {};
errors[itemName] = er;
dump("Error sanitizing " + itemName + ": " + er + "\n");
}
}
}
return errors;
},
items: {
cache: {
clear: function ()
{
const cc = Components.classes;
const ci = Components.interfaces;
var cacheService = cc["@mozilla.org/network/cache-service;1"]
.getService(ci.nsICacheService);
try {
cacheService.evictEntries(ci.nsICache.STORE_ANYWHERE);
} catch(er) {}
},
get canClear()
{
return true;
}
},
cookies: {
clear: function ()
{
var cookieMgr = Components.classes["@mozilla.org/cookiemanager;1"]
.getService(Components.interfaces.nsICookieManager);
cookieMgr.removeAll();
},
get canClear()
{
return true;
}
},
offlineApps: {
clear: function ()
{
const Cc = Components.classes;
const Ci = Components.interfaces;
var cacheService = Cc["@mozilla.org/network/cache-service;1"].
getService(Ci.nsICacheService);
try {
cacheService.evictEntries(Ci.nsICache.STORE_OFFLINE);
} catch(er) {}
var storageManagerService = Cc["@mozilla.org/dom/storagemanager;1"].
getService(Ci.nsIDOMStorageManager);
storageManagerService.clearOfflineApps();
},
get canClear()
{
return true;
}
},
history: {
clear: function ()
{
var globalHistory = Components.classes["@mozilla.org/browser/global-history;2"]
.getService(Components.interfaces.nsIBrowserHistory);
globalHistory.removeAllPages();
try {
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.notifyObservers(null, "browser:purge-session-history", "");
}
catch (e) { }
// Clear last URL of the Open Web Location dialog
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch2);
try {
prefs.clearUserPref("general.open_location.last_url");
}
catch (e) { }
},
get canClear()
{
// bug 347231: Always allow clearing history due to dependencies on
// the browser:purge-session-history notification. (like error console)
return true;
}
},
formdata: {
clear: function ()
{
//Clear undo history of all searchBars
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
var windows = windowManagerInterface.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
var searchBar = windows.getNext().document.getElementById("searchbar");
if (searchBar) {
searchBar.value = "";
searchBar.textbox.editor.transactionManager.clear();
}
}
var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"]
.getService(Components.interfaces.nsIFormHistory2);
formHistory.removeAllEntries();
},
get canClear()
{
var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"]
.getService(Components.interfaces.nsIFormHistory2);
return formHistory.hasEntries;
}
},
downloads: {
clear: function ()
{
var dlMgr = Components.classes["@mozilla.org/download-manager;1"]
.getService(Components.interfaces.nsIDownloadManager);
dlMgr.cleanUp();
},
get canClear()
{
var dlMgr = Components.classes["@mozilla.org/download-manager;1"]
.getService(Components.interfaces.nsIDownloadManager);
return dlMgr.canCleanUp;
}
},
passwords: {
clear: function ()
{
var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
.getService(Components.interfaces.nsILoginManager);
pwmgr.removeAllLogins();
},
get canClear()
{
var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
.getService(Components.interfaces.nsILoginManager);
var count = pwmgr.countLogins("", "", ""); // count all logins
return (count > 0);
}
},
sessions: {
clear: function ()
{
// clear all auth tokens
var sdr = Components.classes["@mozilla.org/security/sdr;1"]
.getService(Components.interfaces.nsISecretDecoderRing);
sdr.logoutAndTeardown();
// clear plain HTTP auth sessions
var authMgr = Components.classes['@mozilla.org/network/http-auth-manager;1']
.getService(Components.interfaces.nsIHttpAuthManager);
authMgr.clearAll();
},
get canClear()
{
return true;
}
}
}
};
// "Static" members
Sanitizer.prefDomain = "privacy.sanitize.";
Sanitizer.prefPrompt = "promptOnSanitize";
Sanitizer.prefShutdown = "sanitizeOnShutdown";
Sanitizer.prefDidShutdown = "didShutdownSanitize";
Sanitizer._prefs = null;
Sanitizer.__defineGetter__("prefs", function()
{
return Sanitizer._prefs ? Sanitizer._prefs
: Sanitizer._prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService)
.getBranch(Sanitizer.prefDomain);
});
// Shows sanitization UI
Sanitizer.showUI = function(aParentWindow)
{
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
#ifdef XP_MACOSX
ww.openWindow(null, // make this an app-modal window on Mac
#else
ww.openWindow(aParentWindow,
#endif
"chrome://browser/content/sanitize.xul",
"Sanitize",
"chrome,titlebar,centerscreen,modal",
null);
};
/**
* Deletes privacy sensitive data in a batch, optionally showing the
* sanitize UI, according to user preferences
*
* @returns null if everything's fine (no error or displayed UI, which
* should handle errors);
* an object in the form { itemName: error, ... } on (partial) failure
*/
Sanitizer.sanitize = function(aParentWindow)
{
if (Sanitizer.prefs.getBoolPref(Sanitizer.prefPrompt)) {
Sanitizer.showUI(aParentWindow);
return null;
}
return new Sanitizer().sanitize();
};
Sanitizer.onStartup = function()
{
// we check for unclean exit with pending sanitization
Sanitizer._checkAndSanitize();
};
Sanitizer.onShutdown = function()
{
// we check if sanitization is needed and perform it
Sanitizer._checkAndSanitize();
};
// this is called on startup and shutdown, to perform pending sanitizations
Sanitizer._checkAndSanitize = function()
{
const prefs = Sanitizer.prefs;
if (prefs.getBoolPref(Sanitizer.prefShutdown) &&
!prefs.prefHasUserValue(Sanitizer.prefDidShutdown)) {
// this is a shutdown or a startup after an unclean exit
Sanitizer.sanitize(null) || // sanitize() returns null on full success
prefs.setBoolPref(Sanitizer.prefDidShutdown, true);
}
};

Просмотреть файл

@ -0,0 +1,201 @@
<?xml version="1.0"?>
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Firefox Sanitizer.
#
# The Initial Developer of the Original Code is
# Ben Goodger.
# Portions created by the Initial Developer are Copyright (C) 2005
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ben Goodger <ben@mozilla.org>
# Giorgio Maone <g.maone@informaction.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
<?xml-stylesheet href="chrome://global/skin/"?>
<!DOCTYPE prefwindow [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
%brandDTD;
%sanitizeDTD;
]>
<prefwindow id="SanitizeDialog" type="child"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
dlgbuttons="accept,cancel"
title="&sanitizeDialog.title;"
style="width: &window.width;;"
ondialogaccept="gSanitizePromptDialog.sanitize();">
<prefpane id="SanitizeDialogPane" onpaneload="gSanitizePromptDialog.init();">
<stringbundle id="bundleBrowser" src="chrome://browser/locale/browser.properties"/>
<script type="application/x-javascript" src="chrome://browser/content/sanitize.js"/>
<script type="application/x-javascript">
<![CDATA[
var gSanitizePromptDialog = {
init: function ()
{
var s = new Sanitizer();
var sanitizePreferences = document.getElementById("sanitizePreferences");
for (var i = 0; i < sanitizePreferences.childNodes.length; ++i) {
var preference = sanitizePreferences.childNodes[i];
var name = s.getNameFromPreference(preference.name);
if (!s.canClearItem(name))
preference.disabled = true;
}
var bundleBrowser = document.getElementById("bundleBrowser");
document.documentElement.getButton("accept").label = bundleBrowser.getString("sanitizeButton");
},
sanitize: function ()
{
var s = new Sanitizer();
var sanitizePreferences = document.getElementById("sanitizePreferences");
var preference, name;
for (var i = 0; i < sanitizePreferences.childNodes.length; ++i) {
preference = sanitizePreferences.childNodes[i];
if (preference.value) {
name = s.getNameFromPreference(preference.name);
try {
s.clearItem(name);
} catch(er) {
dump(er + " sanitizing " + name);
// TODO: give user feedback about partially failed sanitization
}
}
}
},
onReadGeneric: function ()
{
var preferences = document.getElementById("sanitizePreferences");
var found = false;
for (var i = 0; i < preferences.childNodes.length; ++i) {
var preference = preferences.childNodes[i];
if (preference.value && !preference.disabled) {
found = true;
break;
}
}
try {
document.documentElement.getButton("accept").disabled = !found;
}
catch (e) { }
return undefined;
},
onReadDownloads: function (aEvent)
{
// Call the common function that will update the accept button if needed
this.onReadGeneric();
let historyPref = document.getElementById("privacy.item.history")
let downloadPref = document.getElementById("privacy.item.downloads");
// Disable the checkbox if history is selected
let downloads = document.getElementById("downloads-checkbox");
downloads.disabled = historyPref.value;
// The "Download History" checkbox is selected if either of the history or
// downloads preferences are true.
return historyPref.value || downloadPref.value;
},
updateDownloadHistory: function ()
{
// When toggling history, we automatically clear download history too,
// so we disable that control and set its value to true.
let downloads = document.getElementById("downloads-checkbox");
let history = document.getElementById("history-checkbox");
let s = new Sanitizer();
downloads.disabled = history.checked ||
!s.canClearItem("downloads");
if (history.checked)
downloads.checked = true;
},
};
]]>
</script>
<preferences id="sanitizePreferences">
<preference id="privacy.item.history" name="privacy.item.history" type="bool" readonly="true"/>
<preference id="privacy.item.formdata" name="privacy.item.formdata" type="bool" readonly="true"/>
<preference id="privacy.item.passwords" name="privacy.item.passwords" type="bool" readonly="true"/>
<preference id="privacy.item.downloads" name="privacy.item.downloads" type="bool" readonly="true"/>
<preference id="privacy.item.cookies" name="privacy.item.cookies" type="bool" readonly="true"/>
<preference id="privacy.item.cache" name="privacy.item.cache" type="bool" readonly="true"/>
<preference id="privacy.item.offlineApps" name="privacy.item.offlineApps" type="bool"/>
<preference id="privacy.item.sessions" name="privacy.item.sessions" type="bool" readonly="true"/>
</preferences>
<description>&sanitizeItems.label;</description>
<checkbox id="history-checkbox"
label="&itemHistory.label;"
accesskey="&itemHistory.accesskey;"
preference="privacy.item.history"
oncommand="gSanitizePromptDialog.updateDownloadHistory();"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox id="downloads-checkbox"
class="indent"
label="&itemDownloads.label;"
accesskey="&itemDownloads.accesskey;"
preference="privacy.item.downloads"
onsyncfrompreference="return gSanitizePromptDialog.onReadDownloads();"/>
<checkbox label="&itemFormSearchHistory.label;"
accesskey="&itemFormSearchHistory.accesskey;"
preference="privacy.item.formdata"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemCache.label;"
accesskey="&itemCache.accesskey;"
preference="privacy.item.cache"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemCookies.label;"
accesskey="&itemCookies.accesskey;"
preference="privacy.item.cookies"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemOfflineApps.label;"
accesskey="&itemOfflineApps.accesskey;"
preference="privacy.item.offlineApps"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemPasswords.label;"
accesskey="&itemPasswords.accesskey;"
preference="privacy.item.passwords"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemSessions.label;"
accesskey="&itemSessions.accesskey;"
preference="privacy.item.sessions"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
</prefpane>
</prefwindow>

Просмотреть файл

@ -417,6 +417,8 @@ function ShortcutEditor()
textbox.addEventListener("keypress", keyListener, true);
textbox.addEventListener("reset", resetListener, true);
tree.addEventListener("DOMAttrModified", modificationListener, true);
fillShortcutList();
};
function hack()
@ -431,6 +433,9 @@ function ShortcutEditor()
this.dismiss = function()
{
if (!tree)
return;
hack();
var textbox = document.getAnonymousElementByAttribute(tree, "anonid", "input");
textbox.removeEventListener("keypress", keyListener, true);
@ -473,7 +478,7 @@ function ShortcutEditor()
{
return sb[i].getString(name);
}
catch (e) { }
catch (e) { return null; }
}
}
@ -553,7 +558,7 @@ function ShortcutEditor()
[["meta shift alt control", undefined, "VK_A"], {exists: true, modifiers: 15, key: false, keycode: "VK_A"}, "Ctrl+Alt+Meta+Shift+A"],
[[], {exists: false, modifiers: 0, key: false, keycode: false}, ""],
[["control"], {exists: false, modifiers: 2, key: false, keycode: false}, ""],
[["foobar", "a"], {exists: true, modifiers: 2, key: "a", keycode: false}, "A"],
[["foobar", "a"], {exists: true, modifiers: 0, key: "a", keycode: false}, "A"],
[["alt", "α"], {exists: true, modifiers: 1, key: "α", keycode: false}, "Alt+Α"],
[["alt", "א"], {exists: true, modifiers: 1, key: "א", keycode: false}, "Alt+א"]
].forEach(function doTests(t)

Просмотреть файл

@ -8,18 +8,25 @@ browser.jar:
content/commandUtil.js (content/commandUtil.js)
content/urlbar.xml (content/urlbar.xml)
content/deckbrowser.xml (content/deckbrowser.xml)
content/notification.xml (content/notification.xml)
content/browser.css (content/browser.css)
content/scrollbars.css (content/scrollbars.css)
content/content.css (content/content.css)
* content/shortcuts.js
* content/shortcuts.js (content/shortcuts.js)
% content branding %branding/
% locale branding @AB_CD@ %branding/
branding/brand.dtd (locale/@AB_CD@/brand/brand.dtd)
branding/brand.properties (locale/@AB_CD@/brand/brand.properties)
% style chrome://mozapps/content/extensions/extensions.xul chrome://browser/skin/extensions.css
content/preferences/richpref.xml (content/preferences/richpref.xml)
* content/sanitize.xul (content/sanitize.xul)
* content/sanitize.js (content/sanitize.js)
classic.jar:
% skin browser classic/1.0 %
browser.css (skin/browser.css)
extensions.css (skin/extensions.css)
notification.css (skin/notification.css)
images/close.png (skin/images/close.png)
images/close-small.png (skin/images/close-small.png)
images/default-favicon.png (skin/images/default-favicon.png)
@ -32,6 +39,20 @@ classic.jar:
images/toolbar.png (skin/images/toolbar.png)
images/mono-toolbar.png (skin/images/mono-toolbar.png)
images/toolbar-background.png (skin/images/toolbar-background.png)
images/addressbar_endcap_r_off.png (skin/images/addressbar_endcap_r_off.png)
images/addressbar_endcap_l_off.png (skin/images/addressbar_endcap_l_off.png)
images/addressbar_endcap_r_on.png (skin/images/addressbar_endcap_r_on.png)
images/addressbar_endcap_l_on.png (skin/images/addressbar_endcap_l_on.png)
images/addressbar_middle.png (skin/images/addressbar_middle.png)
images/titlebar.png (skin/images/titlebar.png)
images/left_sidebar_top.png (skin/images/left_sidebar_top.png)
images/left_sidebar_middle.png (skin/images/left_sidebar_middle.png)
images/left_sidebar_bottom.png (skin/images/left_sidebar_bottom.png)
images/left_buttons.png (skin/images/left_buttons.png)
images/right_sidebar_top.png (skin/images/right_sidebar_top.png)
images/right_sidebar_middle.png (skin/images/right_sidebar_middle.png)
images/right_sidebar_bottom.png (skin/images/right_sidebar_bottom.png)
images/right_buttons.png (skin/images/right_buttons.png)
@AB_CD@.jar:
% locale browser @AB_CD@ %
@ -40,3 +61,7 @@ classic.jar:
shortcuts.properties (locale/@AB_CD@/shortcuts.properties)
search.properties (locale/@AB_CD@/search.properties)
region.properties (locale/@AB_CD@/region.properties)
preferences.dtd (locale/@AB_CD@/preferences.dtd)
# Fennec-specific overrides of generic strings
* netError.dtd (locale/@AB_CD@/overrides/netError.dtd)
% override chrome://global/locale/netErrorApp.dtd chrome://browser/locale/netError.dtd

Просмотреть файл

@ -6,6 +6,14 @@ popupButtonAlwaysAllow.accesskey=A
popupButtonNeverWarn=Never tell me
popupButtonNeverWarn.accesskey=N
# XPInstall
xpinstallPromptWarning=%S prevented this site (%S) from asking you to install software on your computer.
xpinstallPromptAllowButton=Allow
xpinstallPromptAllowButton.accesskey=A
xpinstallDisabledMessageLocked=Software installation has been disabled by your system administrator.
xpinstallDisabledMessage=Software installation is currently disabled. Click Enable and try again.
xpinstallDisabledButton=Enable
xpinstallDisabledButton.accesskey=n
# Site Identity
identity.identified.verifier=Verified by: %S
@ -18,9 +26,11 @@ identity.unknown.tooltip=This web site does not supply identity information.
identity.ownerUnknown2=(unknown)
# Geolocation UI
gelocation.exactLocation=Exact Location (within 10 feet)
gelocation.exactLocation=Exact Location
gelocation.exactLocation.subLabel=within 10 feet
gelocation.exactLocationKey=E
gelocation.neighborhoodLocation=Neighborhood (within 1 mile)
gelocation.neighborhoodLocation=Neighborhood
gelocation.neighborhoodLocation.subLabel=within 1 mile
gelocation.neighborhoodLocationKey=N
gelocation.nothingLocation=Nothing
gelocation.nothingLocationKey=C

Просмотреть файл

@ -0,0 +1,180 @@
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!ENTITY loadError.label "Problem loading page">
<!ENTITY retry.label "Try Again">
<!-- Specific error messages -->
<!ENTITY connectionFailure.title "Unable to connect">
<!ENTITY connectionFailure.longDesc "&sharedLongDesc;">
<!ENTITY deniedPortAccess.title "This address is restricted">
<!ENTITY deniedPortAccess.longDesc "">
<!ENTITY dnsNotFound.title "Server not found">
<!ENTITY dnsNotFound.longDesc "
<ul>
<li>Check the address for typing errors such as
<strong>ww</strong>.example.com instead of
<strong>www</strong>.example.com</li>
<li>If you are unable to load any pages, check your computer's network
connection.</li>
<li>If your computer or network is protected by a firewall or proxy, make sure
that &brandShortName; is permitted to access the Web.</li>
</ul>
">
<!ENTITY fileNotFound.title "File not found">
<!ENTITY fileNotFound.longDesc "
<ul>
<li>Check the file name for capitalization or other typing errors.</li>
<li>Check to see if the file was moved, renamed or deleted.</li>
</ul>
">
<!ENTITY generic.title "Oops.">
<!ENTITY generic.longDesc "
<p>&brandShortName; can't load this page for some reason.</p>
">
<!ENTITY malformedURI.title "The address isn't valid">
<!ENTITY malformedURI.longDesc "
<ul>
<li>Web addresses are usually written like
<strong>http://www.example.com/</strong></li>
<li>Make sure that you're using forward slashes (i.e.
<strong>/</strong>).</li>
</ul>
">
<!ENTITY netInterrupt.title "The connection was interrupted">
<!ENTITY netInterrupt.longDesc "&sharedLongDesc;">
<!ENTITY netOffline.title "Offline mode">
<!ENTITY netOffline.longDesc "
<ul>
<li>Uncheck &quot;Work Offline&quot; in the File menu, then try again.</li>
</ul>
">
<!ENTITY contentEncodingError.title "Content Encoding Error">
<!ENTITY contentEncodingError.longDesc "
<ul>
<li>Please contact the website owners to inform them of this problem.</li>
</ul>
">
<!ENTITY unsafeContentType.title "Unsafe File Type">
<!ENTITY unsafeContentType.longDesc "
<ul>
<li>Please contact the website owners to inform them of this problem.</li>
</ul>
">
<!ENTITY netReset.title "The connection was reset">
<!ENTITY netReset.longDesc "&sharedLongDesc;">
<!ENTITY netTimeout.title "The connection has timed out">
<!ENTITY netTimeout.longDesc "&sharedLongDesc;">
<!ENTITY protocolNotFound.title "The address wasn't understood">
<!ENTITY protocolNotFound.longDesc "
<ul>
<li>You might need to install other software to open this address.</li>
</ul>
">
<!ENTITY proxyConnectFailure.title "The proxy server is refusing connections">
<!ENTITY proxyConnectFailure.longDesc "
<ul>
<li>Check the proxy settings to make sure that they are correct.</li>
<li>Contact your network administrator to make sure the proxy server is
working.</li>
</ul>
">
<!ENTITY proxyResolveFailure.title "Unable to find the proxy server">
<!ENTITY proxyResolveFailure.longDesc "
<ul>
<li>Check the proxy settings to make sure that they are correct.</li>
<li>Check to make sure your computer has a working network connection.</li>
<li>If your computer or network is protected by a firewall or proxy, make sure
that &brandShortName; is permitted to access the Web.</li>
</ul>
">
<!ENTITY redirectLoop.title "The page isn't redirecting properly">
<!ENTITY redirectLoop.longDesc "
<ul>
<li>This problem can sometimes be caused by disabling or refusing to accept
cookies.</li>
</ul>
">
<!ENTITY unknownSocketType.title "Unexpected response from server">
<!ENTITY unknownSocketType.longDesc "
<ul>
<li>Check to make sure your system has the Personal Security Manager
installed.</li>
<li>This might be due to a non-standard configuration on the server.</li>
</ul>
">
<!ENTITY nssFailure2.title "Secure Connection Failed">
<!ENTITY nssFailure2.longDesc "
<ul>
<li>The page you are trying to view can not be shown because the authenticity of the received data could not be verified.</li>
<li>Please contact the web site owners to inform them of this problem. Alternatively, use the command found in the help menu to report this broken site.</li>
</ul>
">
<!ENTITY nssBadCert.title "Secure Connection Failed">
<!ENTITY nssBadCert.longDesc2 "
<ul>
<li>This could be a problem with the server's configuration, or it could be
someone trying to impersonate the server.</li>
<li>If you have connected to this server successfully in the past, the error may
be temporary, and you can try again later.</li>
</ul>
">
<!ENTITY sharedLongDesc "
<ul>
<li>The site could be temporarily unavailable or too busy. Try again in a few
moments.</li>
<li>If you are unable to load any pages, check your computer's network
connection.</li>
<li>If your computer or network is protected by a firewall or proxy, make sure
that &brandShortName; is permitted to access the Web.</li>
</ul>
">
<!ENTITY malwareBlocked.title "Suspected Attack Site!">
<!ENTITY malwareBlocked.longDesc "
<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p>
<p>Web site owners who believe their site has been reported as an attack site in error may <a href='http://www.stopbadware.org/home/reviewinfo' >request a review</a>.</p>
">
<!ENTITY phishingBlocked.title "Suspected Web Forgery!">
<!ENTITY phishingBlocked.longDesc "
<p>Entering any personal information on this page may result in identity theft or other fraud.</p>
<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
">
<!ENTITY securityOverride.linkText "Or you can add an exception…">
<!ENTITY securityOverride.getMeOutOfHereButton "Get me out of here!">
<!ENTITY securityOverride.exceptionButtonLabel "Add Exception…">
<!-- LOCALIZATION NOTE (securityOverride.warningText) - Do not translate the
contents of the <xul:button> tags. The only language content is the label= field,
which uses strings already defined above. The button is included here (instead of
netError.xhtml) because it exposes functionality specific to firefox. -->
<!ENTITY securityOverride.warningText "
<p>You should not add an exception if you are using an internet connection that you do not trust completely or if you are not used to seeing a warning for this server.</p>
<xul:button xmlns:xul='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' id='getMeOutOfHereButton' label='&securityOverride.getMeOutOfHereButton;'/>
<xul:button xmlns:xul='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' id='exceptionDialogButton' label='&securityOverride.exceptionButtonLabel;'/>
">

Просмотреть файл

@ -0,0 +1,15 @@
<!ENTITY content.title "Content">
<!ENTITY permissions.default.image.title "Load images">
<!ENTITY permissions.default.image.description "Makes websites pretty">
<!ENTITY javascript.enabled.title "Enable Javascript">
<!ENTITY javascript.enabled.description "Makes websites flashy">
<!ENTITY plugins.enabled.title "Enable Plugins">
<!ENTITY plugins.enabled.description "Makes websites annoying">
<!ENTITY privacy.title "Privacy &amp; Security">
<!ENTITY network.cookie.cookieBehavior.title "Save cookies">
<!ENTITY network.cookie.cookieBehavior.description "Delicious delicacies">
<!ENTITY clear.private.data.title "Clear private data">
<!ENTITY clear.private.data.button "Clear…">
<!ENTITY clear.private.data.description "Saves your hide">
<!ENTITY signon.rememberSignons.title "Save passwords">
<!ENTITY signon.rememberSignons.description "Lets you type less">

Просмотреть файл

@ -0,0 +1,13 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Amazon.com</ShortName>
<Description>Amazon.com Search</Description>
<InputEncoding>ISO-8859-1</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHgSURBVHjalFM9TNtQEP4cB7PwM1RITUXIgsRaYEEVEyKZwhiyZAQyd0BhpFOlIjoBqhjSqVQMoVMLLAjEwECCQJkSkBqJYDOAFOMKFSf28d7DTUxiUDnp/Pzeu/vuu7t3ICKF6SLTMv2/lB0fRWKfjwDm4JJisYh0Oo3fpZLYT0SjSCQS8JAFMADNDZ3NZsnf1taiqVTKi4nGASruk5lkkmTmMB6JUKFQqO+DfX1eABWeQoVR6f7HSdM0obqu48Yw8G1tDT82NsRd1TSbU9BbGPCog8PDj+jLzurFoAVgMh4XxoNDQ6SqKi0tL9eBvAB8zZwymYxYY7EYAoEA8vm82BNTg6XUIs0MeGTZoR1mhXSnwNl4pmAbjU7mcjkKhkL1ynMnntZ4OEw3VyrV8utk7s5TdW++0QXz+1i3P7IK36t+PCfVn1OQOoOA0gXr5DPak+cPXbBK+/T3S69AtY3LJ98vZ1or/iLr+pTuvr59/A6s003UdqZFJF/PCKQ3o5CUznoBST2AfbEF/9iqYEDaIfwj73VJPEfgNTe0tWNYR0uwy9uOW0OkrgHI7z5ADo2C7v48nLV3XHKAT+x/1m1sX58xsBxg8rZJrDYD8DHHp4aJj/MK09sXjPOt46PcCzAACXY8/u34wN0AAAAASUVORK5CYII=</Image>
<Url type="text/html" method="GET" template="http://www.amazon.com/exec/obidos/external-search/">
<Param name="field-keywords" value="{searchTerms}"/>
<Param name="mode" value="blended"/>
<Param name="tag" value="mozilla-20"/>
<Param name="sourceid" value="Mozilla-search"/>
</Url>
<SearchForm>http://www.amazon.com/</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -0,0 +1,13 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Answers.com</ShortName>
<Description>Dictionary Search on Answers.com</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////K////4f////E////5f///+n////P////mv///0EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8E////fv///+//////////////////////7NnP/+LFtv/////+////of///xYAAAAAAAAAAAAAAAD///8D////lf////////////j0//bi1v/OlXf/tGU9/6FCEv/OmH3////////////////D////FgAAAAAAAAAA////avPm4P/evaz/8NbI//7r3//23M3/xYRi/5kzAP/Df1z//u/l//749P/v4dn/+PPw/////6j///8B////GP///+W/f1//smM7//bczf/+69///uvf/9ytlP+ZMwD/5se3/+/f1//AgmP/nj0N/927qv/////+////QP///2z/////8NvQ/8WCYP/+69///uvf//7r3/+7ckz/pUkb/9m1ov+ePQ3/okUW/8+fh//38O3//////////5r///+t//////7y6v/Cflv/58Cr//DRwP/mwKv/okQU/8ODYv/cuqj/yZN4//Tq5f/+9e///vDn///////////Q////yf/////+7+b/05yA/65ZLv+9dVD/sF40/5kzAP/kvKb//vTu//Tr5v/7+Pb//vfz//707f//////////6f///8X//////vDm/+K4ov/KjGz//ure/8uNbf+jRBX/+OTX/+3b0v+jSBr/pk0h/717Wv/Wrpr//Pn4/////+b///+i//////7z7f/02Mj/wn5b//vl2P+uWS7/vXhU//v49//48u//1q6a/717Wv+oUSb/tWxH//jz8P/////K////V///////+/j//ure/8aFZP/fs5v/oEAQ/9q1o/+zaEL/1ayX//718P/+9/P/+PHu//jz8P//////////h////wr////O///////38v/YpYr/tGQ7/6ZLHf/06eX/s2dB/549Df/x49z//vDn//7x6f//////////8////yoAAAAA////R/////v/////7dXI/5kzAP+7cUv//vHp/+vYzv+bNwX/vHlY//38/P///////////////30AAAAAAAAAAAAAAAD///9n////+/z5+P++e1n/3LGc//7w5//++PT/0KKL/8OIa//9/Pv//////////5X///8GAAAAAAAAAAAAAAAAAAAAAP///0n////K///////////////////////////+/v7/////5v///2z///8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Cv///1f///+g////xP///8n///+r////bP///xoAAAAAAAAAAAAAAAAAAAAA+B////AH///AA///wAH//4AB//+AAP//AAD//wAA//8AAP//AAD//4AA//+AAf//wAP//+AD///wD////D///w==</Image>
<Url type="text/html" method="GET" template="http://www.answers.com/main/ntquery">
<Param name="s" value="{searchTerms}"/>
<Param name="gwp" value="13"/>
</Url>
<Url type="application/x-suggestions+json" method="GET"
template="http://www.answers.com/main/startswith?output=json&amp;client=firefox&amp;s={searchTerms}"/>
<SearchForm>http://www.answers.com/</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -0,0 +1,11 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Creative Commons</ShortName>
<Description>Find photos, movies, music, and text to rip, sample, mash, and share.</Description>
<InputEncoding>utf-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJUSURBVDiNjZO9S1thGMXPvTfJFbnkipNkLLS0ksFg0M0lf4CboNCEgIIg/RiKtEOn0qGWTtbVoBYcIji10I9J0ApWCjp0kRaXdhHjTW4+uGnur4NJ8GOwZ3nf4TnnfZ5z3scAdBGGYdyVdN+yrGHTNNOtVqsVhuG+pO+S3gE/LtV3BIxzPDJNc8FxHGN0dNRKpVIGoJ2dndr+/r5Vr9cl6bmkN0AoSQIEyHXdj5KYnZ3F932uolKpkM/nK5KQ9FmSCZwLOI7zQBLr6+vXiFdRLBaDtsiTTve3YrFYkM/nbyR3MDU1dSKpLumO+vr6Xruui+d5AFSrVVZWVtjY2KDRaABwdHTE4uIie3t7AJTLZaLRaFXSCyUSid1MJgOA53n09/eTTqdJJpPMzc2xurqKbduMj48Tj8fZ3d0FYHBw8FjSezmOU56fnwdgeXkZ27ap1WpUKhWazSZjY2Nks1kASqVSd4zp6eljSX/MtiHdRDpnEATyfb+bkiSVSqXu3TCM8xgHBga+dkY4OzvDdV2GhoZIJBLMzMxQKBSIRqNkMhlisRhbW1sAJJPJn5I+KB6Pv7poou/7rK2tsbm5SRAEXROXlpY4ODgAoFarYdu2J+llN8ZcLvffMeZyud+SGpLuCVBPT89jSRQKhRvJxWKxISmU9JTOT5Rk9Pb2fpHE5OQkJycn14inp6dMTEx4bdM/SbKAy8sk6WEkElmwLCuSSqUYGRmxgHB7e7t+eHgYazabgaRnkt7SeZnr63xbUtYwjGHTNNNhGP4F9iR9a6/zr4v1/wDE1D9XlC4rrAAAAABJRU5ErkJggg==</Image>
<Url type="text/html" method="GET" template="http://search.creativecommons.org/">
<Param name="q" value="{searchTerms}"/>
<Param name="sourceid" value="Mozilla-search"/>
</Url>
<SearchForm>http://search.creativecommons.org/</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -0,0 +1,17 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>eBay</ShortName>
<Description>eBay - Online actions</Description>
<InputEncoding>ISO-8859-1</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAA/wAAAABAAABAQAAAgEAAAMBAAAD/QAAAAIAAAECAAACAgAAAwIAAAP+AAAAAwAAAQMAAAIDAAADAwAAA/8AAAAD/AABA/wAAgP8AAMD/AAD//wAAAABAAEAAQACAAEAAwABAAP8AQAAAQEAAQEBAAIBAQADAQEAA/0BAAACAQABAgEAAgIBAAMCAQAD/gEAAAMBAAEDAQACAwEAAwMBAAP/AQAAA/0AAQP9AAID/QADA/0AA//9AAAAAgABAAIAAgACAAMAAgAD/AIAAAECAAEBAgACAQIAAwECAAP9AgAAAgIAAQICAAICAgADAgIAA/4CAAADAgABAwIAAgMCAAMDAgAD/wIAAAP+AAED/gACA/4AAwP+AAP//gAAAAMAAQADAAIAAwADAAMAA/wDAAABAwABAQMAAgEDAAMBAwAD/QMAAAIDAAECAwACAgMAAwIDAAP+AwAAAwMAAQMDAAIDAwADAwMAA/8DAAAD/wABA/8AAgP/AAMD/wAD//8AAAAD/AEAA/wCAAP8AwAD/AP8A/wAAQP8AQED/AIBA/wDAQP8A/0D/AACA/wBAgP8AgID/AMCA/wD/gP8AAMD/AEDA/wCAwP8AwMD/AP/A/wAA//8AQP//AID//wDA//8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8fHx8fHx8fHx8fHx8AAB8cGRkUFAcHBx8fBUKfAAAfFBkfHxNHF4cb29vCnwAAHxkZFBQUBx8HG98bwp8fAB8ZGR8UGQcXhxvb28KFXx8fHZkZGRNHBwcfG8jCgoQfAB8fHx8HBx8b29vCnwPCnwAAAB8fBwcfHx8EBB8Dwp8AAAAAHx8fHwAfHx8AHx8fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AACAAwAAAAMAAAADAAAAAQAAAAAAAAAAAACAAAAA4AAAAPCIAAD//wAA//8AAP//AAA=</Image>
<Url type="text/html" method="GET" template="http://search.ebay.com/search/search.dll">
<Param name="query" value="{searchTerms}"/>
<Param name="MfcISAPICommand" value="GetResult"/>
<Param name="ht" value="1"/>
<Param name="ebaytag1" value="ebayreg"/>
<Param name="srchdesc" value="n"/>
<Param name="maxRecordsReturned" value="300"/>
<Param name="maxRecordsPerPage" value="50"/>
<Param name="SortProperty" value="MetaEndSort"/>
</Url>
<SearchForm>http://search.ebay.com/</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -0,0 +1,17 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Google</ShortName>
<Description>Google Search</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAaRJREFUeNpiVIg5JRURw0A0YAHio943kYV%2B%2Ff33%2BdvvX7%2F%2FMjEx8nKycrGzwKXOiPKzICvdeezLhCV3jp15%2Bfv%2FX0YGhv8MDDxMX2qKTIw0RK10eYD6QYqATvoPBkt3f5K0W9Ew4fjTFz%2F%2Bw8Dm3W8UPeZxqFa%2BevsFyD0twgfVsOfkRxHrtfV9u5BVQ8Crd98%2FffkGYQM1QJ20%2FfSPv79eNxQGYfpSVJADmcvEAHbr7oOX2dj%2FERNKIA2%2F%2F%2Fz%2FxfCDhYVoDUDw5P6vf9%2B5iY0HVmZGQWm%2BN3fff%2Fn2k4eLHS739x%2FDiRs%2Ff%2F%2F5x8HO%2FOHzN3djfqgNjIwMgc6qzLx%2Fpy47j2zY%2Feff06tXhOUucgxeun33AUZGpHh4%2Bvo7t8EyIJqz%2FhpasD59%2B5dNrqdnznZIsEL9ICXCsWuBCwvTv%2FymS5PWPP32ExEALz%2F%2BB5r848cPCJcRaMP9xaYQzofPPzfuvrnj0Jst%2B5%2F8%2Bc4sLPeDkYlRgJc93VPE18NIXkYUmJYQSQMZ%2FP3379uPH7%2F%2F%2FEETBzqJ0WqLGvFpe2LCC4AAAwAyjg7ENzDDWAAAAABJRU5ErkJggg%3D%3D</Image>
<Url type="application/x-suggestions+json" method="GET" template="http://suggestqueries.google.com/complete/search?output=firefox&amp;client=firefox&amp;hl={moz:locale}&amp;q={searchTerms}"/>
<Url type="text/html" method="GET" template="http://www.google.com/search">
<Param name="q" value="{searchTerms}"/>
<Param name="ie" value="utf-8"/>
<Param name="oe" value="utf-8"/>
<Param name="aq" value="t"/>
<!-- Dynamic parameters -->
<Param name="rls" value="{moz:distributionID}:{moz:locale}:{moz:official}"/>
<MozParam name="client" condition="defaultEngine" trueValue="firefox-a" falseValue="firefox"/>
</Url>
<SearchForm>http://www.google.com/firefox</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -0,0 +1,7 @@
amazondotcom
answers
creativecommons
eBay
google
wikipedia
yahoo

Просмотреть файл

@ -0,0 +1,15 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Wikipedia (en)</ShortName>
<Description>Wikipedia, the free encyclopedia</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAEAgQAhIOEAMjHyABIR0gA6ejpAGlqaQCpqKkAKCgoAPz9%2FAAZGBkAmJiYANjZ2ABXWFcAent6ALm6uQA8OjwAiIiIiIiIiIiIiI4oiL6IiIiIgzuIV4iIiIhndo53KIiIiB%2FWvXoYiIiIfEZfWBSIiIEGi%2FfoqoiIgzuL84i9iIjpGIoMiEHoiMkos3FojmiLlUipYliEWIF%2BiDe0GoRa7D6GPbjcu1yIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
<Url type="application/x-suggestions+json" method="GET" template="http://en.wikipedia.org/w/api.php">
<Param name="action" value="opensearch"/>
<Param name="search" value="{searchTerms}"/>
</Url>
<Url type="text/html" method="GET" template="http://en.wikipedia.org/wiki/Special:Search">
<Param name="search" value="{searchTerms}"/>
<Param name="sourceid" value="Mozilla-search"/>
</Url>
<SearchForm>http://en.wikipedia.org/wiki/Special:Search</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -0,0 +1,14 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Yahoo</ShortName>
<Description>Yahoo Search</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,R0lGODlhEAAQAJECAP8AAAAAAP///wAAACH5BAEAAAIALAAAAAAQABAAAAIplI+py+0NogQuyBDEnEd2kHkfFWUamEzmpZSfmaIHPHrRguUm/fT+UwAAOw==</Image>
<Url type="application/x-suggestions+json" method="GET"
template="http://ff.search.yahoo.com/gossip?output=fxjson&amp;command={searchTerms}" />
<Url type="text/html" method="GET" template="http://search.yahoo.com/search">
<Param name="p" value="{searchTerms}"/>
<Param name="ei" value="UTF-8"/>
<MozParam name="fr" condition="pref" pref="yahoo-fr" />
</Url>
<SearchForm>http://search.yahoo.com/</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -26,3 +26,6 @@ cmd_selectAll.name=Select All
cmd_shortcuts.name=Edit shortcuts
cmd_newTab.name=Open new tab
cmd_closeTab.name=Close current tab
cmd_actions.name=Open Actions list
cmd_panel.name=Open panel of stuff
cmd_sanitize.name=Delete all saved personal information

Просмотреть файл

@ -76,7 +76,7 @@ toolbarbutton {
-moz-margin-end: 0px;
}
toolbarbutton .toolbarbutton-text {
toolbarbutton:not(.searchengine) .toolbarbutton-text {
display: none !important;
}
@ -92,67 +92,119 @@ toolbarbutton[open="true"] {
background-image: url("chrome://browser/skin/images/toolbar-background.png");
background-repeat: repeat-x;
background-position: top left;
padding: 8px;
padding: 4px 12px;
border: none;
}
toolbarbutton.urlbar-icon-button {
list-style-image: url("chrome://browser/skin/images/toolbar.png");
list-style-image: url("chrome://browser/skin/images/titlebar.png");
-moz-padding-start: 24px !important;
}
#tool-reload {
-moz-image-region: rect(6px 302px 32px 275px);
-moz-image-region: rect(0px 222px 24px 198px);
}
#tool-stop {
-moz-image-region: rect(7px 336px 32px 311px);
-moz-image-region: rect(0px 246px 24px 222px);
}
#tool-go {
-moz-image-region: rect(7px 368px 32px 346px);
-moz-image-region: rect(0px 198px 24px 174px);
}
#tool-bookmarks {
-moz-image-region: rect(0px 174px 48px 126px);
}
#tool-bookmarks:hover:active {
-moz-image-region: rect(48px 174px 96px 126px);
}
#browser-controls {
background-color: rgb(123,125,123);
background: url("images/right_sidebar_middle.png") transparent top left repeat-y;
}
toolbarbutton.browser-control-button {
list-style-image: url("chrome://browser/skin/images/toolbar.png");
list-style-image: url("chrome://browser/skin/images/right_buttons.png");
}
#tool-star {
-moz-image-region: rect(2px 151px 39px 113px);
-moz-image-region: rect(0px 48px 48px 0px);
}
#tool-star:hover:active {
-moz-image-region: rect(0px 96px 48px 48px);
}
#tool-star[starred="true"] {
-moz-image-region: rect(121px 151px 158px 113px);
-moz-image-region: rect(0px 192px 48px 144px);
}
#tool-back {
-moz-image-region: rect(0px 58px 58px 0px);
-moz-image-region: rect(48px 64px 112px 0px);
padding-bottom: 0px !important;
}
#tool-back:hover:active {
-moz-image-region: rect(48px 128px 112px 64px);
padding-bottom: 0px !important;
}
#tool-back[disabled="true"] {
-moz-image-region: rect(58px 58px 116px 0px);
-moz-image-region: rect(48px 192px 112px 128px) !important;
padding-bottom: 0px !important;
}
#tool-forward {
-moz-image-region: rect(0px 108px 37px 60px);
-moz-image-region: rect(112px 48px 160px 0px);
padding-top: 0px !important;
}
#tool-forward:hover:active {
-moz-image-region: rect(112px 96px 160px 48px);
padding-top: 0px !important;
}
#tool-forward[disabled="true"] {
-moz-image-region: rect(58px 108px 95px 60px);
-moz-image-region: rect(112px 144px 160px 96px) !important;
padding-top: 0px !important;
}
#tool-bookmarks {
-moz-image-region: rect(1px 190px 37px 160px);
#tool-actions {
-moz-image-region: rect(160px 48px 208px 0px);
}
#tool-actions {
-moz-image-region: rect(0px 242px 45px 197px);
#tool-actions:hover:active {
-moz-image-region: rect(160px 96px 208px 48px);
}
#tool-stuff {
-moz-image-region: rect(208px 48px 256px 0px);
}
#tool-stuff:hover:active {
-moz-image-region: rect(208px 96px 256px 48px);
}
#tool-addons {
-moz-image-region: rect(2px 151px 39px 113px);
}
#tool-downloads {
-moz-image-region: rect(2px 151px 39px 113px);
}
#tool-preferences {
-moz-image-region: rect(2px 151px 39px 113px);
}
#tool-shortcuts {
-moz-image-region: rect(208px 48px 256px 0px);
}
#tool-shortcuts:hover:active {
-moz-image-region: rect(208px 96px 256px 48px);
}
.tool-search {
@ -160,34 +212,60 @@ toolbarbutton.browser-control-button {
-moz-image-region: rect(0px 36px 36px 0px);
}
#toolbar-main[mode="loading"] > #urlbar-icons > #tool-go,
#toolbar-main[mode="loading"] > #urlbar-icons > #tool-reload {
#toolbar-main[mode="loading"] > #urlbar-container > #urlbar-icons > #tool-go,
#toolbar-main[mode="loading"] > #urlbar-container > #urlbar-icons > #tool-reload {
visibility: collapse;
}
#toolbar-main[mode="view"] > #urlbar-icons > #tool-go,
#toolbar-main[mode="view"] > #urlbar-icons > #tool-stop {
#toolbar-main[mode="view"] > #urlbar-container > #urlbar-icons > #tool-go,
#toolbar-main[mode="view"] > #urlbar-container > #urlbar-icons > #tool-stop {
visibility: collapse;
}
#toolbar-main[mode="edit"] > #urlbar-icons > #tool-reload,
#toolbar-main[mode="edit"] > #urlbar-icons > #tool-stop {
#toolbar-main[mode="edit"] > #urlbar-container > #urlbar-icons > #tool-reload,
#toolbar-main[mode="edit"] > #urlbar-container > #urlbar-icons > #tool-stop {
visibility: collapse;
}
.searchengine {
-moz-box-orient: horizontal;
}
#urlbar-container {
background-color: rgba(207,207,207,0.9);
border: 1px solid rgba(255,255,255,0.9);
-moz-border-radius: 10px;
background-color: transparent;
color: #000;
padding: 2px !important;
-moz-box-orient: horizontal;
-moz-box-align: center;
min-height: 60px;
}
#toolbar-main[mode="edit"] > #urlbar-container {
background-color: rgba(247,247,247,0.9);
border-color: rgba(0,0,0,0.9);
#identity-box {
min-height: 49px;
min-width: 65px;
background: url("images/addressbar_endcap_l_off.png") transparent top right no-repeat;
}
#identity-box:hover:active {
background: url("images/addressbar_endcap_l_on.png") transparent top right no-repeat;
}
/* favicon images are 16x16 */
#urlbar-image-deck {
max-width: 24px;
max-height: 24px;
min-width: 24px;
min-height: 24px;
margin: 12px 2px 2px 12px;
}
#urlbar-throbber[loading] {
list-style-image: url("chrome://browser/skin/images/throbber.gif");
}
#urlbar-editarea {
min-height: 49px;
-moz-box-align: center;
background: url("images/addressbar_middle.png") transparent top left repeat-x;
}
#urlbar-caption {
@ -198,22 +276,20 @@ toolbarbutton.browser-control-button {
-moz-appearance: none !important;
padding: 0px !important;
border: none !important;
background-color: rgba(247,247,247,0.9);
}
/* favicon images are 16x16 */
#urlbar-image-stack {
width: 36px;
height: 36px;
margin: 2px 2px 2px 12px;
background-color: transparent;
}
/* urlbar toolbuttons images are 36x36 */
#urlbar-icons {
height: 36px;
min-height: 49px;
min-width: 65px;
-moz-box-align: center;
background: url("images/addressbar_endcap_r_off.png") transparent top left no-repeat;
}
#urlbar-icons:hover:active {
background: url("images/addressbar_endcap_r_on.png") transparent top left no-repeat;
}
/* URL List */
#urllist-container {
@ -221,6 +297,15 @@ toolbarbutton.browser-control-button {
padding: 8px;
}
#urllist-close {
-moz-appearance: none;
border: none;
background-color: transparent;
margin: 0;
padding: 0;
list-style-image: url("chrome://browser/skin/images/close-small.png");
}
#urllist-items, .autocomplete-richlistbox {
-moz-appearance: none !important;
background-color: rgba(207,207,207,0.9);
@ -249,14 +334,16 @@ toolbarbutton.browser-control-button {
/* tab list */
#tab-list-container {
background-color: rgb(123,125,123);
background: url("images/left_sidebar_middle.png") transparent top left repeat-y;
min-width: 132px;
}
#tab-list {
-moz-appearance: none;
margin: 0;
padding: 4px;
background-color: rgb(123,125,123);
-moz-padding-end: 12px;
background-color: transparent;
}
richlistitem[type="documenttab"] {
@ -272,8 +359,23 @@ richlistitem[type="documenttab"][selected="true"] {
}
#newtab-button {
-moz-appearance: none;
background-color: rgba(207,207,207,0.9);
list-style-image: url("images/left_buttons.png");
-moz-image-region: rect(0px 48px 48px 0px);
}
#newtab-button:hover:active {
list-style-image: url("images/left_buttons.png");
-moz-image-region: rect(0px 96px 48px 48px);
}
#retrievetab-button {
list-style-image: url("images/left_buttons.png");
-moz-image-region: rect(48px 48px 96px 0px);
}
#retrievetab-button:hover:active {
list-style-image: url("images/left_buttons.png");
-moz-image-region: rect(48px 96px 96px 48px);
}
/* autocomplete */
@ -451,11 +553,53 @@ findbar {
padding: 10px;
}
#tool-shortcuts {
-moz-image-region: rect(300px 59px 359px 0px);
/* Preferences window */
#prefs-container
{
background-color: rgba(123,125,123,0.9);
}
#shortcuts-container {
background-color: rgba(123,125,123,0.9);
padding: 8px;
richpref
{
background-color: white;
}
.prefsection
{
font-size: 1.5em ! important;
color: white;
background-color: grey;
padding: .2em 0 .2em 0;
}
.prefbox
{
padding: .3em .3em .3em .5em;
border: thin solid lightgrey;
}
.preftitle
{
font-size: 1.25em ! important;
}
.prefdesc
{
font-size: 1em ! important;
color: grey;
background-color: white;
}
/* BUG: This rule doesn't actually work; I don't know why. */
richpref > button
{
font-size: 1em ! important;
}
/* Shortcut editor */
#shortcuts
{
border: 0;
padding: .2em;
}

Просмотреть файл

@ -0,0 +1,46 @@
label,
description,
textbox {
font-family: "Nokia Sans", sans-serif !important;
font-size: 12pt !important;
}
richlistitem {
font-family: "Nokia Sans", sans-serif !important;
font-size: 12pt !important;
}
#extensionsManager {
-moz-appearance: none;
background-color: rgba(123,125,123,0.9);
}
#extensionsView {
-moz-appearance: none !important;
background-color: rgba(207,207,207,0.9);
border: 2px solid #fff !important;
-moz-border-top-colors: none;
-moz-border-right-colors: none;
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-radius: 10px;
}
#themeSplitter {
background-color: rgba(123,125,123,0.9);
}
#themePreviewArea {
-moz-appearance: none !important;
background-color: rgba(207,207,207,0.9);
border: 2px solid #fff !important;
-moz-border-top-colors: none;
-moz-border-right-colors: none;
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-radius: 10px;
}
#resizerBox {
display: none;
}

Двоичные данные
mobile/chrome/skin/images/addressbar_endcap_l_off.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
mobile/chrome/skin/images/addressbar_endcap_l_on.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
mobile/chrome/skin/images/addressbar_endcap_r_off.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичные данные
mobile/chrome/skin/images/addressbar_endcap_r_on.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
mobile/chrome/skin/images/addressbar_middle.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
mobile/chrome/skin/images/left_buttons.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.6 KiB

Двоичные данные
mobile/chrome/skin/images/left_sidebar_bottom.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
mobile/chrome/skin/images/left_sidebar_middle.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Двоичные данные
mobile/chrome/skin/images/left_sidebar_top.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
mobile/chrome/skin/images/right_buttons.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 38 KiB

Двоичные данные
mobile/chrome/skin/images/right_sidebar_bottom.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
mobile/chrome/skin/images/right_sidebar_middle.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 158 B

Двоичные данные
mobile/chrome/skin/images/right_sidebar_top.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
mobile/chrome/skin/images/titlebar.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 38 KiB

Двоичные данные
mobile/chrome/skin/images/toolbar-background.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 675 B

После

Ширина:  |  Высота:  |  Размер: 594 B

Просмотреть файл

@ -0,0 +1,26 @@
notification {
background: rgb(255, 255, 176);
color: black;
}
notification button {
-moz-appearance: none !important;
background: none !important;
border: 1px solid rgb(192, 192, 160) !important;
-moz-border-radius: 6px !important;
-moz-border-top-colors: rgb(192, 192, 160) !important;
-moz-border-right-colors: rgb(192, 192, 160) !important;
-moz-border-bottom-colors: rgb(192, 192, 160) !important;
-moz-border-left-colors: rgb(192, 192, 160) !important;
margin: 12px 0 12px 6px;
}
.sn-button-text {
background: transparent !important;
color: black !important;
}
.sn-button-extra-text {
color: grey;
font-size: 8pt !important;
}

Просмотреть файл

@ -37,7 +37,7 @@
MOZ_APP_NAME=fennec
MOZ_APP_DISPLAYNAME=Fennec
MOZ_APP_VERSION=0.6
MOZ_APP_VERSION=0.9pre
MOZ_XUL_APP=1
MOZ_UPDATER=0

Просмотреть файл

@ -86,7 +86,8 @@ deb: debian/control
$(NSINSTALL) debian/$(MOZ_APP_NAME).desktop $(DEBDESTDIR)/usr/share/applications/hildon/
$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/dbus-1/services/
cp debian/$(MOZ_APP_NAME).service $(DEBDESTDIR)/usr/share/dbus-1/services/org.mozilla.$(MOZ_APP_NAME).service
# $(NSINSTALL) -m 755 debian/postinst debian/$(MOZ_APP_NAME)/DEBIAN
dh_link; fakeroot dh_fixperms; dh_shlibdeps; fakeroot dh_gencontrol; fakeroot dh_md5sums; dh_builddeb
$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/icons/hicolor/scalable/hildon/
cp $(srcdir)/debian/$(MOZ_APP_NAME)_scalable.png $(DEBDESTDIR)/usr/share/icons/hicolor/scalable/hildon/$(MOZ_APP_NAME).png
dh_link; fakeroot dh_fixperms; fakeroot dh_installdeb; dh_shlibdeps; fakeroot dh_gencontrol; fakeroot dh_md5sums; dh_builddeb
endif

Просмотреть файл

@ -12,37 +12,35 @@ Depends: ${shlibs:Depends}, xulrunner (>=@GRE_MILESTONE@-@GRE_BUILDID@)
Description: Mozilla's mobile browser
This browser is the full rendering engine of Mozilla Firefox combined with a user interface designed to make browsing the web on a mobile device a rich and uncompromised experience.
XB-Maemo-Icon-26:
MB5!.1PT*&@H````-24A$4@```!H````:"`8```"I2DS.````"7!(67,```L3
M```+$P$`FIP8```%;$E$051(B:667XQ4U1W'/_>>>V?NG=F9V3^S_W%9<'#!
M/Q1;NQ:EQH@:T2"EH>&A34R;]$U?Q%9-VH:41BUJFV"-B<8'^Z!-VP=E?37&
M5=18L"SACVMVH<M.9W>8V9G9N7-G[O_3AP6$LD"$;W*3<T_R^W[.]Y=S3@Z<
ME90H_)\DE\Y=J]3SHW_\1)6O#FV2NVD'D*\,W<T;JWK.0W>3OA[012N68]LW
MD1W^!8?W_XGANQ^C5?V$(V/_8L.VGU.:.JG\\M@[UPK2SD/V#=U,K=QDW;TF
M#S_[&HZC4,^O9_T6'84VWO[PI]>32/MFV.URZ^;G273UT7^7`3&)#%*!TM"U
MS]ZHTC?\B/SUD7\J>\E?,TC^'4%LA4?DS\O^V]<H<L!I.6`:,5S[:#B^T)?1
M\MJZ>]YF8:GLB3@/WIQ!,U1F9AH<V]VX&DB1N]'HS6WFN]L>8>"V`6(=O;)S
M8]O<?"!E%/+ZFZ_R_'-[U;4CZTX6NA_8;VZX_X>IWO3W4\,]W;II4CE3MZJS
M9R9JIPICSOBQ,4Z_4+U<HH@H?H"W7CY`@,&NEUY1>M;?GFBC^=2NWR-434HU
M;OY@\]:'8OTW;3]N&@RM74ER1195Z!0S1E^QS5B3CZL[BHJ<L$_L^1T'?[O_
MDD07_LCQQW]$;M-3M&JEL8EJ[M$?/QN"2*OI[-"JW(AX[&<[J:174NK(D<T-
M(F*"N>EYBJ<7*)VI4%EHL'!ZWG7R\[_AT)Z7+O06YR%_&>PBU;V#RLE]%/]S
M5/A6YK7WIP+1WCLJA"Z:C44*E1H=]SZ*TMF-D=31@?J9&E:Q@EVW<2IUM$Q"
M\U8/W1>MW9)GXMW#Y_R_.;!6(^+SO[VH;/[K%XN'QJ>/C7VR+]CVAY1^XRVJ
M%A?(9`IO=`MS'8-XAH[M!5B-%JUZ`]_U20UT0;-%Z_@I8J&OJ<.]S['QF=RR
MK;M(]^S=R<8-[PA148S\89*WW$GVUN^1T049324I)-;D?VG,E:F7+%+?N9'%
M:I7J=!&W+TLSE<;Y^."?>>^))R].=+%4#+&3,%1"LX?6Z`[\U`W87\]0*Y2H
MN1YU)\0UX]A^2*0+HJ2!.;*2MM4K$%T91,M%B2>VPM;LN5VWC+9T0>P.K!;,
M%8AL"RN10$G$"7K:(1G#C1N8G2F2=XP02/!5B=-R\<(63!>1PH!(K"*W)L<4
MY>5!;4X/]<5V)AM0KX(J"!(F]722T/.(!KHQLYTT58FN0A!&1&Z(W_+P\B6\
M`U_BZW%D6U805FX`/E\>%/D&MB/(SX,:@6&"ZQ`T&MC51?SV#*X21Q,0DZ`&
M+J$?X9>K^">F""HE@DH-?!>D;5R^=:%E4;-<'#N!],#WH!D#31`,KB!038)\
M$5W5<%4)00"A@CST;[P3D_BVA73J$'J`6[\\R)THXVS,T[ZJ`]\#Q8;:/&@Z
M%(`C<;QL%X$O(!T#1<!"!8X>)5I<`,^&R`.$!<Q<83-0I5[X"*7S-M(IJ!6@
M50-A@&-#N0"#JXFZ^J&B@YF&\@($$AP+\``)A!,P>Q(NN!DN;9_2Q._8CB\,
M(@]:<Q#Y$#H0^-!8A,(T%&?`5T#)0*B"-7T6I$CP_PBS!ZX,HEP@3/3C)D:)
MXA"5(*Q!%"Y]01-D"%*'P`17!3L`KP'2!J(/8'8/>,VK@(A@]CBH:PGM'+)\
M=EH#G*55JQF(C8"O@]T`IP&1!()).+4+ZE^=,[L2"&`1YKZ$L!=J-X&B0AIH
M`C;(&O@.!&6(3H.<!N8_A9E?06W\*M[+:A!23T/J('2UH$TNG2!#0DI".H#,
M)&1>!-8M9_!MWFTQB*V&Q"AX(V`,@-3`*X*<`O\@^">6HEX?Z$*90/QLO<]2
:+Z,K%?P/&D=O=_6]@+\`````245.1*Y"8((`
`
iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c
6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0
SU1FB9gIGwMdOFD5xWYAAAUNSURBVEjH7ZbrT1tlHMe/59KW0pa2XC3QMi6D
bWFjrNFlim4OkLEyg5SJDCUhkl3eGTOzxH/A6MyiJs4YI8k2nKwbY4tjLxS2
QXSZ6DRsiAIVGKVQSm+HntPTntNzji+WJctEM29vzL4vnzzP55s8v+f3+z7A
I/1NEX9l88DAFRMbidkUgpb1BtpT+1wN89BGl1yf6gz61LVxyjRXV1cf+h18
8ArVdd33ilfSHtKlGzZn5hvUocUYYkw0iTt3blXlUZ88va2wq7a2Xnjw7NC1
a4TA+c2ikGCIfldXZXE29YOgUCKh0Q0vRRIfKuqsi7U11fKx9z/PO+EWeuTC
gqqqCitoksC6NalICApmvRy4aQ+uftSNx4vMN9tat+97vmnPJABc/epcucWk
Oihy7B4lKVqngvSzNKU1LnPxiGw0kCqNRqw256VUh3n2evfJ7lNvX5g4PEEa
izfb18Eji4gLEqg4jWg8iVkuDqMKyF9rxdcRxi6M+QZ7Xa4jlWW6OinGtoUW
FyiKpBDlZUikRSYAYNB1/Hs1ydtlWUFhkRVZORn4cTqCjl4PuCIbDFAjtzIf
BEUCJHG3tIoCMcRi+eOLCEsCchxPomszIEX8CAUiUGtoqDVqLEVVYWPuOgsN
AFGR6jFTil2rS8Hsr14szPlgs1lwonMDOoZZsFoCv8wHABUJkCQIALIkQfaF
QDZWIVsScfIpHfyjo1CSEiy5OUgIcbAsj6ig6WuqrUkQANB/qT8z6Rtzk8mY
Mc2chvwCCyiKQJwXMEWk4eDlWUgaGqBpKBQBKRQF7/YgfseLvK3lOLv/Cegi
fphMBgQDEXhm5gEFYGW1TGeVbWludo6SAOBocAQE2vAeHxcRXA5jemoOwcAK
VBSJrRkkOmwE4HaDmJoCMeUGteSFNDMBOTCHN7cYYLfoUVpWAI5LIC5IAEmB
jwvgScOZ5mbnKACQ956i7rGSowKlH2ciK/D5VxBmEpBAYNHjw2s7S1Gh5lFO
xbA7R42d2WrY0gi0VBWjrXojRIlAFFkw5JXBYEqHlJTAyLplc7b18KoN2+c6
vSE4MzYs8VxGhq0EljWlyDSngvVNomhNNkClgNJnQkkKENllEIoEP5eC9IJN
mHNPwDM5hoBnGpJKmzDZ1jta214evMcm7zd64cV942m29bs5iQ4vzbrBcyzU
ZiusFTvAcTFEQgFEFucQXphGlGEQ4wVkl9jBxnjwfAzB5SVEJVLQW8v23W8C
ANSD3Xy2t8+7va5x6VRPb6PMBZFhUCFVDiEeY5HgE+A5DomEgKSYhCQmIcYZ
LMz7cPF0N1z917B15663Ol/tPP4gl15tLtnt9s+Gh4ZeTyTiG4NzP0NhTTAa
dZAUGbIk370KkoQiA8yMF6FwFLcnZ1C6sWLJZrO+uxqTXG2xbleN2ORs7Lw5
6eO/GRkHkZKNy0M/YXZ+GWw0BjbKY+T2DL4bW8RKTMEXAyNQNHrZ4ag/1NDQ
wDy0EQDsP7B/pLW9rUOlNypaLQWH0wlO1iHG8khKJKBJx66mRqSoAYHWYu9L
LW+0t7f3/RGP/LPRnp+Vfr5qm308EvJDXplHa8cBiAqNTGsZWlqc8LtvQpWi
RvOe6kBJSfEH/yiPvhwY1KwwTGWMCT9Tvqn8iPfWjfScwrXwhZiIPxg5rjOY
bqQZTN86Gur9/1rwnXOdKZ++NTKkTTMruYXrdzj3Osf+s0g+dvQd24W+8/mP
Pif/P/0GTJtNNru0m40AAAAASUVORK5CYII=

Просмотреть файл

@ -1,17 +1,17 @@
[Desktop Entry]
Version=1.0
Version=@MOZ_APP_VERSION@
Encoding=UTF-8
Name=Fennec
Name=@MOZ_APP_DISPLAYNAME@
Comment=Fennec mobile browser
GenericName=Fennec
GenericName=@MOZ_APP_DISPLAYNAME@
Exec=/usr/local/fennec/fennec
Terminal=false
X-MultipleArgs=false
Type=Application
Icon=fennec
Icon=@MOZ_APP_NAME@
Categories=Application;Network;
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/vnd.mozilla.xul+xml;application/rss+xml;application/rdf+xml;image/gif;image/jpeg;image/png;
StartupWMClass=Fennec
StartupWMClass=@MOZ_APP_DISPLAYNAME@
StartupNotify=true
X-Osso-Service=org.mozilla.fennec
GenericName[it_IT]=Mobile Browser
X-Osso-Service=Mozilla.@MOZ_APP_DISPLAYNAME@

Просмотреть файл

@ -0,0 +1,36 @@
#! /bin/sh
# postinst script for fennec
#
# see: dh_installdeb(1)
set -e
case "$1" in
configure)
# for fennec icons
gtk-update-icon-cache -f /usr/share/icons/hicolor
# select where to install fennec menu
if [ "$2" == "" ]; then
if [ ! -f /targets/links/scratchbox.config ]; then
maemo-select-menu-location fennec.desktop tana_fi_web
fi
if [ -x /usr/bin/update-desktop-database ]; then
update-desktop-database /usr/share/applications
fi
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0

Просмотреть файл

@ -1,4 +1,4 @@
[D-BUS Service]
Name=org.mozilla.fennec
Name=Mozilla.@MOZ_APP_DISPLAYNAME@
Exec=/usr/local/fennec/fennec

Двоичные данные
mobile/installer/debian/fennec_scalable.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Просмотреть файл

@ -44,10 +44,10 @@ mobile/app/Makefile
mobile/installer/Makefile
mobile/installer/debian/changelog
mobile/installer/debian/compat
mobile/installer/debian/control
mobile/installer/debian/fennec.desktop
mobile/installer/debian/fennec.links
mobile/installer/debian/fennec.service
mobile/installer/debian/files
mobile/installer/debian/icon_base64
mobile/installer/debian/menu"
mobile/installer/debian/menu
mobile/installer/debian/fennec.postinst"