bug 441794: merge back to main line

This commit is contained in:
Daniel Brooks 2008-07-17 16:51:26 -05:00
commit 6d33eb8a1f
21 changed files with 1005 additions and 219 deletions

View File

@ -38,6 +38,7 @@
pref("toolkit.defaultChromeURI", "chrome://browser/content/browser.xul");
pref("general.useragent.extra.mobile", "@APP_UA_NAME@/@APP_VERSION@");
pref("browser.chromeURL", "chrome://browser/content/");
pref("browser.startup.homepage", "http://www.mozilla.org/");
pref("browser.ui.cursor", false);
@ -123,3 +124,36 @@ pref("extensions.getMoreThemesURL", "chrome://mozapps/locale/extensions/extensio
pref("browser.display.use_focus_colors", true);
pref("browser.display.focus_background_color", "#ffffa0");
pref("browser.display.focus_text_color", "#00000");
/* block popups by default, and notify the user about blocked popups */
pref("dom.disable_open_during_load", true);
pref("privacy.popups.showBrowserMessage", true);
pref("keyword.enabled", true);
pref("keyword.URL", "http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=");
pref("snav.enabled", true);
pref("accessibility.typeaheadfind", false);
pref("accessibility.typeaheadfind.timeout", 5000);
pref("accessibility.typeaheadfind.flashBar", 1);
pref("accessibility.typeaheadfind.linksonly", false);
pref("accessibility.typeaheadfind.casesensitive", false);
// pointer to the default engine name
pref("browser.search.defaultenginename", "chrome://browser/locale/region.properties");
// disable logging for the search service by default
pref("browser.search.log", false);
// 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");
// disable updating
pref("browser.search.update", false);
pref("browser.search.update.log", false);
pref("browser.search.updateinterval", 6);
// enable search suggestions by default
pref("browser.search.suggest.enabled", true);

View File

@ -50,6 +50,7 @@ var BrowserUI = {
_caption : null,
_edit : null,
_throbber : null,
_autocompleteNavbuttons : null,
_favicon : null,
_faviconAdded : false,
_fadeoutID : null,
@ -137,12 +138,13 @@ var BrowserUI = {
this._caption = document.getElementById("urlbar-caption");
this._caption.addEventListener("click", this, false);
this._edit = document.getElementById("urlbar-edit");
this._edit.addEventListener("focus", this, false);
this._edit.addEventListener("blur", this, false);
this._edit.addEventListener("keypress", this, false);
this._edit.addEventListener("keypress", this, true);
this._edit.addEventListener("input", this, false);
this._throbber = document.getElementById("urlbar-throbber");
this._favicon = document.getElementById("urlbar-favicon");
this._favicon.addEventListener("error", this, false);
this._autocompleteNavbuttons = document.getElementById("autocomplete_navbuttons");
getBrowser().addEventListener("DOMTitleChanged", this, true);
getBrowser().addEventListener("DOMLinkAdded", this, true);
@ -220,25 +222,13 @@ var BrowserUI = {
},
goToURI : function(aURI) {
this._edit.reallyClosePopup();
if (!aURI)
aURI = this._edit.value;
if (!this._URIFixup)
this._URIFixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
try {
aURI = this._URIFixup.createFixupURI(aURI, 0);
aURI = this._URIFixup.createExposableURI(aURI);
}
catch (ex) {
aURI = null;
}
if (aURI == null)
this.search();
else
getBrowser().loadURI(aURI.spec, null, null, false);
var flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
getBrowser().loadURIWithFlags(aURI, flags, null, null);
this._showMode(PANELMODE_VIEW);
},
@ -249,6 +239,64 @@ var BrowserUI = {
this._showMode(PANELMODE_VIEW);
},
sizeAutocompletePopup : function () {
var rect = document.getElementById("browser-container").getBoundingClientRect();
var popup = document.getElementById("popup_autocomplete");
popup.height = rect.bottom - rect.top;
},
openDefaultHistory : function () {
if (!this._edit.value) {
this._autocompleteNavbuttons.hidden = true;
this._edit.showHistoryPopup();
}
},
doButtonSearch : function(button)
{
if (!("engine" in button) || !button.engine)
return;
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);
},
engines : null,
updateSearchEngines : function () {
if (this.engines)
return;
// XXXndeakin remove the try-catch once the search service is properly built
try {
var searchService = Cc["@mozilla.org/browser/search-service;1"].
getService(Ci.nsIBrowserSearchService);
} catch (ex) {
this.engines = [ ];
return;
}
var engines = searchService.getVisibleEngines({ });
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++) {
var button = document.createElementNS(kXULNS, "toolbarbutton");
var engine = engines[e];
button.id = engine.name;
button.setAttribute("label", engine.name);
if (engine.iconURI)
button.setAttribute("image", engine.iconURI.spec);
container.insertBefore(button, container.firstChild);
button.engine = engine;
}
},
_showMode : function(aMode) {
if (this._fadeoutID) {
clearTimeout(this._fadeoutID);
@ -270,11 +318,9 @@ var BrowserUI = {
this._caption.hidden = true;
this._edit.hidden = false;
this._edit.focus();
this.showHistory();
bookmark.hidden = true;
urllist.hidden = false;
urllist.hidden = true;
this.openDefaultHistory();
}
else if (aMode == PANELMODE_BOOKMARK) {
toolbar.setAttribute("mode", "view");
@ -368,14 +414,17 @@ var BrowserUI = {
case "click":
this._showMode(PANELMODE_EDIT);
break;
case "focus":
setTimeout(function() { aEvent.target.select(); }, 0);
case "input":
if (this._edit.value) {
this.updateSearchEngines();
this._autocompleteNavbuttons.hidden = false;
}
break;
case "keypress":
if (aEvent.keyCode == aEvent.DOM_VK_RETURN)
this.goToURI();
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE)
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
this._edit.reallyClosePopup();
this._showMode(PANELMODE_VIEW);
}
break;
// Favicon events
case "error":
@ -471,6 +520,22 @@ var BookmarkHelper = {
_bmksvc : null,
_tagsvc : null,
_getTagsArrayFromTagField : function() {
// we don't require the leading space (after each comma)
var tags = document.getElementById("bookmark-tags").value.split(",");
for (var i=0; i<tags.length; i++) {
// remove trailing and leading spaces
tags[i] = tags[i].replace(/^\s+/, "").replace(/\s+$/, "");
// remove empty entries from the array.
if (tags[i] == "") {
tags.splice(i, 1);
i--;
}
}
return tags;
},
edit : function(aURI) {
this._bmksvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
this._tagsvc = Cc["@mozilla.org/browser/tagging-service;1"].getService(Ci.nsITaggingService);
@ -481,8 +546,10 @@ var BookmarkHelper = {
this._item = bookmarkIDs[0];
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-tags").value = currentTags.join(", ");
}
window.addEventListener("keypress", this, true);
},
remove : function() {
@ -499,9 +566,8 @@ var BookmarkHelper = {
this._bmksvc.setItemTitle(this._item, document.getElementById("bookmark-name").value);
// Update the tags
var taglist = document.getElementById("hudbookmark-tags").value;
var tags = this._getTagsArrayFromTagField();
var currentTags = this._tagsvc.getTagsForURI(this._uri, {});
var tags = taglist.split(" ");
if (tags.length > 0 || currentTags.length > 0) {
var tagsToRemove = [];
var tagsToAdd = [];
@ -526,7 +592,17 @@ var BookmarkHelper = {
},
close : function() {
window.removeEventListener("keypress", this, true);
this._item = null;
BrowserUI.hide();
},
handleEvent: function (aEvent) {
switch (aEvent.type) {
case "keypress":
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE)
this.close();
break;
}
}
};

View File

@ -0,0 +1,7 @@
deckbrowser {
-moz-binding: url("chrome://browser/content/deckbrowser.xml#deckbrowser");
}
#urlbar-edit {
-moz-binding: url("chrome://browser/content/urlbar.xml#autocomplete-aligned");
}

View File

@ -43,6 +43,20 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const FINDSTATE_FIND = 0;
const FINDSTATE_FIND_AGAIN = 1;
const FINDSTATE_FIND_PREVIOUS = 2;
Cu.import("resource://gre/modules/SpatialNavigation.js");
// create a lazy-initialized handle for the pref service on the global object
// in the style of bug 385809
__defineGetter__("gPrefService", function () {
delete gPrefService;
return gPrefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch2);
});
function getBrowser() {
return Browser.content.browser;
}
@ -81,11 +95,16 @@ var Browser = {
this._content = document.getElementById("content");
this._content.addEventListener("DOMTitleChanged", this, true);
this._content.addEventListener("overpan", this, false);
this._content.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
BrowserUI.init();
this._progressController = new ProgressController(this.content);
this._spatialNavigation = new SpatialNavigation(this.content);
this.setupGeolocationPrompt();
Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
// Determine the initial launch page
@ -120,21 +139,74 @@ var Browser = {
}
},
setupGeolocationPrompt: function() {
var geolocationService = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationService);
geolocationService.prompt = function(request) {
var notificationBox = Browser.getNotificationBox();
var notification = notificationBox.getNotificationWithValue("geolocation");
if (!notification) {
var bundle_browser = document.getElementById("bundle_browser");
var buttons = [{
label: bundle_browser.getString("gelocation.exactLocation"),
accessKey: bundle_browser.getString("gelocation.exactLocationKey"),
callback: function(){request.allow()},
},
{
label: bundle_browser.getString("gelocation.neighborhoodLocation"),
accessKey: bundle_browser.getString("gelocation.neighborhoodLocationKey"),
callback: function(){request.allowButFuzz()},
},
{
label: bundle_browser.getString("gelocation.nothingLocation"),
accessKey: bundle_browser.getString("gelocation.nothingLocationKey"),
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);
return 1;
}
};
},
get content() {
return this._content;
},
/**
* Return the currently active <browser> object, since a <deckbrowser> may
* have more than one
*/
get currentBrowser() {
return this._content.browser;
},
handleEvent: function (aEvent) {
switch (aEvent.type) {
case "DOMTitleChanged":
this._titleChanged(aEvent);
break;
case "overpan":
// Open the sidebar controls if we get a right side overpan
if (aEvent.detail == 2)
document.getElementById("browser-controls").collapsed = false;
// Close the sidebar controls if we get a left side overpan
else if (aEvent.detail == 1)
document.getElementById("browser-controls").collapsed = true;
break;
}
},
supportsCommand : function(cmd) {
var isSupported = false;
switch (cmd) {
case "cmd_menu":
case "cmd_fullscreen":
case "cmd_addons":
case "cmd_downloads":
@ -153,10 +225,14 @@ var Browser = {
doCommand : function(cmd) {
var browser = this.content.browser;
var controls = document.getElementById("browser-controls");
switch (cmd) {
case "cmd_menu":
controls.collapsed = !controls.collapsed;
break;
case "cmd_fullscreen":
window.fullScreen = window.fullScreen ? false : true;
window.fullScreen = !window.fullScreen;
break;
case "cmd_addons":
{
@ -187,7 +263,38 @@ var Browser = {
Cc["@mozilla.org/download-manager-ui;1"].getService(Ci.nsIDownloadManagerUI).show(window);
break;
}
}
},
getNotificationBox : function() {
return document.getElementById("notifications");
},
findState: FINDSTATE_FIND,
openFind: function(aState) {
this.findState = aState;
var findbar = document.getElementById("findbar");
var browser = findbar.browser;
if (!browser) {
browser = this.content.browser;
findbar.browser = browser;
}
var panel = document.getElementById("findpanel");
if (panel.state == "open")
this.doFind(null);
else
panel.openPopup(document.getElementById("findpanel-placeholder"), "before_start");
},
doFind: function (aEvent) {
var findbar = document.getElementById("findbar");
if (Browser.findState == FINDSTATE_FIND)
findbar.onFindCommand();
else
findbar.onFindAgainCommand(Browser.findState == FINDSTATE_FIND_PREVIOUS);
}
};
function ProgressController(aTabBrowser) {
@ -226,7 +333,7 @@ ProgressController.prototype = {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
aWebProgress.DOMWindow.focus();
this._tabbrowser.updateCanvasState();
this._tabbrowser.updateCanvasState(true);
//aWebProgress.DOMWindow.scrollbars.visible = false;
}
}
@ -238,13 +345,42 @@ ProgressController.prototype = {
},
// This method is called to indicate a change to the current location.
onLocationChange : function(aWebProgress, aRequest, aLocation) {
onLocationChange : function(aWebProgress, aRequest, aLocationURI) {
var location = aLocationURI ? aLocationURI.spec : "";
this._hostChanged = true;
// This code here does not compare uris exactly when determining
// whether or not the message(s) should be hidden since the message
// may be prematurely hidden when an install is invoked by a click
// on a link that looks like this:
//
// <a href="#" onclick="return install();">Install Foo</a>
//
// - which fires a onLocationChange message to uri + '#'...
cBrowser = Browser.currentBrowser;
if (cBrowser.lastURI) {
var oldSpec = cBrowser.lastURI.spec;
var oldIndexOfHash = oldSpec.indexOf("#");
if (oldIndexOfHash != -1)
oldSpec = oldSpec.substr(0, oldIndexOfHash);
var newSpec = location;
var newIndexOfHash = newSpec.indexOf("#");
if (newIndexOfHash != -1)
newSpec = newSpec.substr(0, newSpec.indexOf("#"));
if (newSpec != oldSpec) {
// Remove all the notifications, except for those which want to
// persist across the first location change.
var nBox = Browser.getNotificationBox();
nBox.removeTransientNotifications();
}
}
cBrowser.lastURI = aLocationURI;
if (aWebProgress.DOMWindow == this._browser.contentWindow) {
BrowserUI.setURI();
this._tabbrowser.updateCanvasState(true);
this._tabbrowser.updateCanvasState();
}
},
@ -278,7 +414,7 @@ ProgressController.prototype = {
this._hostChanged = false;
// Don't pass in the actual location object, since it can cause us to
// Don't pass in the actual location object, since it can cause us to
// hold on to the window object too long. Just pass in the fields we
// care about. (bug 424829)
var location = getBrowser().contentWindow.location;
@ -293,7 +429,7 @@ ProgressController.prototype = {
// properties anyways, though.
}
getIdentityHandler().checkIdentity(this._state, locationObj);
},
QueryInterface : function(aIID) {
@ -313,13 +449,13 @@ function IdentityHandler() {
this._stringBundle = document.getElementById("bundle_browser");
this._staticStrings = {};
this._staticStrings[this.IDENTITY_MODE_DOMAIN_VERIFIED] = {
encryption_label: this._stringBundle.getString("identity.encrypted")
encryption_label: this._stringBundle.getString("identity.encrypted")
};
this._staticStrings[this.IDENTITY_MODE_IDENTIFIED] = {
encryption_label: this._stringBundle.getString("identity.encrypted")
};
this._staticStrings[this.IDENTITY_MODE_UNKNOWN] = {
encryption_label: this._stringBundle.getString("identity.unencrypted")
encryption_label: this._stringBundle.getString("identity.unencrypted")
};
this._cacheElements();
@ -358,7 +494,7 @@ IdentityHandler.prototype = {
displaySecurityInfo();
event.stopPropagation();
},
/**
* Helper to parse out the important parts of _lastStatus (of the SSL cert in
* particular) for use in constructing identity UI strings
@ -367,10 +503,10 @@ IdentityHandler.prototype = {
var result = {};
var status = this._lastStatus.QueryInterface(Components.interfaces.nsISSLStatus);
var cert = status.serverCert;
// Human readable name of Subject
result.subjectOrg = cert.organization;
// SubjectName fields, broken up for individual access
if (cert.subjectName) {
result.subjectNameFields = {};
@ -378,25 +514,25 @@ IdentityHandler.prototype = {
var field = v.split("=");
this[field[0]] = field[1];
}, result.subjectNameFields);
// Call out city, state, and country specifically
result.city = result.subjectNameFields.L;
result.state = result.subjectNameFields.ST;
result.country = result.subjectNameFields.C;
}
// Human readable name of Certificate Authority
result.caOrg = cert.issuerOrganization || cert.issuerCommonName;
result.cert = cert;
return result;
},
/**
* Determine the identity of the page being displayed by examining its SSL cert
* (if available) and, if necessary, update the UI to reflect this. Intended to
* be called by onSecurityChange
*
*
* @param PRUint32 state
* @param JS Object location that mirrors an nsLocation (i.e. has .host and
* .hostname and .port)
@ -407,7 +543,7 @@ IdentityHandler.prototype = {
.SSLStatus;
this._lastStatus = currentStatus;
this._lastLocation = location;
if (state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
this.setMode(this.IDENTITY_MODE_IDENTIFIED);
else if (state & Components.interfaces.nsIWebProgressListener.STATE_SECURE_HIGH)
@ -415,7 +551,7 @@ IdentityHandler.prototype = {
else
this.setMode(this.IDENTITY_MODE_UNKNOWN);
},
/**
* Return the eTLD+1 version of the current hostname
*/
@ -432,7 +568,7 @@ IdentityHandler.prototype = {
return this._lastLocation.hostname;
}
},
/**
* Update the UI to reflect the specified mode, which should be one of the
* IDENTITY_MODE_* constants.
@ -446,12 +582,12 @@ IdentityHandler.prototype = {
this._identityBox.className = newMode;
this.setIdentityMessages(newMode);
// Update the popup too, if it's open
if (this._identityPopup.state == "open")
this.setPopupMessages(newMode);
},
/**
* Set up the messages for the primary identity UI based on the specified mode,
* and the details of the SSL cert, where applicable
@ -477,30 +613,30 @@ IdentityHandler.prototype = {
// for certs that are trusted because of a security exception.
var tooltip = this._stringBundle.getFormattedString("identity.identified.verifier",
[iData.caOrg]);
// Check whether this site is a security exception. XPConnect does the right
// thing here in terms of converting _lastLocation.port from string to int, but
// the overrideService doesn't like undefined ports, so make sure we have
// something in the default case (bug 432241).
if (this._overrideService.hasMatchingOverride(this._lastLocation.hostname,
if (this._overrideService.hasMatchingOverride(this._lastLocation.hostname,
(this._lastLocation.port || 443),
iData.cert, {}, {}))
tooltip = this._stringBundle.getString("identity.identified.verified_by_you");
}
else if (newMode == this.IDENTITY_MODE_IDENTIFIED) {
// If it's identified, then we can populate the dialog with credentials
iData = this.getIdentityData();
iData = this.getIdentityData();
tooltip = this._stringBundle.getFormattedString("identity.identified.verifier",
[iData.caOrg]);
}
else {
tooltip = this._stringBundle.getString("identity.unknown.tooltip");
}
// Push the appropriate strings out to the UI
this._identityBox.tooltipText = tooltip;
},
/**
* Set up the title and content messages for the identity message popup,
* based on the specified mode, and the details of the SSL cert, where
@ -509,17 +645,17 @@ IdentityHandler.prototype = {
* @param newMode The newly set identity mode. Should be one of the IDENTITY_MODE_* constants.
*/
setPopupMessages : function(newMode) {
this._identityPopup.className = newMode;
this._identityPopupContentBox.className = newMode;
// Set the static strings up front
this._identityPopupEncLabel.textContent = this._staticStrings[newMode].encryption_label;
// Initialize the optional strings to empty values
var supplemental = "";
var verifier = "";
if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) {
var iData = this.getIdentityData();
var host = this.getEffectiveHost();
@ -531,12 +667,12 @@ IdentityHandler.prototype = {
// If it's identified, then we can populate the dialog with credentials
iData = this.getIdentityData();
host = this.getEffectiveHost();
owner = iData.subjectOrg;
owner = iData.subjectOrg;
verifier = this._identityBox.tooltipText;
// Build an appropriate supplemental block out of whatever location data we have
if (iData.city)
supplemental += iData.city + "\n";
supplemental += iData.city + "\n";
if (iData.state && iData.country)
supplemental += this._stringBundle.getFormattedString("identity.identified.state_and_country",
[iData.state, iData.country]);
@ -550,7 +686,7 @@ IdentityHandler.prototype = {
host = "";
owner = "";
}
// Push the appropriate strings out to the UI
this._identityPopupContentHost.textContent = host;
this._identityPopupContentOwner.textContent = owner;
@ -563,12 +699,12 @@ IdentityHandler.prototype = {
},
/**
* Click handler for the identity-box element in primary chrome.
* Click handler for the identity-box element in primary chrome.
*/
handleIdentityButtonEvent : function(event) {
event.stopPropagation();
if ((event.type == "click" && event.button != 0) ||
(event.type == "keypress" && event.charCode != KeyEvent.DOM_VK_SPACE &&
event.keyCode != KeyEvent.DOM_VK_RETURN))
@ -577,20 +713,20 @@ IdentityHandler.prototype = {
// Make sure that the display:none style we set in xul is removed now that
// the popup is actually needed
this._identityPopup.hidden = false;
// Tell the popup to consume dismiss clicks, to avoid bug 395314
this._identityPopup.popupBoxObject
.setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
// Update the popup strings
this.setPopupMessages(this._identityBox.className);
// Now open the popup, anchored off the primary chrome element
this._identityPopup.openPopup(this._identityBox, 'after_start');
}
};
var gIdentityHandler;
var gIdentityHandler;
/**
* Returns the singleton instance of the identity handler class. Should always be
@ -599,5 +735,86 @@ var gIdentityHandler;
function getIdentityHandler() {
if (!gIdentityHandler)
gIdentityHandler = new IdentityHandler();
return gIdentityHandler;
return gIdentityHandler;
}
/**
* Handler for blocked popups, triggered by DOMUpdatePageReport events in browser.xml
*/
const gPopupBlockerObserver = {
_kIPM: Components.interfaces.nsIPermissionManager,
onUpdatePageReport: function (aEvent)
{
var cBrowser = Browser.currentBrowser;
if (aEvent.originalTarget != cBrowser)
return;
if (!cBrowser.pageReport)
return;
// Only show the notification again if we've not already shown it. Since
// notifications are per-browser, we don't need to worry about re-adding
// it.
if (!cBrowser.pageReport.reported) {
if(gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) {
var bundle_browser = document.getElementById("bundle_browser");
var brandBundle = document.getElementById("bundle_brand");
var brandShortName = brandBundle.getString("brandShortName");
var message;
var popupCount = cBrowser.pageReport.length;
if (popupCount > 1)
message = bundle_browser.getFormattedString("popupWarningMultiple", [brandShortName, popupCount]);
else
message = bundle_browser.getFormattedString("popupWarning", [brandShortName]);
var notificationBox = Browser.getNotificationBox();
var notification = notificationBox.getNotificationWithValue("popup-blocked");
if (notification) {
notification.label = message;
}
else {
var buttons = [
{
label: bundle_browser.getString("popupButtonAlwaysAllow"),
accessKey: bundle_browser.getString("popupButtonAlwaysAllow.accesskey"),
callback: function() { gPopupBlockerObserver.toggleAllowPopupsForSite(); }
},
{
label: bundle_browser.getString("popupButtonNeverWarn"),
accessKey: bundle_browser.getString("popupButtonNeverWarn.accesskey"),
callback: function() { gPopupBlockerObserver.dontShowMessage(); }
}
];
const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
notificationBox.appendNotification(message, "popup-blocked",
"",
priority, buttons);
}
}
// Record the fact that we've reported this blocked popup, so we don't
// show it again.
cBrowser.pageReport.reported = true;
}
},
toggleAllowPopupsForSite: function (aEvent)
{
var currentURI = Browser.currentBrowser.webNavigation.currentURI;
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(this._kIPM);
pm.add(currentURI, "popup", this._kIPM.ALLOW_ACTION);
Browser.getNotificationBox().removeCurrentNotification();
},
dontShowMessage: function ()
{
var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
gPrefService.setBoolPref("privacy.popups.showBrowserMessage", !showMessage);
Browser.getNotificationBox().removeCurrentNotification();
}
};

View File

@ -39,7 +39,7 @@
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/deckbrowser.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
@ -56,6 +56,7 @@
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
<stringbundle id="bundle-keys" src="chrome://global/locale/keys.properties"/>
<stringbundle id="bundle-platformKeys" src="chrome://global-platform/locale/platformKeys.properties"/>
</stringbundleset>
@ -69,6 +70,17 @@
<script type="application/x-javascript" src="chrome://browser/content/browser-ui.js"/>
<script type="application/x-javascript;version=1.8" src="chrome://browser/content/shortcuts.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
<stringbundle id="bundle-keys" src="chrome://global/locale/keys.properties"/>
<stringbundle id="bundle-platformKeys" src="chrome://global-platform/locale/platformKeys.properties"/>
</stringbundleset>
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
</stringbundleset>
<commandset id="cmdset_main">
<!-- basic navigation -->
<command id="cmd_back" label="&back.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
@ -83,6 +95,7 @@
<command id="cmd_bookmarks" label="&bookmarks.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<!-- 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);"/>
@ -101,6 +114,10 @@
<command id="cmd_paste" label="&paste.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_delete" label="&delete.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_selectAll" label="&selectAll.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_find" oncommand="Browser.openFind(FINDSTATE_FIND);"/>
<command id="cmd_findAgain" oncommand="Browser.openFind(FINDSTATE_FIND_AGAIN);"/>
<command id="cmd_findPrevious" oncommand="Browser.openFind(FINDSTATE_FIND_PREVIOUS);"/>
</commandset>
<keyset id="mainKeyset">
@ -116,14 +133,29 @@
<key id="key_pageDown" keycode="VK_DOWN" command="cmd_scrollPageDown" modifiers="shift"/>
<!-- 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"/>
<key id="key_find" key="&findOnCmd.commandkey;" command="cmd_find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="cmd_findAgain" modifiers="accel"/>
<key id="key_findPrevious" key="&findAgainCmd.commandkey;" command="cmd_findPrevious" modifiers="accel,shift"/>
<key keycode="&findAgainCmd.commandkey2;" command="cmd_findAgain"/>
<key keycode="&findAgainCmd.commandkey2;" command="cmd_findPrevious" modifiers="shift"/>
</keyset>
<popupset id="mainPopupSet">
<panel type="autocomplete-richlistbox" id="popup_autocomplete"
noautofocus="true" onpopupshowing="BrowserUI.sizeAutocompletePopup()">
<hbox id="autocomplete_navbuttons" align="center" flex="1"
oncommand="BrowserUI.doButtonSearch(event.target);">
<image class="tool-search"/>
</hbox>
</panel>
<!-- popup for content autocomplete -->
<panel type="autocomplete" id="popup_autocomplete" noautofocus="true"/>
<panel type="autocomplete" id="popup_autocomplete_content" noautofocus="true"/>
<!-- popup for site identity information -->
<panel id="identity-popup" position="after_start" hidden="true" noautofocus="true"
@ -162,7 +194,18 @@
</stack>
</box>
<description id="urlbar-caption" crop="end" flex="1"/>
<textbox id="urlbar-edit" flex="1" hidden="true"/>
<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"/>
@ -175,9 +218,11 @@
<stack id="ui-stack" flex="1">
<hbox id="browser-container" flex="1">
<vbox id="browser" flex="1">
<deckbrowser id="content" autocompletepopup="popup_autocomplete" flex="1"/>
<notificationbox id="notifications" flex="1">
<deckbrowser id="content" autocompletepopup="popup_autocomplete_content" flex="1"/>
</notificationbox>
</vbox>
<vbox id="browser-controls">
<vbox id="browser-controls" collapsed="true">
<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"/>
@ -187,17 +232,13 @@
</vbox>
</hbox>
<vbox id="notifcationbox-container" flex="1" hidden="true">
<notifcationbox id="notifications"/>
</vbox>
<vbox id="urllist-container" flex="1" hidden="true">
<hbox id="urllist-items-container" flex="1">
<richlistbox id="urllist-items" flex="1"/>
</hbox>
<separator class="thin"/>
<hbox id="urllist-search">
<image id="tool-search"/>
<image class="tool-search"/>
</hbox>
</vbox>
@ -250,4 +291,10 @@
</vbox>
</stack>
<vbox id="findpanel-placeholder" sizetopopup="always">
<panel id="findpanel" onpopupshown="Browser.doFind()">
<findbar id="findbar"/>
</panel>
</vbox>
</window>

View File

@ -1,3 +0,0 @@
deckbrowser {
-moz-binding: url("chrome://browser/content/deckbrowser.xml#deckbrowser");
}

View File

@ -34,25 +34,24 @@
this._stack.addEventListener("mousemove", this.stackEventHandler, true);
// zoom
this._stack.addEventListener("dblclick", this.stackEventHandler, true);
// FIXME: dblclicks don't work on the device
// this._stack.addEventListener("dblclick", this.stackEventHandler, true);
this._stack.addEventListener("DOMMouseScroll", this.stackEventHandler, true);
this._scrollStartTimeout = -1;
this._dragStartTimeout = -1;
</constructor>
<field name="dragData">
({
dragging: false,
offX: 0,
offY: 0,
dragX: 0,
dragY: 0,
sX: 0,
sY: 0,
scrollableWidth: 0,
scrollableHeight: 0,
canvasH: 0,
canvasW: 0,
pageX: 0,
pageY: 0
pageY: 0,
oldPageX: 0,
oldPageY: 0
})
</field>
@ -71,12 +70,10 @@
</property>
<method name="updateCanvasState">
<parameter name="aLocationChanged"/>
<parameter name="aNewDoc"/>
<body><![CDATA[
if (aLocationChanged) {
this.dragData.pageX = 0;
this.dragData.pageY = 0;
}
if (aNewDoc)
this._updateViewState();
if (this._updateTimeout)
clearTimeout(this._updateTimeout);
@ -89,10 +86,26 @@
]]></body>
</method>
<method name="_updateViewState">
<body><![CDATA[
// Reset the pan data.
this.dragData.pageX = 0;
this.dragData.pageY = 0;
this._zoomed = false;
// Adjust the zoomLevel to fit the page contents in our window
// width
var [contentWidth, ] = this._contentAreaDimensions;
var canvasRect = this._canvas.getBoundingClientRect();
var canvasWidth = canvasRect.right - canvasRect.left;
this._zoomLevel = canvasWidth / contentWidth;
]]></body>
</method>
<method name="_browserToCanvas">
<body><![CDATA[
this._updateCanvasPosition();
// FIXME: canvas needs to know it's actual width/height
var rect = this._canvas.getBoundingClientRect();
var w = rect.right - rect.left;
@ -104,11 +117,10 @@
ctx.clearRect(0,0,w,h);
//dump("x, y: " + this.dragData.pageX + "," + this.dragData.pageY + "\n");
ctx.save();
ctx.scale(this._zoomLevel, this._zoomLevel);
ctx.drawWindow(this.browser.contentWindow,
-this.dragData.pageX / this._zoomLevel, -this.dragData.pageY / this._zoomLevel,
ctx.drawWindow(this.browser.contentWindow,
this.dragData.pageX, this.dragData.pageY,
w / this._zoomLevel, h / this._zoomLevel,
"white");
ctx.restore();
@ -117,13 +129,15 @@
<method name="_updateCanvasPosition">
<body><![CDATA[
//dump("setting left/top: " + this.dragData.offX + "/" + this.dragData.offY + "\n");
this._canvas.style.marginLeft = this.dragData.offX + "px";
this._canvas.style.marginRight = -this.dragData.offX + "px";
this._canvas.style.marginTop = this.dragData.offY + "px";
this._canvas.style.marginBottom = -this.dragData.offY + "px";
this._canvas.style.marginLeft = this.dragData.dragX + "px";
this._canvas.style.marginRight = -this.dragData.dragX + "px";
this._canvas.style.marginTop = this.dragData.dragY + "px";
this._canvas.style.marginBottom = -this.dragData.dragY + "px";
//window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils).redraw();
// Force a sync redraw
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.redraw();
]]></body>
</method>
@ -149,87 +163,273 @@
]]></body>
</method>
/**
* Retrieve the content element for a given point (relative to the top
* left corner of the browser window).
*/
<method name="elementFromPoint">
<parameter name="aX"/>
<parameter name="aY"/>
<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);
// Reset scroll state
this.browser.contentWindow.scrollTo(0, 0);
return element;
]]></body>
</method>
<method name="zoomToElement">
<parameter name="aElement"/>
<body><![CDATA[
const margin = 0;
// scale to the element's width
var elRect = this._getPagePosition(aElement);
this._zoomLevel = Math.max((this.browser.boxObject.width) / (elRect.width + (2 * margin)),
2);
// pan to the element
this._panTo(Math.max(elRect.x - margin, 0),
Math.max(0, elRect.y - margin));
]]></body>
</method>
<method name="_getPagePosition">
<parameter name="aElement"/>
<body><![CDATA[
var r = aElement.getBoundingClientRect();
var retVal = {
width: r.right - r.left,
height: r.bottom - r.top,
x: r.left,
y: r.top
};
return retVal;
]]></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"/>
<body><![CDATA[
//return;
var cwin = this.browser.contentWindow;
// Scroll the browser so that the event is targeted properly
cwin.scrollTo(-this.dragData.pageX / this._zoomLevel, -this.dragData.pageY / this._zoomLevel);
if (!(aEvent instanceof MouseEvent)) {
Components.utils.reportError("_redispatchMouseEvent called with a non-mouse event");
return;
}
// Scroll the browser so that the event is targeted properly
var [pageOffsetX, pageOffsetY] = this._scrollAndGetOffset();
var cwu = cwin.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
// 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 cwin = this.browser.contentWindow;
var cwu = cwin.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
cwu.sendMouseEvent(aType || aEvent.type,
(aEvent.clientX) / this._zoomLevel,
(aEvent.clientY - browserTop) / this._zoomLevel,
pageOffsetX + clickOffsetX,
pageOffsetY + clickOffsetY,
aEvent.button || 0,
aEvent.clickCount || 1,
aEvent.detail || 1,
0);
// Reset scroll state
cwin.scrollTo(0, 0);
]]></body>
</method>
<method name="_doPan">
<property name="_contentAreaDimensions" readonly="true">
<getter>
var cdoc = this.browser.contentDocument;
// These might not exist yet
var body = cdoc.body || {};
var html = cdoc.documentElement || {};
var w = Math.max(body.scrollWidth, html.scrollWidth);
var h = Math.max(body.scrollHeight, html.scrollHeight);
if (isNaN(w) || isNaN(h))
throw "Can't get content width/height";
return [w, h];
</getter>
</property>
<property name="_effectiveCanvasDimensions" readonly="true">
<getter><![CDATA[
return [this._canvas.width / this._zoomLevel,
this._canvas.height / this._zoomLevel];
]]></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
* the maximum values that can be used for the canvas' .top and .left
* such that it is still within the scrollable area of the page, taking
* into account the current zoomLevel.
*/
<method name="_constrainPanCoords">
<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;
var offscreenWidth = contentAreaWidth - canvasW;
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);
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
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="_moveCanvas">
<parameter name="aDx"/>
<parameter name="aDy"/>
<body><![CDATA[
// constrain offsets to the actual scrollWidth/scrollHeight
var [x, y] = this._constrainPanCoords(aDx, aDy);
var offscreenWidth = this.dragData.scrollableWidth - this.dragData.canvasW;
if (offscreenWidth <= 0) {
// Content is narrower than viewport, no need to pan horizontally
this.dragData.offX = 0;
} else {
var newPageX = Math.max(this.dragData.pageX + aDx, -offscreenWidth);
newPageX = Math.min(newPageX, 0);
var deltaX = newPageX - this.dragData.pageX;
this.dragData.offX = deltaX;
}
var offscreenHeight = this.dragData.scrollableHeight - this.dragData.canvasH;
if (offscreenHeight <= 0) {
// Content is shorter than viewport, no need to pan vertically
this.dragData.offY = 0;
} else {
// min of 0, max of scrollableHeight - canvasHeight
var newPageY = Math.max(this.dragData.pageY + aDy, -offscreenHeight);
newPageY = Math.min(newPageY, 0);
var deltaY = newPageY - this.dragData.pageY;
this.dragData.offY = deltaY;
}
// Canvas needs to move up for content to scroll down
this.dragData.dragX = -x;
this.dragData.dragY = -y;
this._updateCanvasPosition();
]]></body>
</method>
<!-- Pans directly to a given X/Y (in page coordinates) -->
<method name="_panTo">
<parameter name="aX"/>
<parameter name="aY"/>
<body><![CDATA[
var [deltaX, deltaY] = this._constrainPanCoords(aX - this.dragData.pageX,
aY - this.dragData.pageY);
this.dragData.pageX += deltaX;
this.dragData.pageY += deltaY;
this._browserToCanvas();
]]></body>
</method>
<method name="_dragStartTimer">
<body><![CDATA[
this.dragData.lastMouseEvent = Date.now() - 10;
this.dragData.dragging = true;
this._scrollStartTimeout = -1;
this._dragStartTimeout = -1;
]]></body>
</method>
<method name="_endPan">
<body><![CDATA[
// update the pageX/Y coords
this.dragData.pageX += this.dragData.offX;
this.dragData.pageY += this.dragData.offY;
// dragX/dragY are garanteed 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;
// relocate the canvas to 0x0 in the window
this.dragData.offX = 0;
this.dragData.offY = 0;
this.dragData.dragX = 0;
this.dragData.dragY = 0;
// update canvas position and draw the canvas at the new location
this._updateCanvasPosition();
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>
@ -240,7 +440,7 @@
handleEvent: function seh_handleEvent(aEvent) {
if (!aEvent.type in this) {
dump("MouseController called with unknown event type " + aEvent.type + "\n");
Components.reportError("MouseController called with unknown event type " + aEvent.type + "\n");
return;
}
this[aEvent.type](aEvent);
@ -248,37 +448,31 @@
mousedown: function seh_mousedown(aEvent) {
if (aEvent.button != 0)
return false;
return;
// cancel any pending canvas updates, since we're going to update again
if (this._updateTimeout)
clearTimeout(this._updateTimeout);
this.deckbrowser.dragData.canvasW = this.deckbrowser._canvas.width;
this.deckbrowser.dragData.canvasH = this.deckbrowser._canvas.height;
var cdoc = this.deckbrowser.browser.contentDocument;
var body = cdoc.body;
var html = cdoc.documentElement;
this.deckbrowser.dragData.scrollableWidth = Math.max(body.scrollWidth, html.scrollWidth);
this.deckbrowser.dragData.scrollableWidth *= this.deckbrowser._zoomLevel;
this.deckbrowser.dragData.scrollableHeight = Math.max(body.scrollHeight, html.scrollHeight);
this.deckbrowser.dragData.scrollableHeight *= this.deckbrowser._zoomLevel;
var zoomLevel = this.deckbrowser._zoomLevel;
var dragData = this.deckbrowser.dragData;
// The start of the current portion drag
this.deckbrowser.dragData.sX = aEvent.screenX;
this.deckbrowser.dragData.sY = aEvent.screenY;
dragData.sX = aEvent.screenX;
dragData.sY = aEvent.screenY;
// The total delta between current mouse position and sX/sY
this.deckbrowser.dragData.offX = 0;
this.deckbrowser.dragData.offY = 0;
dragData.dragX = 0;
dragData.dragY = 0;
//this.deckbrowser._updateCanvasPosition();
var self = this.deckbrowser;
this.deckbrowser._scrollStartTimeout = setTimeout(function () {
this.deckbrowser._dragStartTimeout = setTimeout(function () {
self._dragStartTimer();
}, 200);
this._lastMouseDown = aEvent;
},
mouseup: function seh_mouseup(aEvent) {
@ -287,12 +481,25 @@
} else if (aEvent.originalTarget == this.deckbrowser._canvas) {
// Mouseup on canvas that isn't releasing from a drag
// cancel scrollStart timer
clearTimeout(this.deckbrowser._scrollStartTimeout);
this.deckbrowser._scrollStartTimeout = -1;
clearTimeout(this.deckbrowser._dragStartTimeout);
this.deckbrowser._dragStartTimeout = -1;
// send mousedown & mouseup
this.deckbrowser._redispatchMouseEvent(aEvent, "mousedown");
this.deckbrowser._redispatchMouseEvent(this._lastMouseDown);
this._lastMouseDown = null;
this.deckbrowser._redispatchMouseEvent(aEvent);
// FIXME: dblclick events don't fire on the n810, check to see if
// we should treat this as a double-click
if (this._lastMouseUp &&
(aEvent.timeStamp - this._lastMouseUp.timeStamp) < 400 &&
Math.abs(aEvent.clientX - this._lastMouseUp.clientX) < 30 &&
Math.abs(aEvent.clientY - this._lastMouseUp.clientY) < 30) {
this.dblclick(aEvent);
return;
}
this._lastMouseUp = aEvent;
}
},
@ -300,20 +507,30 @@
if (!this.deckbrowser.dragData.dragging) {
// If we've moved more than N pixels lets go ahead and assume we're dragging
// and not wait for the timeout to complete.
if (this.deckbrowser._scrollStartTimeout != -1 &&
if (this.deckbrowser._dragStartTimeout != -1 &&
(Math.abs(this.deckbrowser.dragData.sX - aEvent.screenX) > 10 ||
Math.abs(this.deckbrowser.dragData.sY - aEvent.screenY) > 10)) {
clearTimeout(this.deckbrowser._scrollStartTimeout);
clearTimeout(this.deckbrowser._dragStartTimeout);
this.deckbrowser._dragStartTimer();
} else {
return false;
}
}
var dx = aEvent.screenX - this.deckbrowser.dragData.sX;
var dy = aEvent.screenY - this.deckbrowser.dragData.sY;
var dx = this.deckbrowser.dragData.sX - aEvent.screenX;
var dy = this.deckbrowser.dragData.sY - aEvent.screenY;
this.deckbrowser._doPan(dx, dy);
// Filter out noise in big panning operations which are
// almost certainly intended to be on-axis horizontal or
// vertical pans.
if (Math.abs(dx) > 40 || Math.abs(dy) > 40) {
if (Math.abs(dx/dy) < 0.3) // dx is a lot less than dy, probably a vertical drag
dx = 0;
else if (Math.abs(dy/dx) < 0.3) // probably a horizontal drag
dy = 0;
}
this.deckbrowser._moveCanvas(dx, dy);
if (Date.now() - this.deckbrowser.dragData.lastMouseEvent < 75) { // FIXME: make this a constant
//dump("dropping event\n");
@ -323,26 +540,33 @@
this.deckbrowser.dragData.lastMouseEvent = Date.now();
aEvent.preventDefault();
return true;
return true;
},
DOMMouseScroll: function seh_DOMMouseScroll(aEvent) {
this.deckbrowser.zoom(aEvent.detail);
},
dblclick: function seh_dblclick(aEvent) {
//dump("Zooming...\n");
var x = aEvent.clientX;
var y = aEvent.clientY;
var target = aEvent.originalTarget;
var dragData = this.deckbrowser.dragData;
if (this.deckbrowser._zoomed) {
this.deckbrowser._zoomLevel = 1;
// reset zoom, pan state
this.deckbrowser._zoomLevel = this._oldZoomLevel;
[dragData.pageX, dragData.pageY] = [dragData.oldPageX, dragData.oldPageY];
this.deckbrowser._browserToCanvas();
this.deckbrowser._zoomed = false;
} else {
this.deckbrowser._zoomLevel = 2;
// Remember pageX/pageY
[dragData.oldPageX, dragData.oldPageY] = [dragData.pageX, dragData.pageY];
this._oldZoomLevel = this.deckbrowser._zoomLevel;
var element = this.deckbrowser.elementFromPoint(aEvent.clientX, aEvent.clientY);
this.deckbrowser.zoomToElement(element);
this.deckbrowser._zoomed = true;
}
this.deckbrowser._browserToCanvas();
}
});
]]>

View File

@ -0,0 +1,30 @@
<?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="autocomplete-aligned" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
<implementation>
<method name="openPopup">
<body><![CDATA[
this.popup.openAutocompletePopup(this, document.getElementById("toolbar-main"));
]]></body>
</method>
<method name="closePopup">
<body><![CDATA[
// do nothing
]]></body>
</method>
<method name="reallyClosePopup">
<body><![CDATA[
this.mConsumeRollupEvent = false;
this.popup.closePopup();
]]></body>
</method>
</implementation>
</binding>
</bindings>

View File

@ -6,8 +6,9 @@ browser.jar:
content/browser.js (content/browser.js)
content/browser-ui.js (content/browser-ui.js)
content/commandUtil.js (content/commandUtil.js)
content/urlbar.xml (content/urlbar.xml)
content/deckbrowser.xml (content/deckbrowser.xml)
content/deckbrowser.css (content/deckbrowser.css)
content/browser.css (content/browser.css)
content/scrollbars.css (content/scrollbars.css)
content/content.css (content/content.css)
* content/shortcuts.js
@ -24,14 +25,18 @@ classic.jar:
images/default-favicon.png (skin/images/default-favicon.png)
images/identity.png (skin/images/identity.png)
images/starred48.png (skin/images/starred48.png)
images/page-starred.png (skin/images/page-starred.png)
images/tag.png (skin/images/tag.png)
images/throbber.png (skin/images/throbber.png)
images/throbber.gif (skin/images/throbber.gif)
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/mono-sidebar.png (skin/images/mono-sidebar.png)
@AB_CD@.jar:
% locale browser @AB_CD@ %
browser.dtd (locale/@AB_CD@/browser.dtd)
browser.properties (locale/@AB_CD@/browser.properties)
shortcuts.properties (locale/@AB_CD@/shortcuts.properties)
search.properties (locale/@AB_CD@/search.properties)
region.properties (locale/@AB_CD@/region.properties)

View File

@ -31,6 +31,14 @@
<!ENTITY bookmarkCancel.label "Cancel">
<!ENTITY bookmarkDone.label "Done">
<!ENTITY findOnCmd.label "Find in This Page…">
<!ENTITY findOnCmd.accesskey "F">
<!ENTITY findOnCmd.commandkey "f">
<!ENTITY findAgainCmd.label "Find Again">
<!ENTITY findAgainCmd.accesskey "g">
<!ENTITY findAgainCmd.commandkey "g">
<!ENTITY findAgainCmd.commandkey2 "VK_F3">
<!ENTITY identity.unverifiedsite2 "This web site does not supply identity information.">
<!ENTITY identity.connectedTo "You are connected to">
<!-- Localization note (identity.runBy) : This string appears between a

View File

@ -1,11 +1,27 @@
# Popup Blocker
popupWarning=%S prevented this site from opening a pop-up window.
popupWarningMultiple=%S prevented this site from opening %S pop-up windows.
popupButtonAlwaysAllow=Always Allow
popupButtonAlwaysAllow.accesskey=A
popupButtonNeverWarn=Never tell me
popupButtonNeverWarn.accesskey=N
# Site Identity
identity.identified.verifier=Verified by: %S
identity.identified.verified_by_you=You have added a security exception for this site
identity.identified.state_and_country=%S, %S
identity.identified.title_with_country=%S (%S)
identity.encrypted=Your connection to this web site is encrypted to prevent eavesdropping.
identity.unencrypted=Your connection to this web site is not encrypted.
identity.unknown.tooltip=This web site does not supply identity information.
identity.ownerUnknown2=(unknown)
# Geolocation UI
gelocation.exactLocation=Exact Location (within 10 feet)
gelocation.exactLocationKey=E
gelocation.neighborhoodLocation=Neighborhood (within 1 mile)
gelocation.neighborhoodLocationKey=N
gelocation.nothingLocation=Nothing
gelocation.nothingLocationKey=C
geolocation.requestMessage=%S wants to know where you are. Tell them:

View File

@ -0,0 +1,34 @@
# Default search engine
browser.search.defaultenginename=Google
# Search engine order (order displayed in the search bar dropdown)s
browser.search.order.1=Google
browser.search.order.2=Yahoo
# This is the default set of web based feed handlers shown in the reader
# selection UI
browser.contentHandlers.types.0.title=Bloglines
browser.contentHandlers.types.0.uri=http://www.bloglines.com/login?r=/sub/%s
browser.contentHandlers.types.1.title=My Yahoo
browser.contentHandlers.types.1.uri=http://add.my.yahoo.com/rss?url=%s
browser.contentHandlers.types.2.title=Google
browser.contentHandlers.types.2.uri=http://fusion.google.com/add?feedurl=%s
# Keyword URL (for location bar searches)
keyword.URL=http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=
# increment this number when anything gets changed in the list below. This will
# cause Firefox to re-read these prefs and inject any new handlers into the
# profile database. Note that "new" is defined as "has a different URL"; this
# means that it's not possible to update the name of existing handler, so
# don't make any spelling errors here.
gecko.handlerService.defaultHandlersVersion=1
# The default set of protocol handlers for webcal:
gecko.handlerService.schemes.webcal.0.name=30 Boxes
gecko.handlerService.schemes.webcal.0.uriTemplate=http://30boxes.com/external/widget?refer=ff&url=%s
# The default set of protocol handlers for mailto:
gecko.handlerService.schemes.mailto.0.name=Yahoo! Mail
gecko.handlerService.schemes.mailto.0.uriTemplate=http://compose.mail.yahoo.com/?To=%s

View File

@ -0,0 +1,25 @@
searchtip=Search using %S
cmd_clearHistory=Clear Search History
cmd_clearHistory_accesskey=C
cmd_showSuggestions=Show Suggestions
cmd_showSuggestions_accesskey=S
addEngineConfirmTitle=Add Search Engine
addEngineConfirmation=Add "%S" to the list of engines available in the search bar?\n\nFrom: %S
addEngineUseNowText=Start &using it right away
addEngineAddButtonLabel=Add
error_loading_engine_title=Download Error
# LOCALIZATION NOTE (error_loading_engine_msg2): %1$S = brandShortName, %2$S = location
error_loading_engine_msg2=%S could not download the search plugin from:\n%S
error_duplicate_engine_msg=%S could not install the search plugin from "%S" because an engine with the same name already exists.
error_invalid_engine_title=Install Error
# LOCALIZATION NOTE (error_invalid_engine_msg): %S = brandShortName
error_invalid_engine_msg=This search engine isn't supported by %S and can't be installed.
cmd_addFoundEngine=Add "%S"
suggestion_label=Suggestions

View File

@ -87,25 +87,28 @@ toolbarbutton[open="true"] {
}
#toolbar-main {
-moz-appearance: none;
-moz-box-align: center;
background: url("chrome://browser/skin/images/toolbar-background.png") repeat-x top left;
background-image: url("chrome://browser/skin/images/toolbar-background.png");
background-repeat: repeat-x;
background-position: top left;
padding: 8px;
}
toolbarbutton.urlbar-icon-button {
list-style-image: url("chrome://browser/skin/images/mono-toolbar.png");
list-style-image: url("chrome://browser/skin/images/toolbar.png");
}
#tool-reload {
-moz-image-region: rect(0px 108px 36px 72px);
-moz-image-region: rect(6px 302px 32px 275px);
}
#tool-stop {
-moz-image-region: rect(0px 216px 36px 180px);
-moz-image-region: rect(7px 336px 32px 311px);
}
#tool-go {
-moz-image-region: rect(0px 72px 36px 36px);
-moz-image-region: rect(7px 368px 32px 346px);
}
#browser-controls {
@ -113,36 +116,46 @@ toolbarbutton.urlbar-icon-button {
}
toolbarbutton.browser-control-button {
list-style-image: url("chrome://browser/skin/images/mono-sidebar.png");
list-style-image: url("chrome://browser/skin/images/toolbar.png");
}
#tool-star {
-moz-image-region: rect(180px 59px 239px 0px);
-moz-image-region: rect(2px 151px 39px 113px);
}
#tool-star[starred="true"] {
-moz-image-region: rect(120px 59px 179px 0px);
-moz-image-region: rect(121px 151px 158px 113px);
}
#tool-back {
-moz-image-region: rect(0px 59px 59px 0px);
padding-bottom: 0px;
-moz-image-region: rect(0px 58px 58px 0px);
padding-bottom: 0px !important;
}
#tool-back[disabled="true"] {
-moz-image-region: rect(58px 58px 116px 0px);
padding-bottom: 0px !important;
}
#tool-forward {
-moz-image-region: rect(60px 59px 119px 0px);
padding-top: 0px;
-moz-image-region: rect(0px 108px 37px 60px);
padding-top: 0px !important;
}
#tool-forward[disabled="true"] {
-moz-image-region: rect(58px 108px 95px 60px);
padding-top: 0px !important;
}
#tool-bookmarks {
-moz-image-region: rect(240px 59px 299px 0px);
-moz-image-region: rect(1px 190px 37px 160px);
}
#tool-actions {
-moz-image-region: rect(300px 59px 359px 0px);
-moz-image-region: rect(0px 242px 45px 197px);
}
#tool-search {
.tool-search {
list-style-image: url("chrome://browser/skin/images/mono-toolbar.png");
-moz-image-region: rect(0px 36px 36px 0px);
}
@ -208,7 +221,7 @@ toolbarbutton.browser-control-button {
padding: 8px;
}
#urllist-items {
#urllist-items, .autocomplete-richlistbox {
-moz-appearance: none !important;
background-color: rgba(207,207,207,0.9);
border: 2px solid #fff !important;
@ -226,13 +239,71 @@ toolbarbutton.browser-control-button {
height: 24px;
}
#urllist-search {
#urllist-search, #autocomplete_navbuttons {
background-color: rgba(207,207,207,0.9);
border: 2px solid #fff !important;
-moz-border-radius: 10px;
_moz-box-align: start;
}
/* autocomplete */
#popup_autocomplete {
moz-appearance: none;
background-color: rgba(207,207,207,0.9);
}
#autocomplete_navbuttons {
margin-top: 12px;
}
#PopupAutoCompleteRichResult {
direction: ltr !important;
}
.ac-result-type-bookmark {
list-style-image: url("chrome://browser/skin/images/page-starred.png");
width: 16px;
height: 16px;
}
.ac-result-type-tag {
list-style-image: url("chrome://browser/skin/images/tag.png");
width: 16px;
height: 16px;
}
.ac-comment {
font-size: 1.15em;
}
.ac-extra > .ac-comment {
font-size: inherit;
}
.ac-url-box {
display: none;
}
.ac-url-text {
color: GrayText;
}
.ac-comment[selected="true"], .ac-url-text[selected="true"] {
color: inherit !important;
}
/* find bar */
#findpanel {
padding: 0 !important;
-moz-appearance: none;
background: transparent;
}
findbar {
background: rgba(128, 128, 128, 0.75);
}
/* Bookmark editor */
#bookmark-container {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

BIN
mobile/chrome/skin/images/tag.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -37,7 +37,7 @@
MOZ_APP_NAME=fennec
MOZ_APP_DISPLAYNAME=Fennec
MOZ_APP_VERSION=0.4
MOZ_APP_VERSION=0.5
MOZ_XUL_APP=1
MOZ_UPDATER=0

View File

@ -76,12 +76,7 @@ deb:
$(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
ifdef NS_HILDON
$(NSINSTALL) $(DEPTH)/dist/bin/components/softkey.xpt $(DEBDESTDIR)/usr/local/$(MOZ_APP_NAME)/components/
$(NSINSTALL) $(DEPTH)/dist/bin/components/libsoftkey.so $(DEBDESTDIR)/usr/local/$(MOZ_APP_NAME)/components/
$(NSINSTALL) $(DEPTH)/dist/bin/libsoftokn3.* $(DEBDESTDIR)/usr/local/$(MOZ_APP_NAME)/
endif
#$(NSINSTALL) -m 755 debian/postinst debian/$(MOZ_APP_NAME)/DEBIAN
# $(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
endif