mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge tracemonkey to mozilla-central. a=blockers
This commit is contained in:
commit
d91fb6ccdc
@ -216,6 +216,7 @@ var TestPilotXulWindow = {
|
||||
},
|
||||
|
||||
onUnload: function() {
|
||||
document.getElementById("settings-pane").writePreferences(true);
|
||||
Observers.remove("testpilot:task:changed", this._onTaskStatusChanged, this);
|
||||
},
|
||||
|
||||
|
@ -175,6 +175,15 @@ var TestPilotMenuUtils;
|
||||
return;
|
||||
}
|
||||
let firefoxnav = window.document.getElementById("nav-bar");
|
||||
/* This is sometimes called for windows that don't have a navbar - in
|
||||
* that case, do nothing. */
|
||||
if (!firefoxnav) {
|
||||
return;
|
||||
}
|
||||
// TODO if the user has removed the feedback button via customization
|
||||
// interface, we don't want to add it back in. Use a pref to store whether
|
||||
// this setup was done or not.
|
||||
|
||||
let curSet = firefoxnav.currentSet;
|
||||
|
||||
if (-1 == curSet.indexOf("feedback-menu-button")) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>testpilot@labs.mozilla.com</em:id>
|
||||
<em:version>1.0.2</em:version>
|
||||
<em:version>1.0.3</em:version>
|
||||
<em:type>2</em:type>
|
||||
|
||||
<!-- Target Application this extension can install into,
|
||||
@ -13,7 +13,7 @@
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>3.5</em:minVersion>
|
||||
<em:maxVersion>4.0b4</em:maxVersion>
|
||||
<em:maxVersion>4.0b5</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -682,8 +682,6 @@ const gXPInstallObserver = {
|
||||
|
||||
if (!enabled) {
|
||||
notificationID = "xpinstall-disabled"
|
||||
if (PopupNotifications.getNotification(notificationID, browser))
|
||||
return;
|
||||
|
||||
if (gPrefService.prefIsLocked("xpinstall.enabled")) {
|
||||
messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
|
||||
@ -702,9 +700,6 @@ const gXPInstallObserver = {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (PopupNotifications.getNotification(notificationID, browser))
|
||||
return;
|
||||
|
||||
messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
|
||||
[brandShortName, installInfo.originatingURI.host]);
|
||||
|
||||
@ -749,10 +744,6 @@ const gXPInstallObserver = {
|
||||
});
|
||||
break;
|
||||
case "addon-install-complete":
|
||||
var notification = PopupNotifications.getNotification(notificationID, browser);
|
||||
if (notification)
|
||||
PopupNotifications.remove(notification);
|
||||
|
||||
var needsRestart = installInfo.installs.some(function(i) {
|
||||
return i.addon.pendingOperations != AddonManager.PENDING_NONE;
|
||||
});
|
||||
|
@ -59,7 +59,7 @@ function test_blocked_install() {
|
||||
// Wait for the blocked notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-blocked", "Should have seen the install blocked");
|
||||
is(notification.id, "addon-install-blocked-notification", "Should have seen the install blocked");
|
||||
is(notification.button.label, "Allow", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
gApp + " prevented this site (example.com) from asking you to install " +
|
||||
@ -76,7 +76,7 @@ function test_blocked_install() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete", "Should have seen the install complete");
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
is(notification.button.label, "Restart Now", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
"XPI Test will be installed after you restart " + gApp + ".",
|
||||
@ -111,7 +111,7 @@ function test_whitelisted_install() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete", "Should have seen the install complete");
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
is(notification.button.label, "Restart Now", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
"XPI Test will be installed after you restart " + gApp + ".",
|
||||
@ -142,7 +142,7 @@ function test_failed_download() {
|
||||
// Wait for the failed notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-failed", "Should have seen the install fail");
|
||||
is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
|
||||
is(notification.getAttribute("label"),
|
||||
"The add-on could not be downloaded because of a connection failure " +
|
||||
"on example.com.",
|
||||
@ -167,7 +167,7 @@ function test_corrupt_file() {
|
||||
// Wait for the failed notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-failed", "Should have seen the install fail");
|
||||
is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
|
||||
is(notification.getAttribute("label"),
|
||||
"The add-on downloaded from example.com could not be installed " +
|
||||
"because it appears to be corrupt.",
|
||||
@ -192,7 +192,7 @@ function test_incompatible() {
|
||||
// Wait for the failed notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-failed", "Should have seen the install fail");
|
||||
is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
|
||||
is(notification.getAttribute("label"),
|
||||
"XPI Test could not be installed because it is not compatible with " +
|
||||
gApp + " " + gVersion + ".",
|
||||
@ -221,7 +221,7 @@ function test_restartless() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete", "Should have seen the install complete");
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
is(notification.button.label, "Open Add-ons Manager", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
"XPI Test has been installed successfully.",
|
||||
@ -260,7 +260,7 @@ function test_multiple() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete", "Should have seen the install complete");
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
is(notification.button.label, "Restart Now", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
"2 add-ons will be installed after you restart " + gApp + ".",
|
||||
@ -293,7 +293,7 @@ function test_url() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete", "Should have seen the install complete");
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
is(notification.button.label, "Restart Now", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
"XPI Test will be installed after you restart " + gApp + ".",
|
||||
@ -321,7 +321,7 @@ function test_localfile() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-failed", "Should have seen the install fail");
|
||||
is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
|
||||
is(notification.getAttribute("label"),
|
||||
"This add-on could not be installed because it appears to be corrupt.",
|
||||
"Should have seen the right message");
|
||||
@ -344,7 +344,7 @@ function test_wronghost() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-failed", "Should have seen the install fail");
|
||||
is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
|
||||
is(notification.getAttribute("label"),
|
||||
"The add-on downloaded from example.com could not be installed " +
|
||||
"because it appears to be corrupt.",
|
||||
@ -374,7 +374,7 @@ function test_reload() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete", "Should have seen the install complete");
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
is(notification.button.label, "Restart Now", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
"XPI Test will be installed after you restart " + gApp + ".",
|
||||
@ -425,7 +425,7 @@ function test_theme() {
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete", "Should have seen the install complete");
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
is(notification.button.label, "Restart Now", "Should have seen the right button");
|
||||
is(notification.getAttribute("label"),
|
||||
"Theme Test will be installed after you restart " + gApp + ".",
|
||||
@ -436,6 +436,105 @@ function test_theme() {
|
||||
runNextTest();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
function test_renotify_blocked() {
|
||||
var triggers = encodeURIComponent(JSON.stringify({
|
||||
"XPI": "unsigned.xpi"
|
||||
}));
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
|
||||
|
||||
// Wait for the blocked notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-blocked-notification", "Should have seen the install blocked");
|
||||
|
||||
aPanel.addEventListener("popuphidden", function () {
|
||||
aPanel.removeEventListener("popuphidden", arguments.callee, false);
|
||||
info("Timeouts after this probably mean bug 589954 regressed");
|
||||
executeSoon(function () {
|
||||
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
|
||||
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-blocked-notification",
|
||||
"Should have seen the install blocked - 2nd time");
|
||||
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
is(aInstalls.length, 2, "Should be two pending installs");
|
||||
aInstalls[0].cancel();
|
||||
aInstalls[1].cancel();
|
||||
|
||||
info("Closing browser tab");
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
runNextTest();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}, false);
|
||||
|
||||
// hide the panel (this simulates the user dismissing it)
|
||||
aPanel.hidePopup();
|
||||
});
|
||||
},
|
||||
|
||||
function test_renotify_installed() {
|
||||
var pm = Services.perms;
|
||||
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
|
||||
|
||||
var triggers = encodeURIComponent(JSON.stringify({
|
||||
"XPI": "unsigned.xpi"
|
||||
}));
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
|
||||
|
||||
// Wait for the install confirmation dialog
|
||||
wait_for_install_dialog(function(aWindow) {
|
||||
aWindow.document.documentElement.acceptDialog();
|
||||
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
|
||||
|
||||
// Dismiss the notification
|
||||
aPanel.addEventListener("popuphidden", function () {
|
||||
aPanel.removeEventListener("popuphidden", arguments.callee, false);
|
||||
|
||||
// Install another
|
||||
executeSoon(function () {
|
||||
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
|
||||
|
||||
// Wait for the install confirmation dialog
|
||||
wait_for_install_dialog(function(aWindow) {
|
||||
aWindow.document.documentElement.acceptDialog();
|
||||
info("Timeouts after this probably mean bug 589954 regressed");
|
||||
|
||||
// Wait for the complete notification
|
||||
wait_for_notification(function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.id, "addon-install-complete-notification", "Should have seen the second install complete");
|
||||
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
is(aInstalls.length, 2, "Should be two pending installs");
|
||||
aInstalls[0].cancel();
|
||||
aInstalls[1].cancel();
|
||||
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
runNextTest();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}, false);
|
||||
|
||||
// hide the panel (this simulates the user dismissing it)
|
||||
aPanel.hidePopup();
|
||||
});
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -60,6 +60,7 @@ function test () {
|
||||
[ 'select', false, null],
|
||||
[ 'output', true, null],
|
||||
[ 'fieldset', true, null],
|
||||
[ 'object', 'false' ],
|
||||
];
|
||||
|
||||
for each (let data in testData) {
|
||||
@ -68,7 +69,6 @@ function test () {
|
||||
|
||||
let todo_testData = [
|
||||
[ 'keygen', 'false' ],
|
||||
[ 'object', 'false' ],
|
||||
];
|
||||
|
||||
for each(let data in todo_testData) {
|
||||
|
@ -327,10 +327,11 @@ var tests = [
|
||||
this.notification.remove();
|
||||
}
|
||||
},
|
||||
// Test that anchor icon appears
|
||||
// Test that icons appear
|
||||
{ // Test #11
|
||||
run: function () {
|
||||
this.notifyObj = new basicNotification();
|
||||
this.notifyObj.id = "geolocation";
|
||||
this.notifyObj.anchorID = "geo-notification-icon";
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
},
|
||||
@ -477,8 +478,11 @@ function checkPopup(popup, notificationObj) {
|
||||
|
||||
is(notifications.length, 1, "only one notification displayed");
|
||||
let notification = notifications[0];
|
||||
let icon = document.getAnonymousElementByAttribute(notification, "class", "popup-notification-icon");
|
||||
if (notificationObj.id == "geolocation")
|
||||
isnot(icon.boxObject.width, 0, "icon for geo displayed");
|
||||
is(notification.getAttribute("label"), notificationObj.message, "message matches");
|
||||
is(notification.id, notificationObj.id, "id matches");
|
||||
is(notification.id, notificationObj.id + "-notification", "id matches");
|
||||
if (notificationObj.mainAction) {
|
||||
is(notification.getAttribute("buttonlabel"), notificationObj.mainAction.label, "main action label matches");
|
||||
is(notification.getAttribute("buttonaccesskey"), notificationObj.mainAction.accessKey, "main action accesskey matches");
|
||||
|
@ -894,8 +894,7 @@ let AboutHomeUtils = {
|
||||
|
||||
loadDefaultSearchEngine: function AHU_loadDefaultSearchEngine()
|
||||
{
|
||||
// TODO: should use originalDefaultEngine once available, see bug 587691.
|
||||
let defaultEngine = Services.search.defaultEngine;
|
||||
let defaultEngine = Services.search.originalDefaultEngine;
|
||||
let submission = defaultEngine.getSubmission("_searchTerms_");
|
||||
if (submission.postData)
|
||||
throw new Error("Home page does not support POST search engines.");
|
||||
|
@ -225,8 +225,7 @@ BrowserGlue.prototype = {
|
||||
Services.obs.removeObserver(this, "places-shutdown");
|
||||
this._isPlacesShutdownObserver = false;
|
||||
}
|
||||
// places-shutdown is fired on profile-before-change, but before
|
||||
// Places executes the last flush and closes connection.
|
||||
// places-shutdown is fired when the profile is about to disappear.
|
||||
this._onProfileShutdown();
|
||||
break;
|
||||
case "idle":
|
||||
|
@ -47,20 +47,47 @@ const URIS = [
|
||||
, "http://c.example3.com/"
|
||||
];
|
||||
|
||||
let expirationObserver = {
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
print("Finished expiration.");
|
||||
Services.obs.removeObserver(expirationObserver,
|
||||
PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
|
||||
let db = PlacesUtils.history
|
||||
.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
const TOPIC_CONNECTION_CLOSED = "places-connection-closed";
|
||||
|
||||
let stmt = db.createStatement(
|
||||
"SELECT id FROM moz_places_temp WHERE url = :page_url "
|
||||
+ "UNION ALL "
|
||||
+ "SELECT id FROM moz_places WHERE url = :page_url "
|
||||
let EXPECTED_NOTIFICATIONS = [
|
||||
"places-shutdown"
|
||||
, "places-will-close-connection"
|
||||
, "places-connection-closing"
|
||||
, "places-sync-finished"
|
||||
, "places-expiration-finished"
|
||||
, "places-sync-finished"
|
||||
, "places-connection-closed"
|
||||
];
|
||||
|
||||
const UNEXPECTED_NOTIFICATIONS = [
|
||||
"xpcom-shutdown"
|
||||
];
|
||||
|
||||
const URL = "ftp://localhost/clearHistoryOnShutdown/";
|
||||
|
||||
let notificationIndex = 0;
|
||||
|
||||
let notificationsObserver = {
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
print("Received notification: " + aTopic);
|
||||
|
||||
// Note that some of these notifications could arrive multiple times, for
|
||||
// example in case of sync, we allow that.
|
||||
if (EXPECTED_NOTIFICATIONS[notificationIndex] != aTopic)
|
||||
notificationIndex++;
|
||||
do_check_eq(EXPECTED_NOTIFICATIONS[notificationIndex], aTopic);
|
||||
|
||||
if (aTopic != TOPIC_CONNECTION_CLOSED)
|
||||
return;
|
||||
|
||||
getDistinctNotifications().forEach(
|
||||
function (topic) Services.obs.removeObserver(notificationsObserver, topic)
|
||||
);
|
||||
|
||||
print("Looking for uncleared stuff.");
|
||||
|
||||
let stmt = DBConn().createStatement(
|
||||
"SELECT id FROM moz_places WHERE url = :page_url "
|
||||
);
|
||||
|
||||
try {
|
||||
@ -73,6 +100,9 @@ let expirationObserver = {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
// Check cache.
|
||||
do_check_false(cacheExists(URL));
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
@ -104,11 +134,60 @@ function run_test() {
|
||||
PlacesUtils.history.TRANSITION_TYPED,
|
||||
false, 0);
|
||||
});
|
||||
print("Add cache.");
|
||||
storeCache(URL, "testData");
|
||||
|
||||
print("Wait expiration.");
|
||||
Services.obs.addObserver(expirationObserver,
|
||||
PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
||||
print("Simulate shutdown.");
|
||||
PlacesUtils.history.QueryInterface(Ci.nsIObserver)
|
||||
.observe(null, TOPIC_GLOBAL_SHUTDOWN, null);
|
||||
print("Simulate and wait shutdown.");
|
||||
getDistinctNotifications().forEach(
|
||||
function (topic)
|
||||
Services.obs.addObserver(notificationsObserver, topic, false)
|
||||
);
|
||||
|
||||
shutdownPlaces();
|
||||
}
|
||||
|
||||
function getDistinctNotifications() {
|
||||
let ar = EXPECTED_NOTIFICATIONS.concat(UNEXPECTED_NOTIFICATIONS);
|
||||
return [ar[i] for (i in ar) if (ar.slice(0, i).indexOf(ar[i]) == -1)];
|
||||
}
|
||||
|
||||
function storeCache(aURL, aContent) {
|
||||
let cache = Cc["@mozilla.org/network/cache-service;1"].
|
||||
getService(Ci.nsICacheService);
|
||||
let session = cache.createSession("FTP", Ci.nsICache.STORE_ANYWHERE,
|
||||
Ci.nsICache.STREAM_BASED);
|
||||
let cacheEntry =
|
||||
session.openCacheEntry(aURL, Ci.nsICache.ACCESS_READ_WRITE, false);
|
||||
|
||||
cacheEntry.setMetaDataElement("servertype", "0");
|
||||
var oStream = cacheEntry.openOutputStream(0);
|
||||
|
||||
var written = oStream.write(aContent, aContent.length);
|
||||
if (written != aContent.length) {
|
||||
do_throw("oStream.write has not written all data!\n" +
|
||||
" Expected: " + written + "\n" +
|
||||
" Actual: " + aContent.length + "\n");
|
||||
}
|
||||
oStream.close();
|
||||
cacheEntry.close();
|
||||
}
|
||||
|
||||
function cacheExists(aURL) {
|
||||
let cache = Cc["@mozilla.org/network/cache-service;1"].
|
||||
getService(Ci.nsICacheService);
|
||||
let session = cache.createSession("FTP", Ci.nsICache.STORE_ANYWHERE,
|
||||
Ci.nsICache.STREAM_BASED);
|
||||
try {
|
||||
let cacheEntry =
|
||||
session.openCacheEntry(aURL, Ci.nsICache.ACCESS_READ, true);
|
||||
} catch (e) {
|
||||
if (e.result == Cr.NS_ERROR_CACHE_KEY_NOT_FOUND ||
|
||||
e.result == Cr.NS_ERROR_FAILURE)
|
||||
return false;
|
||||
|
||||
// Throw the textual error description.
|
||||
do_throw(e);
|
||||
}
|
||||
cacheEntry.close();
|
||||
return true;
|
||||
}
|
||||
|
@ -68,6 +68,9 @@
|
||||
|
||||
<preference id="general.autoScroll" name="general.autoScroll" type="bool"/>
|
||||
<preference id="general.smoothScroll" name="general.smoothScroll" type="bool"/>
|
||||
#ifdef XP_WIN
|
||||
<preference id="gfx.direct2d.disabled" name="gfx.direct2d.disabled" type="bool" inverted="true"/>
|
||||
#endif
|
||||
<preference id="layout.spellcheckDefault" name="layout.spellcheckDefault" type="int"/>
|
||||
|
||||
#ifdef HAVE_SHELL_SERVICE
|
||||
@ -174,6 +177,12 @@
|
||||
label="&useSmoothScrolling.label;"
|
||||
accesskey="&useSmoothScrolling.accesskey;"
|
||||
preference="general.smoothScroll"/>
|
||||
#ifdef XP_WIN
|
||||
<checkbox id="allowHWAccel"
|
||||
label="&allowHWAccel.label;"
|
||||
accesskey="&allowHWAccel.accesskey;"
|
||||
preference="gfx.direct2d.disabled"/>
|
||||
#endif
|
||||
<checkbox id="checkSpelling"
|
||||
label="&checkSpelling.label;"
|
||||
accesskey="&checkSpelling.accesskey;"
|
||||
|
@ -16,7 +16,6 @@
|
||||
!define WindowClass "FirefoxMessageWindow"
|
||||
!define DDEApplication "Firefox"
|
||||
!define AppRegName "Firefox"
|
||||
!define MinSupportedVer "Microsoft Windows 2000"
|
||||
|
||||
!define BrandShortName "@MOZ_APP_DISPLAYNAME@"
|
||||
!define PreReleaseSuffix "@PRE_RELEASE_SUFFIX@"
|
||||
@ -38,3 +37,14 @@
|
||||
!if "@PRE_RELEASE_SUFFIX@" != ""
|
||||
!define NO_INSTDIR_FROM_REG
|
||||
!endif
|
||||
|
||||
# ARCH is used when it is necessary to differentiate the x64 registry keys from
|
||||
# the x86 registry keys (e.g. the uninstall registry key).
|
||||
#ifdef HAVE_64BIT_OS
|
||||
!define HAVE_64BIT_OS
|
||||
!define ARCH "x64"
|
||||
!define MinSupportedVer "Microsoft Windows Vista x64"
|
||||
#else
|
||||
!define ARCH "x86"
|
||||
!define MinSupportedVer "Microsoft Windows 2000"
|
||||
#endif
|
||||
|
@ -134,8 +134,11 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
|
||||
|
||||
Name "${BrandFullName}"
|
||||
OutFile "setup.exe"
|
||||
InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
|
||||
InstallDir "$PROGRAMFILES\${BrandFullName}\"
|
||||
!ifdef HAVE_64BIT_OS
|
||||
InstallDir "$PROGRAMFILES64\${BrandFullName}\"
|
||||
!else
|
||||
InstallDir "$PROGRAMFILES32\${BrandFullName}\"
|
||||
!endif
|
||||
ShowInstDetails nevershow
|
||||
|
||||
################################################################################
|
||||
@ -248,7 +251,7 @@ Section "-Application" APP_IDX
|
||||
; registered. bug 338878
|
||||
${LogHeader} "DLL Registration"
|
||||
ClearErrors
|
||||
RegDLL "$INSTDIR\AccessibleMarshal.dll"
|
||||
${RegisterDLL} "$INSTDIR\AccessibleMarshal.dll"
|
||||
${If} ${Errors}
|
||||
${LogMsg} "** ERROR Registering: $INSTDIR\AccessibleMarshal.dll **"
|
||||
${Else}
|
||||
@ -551,7 +554,7 @@ Function CustomAbort
|
||||
${Else}
|
||||
UAC::ExecCodeSegment $0
|
||||
${EndIf}
|
||||
|
||||
|
||||
CustomAbort_finish:
|
||||
Return
|
||||
${EndUnless}
|
||||
@ -1002,8 +1005,7 @@ Function .onInit
|
||||
|
||||
; There must always be a core directory.
|
||||
${GetSize} "$EXEDIR\core\" "/S=0K" $R5 $R7 $R8
|
||||
IntOp $R8 $R5 + $R6
|
||||
SectionSetSize ${APP_IDX} $R8
|
||||
SectionSetSize ${APP_IDX} $R5
|
||||
|
||||
; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
|
||||
; the user clicks the back button
|
||||
|
@ -289,7 +289,7 @@
|
||||
WriteRegStr HKLM "$0\Capabilities" "ApplicationIcon" "$8,0"
|
||||
WriteRegStr HKLM "$0\Capabilities" "ApplicationName" "${BrandShortName}"
|
||||
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".htm" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".htm" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".html" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".shtml" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".xht" "FirefoxHTML"
|
||||
@ -331,7 +331,7 @@
|
||||
${WriteRegStr2} $TmpVal "$0" "PathToExe" "$8\${FileMainEXE}" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
|
||||
${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} (${AppVersion})" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${AppVersion} (${AB_CD})" 0
|
||||
@ -355,7 +355,7 @@
|
||||
; Add uninstall registry entries. This macro tests for write access to determine
|
||||
; if the uninstall keys should be added to HKLM or HKCU.
|
||||
!macro SetUninstallKeys
|
||||
StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})"
|
||||
StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})"
|
||||
|
||||
WriteRegStr HKLM "$0" "${BrandShortName}InstallerTest" "Write Test"
|
||||
${If} ${Errors}
|
||||
@ -370,10 +370,10 @@
|
||||
${GetLongPath} "$INSTDIR" $8
|
||||
|
||||
; Write the uninstall registry keys
|
||||
${WriteRegStr2} $1 "$0" "Comments" "${BrandFullNameInternal}" 0
|
||||
${WriteRegStr2} $1 "$0" "Comments" "${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})" 0
|
||||
${WriteRegStr2} $1 "$0" "DisplayIcon" "$8\${FileMainEXE},0" 0
|
||||
${WriteRegStr2} $1 "$0" "DisplayName" "${BrandFullNameInternal} (${AppVersion})" 0
|
||||
${WriteRegStr2} $1 "$0" "DisplayVersion" "${AppVersion} (${AB_CD})" 0
|
||||
${WriteRegStr2} $1 "$0" "DisplayName" "${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})" 0
|
||||
${WriteRegStr2} $1 "$0" "DisplayVersion" "${AppVersion}" 0
|
||||
${WriteRegStr2} $1 "$0" "InstallLocation" "$8" 0
|
||||
${WriteRegStr2} $1 "$0" "Publisher" "Mozilla" 0
|
||||
${WriteRegStr2} $1 "$0" "UninstallString" "$8\uninstall\helper.exe" 0
|
||||
@ -382,6 +382,9 @@
|
||||
${WriteRegDWORD2} $1 "$0" "NoModify" 1 0
|
||||
${WriteRegDWORD2} $1 "$0" "NoRepair" 1 0
|
||||
|
||||
${GetSize} "$8" "/S=0K" $R2 $R3 $R4
|
||||
${WriteRegDWORD2} $1 "$0" "EstimatedSize" $R2 0
|
||||
|
||||
${If} "$TmpVal" == "HKLM"
|
||||
SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM)
|
||||
${Else}
|
||||
|
@ -70,6 +70,7 @@ Var TmpVal
|
||||
!include WinVer.nsh
|
||||
!include WordFunc.nsh
|
||||
|
||||
!insertmacro GetSize
|
||||
!insertmacro StrFilter
|
||||
!insertmacro WordReplace
|
||||
|
||||
@ -133,11 +134,15 @@ VIAddVersionKey "OriginalFilename" "helper.exe"
|
||||
!insertmacro UninstallOnInitCommon
|
||||
|
||||
!insertmacro un.OnEndCommon
|
||||
!insertmacro un.UninstallUnOnInitCommon
|
||||
|
||||
Name "${BrandFullName}"
|
||||
OutFile "helper.exe"
|
||||
InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
|
||||
InstallDir "$PROGRAMFILES\${BrandFullName}"
|
||||
!ifdef HAVE_64BIT_OS
|
||||
InstallDir "$PROGRAMFILES64\${BrandFullName}\"
|
||||
!else
|
||||
InstallDir "$PROGRAMFILES32\${BrandFullName}\"
|
||||
!endif
|
||||
ShowUnInstDetails nevershow
|
||||
|
||||
################################################################################
|
||||
@ -209,7 +214,7 @@ Section "Uninstall"
|
||||
${If} ${Errors}
|
||||
; If the user closed the application it can take several seconds for it to
|
||||
; shut down completely. If the application is being used by another user we
|
||||
; can still delete the files when the system is restarted.
|
||||
; can still delete the files when the system is restarted.
|
||||
Sleep 5000
|
||||
${DeleteFile} "$INSTDIR\${FileMainEXE}"
|
||||
ClearErrors
|
||||
@ -571,18 +576,9 @@ Function .onInit
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
${un.GetParent} "$INSTDIR" $INSTDIR
|
||||
${un.GetLongPath} "$INSTDIR" $INSTDIR
|
||||
${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}"
|
||||
Abort
|
||||
${EndUnless}
|
||||
|
||||
StrCpy $LANGUAGE 0
|
||||
${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
|
||||
|
||||
; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
|
||||
; the user clicks the back button
|
||||
StrCpy $hHeaderBitmap ""
|
||||
${un.UninstallUnOnInitCommon}
|
||||
|
||||
!insertmacro InitInstallOptionsFile "unconfirm.ini"
|
||||
FunctionEnd
|
||||
|
@ -17,6 +17,8 @@
|
||||
<!ENTITY useAutoScroll.accesskey "a">
|
||||
<!ENTITY useSmoothScrolling.label "Use smooth scrolling">
|
||||
<!ENTITY useSmoothScrolling.accesskey "m">
|
||||
<!ENTITY allowHWAccel.label "Use hardware acceleration when available">
|
||||
<!ENTITY allowHWAccel.accesskey "h">
|
||||
<!ENTITY checkSpelling.label "Check my spelling as I type">
|
||||
<!ENTITY checkSpelling.accesskey "t">
|
||||
|
||||
|
@ -1236,7 +1236,7 @@ statusbarpanel#statusbar-display {
|
||||
}
|
||||
|
||||
.tabbrowser-tab[pinned] > .tab-icon-image {
|
||||
margin: 2px 0 0;
|
||||
margin: 2px 2px 0;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[busy] > .tab-icon-image {
|
||||
|
@ -1391,10 +1391,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
height: 16px;
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
-moz-margin-end: 3px;
|
||||
}
|
||||
|
||||
.tabbrowser-tab:not([pinned]) > .tab-icon-image {
|
||||
-moz-margin-end: 3px;
|
||||
.tabbrowser-tab[pinned] > .tab-icon-image {
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: 2px;
|
||||
}
|
||||
|
||||
/* tabbrowser-tab focus ring */
|
||||
|
@ -52,6 +52,7 @@ MOZ_APP_NAME = @MOZ_APP_NAME@
|
||||
MOZ_APP_DISPLAYNAME = @MOZ_APP_DISPLAYNAME@
|
||||
MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
|
||||
MOZ_APP_VERSION = @MOZ_APP_VERSION@
|
||||
MOZ_UA_FIREFOX_VERSION = @FIREFOX_VERSION@
|
||||
|
||||
MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
|
||||
|
||||
|
@ -8771,7 +8771,8 @@ AC_DEFINE_UNQUOTED(MOZ_APP_UA_NAME, "$MOZ_APP_UA_NAME")
|
||||
AC_SUBST(MOZ_APP_UA_NAME)
|
||||
AC_DEFINE_UNQUOTED(MOZ_APP_VERSION, "$MOZ_APP_VERSION")
|
||||
AC_SUBST(MOZ_APP_VERSION)
|
||||
AC_DEFINE_UNQUOTED(FIREFOX_VERSION, "$FIREFOX_VERSION")
|
||||
AC_DEFINE_UNQUOTED(MOZ_UA_FIREFOX_VERSION, "$FIREFOX_VERSION")
|
||||
AC_SUBST(MOZ_UA_FIREFOX_VERSION)
|
||||
AC_SUBST(FIREFOX_VERSION)
|
||||
|
||||
AC_SUBST(MOZ_PKG_SPECIAL)
|
||||
|
@ -1698,6 +1698,20 @@ nsContentSink::ContinueInterruptedParsingAsync()
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsContentSink::NotifyDocElementCreated(nsIDocument* aDoc)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
|
||||
observerService->
|
||||
NotifyObservers(domDoc, "document-element-inserted",
|
||||
EmptyString().get());
|
||||
}
|
||||
}
|
||||
|
||||
// URIs: action, href, src, longdesc, usemap, cite
|
||||
PRBool
|
||||
IsAttrURI(nsIAtom *aName)
|
||||
|
@ -270,6 +270,9 @@ protected:
|
||||
// stylesheets are all done loading.
|
||||
public:
|
||||
void StartLayout(PRBool aIgnorePendingSheets);
|
||||
|
||||
static void NotifyDocElementCreated(nsIDocument* aDoc);
|
||||
|
||||
protected:
|
||||
void
|
||||
FavorPerformanceHint(PRBool perfOverStarvation, PRUint32 starvationDelay);
|
||||
|
@ -845,7 +845,9 @@ ExternalResourceShower(nsIURI* aKey,
|
||||
nsExternalResourceMap::ExternalResource* aData,
|
||||
void* aClosure)
|
||||
{
|
||||
aData->mViewer->Show();
|
||||
if (aData->mViewer) {
|
||||
aData->mViewer->Show();
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
@ -4297,7 +4299,7 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
PRInt32 ns = nodeInfo->NamespaceID();
|
||||
NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(), PR_FALSE);
|
||||
rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(), PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(content, aReturn);
|
||||
|
@ -767,75 +767,11 @@ nsFrameLoader::ShowRemoteFrame(nsIFrameFrame* frame, nsIView* view)
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIWidget* w = view->GetWidget();
|
||||
if (!w) {
|
||||
NS_ERROR("Our view doesn't have a widget. Totally stuffed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIntSize size = GetSubDocumentSize(frame->GetFrame());
|
||||
|
||||
#ifdef XP_WIN
|
||||
HWND parentwin =
|
||||
static_cast<HWND>(w->GetNativeData(NS_NATIVE_WINDOW));
|
||||
|
||||
if (!mRemoteBrowser->SendCreateWidget(parentwin))
|
||||
return false;
|
||||
#elif defined(MOZ_WIDGET_GTK2)
|
||||
GdkWindow* parent_win =
|
||||
static_cast<GdkWindow*>(w->GetNativeData(NS_NATIVE_WINDOW));
|
||||
|
||||
gpointer user_data = nsnull;
|
||||
gdk_window_get_user_data(parent_win, &user_data);
|
||||
|
||||
MozContainer* parentMozContainer = MOZ_CONTAINER(user_data);
|
||||
GtkContainer* container = GTK_CONTAINER(parentMozContainer);
|
||||
|
||||
// create the socket for the child and add it to our view's widget
|
||||
mRemoteSocket = gtk_socket_new();
|
||||
gtk_widget_set_parent_window(mRemoteSocket, parent_win);
|
||||
gtk_container_add(container, mRemoteSocket);
|
||||
gtk_widget_realize(mRemoteSocket);
|
||||
|
||||
// set the child window's size and position
|
||||
GtkAllocation alloc = { 0, 0, size.width, size.height };
|
||||
gtk_widget_size_allocate(mRemoteSocket, &alloc);
|
||||
|
||||
gtk_widget_show(mRemoteSocket);
|
||||
GdkNativeWindow id = gtk_socket_get_id(GTK_SOCKET(mRemoteSocket));
|
||||
if (!mRemoteBrowser->SendCreateWidget(id))
|
||||
return false;
|
||||
|
||||
#elif defined(MOZ_WIDGET_QT)
|
||||
if (getenv("USE_XEMBED_PROXY")) {
|
||||
// Very bad idea to use Xembedding for IPC, but test-ipc.xul still rendering with XEmbed
|
||||
QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(w->GetNativeData(NS_NATIVE_WINDOW));
|
||||
NS_ENSURE_TRUE(widget, false);
|
||||
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(widget);
|
||||
NS_ENSURE_TRUE(proxy, false);
|
||||
mRemoteSocket = new QX11EmbedContainer();
|
||||
NS_ENSURE_TRUE(mRemoteSocket, false);
|
||||
proxy->setWidget(mRemoteSocket);
|
||||
mRemoteSocket->show();
|
||||
mRemoteSocket->resize(size.width, size.height);
|
||||
if (!mRemoteBrowser->SendCreateWidget(0))
|
||||
return false;
|
||||
} else {
|
||||
// Don't create any parent/child XEmbed, because we are painting with shared memory
|
||||
if (!mRemoteBrowser->SendCreateWidget(0))
|
||||
return false;
|
||||
}
|
||||
#elif defined(ANDROID)
|
||||
// Painting with shared memory
|
||||
|
||||
if (!mRemoteBrowser->SendCreateWidget(0))
|
||||
return false;
|
||||
#elif defined(XP_MACOSX)
|
||||
# warning IMPLEMENT ME
|
||||
|
||||
#else
|
||||
#error TODO for this platform
|
||||
#endif
|
||||
|
||||
mRemoteBrowser->Move(0, 0, size.width, size.height);
|
||||
mRemoteWidgetCreated = PR_TRUE;
|
||||
|
@ -17,3 +17,4 @@ load 515829-2.html
|
||||
load 570566-1.html
|
||||
load 571428-1.html
|
||||
load 580507-1.xhtml
|
||||
load 590387.html
|
||||
|
@ -50,10 +50,13 @@
|
||||
#include "nsFormSubmission.h"
|
||||
#include "nsIObjectFrame.h"
|
||||
#include "nsIPluginInstance.h"
|
||||
#include "nsIConstraintValidation.h"
|
||||
|
||||
|
||||
class nsHTMLObjectElement : public nsGenericHTMLFormElement,
|
||||
public nsObjectLoadingContent,
|
||||
public nsIDOMHTMLObjectElement
|
||||
public nsIDOMHTMLObjectElement,
|
||||
public nsIConstraintValidation
|
||||
#ifdef MOZ_SVG
|
||||
, public nsIDOMGetSVGDocument
|
||||
#endif
|
||||
@ -127,6 +130,9 @@ public:
|
||||
|
||||
void StartObjectLoad() { StartObjectLoad(PR_TRUE); }
|
||||
|
||||
// nsIConstraintValidation
|
||||
PRBool IsBarredFromConstraintValidation() const { return PR_TRUE; }
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLObjectElement,
|
||||
nsGenericHTMLFormElement)
|
||||
|
||||
@ -201,6 +207,7 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLObjectElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIContainerObserver)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIInterfaceRequestor)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIChannelEventSink)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIConstraintValidation)
|
||||
#ifdef MOZ_SVG
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIDOMGetSVGDocument)
|
||||
#endif
|
||||
@ -211,6 +218,8 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLObjectElement)
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(nsHTMLObjectElement)
|
||||
|
||||
// nsIConstraintValidation
|
||||
NS_IMPL_NSICONSTRAINTVALIDATION(nsHTMLObjectElement)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLObjectElement::GetForm(nsIDOMHTMLFormElement **aForm)
|
||||
|
@ -9,7 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=345624
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
input, textarea, fieldset, button, select, keygen, output { background-color: rgb(0,0,0) !important; }
|
||||
input, textarea, fieldset, button, select, keygen, output, object { background-color: rgb(0,0,0) !important; }
|
||||
:valid { background-color: rgb(0,255,0) !important; }
|
||||
:invalid { background-color: rgb(255,0,0) !important; }
|
||||
</style>
|
||||
@ -25,6 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=345624
|
||||
<textarea id='t' oninvalid="invalidEventHandler(event);"></textarea>
|
||||
<keygen id='k'></keygen>
|
||||
<output id='o'></output>
|
||||
<object id='obj'></object>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
@ -96,6 +97,10 @@ function checkDefaultPseudoClass()
|
||||
.getPropertyValue('background-color'), "rgb(0, 0, 0)",
|
||||
"Nor :valid and :invalid should apply");
|
||||
|
||||
is(window.getComputedStyle(document.getElementById('obj'), null)
|
||||
.getPropertyValue('background-color'), "rgb(0, 0, 0)",
|
||||
"Nor :valid and :invalid should apply");
|
||||
|
||||
todo_is(window.getComputedStyle(document.getElementById('k'), null)
|
||||
.getPropertyValue('background-color'), "rgb(0, 0, 0)",
|
||||
"Nor :valid and :invalid should apply");
|
||||
@ -119,9 +124,10 @@ function checkDefaultPseudoClass()
|
||||
|
||||
function checkSpecificWillValidate()
|
||||
{
|
||||
// fieldset, output, keygen (TODO) and select elements
|
||||
// fieldset, output, object, keygen (TODO) and select elements
|
||||
ok(!document.getElementById('f').willValidate, "Fielset element should be barred from constraint validation");
|
||||
ok(!document.getElementById('o').willValidate, "Output element should be barred from constraint validation");
|
||||
ok(!document.getElementById('obj').willValidate, "Object element should be barred from constraint validation");
|
||||
todo(!document.getElementById('k').willValidate, "Keygen element should be barred from constraint validation");
|
||||
ok(document.getElementById('s').willValidate, "Select element should not be barred from constraint validation");
|
||||
|
||||
@ -175,7 +181,6 @@ function checkSpecificWillValidate()
|
||||
is(window.getComputedStyle(t, null).getPropertyValue('background-color'),
|
||||
"rgb(0, 255, 0)", ":valid pseudo-class should apply");
|
||||
|
||||
// TODO: output elements are always barred from constraint validation.
|
||||
// TODO: PROGRESS
|
||||
// TODO: METER
|
||||
}
|
||||
@ -273,6 +278,7 @@ checkConstraintValidationAPIExist(document.getElementById('s'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('t'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('k'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('o'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('obj'));
|
||||
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('f'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('i'));
|
||||
@ -281,12 +287,13 @@ checkConstraintValidationAPIDefaultValues(document.getElementById('s'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('t'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('k'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('o'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('obj'));
|
||||
|
||||
checkDefaultPseudoClass();
|
||||
|
||||
checkSpecificWillValidate();
|
||||
|
||||
// Not checking fieldset, output and keygen
|
||||
// Not checking fieldset, output, object and keygen
|
||||
// because they are always barred from constraint validation.
|
||||
checkCommonWillValidate(document.getElementById('i'));
|
||||
checkCommonWillValidate(document.getElementById('b'));
|
||||
@ -300,8 +307,9 @@ checkCustomError(document.getElementById('s'), false);
|
||||
checkCustomError(document.getElementById('t'), false);
|
||||
checkCustomError(document.getElementById('f'), true);
|
||||
checkCustomError(document.getElementById('o'), true);
|
||||
checkCustomError(document.getElementById('obj'), true);
|
||||
|
||||
// Not checking fieldset, output and keygen
|
||||
// Not checking fieldset, output, object and keygen
|
||||
// because they are always barred from constraint validation.
|
||||
checkCheckValidity(document.getElementById('i'));
|
||||
checkCheckValidity(document.getElementById('b'));
|
||||
@ -315,6 +323,7 @@ checkValidityStateObjectAliveWithoutElement("button");
|
||||
checkValidityStateObjectAliveWithoutElement("select");
|
||||
checkValidityStateObjectAliveWithoutElement("textarea");
|
||||
checkValidityStateObjectAliveWithoutElement("output");
|
||||
checkValidityStateObjectAliveWithoutElement("object");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -60,9 +60,8 @@ const PRUint32 MSEC_PER_MIN = 1000 * 60;
|
||||
const PRUint32 MSEC_PER_HOUR = 1000 * 60 * 60;
|
||||
const PRInt32 DECIMAL_BASE = 10;
|
||||
|
||||
// XXX SVG/SMIL Animation use 'accessKey' whilst SMIL3 uses 'accesskey'
|
||||
// We should allow both
|
||||
#define ACCESSKEY_PREFIX NS_LITERAL_STRING("accessKey(")
|
||||
#define ACCESSKEY_PREFIX_LC NS_LITERAL_STRING("accesskey(") // SMIL2+
|
||||
#define ACCESSKEY_PREFIX_CC NS_LITERAL_STRING("accessKey(") // SVG/SMIL ANIM
|
||||
#define REPEAT_PREFIX NS_LITERAL_STRING("repeat(")
|
||||
#define WALLCLOCK_PREFIX NS_LITERAL_STRING("wallclock(")
|
||||
|
||||
@ -264,13 +263,17 @@ ParseOptionalOffset(const nsAString& aSpec, nsSMILTimeValueSpecParams& aResult)
|
||||
nsresult
|
||||
ParseAccessKey(const nsAString& aSpec, nsSMILTimeValueSpecParams& aResult)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(StringBeginsWith(aSpec, ACCESSKEY_PREFIX),
|
||||
NS_ABORT_IF_FALSE(StringBeginsWith(aSpec, ACCESSKEY_PREFIX_CC) ||
|
||||
StringBeginsWith(aSpec, ACCESSKEY_PREFIX_LC),
|
||||
"Calling ParseAccessKey on non-accesskey-type spec");
|
||||
|
||||
nsSMILTimeValueSpecParams result;
|
||||
result.mType = nsSMILTimeValueSpecParams::ACCESSKEY;
|
||||
|
||||
const PRUnichar* start = aSpec.BeginReading() + ACCESSKEY_PREFIX.Length();
|
||||
NS_ABORT_IF_FALSE(
|
||||
ACCESSKEY_PREFIX_LC.Length() == ACCESSKEY_PREFIX_CC.Length(),
|
||||
"Case variations for accesskey prefix differ in length");
|
||||
const PRUnichar* start = aSpec.BeginReading() + ACCESSKEY_PREFIX_LC.Length();
|
||||
const PRUnichar* end = aSpec.EndReading();
|
||||
|
||||
// Expecting at least <accesskey> + ')'
|
||||
@ -703,7 +706,8 @@ nsSMILParserUtils::ParseTimeValueSpecParams(const nsAString& aSpec,
|
||||
}
|
||||
|
||||
// accesskey type
|
||||
else if (StringBeginsWith(spec, ACCESSKEY_PREFIX)) {
|
||||
else if (StringBeginsWith(spec, ACCESSKEY_PREFIX_LC) ||
|
||||
StringBeginsWith(spec, ACCESSKEY_PREFIX_CC)) {
|
||||
rv = ParseAccessKey(spec, aResult);
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,8 @@ nsSMILTimeValueSpec::SetSpec(const nsAString& aStringSpec,
|
||||
// Fill in the event symbol to simplify handling later
|
||||
if (mParams.mType == nsSMILTimeValueSpecParams::REPEAT) {
|
||||
mParams.mEventSymbol = nsGkAtoms::repeatEvent;
|
||||
} else if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
|
||||
mParams.mEventSymbol = nsGkAtoms::keypress;
|
||||
}
|
||||
|
||||
ResolveReferences(aContextNode);
|
||||
@ -131,9 +133,7 @@ nsSMILTimeValueSpec::SetSpec(const nsAString& aStringSpec,
|
||||
void
|
||||
nsSMILTimeValueSpec::ResolveReferences(nsIContent* aContextNode)
|
||||
{
|
||||
if (mParams.mType != nsSMILTimeValueSpecParams::SYNCBASE &&
|
||||
mParams.mType != nsSMILTimeValueSpecParams::EVENT &&
|
||||
mParams.mType != nsSMILTimeValueSpecParams::REPEAT)
|
||||
if (mParams.mType != nsSMILTimeValueSpecParams::SYNCBASE && !IsEventBased())
|
||||
return;
|
||||
|
||||
NS_ABORT_IF_FALSE(aContextNode,
|
||||
@ -155,6 +155,10 @@ nsSMILTimeValueSpec::ResolveReferences(nsIContent* aContextNode)
|
||||
} else if (mParams.mType == nsSMILTimeValueSpecParams::EVENT) {
|
||||
Element* target = mOwner->GetTargetElement();
|
||||
mReferencedElement.ResetWithElement(target);
|
||||
} else if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
|
||||
nsIDocument* doc = aContextNode->GetCurrentDoc();
|
||||
NS_ABORT_IF_FALSE(doc, "We are in the document but current doc is null");
|
||||
mReferencedElement.ResetWithElement(doc->GetRootElement());
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "Syncbase or repeat spec without ID");
|
||||
}
|
||||
@ -277,11 +281,12 @@ nsSMILTimeValueSpec::UpdateReferencedElement(Element* aFrom, Element* aTo)
|
||||
|
||||
case nsSMILTimeValueSpecParams::EVENT:
|
||||
case nsSMILTimeValueSpecParams::REPEAT:
|
||||
case nsSMILTimeValueSpecParams::ACCESSKEY:
|
||||
RegisterEventListener(aTo);
|
||||
break;
|
||||
|
||||
default:
|
||||
// not a referencing-type or not yet supported
|
||||
// not a referencing-type
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -319,8 +324,7 @@ nsSMILTimeValueSpec::GetTimedElement(Element* aElement)
|
||||
void
|
||||
nsSMILTimeValueSpec::RegisterEventListener(Element* aTarget)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mParams.mType == nsSMILTimeValueSpecParams::EVENT ||
|
||||
mParams.mType == nsSMILTimeValueSpecParams::REPEAT,
|
||||
NS_ABORT_IF_FALSE(IsEventBased(),
|
||||
"Attempting to register event-listener for unexpected nsSMILTimeValueSpec"
|
||||
" type");
|
||||
NS_ABORT_IF_FALSE(mParams.mEventSymbol,
|
||||
@ -373,7 +377,23 @@ nsSMILTimeValueSpec::GetEventListenerManager(Element* aTarget,
|
||||
NS_ABORT_IF_FALSE(aSystemGroup && !*aSystemGroup,
|
||||
"Bad out param for system group");
|
||||
|
||||
nsIEventListenerManager* elm = aTarget->GetListenerManager(PR_TRUE);
|
||||
nsCOMPtr<nsPIDOMEventTarget> piTarget;
|
||||
|
||||
if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
|
||||
nsIDocument* doc = aTarget->GetCurrentDoc();
|
||||
if (!doc)
|
||||
return nsnull;
|
||||
nsPIDOMWindow* win = doc->GetWindow();
|
||||
if (!win)
|
||||
return nsnull;
|
||||
piTarget = do_QueryInterface(win);
|
||||
} else {
|
||||
piTarget = aTarget;
|
||||
}
|
||||
if (!piTarget)
|
||||
return nsnull;
|
||||
|
||||
nsIEventListenerManager* elm = piTarget->GetListenerManager(PR_TRUE);
|
||||
if (!elm)
|
||||
return nsnull;
|
||||
|
||||
@ -413,9 +433,23 @@ nsSMILTimeValueSpec::HandleEvent(nsIDOMEvent* aEvent)
|
||||
PRBool
|
||||
nsSMILTimeValueSpec::CheckEventDetail(nsIDOMEvent *aEvent)
|
||||
{
|
||||
if (mParams.mType != nsSMILTimeValueSpecParams::REPEAT)
|
||||
return PR_TRUE;
|
||||
switch (mParams.mType)
|
||||
{
|
||||
case nsSMILTimeValueSpecParams::REPEAT:
|
||||
return CheckRepeatEventDetail(aEvent);
|
||||
|
||||
case nsSMILTimeValueSpecParams::ACCESSKEY:
|
||||
return CheckAccessKeyEventDetail(aEvent);
|
||||
|
||||
default:
|
||||
// nothing to check
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSMILTimeValueSpec::CheckRepeatEventDetail(nsIDOMEvent *aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMTimeEvent> timeEvent = do_QueryInterface(aEvent);
|
||||
if (!timeEvent) {
|
||||
NS_WARNING("Received a repeat event that was not a DOMTimeEvent");
|
||||
@ -424,7 +458,64 @@ nsSMILTimeValueSpec::CheckEventDetail(nsIDOMEvent *aEvent)
|
||||
|
||||
PRInt32 detail;
|
||||
timeEvent->GetDetail(&detail);
|
||||
return detail == mParams.mRepeatIterationOrAccessKey;
|
||||
return detail > 0 && (PRUint32)detail == mParams.mRepeatIterationOrAccessKey;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSMILTimeValueSpec::CheckAccessKeyEventDetail(nsIDOMEvent *aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aEvent);
|
||||
if (!keyEvent) {
|
||||
NS_WARNING("Received an accesskey event that was not a DOMKeyEvent");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Ignore the key event if any modifier keys are pressed UNLESS we're matching
|
||||
// on the charCode in which case we ignore the state of the shift and alt keys
|
||||
// since they might be needed to generate the character in question.
|
||||
PRBool isCtrl;
|
||||
PRBool isMeta;
|
||||
keyEvent->GetCtrlKey(&isCtrl);
|
||||
keyEvent->GetMetaKey(&isMeta);
|
||||
if (isCtrl || isMeta)
|
||||
return PR_FALSE;
|
||||
|
||||
PRUint32 code;
|
||||
keyEvent->GetCharCode(&code);
|
||||
if (code)
|
||||
return code == mParams.mRepeatIterationOrAccessKey;
|
||||
|
||||
// Only match on the keyCode if it corresponds to some ASCII character that
|
||||
// does not produce a charCode.
|
||||
// In this case we can safely bail out if either alt or shift is pressed since
|
||||
// they won't already be incorporated into the keyCode unlike the charCode.
|
||||
PRBool isAlt;
|
||||
PRBool isShift;
|
||||
keyEvent->GetAltKey(&isAlt);
|
||||
keyEvent->GetShiftKey(&isShift);
|
||||
if (isAlt || isShift)
|
||||
return PR_FALSE;
|
||||
|
||||
keyEvent->GetKeyCode(&code);
|
||||
switch (code)
|
||||
{
|
||||
case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
|
||||
return mParams.mRepeatIterationOrAccessKey == 0x08;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_RETURN:
|
||||
case nsIDOMKeyEvent::DOM_VK_ENTER:
|
||||
return mParams.mRepeatIterationOrAccessKey == 0x0A ||
|
||||
mParams.mRepeatIterationOrAccessKey == 0x0D;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ESCAPE:
|
||||
return mParams.mRepeatIterationOrAccessKey == 0x1B;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_DELETE:
|
||||
return mParams.mRepeatIterationOrAccessKey == 0x7F;
|
||||
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
nsSMILTimeValue
|
||||
|
@ -99,6 +99,8 @@ protected:
|
||||
nsIDOMEventGroup** aSystemGroup);
|
||||
void HandleEvent(nsIDOMEvent* aEvent);
|
||||
PRBool CheckEventDetail(nsIDOMEvent* aEvent);
|
||||
PRBool CheckRepeatEventDetail(nsIDOMEvent* aEvent);
|
||||
PRBool CheckAccessKeyEventDetail(nsIDOMEvent* aEvent);
|
||||
nsSMILTimeValue ConvertBetweenTimeContainers(const nsSMILTimeValue& aSrcTime,
|
||||
const nsSMILTimeContainer* aSrcContainer);
|
||||
|
||||
|
@ -54,6 +54,7 @@ _TEST_FILES = \
|
||||
smilAnimateMotionValueLists.js \
|
||||
smilTestUtils.js \
|
||||
smilXHR_helper.svg \
|
||||
test_smilAccessKey.xhtml \
|
||||
test_smilAnimateMotion.xhtml \
|
||||
test_smilAnimateMotionInvalidValues.xhtml \
|
||||
test_smilAnimateMotionOverrideRules.xhtml \
|
||||
|
360
content/smil/test/test_smilAccessKey.xhtml
Normal file
360
content/smil/test/test_smilAccessKey.xhtml
Normal file
@ -0,0 +1,360 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Test for SMIL accessKey support</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=587910">Mozilla Bug
|
||||
587910</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
|
||||
<circle cx="20" cy="20" r="15" fill="blue" id="circle"/>
|
||||
</svg>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
/** Test for SMIL accessKey support **/
|
||||
|
||||
const gSvgns = "http://www.w3.org/2000/svg";
|
||||
var gSvg = document.getElementById("svg");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function main()
|
||||
{
|
||||
gSvg.pauseAnimations();
|
||||
|
||||
// Basic syntax
|
||||
testOk('accessKey(a)', 'a');
|
||||
testOk(' accessKey(a) ', 'a');
|
||||
testNotOk('accessKey (a)', 'a');
|
||||
testNotOk('accessKey( a)', 'a');
|
||||
testNotOk('accessKey(a )', 'a');
|
||||
testNotOk('accessKey(a)', 'b');
|
||||
testNotOk('accessKey()', ' ');
|
||||
|
||||
// Test the test framework itself
|
||||
testOk('accessKey(a)', 97);
|
||||
|
||||
// Allow for either accessKey (SVG / SMIL Animation) or accesskey (SMIL2+)
|
||||
testOk('accesskey(a)', 'a');
|
||||
|
||||
// Offset
|
||||
testOk('accessKey(a)+0s', 'a');
|
||||
testOk('accessKey(a) + 0min', 'a');
|
||||
testOk('accessKey(a) -0h', 'a');
|
||||
testOk('accessKey(a)+100ms', 'a', 0, 0.1);
|
||||
testOk('accessKey(a)-0.1s', 'a', 0, -0.1);
|
||||
|
||||
// Id references are not allowed
|
||||
testNotOk('svg.accessKey(a)', 'a');
|
||||
testNotOk('window.accessKey(a)', 'a');
|
||||
|
||||
// Case sensitivity
|
||||
testOk('accessKey(A)', 'A');
|
||||
testNotOk('accessKey(a)', 'A');
|
||||
testNotOk('accessKey(A)', 'a');
|
||||
|
||||
// Test unusual characters
|
||||
testOk('accessKey(-)', '-');
|
||||
testOk('accessKey(\\)', '\\');
|
||||
testOk('accessKey( )', ' ');
|
||||
testOk('accessKey(\x0D)', 0, 13); // Return
|
||||
testOk('accessKey(\x0D)', 0, 14); // Enter
|
||||
testOk('accessKey(\n)', 0, 13); // New line
|
||||
testOk('accessKey(\r)', 0, 13); // Carriage return
|
||||
testOk('accessKey(\x08)', 0, 8); // Backspace
|
||||
testOk('accessKey(\x1B)', 0, 0x1B); // Escape
|
||||
testOk('accessKey(\x7F)', 0, 46); // Del
|
||||
|
||||
// Check some disallowed keys
|
||||
// -- For now we don't allow tab since the interaction with focus causes
|
||||
// confusing results
|
||||
testNotOk('accessKey(\x09)', 0, 9); // Tab
|
||||
|
||||
// Test setting the keyCode field
|
||||
testNotOk('accessKey(a)', 0, 97);
|
||||
testOk('accessKey(a)', 97, 66); // Give priority to charCode field
|
||||
testNotOk('accessKey(a)', 98, 97); // Give priority to charCode field
|
||||
|
||||
// Test unicode
|
||||
testOk("accessKey(\u20AC)", 8364); // euro-symbol
|
||||
|
||||
// Test an astral character just to make sure we don't crash
|
||||
testOk("accessKey(\uD835\uDC00)", 119808); // mathematical bold capital A
|
||||
// 0x1D400
|
||||
// Test bad surrogate pairs don't confuse us either
|
||||
testNotOk("accessKey(\uD800\uD800)", 97);
|
||||
testNotOk("accessKey(\uD80020)", 97);
|
||||
testNotOk("accessKey(\uD800)", 97);
|
||||
|
||||
// Test modifiers
|
||||
// -- When matching on charCode ignore shift and alt
|
||||
testNotOk('accessKey(a)', 'a', 0, 0, { ctrl: true });
|
||||
testNotOk('accessKey(a)', 'a', 0, 0, { meta: true });
|
||||
testOk('accessKey(a)', 'a', 0, 0, { alt: true });
|
||||
testOk('accessKey(a)', 'a', 0, 0, { shift: true });
|
||||
testNotOk('accessKey(a)', 'a', 0, 0, { shift: true, ctrl: true });
|
||||
testNotOk('accessKey(a)', 'a', 0, 0, { alt: true, meta: true });
|
||||
// -- When matching on keyCode ignore all
|
||||
testNotOk('accessKey(\x0D)', 0, 13, 0, { ctrl: true });
|
||||
testNotOk('accessKey(\x0D)', 0, 13, 0, { meta: true });
|
||||
testNotOk('accessKey(\x0D)', 0, 13, 0, { alt: true });
|
||||
testNotOk('accessKey(\x0D)', 0, 13, 0, { shift: true });
|
||||
testNotOk('accessKey(\x0D)', 0, 13, 0, { shift: true, ctrl: true });
|
||||
|
||||
testOpenEnd();
|
||||
testPreventDefault();
|
||||
testDispatchToWindow();
|
||||
testAdoptNode();
|
||||
testFauxEvent();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function testOk(spec, charCode, keyCode, offset, modifiers)
|
||||
{
|
||||
if (typeof offset == 'undefined') offset = 0;
|
||||
var msg = "No interval created for '" + spec +
|
||||
"' with input [charCode: " + charCode + "; keyCode: " + keyCode + "]" +
|
||||
getModifiersDescr(modifiers);
|
||||
ok(test(spec, charCode, keyCode, offset, modifiers), msg);
|
||||
}
|
||||
|
||||
function testNotOk(spec, charCode, keyCode, offset, modifiers)
|
||||
{
|
||||
if (typeof offset == 'undefined') offset = 0;
|
||||
var msg = "Interval unexpectedly created for '" + spec +
|
||||
"' with input [charCode: " + charCode + "; keyCode: " + keyCode + "]" +
|
||||
getModifiersDescr(modifiers);
|
||||
ok(!test(spec, charCode, keyCode, offset, modifiers), msg);
|
||||
}
|
||||
|
||||
function getModifiersDescr(modifiers)
|
||||
{
|
||||
if (typeof modifiers != 'object')
|
||||
return '';
|
||||
var str = ' modifiers set:';
|
||||
for (var key in modifiers) {
|
||||
if (modifiers[key]) str += ' ' + key;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function test(spec, charCode, keyCode, offset, modifiers)
|
||||
{
|
||||
gSvg.setCurrentTime(1);
|
||||
ok(gSvg.animationsPaused(), "Expected animations to be paused");
|
||||
|
||||
var anim = createAnim(spec);
|
||||
var evt = createEvent(charCode, keyCode, modifiers);
|
||||
|
||||
document.getElementById('circle').dispatchEvent(evt);
|
||||
|
||||
var gotStartTimeOk = true;
|
||||
try {
|
||||
var start = anim.getStartTime();
|
||||
if (offset) {
|
||||
var expected = gSvg.getCurrentTime() + offset;
|
||||
ok(Math.abs(expected - start) <= 0.00001,
|
||||
"Unexpected start time for animation with begin: " + spec +
|
||||
" got " + start + ", expected " + expected);
|
||||
} else {
|
||||
is(start, gSvg.getCurrentTime() + offset,
|
||||
"Unexpected start time for animation with begin: " + spec);
|
||||
}
|
||||
} catch(e) {
|
||||
is(e.code, DOMException.INVALID_STATE_ERR,
|
||||
"Unexpected exception code: " + e);
|
||||
gotStartTimeOk = false;
|
||||
}
|
||||
|
||||
removeElement(anim);
|
||||
|
||||
return gotStartTimeOk;
|
||||
}
|
||||
|
||||
function createAnim(beginSpec)
|
||||
{
|
||||
var anim = document.createElementNS(gSvgns, 'animate');
|
||||
anim.setAttribute('attributeName', 'cx');
|
||||
anim.setAttribute('values', '0; 100');
|
||||
anim.setAttribute('dur', '10s');
|
||||
anim.setAttribute('begin', beginSpec);
|
||||
return document.getElementById('circle').appendChild(anim);
|
||||
}
|
||||
|
||||
function createEvent(charCode, keyCode, modifiers)
|
||||
{
|
||||
if (typeof charCode == 'string') {
|
||||
is(charCode.length, 1,
|
||||
"If charCode is a string it should be 1 character long");
|
||||
charCode = charCode.charCodeAt(0);
|
||||
} else if (typeof charCode == 'undefined') {
|
||||
charCode = 0;
|
||||
}
|
||||
args = { ctrl: false, alt: false, shift: false, meta: false };
|
||||
if (typeof modifiers == 'object') {
|
||||
for (var key in modifiers)
|
||||
args[key] = modifiers[key];
|
||||
}
|
||||
if (typeof keyCode == 'undefined') keyCode = 0;
|
||||
var evt = document.createEvent("KeyboardEvent");
|
||||
evt.initKeyEvent("keypress", true, true, window,
|
||||
args['ctrl'],
|
||||
args['alt'],
|
||||
args['shift'],
|
||||
args['meta'],
|
||||
keyCode,
|
||||
charCode);
|
||||
return evt;
|
||||
}
|
||||
|
||||
function testOpenEnd()
|
||||
{
|
||||
// Test that an end specification with an accesskey value is treated as open
|
||||
// ended
|
||||
gSvg.setCurrentTime(0);
|
||||
ok(gSvg.animationsPaused(), "Expected animations to be paused");
|
||||
|
||||
var anim = createAnim('0s; 2s');
|
||||
anim.setAttribute('end', '1s; accessKey(a)');
|
||||
|
||||
gSvg.setCurrentTime(2);
|
||||
|
||||
try {
|
||||
is(anim.getStartTime(), 2,
|
||||
"Unexpected start time for second interval of open-ended animation");
|
||||
} catch(e) {
|
||||
is(e.code, DOMException.INVALID_STATE_ERR,
|
||||
"Unexpected exception code:" + e.code);
|
||||
ok(false, "Failed to recognise accessKey as qualifying for creating an " +
|
||||
"open-ended interval");
|
||||
}
|
||||
|
||||
removeElement(anim);
|
||||
}
|
||||
|
||||
function testPreventDefault()
|
||||
{
|
||||
// SVG/SMIL don't specify what should happen if preventDefault is called on
|
||||
// the keypress event. For now, for consistency with event timing we ignore
|
||||
// it.
|
||||
gSvg.setCurrentTime(1);
|
||||
ok(gSvg.animationsPaused(), "Expected animations to be paused");
|
||||
|
||||
var anim = createAnim('accessKey(a)');
|
||||
var evt = createEvent('a');
|
||||
|
||||
var circle = document.getElementById('circle');
|
||||
var func = function(evt) { evt.preventDefault(); }
|
||||
circle.addEventListener('keypress', func, false);
|
||||
circle.dispatchEvent(evt);
|
||||
|
||||
try {
|
||||
var start = anim.getStartTime();
|
||||
} catch(e) {
|
||||
ok(false, "preventDefault() cancelled accessKey handling");
|
||||
}
|
||||
|
||||
circle.removeEventListener('keypress', func, false);
|
||||
removeElement(anim);
|
||||
}
|
||||
|
||||
function testDispatchToWindow()
|
||||
{
|
||||
gSvg.setCurrentTime(1);
|
||||
ok(gSvg.animationsPaused(), "Expected animations to be paused");
|
||||
|
||||
var anim = createAnim('accessKey(a)');
|
||||
var evt = createEvent('a');
|
||||
|
||||
window.dispatchEvent(evt);
|
||||
|
||||
try {
|
||||
var start = anim.getStartTime();
|
||||
} catch(e) {
|
||||
ok(false, "Key event dispatched to the window failed to trigger " +
|
||||
"accesskey handling");
|
||||
}
|
||||
|
||||
removeElement(anim);
|
||||
}
|
||||
|
||||
function testAdoptNode()
|
||||
{
|
||||
gSvg.setCurrentTime(1);
|
||||
ok(gSvg.animationsPaused(), "Expected animations to be paused");
|
||||
|
||||
// Create a new document with an animation element
|
||||
var newdoc = document.implementation.createDocument(gSvgns, 'svg', null);
|
||||
var anim = newdoc.createElementNS(gSvgns, 'animate');
|
||||
anim.setAttribute('attributeName', 'cx');
|
||||
anim.setAttribute('values', '0; 100');
|
||||
anim.setAttribute('dur', '10s');
|
||||
anim.setAttribute('begin', 'accesskey(a)');
|
||||
newdoc.documentElement.appendChild(anim);
|
||||
|
||||
// Adopt
|
||||
ok(anim.ownerDocument !== document,
|
||||
"Expected newly created animation to belong to a different doc");
|
||||
document.adoptNode(anim);
|
||||
document.getElementById('circle').appendChild(anim);
|
||||
ok(anim.ownerDocument === document,
|
||||
"Expected newly created animation to belong to the same doc");
|
||||
|
||||
var evt = createEvent('a');
|
||||
|
||||
// Now fire an event at the original window and check nothing happens
|
||||
newdoc.dispatchEvent(evt);
|
||||
try {
|
||||
var start = anim.getStartTime();
|
||||
ok(false, "Adopted node still receiving accesskey events from old doc");
|
||||
} catch(e) {
|
||||
// Ok
|
||||
}
|
||||
|
||||
// And then fire at our window
|
||||
document.dispatchEvent(evt);
|
||||
try {
|
||||
var start = anim.getStartTime();
|
||||
} catch(e) {
|
||||
ok(false, "Adopted node failed to catch accesskey event");
|
||||
}
|
||||
|
||||
removeElement(anim);
|
||||
}
|
||||
|
||||
function testFauxEvent()
|
||||
{
|
||||
// Test a non-KeyEvent labelled as a key event
|
||||
gSvg.setCurrentTime(0);
|
||||
ok(gSvg.animationsPaused(), "Expected animations to be paused");
|
||||
|
||||
var anim = createAnim('accessKey(a)');
|
||||
var evt = document.createEvent("SVGEvents");
|
||||
evt.initEvent("keypress", true, true);
|
||||
document.getElementById('circle').dispatchEvent(evt);
|
||||
|
||||
// We're really just testing that the above didn't crash us, but while we're
|
||||
// at it, just do a sanity check that we didn't also create an interval
|
||||
try {
|
||||
var start = anim.getStartTime();
|
||||
ok(false, "Faux event generated interval");
|
||||
} catch(e) {
|
||||
// All is well
|
||||
}
|
||||
|
||||
removeElement(anim);
|
||||
}
|
||||
|
||||
window.addEventListener("load", main, false);
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -446,7 +446,7 @@ nsXMLContentSink::OnTransformDone(nsresult aResult,
|
||||
mDocument->IndexOf(rootElement));
|
||||
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
|
||||
}
|
||||
|
||||
|
||||
// Start the layout process
|
||||
StartLayout(PR_FALSE);
|
||||
|
||||
@ -1088,6 +1088,10 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
||||
MaybeStartLayout(PR_FALSE);
|
||||
}
|
||||
|
||||
if (content == mDocElement) {
|
||||
NotifyDocElementCreated(mDocument);
|
||||
}
|
||||
|
||||
return aInterruptable && NS_SUCCEEDED(result) ? DidProcessATokenImpl() :
|
||||
result;
|
||||
}
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -157,20 +158,26 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocument* aDocument,
|
||||
NS_ASSERTION(xblDoc, "xml document doesn't implement nsIDOMDocumentXBL");
|
||||
NS_ENSURE_TRUE(xblDoc, NS_ERROR_FAILURE);
|
||||
|
||||
xblDoc->LoadBindingDocument(NS_LITERAL_STRING("chrome://global/content/xml/XMLPrettyPrint.xml"));
|
||||
nsCOMPtr<nsIURI> bindingUri;
|
||||
rv = NS_NewURI(getter_AddRefs(bindingUri),
|
||||
NS_LITERAL_STRING("chrome://global/content/xml/XMLPrettyPrint.xml#prettyprint"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> sysPrincipal;
|
||||
nsContentUtils::GetSecurityManager()->
|
||||
GetSystemPrincipal(getter_AddRefs(sysPrincipal));
|
||||
aDocument->BindingManager()->LoadBindingDocument(aDocument, bindingUri,
|
||||
sysPrincipal);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> rootElem;
|
||||
sourceDocument->GetDocumentElement(getter_AddRefs(rootElem));
|
||||
NS_ENSURE_TRUE(rootElem, NS_ERROR_UNEXPECTED);
|
||||
nsCOMPtr<nsIContent> rootCont = aDocument->GetRootElement();
|
||||
NS_ENSURE_TRUE(rootCont, NS_ERROR_UNEXPECTED);
|
||||
|
||||
rv = xblDoc->AddBinding(rootElem,
|
||||
NS_LITERAL_STRING("chrome://global/content/xml/XMLPrettyPrint.xml#prettyprint"));
|
||||
rv = aDocument->BindingManager()->AddLayeredBinding(rootCont, bindingUri,
|
||||
sysPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Hand the result document to the binding
|
||||
nsCOMPtr<nsIObserver> binding;
|
||||
nsCOMPtr<nsIContent> rootCont = do_QueryInterface(rootElem);
|
||||
NS_ASSERTION(rootCont, "Element doesn't implement nsIContent");
|
||||
aDocument->BindingManager()->GetBindingImplementation(rootCont,
|
||||
NS_GET_IID(nsIObserver),
|
||||
(void**)getter_AddRefs(binding));
|
||||
|
@ -68,6 +68,7 @@
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "txXMLUtils.h"
|
||||
#include "nsContentSink.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "txError.h"
|
||||
@ -577,13 +578,14 @@ txMozillaXMLOutput::closePrevious(PRBool aFlushText)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (currentIsDoc) {
|
||||
mRootContentCreated = PR_TRUE;
|
||||
}
|
||||
|
||||
rv = mCurrentNode->AppendChildTo(mOpenedElement, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (currentIsDoc) {
|
||||
mRootContentCreated = PR_TRUE;
|
||||
nsContentSink::NotifyDocElementCreated(mDocument);
|
||||
}
|
||||
|
||||
mCurrentNode = mOpenedElement;
|
||||
mOpenedElement = nsnull;
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
|
||||
nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1");
|
||||
if (searchSvc) {
|
||||
nsCOMPtr<nsISearchEngine> defaultEngine;
|
||||
searchSvc->GetDefaultEngine(getter_AddRefs(defaultEngine));
|
||||
searchSvc->GetOriginalDefaultEngine(getter_AddRefs(defaultEngine));
|
||||
if (defaultEngine) {
|
||||
nsCOMPtr<nsISearchSubmission> submission;
|
||||
// We want to allow default search plugins to specify alternate
|
||||
|
@ -3986,6 +3986,10 @@ nsGlobalWindow::SetFullScreen(PRBool aFullScreen)
|
||||
if (itemType != nsIDocShellTreeItem::typeChrome)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// If we are already in full screen mode, just return.
|
||||
if (mFullScreen == aFullScreen)
|
||||
return NS_OK;
|
||||
|
||||
// dispatch a "fullscreen" DOM event so that XUL apps can
|
||||
// respond visually if we are kicked into full screen mode
|
||||
if (!DispatchCustomEvent("fullscreen")) {
|
||||
@ -4001,12 +4005,14 @@ nsGlobalWindow::SetFullScreen(PRBool aFullScreen)
|
||||
xulWin->SetIntrinsicallySized(PR_FALSE);
|
||||
}
|
||||
|
||||
// Set this before so if widget sends an event indicating its
|
||||
// gone full screen, the state trap above works.
|
||||
mFullScreen = aFullScreen;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetMainWidget();
|
||||
if (widget)
|
||||
widget->MakeFullScreen(aFullScreen);
|
||||
|
||||
mFullScreen = aFullScreen;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,9 @@
|
||||
* http://www.w3.org/TR/DOM-Level-2-HTML/
|
||||
*/
|
||||
|
||||
[scriptable, uuid(a6cf90ac-15b3-11d2-932e-00805f8add32)]
|
||||
interface nsIDOMValidityState;
|
||||
|
||||
[scriptable, uuid(9b93aab4-7fe8-4f79-9ad2-0623178a0c46)]
|
||||
interface nsIDOMHTMLObjectElement : nsIDOMHTMLElement
|
||||
{
|
||||
readonly attribute nsIDOMHTMLFormElement form;
|
||||
@ -70,4 +72,12 @@ interface nsIDOMHTMLObjectElement : nsIDOMHTMLElement
|
||||
attribute DOMString width;
|
||||
// Introduced in DOM Level 2:
|
||||
readonly attribute nsIDOMDocument contentDocument;
|
||||
|
||||
// The following lines are parte of the constraint validation API, see:
|
||||
// http://dev.w3.org/html5/spec/forms.html#the-constraint-validation-api
|
||||
readonly attribute boolean willValidate;
|
||||
readonly attribute nsIDOMValidityState validity;
|
||||
readonly attribute DOMString validationMessage;
|
||||
boolean checkValidity();
|
||||
void setCustomValidity(in DOMString error);
|
||||
};
|
||||
|
@ -90,7 +90,6 @@
|
||||
#include "nsGeolocation.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_QT
|
||||
#include <QX11EmbedWidget>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsWidget>
|
||||
#endif
|
||||
@ -430,17 +429,9 @@ TabChild::RecvCreateWidget(const MagicWindowHandle& parentWidget)
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
GtkWidget* win = gtk_plug_new((GdkNativeWindow)parentWidget);
|
||||
gtk_widget_show(win);
|
||||
GtkWidget* win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
#elif defined(MOZ_WIDGET_QT)
|
||||
QX11EmbedWidget *embedWin = nsnull;
|
||||
if (parentWidget) {
|
||||
embedWin = new QX11EmbedWidget();
|
||||
NS_ENSURE_TRUE(embedWin, false);
|
||||
embedWin->embedInto(parentWidget);
|
||||
embedWin->show();
|
||||
}
|
||||
QGraphicsView *view = new QGraphicsView(new QGraphicsScene(), embedWin);
|
||||
QGraphicsView *view = new QGraphicsView(new QGraphicsScene());
|
||||
NS_ENSURE_TRUE(view, false);
|
||||
QGraphicsWidget *win = new QGraphicsWidget();
|
||||
NS_ENSURE_TRUE(win, false);
|
||||
|
@ -85,7 +85,7 @@ function clickNotificationButton(aButtonIndex) {
|
||||
var chromeWin = getChromeWindow();
|
||||
if (chromeWin.PopupNotifications) {
|
||||
var panel = chromeWin.PopupNotifications.panel;
|
||||
var notificationEl = panel.getElementsByAttribute("id", "geolocation")[0];
|
||||
var notificationEl = panel.getElementsByAttribute("id", "geolocation-notification")[0];
|
||||
if (aButtonIndex == kAcceptButton)
|
||||
notificationEl.button.doCommand();
|
||||
else if (aButtonIndex == kDenyButton)
|
||||
|
@ -4,7 +4,7 @@
|
||||
package="org.mozilla.@MOZ_APP_NAME@"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="1"
|
||||
android:versionName="@MOZ_APP_VERSION@"
|
||||
android:versionName=@MOZ_APP_VERSION@
|
||||
android:sharedUserId="org.mozilla.sharedID">
|
||||
<uses-sdk android:minSdkVersion="5"
|
||||
android:targetSdkVersion="5"/>
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-/ * ***** BEGIN LICENSE BLOCK *****
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** 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
|
||||
@ -59,6 +60,7 @@ abstract public class GeckoApp
|
||||
public static FrameLayout mainLayout;
|
||||
public static GeckoSurfaceView surfaceView;
|
||||
public static GeckoApp mAppContext;
|
||||
ProgressDialog mProgressDialog;
|
||||
|
||||
void launch()
|
||||
{
|
||||
@ -102,6 +104,10 @@ abstract public class GeckoApp
|
||||
ViewGroup.LayoutParams.FILL_PARENT));
|
||||
|
||||
if (!GeckoAppShell.sGeckoRunning) {
|
||||
|
||||
mProgressDialog =
|
||||
ProgressDialog.show(GeckoApp.this, "", getAppName() +
|
||||
" is loading", true);
|
||||
// Load our JNI libs; we need to do this before launch() because
|
||||
// setInitialSize will be called even before Gecko is actually up
|
||||
// and running.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -135,12 +135,12 @@ class GeckoSurfaceView
|
||||
mSurfaceLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
if (GeckoAppShell.sGeckoRunning)
|
||||
mSurfaceNeedsRedraw = true;
|
||||
}
|
||||
|
||||
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
Log.i("GeckoAppJava", "surface destroyed");
|
||||
mSurfaceValid = false;
|
||||
@ -211,6 +211,10 @@ class GeckoSurfaceView
|
||||
}
|
||||
|
||||
public void draw2D(ByteBuffer buffer) {
|
||||
if (GeckoApp.mAppContext.mProgressDialog != null) {
|
||||
GeckoApp.mAppContext.mProgressDialog.dismiss();
|
||||
GeckoApp.mAppContext.mProgressDialog = null;
|
||||
}
|
||||
Canvas c = getHolder().lockCanvas();
|
||||
if (c == null)
|
||||
return;
|
||||
|
@ -54,7 +54,6 @@ JAVAFILES = \
|
||||
DEFINES += \
|
||||
-DMOZ_APP_DISPLAYNAME=$(MOZ_APP_DISPLAYNAME) \
|
||||
-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
|
||||
-DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
|
||||
-DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
|
||||
|
||||
GARBAGE += \
|
||||
|
@ -84,6 +84,8 @@
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
#include "nsIGfxInfo.h"
|
||||
|
||||
gfxPlatform *gPlatform = nsnull;
|
||||
|
||||
// These two may point to the same profile
|
||||
@ -220,6 +222,17 @@ gfxPlatform::Init()
|
||||
|
||||
gfxAtoms::RegisterAtoms();
|
||||
|
||||
/* Initialize the GfxInfo service.
|
||||
* Note: we can't call functions on GfxInfo that depend
|
||||
* on gPlatform until after it has been initialized
|
||||
* below. GfxInfo initialization annotates our
|
||||
* crash reports so we want to do it before
|
||||
* we try to load any drivers and do device detection
|
||||
* incase that code crashes. See bug #591561. */
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo;
|
||||
/* this currently will only succeed on Windows */
|
||||
gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
|
||||
#if defined(XP_WIN)
|
||||
gPlatform = new gfxWindowsPlatform;
|
||||
#elif defined(XP_MACOSX)
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "nsIWindowsRegKey.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "plbase64.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
|
||||
#ifdef MOZ_FT2_FONTS
|
||||
#include "ft2build.h"
|
||||
@ -232,7 +233,17 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
NS_RegisterMemoryReporter(new D2DVRAMReporter());
|
||||
mD2DDevice = NULL;
|
||||
|
||||
if (isVistaOrHigher) {
|
||||
PRBool d2dDisabled = PR_FALSE;
|
||||
nsresult rv = pref->GetBoolPref("gfx.direct2d.disabled", &d2dDisabled);
|
||||
if (NS_FAILED(rv))
|
||||
d2dDisabled = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
|
||||
PRBool safeMode = PR_FALSE;
|
||||
if (xr)
|
||||
xr->GetInSafeMode(&safeMode);
|
||||
|
||||
if (isVistaOrHigher && !d2dDisabled && !safeMode) {
|
||||
// We need a DWriteFactory to work.
|
||||
HMODULE d3d10module = LoadLibraryA("d3d10_1.dll");
|
||||
D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func)
|
||||
@ -282,7 +293,6 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
#endif
|
||||
|
||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
nsresult rv;
|
||||
PRBool useDirectWrite = PR_FALSE;
|
||||
|
||||
rv = pref->GetBoolPref(
|
||||
@ -315,7 +325,8 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
#endif
|
||||
|
||||
PRInt32 rmode;
|
||||
if (NS_SUCCEEDED(pref->GetIntPref("mozilla.widget.render-mode", &rmode))) {
|
||||
if (!safeMode &&
|
||||
NS_SUCCEEDED(pref->GetIntPref("mozilla.widget.render-mode", &rmode))) {
|
||||
if (rmode >= 0 && rmode < RENDER_MODE_MAX) {
|
||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
if (rmode != RENDER_DIRECT2D && !useDirectWrite) {
|
||||
|
@ -5066,6 +5066,7 @@ AC_SUBST(MOZ_APP_NAME)
|
||||
AC_SUBST(MOZ_APP_DISPLAYNAME)
|
||||
AC_SUBST(MOZ_APP_UA_NAME)
|
||||
AC_SUBST(MOZ_APP_VERSION)
|
||||
AC_SUBST(MOZ_UA_FIREFOX_VERSION)
|
||||
AC_SUBST(FIREFOX_VERSION)
|
||||
|
||||
AC_SUBST(MOZ_PKG_SPECIAL)
|
||||
|
@ -333,4 +333,3 @@ load 586806-1.html
|
||||
load 586806-2.html
|
||||
load 586806-3.html
|
||||
load 586973-1.html
|
||||
load 590387.html
|
||||
|
17
layout/reftests/svg/smil/event/accesskey-entity-1.svg
Normal file
17
layout/reftests/svg/smil/event/accesskey-entity-1.svg
Normal file
@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="
|
||||
document.documentElement.pauseAnimations();
|
||||
document.documentElement.setCurrentTime(0);
|
||||
keypress(0x20);
|
||||
delayedSnapshot(2)">
|
||||
<script xlink:href="event-util.js" type="text/javascript"/>
|
||||
<circle id="circle" r="10"/>
|
||||
<rect width="100" height="100" fill="red">
|
||||
<set attributeName="fill" attributeType="CSS"
|
||||
to="green" begin="accesskey( )" dur="4s"/>
|
||||
<set attributeName="width" attributeType="XML"
|
||||
to="200" begin="accesskey(!)" dur="4s"/>
|
||||
</rect>
|
||||
</svg>
|
After Width: | Height: | Size: 647 B |
15
layout/reftests/svg/smil/event/accesskey-entity-2.svg
Normal file
15
layout/reftests/svg/smil/event/accesskey-entity-2.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="
|
||||
document.documentElement.pauseAnimations();
|
||||
document.documentElement.setCurrentTime(0);
|
||||
keypress(0x0D);
|
||||
delayedSnapshot(2)">
|
||||
<script xlink:href="event-util.js" type="text/javascript"/>
|
||||
<circle id="circle" r="10"/>
|
||||
<rect width="100" height="100" fill="red">
|
||||
<set attributeName="fill" attributeType="CSS"
|
||||
to="green" begin="accesskey(
)" dur="4s"/>
|
||||
</rect>
|
||||
</svg>
|
After Width: | Height: | Size: 544 B |
@ -1,21 +1,37 @@
|
||||
// Allows a moment for events to be processed then performs a seek and runs
|
||||
// a snapshot.
|
||||
function delayedSnapshot(seekTimeInSeconds) {
|
||||
function delayedSnapshot(seekTimeInSeconds)
|
||||
{
|
||||
// Allow time for events to be processed
|
||||
window.setTimeout(finish, 10, seekTimeInSeconds);
|
||||
}
|
||||
|
||||
function finish(seekTimeInSeconds) {
|
||||
function finish(seekTimeInSeconds)
|
||||
{
|
||||
document.documentElement.pauseAnimations();
|
||||
if (seekTimeInSeconds)
|
||||
document.documentElement.setCurrentTime(seekTimeInSeconds);
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
function click(targetId) {
|
||||
function click(targetId)
|
||||
{
|
||||
var evt = document.createEvent("MouseEvents");
|
||||
evt.initMouseEvent("click", true, true, window,
|
||||
0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
var target = document.getElementById(targetId);
|
||||
target.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
function keypress(charCode)
|
||||
{
|
||||
var evt = document.createEvent("KeyboardEvent");
|
||||
evt.initKeyEvent("keypress", true, true, window,
|
||||
false, // ctrlKeyArg
|
||||
false, // altKeyArg
|
||||
false, // shiftKeyArg
|
||||
false, // metaKeyArg
|
||||
0, // keyCode
|
||||
charCode);
|
||||
document.documentElement.dispatchEvent(evt);
|
||||
}
|
||||
|
@ -27,3 +27,5 @@
|
||||
== event-target-surgery-2.svg green-box-ref.svg
|
||||
== event-target-surgery-3.svg green-box-ref.svg
|
||||
== event-target-non-svg-1.xhtml green-box-ref.xhtml
|
||||
== accesskey-entity-1.svg green-box-ref.svg
|
||||
== accesskey-entity-2.svg green-box-ref.svg
|
||||
|
@ -3185,12 +3185,18 @@ pref("gfx.color_management.mode", 0);
|
||||
// Initialize default render-mode.
|
||||
pref("mozilla.widget.render-mode", -1);
|
||||
|
||||
// Initialize default accelerated layers
|
||||
pref("mozilla.widget.accelerated-layers", true);
|
||||
// Default value of acceleration for all widgets.
|
||||
pref("layers.accelerate-all", false);
|
||||
|
||||
// Whether to allow acceleration on layers at all.
|
||||
pref("layers.accelerate-none", false);
|
||||
|
||||
#ifdef XP_WIN
|
||||
#ifndef WINCE
|
||||
pref("mozilla.layers.prefer-opengl", false);
|
||||
// Whether to disable the automatic detection and use of direct2d.
|
||||
pref("gfx.direct2d.disabled", false);
|
||||
|
||||
pref("layers.prefer-opengl", false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -847,7 +847,7 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
|
||||
if (PREF_CHANGED(UA_PREF("compatMode.firefox"))) {
|
||||
rv = prefs->GetBoolPref(UA_PREF("compatMode.firefox"), &cVar);
|
||||
if (NS_SUCCEEDED(rv) && cVar) {
|
||||
mCompatFirefox.AssignLiteral("Firefox/" FIREFOX_VERSION);
|
||||
mCompatFirefox.AssignLiteral("Firefox/" MOZ_UA_FIREFOX_VERSION);
|
||||
} else {
|
||||
mCompatFirefox.Truncate();
|
||||
}
|
||||
|
@ -57,6 +57,8 @@
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsIStyleSheetLinkingElement.h"
|
||||
#include "nsIDOMDocumentType.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIMutationObserver.h"
|
||||
#include "nsIFormProcessor.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@ -227,6 +229,23 @@ nsHtml5TreeOperation::Append(nsIContent* aNode,
|
||||
return rv;
|
||||
}
|
||||
|
||||
class nsDocElementCreatedNotificationRunner : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsDocElementCreatedNotificationRunner(nsIDocument* aDoc)
|
||||
: mDoc(aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsContentSink::NotifyDocElementCreated(mDoc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
|
||||
nsHtml5TreeOpExecutor* aBuilder)
|
||||
@ -238,6 +257,12 @@ nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
|
||||
rv = doc->AppendChildTo(aNode, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsNodeUtils::ContentInserted(doc, aNode, childCount);
|
||||
|
||||
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
|
||||
"Someone forgot to block scripts");
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new nsDocElementCreatedNotificationRunner(doc));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -2773,7 +2773,7 @@ nsNavBookmarks::UpdateKeywordsHashForRemovedBookmark(PRInt64 aItemId)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId,
|
||||
const nsAString& aKeyword)
|
||||
const nsAString& aUserCasedKeyword)
|
||||
{
|
||||
NS_ENSURE_ARG_MIN(aBookmarkId, 1);
|
||||
|
||||
@ -2781,7 +2781,7 @@ nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Shortcuts are always lowercased internally.
|
||||
nsAutoString keyword(aKeyword);
|
||||
nsAutoString keyword(aUserCasedKeyword);
|
||||
ToLowerCase(keyword);
|
||||
|
||||
// Check if bookmark was already associated to a keyword.
|
||||
@ -2899,21 +2899,22 @@ nsNavBookmarks::GetKeywordForBookmark(PRInt64 aBookmarkId, nsAString& aKeyword)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetURIForKeyword(const nsAString& aKeyword, nsIURI** aURI)
|
||||
nsNavBookmarks::GetURIForKeyword(const nsAString& aUserCasedKeyword,
|
||||
nsIURI** aURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_TRUE(!aKeyword.IsEmpty(), NS_ERROR_INVALID_ARG);
|
||||
NS_ENSURE_TRUE(!aUserCasedKeyword.IsEmpty(), NS_ERROR_INVALID_ARG);
|
||||
*aURI = nsnull;
|
||||
|
||||
// Shortcuts are always lowercased internally.
|
||||
nsAutoString keyword(aKeyword);
|
||||
nsAutoString keyword(aUserCasedKeyword);
|
||||
ToLowerCase(keyword);
|
||||
|
||||
nsresult rv = EnsureKeywordsHash();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
keywordSearchData searchData;
|
||||
searchData.keyword.Assign(aKeyword);
|
||||
searchData.keyword.Assign(keyword);
|
||||
searchData.itemId = -1;
|
||||
mBookmarkToKeywordHash.EnumerateRead(SearchBookmarkForKeyword, &searchData);
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "mozIStorageCompletionCallback.h"
|
||||
|
||||
#include "nsNavBookmarks.h"
|
||||
#include "nsAnnotationService.h"
|
||||
@ -182,7 +183,8 @@ static const PRInt64 USECS_PER_DAY = LL_INIT(20, 500654080);
|
||||
#endif
|
||||
#define TOPIC_IDLE_DAILY "idle-daily"
|
||||
#define TOPIC_PREF_CHANGED "nsPref:changed"
|
||||
#define TOPIC_GLOBAL_SHUTDOWN "profile-before-change"
|
||||
#define TOPIC_PROFILE_TEARDOWN "profile-change-teardown"
|
||||
#define TOPIC_PROFILE_CHANGE "profile-before-change"
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsNavHistory)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsNavHistory)
|
||||
@ -312,8 +314,11 @@ protected:
|
||||
|
||||
|
||||
class PlacesEvent : public nsRunnable
|
||||
, public mozIStorageCompletionCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
PlacesEvent(const char* aTopic)
|
||||
: mTopic(aTopic)
|
||||
, mDoubleEnqueue(false)
|
||||
@ -333,6 +338,12 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Complete()
|
||||
{
|
||||
Notify();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Notify()
|
||||
{
|
||||
@ -351,6 +362,12 @@ protected:
|
||||
bool mDoubleEnqueue;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(
|
||||
PlacesEvent
|
||||
, mozIStorageCompletionCallback
|
||||
, nsIRunnable
|
||||
)
|
||||
|
||||
} // anonymouse namespace
|
||||
|
||||
|
||||
@ -475,7 +492,8 @@ nsNavHistory::Init()
|
||||
nsCOMPtr<nsIObserverService> obsSvc =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
if (obsSvc) {
|
||||
(void)obsSvc->AddObserver(this, TOPIC_GLOBAL_SHUTDOWN, PR_FALSE);
|
||||
(void)obsSvc->AddObserver(this, TOPIC_PROFILE_TEARDOWN, PR_FALSE);
|
||||
(void)obsSvc->AddObserver(this, TOPIC_PROFILE_CHANGE, PR_FALSE);
|
||||
(void)obsSvc->AddObserver(this, TOPIC_IDLE_DAILY, PR_FALSE);
|
||||
(void)obsSvc->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, PR_FALSE);
|
||||
#ifdef MOZ_XUL
|
||||
@ -5668,69 +5686,73 @@ nsNavHistory::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
|
||||
|
||||
if (strcmp(aTopic, TOPIC_GLOBAL_SHUTDOWN) == 0) {
|
||||
if (strcmp(aTopic, TOPIC_PROFILE_TEARDOWN) == 0) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (!os) {
|
||||
NS_WARNING("Unable to shutdown Places: Observer Service unavailable.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
(void)os->RemoveObserver(this, TOPIC_GLOBAL_SHUTDOWN);
|
||||
(void)os->RemoveObserver(this, TOPIC_PROFILE_TEARDOWN);
|
||||
(void)os->RemoveObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC);
|
||||
(void)os->RemoveObserver(this, TOPIC_IDLE_DAILY);
|
||||
#ifdef MOZ_XUL
|
||||
(void)os->RemoveObserver(this, TOPIC_AUTOCOMPLETE_FEEDBACK_INCOMING);
|
||||
#endif
|
||||
|
||||
// Notify all Places users that we are about to shutdown. The notification
|
||||
// is enqueued because there is network work on profile-before-change that
|
||||
// should run before us.
|
||||
nsRefPtr<PlacesEvent> shutdownEvent =
|
||||
new PlacesEvent(TOPIC_PLACES_SHUTDOWN);
|
||||
nsresult rv = NS_DispatchToMainThread(shutdownEvent);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Unable to shutdown Places: message dispatch failed.");
|
||||
// If shutdown happens in the same scope as the service init, we should
|
||||
// immediately notify the places-init topic. Otherwise, since it's an
|
||||
// enqueued notification and the event loop won't spin, it could be notified
|
||||
// after xpcom-shutdown, when the connection does not exist anymore.
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
nsresult rv = os->EnumerateObservers(TOPIC_PLACES_INIT_COMPLETE,
|
||||
getter_AddRefs(e));
|
||||
if (NS_SUCCEEDED(rv) && e) {
|
||||
nsCOMPtr<nsIObserver> observer;
|
||||
PRBool loop = PR_TRUE;
|
||||
while(NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop) {
|
||||
e->GetNext(getter_AddRefs(observer));
|
||||
(void)observer->Observe(observer, TOPIC_PLACES_INIT_COMPLETE, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
// Once everybody has been notified, proceed with the real shutdown.
|
||||
// Note: PlacesEvent contains special code to double enqueue this
|
||||
// notification because we must ensure any enqueued work from observers
|
||||
// is complete before going on.
|
||||
(void)os->AddObserver(this, TOPIC_PLACES_TEARDOWN, PR_FALSE);
|
||||
nsRefPtr<PlacesEvent> teardownEvent =
|
||||
new PlacesEvent(TOPIC_PLACES_TEARDOWN, true);
|
||||
rv = NS_DispatchToMainThread(teardownEvent);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Unable to shutdown Places: message dispatch failed.");
|
||||
// Notify all Places users that we are about to shutdown.
|
||||
(void)os->NotifyObservers(nsnull, TOPIC_PLACES_SHUTDOWN, nsnull);
|
||||
}
|
||||
|
||||
else if (strcmp(aTopic, TOPIC_PLACES_TEARDOWN) == 0) {
|
||||
// Don't even try to notify observers from this point on, the category
|
||||
// cache would init services that could not shutdown correctly or try to
|
||||
// use our APIs.
|
||||
mCanNotify = false;
|
||||
else if (strcmp(aTopic, TOPIC_PROFILE_CHANGE) == 0) {
|
||||
// Fire internal shutdown notifications.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
(void)os->RemoveObserver(this, TOPIC_PROFILE_CHANGE);
|
||||
// Double notification allows to correctly enqueue tasks without the need
|
||||
// to enqueue notification events to the main-thread. There is no
|
||||
// guarantee that the event loop will spin before xpcom-shutdown indeed,
|
||||
// see bug 580892.
|
||||
(void)os->NotifyObservers(nsnull, TOPIC_PLACES_WILL_CLOSE_CONNECTION, nsnull);
|
||||
(void)os->NotifyObservers(nsnull, TOPIC_PLACES_CONNECTION_CLOSING, nsnull);
|
||||
}
|
||||
|
||||
// Operations that are unlikely to create issues to implementers should go
|
||||
// in global shutdown. Any other thing that must run really late must be
|
||||
// in profile teardown. Any other thing that must run really late should be
|
||||
// here instead.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
(void)os->RemoveObserver(this, TOPIC_PLACES_TEARDOWN);
|
||||
|
||||
// Don't even try to notify observers from this point on, the category
|
||||
// cache would init services that could try to use our APIs.
|
||||
mCanNotify = false;
|
||||
|
||||
// Stop observing preferences changes.
|
||||
if (mPrefBranch)
|
||||
mPrefBranch->RemoveObserver("", this);
|
||||
|
||||
// Force a preferences save.
|
||||
nsCOMPtr<nsIPrefService> prefService = do_QueryInterface(mPrefBranch);
|
||||
if (prefService)
|
||||
prefService->SavePrefFile(nsnull);
|
||||
|
||||
// Finalize all statements.
|
||||
nsresult rv = FinalizeInternalStatements();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// NOTE: We don't close the connection because the sync service could still
|
||||
// need it for a final flush.
|
||||
// Finally, close the connection.
|
||||
nsRefPtr<PlacesEvent> closeListener =
|
||||
new PlacesEvent(TOPIC_PLACES_CONNECTION_CLOSED);
|
||||
(void)mDBConn->AsyncClose(closeListener);
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -93,12 +93,22 @@
|
||||
// Fired after autocomplete feedback has been updated.
|
||||
#define TOPIC_AUTOCOMPLETE_FEEDBACK_UPDATED "places-autocomplete-feedback-updated"
|
||||
#endif
|
||||
// Fired when Places is shutting down.
|
||||
|
||||
// Fired when Places is shutting down. Any code should stop accessing Places
|
||||
// APIs after this notification. If you need to listen for Places shutdown
|
||||
// you should only use this notification, next ones are intended only for
|
||||
// internal Places use.
|
||||
#define TOPIC_PLACES_SHUTDOWN "places-shutdown"
|
||||
// Internal notification, called after places-shutdown.
|
||||
// If you need to listen for Places shutdown, you should really use
|
||||
// places-shutdown, because places-teardown is guaranteed to break your code.
|
||||
#define TOPIC_PLACES_TEARDOWN "places-teardown"
|
||||
// For Internal use only. Fired when connection is about to be closed, only
|
||||
// cleanup tasks should run at this stage, nothing should be added to the
|
||||
// database, nor APIs should be called.
|
||||
#define TOPIC_PLACES_WILL_CLOSE_CONNECTION "places-will-close-connection"
|
||||
// For Internal use only. Fired as the last notification before the connection
|
||||
// is gone.
|
||||
#define TOPIC_PLACES_CONNECTION_CLOSING "places-connection-closing"
|
||||
// Fired when the connection has gone, nothing will work from now on.
|
||||
#define TOPIC_PLACES_CONNECTION_CLOSED "places-connection-closed"
|
||||
|
||||
// Fired when Places found a locked database while initing.
|
||||
#define TOPIC_DATABASE_LOCKED "places-database-locked"
|
||||
// Fired after Places inited.
|
||||
|
@ -46,10 +46,8 @@ const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
// Use places-teardown to ensure we run last in the shutdown process.
|
||||
// Any other implementer should use places-shutdown instead, since teardown is
|
||||
// where things really break.
|
||||
const kTopicShutdown = "places-teardown";
|
||||
// A database flush should be the last operation during the shutdown process.
|
||||
const kTopicShutdown = "places-connection-closing";
|
||||
const kSyncFinished = "places-sync-finished";
|
||||
const kDebugStopSync = "places-debug-stop-sync";
|
||||
const kDebugStartSync = "places-debug-start-sync";
|
||||
@ -125,22 +123,9 @@ nsPlacesDBFlush.prototype = {
|
||||
this._timer = null;
|
||||
}
|
||||
|
||||
// Other components could still make changes to history at this point,
|
||||
// for example to clear private data on shutdown, so here we dispatch
|
||||
// an event to the main thread so that we will sync after
|
||||
// Places shutdown ensuring all data have been saved.
|
||||
Services.tm.mainThread.dispatch({
|
||||
_self: this,
|
||||
run: function() {
|
||||
// Flush any remaining change to disk tables.
|
||||
this._self._flushWithQueries([kQuerySyncPlacesId, kQuerySyncHistoryVisitsId]);
|
||||
|
||||
// Close the database connection, this was the last sync and we can't
|
||||
// ensure database coherence from now on.
|
||||
this._self._finalizeInternalStatements();
|
||||
this._self._db.asyncClose();
|
||||
}
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
// Flush any remaining change to disk tables.
|
||||
this._flushWithQueries([kQuerySyncPlacesId, kQuerySyncHistoryVisitsId]);
|
||||
this._finalizeInternalStatements();
|
||||
}
|
||||
else if (aTopic == "nsPref:changed" && aData == kSyncPrefName) {
|
||||
// Get the new pref value, and then update our timer
|
||||
|
@ -80,7 +80,8 @@ const nsPlacesExpirationFactory = {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Constants
|
||||
|
||||
const TOPIC_SHUTDOWN = "places-shutdown";
|
||||
// Last expiration step should run before the final sync.
|
||||
const TOPIC_SHUTDOWN = "places-will-close-connection";
|
||||
const TOPIC_PREF_CHANGED = "nsPref:changed";
|
||||
const TOPIC_DEBUG_START_EXPIRATION = "places-debug-start-expiration";
|
||||
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
|
||||
@ -522,24 +523,16 @@ nsPlacesExpiration.prototype = {
|
||||
this._timer = null;
|
||||
}
|
||||
|
||||
// We must be sure to run after all other shutdown observers (but DBFlush)
|
||||
// thus we enqueue the calls.
|
||||
let self = this;
|
||||
Services.tm.mainThread.dispatch({
|
||||
run: function() {
|
||||
// If we ran a clearHistory recently, or database id not dirty, we don't want to spend
|
||||
// time expiring on shutdown. In such a case just expire session annotations.
|
||||
let hasRecentClearHistory =
|
||||
Date.now() - self._lastClearHistoryTime <
|
||||
SHUTDOWN_WITH_RECENT_CLEARHISTORY_TIMEOUT_SECONDS * 1000;
|
||||
let action = hasRecentClearHistory ||
|
||||
self.status != STATUS.DIRTY ? ACTION.CLEAN_SHUTDOWN
|
||||
: ACTION.SHUTDOWN;
|
||||
self._expireWithActionAndLimit(action, LIMIT.LARGE);
|
||||
|
||||
self._finalizeInternalStatements();
|
||||
}
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
// If we ran a clearHistory recently, or database id not dirty, we don't want to spend
|
||||
// time expiring on shutdown. In such a case just expire session annotations.
|
||||
let hasRecentClearHistory =
|
||||
Date.now() - this._lastClearHistoryTime <
|
||||
SHUTDOWN_WITH_RECENT_CLEARHISTORY_TIMEOUT_SECONDS * 1000;
|
||||
let action = hasRecentClearHistory ||
|
||||
this.status != STATUS.DIRTY ? ACTION.CLEAN_SHUTDOWN
|
||||
: ACTION.SHUTDOWN;
|
||||
this._expireWithActionAndLimit(action, LIMIT.LARGE);
|
||||
this._finalizeInternalStatements();
|
||||
}
|
||||
else if (aTopic == TOPIC_PREF_CHANGED) {
|
||||
this._loadPrefs();
|
||||
|
@ -40,6 +40,12 @@ let bs = PlacesUtils.bookmarks;
|
||||
let db = DBConn();
|
||||
|
||||
function check_keyword(aItemId, aExpectedBookmarkKeyword, aExpectedURIKeyword) {
|
||||
// All keywords are handled lowercased internally.
|
||||
if (aExpectedURIKeyword)
|
||||
aExpectedURIKeyword = aExpectedURIKeyword.toLowerCase();
|
||||
if (aExpectedBookmarkKeyword)
|
||||
aExpectedBookmarkKeyword = aExpectedBookmarkKeyword.toLowerCase();
|
||||
|
||||
if (aItemId) {
|
||||
print("Check keyword for bookmark");
|
||||
do_check_eq(bs.getKeywordForBookmark(aItemId), aExpectedBookmarkKeyword);
|
||||
@ -50,8 +56,11 @@ function check_keyword(aItemId, aExpectedBookmarkKeyword, aExpectedURIKeyword) {
|
||||
|
||||
print("Check uri for keyword");
|
||||
// This API can't tell which uri the user wants, so it returns a random one.
|
||||
if (aExpectedURIKeyword)
|
||||
if (aExpectedURIKeyword) {
|
||||
do_check_true(/http:\/\/test[0-9]\.mozilla\.org/.test(bs.getURIForKeyword(aExpectedURIKeyword).spec));
|
||||
// Check case insensitivity.
|
||||
do_check_true(/http:\/\/test[0-9]\.mozilla\.org/.test(bs.getURIForKeyword(aExpectedURIKeyword.toUpperCase()).spec));
|
||||
}
|
||||
}
|
||||
else {
|
||||
stmt = db.createStatement(
|
||||
@ -93,6 +102,8 @@ function run_test() {
|
||||
check_keyword(itemId1, null, null);
|
||||
bs.setKeywordForBookmark(itemId1, "keyword");
|
||||
check_keyword(itemId1, "keyword", "keyword");
|
||||
// Check case insensitivity.
|
||||
check_keyword(itemId1, "kEyWoRd", "kEyWoRd");
|
||||
|
||||
print("Add another bookmark with the same uri, should not inherit keyword.");
|
||||
let itemId1_bis = bs.insertBookmark(folderId,
|
||||
@ -101,6 +112,8 @@ function run_test() {
|
||||
"test1_bis");
|
||||
|
||||
check_keyword(itemId1_bis, null, "keyword");
|
||||
// Check case insensitivity.
|
||||
check_keyword(itemId1_bis, null, "kEyWoRd");
|
||||
|
||||
print("Set same keyword on another bookmark with a different uri.");
|
||||
let itemId2 = bs.insertBookmark(folderId,
|
||||
@ -108,7 +121,9 @@ function run_test() {
|
||||
bs.DEFAULT_INDEX,
|
||||
"test2");
|
||||
check_keyword(itemId2, null, null);
|
||||
bs.setKeywordForBookmark(itemId2, "keyword");
|
||||
bs.setKeywordForBookmark(itemId2, "kEyWoRd");
|
||||
check_keyword(itemId1, "kEyWoRd", "kEyWoRd");
|
||||
// Check case insensitivity.
|
||||
check_keyword(itemId1, "keyword", "keyword");
|
||||
check_keyword(itemId1_bis, null, "keyword");
|
||||
check_keyword(itemId2, "keyword", "keyword");
|
||||
|
@ -57,7 +57,7 @@ let (commonFile = do_get_file("../head_common.js", false)) {
|
||||
function shutdownExpiration()
|
||||
{
|
||||
let expire = Cc["@mozilla.org/places/expiration;1"].getService(Ci.nsIObserver);
|
||||
expire.observe(null, PlacesUtils.TOPIC_SHUTDOWN, null);
|
||||
expire.observe(null, "places-will-close-connection", null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,9 +40,6 @@ const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
|
||||
const NS_APP_HISTORY_50_FILE = "UHist";
|
||||
const NS_APP_BOOKMARKS_50_FILE = "BMarks";
|
||||
|
||||
// Backwards compatible consts, use PlacesUtils properties if possible.
|
||||
const TOPIC_GLOBAL_SHUTDOWN = "profile-before-change";
|
||||
|
||||
// Shortcuts to transactions type.
|
||||
const TRANSITION_LINK = Ci.nsINavHistoryService.TRANSITION_LINK;
|
||||
const TRANSITION_TYPED = Ci.nsINavHistoryService.TRANSITION_TYPED;
|
||||
@ -347,11 +344,11 @@ function waitForClearHistory(aCallback) {
|
||||
/**
|
||||
* Simulates a Places shutdown.
|
||||
*/
|
||||
function shutdownPlaces()
|
||||
function shutdownPlaces(aKeepAliveConnection)
|
||||
{
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsIObserver);
|
||||
hs.observe(null, TOPIC_GLOBAL_SHUTDOWN, null);
|
||||
let hs = PlacesUtils.history.QueryInterface(Ci.nsIObserver);
|
||||
hs.observe(null, "profile-change-teardown", null);
|
||||
hs.observe(null, "profile-before-change", null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ const TEST_URI = "http://test.com/";
|
||||
|
||||
const kSyncPrefName = "syncDBTableIntervalInSecs";
|
||||
const SYNC_INTERVAL = 600; // ten minutes
|
||||
const kSyncFinished = "places-sync-finished";
|
||||
const TOPIC_CONNECTION_CLOSED = "places-connection-closed";
|
||||
|
||||
var historyObserver = {
|
||||
onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId,
|
||||
@ -64,9 +64,8 @@ hs.addObserver(historyObserver, false);
|
||||
var observer = {
|
||||
visitId: -1,
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == kSyncFinished) {
|
||||
// remove the observer, we don't need to observe sync on quit
|
||||
os.removeObserver(this, kSyncFinished);
|
||||
if (aTopic == TOPIC_CONNECTION_CLOSED) {
|
||||
os.removeObserver(this, aTopic);
|
||||
|
||||
// visit id must be valid
|
||||
do_check_neq(this.visitId, -1);
|
||||
@ -75,7 +74,7 @@ var observer = {
|
||||
}
|
||||
}
|
||||
}
|
||||
os.addObserver(observer, kSyncFinished, false);
|
||||
os.addObserver(observer, TOPIC_CONNECTION_CLOSED, false);
|
||||
|
||||
function run_test()
|
||||
{
|
||||
|
@ -53,10 +53,7 @@ const TEST_URI = "http://test.com/";
|
||||
const PREF_SYNC_INTERVAL = "syncDBTableIntervalInSecs";
|
||||
const SYNC_INTERVAL = 600; // ten minutes
|
||||
const TOPIC_SYNC_FINISHED = "places-sync-finished";
|
||||
|
||||
// Polling constants to check the connection closed status.
|
||||
const POLLING_TIMEOUT_MS = 100;
|
||||
const POLLING_MAX_PASSES = 20;
|
||||
const TOPIC_CONNECTION_CLOSED = "places-connection-closed";
|
||||
|
||||
var historyObserver = {
|
||||
visitId: -1,
|
||||
@ -82,6 +79,7 @@ var observer = {
|
||||
// The first sync is due to the insert bookmark.
|
||||
// Simulate a clear private data just before shutdown.
|
||||
bh.removeAllPages();
|
||||
os.addObserver(shutdownObserver, TOPIC_CONNECTION_CLOSED, false);
|
||||
// Immediately notify shutdown.
|
||||
shutdownPlaces();
|
||||
return;
|
||||
@ -94,27 +92,16 @@ var observer = {
|
||||
do_check_neq(historyObserver.visitId, -1);
|
||||
// History must have been cleared.
|
||||
do_check_true(historyObserver.cleared);
|
||||
|
||||
// The database connection will be closed after this sync, but we can't
|
||||
// know how much time it will take, so we use a polling strategy.
|
||||
do_timeout(POLLING_TIMEOUT_MS, check_results);
|
||||
}
|
||||
}
|
||||
}
|
||||
os.addObserver(observer, TOPIC_SYNC_FINISHED, false);
|
||||
|
||||
var gPasses = 0;
|
||||
function check_results() {
|
||||
if (++gPasses >= POLLING_MAX_PASSES) {
|
||||
do_throw("Maximum time elapsdes waiting for Places database connection to close");
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
if (PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection.connectionReady) {
|
||||
do_timeout(POLLING_TIMEOUT_MS, check_results);
|
||||
return;
|
||||
}
|
||||
let shutdownObserver = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
os.removeObserver(this, aTopic);
|
||||
do_check_false(PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection.connectionReady);
|
||||
|
||||
let dbConn = DBConn();
|
||||
do_check_true(dbConn.connectionReady);
|
||||
@ -144,6 +131,7 @@ function check_results() {
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function run_test()
|
||||
|
@ -336,7 +336,10 @@ PopupNotifications.prototype = {
|
||||
let doc = this.window.document;
|
||||
let popupnotification = doc.createElementNS(XUL_NS, "popupnotification");
|
||||
popupnotification.setAttribute("label", n.message);
|
||||
popupnotification.setAttribute("id", n.id);
|
||||
// Append "-notification" to the ID to try to avoid ID conflicts with other stuff
|
||||
// in the document.
|
||||
popupnotification.setAttribute("id", n.id + "-notification");
|
||||
popupnotification.setAttribute("popupid", n.id);
|
||||
if (n.mainAction) {
|
||||
popupnotification.setAttribute("buttonlabel", n.mainAction.label);
|
||||
popupnotification.setAttribute("buttonaccesskey", n.mainAction.accessKey);
|
||||
|
@ -469,7 +469,7 @@
|
||||
<binding id="popup-notification">
|
||||
<content align="start">
|
||||
<xul:image class="popup-notification-icon"
|
||||
xbl:inherits="popupid=id"/>
|
||||
xbl:inherits="popupid"/>
|
||||
<xul:vbox>
|
||||
<xul:description class="popup-notification-description"
|
||||
xbl:inherits="value=label"/>
|
||||
|
@ -10,8 +10,10 @@
|
||||
<!ENTITY installFromFile.label "Install From File…">
|
||||
<!ENTITY installFromFile.accesskey "I">
|
||||
|
||||
<!ENTITY cmd.back.tooltip "Go back one page">
|
||||
<!ENTITY cmd.forward.tooltip "Go forward one page">
|
||||
|
||||
<!-- categories / views -->
|
||||
<!-- LOCALIZATION NOTE: These should match the header-* entries in extensions.properties -->
|
||||
<!ENTITY view.search.label "Search">
|
||||
<!ENTITY view.discover.label "Get Add-ons">
|
||||
<!ENTITY view.locales.label "Languages">
|
||||
@ -21,6 +23,8 @@
|
||||
<!ENTITY view.plugins.label "Plugins">
|
||||
<!ENTITY view.recentUpdates.label "Recent Updates">
|
||||
<!ENTITY view.availableUpdates.label "Available Updates">
|
||||
<!ENTITY view.utilites.preferences.tooltip "Options for all add-ons">
|
||||
<!ENTITY view.utilites.preferencesUnix.tooltip "Preferences for all add-ons">
|
||||
|
||||
<!-- addon updates -->
|
||||
<!ENTITY updates.updateAddonsNow.label "Update Add-ons Now">
|
||||
@ -41,8 +45,10 @@
|
||||
<!ENTITY cmd.showDetails.accesskey "S">
|
||||
<!ENTITY cmd.findUpdates.label "Find Updates">
|
||||
<!ENTITY cmd.findUpdates.accesskey "F">
|
||||
<!ENTITY cmd.preferences.label "Preferences">
|
||||
<!ENTITY cmd.preferences.accesskey "P">
|
||||
<!ENTITY cmd.preferencesWin.label "Options">
|
||||
<!ENTITY cmd.preferencesWin.accesskey "O">
|
||||
<!ENTITY cmd.preferencesUnix.label "Preferences">
|
||||
<!ENTITY cmd.preferencesUnix.accesskey "P">
|
||||
<!ENTITY cmd.about.label "About">
|
||||
<!ENTITY cmd.about.accesskey "A">
|
||||
|
||||
@ -52,8 +58,10 @@
|
||||
<!ENTITY cmd.disableAddon.accesskey "D">
|
||||
<!ENTITY cmd.uninstallAddon.label "Remove">
|
||||
<!ENTITY cmd.uninstallAddon.accesskey "R">
|
||||
<!ENTITY cmd.showPreferences.label "Preferences">
|
||||
<!ENTITY cmd.showPreferences.tooltip "Change this add-on's preferences">
|
||||
<!ENTITY cmd.showPreferencesWin.label "Options">
|
||||
<!ENTITY cmd.showPreferencesWin.tooltip "Change this add-on's options">
|
||||
<!ENTITY cmd.showPreferencesUnix.label "Preferences">
|
||||
<!ENTITY cmd.showPreferencesUnix.tooltip "Change this add-on's preferences">
|
||||
<!ENTITY cmd.contribute.label "Contribute">
|
||||
<!ENTITY cmd.contribute.accesskey "C">
|
||||
<!ENTITY cmd.contribute.tooltip "Contribute to the development of this add-on">
|
||||
@ -76,9 +84,12 @@
|
||||
<!ENTITY detail.checkForUpdates.label "Check for updates">
|
||||
<!ENTITY detail.checkForUpdates.accesskey "F">
|
||||
<!ENTITY detail.checkForUpdates.tooltip "Check for updates for this add-on">
|
||||
<!ENTITY detail.showPreferences.label "Preferences">
|
||||
<!ENTITY detail.showPreferences.accesskey "P">
|
||||
<!ENTITY detail.showPreferences.tooltip "Change this add-on's preferences">
|
||||
<!ENTITY detail.showPreferencesWin.label "Options">
|
||||
<!ENTITY detail.showPreferencesWin.accesskey "O">
|
||||
<!ENTITY detail.showPreferencesWin.tooltip "Change this add-on's Options">
|
||||
<!ENTITY detail.showPreferencesUnix.label "Preferences">
|
||||
<!ENTITY detail.showPreferencesUnix.accesskey "P">
|
||||
<!ENTITY detail.showPreferencesUnix.tooltip "Change this add-on's preferences">
|
||||
|
||||
|
||||
<!-- ratings -->
|
||||
|
@ -6,20 +6,6 @@ aboutWindowVersionString=version %S
|
||||
#LOCALIZATION NOTE (aboutAddon) %S is the addon name
|
||||
aboutAddon=About %S
|
||||
|
||||
#LOCALIZATION NOTE These should match the view.*.label entities in extensions.dtd
|
||||
header-search=Search Results
|
||||
header-discover=Get Add-ons
|
||||
header-locale=Languages
|
||||
header-searchengine=Search Engines
|
||||
header-extension=Extensions
|
||||
header-theme=Themes
|
||||
header-plugin=Plugins
|
||||
header-recentUpdates=Recent Updates
|
||||
header-availableUpdates=Available Updates
|
||||
|
||||
#LOCALIZATION NOTE (header-goBack) %S is the name of the pane to go back to
|
||||
header-goBack=Back to %S
|
||||
|
||||
#LOCALIZATION NOTE (uninstallNotice) %S is the add-on name
|
||||
uninstallNotice=%S has been removed.
|
||||
|
||||
|
@ -52,16 +52,22 @@
|
||||
|
||||
<!ENTITY details.link "Details">
|
||||
|
||||
<!ENTITY error.title "Update Failed">
|
||||
|
||||
<!ENTITY error.label "There were problems checking for, downloading, or installing this
|
||||
update. &brandShortName; could not be updated because:">
|
||||
|
||||
<!ENTITY errorManual.label "You can update &brandShortName; manually by visiting this link
|
||||
and downloading the latest version:">
|
||||
|
||||
<!ENTITY errorpatching.title "Update Failed">
|
||||
<!ENTITY errorpatching.intro "The partial Update could not be applied.
|
||||
&brandShortName; will try again by downloading a complete Update.">
|
||||
|
||||
<!ENTITY errorCertAttrNoUpdate.label "Something is preventing &brandShortName; from updating securely.
|
||||
Please check you have the latest version of &brandShortName; at:">
|
||||
<!ENTITY errorCertAttrHasUpdate.label "Something is trying to trick &brandShortName; into accepting an
|
||||
insecure update. Please contact your network provider and seek help.">
|
||||
|
||||
<!ENTITY finishedPage.title "Update Ready to Install">
|
||||
<!ENTITY finishedPage.text "The update will be installed the next time &brandShortName; starts. You
|
||||
can restart &brandShortName; now, or continue working and restart later.">
|
||||
|
@ -32,7 +32,6 @@ updateType_minor=Security Update
|
||||
|
||||
# LOCALIZATION NOTE: When present %S is brandShortName
|
||||
verificationError=%S could not confirm the integrity of the update package.
|
||||
errorsPageHeader=Update Failed
|
||||
licenseContentNotFound=The license file for this version could not be found. Please visit the %S homepage for more information.
|
||||
updateMoreInfoContentNotFound=Additional details about this version could not be found. Please visit the %S homepage for more information.
|
||||
resumePausedAfterCloseTitle=Software Update
|
||||
|
@ -93,9 +93,11 @@ XPCOMUtils.defineLazyGetter(gStrings, "appVersion", function() {
|
||||
return Services.appinfo.version;
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener("load", initialize, false);
|
||||
window.addEventListener("unload", shutdown, false);
|
||||
window.addEventListener("popstate", function(event) {
|
||||
gViewController.statePopped(event);
|
||||
}, false);
|
||||
|
||||
var gPendingInitializations = 1;
|
||||
__defineGetter__("gIsInitializing", function() gPendingInitializations > 0);
|
||||
@ -105,19 +107,6 @@ function initialize() {
|
||||
gHeader.initialize();
|
||||
gViewController.initialize();
|
||||
gEventManager.initialize();
|
||||
|
||||
var view = VIEW_DEFAULT;
|
||||
if (gCategories.node.selectedItem &&
|
||||
gCategories.node.selectedItem.id != "category-search")
|
||||
view = gCategories.node.selectedItem.value;
|
||||
|
||||
if ("arguments" in window && window.arguments.length > 0) {
|
||||
if ("view" in window.arguments[0])
|
||||
view = window.arguments[0].view;
|
||||
}
|
||||
|
||||
gViewController.loadView(view);
|
||||
notifyInitialized();
|
||||
}
|
||||
|
||||
function notifyInitialized() {
|
||||
@ -140,8 +129,14 @@ function shutdown() {
|
||||
}
|
||||
|
||||
// Used by external callers to load a specific view into the manager
|
||||
function loadView(aViewId, aCallback) {
|
||||
gViewController.loadView(aViewId, aCallback);
|
||||
function loadView(aViewId) {
|
||||
if (!gViewController.initialViewSelected) {
|
||||
// The caller opened the window and immediately loaded the view so it
|
||||
// should be the initial history entry
|
||||
gViewController.loadInitialView(aViewId);
|
||||
} else {
|
||||
gViewController.loadView(aViewId);
|
||||
}
|
||||
}
|
||||
|
||||
var gEventManager = {
|
||||
@ -258,9 +253,9 @@ var gViewController = {
|
||||
currentViewId: "",
|
||||
currentViewObj: null,
|
||||
currentViewRequest: 0,
|
||||
previousViewId: "",
|
||||
viewObjects: {},
|
||||
viewChangeCallback: null,
|
||||
initialViewSelected: false,
|
||||
|
||||
initialize: function() {
|
||||
this.viewPort = document.getElementById("view-port");
|
||||
@ -294,6 +289,32 @@ var gViewController = {
|
||||
}
|
||||
},
|
||||
|
||||
statePopped: function(e) {
|
||||
// If this is a navigation to a previous state then load that state
|
||||
if (e.state) {
|
||||
this.loadViewInternal(e.state.view, e.state.previousView);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the initial view has already been selected (by a call to loadView) then
|
||||
// bail out now
|
||||
if (this.initialViewSelected)
|
||||
return;
|
||||
|
||||
// Otherwise load the default view
|
||||
var view = VIEW_DEFAULT;
|
||||
if (gCategories.node.selectedItem &&
|
||||
gCategories.node.selectedItem.id != "category-search")
|
||||
view = gCategories.node.selectedItem.value;
|
||||
|
||||
if ("arguments" in window && window.arguments.length > 0) {
|
||||
if ("view" in window.arguments[0])
|
||||
view = window.arguments[0].view;
|
||||
}
|
||||
|
||||
this.loadInitialView(view);
|
||||
},
|
||||
|
||||
parseViewId: function(aViewId) {
|
||||
var matchRegex = /^addons:\/\/([^\/]+)\/(.*)$/;
|
||||
var [,viewType, viewParam] = aViewId.match(matchRegex) || [];
|
||||
@ -301,13 +322,32 @@ var gViewController = {
|
||||
},
|
||||
|
||||
get isLoading() {
|
||||
return this.currentViewObj.node.hasAttribute("loading");
|
||||
return !this.currentViewObj || this.currentViewObj.node.hasAttribute("loading");
|
||||
},
|
||||
|
||||
loadView: function(aViewId, aCallback) {
|
||||
loadView: function(aViewId) {
|
||||
if (aViewId == this.currentViewId)
|
||||
return;
|
||||
|
||||
window.history.pushState({
|
||||
view: aViewId,
|
||||
previousView: this.currentViewId
|
||||
}, document.title);
|
||||
this.loadViewInternal(aViewId, this.currentViewId);
|
||||
},
|
||||
|
||||
loadInitialView: function(aViewId) {
|
||||
window.history.replaceState({
|
||||
view: aViewId,
|
||||
previousView: null
|
||||
}, document.title);
|
||||
|
||||
this.loadViewInternal(aViewId, null);
|
||||
this.initialViewSelected = true;
|
||||
notifyInitialized();
|
||||
},
|
||||
|
||||
loadViewInternal: function(aViewId, aPreviousView) {
|
||||
var view = this.parseViewId(aViewId);
|
||||
|
||||
if (!view.type || !(view.type in this.viewObjects))
|
||||
@ -329,25 +369,41 @@ var gViewController = {
|
||||
}
|
||||
}
|
||||
|
||||
gCategories.select(aViewId);
|
||||
|
||||
this.previousViewId = this.currentViewId;
|
||||
gCategories.select(aViewId, aPreviousView);
|
||||
|
||||
this.currentViewId = aViewId;
|
||||
this.currentViewObj = viewObj;
|
||||
|
||||
this.viewChangeCallback = aCallback;
|
||||
|
||||
this.viewPort.selectedPanel = this.currentViewObj.node;
|
||||
this.viewPort.selectedPanel.setAttribute("loading", "true");
|
||||
this.currentViewObj.show(view.param, ++this.currentViewRequest);
|
||||
},
|
||||
|
||||
// Moves back in the document history and removes the current history entry
|
||||
popState: function(aCallback) {
|
||||
this.viewChangeCallback = function() {
|
||||
// TODO To ensure we can't go forward again we put an additional entry for
|
||||
// the current page into the history. Ideally we would just strip the
|
||||
// history but there doesn't seem to be a way to do that. Bug 590661
|
||||
window.history.pushState({
|
||||
view: gViewController.currentViewId,
|
||||
previousView: gViewController.currentViewId
|
||||
}, document.title);
|
||||
this.updateCommands();
|
||||
|
||||
if (aCallback)
|
||||
aCallback();
|
||||
};
|
||||
window.history.back();
|
||||
},
|
||||
|
||||
notifyViewChanged: function() {
|
||||
this.viewPort.selectedPanel.removeAttribute("loading");
|
||||
|
||||
if (this.viewChangeCallback)
|
||||
if (this.viewChangeCallback) {
|
||||
this.viewChangeCallback();
|
||||
this.viewChangeCallback = null;
|
||||
}
|
||||
|
||||
var event = document.createEvent("Events");
|
||||
event.initEvent("ViewChanged", true, true);
|
||||
@ -355,6 +411,28 @@ var gViewController = {
|
||||
},
|
||||
|
||||
commands: {
|
||||
cmd_back: {
|
||||
isEnabled: function() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.canGoBack;
|
||||
},
|
||||
doCommand: function() {
|
||||
window.history.back();
|
||||
}
|
||||
},
|
||||
|
||||
cmd_forward: {
|
||||
isEnabled: function() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.canGoForward;
|
||||
},
|
||||
doCommand: function() {
|
||||
window.history.forward();
|
||||
}
|
||||
},
|
||||
|
||||
cmd_restartApp: {
|
||||
isEnabled: function() true,
|
||||
doCommand: function() {
|
||||
@ -616,7 +694,7 @@ var gViewController = {
|
||||
return;
|
||||
}
|
||||
|
||||
gViewController.loadView(gViewController.previousViewId, function() {
|
||||
gViewController.popState(function() {
|
||||
gViewController.currentViewObj.getListItemForID(aAddon.id).uninstall();
|
||||
});
|
||||
},
|
||||
@ -921,15 +999,17 @@ var gCategories = {
|
||||
});
|
||||
},
|
||||
|
||||
select: function(aId) {
|
||||
select: function(aId, aPreviousView) {
|
||||
var view = gViewController.parseViewId(aId);
|
||||
if (view.type == "detail") {
|
||||
aId = aPreviousView;
|
||||
view = gViewController.parseViewId(aPreviousView);
|
||||
}
|
||||
|
||||
if (this.node.selectedItem &&
|
||||
this.node.selectedItem.value == aId)
|
||||
return;
|
||||
|
||||
var view = gViewController.parseViewId(aId);
|
||||
if (view.type == "detail")
|
||||
return;
|
||||
|
||||
if (view.type == "search")
|
||||
var item = this._search;
|
||||
else
|
||||
@ -942,6 +1022,8 @@ var gCategories = {
|
||||
this.node.selectedItem = item;
|
||||
this.node.suppressOnSelect = false;
|
||||
this.node.ensureElementIsVisible(item);
|
||||
// When supressing onselect last-selected doesn't get updated
|
||||
this.node.setAttribute("last-selected", item.id);
|
||||
|
||||
this.maybeHideSearch();
|
||||
}
|
||||
@ -970,21 +1052,12 @@ var gCategories = {
|
||||
var gHeader = {
|
||||
_search: null,
|
||||
_searching: null,
|
||||
_name: null,
|
||||
_link: null,
|
||||
_dest: "",
|
||||
|
||||
initialize: function() {
|
||||
this._name = document.getElementById("header-name");
|
||||
this._link = document.getElementById("header-link");
|
||||
this._search = document.getElementById("header-search");
|
||||
this._searching = document.getElementById("header-searching");
|
||||
|
||||
var self = this;
|
||||
this._link.addEventListener("command", function() {
|
||||
gViewController.loadView(gViewController.previousViewId);
|
||||
}, false);
|
||||
|
||||
this._search.addEventListener("command", function(aEvent) {
|
||||
var query = aEvent.target.value;
|
||||
if (query.length == 0)
|
||||
@ -992,21 +1065,6 @@ var gHeader = {
|
||||
|
||||
gViewController.loadView("addons://search/" + encodeURIComponent(query));
|
||||
}, false);
|
||||
|
||||
this.setName("");
|
||||
},
|
||||
|
||||
setName: function(aName) {
|
||||
this._name.value = aName;
|
||||
this._name.hidden = false;
|
||||
this._link.hidden = true;
|
||||
},
|
||||
|
||||
showBackButton: function() {
|
||||
this._link.label = gStrings.ext.formatStringFromName("header-goBack",
|
||||
[this._name.value], 1);
|
||||
this._name.hidden = true;
|
||||
this._link.hidden = false;
|
||||
},
|
||||
|
||||
get searchQuery() {
|
||||
@ -1069,7 +1127,6 @@ var gDiscoverView = {
|
||||
},
|
||||
|
||||
show: function() {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-discover"));
|
||||
// load content only if we're not already showing something on AMO
|
||||
// XXXunf should only be comparing hostname. bug 557698
|
||||
if (this._browser.currentURI.spec.indexOf(this._browser.homePage) == -1)
|
||||
@ -1127,7 +1184,6 @@ var gSearchView = {
|
||||
},
|
||||
|
||||
show: function(aQuery, aRequest) {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-search"));
|
||||
gHeader.isSearching = true;
|
||||
this.showEmptyNotice(false);
|
||||
|
||||
@ -1360,7 +1416,6 @@ var gListView = {
|
||||
},
|
||||
|
||||
show: function(aType, aRequest) {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-" + aType));
|
||||
this.showEmptyNotice(false);
|
||||
|
||||
while (this._listBox.itemCount > 0)
|
||||
@ -1499,7 +1554,6 @@ var gDetailView = {
|
||||
this._loadingTimer = setTimeout(function() {
|
||||
self.node.setAttribute("loading-extended", true);
|
||||
}, LOADING_MSG_DELAY);
|
||||
gHeader.showBackButton();
|
||||
|
||||
var view = gViewController.currentViewId;
|
||||
|
||||
@ -1624,7 +1678,7 @@ var gDetailView = {
|
||||
},
|
||||
|
||||
onUninstalled: function() {
|
||||
gViewController.loadView(gViewController.previousViewId);
|
||||
gViewController.popState();
|
||||
},
|
||||
|
||||
onOperationCancelled: function() {
|
||||
@ -1678,8 +1732,6 @@ var gUpdatesView = {
|
||||
},
|
||||
|
||||
show: function(aType, aRequest) {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-" + aType + "Updates"));
|
||||
|
||||
document.getElementById("empty-availableUpdates-msg").hidden = aType != "available";
|
||||
document.getElementById("empty-recentUpdates-msg").hidden = aType != "recent";
|
||||
this.showEmptyNotice(false);
|
||||
|
@ -21,6 +21,7 @@
|
||||
-
|
||||
- Contributor(s):
|
||||
- Blair McBride <bmcbride@mozilla.com>
|
||||
- David Dahl <ddahl@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
|
||||
@ -801,8 +802,13 @@
|
||||
</xul:hbox>
|
||||
<xul:hbox anonid="control-container" class="control-container">
|
||||
<xul:button anonid="preferences-btn" class="addon-control"
|
||||
label="&cmd.showPreferences.label;"
|
||||
tooltiptext="&cmd.showPreferences.tooltip;"
|
||||
#ifdef XP_WIN
|
||||
label="&cmd.showPreferencesWin.label;"
|
||||
tooltiptext="&cmd.showPreferencesWin.tooltip;"
|
||||
#else
|
||||
label="&cmd.showPreferencesUnix.label;"
|
||||
tooltiptext="&cmd.showPreferencesUnix.tooltip;"
|
||||
#endif
|
||||
oncommand="document.getBindingParent(this).showPreferences();"/>
|
||||
<xul:button anonid="enable-btn" class="addon-control enable"
|
||||
label="&cmd.enableAddon.label;"
|
||||
|
@ -21,6 +21,7 @@
|
||||
-
|
||||
- Contributor(s):
|
||||
- Blair McBride <bmcbride@mozilla.com>
|
||||
- David Dahl <ddahl@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
|
||||
@ -69,8 +70,13 @@
|
||||
accesskey="&cmd.findUpdates.accesskey;"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menuitem_preferences" command="cmd_showItemPreferences"
|
||||
label="&cmd.preferences.label;"
|
||||
accesskey="&cmd.preferences.accesskey;"/>
|
||||
#ifdef XP_WIN
|
||||
label="&cmd.preferencesWin.label;"
|
||||
accesskey="&cmd.preferencesWin.accesskey;"/>
|
||||
#else
|
||||
label="&cmd.preferencesUnix.label;"
|
||||
accesskey="&cmd.preferencesUnix.accesskey;"/>
|
||||
#endif
|
||||
<menuitem id="menuitem_about" command="cmd_showItemAbout"
|
||||
label="&cmd.about.label;"
|
||||
accesskey="&cmd.about.accesskey;"/>
|
||||
@ -88,6 +94,8 @@
|
||||
<command id="cmd_goToAvailableUpdates"/>
|
||||
<command id="cmd_toggleBackgroundUpdateCheck"/>
|
||||
<command id="cmd_installFromFile"/>
|
||||
<command id="cmd_back"/>
|
||||
<command id="cmd_forward"/>
|
||||
</commandset>
|
||||
|
||||
<!-- view commands - these act on the selected addon -->
|
||||
@ -107,8 +115,10 @@
|
||||
|
||||
<!-- main header -->
|
||||
<hbox id="header" align="center">
|
||||
<label id="header-name"/>
|
||||
<button id="header-link"/>
|
||||
<button id="back-btn" class="nav-button" command="cmd_back"
|
||||
tooltiptext="&cmd.back.tooltip;"/>
|
||||
<button id="forward-btn" class="nav-button" command="cmd_forward"
|
||||
tooltiptext="&cmd.forward.tooltip;"/>
|
||||
<spacer flex="1"/>
|
||||
<hbox id="updates-container" align="center">
|
||||
<image class="spinner"/>
|
||||
@ -127,7 +137,12 @@
|
||||
label="&updates.restart.label;"
|
||||
command="cmd_restartApp"/>
|
||||
</hbox>
|
||||
<button id="header-utils-btn" type="menu">
|
||||
<button id="header-utils-btn" type="menu"
|
||||
#ifdef XP_WIN
|
||||
tooltiptext="&view.utilites.preferences.tooltip;">
|
||||
#else
|
||||
tooltiptext="&view.utilites.preferencesUnix.tooltip;">
|
||||
#endif
|
||||
<menupopup id="utils-menu">
|
||||
<menuitem id="utils-updateNow"
|
||||
label="&updates.updateAddonsNow.label;"
|
||||
@ -346,9 +361,15 @@
|
||||
tooltiptext="&detail.checkForUpdates.tooltip;"
|
||||
command="cmd_findItemUpdates"/>
|
||||
<button id="detail-prefs" class="addon-control"
|
||||
label="&detail.showPreferences.label;"
|
||||
accesskey="&detail.showPreferences.accesskey;"
|
||||
tooltiptext="&detail.showPreferences.tooltip;"
|
||||
#ifdef XP_WIN
|
||||
label="&detail.showPreferencesWin.label;"
|
||||
accesskey="&detail.showPreferencesWin.accesskey;"
|
||||
tooltiptext="&detail.showPreferencesWin.tooltip;"
|
||||
#else
|
||||
label="&detail.showPreferencesUnix.label;"
|
||||
accesskey="&detail.showPreferencesUnix.accesskey;"
|
||||
tooltiptext="&detail.showPreferencesUnix.tooltip;"
|
||||
#endif
|
||||
command="cmd_showItemPreferences"/>
|
||||
</vbox>
|
||||
<grid class="detail-meta fade" flex="1">
|
||||
|
@ -1,9 +1,9 @@
|
||||
toolkit.jar:
|
||||
% content mozapps %content/mozapps/
|
||||
content/mozapps/extensions/extensions.xul (content/extensions.xul)
|
||||
* content/mozapps/extensions/extensions.xul (content/extensions.xul)
|
||||
content/mozapps/extensions/extensions.css (content/extensions.css)
|
||||
content/mozapps/extensions/extensions.js (content/extensions.js)
|
||||
content/mozapps/extensions/extensions.xml (content/extensions.xml)
|
||||
* content/mozapps/extensions/extensions.xml (content/extensions.xml)
|
||||
content/mozapps/extensions/updateinfo.xsl (content/updateinfo.xsl)
|
||||
content/mozapps/extensions/extensions-content.js (content/extensions-content.js)
|
||||
* content/mozapps/extensions/about.xul (content/about.xul)
|
||||
|
@ -52,6 +52,7 @@ _TEST_FILES = \
|
||||
browser_bug557956.rdf \
|
||||
browser_bug557956_8_2.xpi \
|
||||
browser_bug557956_9_2.xpi \
|
||||
browser_bug562797.js \
|
||||
browser_bug562890.js \
|
||||
browser_bug562899.js \
|
||||
browser_bug562992.js \
|
||||
|
502
toolkit/mozapps/extensions/test/browser/browser_bug562797.js
Normal file
502
toolkit/mozapps/extensions/test/browser/browser_bug562797.js
Normal file
@ -0,0 +1,502 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests that history navigation works for the add-ons manager. Only used if
|
||||
* in-content UI is supported for this application.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
// XXX
|
||||
ok(true, "Test temporarily disabled due to timeouts\n");
|
||||
return;
|
||||
|
||||
if (!gUseInContentUI)
|
||||
return;
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
var gProvider = new MockProvider();
|
||||
gProvider.createAddons([{
|
||||
id: "test1@tests.mozilla.org",
|
||||
name: "Test add-on 1",
|
||||
description: "foo"
|
||||
},
|
||||
{
|
||||
id: "test2@tests.mozilla.org",
|
||||
name: "Test add-on 2",
|
||||
description: "bar"
|
||||
},
|
||||
{
|
||||
id: "test3@tests.mozilla.org",
|
||||
name: "Test add-on 3",
|
||||
type: "theme",
|
||||
description: "bar"
|
||||
}]);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
finish();
|
||||
}
|
||||
|
||||
function is_in_list(aManager, view, canGoBack, canGoForward) {
|
||||
var doc = aManager.document;
|
||||
|
||||
is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
|
||||
is(doc.getElementById("view-port").selectedPanel.id, "list-view", "Should be on the right view");
|
||||
is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
|
||||
is(!doc.getElementById("back-btn").disabled, canGoBack, "Back button should have the right state");
|
||||
is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
|
||||
is(!doc.getElementById("forward-btn").disabled, canGoForward, "Forward button should have the right state");
|
||||
}
|
||||
|
||||
function is_in_search(aManager, query, canGoBack, canGoForward) {
|
||||
var doc = aManager.document;
|
||||
|
||||
is(doc.getElementById("categories").selectedItem.value, "addons://search/", "Should be on the right category");
|
||||
is(doc.getElementById("view-port").selectedPanel.id, "search-view", "Should be on the right view");
|
||||
is(doc.getElementById("header-search").value, query, "Should have used the right query");
|
||||
is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
|
||||
is(!doc.getElementById("back-btn").disabled, canGoBack, "Back button should have the right state");
|
||||
is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
|
||||
is(!doc.getElementById("forward-btn").disabled, canGoForward, "Forward button should have the right state");
|
||||
}
|
||||
|
||||
function is_in_detail(aManager, view, canGoBack, canGoForward) {
|
||||
var doc = aManager.document;
|
||||
|
||||
is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
|
||||
is(doc.getElementById("view-port").selectedPanel.id, "detail-view", "Should be on the right view");
|
||||
is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
|
||||
is(!doc.getElementById("back-btn").disabled, canGoBack, "Back button should have the right state");
|
||||
is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
|
||||
is(!doc.getElementById("forward-btn").disabled, canGoForward, "Forward button should have the right state");
|
||||
}
|
||||
|
||||
// Tests simple forward and back navigation and that the right heading and
|
||||
// category is selected
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("category-plugins"), 2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
gBrowser.goForward();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test1@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 6");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 7");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that browsing to the add-ons manager from a website and going back works
|
||||
add_test(function() {
|
||||
info("Part 1");
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.loadURI("http://example.com/");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
//Must let the load complete for it to go into the session history
|
||||
executeSoon(function() {
|
||||
info("Part 2");
|
||||
ok(!gBrowser.canGoBack, "Should not be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.loadURI("about:addons");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, true);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
gBrowser.addEventListener("pageshow", function() {
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
info("Part 4");
|
||||
is(gBrowser.currentURI.spec, "http://example.com/", "Should be showing the webpage");
|
||||
ok(!gBrowser.canGoBack, "Should not be able to go back");
|
||||
ok(gBrowser.canGoForward, "Should be able to go forward");
|
||||
|
||||
gBrowser.goForward();
|
||||
gBrowser.addEventListener("pageshow", function() {
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
}, false);
|
||||
}, false);
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
|
||||
// Tests that opening a custom first view only stores a single history entry
|
||||
add_test(function() {
|
||||
open_manager("addons://list/plugin", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/plugin", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("category-extensions"), 2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/plugin", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Tests that opening a view while the manager is already open adds a new
|
||||
// history entry
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
aManager.loadView("addons://list/plugin");
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
gBrowser.goForward();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests than navigating to a website and then going back returns to the
|
||||
// previous view
|
||||
add_test(function() {
|
||||
open_manager("addons://list/plugin", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/plugin", false, false);
|
||||
|
||||
gBrowser.loadURI("http://example.com/");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
info("Part 2");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(gBrowser.canGoBack, "Should be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/plugin", false, true);
|
||||
|
||||
gBrowser.goForward();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
info("Part 4");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(gBrowser.canGoBack, "Should be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_list(aManager, "addons://list/plugin", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that going back to search results works
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
var search = aManager.document.getElementById("header-search");
|
||||
search.focus();
|
||||
search.value = "bar";
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_search(aManager, "bar", true, false);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test2@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_detail(aManager, "addons://search/", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_search(aManager, "bar", true, true);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
gBrowser.goForward();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_detail(aManager, "addons://search/", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that going back to a detail view loaded from a search result works
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
var search = aManager.document.getElementById("header-search");
|
||||
search.focus();
|
||||
search.value = "bar";
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_search(aManager, "bar", true, false);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test2@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_detail(aManager, "addons://search/", true, false);
|
||||
|
||||
gBrowser.loadURI("http://example.com/");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
info("Part 4");
|
||||
executeSoon(function() {
|
||||
ok(gBrowser.canGoBack, "Should be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.goBack();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_detail(aManager, "addons://search/", true, true);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 6");
|
||||
is_in_search(aManager, "bar", true, true);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that refreshing a list view does not affect the history
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("category-plugins"), 2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.reload();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that refreshing a detail view does not affect the history
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test1@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.reload();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that removing an extension from the detail view goes back and doesn't
|
||||
// allow you to go forward again.
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test1@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("detail-uninstall"),
|
||||
2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function() {
|
||||
// TODO until bug 590661 is fixed the back button will be enabled
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -437,10 +437,8 @@ add_test(function() {
|
||||
var version = gManagerWindow.document.getElementById("detail-version").value;
|
||||
is(version, item.mAddon.version, "Version in detail view should be correct");
|
||||
|
||||
var headerLink = gManagerWindow.document.getElementById("header-link");
|
||||
is(headerLink.hidden, false, "Header link should be showing in detail view");
|
||||
|
||||
EventUtils.synthesizeMouse(headerLink, 2, 2, { }, gManagerWindow);
|
||||
EventUtils.synthesizeMouse(gManagerWindow.document.getElementById("back-btn"),
|
||||
2, 2, { }, gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, run_next_double_click_test);
|
||||
});
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ const PREF_SEARCH_MAXRESULTS = "extensions.getAddons.maxResults";
|
||||
var gPendingTests = [];
|
||||
var gTestsRun = 0;
|
||||
|
||||
var gUseInContentUI = ("switchToTabHavingURI" in window);
|
||||
|
||||
// Turn logging on for all tests
|
||||
Services.prefs.setBoolPref(PREF_LOGGING_ENABLED, true);
|
||||
// Turn off remote results in searches
|
||||
@ -71,6 +73,49 @@ function get_addon_file_url(aFilename) {
|
||||
}
|
||||
}
|
||||
|
||||
function check_all_in_list(aManager, aIds, aIgnoreExtras) {
|
||||
var doc = aManager.document;
|
||||
var view = doc.getElementById("view-port").selectedPanel;
|
||||
var listid = view.id == "search-view" ? "search-list" : "addon-list";
|
||||
var list = doc.getElementById(listid);
|
||||
|
||||
var inlist = [];
|
||||
var node = list.firstChild;
|
||||
while (node) {
|
||||
if (node.value)
|
||||
inlist.push(node.value);
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
for (var i = 0; i < aIds.length; i++) {
|
||||
if (inlist.indexOf(aIds[i]) == -1)
|
||||
ok(false, "Should find " + aIds[i] + " in the list");
|
||||
}
|
||||
|
||||
if (aIgnoreExtras)
|
||||
return;
|
||||
|
||||
for (i = 0; i < inlist.length; i++) {
|
||||
if (aIds.indexOf(inlist[i]) == -1)
|
||||
ok(false, "Shouldn't have seen " + inlist[i] + " in the list");
|
||||
}
|
||||
}
|
||||
|
||||
function get_addon_element(aManager, aId) {
|
||||
var doc = aManager.document;
|
||||
var view = doc.getElementById("view-port").selectedPanel;
|
||||
var listid = view.id == "search-view" ? "search-list" : "addon-list";
|
||||
var list = doc.getElementById(listid);
|
||||
|
||||
var node = list.firstChild;
|
||||
while (node) {
|
||||
if (node.value == aId)
|
||||
return node;
|
||||
node = node.nextSibling;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function wait_for_view_load(aManagerWindow, aCallback, aForceWait) {
|
||||
if (!aForceWait && !aManagerWindow.gViewController.isLoading) {
|
||||
aCallback(aManagerWindow);
|
||||
@ -89,6 +134,7 @@ function wait_for_manager_load(aManagerWindow, aCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
info("Waiting for initialization");
|
||||
aManagerWindow.document.addEventListener("Initialized", function() {
|
||||
aManagerWindow.document.removeEventListener("Initialized", arguments.callee, false);
|
||||
aCallback(aManagerWindow);
|
||||
@ -111,7 +157,7 @@ function open_manager(aView, aCallback, aLoadCallback) {
|
||||
});
|
||||
}
|
||||
|
||||
if ("switchToTabHavingURI" in window) {
|
||||
if (gUseInContentUI) {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
switchToTabHavingURI(MANAGER_URI, true, function(aBrowser) {
|
||||
setup_manager(aBrowser.contentWindow.wrappedJSObject);
|
||||
|
@ -20,6 +20,7 @@
|
||||
# Contributor(s):
|
||||
# Robert Strong <robert.bugzilla@gmail.com>
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Amir Szekely <kichik@gmail.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
|
||||
@ -111,6 +112,8 @@
|
||||
!include /NONFATAL WinVer.nsh
|
||||
!endif
|
||||
|
||||
!include x64.nsh
|
||||
|
||||
; NSIS provided macros that we have overridden.
|
||||
!include overrides.nsh
|
||||
|
||||
@ -468,21 +471,38 @@
|
||||
SetOutPath "$R7"
|
||||
StrCpy $R9 "false"
|
||||
|
||||
start:
|
||||
Pop $R8
|
||||
StrCmp "$R8" "end" end +1
|
||||
IfFileExists "$INSTDIR\$R8" +1 start
|
||||
${While} $R8 != "end"
|
||||
${Unless} ${FileExists} "$INSTDIR\$R8"
|
||||
Pop $R8 ; get next file to check before continuing
|
||||
${Continue}
|
||||
${EndUnless}
|
||||
|
||||
ClearErrors
|
||||
CopyFiles /SILENT "$INSTDIR\$R8" "$R7\$R8"
|
||||
IfErrors +4 +1
|
||||
Delete "$INSTDIR\$R8"
|
||||
IfErrors +1 start
|
||||
Delete "$R7\$R8"
|
||||
ClearErrors
|
||||
CopyFiles /SILENT "$INSTDIR\$R8" "$R7\$R8" ; try to copy
|
||||
${If} ${Errors}
|
||||
; File is in use
|
||||
StrCpy $R9 "true"
|
||||
${Break}
|
||||
${EndIf}
|
||||
|
||||
StrCpy $R9 "true"
|
||||
Delete "$INSTDIR\$R8" ; delete original
|
||||
${If} ${Errors}
|
||||
; File is in use
|
||||
StrCpy $R9 "true"
|
||||
Delete "$R7\$R8" ; delete temp copy
|
||||
${Break}
|
||||
${EndIf}
|
||||
|
||||
end:
|
||||
Pop $R8 ; get next file to check
|
||||
${EndWhile}
|
||||
|
||||
; clear stack
|
||||
${While} $R8 != "end"
|
||||
Pop $R8
|
||||
${EndWhile}
|
||||
|
||||
; restore everything
|
||||
SetOutPath "$INSTDIR"
|
||||
CopyFiles /SILENT "$R7\*" "$INSTDIR\"
|
||||
RmDir /r "$R7"
|
||||
@ -577,9 +597,10 @@
|
||||
Push $R7
|
||||
|
||||
FindWindow $R7 "$R8"
|
||||
IntCmp $R7 0 +3 +1 +1
|
||||
MessageBox MB_OK|MB_ICONQUESTION "$R9"
|
||||
Abort
|
||||
${If} $R7 <> 0 ; integer comparison
|
||||
MessageBox MB_OK|MB_ICONQUESTION "$R9"
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
Pop $R7
|
||||
Exch $R8
|
||||
@ -665,8 +686,8 @@
|
||||
|
||||
FindWindow $R7 "${WindowClass}"
|
||||
IntCmp $R7 0 +4 +1 +1
|
||||
System::Call 'user32::PostMessage(i r17, i ${WM_QUIT}, i 0, i 0)'
|
||||
# The amount of time to wait for the app to shutdown before prompting again
|
||||
System::Call 'user32::PostMessage(i R7, i ${WM_QUIT}, i 0, i 0)'
|
||||
; The amount of time to wait for the app to shutdown before prompting again
|
||||
Sleep 5000
|
||||
|
||||
Push $R6
|
||||
@ -781,12 +802,14 @@
|
||||
WriteRegStr SHCTX "$R6" "$R7" "$R8"
|
||||
|
||||
!ifndef NO_LOG
|
||||
IfErrors 0 +3
|
||||
${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **"
|
||||
GoTo +4
|
||||
StrCmp "$R9" "1" +1 +2
|
||||
${LogUninstall} "RegVal: $R5 | $R6 | $R7"
|
||||
${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8"
|
||||
${If} ${Errors}
|
||||
${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **"
|
||||
${Else}
|
||||
${If} $R9 == 1 ; add to the uninstall log?
|
||||
${LogUninstall} "RegVal: $R5 | $R6 | $R7"
|
||||
${EndIf}
|
||||
${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8"
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
Exch $R5
|
||||
@ -889,12 +912,14 @@
|
||||
WriteRegDWORD SHCTX "$R6" "$R7" "$R8"
|
||||
|
||||
!ifndef NO_LOG
|
||||
IfErrors 0 +3
|
||||
${LogMsg} "** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **"
|
||||
GoTo +4
|
||||
StrCmp "$R9" "1" +1 +2
|
||||
${LogUninstall} "RegVal: $R5 | $R6 | $R7"
|
||||
${LogMsg} "Added Registry DWord: $R5 | $R6 | $R7 | $R8"
|
||||
${If} ${Errors}
|
||||
${LogMsg} "** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **"
|
||||
${Else}
|
||||
${If} $R9 == 1 ; add to the uninstall log?
|
||||
${LogUninstall} "RegVal: $R5 | $R6 | $R7"
|
||||
${EndIf}
|
||||
${LogMsg} "Added Registry DWord: $R5 | $R6 | $R7 | $R8"
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
Exch $R5
|
||||
@ -997,12 +1022,14 @@
|
||||
WriteRegStr HKCR "$R6" "$R7" "$R8"
|
||||
|
||||
!ifndef NO_LOG
|
||||
IfErrors 0 +3
|
||||
${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **"
|
||||
GoTo +4
|
||||
StrCmp "$R9" "1" +1 +2
|
||||
${LogUninstall} "RegVal: $R5 | $R6 | $R7"
|
||||
${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8"
|
||||
${If} ${Errors}
|
||||
${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **"
|
||||
${Else}
|
||||
${If} $R9 == 1 ; add to the uninstall log?
|
||||
${LogUninstall} "RegVal: $R5 | $R6 | $R7"
|
||||
${EndIf}
|
||||
${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8"
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
Exch $R5
|
||||
@ -1059,16 +1086,13 @@
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Creates a registry key. NSIS doesn't supply a RegCreateKey method and instead
|
||||
* will auto create keys when a reg key name value pair is set.
|
||||
* i - int (includes char, byte, short, handles, pointers and so on)
|
||||
* w - wide-char text, string (LPCWSTR, pointer to first character)
|
||||
* * - pointer specifier -> the proc needs the pointer to type, affects next
|
||||
* char (parameter) [ex: '*i' - pointer to int]
|
||||
* see the NSIS documentation for additional information.
|
||||
*/
|
||||
!define RegCreateKey "Advapi32::RegCreateKeyW(i, w, *i) i"
|
||||
!define KEY_SET_VALUE 0x0002
|
||||
!define KEY_WOW64_64KEY 0x0100
|
||||
!ifndef HAVE_64BIT_OS
|
||||
!define CREATE_KEY_SAM ${KEY_SET_VALUE}
|
||||
!else
|
||||
!define CREATE_KEY_SAM ${KEY_SET_VALUE}|${KEY_WOW64_64KEY}
|
||||
!endif
|
||||
|
||||
/**
|
||||
* Creates a registry key. This will log the actions to the install and
|
||||
@ -1088,8 +1112,8 @@
|
||||
* located in one of the predefined registry keys this must be closed
|
||||
* with RegCloseKey (this should not be needed unless someone decides to
|
||||
* do something extremely squirrelly with NSIS).
|
||||
* $R5 = return value from RegCreateKeyA (represented by r15 in the system call).
|
||||
* $R6 = [in] hKey passed to RegCreateKeyA.
|
||||
* $R5 = return value from RegCreateKeyExW (represented by R5 in the system call).
|
||||
* $R6 = [in] hKey passed to RegCreateKeyExW.
|
||||
* $R7 = _ROOT
|
||||
* $R8 = _KEY
|
||||
* $R9 = _LOG_UNINSTALL
|
||||
@ -1119,18 +1143,25 @@
|
||||
StrCpy $R6 "0x80000002"
|
||||
|
||||
; see definition of RegCreateKey
|
||||
System::Call "${RegCreateKey}($R6, '$R8', .r14) .r15"
|
||||
System::Call "Advapi32::RegCreateKeyExW(i R6, w R8, i 0, i 0, i 0,\
|
||||
i ${CREATE_KEY_SAM}, i 0, *i .R4,\
|
||||
i 0) i .R5"
|
||||
|
||||
!ifndef NO_LOG
|
||||
; if $R5 is not 0 then there was an error creating the registry key.
|
||||
IntCmp $R5 0 +3 +3
|
||||
${LogMsg} "** ERROR Adding Registry Key: $R7 | $R8 **"
|
||||
GoTo +4
|
||||
StrCmp "$R9" "1" +1 +2
|
||||
${LogUninstall} "RegKey: $R7 | $R8"
|
||||
${LogMsg} "Added Registry Key: $R7 | $R8"
|
||||
${If} $R5 <> 0
|
||||
${LogMsg} "** ERROR Adding Registry Key: $R7 | $R8 **"
|
||||
${Else}
|
||||
${If} $R9 == 1 ; add to the uninstall log?
|
||||
${LogUninstall} "RegKey: $R7 | $R8"
|
||||
${EndIf}
|
||||
${LogMsg} "Added Registry Key: $R7 | $R8"
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
StrCmp $R5 0 +1 +2
|
||||
System::Call "Advapi32::RegCloseKey(iR4)"
|
||||
|
||||
Pop $R4
|
||||
Pop $R5
|
||||
Pop $R6
|
||||
@ -1484,6 +1515,43 @@
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
################################################################################
|
||||
# Macros for handling DLL registration
|
||||
|
||||
|
||||
!macro RegisterDLL DLL
|
||||
|
||||
; The x64 regsvr32.exe registers x86 DLL's properly on Windows Vista and above
|
||||
; (not on Windows XP http://support.microsoft.com/kb/282747) so just use it
|
||||
; when installing on an x64 systems even when installing an x86 application.
|
||||
${If} ${RunningX64}
|
||||
${DisableX64FSRedirection}
|
||||
ExecWait '"$SYSDIR\regsvr32.exe" /s "${DLL}"'
|
||||
${EnableX64FSRedirection}
|
||||
${Else}
|
||||
RegDLL "${DLL}"
|
||||
${EndIf}
|
||||
|
||||
!macroend
|
||||
|
||||
!macro UnregisterDLL DLL
|
||||
|
||||
; The x64 regsvr32.exe registers x86 DLL's properly on Windows Vista and above
|
||||
; (not on Windows XP http://support.microsoft.com/kb/282747) so just use it
|
||||
; when installing on an x64 systems even when installing an x86 application.
|
||||
${If} ${RunningX64}
|
||||
${DisableX64FSRedirection}
|
||||
ExecWait '"$SYSDIR\regsvr32.exe" /s /u "${DLL}"'
|
||||
${EnableX64FSRedirection}
|
||||
${Else}
|
||||
UnRegDLL "${DLL}"
|
||||
${EndIf}
|
||||
|
||||
!macroend
|
||||
|
||||
!define RegisterDLL `!insertmacro RegisterDLL`
|
||||
!define UnregisterDLL `!insertmacro UnregisterDLL`
|
||||
|
||||
################################################################################
|
||||
# Macros for retrieving existing install paths
|
||||
|
||||
@ -1781,20 +1849,31 @@
|
||||
; UNC path so always try to create $INSTDIR
|
||||
CreateDirectory "$INSTDIR\"
|
||||
GetTempFileName $R8 "$INSTDIR\"
|
||||
IfFileExists "$R8" +3 +1 ; Can files be created?
|
||||
StrCpy $R9 "false"
|
||||
Goto +12
|
||||
Delete "$R8"
|
||||
IfFileExists "$R8" +1 +3 ; Can files be deleted?
|
||||
StrCpy $R9 "false"
|
||||
Goto +8
|
||||
CreateDirectory "$R8"
|
||||
IfFileExists "$R8" +3 +1 ; Can directories be created?
|
||||
StrCpy $R9 "false"
|
||||
GoTo +4
|
||||
RmDir "$R8"
|
||||
IfFileExists "$R8" +1 +2 ; Can directories be deleted?
|
||||
StrCpy $R9 "false"
|
||||
|
||||
${Unless} ${FileExists} $R8 ; Can files be created?
|
||||
StrCpy $R9 "false"
|
||||
Goto done
|
||||
${EndUnless}
|
||||
|
||||
Delete $R8
|
||||
${If} ${FileExists} $R8 ; Can files be deleted?
|
||||
StrCpy $R9 "false"
|
||||
Goto done
|
||||
${EndIf}
|
||||
|
||||
CreateDirectory $R8
|
||||
${Unless} ${FileExists} $R8 ; Can directories be created?
|
||||
StrCpy $R9 "false"
|
||||
Goto done
|
||||
${EndUnless}
|
||||
|
||||
RmDir $R8
|
||||
${If} ${FileExists} $R8 ; Can directories be deleted?
|
||||
StrCpy $R9 "false"
|
||||
Goto done
|
||||
${EndIf}
|
||||
|
||||
done:
|
||||
|
||||
RmDir "$INSTDIR\" ; Only remove $INSTDIR if it is empty
|
||||
ClearErrors
|
||||
@ -1843,7 +1922,7 @@
|
||||
* directory using GetDiskFreeSpaceExW which respects disk quotas. This macro
|
||||
* will calculate the size of all sections that are selected, compare that with
|
||||
* the free space available, and if there is sufficient free space it will
|
||||
* return true... if not, it will return false.
|
||||
* return true... if not, it will return false.
|
||||
*
|
||||
* @return _RESULT
|
||||
* "true" if there is sufficient free space otherwise "false".
|
||||
@ -1902,7 +1981,7 @@
|
||||
Delete "$R7"
|
||||
CreateDirectory "$R7"
|
||||
|
||||
System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i(r17, .r16, ., .) .'
|
||||
System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i(R7, .R6, ., .) .'
|
||||
|
||||
; Convert to KB for comparison with $R8 which is in KB
|
||||
System::Int64Op $R6 / 1024
|
||||
@ -2199,7 +2278,7 @@
|
||||
GetFullPathName $R8 "$R9"
|
||||
IfErrors end_GetLongPath +1 ; If the path doesn't exist return an empty string.
|
||||
|
||||
System::Call 'kernel32::GetLongPathNameW(w r18, w .r17, i 1024)i .r16'
|
||||
System::Call 'kernel32::GetLongPathNameW(w R8, w .R7, i 1024)i .R6'
|
||||
StrCmp "$R7" "" +4 +1 ; Empty string when GetLongPathNameW is not present.
|
||||
StrCmp $R6 0 +3 +1 ; Should never equal 0 since the path exists.
|
||||
StrCpy $R9 "$R7"
|
||||
@ -2307,6 +2386,9 @@
|
||||
* to this reg cleanup since the referenced key would be for an app that is no
|
||||
* longer installed on the system.
|
||||
*
|
||||
* $R0 = on x64 systems set to 'false' at the beginning of the macro when
|
||||
* enumerating the x86 registry view and set to 'true' when enumerating
|
||||
* the x64 registry view.
|
||||
* $R1 = stores the long path to $INSTDIR
|
||||
* $R2 = return value from the stack from the GetParent and GetLongPath macros
|
||||
* $R3 = return value from the outer loop's EnumRegKey
|
||||
@ -2342,10 +2424,23 @@
|
||||
Push $R3
|
||||
Push $R2
|
||||
Push $R1
|
||||
Push $R0
|
||||
|
||||
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R1
|
||||
StrCpy $R6 0 ; set the counter for the outer loop to 0
|
||||
|
||||
${If} ${RunningX64}
|
||||
StrCpy $R0 "false"
|
||||
; Set the registry to the 32 bit registry for 64 bit installations or to
|
||||
; the 64 bit registry for 32 bit installations at the beginning so it can
|
||||
; easily be set back to the correct registry view when finished.
|
||||
!ifdef HAVE_64BIT_OS
|
||||
SetRegView 32
|
||||
!else
|
||||
SetRegView 64
|
||||
!endif
|
||||
${EndIf}
|
||||
|
||||
outerloop:
|
||||
EnumRegKey $R3 SHCTX $R9 $R6
|
||||
StrCmp $R3 "" end +1 ; if empty there are no more keys to enumerate
|
||||
@ -2393,8 +2488,23 @@
|
||||
GoTo outerloop
|
||||
|
||||
end:
|
||||
${If} ${RunningX64}
|
||||
${AndIf} "$R0" == "false"
|
||||
; Set the registry to the correct view.
|
||||
!ifdef HAVE_64BIT_OS
|
||||
SetRegView 64
|
||||
!else
|
||||
SetRegView 32
|
||||
!endif
|
||||
|
||||
StrCpy $R6 0 ; set the counter for the outer loop to 0
|
||||
StrCpy $R0 "true"
|
||||
GoTo outerloop
|
||||
${EndIf}
|
||||
|
||||
ClearErrors
|
||||
|
||||
Pop $R0
|
||||
Pop $R1
|
||||
Pop $R2
|
||||
Pop $R3
|
||||
@ -2443,9 +2553,13 @@
|
||||
|
||||
/**
|
||||
* Removes all registry keys from \Software\Windows\CurrentVersion\Uninstall
|
||||
* that reference this install location. This uses SHCTX to determine the
|
||||
* registry hive so you must call SetShellVarContext first.
|
||||
* that reference this install location in both the 32 bit and 64 bit registry
|
||||
* view. This macro uses SHCTX to determine the registry hive so you must call
|
||||
* SetShellVarContext first.
|
||||
*
|
||||
* $R3 = on x64 systems set to 'false' at the beginning of the macro when
|
||||
* enumerating the x86 registry view and set to 'true' when enumerating
|
||||
* the x64 registry view.
|
||||
* $R4 = stores the long path to $INSTDIR
|
||||
* $R5 = return value from ReadRegStr
|
||||
* $R6 = string for the base reg key (e.g. Software\Microsoft\Windows\CurrentVersion\Uninstall)
|
||||
@ -2474,12 +2588,25 @@
|
||||
Push $R6
|
||||
Push $R5
|
||||
Push $R4
|
||||
Push $R3
|
||||
|
||||
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R4
|
||||
StrCpy $R6 "Software\Microsoft\Windows\CurrentVersion\Uninstall"
|
||||
StrCpy $R7 ""
|
||||
StrCpy $R8 0
|
||||
|
||||
${If} ${RunningX64}
|
||||
StrCpy $R3 "false"
|
||||
; Set the registry to the 32 bit registry for 64 bit installations or to
|
||||
; the 64 bit registry for 32 bit installations at the beginning so it can
|
||||
; easily be set back to the correct registry view when finished.
|
||||
!ifdef HAVE_64BIT_OS
|
||||
SetRegView 32
|
||||
!else
|
||||
SetRegView 64
|
||||
!endif
|
||||
${EndIf}
|
||||
|
||||
loop:
|
||||
EnumRegKey $R7 SHCTX $R6 $R8
|
||||
StrCmp $R7 "" end +1
|
||||
@ -2492,13 +2619,29 @@
|
||||
StrCmp "$R9" "$R4" +1 loop
|
||||
ClearErrors
|
||||
DeleteRegKey SHCTX "$R6\$R7"
|
||||
IfErrors loop
|
||||
IfErrors loop +1
|
||||
IntOp $R8 $R8 - 1 ; Decrement the counter on successful deletion
|
||||
GoTo loop
|
||||
|
||||
end:
|
||||
${If} ${RunningX64}
|
||||
${AndIf} "$R3" == "false"
|
||||
; Set the registry to the correct view.
|
||||
!ifdef HAVE_64BIT_OS
|
||||
SetRegView 64
|
||||
!else
|
||||
SetRegView 32
|
||||
!endif
|
||||
|
||||
StrCpy $R7 ""
|
||||
StrCpy $R8 0
|
||||
StrCpy $R3 "true"
|
||||
GoTo loop
|
||||
${EndIf}
|
||||
|
||||
ClearErrors
|
||||
|
||||
Pop $R3
|
||||
Pop $R4
|
||||
Pop $R5
|
||||
Pop $R6
|
||||
@ -2838,15 +2981,16 @@
|
||||
StrCpy $R8 "$R9"
|
||||
StrCpy $R9 "false"
|
||||
ReadRegStr $R7 SHCTX "Software\Classes\$R8\shell\open\command" ""
|
||||
StrCmp "$R7" "" end
|
||||
|
||||
${GetPathFromString} "$R7" $R7
|
||||
${GetParent} "$R7" $R7
|
||||
${GetLongPath} "$R7" $R7
|
||||
StrCmp "$R7" "$INSTDIR" +1 end
|
||||
StrCpy $R9 "true"
|
||||
${If} $R7 != ""
|
||||
${GetPathFromString} "$R7" $R7
|
||||
${GetParent} "$R7" $R7
|
||||
${GetLongPath} "$R7" $R7
|
||||
${If} $R7 == $INSTDIR
|
||||
StrCpy $R9 "true"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
end:
|
||||
ClearErrors
|
||||
|
||||
Pop $R7
|
||||
@ -2892,14 +3036,14 @@
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* If present removes the VirtualStore directory for this installation. Uses the
|
||||
* program files directory path and the current install location to determine
|
||||
* the sub-directory in the VirtualStore directory.
|
||||
* Removes the application's VirtualStore directory if present when the
|
||||
* installation directory is a sub-directory of the program files directory.
|
||||
*
|
||||
* $R4 = $PROGRAMFILES/$PROGRAMFILES64 for CleanVirtualStore_Internal
|
||||
* $R5 = various path values.
|
||||
* $R6 = length of the long path to $PROGRAMFILES
|
||||
* $R7 = length of the long path to $INSTDIR
|
||||
* $R8 = long path to $PROGRAMFILES
|
||||
* $R6 = length of the long path to $PROGRAMFILES32 or $PROGRAMFILES64
|
||||
* $R7 = long path to $PROGRAMFILES32 or $PROGRAMFILES64
|
||||
* $R8 = length of the long path to $INSTDIR
|
||||
* $R9 = long path to $INSTDIR
|
||||
*/
|
||||
!macro CleanVirtualStore
|
||||
@ -2921,34 +3065,25 @@
|
||||
Push $R7
|
||||
Push $R6
|
||||
Push $R5
|
||||
Push $R4
|
||||
|
||||
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R9
|
||||
StrCmp $R9 "" end +1
|
||||
${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R8
|
||||
StrCmp $R8 "" end +1
|
||||
${If} "$R9" != ""
|
||||
StrLen $R8 "$R9"
|
||||
|
||||
StrLen $R7 "$R9"
|
||||
StrLen $R6 "$R8"
|
||||
; Only continue If the length of $INSTDIR is greater than the length of
|
||||
; $PROGRAMFILES
|
||||
IntCmp $R7 $R6 end end +1
|
||||
StrCpy $R4 $PROGRAMFILES32
|
||||
Call ${_MOZFUNC_UN}CleanVirtualStore_Internal
|
||||
|
||||
; Copy from the start of $INSTDIR the length of $PROGRAMFILES
|
||||
StrCpy $R5 "$R9" $R6
|
||||
StrCmp "$R5" "$R8" +1 end ; Check if $INSTDIR is under $PROGRAMFILES
|
||||
${If} ${RunningX64}
|
||||
StrCpy $R4 $PROGRAMFILES64
|
||||
Call ${_MOZFUNC_UN}CleanVirtualStore_Internal
|
||||
${EndIf}
|
||||
|
||||
; Remove the drive letter and colon from the $INSTDIR long path
|
||||
StrCpy $R5 "$R9" "" 2
|
||||
StrCpy $R5 "$PROFILE\AppData\Local\VirtualStore$R5"
|
||||
${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
|
||||
StrCmp $R5 "" end +1
|
||||
${EndIf}
|
||||
|
||||
IfFileExists "$R5" +1 end
|
||||
RmDir /r "$R5"
|
||||
|
||||
end:
|
||||
ClearErrors
|
||||
|
||||
Pop $R4
|
||||
Pop $R5
|
||||
Pop $R6
|
||||
Pop $R7
|
||||
@ -2956,6 +3091,27 @@
|
||||
Pop $R9
|
||||
FunctionEnd
|
||||
|
||||
Function ${_MOZFUNC_UN}CleanVirtualStore_Internal
|
||||
${${_MOZFUNC_UN}GetLongPath} "" $R7
|
||||
${If} "$R7" != ""
|
||||
StrLen $R6 "$R7"
|
||||
${If} $R8 < $R6
|
||||
; Copy from the start of $INSTDIR the length of $PROGRAMFILES64
|
||||
StrCpy $R5 "$R9" $R6
|
||||
${If} "$R5" == "$R7"
|
||||
; Remove the drive letter and colon from the $INSTDIR long path
|
||||
StrCpy $R5 "$R9" "" 2
|
||||
StrCpy $R5 "$LOCALAPPDATA\VirtualStore$R5"
|
||||
${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
|
||||
${If} "$R5" != ""
|
||||
${AndIf} ${FileExists} "$R5"
|
||||
RmDir /r "$R5"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
@ -3036,7 +3192,7 @@
|
||||
; $PROGRAMFILES
|
||||
IntCmp $R6 $R5 end end +1
|
||||
|
||||
; Copy from the start of $INSTDIR the length of $PROGRAMFILES
|
||||
; Copy from the start of $INSTDIR the length of $PROGRAMFILES
|
||||
StrCpy $R4 "$R8" $R5
|
||||
StrCmp "$R4" "$R7" +1 end ; Check if $INSTDIR is under $PROGRAMFILES
|
||||
|
||||
@ -3430,21 +3586,20 @@
|
||||
ClearErrors
|
||||
|
||||
GetFullPathName $R3 "$INSTDIR\uninstall"
|
||||
IfFileExists "$R3\uninstall.update" +1 end_UpdateUninstallLog
|
||||
${If} ${FileExists} "$R3\uninstall.update"
|
||||
${LineFind} "$R3\uninstall.update" "" "1:-1" "CleanupUpdateLog"
|
||||
|
||||
${LineFind} "$R3\uninstall.update" "" "1:-1" "CleanupUpdateLog"
|
||||
GetTempFileName $R2 "$R3"
|
||||
FileOpen $R1 "$R2" w
|
||||
${TextCompareNoDetails} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "CreateUpdateDiff"
|
||||
FileClose $R1
|
||||
|
||||
GetTempFileName $R2 "$R3"
|
||||
FileOpen $R1 "$R2" w
|
||||
${TextCompareNoDetails} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "CreateUpdateDiff"
|
||||
FileClose $R1
|
||||
IfErrors +2 0
|
||||
${FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log"
|
||||
|
||||
IfErrors +2 0
|
||||
${FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log"
|
||||
${DeleteFile} "$R2"
|
||||
${EndIf}
|
||||
|
||||
${DeleteFile} "$R2"
|
||||
|
||||
end_UpdateUninstallLog:
|
||||
ClearErrors
|
||||
|
||||
Pop $R0
|
||||
@ -3491,8 +3646,9 @@
|
||||
|
||||
Function CreateUpdateDiff
|
||||
${TrimNewLines} "$9" $9
|
||||
StrCmp $9 "" +2 +1
|
||||
FileWrite $R1 "$9$\r$\n"
|
||||
${If} $9 != ""
|
||||
FileWrite $R1 "$9$\r$\n"
|
||||
${EndIf}
|
||||
|
||||
Push 0
|
||||
FunctionEnd
|
||||
@ -3764,24 +3920,27 @@
|
||||
|
||||
ClearErrors
|
||||
Delete "$R1"
|
||||
IfErrors +3 +1
|
||||
${LogMsg} "Deleted File: $R1"
|
||||
GoTo end
|
||||
${Unless} ${Errors}
|
||||
${LogMsg} "Deleted File: $R1"
|
||||
Goto end
|
||||
${EndUnless}
|
||||
|
||||
ClearErrors
|
||||
Rename "$R1" "$R1.moz-delete"
|
||||
IfErrors +4 +1
|
||||
Delete /REBOOTOK "$R1.moz-delete"
|
||||
${LogMsg} "Delayed Delete File (Reboot Required): $R1.moz-delete"
|
||||
GoTo end
|
||||
${Unless} ${Errors}
|
||||
Delete /REBOOTOK "$R1.moz-delete"
|
||||
${LogMsg} "Delayed Delete File (Reboot Required): $R1.moz-delete"
|
||||
GoTo end
|
||||
${EndUnless}
|
||||
|
||||
; Check if the file exists in the source. If it does the new file will
|
||||
; replace the existing file when the system is rebooted. If it doesn't
|
||||
; the file will be deleted when the system is rebooted.
|
||||
IfFileExists "$EXEDIR\core$R9" end +1
|
||||
IfFileExists "$EXEDIR\optional$R9" end +1
|
||||
Delete /REBOOTOK "$R1"
|
||||
${LogMsg} "Delayed Delete File (Reboot Required): $R1"
|
||||
${Unless} ${FileExists} "$EXEDIR\core$R9"
|
||||
${AndUnless} ${FileExists} "$EXEDIR\optional$R9"
|
||||
Delete /REBOOTOK "$R1"
|
||||
${LogMsg} "Delayed Delete File (Reboot Required): $R1"
|
||||
${EndUnless}
|
||||
|
||||
end:
|
||||
ClearErrors
|
||||
@ -3937,7 +4096,7 @@
|
||||
StrCmp $R0 "\" +2 +1
|
||||
StrCpy $R1 "$R9"
|
||||
|
||||
UnRegDLL $R1
|
||||
${UnregisterDLL} $R1
|
||||
|
||||
end:
|
||||
ClearErrors
|
||||
@ -4030,10 +4189,9 @@
|
||||
Push $R0
|
||||
|
||||
StrCpy $R3 ""
|
||||
IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end_FindSMProgramsDir
|
||||
${LineFind} "$INSTDIR\uninstall\uninstall.log" "/NUL" "1:-1" "FindSMProgramsDirRelPath"
|
||||
|
||||
end_FindSMProgramsDir:
|
||||
${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log"
|
||||
${LineFind} "$INSTDIR\uninstall\uninstall.log" "/NUL" "1:-1" "FindSMProgramsDirRelPath"
|
||||
${EndIf}
|
||||
ClearErrors
|
||||
|
||||
Pop $R0
|
||||
@ -4406,24 +4564,35 @@
|
||||
Push $R6
|
||||
Push $R5
|
||||
|
||||
${Unless} ${AtLeastWin2000}
|
||||
; XXX-rstrong - some systems fail the AtLeastWin2000 test for an
|
||||
; unknown reason. To work around this also check if the Windows NT
|
||||
; registry Key exists and if it does if the first char in
|
||||
; CurrentVersion is equal to 3 (Windows NT 3.5 and 3.5.1) or 4
|
||||
; (Windows NT 4).
|
||||
StrCpy $R8 ""
|
||||
ClearErrors
|
||||
ReadRegStr $R8 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion"
|
||||
StrCpy $R8 "$R8" 1
|
||||
${If} ${Errors}
|
||||
${OrIf} "$R8" == "3"
|
||||
${OrIf} "$R8" == "4"
|
||||
!ifdef HAVE_64BIT_OS
|
||||
${Unless} ${RunningX64}
|
||||
${OrUnless} ${AtLeastWinVista}
|
||||
MessageBox MB_OK|MB_ICONSTOP "$R9" IDOK
|
||||
; Nothing initialized so no need to call OnEndCommon
|
||||
Quit
|
||||
${EndIf}
|
||||
${EndUnless}
|
||||
${EndUnless}
|
||||
|
||||
SetRegView 64
|
||||
!else
|
||||
${Unless} ${AtLeastWin2000}
|
||||
; XXX-rstrong - some systems fail the AtLeastWin2000 test for an
|
||||
; unknown reason. To work around this also check if the Windows NT
|
||||
; registry Key exists and if it does if the first char in
|
||||
; CurrentVersion is equal to 3 (Windows NT 3.5 and 3.5.1) or 4
|
||||
; (Windows NT 4).
|
||||
StrCpy $R8 ""
|
||||
ClearErrors
|
||||
ReadRegStr $R8 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion"
|
||||
StrCpy $R8 "$R8" 1
|
||||
${If} ${Errors}
|
||||
${OrIf} "$R8" == "3"
|
||||
${OrIf} "$R8" == "4"
|
||||
MessageBox MB_OK|MB_ICONSTOP "$R9" IDOK
|
||||
; Nothing initialized so no need to call OnEndCommon
|
||||
Quit
|
||||
${EndIf}
|
||||
${EndUnless}
|
||||
!endif
|
||||
|
||||
${GetParameters} $R8
|
||||
|
||||
@ -4445,7 +4614,11 @@
|
||||
SetSilent silent
|
||||
ReadINIStr $R8 $R7 "Install" "InstallDirectoryName"
|
||||
${If} $R8 != ""
|
||||
StrCpy $INSTDIR "$PROGRAMFILES\$R8"
|
||||
!ifdef HAVE_64BIT_OS
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\$R8"
|
||||
!else
|
||||
StrCpy $INSTDIR "$PROGRAMFILES32\$R8"
|
||||
!endif
|
||||
${Else}
|
||||
ReadINIStr $R8 $R7 "Install" "InstallDirectoryPath"
|
||||
${If} $R8 != ""
|
||||
@ -4459,11 +4632,19 @@
|
||||
StrCpy $R6 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})"
|
||||
ReadRegStr $R8 HKLM "$R6" "InstallLocation"
|
||||
${If} $R8 == ""
|
||||
StrCpy $INSTDIR "$PROGRAMFILES\${BrandFullName}"
|
||||
!ifdef HAVE_64BIT_OS
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\${BrandFullName}"
|
||||
!else
|
||||
StrCpy $INSTDIR "$PROGRAMFILES32\${BrandFullName}"
|
||||
!endif
|
||||
${Else}
|
||||
GetFullPathName $INSTDIR "$R8"
|
||||
${Unless} ${FileExists} "$INSTDIR"
|
||||
StrCpy $INSTDIR "$PROGRAMFILES\${BrandFullName}"
|
||||
!ifdef HAVE_64BIT_OS
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\${BrandFullName}"
|
||||
!else
|
||||
StrCpy $INSTDIR "$PROGRAMFILES32\${BrandFullName}"
|
||||
!endif
|
||||
${EndUnless}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
@ -4589,10 +4770,10 @@
|
||||
!define UninstallOnInitCommon "!insertmacro UninstallOnInitCommonCall"
|
||||
|
||||
Function UninstallOnInitCommon
|
||||
; Prevents breaking apps that don't use SetBrandNameVars
|
||||
!ifdef SetBrandNameVars
|
||||
${SetBrandNameVars} "$EXEDIR\distribution\setup.ini"
|
||||
!endif
|
||||
; Prevents breaking apps that don't use SetBrandNameVars
|
||||
!ifdef SetBrandNameVars
|
||||
${SetBrandNameVars} "$EXEDIR\distribution\setup.ini"
|
||||
!endif
|
||||
|
||||
; Prevent launching the application when a reboot is required and this
|
||||
; executable is the main application executable
|
||||
@ -4606,10 +4787,10 @@
|
||||
IfFileExists "$INSTDIR\${FileMainEXE}" +2 +1
|
||||
Quit ; Nothing initialized so no need to call OnEndCommon
|
||||
|
||||
; Prevents breaking apps that don't use SetBrandNameVars
|
||||
!ifdef SetBrandNameVars
|
||||
${SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
|
||||
!endif
|
||||
; Prevents breaking apps that don't use SetBrandNameVars
|
||||
!ifdef SetBrandNameVars
|
||||
${SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
|
||||
!endif
|
||||
|
||||
; Prevent all operations (e.g. set as default, postupdate, etc.) when a
|
||||
; reboot is required and the executable launched is helper.exe
|
||||
@ -4618,6 +4799,10 @@
|
||||
Reboot
|
||||
Quit ; Nothing initialized so no need to call OnEndCommon
|
||||
|
||||
!ifdef HAVE_64BIT_OS
|
||||
SetRegView 64
|
||||
!endif
|
||||
|
||||
${GetParameters} $R0
|
||||
|
||||
StrCmp "$R0" "" continue +1
|
||||
@ -4718,8 +4903,9 @@
|
||||
WriteUninstaller "$EXEDIR\uninstaller.exe"
|
||||
|
||||
StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\""
|
||||
StrCmp $R0 "/S" +1 +2
|
||||
StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\" /S"
|
||||
${If} ${Silent}
|
||||
StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\" /S"
|
||||
${EndIf}
|
||||
|
||||
; When the uninstaller is launched it copies itself to the temp directory
|
||||
; so it won't be in use so it can delete itself.
|
||||
@ -4742,6 +4928,53 @@
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Called from the uninstaller's un.onInit function not to be confused with the
|
||||
* installer's .onInit or the uninstaller's .onInit functions.
|
||||
*/
|
||||
!macro un.UninstallUnOnInitCommon
|
||||
|
||||
!ifndef un.UninstallUnOnInitCommon
|
||||
!insertmacro un.GetLongPath
|
||||
!insertmacro un.GetParent
|
||||
!insertmacro un.SetBrandNameVars
|
||||
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
!define un.UninstallUnOnInitCommon "!insertmacro un.UninstallUnOnInitCommonCall"
|
||||
|
||||
Function un.UninstallUnOnInitCommon
|
||||
${un.GetParent} "$INSTDIR" $INSTDIR
|
||||
${un.GetLongPath} "$INSTDIR" $INSTDIR
|
||||
${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}"
|
||||
Abort
|
||||
${EndUnless}
|
||||
|
||||
!ifdef HAVE_64BIT_OS
|
||||
SetRegView 64
|
||||
!endif
|
||||
|
||||
; Prevents breaking apps that don't use SetBrandNameVars
|
||||
!ifdef un.SetBrandNameVars
|
||||
${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
|
||||
!endif
|
||||
|
||||
; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
|
||||
; the user clicks the back button
|
||||
StrCpy $hHeaderBitmap ""
|
||||
FunctionEnd
|
||||
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
!macro un.UninstallUnOnInitCommonCall
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
Call un.UninstallUnOnInitCommon
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Called from the MUI leaveOptions function to set the value of $INSTDIR.
|
||||
*/
|
||||
@ -4891,14 +5124,16 @@
|
||||
Push $R7
|
||||
|
||||
${CanWriteToInstallDir} $R7
|
||||
StrCmp $R7 "false" +1 +3
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "$R9"
|
||||
Abort
|
||||
${If} $R7 == "false"
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "$R9"
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
${CheckDiskSpace} $R7
|
||||
StrCmp $R7 "false" +1 +3
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "$R8"
|
||||
Abort
|
||||
${If} $R7 == "false"
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "$R8"
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
Pop $R7
|
||||
Exch $R8
|
||||
@ -4951,12 +5186,13 @@
|
||||
RmDir /r "$INSTDIR\distribution"
|
||||
|
||||
; Remove files from the uninstall directory.
|
||||
IfFileExists "$INSTDIR\uninstall" +1 +7
|
||||
Delete "$INSTDIR\uninstall\*wizard*"
|
||||
Delete "$INSTDIR\uninstall\uninstall.ini"
|
||||
Delete "$INSTDIR\uninstall\cleanup.log"
|
||||
Delete "$INSTDIR\uninstall\uninstall.update"
|
||||
${OnInstallUninstall}
|
||||
${If} ${FileExists} "$INSTDIR\uninstall"
|
||||
Delete "$INSTDIR\uninstall\*wizard*"
|
||||
Delete "$INSTDIR\uninstall\uninstall.ini"
|
||||
Delete "$INSTDIR\uninstall\cleanup.log"
|
||||
Delete "$INSTDIR\uninstall\uninstall.update"
|
||||
${OnInstallUninstall}
|
||||
${EndIf}
|
||||
|
||||
; Since we write to the uninstall.log in this directory during the
|
||||
; installation create the directory if it doesn't already exist.
|
||||
@ -5064,7 +5300,7 @@
|
||||
; the UAC plugin to use UAC::ExecCodeSegment to execute code in
|
||||
; the non-elevated context.
|
||||
${Unless} ${Errors}
|
||||
UAC::RunElevated
|
||||
UAC::RunElevated
|
||||
${EndUnless}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
@ -5117,7 +5353,7 @@
|
||||
; plugin to use UAC::ExecCodeSegment to execute code in the
|
||||
; non-elevated context.
|
||||
${Unless} ${Errors}
|
||||
UAC::RunElevated
|
||||
UAC::RunElevated
|
||||
${EndUnless}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
@ -5330,6 +5566,12 @@
|
||||
${LogMsg} "OS Name : Unable to detect"
|
||||
${EndIf}
|
||||
|
||||
!ifdef HAVE_64BIT_OS
|
||||
${LogMsg} "Target CPU : x64"
|
||||
!else
|
||||
${LogMsg} "Target CPU : x86"
|
||||
!endif
|
||||
|
||||
Pop $9
|
||||
Pop $R0
|
||||
Pop $R1
|
||||
@ -5551,7 +5793,7 @@
|
||||
* @param _SECTION_NAME
|
||||
* The section name to write to in the shortcut log ini file
|
||||
* @param _FILE_NAME
|
||||
* The
|
||||
* The shortcut's file name
|
||||
*
|
||||
* $R6 = return value from ReadIniStr for the shortcut file name
|
||||
* $R7 = counter for supporting multiple shortcuts in the same location
|
||||
@ -5741,7 +5983,8 @@
|
||||
* to the shortcuts log ini file.
|
||||
*
|
||||
* @param _REL_PATH_TO_DIR
|
||||
* The
|
||||
* The relative path from the Start Menu Programs directory to the
|
||||
* program's directory.
|
||||
*
|
||||
* $R9 = _REL_PATH_TO_DIR
|
||||
*/
|
||||
@ -5843,12 +6086,12 @@
|
||||
; the categories will be removed by the second call to
|
||||
; WSCSetApplicationCategory.
|
||||
StrCmp "$R9" "0x00000000" +2 +1
|
||||
System::Call "Ws2_32::WSCSetApplicationCategory(w r18, i r17, w n, i 0,\
|
||||
System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\
|
||||
i 0x00000000, i n, *i) i"
|
||||
|
||||
; Set the permitted LSP categories
|
||||
System::Call "Ws2_32::WSCSetApplicationCategory(w r18, i r17, w n, i 0,\
|
||||
i r19, i n, *i .s) i.r16"
|
||||
System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\
|
||||
i R9, i n, *i .s) i.R6"
|
||||
Pop $R5
|
||||
|
||||
!ifndef NO_LOG
|
||||
@ -5923,9 +6166,9 @@
|
||||
ClearErrors
|
||||
|
||||
; stack: path, appid
|
||||
Exch $R9 ; stack: $R9, appid | $R9 = path
|
||||
Exch $R9 ; stack: $R9, appid | $R9 = path
|
||||
Exch 1 ; stack: appid, $R9
|
||||
Exch $R8 ; stack: $R8, $R9 | $R8 = appid
|
||||
Exch $R8 ; stack: $R8, $R9 | $R8 = appid
|
||||
Push $R7 ; stack: $R7, $R8, $R9
|
||||
Push $R6
|
||||
Push $R5
|
||||
|
@ -1579,9 +1579,6 @@ var gErrorsPage = {
|
||||
gUpdates.setButtons(null, null, "okButton", true);
|
||||
gUpdates.wiz.getButton("finish").focus();
|
||||
|
||||
var errorsTitle = gUpdates.getAUSString("errorsPageHeader");
|
||||
document.getElementById("errorsHeader").setAttribute("label", errorsTitle);
|
||||
|
||||
var statusText = gUpdates.update.statusText;
|
||||
LOG("gErrorsPage" , "onPageShow - update.statusText: " + statusText);
|
||||
|
||||
|
@ -215,7 +215,7 @@
|
||||
|
||||
<wizardpage id="errors" pageid="errors" object="gErrorsPage"
|
||||
onpageshow="gErrorsPage.onPageShow();">
|
||||
<updateheader id="errorsHeader" label=""/>
|
||||
<updateheader label="&error.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label id="errorIntro">&error.label;</label>
|
||||
<separator/>
|
||||
@ -233,7 +233,7 @@
|
||||
<wizardpage id="errorpatching" pageid="errorpatching" next="downloading"
|
||||
object="gErrorPatchingPage"
|
||||
onpageshow="gErrorPatchingPage.onPageShow();">
|
||||
<updateheader label="&errorpatching.title;"/>
|
||||
<updateheader label="&error.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label>&errorpatching.intro;</label>
|
||||
</vbox>
|
||||
|
@ -46,6 +46,42 @@
|
||||
-moz-border-radius: 5px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
-moz-appearance: toolbarbutton;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar");
|
||||
}
|
||||
|
||||
#forward-btn:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar");
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar");
|
||||
}
|
||||
|
||||
#forward-btn:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar");
|
||||
}
|
||||
|
||||
#back-btn[disabled="true"]:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
#forward-btn[disabled="true"]:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
#back-btn[disabled="true"]:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
#forward-btn[disabled="true"]:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
/*** category selector ***/
|
||||
|
||||
@ -155,7 +191,6 @@
|
||||
|
||||
#header {
|
||||
margin-bottom: 20px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#header-name, #header-link {
|
||||
|
@ -35,6 +35,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
%include ../../global/shared.inc
|
||||
|
||||
#addons-page {
|
||||
background-color: #c5ccd7;
|
||||
-moz-appearance: none;
|
||||
@ -47,6 +49,52 @@
|
||||
-moz-border-radius: 5px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
-moz-appearance: none;
|
||||
min-width: 0;
|
||||
padding: 0 4px;
|
||||
margin: 0;
|
||||
text-shadow: @loweredShadow@;
|
||||
border: 1px solid @toolbarbuttonBorderColor@;
|
||||
-moz-box-shadow: @loweredShadow@;
|
||||
background: @toolbarbuttonBackground@;
|
||||
background-origin: border-box;
|
||||
list-style-image: url(chrome://mozapps/skin/extensions/navigation.png);
|
||||
}
|
||||
|
||||
.nav-button .button-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-button[disabled="true"] .button-icon {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(ltr),
|
||||
#forward-btn:-moz-locale-dir(rtl) {
|
||||
-moz-border-radius-topleft: @toolbarbuttonCornerRadius@;
|
||||
-moz-border-radius-bottomleft: @toolbarbuttonCornerRadius@;
|
||||
border-right: none;
|
||||
-moz-image-region: rect(0, 20px, 20px, 0);
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(rtl),
|
||||
#forward-btn:-moz-locale-dir(ltr) {
|
||||
-moz-border-radius-topright: @toolbarbuttonCornerRadius@;
|
||||
-moz-border-radius-bottomright: @toolbarbuttonCornerRadius@;
|
||||
-moz-image-region: rect(0, 40px, 20px, 20px);
|
||||
}
|
||||
|
||||
.nav-button:hover:active:not([disabled="true"]) {
|
||||
background: @toolbarbuttonPressedBackgroundColor@;
|
||||
text-shadow: @loweredShadow@;
|
||||
-moz-box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@;
|
||||
}
|
||||
|
||||
.nav-button:-moz-window-inactive {
|
||||
border-color: @toolbarbuttonInactiveBorderColor@;
|
||||
background-image: @toolbarbuttonInactiveBackgroundImage@;
|
||||
}
|
||||
|
||||
/*** category selector ***/
|
||||
|
||||
@ -156,7 +204,6 @@
|
||||
|
||||
#header {
|
||||
margin-bottom: 20px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#header-name, #header-link {
|
||||
|
BIN
toolkit/themes/pinstripe/mozapps/extensions/navigation.png
Normal file
BIN
toolkit/themes/pinstripe/mozapps/extensions/navigation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 586 B |
@ -26,8 +26,9 @@ toolkit.jar:
|
||||
skin/classic/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/mozapps/extensions/pause.png (extensions/pause.png)
|
||||
skin/classic/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/mozapps/extensions/about.css (extensions/about.css)
|
||||
skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
|
||||
* skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
|
||||
skin/classic/mozapps/extensions/update.css (extensions/update.css)
|
||||
skin/classic/mozapps/extensions/eula.css (extensions/eula.css)
|
||||
skin/classic/mozapps/extensions/blocklist.css (extensions/blocklist.css)
|
||||
|
@ -47,6 +47,21 @@
|
||||
-moz-border-radius: 5px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
list-style-image: url(chrome://mozapps/skin/extensions/navigation.png);
|
||||
min-width: 0;
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(ltr),
|
||||
#forward-btn:-moz-locale-dir(rtl) {
|
||||
-moz-image-region: rect(0, 18px, 18px, 0);
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(rtl),
|
||||
#forward-btn:-moz-locale-dir(ltr) {
|
||||
-moz-image-region: rect(0, 36px, 18px, 18px);
|
||||
}
|
||||
|
||||
/*** category selector ***/
|
||||
|
||||
@ -156,7 +171,6 @@
|
||||
|
||||
#header {
|
||||
margin-bottom: 20px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#header-name, #header-link {
|
||||
|
BIN
toolkit/themes/winstripe/mozapps/extensions/navigation.png
Normal file
BIN
toolkit/themes/winstripe/mozapps/extensions/navigation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -32,6 +32,7 @@ toolkit.jar:
|
||||
skin/classic/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/mozapps/extensions/pause.png (extensions/pause.png)
|
||||
skin/classic/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/mozapps/extensions/eula.css (extensions/eula.css)
|
||||
skin/classic/mozapps/handling/handling.css (handling/handling.css)
|
||||
skin/classic/mozapps/passwordmgr/key.png (passwordmgr/key.png)
|
||||
@ -95,6 +96,7 @@ toolkit.jar:
|
||||
skin/classic/aero/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/aero/mozapps/extensions/pause.png (extensions/pause.png)
|
||||
skin/classic/aero/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/aero/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/aero/mozapps/extensions/eula.css (extensions/eula.css)
|
||||
skin/classic/aero/mozapps/handling/handling.css (handling/handling.css)
|
||||
skin/classic/aero/mozapps/passwordmgr/key.png (passwordmgr/key-aero.png)
|
||||
|
@ -112,6 +112,7 @@ XPIDLSRCS = \
|
||||
nsIPrintSettingsService.idl \
|
||||
nsIPrintOptions.idl \
|
||||
nsIIdleService.idl \
|
||||
nsIGfxInfo.idl \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
@ -126,7 +127,6 @@ XPIDLSRCS += nsIPrintSettingsWin.idl \
|
||||
nsITaskbarPreviewButton.idl \
|
||||
nsIJumpListBuilder.idl \
|
||||
nsIJumpListItem.idl \
|
||||
nsIGfxInfo.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
@ -66,6 +66,5 @@ interface nsIGfxInfo : nsISupports
|
||||
readonly attribute DOMString adapterDriverVersion;
|
||||
|
||||
readonly attribute DOMString adapterDriverDate;
|
||||
|
||||
};
|
||||
|
||||
|
@ -54,6 +54,8 @@ using namespace mozilla::widget;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(GfxInfo, nsIGfxInfo)
|
||||
|
||||
/* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization
|
||||
* has occurred because they depend on it for information. (See bug 591561) */
|
||||
nsresult GfxInfo::GetD2DEnabled(PRBool *aEnabled)
|
||||
{
|
||||
*aEnabled = gfxWindowsPlatform::GetPlatform()->GetRenderMode() == gfxWindowsPlatform::RENDER_DIRECT2D;
|
||||
@ -68,13 +70,12 @@ nsresult GfxInfo::GetDWriteEnabled(PRBool *aEnabled)
|
||||
|
||||
/* XXX: GfxInfo doesn't handle multiple GPUs. We should try to do that. Bug #591057 */
|
||||
|
||||
static nsresult GetKeyValue(const TCHAR* keyLocation, const TCHAR* keyName, nsAString& destString, int type)
|
||||
static nsresult GetKeyValue(const WCHAR* keyLocation, const WCHAR* keyName, nsAString& destString, int type)
|
||||
{
|
||||
HKEY key;
|
||||
DWORD dwcbData;
|
||||
WCHAR wCharValue[1024];
|
||||
TCHAR tCharValue[1024];
|
||||
DWORD dValue;
|
||||
DWORD resultType;
|
||||
LONG result;
|
||||
nsresult retval = NS_OK;
|
||||
|
||||
@ -87,27 +88,47 @@ static nsresult GetKeyValue(const TCHAR* keyLocation, const TCHAR* keyName, nsAS
|
||||
case REG_DWORD: {
|
||||
// We only use this for vram size
|
||||
dwcbData = sizeof(dValue);
|
||||
result = RegQueryValueExW(key, keyName, NULL, NULL, (LPBYTE)&dValue, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
result = RegQueryValueExW(key, keyName, NULL, &resultType, (LPBYTE)&dValue, &dwcbData);
|
||||
if (result == ERROR_SUCCESS && resultType == REG_DWORD) {
|
||||
dValue = dValue / 1024 / 1024;
|
||||
destString.AppendInt(static_cast<PRInt32>(dValue));
|
||||
} else {
|
||||
retval = NS_ERROR_FAILURE;
|
||||
}
|
||||
dValue = dValue / 1024 / 1024;
|
||||
destString.AppendInt(static_cast<PRInt32>(dValue));
|
||||
break;
|
||||
}
|
||||
case REG_MULTI_SZ: {
|
||||
// A chain of null-separated strings; we convert the nulls to spaces
|
||||
dwcbData = sizeof(tCharValue);
|
||||
result = RegQueryValueExW(key, keyName, NULL, NULL, (LPBYTE)tCharValue, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
WCHAR wCharValue[1024];
|
||||
dwcbData = sizeof(wCharValue);
|
||||
|
||||
result = RegQueryValueExW(key, keyName, NULL, &resultType, (LPBYTE)wCharValue, &dwcbData);
|
||||
if (result == ERROR_SUCCESS && resultType == REG_MULTI_SZ) {
|
||||
// This bit here could probably be cleaner.
|
||||
bool isValid = false;
|
||||
|
||||
DWORD strLen = dwcbData/sizeof(wCharValue[0]);
|
||||
for (DWORD i = 0; i < strLen; i++) {
|
||||
if (wCharValue[i] == '\0') {
|
||||
if (i < strLen - 1 && wCharValue[i + 1] == '\0') {
|
||||
isValid = true;
|
||||
break;
|
||||
} else {
|
||||
wCharValue[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure wCharValue is null terminated
|
||||
wCharValue[strLen-1] = '\0';
|
||||
|
||||
if (isValid)
|
||||
destString = wCharValue;
|
||||
|
||||
} else {
|
||||
retval = NS_ERROR_FAILURE;
|
||||
}
|
||||
// This bit here could probably be cleaner.
|
||||
for (DWORD i = 0, len = dwcbData/sizeof(tCharValue[0]); i < len; i++) {
|
||||
if (tCharValue[i] == '\0')
|
||||
tCharValue[i] = ' ';
|
||||
}
|
||||
destString = tCharValue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -140,44 +161,40 @@ void GfxInfo::Init()
|
||||
{
|
||||
NS_TIME_FUNCTION;
|
||||
|
||||
DISPLAY_DEVICE lpDisplayDevice;
|
||||
lpDisplayDevice.cb = sizeof(lpDisplayDevice);
|
||||
DISPLAY_DEVICEW displayDevice;
|
||||
displayDevice.cb = sizeof(displayDevice);
|
||||
int deviceIndex = 0;
|
||||
|
||||
while (EnumDisplayDevices(NULL, deviceIndex, &lpDisplayDevice, 0)) {
|
||||
if (lpDisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||
while (EnumDisplayDevicesW(NULL, deviceIndex, &displayDevice, 0)) {
|
||||
if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||
break;
|
||||
deviceIndex++;
|
||||
}
|
||||
|
||||
/* DeviceKey is "reserved" according to MSDN so we'll be careful with it */
|
||||
if (wcsncmp(lpDisplayDevice.DeviceKey, DEVICE_KEY_PREFIX, wcslen(DEVICE_KEY_PREFIX)) != 0)
|
||||
/* check that DeviceKey begins with DEVICE_KEY_PREFIX */
|
||||
if (wcsncmp(displayDevice.DeviceKey, DEVICE_KEY_PREFIX, NS_ARRAY_LENGTH(DEVICE_KEY_PREFIX)-1) != 0)
|
||||
return;
|
||||
|
||||
// make sure the string is NULL terminated
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(lpDisplayDevice.DeviceKey); i++) {
|
||||
if (lpDisplayDevice.DeviceKey[i] == L'\0')
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == sizeof(lpDisplayDevice.DeviceKey)) {
|
||||
// we did not find a NULL
|
||||
return;
|
||||
if (wcsnlen(displayDevice.DeviceKey, NS_ARRAY_LENGTH(displayDevice.DeviceKey))
|
||||
== NS_ARRAY_LENGTH(displayDevice.DeviceKey)) {
|
||||
// we did not find a NULL
|
||||
return;
|
||||
}
|
||||
|
||||
// chop off DEVICE_KEY_PREFIX
|
||||
mDeviceKey = lpDisplayDevice.DeviceKey + wcslen(DEVICE_KEY_PREFIX);
|
||||
mDeviceKey = displayDevice.DeviceKey + NS_ARRAY_LENGTH(DEVICE_KEY_PREFIX)-1;
|
||||
|
||||
mDeviceID = lpDisplayDevice.DeviceID;
|
||||
mDeviceString = lpDisplayDevice.DeviceString;
|
||||
mDeviceID = displayDevice.DeviceID;
|
||||
mDeviceString = displayDevice.DeviceString;
|
||||
|
||||
|
||||
HKEY key, subkey;
|
||||
LONG result, enumresult;
|
||||
DWORD index = 0;
|
||||
TCHAR subkeyname[64];
|
||||
TCHAR value[128];
|
||||
WCHAR subkeyname[64];
|
||||
WCHAR value[128];
|
||||
DWORD dwcbData = sizeof(subkeyname);
|
||||
|
||||
// "{4D36E968-E325-11CE-BFC1-08002BE10318}" is the display class
|
||||
|
@ -226,6 +226,8 @@
|
||||
#include "nsICrashReporter.h"
|
||||
#endif
|
||||
|
||||
#include "nsIXULRuntime.h"
|
||||
|
||||
using namespace mozilla::widget;
|
||||
|
||||
/**************************************************************
|
||||
@ -2439,20 +2441,6 @@ void nsWindow::SetTransparencyMode(nsTransparencyMode aMode)
|
||||
GetTopLevelWindow(PR_TRUE)->SetWindowTranslucencyInner(aMode);
|
||||
}
|
||||
|
||||
namespace {
|
||||
BOOL CALLBACK AddClientAreaToRegion(HWND hWnd, LPARAM lParam) {
|
||||
nsIntRegion *region = reinterpret_cast<nsIntRegion*>(lParam);
|
||||
|
||||
RECT clientRect;
|
||||
::GetWindowRect(hWnd, &clientRect);
|
||||
nsIntRect clientArea(clientRect.left, clientRect.top,
|
||||
clientRect.right - clientRect.left,
|
||||
clientRect.bottom - clientRect.top);
|
||||
region->Or(*region, clientArea);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
|
||||
const nsIntRegion &aPossiblyTransparentRegion) {
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
@ -2468,24 +2456,10 @@ void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
|
||||
mPossiblyTransparentRegion.Sub(mPossiblyTransparentRegion, aDirtyRegion);
|
||||
mPossiblyTransparentRegion.Or(mPossiblyTransparentRegion, aPossiblyTransparentRegion);
|
||||
|
||||
nsIntRegion childWindowRegion;
|
||||
|
||||
::EnumChildWindows(mWnd, AddClientAreaToRegion, reinterpret_cast<LPARAM>(&childWindowRegion));
|
||||
|
||||
nsIntPoint clientOffset = GetClientOffset();
|
||||
childWindowRegion.MoveBy(-clientOffset);
|
||||
|
||||
RECT r;
|
||||
::GetWindowRect(mWnd, &r);
|
||||
childWindowRegion.MoveBy(-r.left, -r.top);
|
||||
|
||||
nsIntRect clientBounds;
|
||||
topWindow->GetClientBounds(clientBounds);
|
||||
nsIntRegion opaqueRegion;
|
||||
opaqueRegion.Sub(clientBounds, mPossiblyTransparentRegion);
|
||||
opaqueRegion.Or(opaqueRegion, childWindowRegion);
|
||||
// Sometimes child windows overlap our bounds
|
||||
opaqueRegion.And(opaqueRegion, clientBounds);
|
||||
|
||||
MARGINS margins = { 0, 0, 0, 0 };
|
||||
DWORD_PTR dwStyle = ::GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
@ -3217,34 +3191,45 @@ nsWindow::GetLayerManager()
|
||||
|
||||
#ifndef WINCE
|
||||
if (!mLayerManager) {
|
||||
if (mUseAcceleratedRendering) {
|
||||
nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
|
||||
PRBool allowAcceleration = PR_TRUE;
|
||||
PRBool preferOpenGL = PR_FALSE;
|
||||
if (prefs) {
|
||||
prefs->GetBoolPref("mozilla.widget.accelerated-layers",
|
||||
&allowAcceleration);
|
||||
prefs->GetBoolPref("mozilla.layers.prefer-opengl",
|
||||
&preferOpenGL);
|
||||
}
|
||||
|
||||
if (allowAcceleration) {
|
||||
PRBool accelerateByDefault = PR_TRUE;
|
||||
PRBool disableAcceleration = PR_FALSE;
|
||||
PRBool preferOpenGL = PR_FALSE;
|
||||
if (prefs) {
|
||||
prefs->GetBoolPref("layers.accelerate-all",
|
||||
&accelerateByDefault);
|
||||
prefs->GetBoolPref("layers.accelerate-none",
|
||||
&disableAcceleration);
|
||||
prefs->GetBoolPref("layers.prefer-opengl",
|
||||
&preferOpenGL);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
|
||||
PRBool safeMode = PR_FALSE;
|
||||
if (xr)
|
||||
xr->GetInSafeMode(&safeMode);
|
||||
|
||||
if (disableAcceleration || safeMode)
|
||||
mUseAcceleratedRendering = PR_FALSE;
|
||||
else if (accelerateByDefault)
|
||||
mUseAcceleratedRendering = PR_TRUE;
|
||||
|
||||
if (mUseAcceleratedRendering) {
|
||||
#ifdef MOZ_ENABLE_D3D9_LAYER
|
||||
if (!preferOpenGL) {
|
||||
nsRefPtr<mozilla::layers::LayerManagerD3D9> layerManager =
|
||||
new mozilla::layers::LayerManagerD3D9(this);
|
||||
if (layerManager->Initialize()) {
|
||||
mLayerManager = layerManager;
|
||||
}
|
||||
if (!preferOpenGL) {
|
||||
nsRefPtr<mozilla::layers::LayerManagerD3D9> layerManager =
|
||||
new mozilla::layers::LayerManagerD3D9(this);
|
||||
if (layerManager->Initialize()) {
|
||||
mLayerManager = layerManager;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!mLayerManager) {
|
||||
nsRefPtr<mozilla::layers::LayerManagerOGL> layerManager =
|
||||
new mozilla::layers::LayerManagerOGL(this);
|
||||
if (layerManager->Initialize()) {
|
||||
mLayerManager = layerManager;
|
||||
}
|
||||
if (!mLayerManager) {
|
||||
nsRefPtr<mozilla::layers::LayerManagerOGL> layerManager =
|
||||
new mozilla::layers::LayerManagerOGL(this);
|
||||
if (layerManager->Initialize()) {
|
||||
mLayerManager = layerManager;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6860,6 +6845,8 @@ nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
|
||||
// We put the region back just below, anyway.
|
||||
::SetWindowRgn(w->mWnd, NULL, TRUE);
|
||||
#endif
|
||||
nsresult rv = w->SetWindowClipRegion(configuration.mClipRegion, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsIntRect bounds;
|
||||
w->GetBounds(bounds);
|
||||
if (bounds.Size() != configuration.mBounds.Size()) {
|
||||
@ -6869,7 +6856,7 @@ nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
|
||||
} else if (bounds.TopLeft() != configuration.mBounds.TopLeft()) {
|
||||
w->Move(configuration.mBounds.x, configuration.mBounds.y);
|
||||
}
|
||||
nsresult rv = w->SetWindowClipRegion(configuration.mClipRegion, PR_FALSE);
|
||||
rv = w->SetWindowClipRegion(configuration.mClipRegion, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -6904,6 +6891,14 @@ nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
|
||||
if (!aIntersectWithExisting) {
|
||||
if (!StoreWindowClipRegion(aRects))
|
||||
return NS_OK;
|
||||
} else {
|
||||
// In this case still early return if nothing changed.
|
||||
if (mClipRects && mClipRectCount == aRects.Length() &&
|
||||
memcmp(mClipRects,
|
||||
aRects.Elements(),
|
||||
sizeof(nsIntRect)*mClipRectCount) == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRGN dest = CreateHRGNFromArray(aRects);
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "LayerManagerOGL.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "nsIObserver.h"
|
||||
@ -762,13 +763,27 @@ LayerManager* nsBaseWidget::GetLayerManager()
|
||||
if (!mLayerManager) {
|
||||
nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
|
||||
PRBool allowAcceleration = PR_TRUE;
|
||||
PRBool disableAcceleration = PR_FALSE;
|
||||
PRBool accelerateByDefault = PR_TRUE;
|
||||
|
||||
if (prefs) {
|
||||
prefs->GetBoolPref("mozilla.widget.accelerated-layers",
|
||||
&allowAcceleration);
|
||||
prefs->GetBoolPref("layers.accelerate-all",
|
||||
&accelerateByDefault);
|
||||
prefs->GetBoolPref("layers.accelerate-none",
|
||||
&disableAcceleration);
|
||||
}
|
||||
|
||||
if (mUseAcceleratedRendering && allowAcceleration) {
|
||||
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
|
||||
PRBool safeMode = PR_FALSE;
|
||||
if (xr)
|
||||
xr->GetInSafeMode(&safeMode);
|
||||
|
||||
if (disableAcceleration || safeMode)
|
||||
mUseAcceleratedRendering = PR_FALSE;
|
||||
else if (accelerateByDefault)
|
||||
mUseAcceleratedRendering = PR_TRUE;
|
||||
|
||||
if (mUseAcceleratedRendering) {
|
||||
nsRefPtr<LayerManagerOGL> layerManager =
|
||||
new mozilla::layers::LayerManagerOGL(this);
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user