Merge from mozilla-central.
|
@ -461,24 +461,24 @@ nsAccUtils::TextLength(nsAccessible *aAccessible)
|
|||
}
|
||||
|
||||
bool
|
||||
nsAccUtils::MustPrune(nsIAccessible *aAccessible)
|
||||
nsAccUtils::MustPrune(nsAccessible* aAccessible)
|
||||
{
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
roles::Role role = aAccessible->Role();
|
||||
|
||||
// We don't prune buttons any more however AT don't expect children inside of
|
||||
// button in general, we allow menu buttons to have children to make them
|
||||
// accessible.
|
||||
return role == nsIAccessibleRole::ROLE_MENUITEM ||
|
||||
role == nsIAccessibleRole::ROLE_COMBOBOX_OPTION ||
|
||||
role == nsIAccessibleRole::ROLE_OPTION ||
|
||||
role == nsIAccessibleRole::ROLE_ENTRY ||
|
||||
role == nsIAccessibleRole::ROLE_FLAT_EQUATION ||
|
||||
role == nsIAccessibleRole::ROLE_PASSWORD_TEXT ||
|
||||
role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_GRAPHIC ||
|
||||
role == nsIAccessibleRole::ROLE_SLIDER ||
|
||||
role == nsIAccessibleRole::ROLE_PROGRESSBAR ||
|
||||
role == nsIAccessibleRole::ROLE_SEPARATOR;
|
||||
return role == roles::MENUITEM ||
|
||||
role == roles::COMBOBOX_OPTION ||
|
||||
role == roles::OPTION ||
|
||||
role == roles::ENTRY ||
|
||||
role == roles::FLAT_EQUATION ||
|
||||
role == roles::PASSWORD_TEXT ||
|
||||
role == roles::TOGGLE_BUTTON ||
|
||||
role == roles::GRAPHIC ||
|
||||
role == roles::SLIDER ||
|
||||
role == roles::PROGRESSBAR ||
|
||||
role == roles::SEPARATOR;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -295,7 +295,7 @@ public:
|
|||
* Return true if the given accessible can't have children. Used when exposing
|
||||
* to platform accessibility APIs, should the children be pruned off?
|
||||
*/
|
||||
static bool MustPrune(nsIAccessible *aAccessible);
|
||||
static bool MustPrune(nsAccessible* aAccessible);
|
||||
|
||||
/**
|
||||
* Search hint enum constants. Used by GetHeaderCellsFor() method.
|
||||
|
|
|
@ -392,11 +392,17 @@ pref("browser.link.open_newwindow", 3);
|
|||
// 2: don't divert window.open with features
|
||||
pref("browser.link.open_newwindow.restriction", 0);
|
||||
|
||||
// Enable browser frames (including OOP), but make in-process browser frames
|
||||
// the default.
|
||||
// Enable browser frames (including OOP, except on Windows, where it doesn't
|
||||
// work), but make in-process browser frames the default.
|
||||
pref("dom.mozBrowserFramesEnabled", true);
|
||||
pref("dom.mozBrowserFramesWhitelist", "http://homescreen.gaiamobile.org,http://browser.gaiamobile.org");
|
||||
|
||||
#ifdef XP_WIN
|
||||
pref("dom.ipc.tabs.disabled", true);
|
||||
#else
|
||||
pref("dom.ipc.tabs.disabled", false);
|
||||
#endif
|
||||
|
||||
pref("dom.ipc.browser_frames.oop_by_default", false);
|
||||
|
||||
// Temporary permission hack for WebSMS
|
||||
|
|
|
@ -179,7 +179,10 @@ var shell = {
|
|||
if (!audioManager)
|
||||
return;
|
||||
|
||||
let volume = audioManager.masterVolume + delta / steps;
|
||||
let currentVolume = audioManager.masterVolume;
|
||||
let newStep = Math.round(steps * Math.sqrt(currentVolume)) + delta;
|
||||
let volume = (newStep / steps) * (newStep / steps);
|
||||
|
||||
if (volume > 1)
|
||||
volume = 1;
|
||||
if (volume < 0)
|
||||
|
|
|
@ -16,6 +16,7 @@ PARALLEL_DIRS = \
|
|||
locales \
|
||||
modules \
|
||||
themes \
|
||||
extensions \
|
||||
$(NULL)
|
||||
|
||||
DIRS = \
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
_CodeSignature/CodeResources
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^Info.plist$</key>
|
||||
<true/>
|
||||
<key>^PkgInfo$</key>
|
||||
<true/>
|
||||
<key>^MacOS/</key>
|
||||
<true/>
|
||||
<key>^Resources/</key>
|
||||
<true/>
|
||||
<key>^MacOS/extensions/.*</key><dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>^MacOS/distribution/.*</key><dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>^MacOS/updates/.*</key><dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>^MacOS/active-update.xml$</key><dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>^MacOS/defaults/.*</key><dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>^MacOS/mozilla.cfg$</key><dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>^MacOS/updates.xml$</key><dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -14,7 +14,6 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
DIRS = \
|
||||
{972ce4c6-7e08-4474-a285-3208198ce6fd} \
|
||||
uriloader@pdf.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
APPEXT = $(call core_abspath,$(DIST))/bin/extensions
|
||||
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# Using the extension-files as an extension files whitelist to avoid noise
|
||||
# in the xpi file such as MOZILLA.readme, install.pdf.in and this make file.
|
||||
FILES := $(shell cat $(srcdir)/extension-files)
|
||||
|
||||
libs::
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(srcdir)/install.rdf.in > install.rdf
|
||||
$(ZIP) -9X $(APPEXT)/uriloader@pdf.js.xpi install.rdf
|
||||
cd $(call core_abspath,$(srcdir)) && \
|
||||
$(ZIP) -9X $(APPEXT)/uriloader@pdf.js.xpi $(FILES)
|
||||
|
||||
install::
|
||||
$(SYSINSTALL) $(IFLAGS1) $(APPEXT)/uriloader@pdf.js.xpi $(DESTDIR)$(mozappdir)/extensions
|
||||
|
||||
GARBAGE += install.rdf
|
|
@ -59,9 +59,8 @@ pref("extensions.hotfix.id", "firefox-hotfix@mozilla.org");
|
|||
pref("extensions.hotfix.cert.checkAttributes", true);
|
||||
pref("extensions.hotfix.certs.1.sha1Fingerprint", "F1:DB:F9:6A:7B:B8:04:FA:48:3C:16:95:C7:2F:17:C6:5B:C2:9F:45");
|
||||
|
||||
// Disable add-ons installed into the shared user and shared system areas by
|
||||
// default. This does not include the application directory. See the SCOPE
|
||||
// constants in AddonManager.jsm for values to use here
|
||||
// Disable add-ons that are not installed by the user in all scopes by default.
|
||||
// See the SCOPE constants in AddonManager.jsm for values to use here.
|
||||
pref("extensions.autoDisableScopes", 15);
|
||||
|
||||
// Dictionary download preference
|
||||
|
@ -146,6 +145,10 @@ pref("app.update.mode", 1);
|
|||
// If set to true, the Update Service will present no UI for any event.
|
||||
pref("app.update.silent", false);
|
||||
|
||||
// If set to true, the Update Service will apply updates in the background
|
||||
// when it finishes downloading them.
|
||||
pref("app.update.stage.enabled", true);
|
||||
|
||||
// Update service URL:
|
||||
pref("app.update.url", "https://aus3.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
|
||||
// app.update.url.manual is in branding section
|
||||
|
@ -1027,7 +1030,7 @@ pref("devtools.layoutview.enabled", false);
|
|||
pref("devtools.layoutview.open", false);
|
||||
|
||||
// Enable the Debugger
|
||||
pref("devtools.debugger.enabled", false);
|
||||
pref("devtools.debugger.enabled", true);
|
||||
pref("devtools.debugger.remote-enabled", false);
|
||||
pref("devtools.debugger.remote-host", "localhost");
|
||||
pref("devtools.debugger.remote-port", 6000);
|
||||
|
|
|
@ -122,6 +122,12 @@ function appUpdater()
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.isApplied) {
|
||||
this.setupUpdateButton("update.restart." +
|
||||
(this.isMajor ? "upgradeButton" : "restartButton"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isDownloading) {
|
||||
this.startDownload();
|
||||
return;
|
||||
|
@ -151,6 +157,16 @@ appUpdater.prototype =
|
|||
this.um.activeUpdate.state == "pending-service");
|
||||
},
|
||||
|
||||
// true when there is an update already installed in the background.
|
||||
get isApplied() {
|
||||
if (this.update)
|
||||
return this.update.state == "applied" ||
|
||||
this.update.state == "applied-service";
|
||||
return this.um.activeUpdate &&
|
||||
(this.um.activeUpdate.state == "applied" ||
|
||||
this.um.activeUpdate.state == "applied-service");
|
||||
},
|
||||
|
||||
// true when there is an update download in progress.
|
||||
get isDownloading() {
|
||||
if (this.update)
|
||||
|
@ -181,6 +197,12 @@ appUpdater.prototype =
|
|||
return true; // Firefox default is true
|
||||
},
|
||||
|
||||
// true when updating in background is enabled.
|
||||
get backgroundUpdateEnabled() {
|
||||
return this.updateEnabled &&
|
||||
Services.prefs.getBoolPref("app.update.stage.enabled");
|
||||
},
|
||||
|
||||
// true when updating is automatic.
|
||||
get updateAuto() {
|
||||
try {
|
||||
|
@ -220,7 +242,7 @@ appUpdater.prototype =
|
|||
* Handles oncommand for the update button.
|
||||
*/
|
||||
buttonOnCommand: function() {
|
||||
if (this.isPending) {
|
||||
if (this.isPending || this.isApplied) {
|
||||
// Notify all windows that an application quit has been requested.
|
||||
let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
|
||||
createInstance(Components.interfaces.nsISupportsPRBool);
|
||||
|
@ -505,9 +527,34 @@ appUpdater.prototype =
|
|||
break;
|
||||
case Components.results.NS_OK:
|
||||
this.removeDownloadListener();
|
||||
if (this.backgroundUpdateEnabled) {
|
||||
this.selectPanel("applying");
|
||||
let update = this.um.activeUpdate;
|
||||
let self = this;
|
||||
let timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function () {
|
||||
// Update the UI when the background updater is finished
|
||||
let status = update.state;
|
||||
if (status == "applied" || status == "applied-service") {
|
||||
self.selectPanel("updateButtonBox");
|
||||
self.setupUpdateButton("update.restart." +
|
||||
(self.isMajor ? "upgradeButton" : "restartButton"));
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
} else if (status == "failed") {
|
||||
// Background update has failed, let's show the UI responsible for
|
||||
// prompting the user to update manually.
|
||||
self.selectPanel("downloadFailed");
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
}
|
||||
}, 500, timer.TYPE_REPEATING_SLACK);
|
||||
} else {
|
||||
this.selectPanel("updateButtonBox");
|
||||
this.setupUpdateButton("update.restart." +
|
||||
(this.isMajor ? "upgradeButton" : "updateButton"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.removeDownloadListener();
|
||||
|
|
|
@ -64,6 +64,9 @@
|
|||
<hbox id="downloading" align="center">
|
||||
<image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
|
||||
</hbox>
|
||||
<hbox id="applying" align="center">
|
||||
<image class="update-throbber"/><label>&update.applying;</label>
|
||||
</hbox>
|
||||
<hbox id="downloadFailed" align="center">
|
||||
<label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
|
||||
</hbox>
|
||||
|
|
|
@ -4184,7 +4184,7 @@ var FullScreen = {
|
|||
cancelWarning: function(event) {
|
||||
if (!this.warningBox)
|
||||
return;
|
||||
this.fullscreenDocUri = null;
|
||||
this.fullscreenDoc = null;
|
||||
this.warningBox.removeEventListener("transitionend", this);
|
||||
if (this.warningFadeOutTimeout) {
|
||||
clearTimeout(this.warningFadeOutTimeout);
|
||||
|
@ -4204,21 +4204,28 @@ var FullScreen = {
|
|||
},
|
||||
|
||||
setFullscreenAllowed: function(isApproved) {
|
||||
let remember = document.getElementById("full-screen-remember-decision").checked;
|
||||
if (remember)
|
||||
Services.perms.add(this.fullscreenDocUri,
|
||||
// The "remember decision" checkbox is hidden when showing for documents that
|
||||
// the permission manager can't handle (documents with URIs without a host).
|
||||
// We simply require those to be approved every time instead.
|
||||
let rememberCheckbox = document.getElementById("full-screen-remember-decision");
|
||||
let uri = this.fullscreenDoc.nodePrincipal.URI;
|
||||
if (!rememberCheckbox.hidden) {
|
||||
if (rememberCheckbox.checked)
|
||||
Services.perms.add(uri,
|
||||
"fullscreen",
|
||||
isApproved ? Services.perms.ALLOW_ACTION : Services.perms.DENY_ACTION,
|
||||
Services.perms.EXPIRE_NEVER);
|
||||
else if (isApproved) {
|
||||
// The user has only temporarily approved fullscren for this domain.
|
||||
// Add the permission (so Gecko knows fullscreen is approved) but add a
|
||||
// listener to remove the permission when the chrome document exits fullscreen.
|
||||
Services.perms.add(this.fullscreenDocUri,
|
||||
// The user has only temporarily approved fullscren for this fullscreen
|
||||
// session only. Add the permission (so Gecko knows to approve any further
|
||||
// fullscreen requests for this host in this fullscreen session) but add
|
||||
// a listener to revoke the permission when the chrome document exits
|
||||
// fullscreen.
|
||||
Services.perms.add(uri,
|
||||
"fullscreen",
|
||||
Services.perms.ALLOW_ACTION,
|
||||
Services.perms.EXPIRE_SESSION);
|
||||
let host = this.fullscreenDocUri.host;
|
||||
let host = uri.host;
|
||||
function onFullscreenchange(event) {
|
||||
if (event.target == document && document.mozFullScreenElement == null) {
|
||||
// The chrome document has left fullscreen. Remove the temporary permission grant.
|
||||
|
@ -4228,15 +4235,21 @@ var FullScreen = {
|
|||
}
|
||||
document.addEventListener("mozfullscreenchange", onFullscreenchange);
|
||||
}
|
||||
}
|
||||
if (this.warningBox)
|
||||
this.warningBox.setAttribute("fade-warning-out", "true");
|
||||
if (!isApproved)
|
||||
// If the document has been granted fullscreen, notify Gecko so it can resume
|
||||
// any pending pointer lock requests, otherwise exit fullscreen; the user denied
|
||||
// the fullscreen request.
|
||||
if (isApproved)
|
||||
Services.obs.notifyObservers(this.fullscreenDoc, "fullscreen-approved", "");
|
||||
else
|
||||
document.mozCancelFullScreen();
|
||||
},
|
||||
|
||||
warningBox: null,
|
||||
warningFadeOutTimeout: null,
|
||||
fullscreenDocUri: null,
|
||||
fullscreenDoc: null,
|
||||
|
||||
// Shows the fullscreen approval UI, or if the domain has already been approved
|
||||
// for fullscreen, shows a warning that the site has entered fullscreen for a short
|
||||
|
@ -4247,15 +4260,37 @@ var FullScreen = {
|
|||
return;
|
||||
|
||||
// Set the strings on the fullscreen approval UI.
|
||||
this.fullscreenDocUri = targetDoc.nodePrincipal.URI;
|
||||
this.fullscreenDoc = targetDoc;
|
||||
let uri = this.fullscreenDoc.nodePrincipal.URI;
|
||||
let host = null;
|
||||
try {
|
||||
host = uri.host;
|
||||
} catch (e) { }
|
||||
let hostLabel = document.getElementById("full-screen-domain-text");
|
||||
let rememberCheckbox = document.getElementById("full-screen-remember-decision");
|
||||
let isApproved = false;
|
||||
if (host) {
|
||||
// Document's principal's URI has a host. Display a warning including the hostname and
|
||||
// show UI to enable the user to permanently grant this host permission to enter fullscreen.
|
||||
let utils = {};
|
||||
Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
|
||||
let [displayHost, fullHost] = utils.DownloadUtils.getURIHost(this.fullscreenDocUri.spec);
|
||||
let displayHost = utils.DownloadUtils.getURIHost(uri.spec)[0];
|
||||
let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
|
||||
let domainText = bundle.formatStringFromName("fullscreen.entered", [displayHost], 1);
|
||||
document.getElementById("full-screen-domain-text").textContent = domainText;
|
||||
let rememberText = bundle.formatStringFromName("fullscreen.rememberDecision", [displayHost], 1);
|
||||
document.getElementById("full-screen-remember-decision").label = rememberText;
|
||||
|
||||
hostLabel.textContent = bundle.formatStringFromName("fullscreen.entered", [displayHost], 1);
|
||||
hostLabel.removeAttribute("hidden");
|
||||
|
||||
rememberCheckbox.label = bundle.formatStringFromName("fullscreen.rememberDecision", [displayHost], 1);
|
||||
rememberCheckbox.checked = false;
|
||||
rememberCheckbox.removeAttribute("hidden");
|
||||
|
||||
// Note we only allow documents whose principal's URI has a host to
|
||||
// store permission grants.
|
||||
isApproved = Services.perms.testPermission(uri, "fullscreen") == Services.perms.ALLOW_ACTION;
|
||||
} else {
|
||||
hostLabel.setAttribute("hidden", "true");
|
||||
rememberCheckbox.setAttribute("hidden", "true");
|
||||
}
|
||||
|
||||
// Note: the warning box can be non-null if the warning box from the previous request
|
||||
// wasn't hidden before another request was made.
|
||||
|
@ -4269,11 +4304,10 @@ var FullScreen = {
|
|||
// If fullscreen mode has not yet been approved for the fullscreen
|
||||
// document's domain, show the approval UI and don't auto fade out the
|
||||
// fullscreen warning box. Otherwise, we're just notifying of entry into
|
||||
// fullscreen mode.
|
||||
let isApproved =
|
||||
Services.perms.testPermission(this.fullscreenDocUri, "fullscreen") == Services.perms.ALLOW_ACTION;
|
||||
// fullscreen mode. Note if the resource's host is null, we must be
|
||||
// showing a local file or a local data URI, and we require explicit
|
||||
// approval every time.
|
||||
let authUI = document.getElementById("full-screen-approval-pane");
|
||||
document.getElementById("full-screen-remember-decision").checked = false;
|
||||
if (isApproved)
|
||||
authUI.setAttribute("hidden", "true");
|
||||
else {
|
||||
|
|
|
@ -780,8 +780,16 @@ function saveMedia()
|
|||
var item = getSelectedImage(tree);
|
||||
var url = gImageView.data[tree.currentIndex][COL_IMAGE_ADDRESS];
|
||||
|
||||
if (url)
|
||||
saveURL(url, null, "SaveImageTitle", false, false, makeURI(item.baseURI));
|
||||
if (url) {
|
||||
var titleKey = "SaveImageTitle";
|
||||
|
||||
if (item instanceof HTMLVideoElement)
|
||||
titleKey = "SaveVideoTitle";
|
||||
else if (item instanceof HTMLAudioElement)
|
||||
titleKey = "SaveAudioTitle";
|
||||
|
||||
saveURL(url, null, titleKey, false, false, makeURI(item.baseURI));
|
||||
}
|
||||
}
|
||||
else {
|
||||
var odir = selectSaveFolder();
|
||||
|
|
|
@ -11,11 +11,9 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MODULE = browserabout
|
||||
LIBRARY_NAME = browserabout_s
|
||||
FORCE_STATIC_LIB = 1
|
||||
ifndef MOZ_MEMORY
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
USE_STATIC_LIBS = 1
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/browser
|
||||
|
||||
|
|
|
@ -16,11 +16,7 @@ IS_COMPONENT = 1
|
|||
MODULE_NAME = nsBrowserCompsModule
|
||||
FORCE_SHARED_LIB = 1
|
||||
|
||||
# Statically link the CRT on Windows if building against
|
||||
# a XULRunner SDK.
|
||||
ifdef LIBXUL_SDK
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
EXPORTS = nsBrowserCompsCID.h
|
||||
|
||||
|
@ -56,7 +52,7 @@ endif
|
|||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(call EXPAND_LIBNAME_PATH,unicharutil_external_s,$(LIBXUL_DIST)/lib) \
|
||||
$(XPCOM_GLUE_LDOPTS) \
|
||||
$(XPCOM_STATICRUNTIME_GLUE_LDOPTS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -15,12 +15,7 @@ LIBRARY_NAME = browserdir_s
|
|||
TEST_DIRS += tests
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
# Because we are an application component, link against the CRT statically
|
||||
# (on Windows, but only if we're not building our own CRT for jemalloc)
|
||||
ifndef MOZ_MEMORY
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/browser
|
||||
EXPORTS_mozilla/browser = DirectoryProvider.h
|
||||
|
|
|
@ -11,10 +11,9 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MODULE = browser_feeds
|
||||
LIBRARY_NAME = browser_feeds_s
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
ifndef MOZ_MEMORY
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
DEFINES += \
|
||||
-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
|
||||
|
|
|
@ -11,10 +11,9 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MODULE = migration
|
||||
LIBRARY_NAME = migration_s
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
ifndef MOZ_MEMORY
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
EXTRA_PP_COMPONENTS = \
|
||||
ProfileMigrator.js \
|
||||
|
|
|
@ -11,11 +11,9 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MODULE = privatebrowsing
|
||||
LIBRARY_NAME = privatebrowsing_s
|
||||
FORCE_STATIC_LIB = 1
|
||||
ifndef MOZ_MEMORY
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
USE_STATIC_LIBS = 1
|
||||
|
||||
CPPSRCS = \
|
||||
nsPrivateBrowsingServiceWrapper.cpp \
|
||||
|
|
|
@ -73,16 +73,16 @@ let DocumentUtils = {
|
|||
// <select>s without the multiple attribute are hard to determine the
|
||||
// default value, so assume we don't have the default.
|
||||
hasDefaultValue = false;
|
||||
value = node.selectedIndex;
|
||||
value = { selectedIndex: node.selectedIndex, value: node.value };
|
||||
} else {
|
||||
// <select>s with the multiple attribute are easier to determine the
|
||||
// default value since each <option> has a defaultSelected
|
||||
let options = Array.map(node.options, function(aOpt, aIx) {
|
||||
let oSelected = aOpt.selected;
|
||||
hasDefaultValue = hasDefaultValue && (oSelected == aOpt.defaultSelected);
|
||||
return oSelected ? aIx : -1;
|
||||
return oSelected ? aOpt.value : -1;
|
||||
});
|
||||
value = options.filter(function(aIx) aIx >= 0);
|
||||
value = options.filter(function(aIx) aIx !== -1);
|
||||
}
|
||||
|
||||
// In order to reduce XPath generation (which is slow), we only save data
|
||||
|
@ -177,23 +177,41 @@ let DocumentUtils = {
|
|||
aNode.checked = aValue;
|
||||
eventType = "change";
|
||||
} else if (typeof aValue == "number") {
|
||||
// handle select backwards compatibility, example { "#id" : index }
|
||||
// We saved the value blindly since selects take more work to determine
|
||||
// default values. So now we should check to avoid unnecessary events.
|
||||
if (aNode.selectedIndex == aValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (aValue < aNode.options.length) {
|
||||
aNode.selectedIndex = aValue;
|
||||
eventType = "change";
|
||||
} catch (ex) { /* throws for invalid indices */ }
|
||||
}
|
||||
} else if (aValue && aValue.selectedIndex >= 0 && aValue.value) {
|
||||
// handle select new format
|
||||
|
||||
// Don't dispatch a change event for no change
|
||||
if (aNode.options[aNode.selectedIndex].value == aValue.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find first option with matching aValue if possible
|
||||
for (let i = 0; i < aNode.options.length; i++) {
|
||||
if (aNode.options[i].value == aValue.value) {
|
||||
aNode.selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eventType = "change";
|
||||
} else if (aValue && aValue.fileList && aValue.type == "file" &&
|
||||
aNode.type == "file") {
|
||||
aNode.mozSetFileNameArray(aValue.fileList, aValue.fileList.length);
|
||||
eventType = "input";
|
||||
} else if (aValue && typeof aValue.indexOf == "function" && aNode.options) {
|
||||
Array.forEach(aNode.options, function(opt, index) {
|
||||
opt.selected = aValue.indexOf(index) > -1;
|
||||
// don't worry about malformed options with same values
|
||||
opt.selected = aValue.indexOf(opt.value) > -1;
|
||||
|
||||
// Only fire the event here if this wasn't selected by default
|
||||
if (!opt.defaultSelected) {
|
||||
|
|
|
@ -121,6 +121,8 @@ _BROWSER_TEST_FILES = \
|
|||
browser_644409-scratchpads.js \
|
||||
browser_645428.js \
|
||||
browser_659591.js \
|
||||
browser_662743.js \
|
||||
browser_662743_sample.html \
|
||||
browser_662812.js \
|
||||
browser_665702-state_session.js \
|
||||
browser_682507.js \
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This tests that session restore component does restore the right <select> option.
|
||||
// Session store should not rely only on previous user's selectedIndex, it should
|
||||
// check its value as well.
|
||||
|
||||
function test() {
|
||||
/** Tests selected options **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
let testTabCount = 0;
|
||||
let formData = [
|
||||
// default case
|
||||
{ },
|
||||
// old format
|
||||
{ "#select_id" : 0 },
|
||||
{ "#select_id" : 2 },
|
||||
// invalid index
|
||||
{ "#select_id" : 8 },
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select" : 5},
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : 6},
|
||||
|
||||
// new format
|
||||
// index doesn't match value (testing an option in between (two))
|
||||
{ id:{ "select_id": {"selectedIndex":0,"value":"val2"} } },
|
||||
// index doesn't match value (testing an invalid value)
|
||||
{ id:{ "select_id": {"selectedIndex":4,"value":"val8"} } },
|
||||
// index doesn't match value (testing an invalid index)
|
||||
{ id:{ "select_id": {"selectedIndex":8,"value":"val5"} } },
|
||||
// index and value match position zero
|
||||
{ id:{ "select_id": {"selectedIndex":0,"value":"val0"} }, xpath: {} },
|
||||
// index doesn't match value (testing the last option (seven))
|
||||
{ id:{},"xpath":{ "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']": {"selectedIndex":1,"value":"val7"} } },
|
||||
// index and value match the default option "selectedIndex":3,"value":"val3"
|
||||
{ xpath: { "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : {"selectedIndex":3,"value":"val3"} } },
|
||||
// index matches default option however it doesn't match value
|
||||
{ id:{ "select_id": {"selectedIndex":3,"value":"val4"} } },
|
||||
|
||||
// combinations
|
||||
{ "#select_id" : 3, id:{ "select_id": {"selectedIndex":1,"value":"val1"} } },
|
||||
{ "#select_id" : 5, xpath: { "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : {"selectedIndex":4,"value":"val4"} } },
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select" : 5, id:{ "select_id": {"selectedIndex":1,"value":"val1"} }},
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : 2, xpath: { "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : {"selectedIndex":7,"value":"val7"} } }
|
||||
];
|
||||
|
||||
let expectedValues = [
|
||||
[ "val3"], // default value
|
||||
[ "val0"],
|
||||
[ "val2"],
|
||||
[ "val3"], // default value (invalid index)
|
||||
[ "val5"],
|
||||
[ "val6"],
|
||||
[ "val2"],
|
||||
[ "val3"], // default value (invalid value)
|
||||
[ "val5"], // value is still valid (even it has an invalid index)
|
||||
[ "val0"],
|
||||
[ "val7"],
|
||||
[ "val3"],
|
||||
[ "val4"],
|
||||
[ "val1"],
|
||||
[ "val4"],
|
||||
[ "val1"],
|
||||
[ "val7"]
|
||||
];
|
||||
let callback = function() {
|
||||
testTabCount--;
|
||||
if (testTabCount == 0) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
for (let i = 0; i < formData.length; i++) {
|
||||
testTabCount++;
|
||||
testTabRestoreData(formData[i], expectedValues[i], callback);
|
||||
}
|
||||
}
|
||||
|
||||
function testTabRestoreData(aFormData, aExpectedValues, aCallback) {
|
||||
let testURL =
|
||||
getRootDirectory(gTestPath) + "browser_662743_sample.html";
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
let tabState = { entries: [{ url: testURL, formdata: aFormData}] };
|
||||
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
ss.setTabState(tab, JSON.stringify(tabState));
|
||||
|
||||
tab.addEventListener("SSTabRestored", function(aEvent) {
|
||||
tab.removeEventListener("SSTabRestored", arguments.callee);
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
let select = doc.getElementById("select_id");
|
||||
let value = select.options[select.selectedIndex].value;
|
||||
|
||||
// test select options values
|
||||
is(value, aExpectedValues[0],
|
||||
"Select Option by selectedIndex &/or value has been restored correctly");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab);
|
||||
aCallback();
|
||||
});
|
||||
|
||||
tab.addEventListener("TabClose", function(aEvent) {
|
||||
tab.removeEventListener("TabClose", arguments.callee);
|
||||
let restoredTabState = JSON.parse(ss.getTabState(tab));
|
||||
let restoredFormData = restoredTabState.entries[0].formdata;
|
||||
let selectIdFormData = restoredFormData.id.select_id;
|
||||
let value = restoredFormData.id.select_id.value;
|
||||
|
||||
// test format
|
||||
ok("id" in restoredFormData && "xpath" in restoredFormData,
|
||||
"FormData format is valid");
|
||||
// validate that there are no old keys
|
||||
is(Object.keys(restoredFormData).length, 2,
|
||||
"FormData key length is valid");
|
||||
// test format
|
||||
ok("selectedIndex" in selectIdFormData && "value" in selectIdFormData,
|
||||
"select format is valid");
|
||||
// validate that there are no old keys
|
||||
is(Object.keys(selectIdFormData).length, 2,
|
||||
"select_id length is valid");
|
||||
// test set collection values
|
||||
is(value, aExpectedValues[0],
|
||||
"Collection has been saved correctly");
|
||||
});
|
||||
}, true);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test 662743</title>
|
||||
|
||||
<!-- Select events -->
|
||||
<h3>Select options</h3>
|
||||
<select id="select_id" name="select_name">
|
||||
<option value="val0">Zero</option>
|
||||
<option value="val1">One</option>
|
||||
<option value="val2">Two</option>
|
||||
<option value="val3" selected="selected">Three</option>
|
||||
<option value="val4">Four</option>
|
||||
<option value="val5">Five</option>
|
||||
<option value="val6">Six</option>
|
||||
<option value="val7">Seven</option>
|
||||
</select>
|
|
@ -11,11 +11,9 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = shellservice
|
||||
FORCE_STATIC_LIB = 1
|
||||
ifndef MOZ_MEMORY
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
USE_STATIC_LIBS = 1
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
CPPSRCS = nsWindowsShellService.cpp
|
||||
|
|
|
@ -412,9 +412,10 @@ function writeUpdatesToXMLFile(aText)
|
|||
const MODE_CREATE = 0x08;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
|
||||
const kIsWin = (navigator.platform.indexOf("Win") == 0);
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("XCurProcD", Ci.nsIFile);
|
||||
get(kIsWin ? "UpdRootD" : "XCurProcD", Ci.nsIFile);
|
||||
file.append("updates.xml");
|
||||
let fos = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
|
|
|
@ -6201,7 +6201,7 @@ var eagerHelperSettingSpec = {
|
|||
{ name: 'always', value: Eagerness.ALWAYS },
|
||||
]
|
||||
},
|
||||
defaultValue: 1,
|
||||
defaultValue: Eagerness.SOMETIMES,
|
||||
description: l10n.lookup('eagerHelperDesc'),
|
||||
ignoreTypeDifference: true
|
||||
};
|
||||
|
@ -6346,7 +6346,8 @@ FocusManager.prototype.removeMonitoredElement = function(element, where) {
|
|||
FocusManager.prototype.updatePosition = function(dimensions) {
|
||||
var ev = {
|
||||
tooltipVisible: this.isTooltipVisible,
|
||||
outputVisible: this.isOutputVisible
|
||||
outputVisible: this.isOutputVisible,
|
||||
dimensions: dimensions
|
||||
};
|
||||
this.onVisibilityChange(ev);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
|
||||
[
|
||||
<!ENTITY % webConsoleDTD SYSTEM "chrome://browser/locale/devtools/webConsole.dtd">
|
||||
%webConsoleDTD;
|
||||
]
|
||||
>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is GCLI.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Foundation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2012
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Joe Walker <jwalker@mozilla.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" href="chrome://global/skin/global.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/content/devtools/gcli.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/gcli.css" type="text/css"/>
|
||||
</head>
|
||||
<body class="gcli-body">
|
||||
<div id="gcli-output-root"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -19,8 +19,8 @@
|
|||
<link rel="stylesheet" href="chrome://browser/content/devtools/gcli.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/gcli.css" type="text/css"/>
|
||||
</head>
|
||||
<body id="gclichrome-body">
|
||||
<div>
|
||||
</div>
|
||||
<body class="gcli-body">
|
||||
<div id="gcli-tooltip-root"></div>
|
||||
<div id="gcli-tooltip-connector"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -533,32 +533,10 @@ StackFrames.prototype = {
|
|||
paramVar.setGrip(paramVal);
|
||||
this._addExpander(paramVar, paramVal);
|
||||
}
|
||||
|
||||
// If we already found 'arguments', we are done here.
|
||||
if ("arguments" in frame.environment.bindings.variables) {
|
||||
// Signal that variables have been fetched.
|
||||
DebuggerController.dispatchEvent("Debugger:FetchedVariables");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Sometimes in call frames with arguments we don't get 'arguments' in the
|
||||
// environment (bug 746601) and we have to construct it manually. Note, that
|
||||
// in this case arguments.callee will be absent, even in the cases where it
|
||||
// shouldn't be.
|
||||
if (frame.arguments && frame.arguments.length > 0) {
|
||||
// Add "arguments".
|
||||
let argsVar = localScope.addVar("arguments");
|
||||
argsVar.setGrip({
|
||||
type: "object",
|
||||
class: "Arguments"
|
||||
});
|
||||
this._addExpander(argsVar, frame.arguments);
|
||||
|
||||
// Signal that variables have been fetched.
|
||||
DebuggerController.dispatchEvent("Debugger:FetchedVariables");
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -566,10 +544,9 @@ StackFrames.prototype = {
|
|||
* new properties.
|
||||
*/
|
||||
_addExpander: function SF__addExpander(aVar, aObject) {
|
||||
// No need for expansion for null and undefined values, but we do need them
|
||||
// for frame.arguments which is a regular array.
|
||||
// No need for expansion for null and undefined values.
|
||||
if (!aVar || !aObject || typeof aObject !== "object" ||
|
||||
(aObject.type !== "object" && !Array.isArray(aObject))) {
|
||||
aObject.type !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -588,23 +565,6 @@ StackFrames.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
// For arrays we have to construct a grip-like object.
|
||||
if (Array.isArray(aObject)) {
|
||||
let properties = { length: { value: aObject.length } };
|
||||
for (let i = 0, l = aObject.length; i < l; i++) {
|
||||
properties[i] = { value: aObject[i] };
|
||||
}
|
||||
aVar.addProperties(properties);
|
||||
|
||||
// Expansion handlers must be set after the properties are added.
|
||||
for (let i = 0, l = aObject.length; i < l; i++) {
|
||||
this._addExpander(aVar[i], aObject[i]);
|
||||
}
|
||||
|
||||
aVar.fetched = true;
|
||||
return;
|
||||
}
|
||||
|
||||
let objClient = this.activeThread.pauseGrip(aObject);
|
||||
objClient.getPrototypeAndProperties(function SF_onProtoAndProps(aResponse) {
|
||||
// Add __proto__.
|
||||
|
|
|
@ -76,18 +76,17 @@ function testFrameParameters()
|
|||
is(localNodes[6].querySelector(".info").textContent, "undefined",
|
||||
"Should have the right property value for 'fArg'.");
|
||||
|
||||
// FIXME bug TODO: reenable
|
||||
//is(localNodes[7].querySelector(".info").textContent, "1",
|
||||
// "Should have the right property value for 'a'.");
|
||||
is(localNodes[7].querySelector(".info").textContent, "1",
|
||||
"Should have the right property value for 'a'.");
|
||||
|
||||
//is(localNodes[8].querySelector(".info").textContent, "[object Object]",
|
||||
// "Should have the right property value for 'b'.");
|
||||
is(localNodes[8].querySelector(".info").textContent, "[object Object]",
|
||||
"Should have the right property value for 'b'.");
|
||||
|
||||
//is(localNodes[9].querySelector(".info").textContent, "[object Object]",
|
||||
// "Should have the right property value for 'c'.");
|
||||
is(localNodes[9].querySelector(".info").textContent, "[object Object]",
|
||||
"Should have the right property value for 'c'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
|
||||
// "Should have the right property value for 'arguments'.");
|
||||
is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
|
||||
"Should have the right property value for 'arguments'.");
|
||||
|
||||
resumeAndFinish();
|
||||
}}, 0);
|
||||
|
|
|
@ -56,7 +56,7 @@ function testFrameParameters()
|
|||
is(localNodes[0].querySelector(".info").textContent, "[object Proxy]",
|
||||
"Should have the right property value for 'this'.");
|
||||
|
||||
// Expand the '__proto__', 'arguments' and 'a' tree nodes. This causes
|
||||
// Expand the 'this', 'arguments' and 'c' tree nodes. This causes
|
||||
// their properties to be retrieved and displayed.
|
||||
localNodes[0].expand();
|
||||
localNodes[9].expand();
|
||||
|
@ -67,6 +67,7 @@ function testFrameParameters()
|
|||
// content window timers are disabled while the debuggee is paused.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function(){
|
||||
dump("count: "+count+" ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the properties.");
|
||||
resumeAndFinish();
|
||||
|
@ -96,17 +97,17 @@ function testFrameParameters()
|
|||
.textContent, 1,
|
||||
"Should have the right value for 'c.a'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".info").textContent,
|
||||
// "[object Arguments]",
|
||||
// "Should have the right property value for 'arguments'.");
|
||||
is(localNodes[10].querySelector(".info").textContent,
|
||||
"[object Arguments]",
|
||||
"Should have the right property value for 'arguments'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".property > .title > .key")
|
||||
// .textContent, "length",
|
||||
// "Should have the right property name for 'length'.");
|
||||
is(localNodes[10].querySelectorAll(".property > .title > .key")[7]
|
||||
.textContent, "length",
|
||||
"Should have the right property name for 'length'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".property > .title > .value")
|
||||
// .textContent, 5,
|
||||
// "Should have the right argument length.");
|
||||
is(localNodes[10].querySelectorAll(".property > .title > .value")[7]
|
||||
.textContent, 5,
|
||||
"Should have the right argument length.");
|
||||
|
||||
resumeAndFinish();
|
||||
}, 100);
|
||||
|
|
|
@ -23,4 +23,5 @@ browser.jar:
|
|||
content/browser/debugger-controller.js (debugger/debugger-controller.js)
|
||||
content/browser/debugger-view.js (debugger/debugger-view.js)
|
||||
content/browser/devtools/gcli.css (commandline/gcli.css)
|
||||
content/browser/devtools/gcliblank.xhtml (commandline/gcliblank.xhtml)
|
||||
content/browser/devtools/gclioutput.xhtml (commandline/gclioutput.xhtml)
|
||||
content/browser/devtools/gclitooltip.xhtml (commandline/gclitooltip.xhtml)
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
const EXPORTED_SYMBOLS = [ "DeveloperToolbar" ];
|
||||
|
||||
const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
||||
const URI_GCLIBLANK = "chrome://browser/content/devtools/gcliblank.xhtml";
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
@ -79,7 +78,6 @@ DeveloperToolbar.prototype.toggle = function DT_toggle()
|
|||
this.hide();
|
||||
} else {
|
||||
this.show();
|
||||
this._input.focus();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -155,8 +153,10 @@ DeveloperToolbar.prototype._onload = function DT_onload()
|
|||
|
||||
this._chromeWindow.getBrowser().tabContainer.addEventListener("TabSelect", this, false);
|
||||
this._chromeWindow.getBrowser().addEventListener("load", this, true);
|
||||
this._chromeWindow.addEventListener("resize", this, false);
|
||||
|
||||
this._element.hidden = false;
|
||||
this._input.focus();
|
||||
|
||||
this._notify(NOTIFICATIONS.SHOW);
|
||||
if (this._pendingShowCallback) {
|
||||
|
@ -263,66 +263,11 @@ DeveloperToolbar.prototype.handleEvent = function DT_handleEvent(aEvent)
|
|||
});
|
||||
}
|
||||
}
|
||||
else if (aEvent.type == "resize") {
|
||||
this.outputPanel._resize();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add class="gcli-panel-inner-arrowcontent" to a panel's
|
||||
* |<xul:box class="panel-inner-arrowcontent">| so we can alter the styling
|
||||
* without complex CSS expressions.
|
||||
* @param aPanel The panel to affect
|
||||
*/
|
||||
function getContentBox(aPanel)
|
||||
{
|
||||
let container = aPanel.ownerDocument.getAnonymousElementByAttribute(
|
||||
aPanel, "anonid", "container");
|
||||
return container.querySelector(".panel-inner-arrowcontent");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to calculate the sum of the vertical padding and margins
|
||||
* between a nested node |aNode| and an ancestor |aRoot|. Iff all of the
|
||||
* children of aRoot are 'only-childs' until you get to aNode then to avoid
|
||||
* scroll-bars, the 'correct' height of aRoot is verticalSpacing + aNode.height.
|
||||
* @param aNode The child node whose height is known.
|
||||
* @param aRoot The parent height whose height we can affect.
|
||||
* @return The sum of the vertical padding/margins in between aNode and aRoot.
|
||||
*/
|
||||
function getVerticalSpacing(aNode, aRoot)
|
||||
{
|
||||
let win = aNode.ownerDocument.defaultView;
|
||||
|
||||
function pxToNum(styles, property) {
|
||||
return parseInt(styles.getPropertyValue(property).replace(/px$/, ''), 10);
|
||||
}
|
||||
|
||||
let vertSpacing = 0;
|
||||
do {
|
||||
let styles = win.getComputedStyle(aNode);
|
||||
vertSpacing += pxToNum(styles, "padding-top");
|
||||
vertSpacing += pxToNum(styles, "padding-bottom");
|
||||
vertSpacing += pxToNum(styles, "margin-top");
|
||||
vertSpacing += pxToNum(styles, "margin-bottom");
|
||||
vertSpacing += pxToNum(styles, "border-top-width");
|
||||
vertSpacing += pxToNum(styles, "border-bottom-width");
|
||||
|
||||
let prev = aNode.previousSibling;
|
||||
while (prev != null) {
|
||||
vertSpacing += prev.clientHeight;
|
||||
prev = prev.previousSibling;
|
||||
}
|
||||
|
||||
let next = aNode.nextSibling;
|
||||
while (next != null) {
|
||||
vertSpacing += next.clientHeight;
|
||||
next = next.nextSibling;
|
||||
}
|
||||
|
||||
aNode = aNode.parentNode;
|
||||
} while (aNode !== aRoot);
|
||||
|
||||
return vertSpacing + 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Panel to handle command line output.
|
||||
* @param aChromeDoc document from which we can pull the parts we need.
|
||||
|
@ -332,32 +277,31 @@ function getVerticalSpacing(aNode, aRoot)
|
|||
function OutputPanel(aChromeDoc, aInput, aLoadCallback)
|
||||
{
|
||||
this._input = aInput;
|
||||
this._anchor = aChromeDoc.getElementById("developer-toolbar");
|
||||
this._toolbar = aChromeDoc.getElementById("developer-toolbar");
|
||||
|
||||
this._loadCallback = aLoadCallback;
|
||||
|
||||
/*
|
||||
<panel id="gcli-output"
|
||||
type="arrow"
|
||||
noautofocus="true"
|
||||
noautohide="true"
|
||||
class="gcli-panel">
|
||||
<iframe id="gcli-output-frame"
|
||||
src=URI_GCLIBLANK
|
||||
<html:iframe xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
id="gcli-output-frame"
|
||||
src="chrome://browser/content/devtools/gclioutput.xhtml"
|
||||
flex="1"/>
|
||||
</panel>
|
||||
*/
|
||||
this._panel = aChromeDoc.createElement("panel");
|
||||
this._panel.id = "gcli-output";
|
||||
this._panel.classList.add("gcli-panel");
|
||||
this._panel.setAttribute("type", "arrow");
|
||||
this._panel.setAttribute("noautofocus", "true");
|
||||
this._panel.setAttribute("noautohide", "true");
|
||||
this._anchor.parentElement.insertBefore(this._panel, this._anchor);
|
||||
this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
|
||||
|
||||
this._frame = aChromeDoc.createElement("iframe");
|
||||
this._frame = aChromeDoc.createElementNS(NS_XHTML, "iframe");
|
||||
this._frame.id = "gcli-output-frame";
|
||||
this._frame.setAttribute("src", URI_GCLIBLANK);
|
||||
this._frame.setAttribute("src", "chrome://browser/content/devtools/gclioutput.xhtml");
|
||||
this._frame.setAttribute("flex", "1");
|
||||
this._panel.appendChild(this._frame);
|
||||
|
||||
|
@ -377,13 +321,9 @@ OutputPanel.prototype._onload = function OP_onload()
|
|||
this._frame.removeEventListener("load", this._onload, true);
|
||||
delete this._onload;
|
||||
|
||||
this._content = getContentBox(this._panel);
|
||||
this._content.classList.add("gcli-panel-inner-arrowcontent");
|
||||
|
||||
this.document = this._frame.contentDocument;
|
||||
this.document.body.classList.add("gclichrome-output");
|
||||
|
||||
this._div = this.document.querySelector("div");
|
||||
this._div = this.document.getElementById("gcli-output-root");
|
||||
this._div.classList.add('gcli-row-out');
|
||||
this._div.setAttribute('aria-live', 'assertive');
|
||||
|
||||
|
@ -399,12 +339,15 @@ OutputPanel.prototype._onload = function OP_onload()
|
|||
*/
|
||||
OutputPanel.prototype.show = function OP_show()
|
||||
{
|
||||
// This is nasty, but displaying the panel causes it to re-flow, which can
|
||||
// change the size it should be, so we need to resize the iframe after the
|
||||
// panel has displayed
|
||||
this._panel.ownerDocument.defaultView.setTimeout(function() {
|
||||
this._resize();
|
||||
}.bind(this), 0);
|
||||
|
||||
this._panel.openPopup(this._input, "before_start", 0, 0, false, false, null);
|
||||
this._resize();
|
||||
this._panel.openPopup(this._anchor, "before_end", -300, 0, false, false, null);
|
||||
|
||||
this._input.focus();
|
||||
};
|
||||
|
@ -415,9 +358,12 @@ OutputPanel.prototype.show = function OP_show()
|
|||
*/
|
||||
OutputPanel.prototype._resize = function CLP_resize()
|
||||
{
|
||||
let vertSpacing = getVerticalSpacing(this._content, this._panel);
|
||||
let idealHeight = this.document.body.scrollHeight + vertSpacing;
|
||||
this._panel.sizeTo(400, Math.min(idealHeight, 500));
|
||||
if (this._panel == null || this.document == null || !this._panel.state == "closed") {
|
||||
return
|
||||
}
|
||||
|
||||
this._frame.height = this.document.body.scrollHeight;
|
||||
this._frame.width = this._input.clientWidth + 2;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -476,10 +422,10 @@ OutputPanel.prototype.destroy = function OP_destroy()
|
|||
this.remove();
|
||||
|
||||
this._panel.removeChild(this._frame);
|
||||
this._anchor.parentElement.removeChild(this._panel);
|
||||
this._toolbar.parentElement.removeChild(this._panel);
|
||||
|
||||
delete this._input;
|
||||
delete this._anchor;
|
||||
delete this._toolbar;
|
||||
delete this._panel;
|
||||
delete this._frame;
|
||||
delete this._content;
|
||||
|
@ -510,7 +456,8 @@ OutputPanel.prototype._visibilityChanged = function OP_visibilityChanged(aEvent)
|
|||
function TooltipPanel(aChromeDoc, aInput, aLoadCallback)
|
||||
{
|
||||
this._input = aInput;
|
||||
this._anchor = aChromeDoc.getElementById("developer-toolbar");
|
||||
this._toolbar = aChromeDoc.getElementById("developer-toolbar");
|
||||
this._dimensions = { start: 0, end: 0 };
|
||||
|
||||
this._onload = this._onload.bind(this);
|
||||
this._loadCallback = aLoadCallback;
|
||||
|
@ -520,22 +467,22 @@ function TooltipPanel(aChromeDoc, aInput, aLoadCallback)
|
|||
noautofocus="true"
|
||||
noautohide="true"
|
||||
class="gcli-panel">
|
||||
<iframe id="gcli-tooltip-frame"
|
||||
src=URI_GCLIBLANK
|
||||
<html:iframe xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
id="gcli-tooltip-frame"
|
||||
src="chrome://browser/content/devtools/gclitooltip.xhtml"
|
||||
flex="1"/>
|
||||
</panel>
|
||||
*/
|
||||
this._panel = aChromeDoc.createElement("panel");
|
||||
this._panel.id = "gcli-tooltip";
|
||||
this._panel.classList.add("gcli-panel");
|
||||
this._panel.setAttribute("type", "arrow");
|
||||
this._panel.setAttribute("noautofocus", "true");
|
||||
this._panel.setAttribute("noautohide", "true");
|
||||
this._anchor.parentElement.insertBefore(this._panel, this._anchor);
|
||||
this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
|
||||
|
||||
this._frame = aChromeDoc.createElement("iframe");
|
||||
this._frame = aChromeDoc.createElementNS(NS_XHTML, "iframe");
|
||||
this._frame.id = "gcli-tooltip-frame";
|
||||
this._frame.setAttribute("src", URI_GCLIBLANK);
|
||||
this._frame.setAttribute("src", "chrome://browser/content/devtools/gclitooltip.xhtml");
|
||||
this._frame.setAttribute("flex", "1");
|
||||
this._panel.appendChild(this._frame);
|
||||
|
||||
|
@ -550,13 +497,9 @@ TooltipPanel.prototype._onload = function TP_onload()
|
|||
{
|
||||
this._frame.removeEventListener("load", this._onload, true);
|
||||
|
||||
this._content = getContentBox(this._panel);
|
||||
this._content.classList.add("gcli-panel-inner-arrowcontent");
|
||||
|
||||
this.document = this._frame.contentDocument;
|
||||
this.document.body.classList.add("gclichrome-tooltip");
|
||||
|
||||
this.hintElement = this.document.querySelector("div");
|
||||
this.hintElement = this.document.getElementById("gcli-tooltip-root");
|
||||
this._connector = this.document.getElementById("gcli-tooltip-connector");
|
||||
|
||||
this.loaded = true;
|
||||
|
||||
|
@ -569,16 +512,58 @@ TooltipPanel.prototype._onload = function TP_onload()
|
|||
/**
|
||||
* Display the TooltipPanel.
|
||||
*/
|
||||
TooltipPanel.prototype.show = function TP_show()
|
||||
TooltipPanel.prototype.show = function TP_show(aDimensions)
|
||||
{
|
||||
let vertSpacing = getVerticalSpacing(this._content, this._panel);
|
||||
let idealHeight = this.document.body.scrollHeight + vertSpacing;
|
||||
this._panel.sizeTo(350, Math.min(idealHeight, 500));
|
||||
this._panel.openPopup(this._anchor, "before_start", 0, 0, false, false, null);
|
||||
if (!aDimensions) {
|
||||
aDimensions = { start: 0, end: 0 };
|
||||
}
|
||||
this._dimensions = aDimensions;
|
||||
|
||||
// This is nasty, but displaying the panel causes it to re-flow, which can
|
||||
// change the size it should be, so we need to resize the iframe after the
|
||||
// panel has displayed
|
||||
this._panel.ownerDocument.defaultView.setTimeout(function() {
|
||||
this._resize();
|
||||
}.bind(this), 0);
|
||||
|
||||
this._resize();
|
||||
this._panel.openPopup(this._input, "before_start", aDimensions.start * 10, 0, false, false, null);
|
||||
this._input.focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* One option is to spend lots of time taking an average width of characters
|
||||
* in the current font, dynamically, and weighting for the frequency of use of
|
||||
* various characters, or even to render the given string off screen, and then
|
||||
* measure the width.
|
||||
* Or we could do this...
|
||||
*/
|
||||
const AVE_CHAR_WIDTH = 4.5;
|
||||
|
||||
/**
|
||||
* Display the TooltipPanel.
|
||||
*/
|
||||
TooltipPanel.prototype._resize = function TP_resize()
|
||||
{
|
||||
if (this._panel == null || this.document == null || !this._panel.state == "closed") {
|
||||
return
|
||||
}
|
||||
|
||||
let offset = 10 + Math.floor(this._dimensions.start * AVE_CHAR_WIDTH);
|
||||
this._frame.style.marginLeft = offset + "px";
|
||||
|
||||
/*
|
||||
// Bug 744906: UX review - Not sure if we want this code to fatten connector
|
||||
// with param width
|
||||
let width = Math.floor(this._dimensions.end * AVE_CHAR_WIDTH);
|
||||
width = Math.min(width, 100);
|
||||
width = Math.max(width, 10);
|
||||
this._connector.style.width = width + "px";
|
||||
*/
|
||||
|
||||
this._frame.height = this.document.body.scrollHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the TooltipPanel.
|
||||
*/
|
||||
|
@ -595,13 +580,15 @@ TooltipPanel.prototype.destroy = function TP_destroy()
|
|||
this.remove();
|
||||
|
||||
this._panel.removeChild(this._frame);
|
||||
this._anchor.parentElement.removeChild(this._panel);
|
||||
this._toolbar.parentElement.removeChild(this._panel);
|
||||
|
||||
delete this._connector;
|
||||
delete this._dimensions;
|
||||
delete this._input;
|
||||
delete this._onload;
|
||||
delete this._panel;
|
||||
delete this._frame;
|
||||
delete this._anchor;
|
||||
delete this._toolbar;
|
||||
delete this._content;
|
||||
delete this.document;
|
||||
delete this.hintElement;
|
||||
|
@ -614,7 +601,7 @@ TooltipPanel.prototype.destroy = function TP_destroy()
|
|||
TooltipPanel.prototype._visibilityChanged = function TP_visibilityChanged(aEvent)
|
||||
{
|
||||
if (aEvent.tooltipVisible === true) {
|
||||
this.show();
|
||||
this.show(aEvent.dimensions);
|
||||
} else {
|
||||
this._panel.hidePopup();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_require_basic.js \
|
||||
browser_templater_basic.js \
|
||||
browser_toolbar_basic.js \
|
||||
browser_toolbar_tooltip.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ registerCleanupFunction(function() {
|
|||
imported = {};
|
||||
});
|
||||
|
||||
const URL = "http://example.com/browser/browser/devtools/shared/test/browser_toolbar_basic.html";
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_toolbar_basic.html";
|
||||
|
||||
function test() {
|
||||
addTab(URL, function(browser, tab) {
|
||||
addTab(TEST_URI, function(browser, tab) {
|
||||
info("Starting browser_toolbar_basic.js");
|
||||
runTest();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the developer toolbar works properly
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>Tooltip Tests</p>";
|
||||
|
||||
function test() {
|
||||
DeveloperToolbarTest.test(TEST_URI, function(browser, tab) {
|
||||
runTest();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
let tooltipPanel = DeveloperToolbar.tooltipPanel;
|
||||
|
||||
DeveloperToolbar.display.focusManager.helpRequest();
|
||||
DeveloperToolbar.display.inputter.setInput('help help');
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 'help help'.length });
|
||||
is(tooltipPanel._dimensions.start, 'help '.length,
|
||||
'search param start, when cursor at end');
|
||||
ok(getLeftMargin() > 30, 'tooltip offset, when cursor at end')
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 'help'.length });
|
||||
is(tooltipPanel._dimensions.start, 0,
|
||||
'search param start, when cursor at end of command');
|
||||
ok(getLeftMargin() > 9, 'tooltip offset, when cursor at end of command')
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 'help help'.length - 1 });
|
||||
is(tooltipPanel._dimensions.start, 'help '.length,
|
||||
'search param start, when cursor at penultimate position');
|
||||
ok(getLeftMargin() > 30, 'tooltip offset, when cursor at penultimate position')
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 0 });
|
||||
is(tooltipPanel._dimensions.start, 0,
|
||||
'search param start, when cursor at start');
|
||||
ok(getLeftMargin() > 9, 'tooltip offset, when cursor at start')
|
||||
}
|
||||
|
||||
function getLeftMargin() {
|
||||
let style = DeveloperToolbar.tooltipPanel._frame.style.marginLeft;
|
||||
return parseInt(style.slice(0, -2), 10);
|
||||
}
|
|
@ -67,7 +67,55 @@ let DeveloperToolbarTest = {
|
|||
DeveloperToolbar.display.inputter.setInput("");
|
||||
DeveloperToolbar.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Quick wrapper around the things you need to do to run DeveloperToolbar
|
||||
* command tests:
|
||||
* - Set the pref 'devtools.toolbar.enabled' to true
|
||||
* - Add a tab pointing at |uri|
|
||||
* - Open the DeveloperToolbar
|
||||
* - Register a cleanup function to undo the above
|
||||
* - Run the tests
|
||||
*
|
||||
* @param uri The uri of a page to load. Can be 'about:blank' or 'data:...'
|
||||
* @param testFunc A function containing the tests to run. This should
|
||||
* arrange for 'finish()' to be called on completion.
|
||||
*/
|
||||
test: function DTT_test(uri, testFunc) {
|
||||
let menuItem = document.getElementById("menu_devToolbar");
|
||||
let command = document.getElementById("Tools:DevToolbar");
|
||||
let appMenuItem = document.getElementById("appmenu_devToolbar");
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
DeveloperToolbarTest.hide();
|
||||
|
||||
// a.k.a Services.prefs.clearUserPref("devtools.toolbar.enabled");
|
||||
if (menuItem) menuItem.hidden = true;
|
||||
if (command) command.setAttribute("disabled", "true");
|
||||
if (appMenuItem) appMenuItem.hidden = true;
|
||||
});
|
||||
|
||||
// a.k.a: Services.prefs.setBoolPref("devtools.toolbar.enabled", true);
|
||||
if (menuItem) menuItem.hidden = false;
|
||||
if (command) command.removeAttribute("disabled");
|
||||
if (appMenuItem) appMenuItem.hidden = false;
|
||||
|
||||
addTab(uri, function(browser, tab) {
|
||||
DeveloperToolbarTest.show(function() {
|
||||
|
||||
try {
|
||||
testFunc(browser, tab);
|
||||
}
|
||||
catch (ex) {
|
||||
ok(false, "" + ex);
|
||||
console.error(ex);
|
||||
finish();
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
function catchFail(func) {
|
||||
|
|
|
@ -1758,6 +1758,7 @@ HUD_SERVICE.prototype =
|
|||
// Remove the HUDBox and the consolePanel if the Web Console is inside a
|
||||
// floating panel.
|
||||
if (hud.consolePanel && hud.consolePanel.parentNode) {
|
||||
hud.consolePanel.hidePopup();
|
||||
hud.consolePanel.parentNode.removeChild(hud.consolePanel);
|
||||
hud.consolePanel.removeAttribute("hudId");
|
||||
hud.consolePanel = null;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
CHROMEDIR = $(call core_abspath,$(DIST))/bin/chrome
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
TEST_DIRS += pdfjs/test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
exclude_files = \
|
||||
test \
|
||||
install.rdf \
|
||||
bootstrap.js \
|
||||
icon.png \
|
||||
icon64.png \
|
||||
$(NULL)
|
||||
|
||||
$(DIST)/bin/chrome/pdfjs.manifest: $(GLOBAL_DEPS)
|
||||
printf "manifest pdfjs/chrome.manifest" > $@
|
||||
|
||||
libs:: $(DIST)/bin/chrome/pdfjs.manifest
|
||||
$(PYTHON) $(topsrcdir)/config/nsinstall.py \
|
||||
$(srcdir)/pdfjs \
|
||||
$(foreach exclude,$(exclude_files), -X $(srcdir)/pdfjs/$(exclude)) \
|
||||
$(DIST)/bin/chrome
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
|
||||
$(DIST)/bin/chrome.manifest "manifest chrome/pdfjs.manifest"
|
|
@ -0,0 +1,3 @@
|
|||
resource pdf.js content/
|
||||
component {6457a96b-2d68-439a-bcfa-44465fbcdbb1} components/PdfStreamConverter.js
|
||||
contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {6457a96b-2d68-439a-bcfa-44465fbcdbb1}
|
До Ширина: | Высота: | Размер: 28 KiB После Ширина: | Высота: | Размер: 28 KiB |
До Ширина: | Высота: | Размер: 401 B После Ширина: | Высота: | Размер: 401 B |
До Ширина: | Высота: | Размер: 502 B После Ширина: | Высота: | Размер: 502 B |
До Ширина: | Высота: | Размер: 23 KiB После Ширина: | Высота: | Размер: 23 KiB |
До Ширина: | Высота: | Размер: 29 KiB После Ширина: | Высота: | Размер: 29 KiB |
До Ширина: | Высота: | Размер: 8.2 KiB После Ширина: | Высота: | Размер: 8.2 KiB |
До Ширина: | Высота: | Размер: 8.0 KiB После Ширина: | Высота: | Размер: 8.0 KiB |
До Ширина: | Высота: | Размер: 2.5 KiB После Ширина: | Высота: | Размер: 2.5 KiB |
До Ширина: | Высота: | Размер: 5.5 KiB После Ширина: | Высота: | Размер: 5.5 KiB |
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 7.8 KiB |
До Ширина: | Высота: | Размер: 9.8 KiB После Ширина: | Высота: | Размер: 9.8 KiB |
До Ширина: | Высота: | Размер: 8.3 KiB После Ширина: | Высота: | Размер: 8.3 KiB |
До Ширина: | Высота: | Размер: 14 KiB После Ширина: | Высота: | Размер: 14 KiB |
До Ширина: | Высота: | Размер: 13 KiB После Ширина: | Высота: | Размер: 13 KiB |
До Ширина: | Высота: | Размер: 4.5 KiB После Ширина: | Высота: | Размер: 4.5 KiB |
До Ширина: | Высота: | Размер: 5.7 KiB После Ширина: | Высота: | Размер: 5.7 KiB |
|
@ -2,11 +2,11 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ../../../../../..
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = browser/app/profile/extensions/uriloader@pdf.js/test
|
||||
relativesrcdir = browser/features/pdfjs/test
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -2,25 +2,12 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const RELATIVE_DIR = "browser/app/profile/extensions/uriloader@pdf.js/test/";
|
||||
const RELATIVE_DIR = "browser/features/pdfjs/test/";
|
||||
const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
AddonManager.getAddonByID("uriloader@pdf.js", function(aAddon) {
|
||||
is(aAddon.userDisabled, true, 'Pdf.js addon must be disabled by default');
|
||||
aAddon.userDisabled = false;
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
aAddon.userDisabled = true;
|
||||
});
|
||||
|
||||
continueTest();
|
||||
});
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
var tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
|
||||
var newTabBrowser = gBrowser.getBrowserForTab(tab);
|
||||
newTabBrowser.addEventListener("load", function onLoad() {
|
|
@ -24,6 +24,8 @@
|
|||
@APPNAME@/Contents/Info.plist
|
||||
@APPNAME@/Contents/PkgInfo
|
||||
@APPNAME@/Contents/Resources/
|
||||
@APPNAME@/Contents/CodeResources
|
||||
@APPNAME@/Contents/_CodeSignature/CodeResources
|
||||
#endif
|
||||
|
||||
[@AB_CD@]
|
||||
|
@ -480,9 +482,10 @@
|
|||
; [Browser Chrome Files]
|
||||
@BINPATH@/chrome/browser@JAREXT@
|
||||
@BINPATH@/chrome/browser.manifest
|
||||
@BINPATH@/chrome/pdfjs.manifest
|
||||
@BINPATH@/chrome/pdfjs/*
|
||||
@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
|
||||
@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
|
||||
@BINPATH@/extensions/uriloader@pdf.js.xpi
|
||||
#ifdef SHIP_FEEDBACK
|
||||
@BINPATH@/distribution/extensions/testpilot@labs.mozilla.com.xpi
|
||||
#endif
|
||||
|
|
|
@ -1092,14 +1092,14 @@ Function .onInit
|
|||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Left "0"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Right "-1"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Top "5"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Bottom "15"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Bottom "25"
|
||||
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Type "checkbox"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Text "$(MAINTENANCE_SERVICE_CHECKBOX_DESC)"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Left "0"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Right "-1"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Top "20"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Bottom "30"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Top "27"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Bottom "37"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" State "1"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Flags "GROUP"
|
||||
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
<!ENTITY update.downloading.start "Downloading update — ">
|
||||
<!ENTITY update.downloading.end "">
|
||||
|
||||
<!ENTITY update.applying "Applying update…">
|
||||
|
||||
<!-- LOCALIZATION NOTE (channel.description.start,channel.description.end): channel.description.start and
|
||||
channel.description.end create one sentence, with the current channel label inserted in between.
|
||||
example: You are currently on the _Stable_ update channel. -->
|
||||
|
|
|
@ -156,6 +156,8 @@ update.openUpdateUI.applyButton.label=Apply Update…
|
|||
update.openUpdateUI.applyButton.accesskey=A
|
||||
update.restart.updateButton.label=Restart to Update
|
||||
update.restart.updateButton.accesskey=R
|
||||
update.restart.restartButton.label=Update & Restart
|
||||
update.restart.restartButton.accesskey=R
|
||||
update.openUpdateUI.upgradeButton.label=Upgrade Now…
|
||||
update.openUpdateUI.upgradeButton.accesskey=U
|
||||
update.restart.upgradeButton.label=Upgrade Now
|
||||
|
|
|
@ -47,6 +47,7 @@ browser/devtools/styleeditor/Makefile
|
|||
browser/devtools/styleinspector/Makefile
|
||||
browser/devtools/tilt/Makefile
|
||||
browser/devtools/webconsole/Makefile
|
||||
browser/extensions/Makefile
|
||||
browser/fuel/Makefile
|
||||
browser/fuel/public/Makefile
|
||||
browser/fuel/src/Makefile
|
||||
|
|
|
@ -108,6 +108,11 @@ function NativeApp(aData) {
|
|||
this.manifest = app.manifest;
|
||||
|
||||
this.profileFolder = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
||||
|
||||
this.webappJson = {
|
||||
"registryDir": this.profileFolder.path,
|
||||
"app": app
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -288,14 +293,9 @@ WinNativeApp.prototype = {
|
|||
*/
|
||||
_createConfigFiles: function() {
|
||||
// ${InstallDir}/webapp.json
|
||||
let json = {
|
||||
"registryDir": this.profileFolder.path,
|
||||
"app": this.app
|
||||
};
|
||||
|
||||
let configJson = this.installDir.clone();
|
||||
configJson.append("webapp.json");
|
||||
writeToFile(configJson, JSON.stringify(json), function() {});
|
||||
writeToFile(configJson, JSON.stringify(this.webappJson), function() {});
|
||||
|
||||
// ${InstallDir}/webapp.ini
|
||||
let webappINI = this.installDir.clone().QueryInterface(Ci.nsILocalFile);
|
||||
|
@ -538,18 +538,9 @@ MacNativeApp.prototype = {
|
|||
|
||||
_createConfigFiles: function() {
|
||||
// ${ProfileDir}/webapp.json
|
||||
let json = {
|
||||
"registryDir": this.profileFolder.path,
|
||||
"app": {
|
||||
"origin": this.launchURI.prePath,
|
||||
"installOrigin": "apps.mozillalabs.com",
|
||||
"manifest": this.manifest
|
||||
}
|
||||
};
|
||||
|
||||
let configJson = this.appProfileDir.clone();
|
||||
configJson.append("webapp.json");
|
||||
writeToFile(configJson, JSON.stringify(json), function() {});
|
||||
writeToFile(configJson, JSON.stringify(this.webappJson), function() {});
|
||||
|
||||
// ${InstallDir}/Contents/MacOS/webapp.ini
|
||||
let applicationINI = this.macOSDir.clone().QueryInterface(Ci.nsILocalFile);
|
||||
|
|
|
@ -331,6 +331,7 @@ user_pref("network.http.prompt-temp-redirect", false);
|
|||
user_pref("media.cache_size", 100);
|
||||
user_pref("security.warn_viewing_mixed", false);
|
||||
user_pref("app.update.enabled", false);
|
||||
user_pref("app.update.stage.enabled", false);
|
||||
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
|
||||
user_pref("dom.w3c_touch_events.enabled", true);
|
||||
user_pref("toolkit.telemetry.prompted", 2);
|
||||
|
|
|
@ -479,6 +479,8 @@ NSS_DISABLE_DBM = @NSS_DISABLE_DBM@
|
|||
|
||||
XPCOM_GLUE_LDOPTS = @XPCOM_GLUE_LDOPTS@
|
||||
XPCOM_STANDALONE_GLUE_LDOPTS = @XPCOM_STANDALONE_GLUE_LDOPTS@
|
||||
XPCOM_STATICRUNTIME_GLUE_LDOPTS = @XPCOM_STATICRUNTIME_GLUE_LDOPTS@
|
||||
XPCOM_STANDALONE_STATICRUNTIME_GLUE_LDOPTS = @XPCOM_STANDALONE_STATICRUNTIME_GLUE_LDOPTS@
|
||||
|
||||
USE_DEPENDENT_LIBS = @USE_DEPENDENT_LIBS@
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ def nsinstall(argv):
|
|||
help="Create link (ignored)")
|
||||
p.add_option('-L', action="store", metavar="linkprefix",
|
||||
help="Link prefix (ignored)")
|
||||
p.add_option('-X', action="append", metavar="file",
|
||||
help="Ignore a file when installing a directory recursively.")
|
||||
|
||||
# The remaining arguments are not used in our tree, thus they're not
|
||||
# implented.
|
||||
|
@ -75,12 +77,18 @@ def nsinstall(argv):
|
|||
os.makedirs(args[0])
|
||||
return 0
|
||||
|
||||
if options.X:
|
||||
options.X = [os.path.abspath(p) for p in options.X]
|
||||
|
||||
# nsinstall arg1 [...] directory
|
||||
if len(args) < 2:
|
||||
p.error('not enough arguments')
|
||||
|
||||
def copy_all_entries(entries, target):
|
||||
for e in entries:
|
||||
if options.X and os.path.abspath(e) in options.X:
|
||||
continue
|
||||
|
||||
dest = os.path.join(target,
|
||||
os.path.basename(os.path.normpath(e)))
|
||||
handleTarget(e, dest)
|
||||
|
|
|
@ -21,8 +21,6 @@ all.h
|
|||
alloca.h
|
||||
alloc.h
|
||||
alsa/asoundlib.h
|
||||
alsa/pcm.h
|
||||
alsa/mixer.h
|
||||
android/log.h
|
||||
ansi_parms.h
|
||||
a.out.h
|
||||
|
|
|
@ -47,11 +47,25 @@ class TestNsinstall(unittest.TestCase):
|
|||
"Test nsinstall <dir> <dest dir>"
|
||||
sourcedir = self.mkdirs("sourcedir")
|
||||
self.touch("testfile", sourcedir)
|
||||
Xfile = self.touch("Xfile", sourcedir)
|
||||
copieddir = self.mkdirs("sourcedir/copieddir")
|
||||
self.touch("testfile2", copieddir)
|
||||
Xdir = self.mkdirs("sourcedir/Xdir")
|
||||
self.touch("testfile3", Xdir)
|
||||
|
||||
destdir = self.mkdirs("destdir")
|
||||
self.assertEqual(nsinstall([sourcedir, destdir]), 0)
|
||||
|
||||
self.assertEqual(nsinstall([sourcedir, destdir,
|
||||
'-X', Xfile,
|
||||
'-X', Xdir]), 0)
|
||||
|
||||
testdir = os.path.join(destdir, "sourcedir")
|
||||
self.assert_(os.path.isdir(testdir))
|
||||
self.assert_(os.path.isfile(os.path.join(testdir, "testfile")))
|
||||
self.assert_(not os.path.exists(os.path.join(testdir, "Xfile")))
|
||||
self.assert_(os.path.isdir(os.path.join(testdir, "copieddir")))
|
||||
self.assert_(os.path.isfile(os.path.join(testdir, "copieddir", "testfile2")))
|
||||
self.assert_(not os.path.exists(os.path.join(testdir, "Xdir")))
|
||||
|
||||
def test_nsinstall_multiple(self):
|
||||
"Test nsinstall <three files> <dest dir>"
|
||||
|
|
28
configure.in
|
@ -1308,6 +1308,18 @@ LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) -lxul'
|
|||
XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
|
||||
XPCOM_STANDALONE_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX)'
|
||||
|
||||
# These are specially defined on Windows only
|
||||
case "$target" in
|
||||
*-mingw*)
|
||||
XPCOM_STATICRUNTIME_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_staticruntime_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
|
||||
XPCOM_STANDALONE_STATICRUNTIME_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_staticruntime.$(LIB_SUFFIX)'
|
||||
;;
|
||||
*)
|
||||
XPCOM_STATICRUNTIME_GLUE_LDOPTS=$XPCOM_GLUE_LDOPTS
|
||||
XPCOM_STANDALONE_STATICRUNTIME_GLUE_LDOPTS=$XPCOM_STANDALONE_GLUE_LDOPTS
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_FS_LAYOUT=unix
|
||||
|
||||
MOZ_COMPONENT_NSPR_LIBS='-L$(LIBXUL_DIST)/bin $(NSPR_LIBS)'
|
||||
|
@ -5743,6 +5755,12 @@ fi
|
|||
|
||||
if test -n "$MOZ_CUBEB"; then
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
dnl No Android implementation of libcubeb yet.
|
||||
;;
|
||||
*-linux*)
|
||||
AC_DEFINE(MOZ_CUBEB)
|
||||
;;
|
||||
*-mingw*)
|
||||
AC_DEFINE(MOZ_CUBEB)
|
||||
;;
|
||||
|
@ -8424,6 +8442,8 @@ AC_SUBST(XPCOM_LIBS)
|
|||
AC_SUBST(XPCOM_FROZEN_LDOPTS)
|
||||
AC_SUBST(XPCOM_GLUE_LDOPTS)
|
||||
AC_SUBST(XPCOM_STANDALONE_GLUE_LDOPTS)
|
||||
AC_SUBST(XPCOM_STATICRUNTIME_GLUE_LDOPTS)
|
||||
AC_SUBST(XPCOM_STANDALONE_STATICRUNTIME_GLUE_LDOPTS)
|
||||
|
||||
AC_SUBST(USE_DEPENDENT_LIBS)
|
||||
|
||||
|
@ -8840,11 +8860,11 @@ xpcom/xpcom-private.h
|
|||
|
||||
# Hack around an Apple bug that effects the egrep that comes with OS X 10.7.
|
||||
# "arch -arch i386 egrep" always uses the 32-bit Intel part of the egrep fat
|
||||
# binary, even on 64-bit systems. It should work on OS X 10.4.5 and up. We
|
||||
# (apparently) only need this hack when egrep's "pattern" is particularly
|
||||
# long (as in the following code). See bug 655339.
|
||||
# binary, even on 64-bit systems. We (apparently) only need this hack when
|
||||
# egrep's "pattern" is particularly long (as in the following code).
|
||||
# See bug 655339.
|
||||
case "$host" in
|
||||
*-apple-darwin*)
|
||||
*-apple-darwin11*)
|
||||
FIXED_EGREP="arch -arch i386 egrep"
|
||||
;;
|
||||
*)
|
||||
|
|
|
@ -593,6 +593,9 @@ public:
|
|||
// system principal, and true for a null principal.
|
||||
static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const char* aType);
|
||||
|
||||
// Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s.
|
||||
static bool HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2);
|
||||
|
||||
static nsILineBreaker* LineBreaker()
|
||||
{
|
||||
return sLineBreaker;
|
||||
|
|
|
@ -183,6 +183,7 @@ public:
|
|||
// Overrides
|
||||
NS_IMETHOD GetSize(PRUint64* aSize);
|
||||
NS_IMETHOD GetType(nsAString& aType);
|
||||
NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate);
|
||||
NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath);
|
||||
NS_IMETHOD GetInternalStream(nsIInputStream**);
|
||||
|
||||
|
|
|
@ -56,10 +56,14 @@ interface nsIDOMBlob : nsISupports
|
|||
[notxpcom] FileInfo getFileInfo(in FileManager aFileManager);
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(b096ef67-7b77-47f8-8e70-5d8ee36416bf)]
|
||||
[scriptable, builtinclass, uuid(eee028d1-8ce9-4c6c-b9ce-d89b656e1e17)]
|
||||
interface nsIDOMFile : nsIDOMBlob
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval lastModifiedDate;
|
||||
|
||||
readonly attribute DOMString mozFullPath;
|
||||
|
||||
// This performs no security checks!
|
||||
|
|
|
@ -92,9 +92,8 @@ class Element;
|
|||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x8e51e6d9, 0x914d, 0x46ba, \
|
||||
{ 0xb3, 0x11, 0x2f, 0x27, 0x3d, 0xe6, 0x0d, 0x19 } }
|
||||
|
||||
{ 0x88d887da, 0xd228, 0x41c2, \
|
||||
{ 0xb8, 0x0a, 0x42, 0xec, 0xf0, 0xcb, 0xce, 0x37 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -744,6 +743,14 @@ public:
|
|||
*/
|
||||
virtual bool IsFullScreenDoc() = 0;
|
||||
|
||||
/**
|
||||
* Sets whether this document is approved for fullscreen mode.
|
||||
* Documents aren't approved for fullscreen until chrome has sent a
|
||||
* "fullscreen-approved" notification with a subject which is a pointer
|
||||
* to the approved document.
|
||||
*/
|
||||
virtual void SetApprovedForFullscreen(bool aIsApproved) = 0;
|
||||
|
||||
/**
|
||||
* Exits all documents from DOM full-screen mode, and moves the top-level
|
||||
* browser window out of full-screen mode. If aRunAsync is true, this runs
|
||||
|
|
|
@ -416,6 +416,48 @@ nsContentSink::LinkContextIsOurDocument(const nsSubstring& aAnchor)
|
|||
return same;
|
||||
}
|
||||
|
||||
// Decode a parameter value using the encoding defined in RFC 5987 (in place)
|
||||
//
|
||||
// charset "'" [ language ] "'" value-chars
|
||||
//
|
||||
// returns true when decoding happened successfully (otherwise leaves
|
||||
// passed value alone)
|
||||
bool
|
||||
nsContentSink::Decode5987Format(nsAString& aEncoded) {
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar =
|
||||
do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
nsCAutoString asciiValue;
|
||||
|
||||
const PRUnichar* encstart = aEncoded.BeginReading();
|
||||
const PRUnichar* encend = aEncoded.EndReading();
|
||||
|
||||
// create a plain ASCII string, aborting if we can't do that
|
||||
// converted form is always shorter than input
|
||||
while (encstart != encend) {
|
||||
if (*encstart > 0 && *encstart < 128) {
|
||||
asciiValue.Append((char)*encstart);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
encstart++;
|
||||
}
|
||||
|
||||
nsAutoString decoded;
|
||||
nsCAutoString language;
|
||||
|
||||
rv = mimehdrpar->DecodeRFC5987Param(asciiValue, language, decoded);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
aEncoded = decoded;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
||||
const nsAString& aLinkData)
|
||||
|
@ -429,6 +471,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
nsAutoString href;
|
||||
nsAutoString rel;
|
||||
nsAutoString title;
|
||||
nsAutoString titleStar;
|
||||
nsAutoString type;
|
||||
nsAutoString media;
|
||||
nsAutoString anchor;
|
||||
|
@ -453,7 +496,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
end = start;
|
||||
last = end - 1;
|
||||
|
||||
bool needsUnescape = false;
|
||||
bool wasQuotedString = false;
|
||||
|
||||
// look for semicolon or comma
|
||||
while (*end != kNullCh && *end != kSemicolon && *end != kComma) {
|
||||
|
@ -467,14 +510,14 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
quote = kGreaterThan;
|
||||
}
|
||||
|
||||
needsUnescape = (ch == kQuote);
|
||||
wasQuotedString = (ch == kQuote);
|
||||
|
||||
PRUnichar* closeQuote = (end + 1);
|
||||
|
||||
// seek closing quote
|
||||
while (*closeQuote != kNullCh && quote != *closeQuote) {
|
||||
// in quoted-string, "\" is an escape character
|
||||
if (needsUnescape && *closeQuote == kBackSlash && *(closeQuote + 1) != kNullCh) {
|
||||
if (wasQuotedString && *closeQuote == kBackSlash && *(closeQuote + 1) != kNullCh) {
|
||||
++closeQuote;
|
||||
}
|
||||
|
||||
|
@ -549,7 +592,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
value++;
|
||||
}
|
||||
|
||||
if (needsUnescape) {
|
||||
if (wasQuotedString) {
|
||||
// unescape in-place
|
||||
PRUnichar* unescaped = value;
|
||||
PRUnichar *src = value;
|
||||
|
@ -574,6 +617,20 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
title = value;
|
||||
title.CompressWhitespace();
|
||||
}
|
||||
} else if (attr.LowerCaseEqualsLiteral("title*")) {
|
||||
if (titleStar.IsEmpty() && !wasQuotedString) {
|
||||
// RFC 5987 encoding; uses token format only, so skip if we get
|
||||
// here with a quoted-string
|
||||
nsAutoString tmp;
|
||||
tmp = value;
|
||||
if (Decode5987Format(tmp)) {
|
||||
titleStar = tmp;
|
||||
titleStar.CompressWhitespace();
|
||||
} else {
|
||||
// header value did not parse, throw it away
|
||||
titleStar.Truncate();
|
||||
}
|
||||
}
|
||||
} else if (attr.LowerCaseEqualsLiteral("type")) {
|
||||
if (type.IsEmpty()) {
|
||||
type = value;
|
||||
|
@ -602,7 +659,10 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
|
||||
href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
rv = ProcessLink(aElement, anchor, href, rel, title, type, media);
|
||||
rv = ProcessLink(aElement, anchor, href, rel,
|
||||
// prefer RFC 5987 variant over non-I18zed version
|
||||
titleStar.IsEmpty() ? title : titleStar,
|
||||
type, media);
|
||||
}
|
||||
|
||||
href.Truncate();
|
||||
|
@ -620,7 +680,10 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
|
||||
href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
rv = ProcessLink(aElement, anchor, href, rel, title, type, media);
|
||||
rv = ProcessLink(aElement, anchor, href, rel,
|
||||
// prefer RFC 5987 variant over non-I18zed version
|
||||
titleStar.IsEmpty() ? title : titleStar,
|
||||
type, media);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -117,6 +117,7 @@ class nsContentSink : public nsICSSLoaderObserver,
|
|||
|
||||
bool IsTimeToNotify();
|
||||
bool LinkContextIsOurDocument(const nsSubstring& aAnchor);
|
||||
bool Decode5987Format(nsAString& aEncoded);
|
||||
|
||||
static void InitializeStatics();
|
||||
|
||||
|
|
|
@ -6491,6 +6491,18 @@ nsContentUtils::IsRequestFullScreenAllowed()
|
|||
IsCallerChrome();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsContentUtils::HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2)
|
||||
{
|
||||
if (!aDoc1 || !aDoc2) {
|
||||
return false;
|
||||
}
|
||||
bool principalsEqual = false;
|
||||
aDoc1->NodePrincipal()->Equals(aDoc2->NodePrincipal(), &principalsEqual);
|
||||
return principalsEqual;
|
||||
}
|
||||
|
||||
static void
|
||||
CheckForWindowedPlugins(nsIContent* aContent, void* aResult)
|
||||
{
|
||||
|
|
|
@ -128,6 +128,13 @@ nsDOMFileBase::GetName(nsAString &aFileName)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileBase::GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate)
|
||||
{
|
||||
aLastModifiedDate->setNull();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
|
||||
{
|
||||
|
@ -417,6 +424,22 @@ nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
|
|||
return mFile->GetPath(aFilename);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate)
|
||||
{
|
||||
PRInt64 msecs;
|
||||
mFile->GetLastModifiedTime(&msecs);
|
||||
JSObject* date = JS_NewDateObjectMsec(cx, msecs);
|
||||
if (date) {
|
||||
aLastModifiedDate->setObject(*date);
|
||||
}
|
||||
else {
|
||||
aLastModifiedDate->setNull();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileFile::GetSize(PRUint64 *aFileSize)
|
||||
{
|
||||
|
|
|
@ -7391,7 +7391,7 @@ nsDocument::OnPageHide(bool aPersisted,
|
|||
// document to reset its state, so reset full-screen state in *this*
|
||||
// document. OnPageHide() is called in every hidden document, so doing
|
||||
// this ensures all hidden documents have their full-screen state reset.
|
||||
ClearFullScreenStack();
|
||||
CleanupFullscreenState();
|
||||
|
||||
// Next reset full-screen state in all visible documents in the doctree.
|
||||
nsIDocument::ExitFullScreen(false);
|
||||
|
@ -8581,7 +8581,7 @@ nsIDocument::ExitFullScreen(bool aRunAsync)
|
|||
static bool
|
||||
ResetFullScreen(nsIDocument* aDocument, void* aData) {
|
||||
if (aDocument->IsFullScreenDoc()) {
|
||||
static_cast<nsDocument*>(aDocument)->ClearFullScreenStack();
|
||||
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
|
||||
NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
|
||||
nsTArray<nsIDocument*>* changed = reinterpret_cast<nsTArray<nsIDocument*>*>(aData);
|
||||
changed->AppendElement(aDocument);
|
||||
|
@ -8659,7 +8659,7 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
nsIDocument* doc = fullScreenDoc;
|
||||
while (doc != this) {
|
||||
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be full-screen doc");
|
||||
static_cast<nsDocument*>(doc)->ClearFullScreenStack();
|
||||
static_cast<nsDocument*>(doc)->CleanupFullscreenState();
|
||||
UnlockPointer();
|
||||
DispatchFullScreenChange(doc);
|
||||
doc = doc->GetParentDocument();
|
||||
|
@ -8675,6 +8675,7 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
// Full-screen stack in document is empty. Go back up to the parent
|
||||
// document. We'll pop the containing element off its stack, and use
|
||||
// its next full-screen element as the full-screen element.
|
||||
static_cast<nsDocument*>(doc)->CleanupFullscreenState();
|
||||
doc = doc->GetParentDocument();
|
||||
} else {
|
||||
// Else we popped the top of the stack, and there's still another
|
||||
|
@ -8682,9 +8683,11 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
if (fullScreenDoc != doc) {
|
||||
// We've popped so enough off the stack that we've rolled back to
|
||||
// a fullscreen element in a parent document. If this document isn't
|
||||
// authorized for fullscreen, dispatch an event to chrome so it
|
||||
// knows to show the authorization UI.
|
||||
if (!nsContentUtils::IsSitePermAllow(doc->NodePrincipal(), "fullscreen")) {
|
||||
// approved for fullscreen, or if it's cross origin, dispatch an
|
||||
// event to chrome so it knows to show the authorization/warning UI.
|
||||
if (!nsContentUtils::HaveEqualPrincipals(fullScreenDoc, doc) ||
|
||||
(!nsContentUtils::IsSitePermAllow(doc->NodePrincipal(), "fullscreen") &&
|
||||
!static_cast<nsDocument*>(doc)->mIsApprovedForFullscreen)) {
|
||||
nsRefPtr<nsAsyncDOMEvent> e =
|
||||
new nsAsyncDOMEvent(doc,
|
||||
NS_LITERAL_STRING("MozEnteredDomFullscreen"),
|
||||
|
@ -8768,12 +8771,34 @@ LogFullScreenDenied(bool aLogFailure, const char* aMessage, nsIDocument* aDoc)
|
|||
aMessage);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ClearFullScreenStack()
|
||||
nsresult
|
||||
nsDocument::AddFullscreenApprovedObserver()
|
||||
{
|
||||
if (mFullScreenStack.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->AddObserver(this, "fullscreen-approved", true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::RemoveFullscreenApprovedObserver()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->RemoveObserver(this, "fullscreen-approved");
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::CleanupFullscreenState()
|
||||
{
|
||||
if (!mFullScreenStack.IsEmpty()) {
|
||||
// The top element in the full-screen stack will have full-screen
|
||||
// style bits set on it and its ancestors. Remove the style bits.
|
||||
// Note the non-top elements won't have the style bits set.
|
||||
|
@ -8783,6 +8808,9 @@ nsDocument::ClearFullScreenStack()
|
|||
nsEventStateManager::SetFullScreenState(top, false);
|
||||
}
|
||||
mFullScreenStack.Clear();
|
||||
}
|
||||
SetApprovedForFullscreen(false);
|
||||
RemoveFullscreenApprovedObserver();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -8950,6 +8978,8 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
|||
}
|
||||
}
|
||||
|
||||
AddFullscreenApprovedObserver();
|
||||
|
||||
// Stores a list of documents which we must dispatch "mozfullscreenchange"
|
||||
// too. We're required by the spec to dispatch the events in root-to-leaf
|
||||
// order, but we traverse the doctree in a leaf-to-root order, so we save
|
||||
|
@ -9011,12 +9041,30 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
|||
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
|
||||
}
|
||||
|
||||
// If this document hasn't already been approved in this session,
|
||||
// check to see if the user has granted the fullscreen access
|
||||
// to the document's principal's host, if it has one.
|
||||
if (!mIsApprovedForFullscreen) {
|
||||
mIsApprovedForFullscreen =
|
||||
nsContentUtils::IsSitePermAllow(NodePrincipal(), "fullscreen");
|
||||
}
|
||||
|
||||
// If this document, or a document with the same principal has not
|
||||
// already been approved for fullscreen this fullscreen-session, dispatch
|
||||
// an event so that chrome knows to pop up a warning/approval UI.
|
||||
nsCOMPtr<nsIDocument> previousFullscreenDoc(do_QueryReferent(sFullScreenDoc));
|
||||
// Note previousFullscreenDoc=nsnull upon first entry, so we always
|
||||
// take this path on the first time we enter fullscreen in a fullscreen
|
||||
// session.
|
||||
if (!mIsApprovedForFullscreen ||
|
||||
!nsContentUtils::HaveEqualPrincipals(previousFullscreenDoc, this)) {
|
||||
nsRefPtr<nsAsyncDOMEvent> e =
|
||||
new nsAsyncDOMEvent(this,
|
||||
NS_LITERAL_STRING("MozEnteredDomFullscreen"),
|
||||
true,
|
||||
true);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
|
||||
// Remember this is the requesting full-screen document.
|
||||
sFullScreenDoc = do_GetWeakReference(static_cast<nsIDocument*>(this));
|
||||
|
@ -9246,19 +9294,6 @@ nsDocument::ClearPendingPointerLockRequest(bool aDispatchErrorEvents)
|
|||
return;
|
||||
}
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryReferent(sPendingPointerLockDoc));
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (!os) {
|
||||
NS_WARNING("Lost observer service in ClearPendingPointerLockRequest()!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserver> obs(do_QueryInterface(doc));
|
||||
if (!os) {
|
||||
NS_WARNING("Document must implement nsIObserver");
|
||||
return;
|
||||
}
|
||||
os->RemoveObserver(obs, "perm-changed");
|
||||
|
||||
if (aDispatchErrorEvents) {
|
||||
DispatchPointerLockError(doc);
|
||||
}
|
||||
|
@ -9285,15 +9320,6 @@ nsDocument::SetPendingPointerLockRequest(Element* aElement)
|
|||
|
||||
NS_ENSURE_TRUE(aElement != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIObserver> obs(do_QueryInterface(aElement->OwnerDoc()));
|
||||
NS_ENSURE_TRUE(obs != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->AddObserver(obs, "perm-changed", true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
sPendingPointerLockDoc = do_GetWeakReference(aElement->OwnerDoc());
|
||||
sPendingPointerLockElement = do_GetWeakReference(aElement);
|
||||
|
||||
|
@ -9304,17 +9330,30 @@ nsDocument::SetPendingPointerLockRequest(Element* aElement)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetApprovedForFullscreen(bool aIsApproved)
|
||||
{
|
||||
mIsApprovedForFullscreen = aIsApproved;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (strcmp("perm-changed", aTopic) == 0) {
|
||||
if (strcmp("fullscreen-approved", aTopic) == 0) {
|
||||
nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
|
||||
if (subject != this) {
|
||||
return NS_OK;
|
||||
}
|
||||
SetApprovedForFullscreen(true);
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryReferent(sPendingPointerLockDoc));
|
||||
if (nsContentUtils::IsSitePermAllow(doc->NodePrincipal(), "fullscreen")) {
|
||||
if (this == doc) {
|
||||
// This doc has a pointer lock request, waiting for fullscreen to be
|
||||
// approved before it can be granted. Process the pointer lock request.
|
||||
nsCOMPtr<Element> element(do_QueryReferent(sPendingPointerLockElement));
|
||||
nsDocument::ClearPendingPointerLockRequest(false);
|
||||
nsAsyncPointerLockRequest::Request(element, doc);
|
||||
nsAsyncPointerLockRequest::Request(element, this);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -9338,8 +9377,8 @@ nsDocument::RequestPointerLock(Element* aElement)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsSitePermAllow(NodePrincipal(), "fullscreen")) {
|
||||
// Domain isn't yet approved for fullscreen, so we must wait until
|
||||
if (!mIsApprovedForFullscreen) {
|
||||
// Document isn't yet approved for fullscreen, so we must wait until
|
||||
// it's been approved.
|
||||
if (NS_FAILED(SetPendingPointerLockRequest(aElement))) {
|
||||
NS_WARNING("Failed to make pointer lock request pending!");
|
||||
|
|
|
@ -929,6 +929,8 @@ public:
|
|||
virtual void AsyncRequestFullScreen(Element* aElement);
|
||||
virtual void RestorePreviousFullScreenState();
|
||||
virtual bool IsFullScreenDoc();
|
||||
virtual void SetApprovedForFullscreen(bool aIsApproved);
|
||||
|
||||
static void ExitFullScreen();
|
||||
|
||||
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
|
||||
|
@ -939,7 +941,14 @@ public:
|
|||
|
||||
// Removes all elements from the full-screen stack, removing full-scren
|
||||
// styles from the top element in the stack.
|
||||
void ClearFullScreenStack();
|
||||
void CleanupFullscreenState();
|
||||
|
||||
// Add/remove "fullscreen-approved" observer service notification listener.
|
||||
// Chrome sends us a notification when fullscreen is approved for a
|
||||
// document, with the notification subject as the document that was approved.
|
||||
// We maintain this listener while in fullscreen mode.
|
||||
nsresult AddFullscreenApprovedObserver();
|
||||
nsresult RemoveFullscreenApprovedObserver();
|
||||
|
||||
// Pushes aElement onto the full-screen stack, and removes full-screen styles
|
||||
// from the former full-screen stack top, and its ancestors, and applies the
|
||||
|
@ -1180,6 +1189,21 @@ protected:
|
|||
// terminated instead of letting it finish at its own pace.
|
||||
bool mParserAborted:1;
|
||||
|
||||
// Whether this document has been approved for fullscreen, either by explicit
|
||||
// approval via the fullscreen-approval UI, or because it received
|
||||
// approval because its document's host already had the "fullscreen"
|
||||
// permission granted when the document requested fullscreen.
|
||||
//
|
||||
// Note if a document's principal doesn't have a host, the permission manager
|
||||
// can't store permissions for it, so we can only manage approval using this
|
||||
// flag.
|
||||
//
|
||||
// Note we must track this separately from the "fullscreen" permission,
|
||||
// so that pending pointer lock requests can determine whether documents
|
||||
// whose principal doesn't have a host (i.e. those which can't store
|
||||
// permissions in the permission manager) have been approved for fullscreen.
|
||||
bool mIsApprovedForFullscreen:1;
|
||||
|
||||
PRUint8 mXMLDeclarationBits;
|
||||
|
||||
nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;
|
||||
|
|
|
@ -34,6 +34,11 @@ var domFile = fileList.files[0];
|
|||
|
||||
is(domFile.name, "prefs.js", "fileName should be prefs.js");
|
||||
|
||||
ok("lastModifiedDate" in domFile, "lastModifiedDate must be present");
|
||||
|
||||
var d = new Date(testFile.lastModifiedTime);
|
||||
ok(d.getTime() == domFile.lastModifiedDate.getTime(), "lastModifiedDate should be the same.");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body> </html>
|
||||
|
|
|
@ -2522,8 +2522,7 @@ GetScrollableLineHeight(nsIFrame* aTargetFrame)
|
|||
// Fall back to the font height of the target frame.
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aTargetFrame, getter_AddRefs(fm),
|
||||
nsLayoutUtils::FontSizeInflationFor(aTargetFrame,
|
||||
nsLayoutUtils::eNotInReflow));
|
||||
nsLayoutUtils::FontSizeInflationFor(aTargetFrame));
|
||||
NS_ASSERTION(fm, "FontMetrics is null!");
|
||||
if (fm)
|
||||
return fm->MaxHeight();
|
||||
|
|
|
@ -11,12 +11,6 @@
|
|||
|
||||
using namespace mozilla;
|
||||
|
||||
static nsSVGEnumMapping sZoomAndPanMap[] = {
|
||||
{&nsGkAtoms::disable, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE},
|
||||
{&nsGkAtoms::magnify, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY},
|
||||
{nsnull, 0}
|
||||
};
|
||||
|
||||
static bool
|
||||
IsMatchingParameter(const nsAString &aString, const nsAString &aParameterName)
|
||||
{
|
||||
|
@ -148,7 +142,6 @@ SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
|
|||
}
|
||||
}
|
||||
|
||||
const nsSVGViewBoxRect *oldViewBoxPtr = root->GetViewBoxProperty();
|
||||
if (viewBoxParams) {
|
||||
SaveOldViewBox(root);
|
||||
root->mViewBox.SetBaseValueString(*viewBoxParams, root);
|
||||
|
@ -156,7 +149,6 @@ SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
|
|||
RestoreOldViewBox(root);
|
||||
}
|
||||
|
||||
const SVGPreserveAspectRatio *oldPARPtr = root->GetPreserveAspectRatioProperty();
|
||||
if (preserveAspectRatioParams) {
|
||||
SaveOldPreserveAspectRatio(root);
|
||||
root->mPreserveAspectRatio.SetBaseValueString(*preserveAspectRatioParams, root);
|
||||
|
@ -164,7 +156,6 @@ SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
|
|||
RestoreOldPreserveAspectRatio(root);
|
||||
}
|
||||
|
||||
const PRUint16 *oldZoomAndPanPtr = root->GetZoomAndPanProperty();
|
||||
if (zoomAndPanParams) {
|
||||
SaveOldZoomAndPan(root);
|
||||
nsCOMPtr<nsIAtom> valAtom = do_GetAtom(*zoomAndPanParams);
|
||||
|
|
|
@ -57,27 +57,40 @@ DOMRequestIpcHelper.prototype = {
|
|||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
this._requests = [];
|
||||
this._window = null;
|
||||
this._messages.forEach((function(msgName) {
|
||||
cpmm.removeMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
this.removeMessageListener();
|
||||
if(this.uninit)
|
||||
this.uninit();
|
||||
}
|
||||
},
|
||||
|
||||
initHelper: function(aWindow, aMessages) {
|
||||
this._messages = aMessages;
|
||||
initRequests: function initRequests() {
|
||||
this._requests = [];
|
||||
this._window = aWindow;
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
this._id = this._getRandomId();
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
},
|
||||
|
||||
initMessageListener: function initMessageListener(aMessages) {
|
||||
this._messages = aMessages;
|
||||
this._messages.forEach((function(msgName) {
|
||||
cpmm.addMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
initHelper: function(aWindow, aMessages) {
|
||||
this.initMessageListener(aMessages);
|
||||
this.initRequests();
|
||||
this._id = this._getRandomId();
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
this._window = aWindow;
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
},
|
||||
|
||||
removeMessageListener: function removeMessageListener() {
|
||||
this._messages.forEach((function(msgName) {
|
||||
cpmm.removeMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
this._messages = null;
|
||||
},
|
||||
|
||||
createRequest: function() {
|
||||
return Services.DOMRequest.createRequest(this._window);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ interface nsIDOMEventListener;
|
|||
interface nsIDOMDOMRequest;
|
||||
interface nsIDOMMozMobileConnectionInfo;
|
||||
|
||||
[scriptable, uuid(ba2be619-fed6-4652-865a-c61f88ffeaa8)]
|
||||
[scriptable, uuid(962298cd-3443-423e-9e47-f22e24ad850b)]
|
||||
interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
||||
{
|
||||
/**
|
||||
|
@ -54,6 +54,111 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
|||
*/
|
||||
attribute nsIDOMEventListener ondatachange;
|
||||
|
||||
/**
|
||||
* Find out about the status of an ICC lock (e.g. the PIN lock).
|
||||
*
|
||||
* @param lockType
|
||||
* Identifies the lock type, e.g. "pin" for the PIN lock.
|
||||
*
|
||||
* @return a DOM Request.
|
||||
* The request's result will be an object containing
|
||||
* information about the specified lock's status,
|
||||
* e.g. {lockType: "pin", enabled: true}.
|
||||
*/
|
||||
nsIDOMDOMRequest getCardLock(in DOMString lockType);
|
||||
|
||||
/**
|
||||
* Unlock a card lock.
|
||||
*
|
||||
* @param info
|
||||
* An object containing the information necessary to unlock
|
||||
* the given lock. At a minimum, this object must have a
|
||||
* "lockType" attribute which specifies the type of lock, e.g.
|
||||
* "pin" for the PIN lock. Other attributes are dependent on
|
||||
* the lock type.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* (1) Unlocking the PIN:
|
||||
*
|
||||
* unlockCardLock({lockType: "pin",
|
||||
* pin: "..."});
|
||||
*
|
||||
* (2) Unlocking the PUK and supplying a new PIN:
|
||||
*
|
||||
* unlockCardLock({lockType: "puk",
|
||||
* puk: "...",
|
||||
* newPin: "..."});
|
||||
*
|
||||
* @return a nsIDOMDOMRequest.
|
||||
* The request's result will be an object containing
|
||||
* information about the unlock operation.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* (1) Unlocking failed:
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: false,
|
||||
* retryCount: 2
|
||||
* }
|
||||
*
|
||||
* (2) Unlocking succeeded:
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: true
|
||||
* }
|
||||
*/
|
||||
nsIDOMDOMRequest unlockCardLock(in jsval info);
|
||||
|
||||
/**
|
||||
* Modify the state of a card lock.
|
||||
*
|
||||
* @param info
|
||||
* An object containing information about the lock and
|
||||
* how to modify its state. At a minimum, this object
|
||||
* must have a "lockType" attribute which specifies the
|
||||
* type of lock, e.g. "pin" for the PIN lock. Other
|
||||
* attributes are dependent on the lock type.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* (1) Disabling the PIN lock:
|
||||
*
|
||||
* setCardLock({lockType: "pin",
|
||||
* pin: "...",
|
||||
* enabled: false});
|
||||
*
|
||||
* (2) Changing the PIN:
|
||||
*
|
||||
* setCardLock({lockType: "pin",
|
||||
* pin: "...",
|
||||
* newPin: "..."});
|
||||
*
|
||||
* @return a nsIDOMDOMRequest.
|
||||
* The request's result will be an object containing
|
||||
* information about the operation.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* (1) Enabling/Disabling card lock failed or change card lock failed.
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: false,
|
||||
* retryCount: 2
|
||||
* }
|
||||
*
|
||||
* (2) Enabling/Disabling card lock succeed or change card lock succeed.
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: true
|
||||
* }
|
||||
*/
|
||||
nsIDOMDOMRequest setCardLock(in jsval info);
|
||||
};
|
||||
|
||||
[scriptable, uuid(f3bb0611-5e4a-46f1-a8f5-cf592b37596e)]
|
||||
|
|
|
@ -12,7 +12,7 @@ interface nsIDOMWindow;
|
|||
* XPCOM component (in the content process) that provides the mobile
|
||||
* network information.
|
||||
*/
|
||||
[scriptable, uuid(1ecd19eb-15d4-47c0-a2cf-80cfa3b94eeb)]
|
||||
[scriptable, uuid(93202514-9ae9-482e-95bc-9c6ed62aea99)]
|
||||
interface nsIMobileConnectionProvider : nsISupports
|
||||
{
|
||||
readonly attribute DOMString cardState;
|
||||
|
@ -20,4 +20,7 @@ interface nsIMobileConnectionProvider : nsISupports
|
|||
readonly attribute nsIDOMMozMobileConnectionInfo dataConnectionInfo;
|
||||
|
||||
nsIDOMDOMRequest getNetworks(in nsIDOMWindow window);
|
||||
nsIDOMDOMRequest getCardLock(in nsIDOMWindow window, in DOMString lockType);
|
||||
nsIDOMDOMRequest unlockCardLock(in nsIDOMWindow window, in jsval info);
|
||||
nsIDOMDOMRequest setCardLock(in nsIDOMWindow window, in jsval info);
|
||||
};
|
||||
|
|