зеркало из https://github.com/mozilla/gecko-dev.git
bug 441794: merge back to main line
This commit is contained in:
Коммит
6fb744ecd9
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
deckbrowser {
|
||||
-moz-binding: url("chrome://browser/content/deckbrowser.xml#deckbrowser");
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
]]>
|
||||
|
|
|
@ -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>
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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 {
|
||||
|
|
Двоичные данные
mobile/chrome/skin/images/mono-sidebar.png
Двоичные данные
mobile/chrome/skin/images/mono-sidebar.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 6.4 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 718 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 517 B |
Двоичные данные
mobile/chrome/skin/images/toolbar-background.png
Двоичные данные
mobile/chrome/skin/images/toolbar-background.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 746 B После Ширина: | Высота: | Размер: 675 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 13 KiB |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче