mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Merge m-c --> cedar
This commit is contained in:
commit
06ec6c6ee8
@ -513,29 +513,13 @@
|
||||
<menuitem id="sync-setup"
|
||||
label="&syncSetup.label;"
|
||||
accesskey="&syncSetup.accesskey;"
|
||||
observes="sync-setup-state"
|
||||
oncommand="gSyncUI.openSetup()"/>
|
||||
<menu id="sync-menu"
|
||||
label="&syncMenu.label;"
|
||||
accesskey="&syncMenu.accesskey;">
|
||||
<menupopup id="sync-menu-popup"
|
||||
onpopupshowing="if (event.target == this) gSyncUI.doUpdateMenu(event);">
|
||||
<menuitem id="sync-loginitem"
|
||||
label="&syncLogInItem.label;"
|
||||
accesskey="&syncLogInItem.accesskey;"
|
||||
oncommand="gSyncUI.doLogin();"/>
|
||||
<menuitem id="sync-logoutitem"
|
||||
label="&syncLogOutItem.label;"
|
||||
accesskey="&syncLogOutItem.accesskey;"
|
||||
oncommand="gSyncUI.doLogout();"/>
|
||||
<menuitem id="sync-syncnowitem"
|
||||
label="&syncSyncNowItem.label;"
|
||||
accesskey="&syncSyncNowItem.accesskey;"
|
||||
oncommand="gSyncUI.doSync(event);"/>
|
||||
<menuseparator id="sync-lastsyncsep" hidden="true"/>
|
||||
<menuitem id="sync-lastsyncitem"
|
||||
disabled="true" hidden="true"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem id="sync-syncnowitem"
|
||||
label="&syncSyncNowItem.label;"
|
||||
accesskey="&syncSyncNowItem.accesskey;"
|
||||
observes="sync-syncnow-state"
|
||||
oncommand="gSyncUI.doSync(event);"/>
|
||||
#endif
|
||||
<menuseparator id="devToolsSeparator"/>
|
||||
<menuitem id="menu_pageinspect"
|
||||
|
@ -192,6 +192,10 @@
|
||||
<broadcaster id="singleFeedMenuitemState" disabled="true"/>
|
||||
<broadcaster id="multipleFeedsMenuState" hidden="true"/>
|
||||
<broadcaster id="tabviewGroupsNumber" groups="0"/>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<broadcaster id="sync-setup-state"/>
|
||||
<broadcaster id="sync-syncnow-state"/>
|
||||
#endif
|
||||
</broadcasterset>
|
||||
|
||||
<keyset id="mainKeyset">
|
||||
|
@ -105,21 +105,15 @@ let gSyncUI = {
|
||||
|
||||
updateUI: function SUI_updateUI() {
|
||||
let needsSetup = this._needsSetup();
|
||||
document.getElementById("sync-setup").hidden = !needsSetup;
|
||||
document.getElementById("sync-menu").hidden = needsSetup;
|
||||
document.getElementById("sync-setup-state").hidden = !needsSetup;
|
||||
document.getElementById("sync-syncnow-state").hidden = needsSetup;
|
||||
|
||||
if (gBrowser) {
|
||||
let showLabel = !this._isLoggedIn() && !needsSetup;
|
||||
let button = document.getElementById("sync-status-button");
|
||||
button.setAttribute("class", showLabel ? "statusbarpanel-iconic-text"
|
||||
: "statusbarpanel-iconic");
|
||||
button.image = "chrome://browser/skin/sync-16.png";
|
||||
|
||||
if (!this._isLoggedIn()) {
|
||||
//XXXzpao When we move the string bundle, we can add more and make this
|
||||
// say "needs setup" or something similar. (bug 583381)
|
||||
button.removeAttribute("tooltiptext");
|
||||
}
|
||||
document.getElementById("sync-button").removeAttribute("status");
|
||||
this._updateLastSyncTime();
|
||||
}
|
||||
if (needsSetup) {
|
||||
document.getElementById("sync-button").removeAttribute("tooltiptext");
|
||||
}
|
||||
},
|
||||
|
||||
@ -155,8 +149,7 @@ let gSyncUI = {
|
||||
onActivityStart: function SUI_onActivityStart() {
|
||||
//XXXzpao Followup: Do this with a class. (bug 583384)
|
||||
if (gBrowser)
|
||||
document.getElementById("sync-status-button").image =
|
||||
"chrome://browser/skin/sync-16-throbber.png";
|
||||
document.getElementById("sync-button").setAttribute("status", "active");
|
||||
},
|
||||
|
||||
onSyncFinish: function SUI_onSyncFinish() {
|
||||
@ -182,7 +175,7 @@ let gSyncUI = {
|
||||
Weave.Notifications.removeAll(title);
|
||||
|
||||
this.updateUI();
|
||||
this._updateLastSyncItem();
|
||||
this._updateLastSyncTime();
|
||||
},
|
||||
|
||||
onLoginError: function SUI_onLoginError() {
|
||||
@ -266,32 +259,6 @@ let gSyncUI = {
|
||||
},
|
||||
|
||||
// Commands
|
||||
doUpdateMenu: function SUI_doUpdateMenu(event) {
|
||||
this._updateLastSyncItem();
|
||||
|
||||
let loginItem = document.getElementById("sync-loginitem");
|
||||
let logoutItem = document.getElementById("sync-logoutitem");
|
||||
let syncItem = document.getElementById("sync-syncnowitem");
|
||||
|
||||
// Don't allow "login" to be selected in some cases
|
||||
let offline = Services.io.offline;
|
||||
let locked = Weave.Service.locked;
|
||||
let noUser = Weave.Service.username == "";
|
||||
let notReady = offline || locked || noUser;
|
||||
loginItem.setAttribute("disabled", notReady);
|
||||
logoutItem.setAttribute("disabled", notReady);
|
||||
|
||||
// Don't allow "sync now" to be selected in some cases
|
||||
let loggedIn = Weave.Service.isLoggedIn;
|
||||
let noNode = Weave.Status.sync == Weave.NO_SYNC_NODE_FOUND;
|
||||
let disableSync = notReady || !loggedIn || noNode;
|
||||
syncItem.setAttribute("disabled", disableSync);
|
||||
|
||||
// Only show one of login/logout
|
||||
loginItem.setAttribute("hidden", loggedIn);
|
||||
logoutItem.setAttribute("hidden", !loggedIn);
|
||||
},
|
||||
|
||||
doLogin: function SUI_doLogin() {
|
||||
Weave.Service.login();
|
||||
},
|
||||
@ -301,16 +268,15 @@ let gSyncUI = {
|
||||
},
|
||||
|
||||
doSync: function SUI_doSync() {
|
||||
Weave.Service.sync();
|
||||
if (Weave.Service.isLoggedIn || Weave.Service.login())
|
||||
Weave.Service.sync();
|
||||
},
|
||||
|
||||
handleStatusbarButton: function SUI_handleStatusbarButton() {
|
||||
if (Weave.Service.isLoggedIn)
|
||||
Weave.Service.sync();
|
||||
else if (this._needsSetup())
|
||||
handleToolbarButton: function SUI_handleStatusbarButton() {
|
||||
if (this._needsSetup())
|
||||
this.openSetup();
|
||||
else
|
||||
Weave.Service.login();
|
||||
this.doSync();
|
||||
},
|
||||
|
||||
//XXXzpao should be part of syncCommon.js - which we might want to make a module...
|
||||
@ -341,28 +307,27 @@ let gSyncUI = {
|
||||
|
||||
|
||||
// Helpers
|
||||
_updateLastSyncItem: function SUI__updateLastSyncItem() {
|
||||
_updateLastSyncTime: function SUI__updateLastSyncTime() {
|
||||
if (!gBrowser)
|
||||
return;
|
||||
|
||||
let syncButton = document.getElementById("sync-button");
|
||||
let lastSync;
|
||||
try {
|
||||
lastSync = Services.prefs.getCharPref("services.sync.lastSync");
|
||||
}
|
||||
catch (e) { };
|
||||
if (!lastSync)
|
||||
if (!lastSync || this._needsSetup()) {
|
||||
syncButton.removeAttribute("tooltiptext");
|
||||
return;
|
||||
|
||||
let lastSyncItem = document.getElementById("sync-lastsyncitem");
|
||||
}
|
||||
|
||||
// Show the day-of-week and time (HH:MM) of last sync
|
||||
let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
|
||||
let lastSyncLabel =
|
||||
this._stringBundle.formatStringFromName("lastSync.label", [lastSyncDate], 1);
|
||||
lastSyncItem.setAttribute("label", lastSyncLabel);
|
||||
lastSyncItem.setAttribute("hidden", "false");
|
||||
document.getElementById("sync-lastsyncsep").hidden = false;
|
||||
|
||||
if (gBrowser)
|
||||
document.getElementById("sync-status-button").
|
||||
setAttribute("tooltiptext", lastSyncLabel);
|
||||
syncButton.setAttribute("tooltiptext", lastSyncLabel);
|
||||
},
|
||||
|
||||
_onSyncEnd: function SUI__onSyncEnd(success) {
|
||||
@ -415,7 +380,7 @@ let gSyncUI = {
|
||||
}
|
||||
|
||||
this.updateUI();
|
||||
this._updateLastSyncItem();
|
||||
this._updateLastSyncTime();
|
||||
},
|
||||
|
||||
observe: function SUI_observe(subject, topic, data) {
|
||||
|
@ -448,7 +448,11 @@
|
||||
#endif
|
||||
style="-moz-user-focus: ignore;">
|
||||
<menupopup id="appmenu-popup"
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
|
||||
#else
|
||||
onpopupshowing="updateEditUIVisibility();">
|
||||
#endif
|
||||
<hbox>
|
||||
<vbox id="appmenuPrimaryPane">
|
||||
<hbox flex="1"
|
||||
@ -764,6 +768,18 @@
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<spacer flex="1"/>
|
||||
<!-- only one of sync-setup or sync-syncnow will be showing at once -->
|
||||
<menuitem id="sync-setup-appmenu"
|
||||
label="&syncSetup.label;"
|
||||
observes="sync-setup-state"
|
||||
oncommand="gSyncUI.openSetup()"/>
|
||||
<menuitem id="sync-syncnowitem-appmenu"
|
||||
label="&syncSyncNowItem.label;"
|
||||
observes="sync-syncnow-state"
|
||||
oncommand="gSyncUI.doSync(event);"/>
|
||||
#endif
|
||||
</vbox>
|
||||
</hbox>
|
||||
</menupopup>
|
||||
@ -1233,7 +1249,12 @@
|
||||
command="cmd_fullZoomEnlarge"
|
||||
tooltiptext="&zoomInButton.tooltip;"/>
|
||||
</toolbaritem>
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<toolbarbutton id="sync-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&syncToolbarButton.label;"
|
||||
oncommand="gSyncUI.handleToolbarButton()"/>
|
||||
#endif
|
||||
</toolbarpalette>
|
||||
</toolbox>
|
||||
|
||||
@ -1276,14 +1297,6 @@
|
||||
hidden="true"
|
||||
onclick="if (event.button == 0 && event.detail == 1) displaySecurityInfo();"/>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<statusbarpanel id="sync-status-button"
|
||||
class="statusbarpanel-iconic"
|
||||
image="chrome://browser/skin/sync-16.png"
|
||||
label="&syncLogInItem.label;"
|
||||
oncommand="gSyncUI.handleStatusbarButton();"
|
||||
onmousedown="event.preventDefault();">
|
||||
</statusbarpanel>
|
||||
<separator class="thin"/>
|
||||
<statusbarpanel id="sync-notifications-button"
|
||||
class="statusbarpanel-iconic-text"
|
||||
hidden="true"
|
||||
|
@ -70,6 +70,7 @@ var gAdvancedPane = {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
this.initSubmitCrashes();
|
||||
#endif
|
||||
this.updateActualCacheSize();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -190,6 +191,8 @@ var gAdvancedPane = {
|
||||
*
|
||||
* browser.cache.disk.capacity
|
||||
* - the size of the browser cache in KB
|
||||
* browser.cache.disk.smart_size.enabled
|
||||
* - If disabled, disk.capacity is used
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -200,7 +203,50 @@ var gAdvancedPane = {
|
||||
document.documentElement.openSubDialog("chrome://browser/content/preferences/connection.xul",
|
||||
"", null);
|
||||
},
|
||||
|
||||
// Retrieves the amount of space currently used by disk cache
|
||||
updateActualCacheSize: function ()
|
||||
{
|
||||
var visitor = {
|
||||
visitDevice: function (deviceID, deviceInfo)
|
||||
{
|
||||
if (deviceID == "disk") {
|
||||
var actualSizeLabel = document.getElementById("actualCacheSize");
|
||||
var sizeStrings = DownloadUtils.convertByteUnits(deviceInfo.totalSize);
|
||||
var prefStrBundle = document.getElementById("bundlePreferences");
|
||||
var sizeStr = prefStrBundle.getFormattedString("actualCacheSize",
|
||||
sizeStrings);
|
||||
actualSizeLabel.value = sizeStr;
|
||||
}
|
||||
// Do not enumerate entries
|
||||
return false;
|
||||
},
|
||||
|
||||
visitEntry: function (deviceID, entryInfo)
|
||||
{
|
||||
// Do not enumerate entries.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
var cacheService =
|
||||
Components.classes["@mozilla.org/network/cache-service;1"]
|
||||
.getService(Components.interfaces.nsICacheService);
|
||||
cacheService.visitEntries(visitor);
|
||||
},
|
||||
|
||||
updateCacheSizeUI: function (smartSizeEnabled)
|
||||
{
|
||||
document.getElementById("useCacheBefore").disabled = smartSizeEnabled;
|
||||
document.getElementById("cacheSize").disabled = smartSizeEnabled;
|
||||
document.getElementById("useCacheAfter").disabled = smartSizeEnabled;
|
||||
},
|
||||
|
||||
readSmartSizeEnabled: function ()
|
||||
{
|
||||
var enabled = document.getElementById("browser.cache.disk.smart_size.enabled").value;
|
||||
this.updateCacheSizeUI(enabled);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts the cache size from units of KB to units of MB and returns that
|
||||
* value.
|
||||
@ -232,6 +278,7 @@ var gAdvancedPane = {
|
||||
try {
|
||||
cacheService.evictEntries(Components.interfaces.nsICache.STORE_ANYWHERE);
|
||||
} catch(ex) {}
|
||||
this.updateActualCacheSize();
|
||||
},
|
||||
|
||||
readOfflineNotify: function()
|
||||
|
@ -85,8 +85,12 @@
|
||||
<!-- Network tab -->
|
||||
<preference id="browser.cache.disk.capacity" name="browser.cache.disk.capacity" type="int"/>
|
||||
<preference id="browser.offline-apps.notify" name="browser.offline-apps.notify" type="bool"/>
|
||||
|
||||
<!-- Update tab -->
|
||||
|
||||
<preference id="browser.cache.disk.smart_size.enabled"
|
||||
name="browser.cache.disk.smart_size.enabled"
|
||||
type="bool"/>
|
||||
|
||||
<!-- Update tab -->
|
||||
#ifdef MOZ_UPDATER
|
||||
<preference id="app.update.enabled" name="app.update.enabled" type="bool"
|
||||
onchange="gAdvancedPane.updateAppUpdateItems();
|
||||
@ -214,65 +218,71 @@
|
||||
<!-- Network -->
|
||||
<tabpanel id="networkPanel" orient="vertical">
|
||||
|
||||
<!-- Connection -->
|
||||
<groupbox id="connectionGroup">
|
||||
<caption label="&connection.label;"/>
|
||||
<!-- Connection -->
|
||||
<groupbox id="connectionGroup">
|
||||
<caption label="&connection.label;"/>
|
||||
|
||||
<hbox align="center">
|
||||
<description flex="1" control="connectionSettings">&connectionDesc.label;</description>
|
||||
<button id="connectionSettings" icon="network" label="&connectionSettings.label;"
|
||||
accesskey="&connectionSettings.accesskey;"
|
||||
oncommand="gAdvancedPane.showConnections();"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
<hbox align="center">
|
||||
<description flex="1" control="connectionSettings">&connectionDesc.label;</description>
|
||||
<button id="connectionSettings" icon="network" label="&connectionSettings.label;"
|
||||
accesskey="&connectionSettings.accesskey;"
|
||||
oncommand="gAdvancedPane.showConnections();"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<!-- Cache/Offline apps -->
|
||||
<groupbox id="offlineGroup">
|
||||
<caption label="&offlineStorage.label;"/>
|
||||
|
||||
<hbox align="center">
|
||||
<label id="useCacheBefore" control="cacheSize"
|
||||
accesskey="&useCacheBefore.accesskey;" value="&useCacheBefore.label;"/>
|
||||
<textbox id="cacheSize" type="number" size="2"
|
||||
preference="browser.cache.disk.capacity"
|
||||
onsyncfrompreference="return gAdvancedPane.readCacheSize();"
|
||||
onsynctopreference="return gAdvancedPane.writeCacheSize();"
|
||||
aria-labelledby="useCacheBefore cacheSize useCacheAfter"/>
|
||||
<label id="useCacheAfter" flex="1">&useCacheAfter.label;</label>
|
||||
<button id="clearCacheButton" icon="clear"
|
||||
label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"
|
||||
oncommand="gAdvancedPane.clearCache();"/>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<checkbox id="offlineNotify" flex="1"
|
||||
label="&offlineNotify.label;" accesskey="&offlineNotify.accesskey;"
|
||||
preference="browser.offline-apps.notify"
|
||||
onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/>
|
||||
<button id="offlineNotifyExceptions"
|
||||
label="&offlineNotifyExceptions.label;"
|
||||
accesskey="&offlineNotifyExceptions.accesskey;"
|
||||
oncommand="gAdvancedPane.showOfflineExceptions();"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<vbox flex="1">
|
||||
|
||||
<label id="offlineAppsListLabel">&offlineAppsList.label;</label>
|
||||
<listbox id="offlineAppsList"
|
||||
style="height: &offlineAppsList.height;;"
|
||||
flex="1"
|
||||
aria-labelledby="offlineAppsListLabel"
|
||||
onselect="gAdvancedPane.offlineAppSelected(event);">
|
||||
</listbox>
|
||||
</vbox>
|
||||
<vbox pack="end">
|
||||
<button id="offlineAppsListRemove"
|
||||
disabled="true"
|
||||
label="&offlineAppsListRemove.label;"
|
||||
accesskey="&offlineAppsListRemove.accesskey;"
|
||||
oncommand="gAdvancedPane.removeOfflineApp();"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
<!-- Cache/Offline apps -->
|
||||
<groupbox id="offlineGroup">
|
||||
<caption label="&offlineStorage.label;"/>
|
||||
|
||||
<hbox align="center">
|
||||
<label id="actualCacheSize" flex="1"/>
|
||||
<button id="clearCacheButton" icon="clear"
|
||||
label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"
|
||||
oncommand="gAdvancedPane.clearCache();"/>
|
||||
</hbox>
|
||||
<checkbox preference="browser.cache.disk.smart_size.enabled"
|
||||
id="allowSmartSize" flex="1"
|
||||
onsyncfrompreference="return gAdvancedPane.readSmartSizeEnabled();"
|
||||
label="&smartSizeCache.label;"/>
|
||||
<hbox align="center" class="indent">
|
||||
<label id="useCacheBefore" control="cacheSize"
|
||||
accesskey="&useCacheBefore.accesskey;" value="&useCacheBefore.label;"/>
|
||||
<textbox id="cacheSize" type="number" size="2"
|
||||
preference="browser.cache.disk.capacity"
|
||||
onsyncfrompreference="return gAdvancedPane.readCacheSize();"
|
||||
onsynctopreference="return gAdvancedPane.writeCacheSize();"
|
||||
aria-labelledby="useCacheBefore cacheSize useCacheAfter"/>
|
||||
<label id="useCacheAfter" flex="1">&useCacheAfter.label;</label>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<checkbox id="offlineNotify" flex="1"
|
||||
label="&offlineNotify.label;" accesskey="&offlineNotify.accesskey;"
|
||||
preference="browser.offline-apps.notify"
|
||||
onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/>
|
||||
<button id="offlineNotifyExceptions"
|
||||
label="&offlineNotifyExceptions.label;"
|
||||
accesskey="&offlineNotifyExceptions.accesskey;"
|
||||
oncommand="gAdvancedPane.showOfflineExceptions();"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<vbox flex="1">
|
||||
<label id="offlineAppsListLabel">&offlineAppsList.label;</label>
|
||||
<listbox id="offlineAppsList"
|
||||
style="height: &offlineAppsList.height;;"
|
||||
flex="1"
|
||||
aria-labelledby="offlineAppsListLabel"
|
||||
onselect="gAdvancedPane.offlineAppSelected(event);">
|
||||
</listbox>
|
||||
</vbox>
|
||||
<vbox pack="end">
|
||||
<button id="offlineAppsListRemove"
|
||||
disabled="true"
|
||||
label="&offlineAppsListRemove.label;"
|
||||
accesskey="&offlineAppsListRemove.accesskey;"
|
||||
oncommand="gAdvancedPane.removeOfflineApp();"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
</tabpanel>
|
||||
|
||||
<!-- Update -->
|
||||
|
@ -51,6 +51,13 @@ var gMainPane = {
|
||||
// set up the "use current page" label-changing listener
|
||||
this._updateUseCurrentButton();
|
||||
window.addEventListener("focus", this._updateUseCurrentButton, false);
|
||||
|
||||
this.updateBrowserStartupLastSession();
|
||||
|
||||
// Notify observers that the UI is now ready
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService)
|
||||
.notifyObservers(window, "main-pane-loaded", null);
|
||||
},
|
||||
|
||||
// HOME PAGE
|
||||
@ -491,5 +498,26 @@ var gMainPane = {
|
||||
showAddonsMgr: function ()
|
||||
{
|
||||
openUILinkIn("about:addons", "window");
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide/show the "Show my windows and tabs from last time" option based
|
||||
* on the value of the browser.privatebrowsing.autostart pref.
|
||||
*/
|
||||
updateBrowserStartupLastSession: function()
|
||||
{
|
||||
let pbAutoStartPref = document.getElementById("browser.privatebrowsing.autostart");
|
||||
let startupPref = document.getElementById("browser.startup.page");
|
||||
let menu = document.getElementById("browserStartupPage");
|
||||
let option = document.getElementById("browserStartupLastSession");
|
||||
if (pbAutoStartPref.value) {
|
||||
option.setAttribute("disabled", "true");
|
||||
if (option.selected) {
|
||||
menu.selectedItem = document.getElementById("browserStartupHomePage");
|
||||
}
|
||||
} else {
|
||||
option.removeAttribute("disabled");
|
||||
startupPref.updateElements(); // select the correct index in the startup menulist
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -79,6 +79,11 @@
|
||||
name="pref.browser.homepage.disable_button.restore_default"
|
||||
type="bool"/>
|
||||
|
||||
<preference id="browser.privatebrowsing.autostart"
|
||||
name="browser.privatebrowsing.autostart"
|
||||
type="bool"
|
||||
onchange="gMainPane.updateBrowserStartupLastSession();"/>
|
||||
|
||||
<!-- Downloads -->
|
||||
<preference id="browser.download.manager.showWhenStarting"
|
||||
name="browser.download.manager.showWhenStarting"
|
||||
@ -109,9 +114,9 @@
|
||||
control="browserStartupPage"/>
|
||||
<menulist id="browserStartupPage" preference="browser.startup.page">
|
||||
<menupopup>
|
||||
<menuitem label="&startupHomePage.label;" value="1"/>
|
||||
<menuitem label="&startupBlankPage.label;" value="0"/>
|
||||
<menuitem label="&startupLastSession.label;" value="3"/>
|
||||
<menuitem label="&startupHomePage.label;" value="1" id="browserStartupHomePage"/>
|
||||
<menuitem label="&startupBlankPage.label;" value="0" id="browserStartupBlank"/>
|
||||
<menuitem label="&startupLastSession.label;" value="3" id="browserStartupLastSession"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
|
@ -45,6 +45,7 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_BROWSER_FILES = \
|
||||
browser_bug410900.js \
|
||||
browser_bug567487.js \
|
||||
privacypane_tests.js \
|
||||
browser_privacypane_1.js \
|
||||
browser_privacypane_2.js \
|
||||
|
67
browser/components/preferences/tests/browser_bug567487.js
Normal file
67
browser/components/preferences/tests/browser_bug567487.js
Normal file
@ -0,0 +1,67 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function observer(win, topic, data) {
|
||||
if (topic != "main-pane-loaded")
|
||||
return;
|
||||
|
||||
Services.obs.removeObserver(observer, "main-pane-loaded");
|
||||
runTest(win);
|
||||
}
|
||||
Services.obs.addObserver(observer, "main-pane-loaded", false);
|
||||
|
||||
openDialog("chrome://browser/content/preferences/preferences.xul", "Preferences",
|
||||
"chrome,titlebar,toolbar,centerscreen,dialog=no", "paneMain");
|
||||
}
|
||||
|
||||
function runTest(win) {
|
||||
let doc = win.document;
|
||||
let pbAutoStartPref = doc.getElementById("browser.privatebrowsing.autostart");
|
||||
let startupPref = doc.getElementById("browser.startup.page");
|
||||
let menu = doc.getElementById("browserStartupPage");
|
||||
let option = doc.getElementById("browserStartupLastSession");
|
||||
let defOption = doc.getElementById("browserStartupHomePage");
|
||||
let otherOption = doc.getElementById("browserStartupBlank");
|
||||
|
||||
ok(!pbAutoStartPref.value, "Sanity check");
|
||||
is(startupPref.value, startupPref.defaultValue, "Sanity check");
|
||||
|
||||
// First, check to make sure that setting pbAutoStartPref disables the menu item
|
||||
pbAutoStartPref.value = true;
|
||||
is(option.getAttribute("disabled"), "true", "Setting private browsing to autostart " +
|
||||
"should disable the 'Show my tabs and windows from last time' option");
|
||||
pbAutoStartPref.value = false;
|
||||
|
||||
// Now ensure the correct behavior when pbAutoStartPref is set with option enabled
|
||||
startupPref.value = option.getAttribute("value");
|
||||
is(menu.selectedItem, option, "Sanity check");
|
||||
pbAutoStartPref.value = true;
|
||||
is(option.getAttribute("disabled"), "true", "Setting private browsing to autostart " +
|
||||
"should disable the 'Show my tabs and windows from last time' option");
|
||||
is(menu.selectedItem, defOption, "The 'Show home page' option should be selected");
|
||||
is(startupPref.value, option.getAttribute("value"), "But the value of the startup " +
|
||||
"pref itself shouldn't change");
|
||||
menu.selectedItem = otherOption;
|
||||
menu.doCommand();
|
||||
is(startupPref.value, otherOption.getAttribute("value"), "And we should be able to " +
|
||||
"chnage it!");
|
||||
pbAutoStartPref.value = false;
|
||||
|
||||
// Now, ensure that with 'Show my windows and tabs from last time' enabled, toggling
|
||||
// pbAutoStartPref would restore that value in the menulist.
|
||||
startupPref.value = option.getAttribute("value");
|
||||
is(menu.selectedItem, option, "Sanity check");
|
||||
pbAutoStartPref.value = true;
|
||||
is(menu.selectedItem, defOption, "The 'Show home page' option should be selected");
|
||||
pbAutoStartPref.value = false;
|
||||
is(menu.selectedItem, option, "The correct value should be restored");
|
||||
|
||||
// cleanup
|
||||
[pbAutoStartPref, startupPref].forEach(function (pref) {
|
||||
if (pref.hasUserValue)
|
||||
pref.reset();
|
||||
});
|
||||
|
||||
win.close();
|
||||
finish();
|
||||
}
|
@ -541,17 +541,10 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
||||
<!-- LOCALIZATION NOTE (syncTabsMenu.label): This appears in the history menu -->
|
||||
<!ENTITY syncTabsMenu.label "Tabs From Other Computers">
|
||||
|
||||
<!ENTITY syncBrand.shortName.label "Sync">
|
||||
<!ENTITY syncBrand.shortName.label "Sync">
|
||||
|
||||
<!ENTITY syncMenu.label "&syncBrand.shortName.label;">
|
||||
<!-- LOCALIZATION NOTE (sync.menu.accesskey): This is part of the tools menu, so
|
||||
don't use a conflicting access key -->
|
||||
<!ENTITY syncMenu.accesskey "Y">
|
||||
<!ENTITY syncSetup.label "Set Up &syncBrand.shortName.label;…">
|
||||
<!ENTITY syncSetup.accesskey "Y">
|
||||
<!ENTITY syncLogInItem.label "Connect">
|
||||
<!ENTITY syncLogInItem.accesskey "C">
|
||||
<!ENTITY syncLogOutItem.label "Disconnect">
|
||||
<!ENTITY syncLogOutItem.accesskey "D">
|
||||
<!ENTITY syncSyncNowItem.label "Sync Now">
|
||||
<!ENTITY syncSyncNowItem.accesskey "S">
|
||||
<!ENTITY syncToolbarButton.label "Sync">
|
||||
|
@ -51,6 +51,7 @@
|
||||
<!ENTITY useCacheAfter.label "MB of space for the cache">
|
||||
<!ENTITY clearCacheNow.label "Clear Now">
|
||||
<!ENTITY clearCacheNow.accesskey "C">
|
||||
<!ENTITY smartSizeCache.label "Let &brandShortName; manage the size of my cache">
|
||||
|
||||
<!ENTITY updateTab.label "Update">
|
||||
|
||||
|
@ -104,6 +104,12 @@ offlineAppUsage=%1$S %2$S
|
||||
offlinepermissionstext=The following websites are not allowed to store data for offline use:
|
||||
offlinepermissionstitle=Offline Data
|
||||
|
||||
####Preferences::Advanced::Network
|
||||
#LOCALIZATION NOTE: The next string is for the disk usage of the http cache.
|
||||
# e.g., "Your cache is currently using 200 MB"
|
||||
# %1$S = size
|
||||
# %2$S = unit (MB, KB, etc.)
|
||||
actualCacheSize=Your cache is currently using %1$S %2$S of disk space
|
||||
|
||||
#### Syncing
|
||||
connect.label=Connect
|
||||
|
@ -1,3 +1,3 @@
|
||||
%filter substitution
|
||||
|
||||
%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button
|
||||
%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-buttons
|
||||
|
@ -682,12 +682,26 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
|
||||
#zoom-out-button {
|
||||
list-style-image: url("moz-icon://stock/gtk-zoom-out?size=toolbar");
|
||||
}
|
||||
|
||||
#zoom-in-button {
|
||||
list-style-image: url("moz-icon://stock/gtk-zoom-in?size=toolbar");
|
||||
}
|
||||
|
||||
/* sync button */
|
||||
#sync-button {
|
||||
list-style-image: url("chrome://browser/skin/sync-16.png");
|
||||
}
|
||||
|
||||
#sync-button[status="active"] {
|
||||
list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
|
||||
}
|
||||
|
||||
toolbar:not([iconsize="small"]) #sync-button > .toolbarbutton-icon {
|
||||
margin: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* 16px primary toolbar buttons */
|
||||
toolbar[iconsize="small"] .toolbarbutton-1:not([type="menu-button"]) {
|
||||
-moz-box-orient: vertical;
|
||||
|
@ -393,7 +393,7 @@ input.defaultName {
|
||||
right: 0;
|
||||
width: 28px;
|
||||
height: 27px;
|
||||
background: url(chrome://browser/skin/tabview/tabview.png) no-repeat scroll 7px 7px #b7b7b7;
|
||||
background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 16, 16, 0) no-repeat scroll 7px 7px #b7b7b7;
|
||||
border-bottom: 1px solid #909090;
|
||||
border-left: 1px solid #B7B7B7;
|
||||
border-top: 1px solid #CFCFCF;
|
||||
|
@ -684,6 +684,7 @@ toolbar[mode="icons"] #zoom-out-button {
|
||||
toolbar[mode="icons"] #zoom-in-button {
|
||||
-moz-border-start: none;
|
||||
-moz-margin-start: 0;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#zoom-out-button:-moz-locale-dir(ltr),
|
||||
@ -698,6 +699,22 @@ toolbar[mode="icons"] #zoom-in-button {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
/* sync button */
|
||||
|
||||
#sync-button {
|
||||
list-style-image: url("chrome://browser/skin/sync-16.png");
|
||||
}
|
||||
|
||||
#sync-button[status="active"] {
|
||||
list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
|
||||
}
|
||||
|
||||
toolbar:not([iconsize="small"]) #sync-button > .toolbarbutton-icon {
|
||||
margin: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* ----- FULLSCREEN WINDOW CONTROLS ----- */
|
||||
|
||||
#minimize-button,
|
||||
@ -2256,9 +2273,3 @@ listitem.style-section {
|
||||
panel[dimmed="true"] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Sync */
|
||||
|
||||
#sync-status-button.statusbarpanel-iconic {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ input.defaultName {
|
||||
right: 0;
|
||||
width: 28px;
|
||||
height: 27px;
|
||||
background: url(chrome://browser/skin/tabview/tabview.png) no-repeat scroll 4px 4px #b7b7b7;
|
||||
background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 20, 20, 0) no-repeat scroll 4px 4px #b7b7b7;
|
||||
border-bottom: 1px solid #909090;
|
||||
border-left: 1px solid #B7B7B7;
|
||||
border-top: 1px solid #CFCFCF;
|
||||
|
@ -912,6 +912,22 @@ toolbar:not([iconsize="small"])[mode="icons"] #forward-button:not([disabled="tru
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
/* sync button */
|
||||
|
||||
#sync-button {
|
||||
list-style-image: url("chrome://browser/skin/sync-16.png");
|
||||
}
|
||||
|
||||
#sync-button[status="active"] {
|
||||
list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
|
||||
}
|
||||
|
||||
toolbar:not([iconsize="small"]) #sync-button > .toolbarbutton-icon {
|
||||
margin: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* ::::: fullscreen window controls ::::: */
|
||||
|
||||
#minimize-button,
|
||||
|
@ -405,7 +405,7 @@ input.defaultName {
|
||||
right: 0;
|
||||
width: 28px;
|
||||
height: 27px;
|
||||
background: url(chrome://browser/skin/tabview/tabview.png) no-repeat scroll 4px 4px #b7b7b7;
|
||||
background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 18, 18, 0) no-repeat scroll 4px 4px #b7b7b7;
|
||||
border-bottom: 1px solid #909090;
|
||||
border-left: 1px solid #B7B7B7;
|
||||
border-top: 1px solid #CFCFCF;
|
||||
|
@ -375,6 +375,9 @@ user_pref("urlclassifier.updateinterval", 172800);
|
||||
user_pref("browser.safebrowsing.provider.0.gethashURL", "http://%(server)s/safebrowsing-dummy/gethash");
|
||||
user_pref("browser.safebrowsing.provider.0.keyURL", "http://%(server)s/safebrowsing-dummy/newkey");
|
||||
user_pref("browser.safebrowsing.provider.0.updateURL", "http://%(server)s/safebrowsing-dummy/update");
|
||||
// Point update checks to the local testing server for fast failures
|
||||
user_pref("extensions.update.url", "http://%(server)s/extensions-dummy/updateURL");
|
||||
user_pref("extensions.blocklist.url", "http://%(server)s/extensions-dummy/blocklistURL");
|
||||
""" % { "server" : self.webServer + ":" + str(self.httpPort) }
|
||||
prefs.append(part)
|
||||
|
||||
|
@ -2357,5 +2357,5 @@ CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
|
||||
libs export libs::
|
||||
$(CHECK_FROZEN_VARIABLES)
|
||||
|
||||
default::
|
||||
default all::
|
||||
if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
|
||||
|
@ -41,7 +41,6 @@
|
||||
|
||||
interface nsIDocShell;
|
||||
interface nsIURI;
|
||||
interface nsIWebProgress;
|
||||
interface nsIFrame;
|
||||
interface nsIChromeFrameMessageManager;
|
||||
interface nsIVariant;
|
||||
@ -54,11 +53,6 @@ interface nsIFrameLoader : nsISupports
|
||||
*/
|
||||
readonly attribute nsIDocShell docShell;
|
||||
|
||||
/**
|
||||
* Get the nsIWebProgress from the frame loader, allowing listener registration.
|
||||
*/
|
||||
readonly attribute nsIWebProgress webProgress;
|
||||
|
||||
/**
|
||||
* Start loading the frame. This method figures out what to load
|
||||
* from the owner content in the frame loader.
|
||||
|
@ -210,11 +210,17 @@ ContentListHashtableMatchEntry(PLDHashTable *table,
|
||||
}
|
||||
|
||||
already_AddRefed<nsContentList>
|
||||
NS_GetContentList(nsINode* aRootNode, nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId)
|
||||
NS_GetContentList(nsINode* aRootNode,
|
||||
PRInt32 aMatchNameSpaceId,
|
||||
nsIAtom* aHTMLMatchAtom,
|
||||
nsIAtom* aXMLMatchAtom)
|
||||
|
||||
{
|
||||
NS_ASSERTION(aRootNode, "content list has to have a root");
|
||||
|
||||
if(!aXMLMatchAtom)
|
||||
aXMLMatchAtom = aHTMLMatchAtom;
|
||||
|
||||
nsContentList* list = nsnull;
|
||||
|
||||
static PLDHashTableOps hash_table_ops =
|
||||
@ -243,8 +249,8 @@ NS_GetContentList(nsINode* aRootNode, nsIAtom* aMatchAtom,
|
||||
ContentListHashEntry *entry = nsnull;
|
||||
// First we look in our hashtable. Then we create a content list if needed
|
||||
if (gContentListHashTable.ops) {
|
||||
nsContentListKey hashKey(aRootNode, aMatchAtom,
|
||||
aMatchNameSpaceId);
|
||||
nsContentListKey hashKey(aRootNode, aHTMLMatchAtom,
|
||||
aXMLMatchAtom, aMatchNameSpaceId);
|
||||
|
||||
// A PL_DHASH_ADD is equivalent to a PL_DHASH_LOOKUP for cases
|
||||
// when the entry is already in the hashtable.
|
||||
@ -259,16 +265,11 @@ NS_GetContentList(nsINode* aRootNode, nsIAtom* aMatchAtom,
|
||||
if (!list) {
|
||||
// We need to create a ContentList and add it to our new entry, if
|
||||
// we have an entry
|
||||
list = new nsContentList(aRootNode, aMatchAtom,
|
||||
aMatchNameSpaceId);
|
||||
list = new nsContentList(aRootNode, aMatchNameSpaceId,
|
||||
aHTMLMatchAtom, aXMLMatchAtom);
|
||||
if (entry) {
|
||||
if (list)
|
||||
entry->mContentList = list;
|
||||
else
|
||||
PL_DHashTableRawRemove(&gContentListHashTable, entry);
|
||||
entry->mContentList = list;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(list, nsnull);
|
||||
}
|
||||
|
||||
NS_ADDREF(list);
|
||||
@ -385,11 +386,12 @@ NS_GetFuncStringContentList(nsINode* aRootNode,
|
||||
// nsContentList implementation
|
||||
|
||||
nsContentList::nsContentList(nsINode* aRootNode,
|
||||
nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId,
|
||||
nsIAtom* aHTMLMatchAtom,
|
||||
nsIAtom* aXMLMatchAtom,
|
||||
PRBool aDeep)
|
||||
: nsBaseContentList(),
|
||||
nsContentListKey(aRootNode, aMatchAtom, aMatchNameSpaceId),
|
||||
nsContentListKey(aRootNode, aHTMLMatchAtom, aXMLMatchAtom, aMatchNameSpaceId),
|
||||
mFunc(nsnull),
|
||||
mDestroyFunc(nsnull),
|
||||
mData(nsnull),
|
||||
@ -398,7 +400,8 @@ nsContentList::nsContentList(nsINode* aRootNode,
|
||||
mFuncMayDependOnAttr(PR_FALSE)
|
||||
{
|
||||
NS_ASSERTION(mRootNode, "Must have root");
|
||||
if (nsGkAtoms::_asterix == mMatchAtom) {
|
||||
if (nsGkAtoms::_asterix == mHTMLMatchAtom) {
|
||||
NS_ASSERTION(mXMLMatchAtom == nsGkAtoms::_asterix, "HTML atom and XML atom are not both asterix?");
|
||||
mMatchAll = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
@ -416,7 +419,7 @@ nsContentList::nsContentList(nsINode* aRootNode,
|
||||
PRInt32 aMatchNameSpaceId,
|
||||
PRBool aFuncMayDependOnAttr)
|
||||
: nsBaseContentList(),
|
||||
nsContentListKey(aRootNode, aMatchAtom, aMatchNameSpaceId),
|
||||
nsContentListKey(aRootNode, aMatchAtom, aMatchAtom, aMatchNameSpaceId),
|
||||
mFunc(aFunc),
|
||||
mDestroyFunc(aDestroyFunc),
|
||||
mData(aData),
|
||||
@ -773,25 +776,39 @@ PRBool
|
||||
nsContentList::Match(Element *aElement)
|
||||
{
|
||||
if (mFunc) {
|
||||
return (*mFunc)(aElement, mMatchNameSpaceId, mMatchAtom, mData);
|
||||
return (*mFunc)(aElement, mMatchNameSpaceId, mXMLMatchAtom, mData);
|
||||
}
|
||||
|
||||
if (mMatchAtom) {
|
||||
nsINodeInfo *ni = aElement->NodeInfo();
|
||||
if (!mXMLMatchAtom)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mMatchNameSpaceId == kNameSpaceID_Unknown) {
|
||||
return (mMatchAll || ni->QualifiedNameEquals(mMatchAtom));
|
||||
}
|
||||
nsINodeInfo *ni = aElement->NodeInfo();
|
||||
|
||||
PRBool unknown = mMatchNameSpaceId == kNameSpaceID_Unknown;
|
||||
PRBool wildcard = mMatchNameSpaceId == kNameSpaceID_Wildcard;
|
||||
PRBool toReturn = mMatchAll;
|
||||
if (!unknown && !wildcard)
|
||||
toReturn &= ni->NamespaceEquals(mMatchNameSpaceId);
|
||||
|
||||
if (mMatchNameSpaceId == kNameSpaceID_Wildcard) {
|
||||
return (mMatchAll || ni->Equals(mMatchAtom));
|
||||
}
|
||||
if (toReturn)
|
||||
return toReturn;
|
||||
|
||||
return ((mMatchAll && ni->NamespaceEquals(mMatchNameSpaceId)) ||
|
||||
ni->Equals(mMatchAtom, mMatchNameSpaceId));
|
||||
nsIDocument* doc = aElement->GetOwnerDoc();
|
||||
PRBool matchHTML = aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
|
||||
doc && doc->IsHTML();
|
||||
|
||||
if (unknown) {
|
||||
return matchHTML ? ni->QualifiedNameEquals(mHTMLMatchAtom) :
|
||||
ni->QualifiedNameEquals(mXMLMatchAtom);
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
|
||||
if (wildcard) {
|
||||
return matchHTML ? ni->Equals(mHTMLMatchAtom) :
|
||||
ni->Equals(mXMLMatchAtom);
|
||||
}
|
||||
|
||||
return matchHTML ? ni->Equals(mHTMLMatchAtom, mMatchNameSpaceId) :
|
||||
ni->Equals(mXMLMatchAtom, mMatchNameSpaceId);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -144,16 +144,20 @@ class nsContentListKey
|
||||
{
|
||||
public:
|
||||
nsContentListKey(nsINode* aRootNode,
|
||||
nsIAtom* aMatchAtom,
|
||||
nsIAtom* aHTMLMatchAtom,
|
||||
nsIAtom* aXMLMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId)
|
||||
: mMatchAtom(aMatchAtom),
|
||||
: mHTMLMatchAtom(aHTMLMatchAtom),
|
||||
mXMLMatchAtom(aXMLMatchAtom),
|
||||
mMatchNameSpaceId(aMatchNameSpaceId),
|
||||
mRootNode(aRootNode)
|
||||
{
|
||||
NS_ASSERTION(!aXMLMatchAtom == !aHTMLMatchAtom, "Either neither or both atoms should be null");
|
||||
}
|
||||
|
||||
nsContentListKey(const nsContentListKey& aContentListKey)
|
||||
: mMatchAtom(aContentListKey.mMatchAtom),
|
||||
: mHTMLMatchAtom(aContentListKey.mHTMLMatchAtom),
|
||||
mXMLMatchAtom(aContentListKey.mXMLMatchAtom),
|
||||
mMatchNameSpaceId(aContentListKey.mMatchNameSpaceId),
|
||||
mRootNode(aContentListKey.mRootNode)
|
||||
{
|
||||
@ -161,21 +165,26 @@ public:
|
||||
|
||||
PRBool Equals(const nsContentListKey& aContentListKey) const
|
||||
{
|
||||
NS_ASSERTION(mHTMLMatchAtom == aContentListKey.mHTMLMatchAtom
|
||||
|| mXMLMatchAtom != aContentListKey.mXMLMatchAtom, "HTML atoms should match if XML atoms match");
|
||||
|
||||
return
|
||||
mMatchAtom == aContentListKey.mMatchAtom &&
|
||||
mXMLMatchAtom == aContentListKey.mXMLMatchAtom &&
|
||||
mMatchNameSpaceId == aContentListKey.mMatchNameSpaceId &&
|
||||
mRootNode == aContentListKey.mRootNode;
|
||||
}
|
||||
|
||||
inline PRUint32 GetHash(void) const
|
||||
{
|
||||
return
|
||||
NS_PTR_TO_INT32(mMatchAtom.get()) ^
|
||||
NS_PTR_TO_INT32(mXMLMatchAtom.get()) ^
|
||||
(NS_PTR_TO_INT32(mRootNode) << 12) ^
|
||||
(mMatchNameSpaceId << 24);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIAtom> mMatchAtom;
|
||||
nsCOMPtr<nsIAtom> mHTMLMatchAtom;
|
||||
nsCOMPtr<nsIAtom> mXMLMatchAtom;
|
||||
PRInt32 mMatchNameSpaceId;
|
||||
nsINode* mRootNode; // Weak ref
|
||||
};
|
||||
@ -230,8 +239,9 @@ public:
|
||||
* our root.
|
||||
*/
|
||||
nsContentList(nsINode* aRootNode,
|
||||
nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId,
|
||||
nsIAtom* aHTMLMatchAtom,
|
||||
nsIAtom* aXMLMatchAtom,
|
||||
PRBool aDeep = PR_TRUE);
|
||||
|
||||
/**
|
||||
@ -485,8 +495,10 @@ protected:
|
||||
};
|
||||
|
||||
already_AddRefed<nsContentList>
|
||||
NS_GetContentList(nsINode* aRootNode, nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId);
|
||||
NS_GetContentList(nsINode* aRootNode,
|
||||
PRInt32 aMatchNameSpaceId,
|
||||
nsIAtom* aHTMLMatchAtom,
|
||||
nsIAtom* aXMLMatchAtom = nsnull);
|
||||
|
||||
already_AddRefed<nsContentList>
|
||||
NS_GetFuncStringContentList(nsINode* aRootNode,
|
||||
|
@ -4407,7 +4407,9 @@ nsDocument::CreateElement(const nsAString& aTagName,
|
||||
ToLowerCase(aTagName, lcTagName);
|
||||
}
|
||||
|
||||
rv = CreateElem(needsLowercase ? lcTagName : aTagName, nsnull,
|
||||
rv = CreateElem(needsLowercase ? static_cast<const nsAString&>(lcTagName)
|
||||
: aTagName,
|
||||
nsnull,
|
||||
IsHTML() ? kNameSpaceID_XHTML : GetDefaultNamespaceID(),
|
||||
PR_TRUE, aReturn);
|
||||
return rv;
|
||||
@ -4594,18 +4596,12 @@ nsDocument::CreateEntityReference(const nsAString& aName,
|
||||
already_AddRefed<nsContentList>
|
||||
nsDocument::GetElementsByTagName(const nsAString& aTagname)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
|
||||
if (IsHTML()) {
|
||||
nsAutoString tmp(aTagname);
|
||||
ToLowerCase(tmp); // HTML elements are lower case internally.
|
||||
nameAtom = do_GetAtom(tmp);
|
||||
}
|
||||
else {
|
||||
nameAtom = do_GetAtom(aTagname);
|
||||
}
|
||||
NS_ENSURE_TRUE(nameAtom, nsnull);
|
||||
nsAutoString lowercaseName;
|
||||
nsContentUtils::ASCIIToLower(aTagname, lowercaseName);
|
||||
nsCOMPtr<nsIAtom> xmlAtom = do_GetAtom(aTagname);
|
||||
nsCOMPtr<nsIAtom> htmlAtom = do_GetAtom(lowercaseName);
|
||||
|
||||
return NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown);
|
||||
return NS_GetContentList(this, kNameSpaceID_Unknown, htmlAtom, xmlAtom);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -4634,9 +4630,8 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aLocalName);
|
||||
NS_ENSURE_TRUE(nameAtom, nsnull);
|
||||
|
||||
return NS_GetContentList(this, nameAtom, nameSpaceId);
|
||||
return NS_GetContentList(this, nameSpaceId, nameAtom);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -5203,9 +5198,7 @@ nsDocument::GetTitleContent(PRUint32 aNamespace)
|
||||
return nsnull;
|
||||
|
||||
nsRefPtr<nsContentList> list =
|
||||
NS_GetContentList(this, nsGkAtoms::title, aNamespace);
|
||||
if (!list)
|
||||
return nsnull;
|
||||
NS_GetContentList(this, aNamespace, nsGkAtoms::title);
|
||||
|
||||
return list->Item(0, PR_FALSE);
|
||||
}
|
||||
@ -5846,7 +5839,7 @@ nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
||||
NS_IMETHODIMP
|
||||
nsDocument::Normalize()
|
||||
{
|
||||
for (PRInt32 i = 0; i < mChildren.ChildCount(); ++i) {
|
||||
for (PRUint32 i = 0; i < mChildren.ChildCount(); ++i) {
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mChildren.ChildAt(i)));
|
||||
node->Normalize();
|
||||
}
|
||||
@ -7406,16 +7399,14 @@ nsDocument::OnPageShow(PRBool aPersisted,
|
||||
if (aPersisted && root) {
|
||||
// Send out notifications that our <link> elements are attached.
|
||||
nsRefPtr<nsContentList> links = NS_GetContentList(root,
|
||||
nsGkAtoms::link,
|
||||
kNameSpaceID_Unknown);
|
||||
kNameSpaceID_Unknown,
|
||||
nsGkAtoms::link);
|
||||
|
||||
if (links) {
|
||||
PRUint32 linkCount = links->Length(PR_TRUE);
|
||||
for (PRUint32 i = 0; i < linkCount; ++i) {
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
|
||||
if (link) {
|
||||
link->LinkAdded();
|
||||
}
|
||||
PRUint32 linkCount = links->Length(PR_TRUE);
|
||||
for (PRUint32 i = 0; i < linkCount; ++i) {
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
|
||||
if (link) {
|
||||
link->LinkAdded();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7460,16 +7451,14 @@ nsDocument::OnPageHide(PRBool aPersisted,
|
||||
Element* root = GetRootElement();
|
||||
if (aPersisted && root) {
|
||||
nsRefPtr<nsContentList> links = NS_GetContentList(root,
|
||||
nsGkAtoms::link,
|
||||
kNameSpaceID_Unknown);
|
||||
kNameSpaceID_Unknown,
|
||||
nsGkAtoms::link);
|
||||
|
||||
if (links) {
|
||||
PRUint32 linkCount = links->Length(PR_TRUE);
|
||||
for (PRUint32 i = 0; i < linkCount; ++i) {
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
|
||||
if (link) {
|
||||
link->LinkRemoved();
|
||||
}
|
||||
PRUint32 linkCount = links->Length(PR_TRUE);
|
||||
for (PRUint32 i = 0; i < linkCount; ++i) {
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
|
||||
if (link) {
|
||||
link->LinkRemoved();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -412,34 +412,6 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetWebProgress(nsIWebProgress **aWebProgress)
|
||||
{
|
||||
nsresult rv;
|
||||
*aWebProgress = nsnull;
|
||||
#ifdef MOZ_IPC
|
||||
if (mRemoteFrame) {
|
||||
if (!mRemoteBrowser) {
|
||||
TryRemoteBrowser();
|
||||
}
|
||||
if (!mRemoteBrowser) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
*aWebProgress = mRemoteBrowser;
|
||||
NS_ADDREF(*aWebProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDocShell> shell;
|
||||
rv = GetDocShell(getter_AddRefs(shell));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIWebProgress> progress(do_QueryInterface(shell));
|
||||
progress.swap(*aWebProgress);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameLoader::Finalize()
|
||||
{
|
||||
@ -1403,6 +1375,14 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
|
||||
NS_ASSERTION(treeItem, "docshell must be a treeitem!");
|
||||
|
||||
// Check that we're still in the docshell tree.
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
NS_WARN_IF_FALSE(treeOwner,
|
||||
"Trying to load a new url to a docshell without owner!");
|
||||
NS_ENSURE_STATE(treeOwner);
|
||||
|
||||
|
||||
PRInt32 ourType;
|
||||
rv = treeItem->GetItemType(&ourType);
|
||||
|
@ -1365,8 +1365,9 @@ nsGenericElement::GetChildrenList()
|
||||
NS_ENSURE_TRUE(slots, nsnull);
|
||||
|
||||
if (!slots->mChildrenList) {
|
||||
slots->mChildrenList = new nsContentList(this, nsGkAtoms::_asterix,
|
||||
kNameSpaceID_Wildcard, PR_FALSE);
|
||||
slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard,
|
||||
nsGkAtoms::_asterix, nsGkAtoms::_asterix,
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
return slots->mChildrenList;
|
||||
@ -2495,12 +2496,13 @@ nsresult
|
||||
nsGenericElement::GetElementsByTagName(const nsAString& aTagname,
|
||||
nsIDOMNodeList** aReturn)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
|
||||
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsAutoString lowercaseName;
|
||||
nsContentUtils::ASCIIToLower(aTagname, lowercaseName);
|
||||
nsCOMPtr<nsIAtom> XMLAtom = do_GetAtom(aTagname);
|
||||
nsCOMPtr<nsIAtom> HTMLAtom = do_GetAtom(lowercaseName);
|
||||
|
||||
nsContentList *list = NS_GetContentList(this, nameAtom,
|
||||
kNameSpaceID_Unknown).get();
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsContentList *list = NS_GetContentList(this, kNameSpaceID_Unknown,
|
||||
HTMLAtom, XMLAtom).get();
|
||||
|
||||
// transfer ref to aReturn
|
||||
*aReturn = list;
|
||||
@ -2627,10 +2629,8 @@ nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aLocalName);
|
||||
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsContentList *list = NS_GetContentList(this, nameAtom, nameSpaceId).get();
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsContentList *list = NS_GetContentList(this, nameSpaceId, nameAtom).get();
|
||||
|
||||
// transfer ref to aReturn
|
||||
*aReturn = list;
|
||||
|
@ -175,6 +175,8 @@ _TEST_FILES1 = test_bug5141.html \
|
||||
test_bug421602.html \
|
||||
test_bug422537.html \
|
||||
test_bug424359-1.html \
|
||||
test_bug499656.html \
|
||||
test_bug499656.xhtml \
|
||||
file_htmlserializer_1.html \
|
||||
file_htmlserializer_1_bodyonly.html \
|
||||
file_htmlserializer_1_format.html \
|
||||
|
@ -45,7 +45,6 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
bug421622-referer.sjs \
|
||||
bug514705.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
@ -54,8 +53,6 @@ _CHROME_FILES = \
|
||||
test_bug429785.xul \
|
||||
test_bug430050.xul \
|
||||
test_bug467123.xul \
|
||||
test_bug514705.xul \
|
||||
bug514705_helper.xul \
|
||||
test_title.xul \
|
||||
title_window.xul \
|
||||
test_bug549682.xul \
|
||||
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>bug514705.html</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
bug514705.html
|
||||
</body>
|
||||
</html>
|
@ -1,90 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Bug514705 helper"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="RunTest();">
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
var Ci = Components.interfaces;
|
||||
var imports = [ "SimpleTest", "is", "isnot", "ok" ];
|
||||
for each (var import in imports) {
|
||||
window[import] = window.opener.wrappedJSObject[import];
|
||||
}
|
||||
var locationChanged = false;
|
||||
var progressChanged = false;
|
||||
var refreshAttempted = false;
|
||||
|
||||
var listener = {
|
||||
onLocationChange: function(webProgress, request, location) {
|
||||
locationChanged = true;
|
||||
},
|
||||
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||
maxSelfProgress, curTotalProgress,
|
||||
maxTotalProgress) {
|
||||
},
|
||||
onSecurityChange: function(webProgress, request, state) {
|
||||
},
|
||||
onStateChange: function(webProgress, request, stateFlags, status) {
|
||||
|
||||
if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
|
||||
(stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
|
||||
var test = SimpleTest;
|
||||
ok (locationChanged, "onLocationChanged was called.");
|
||||
ok (progressChanged, "onProgressChanged64 was called.");
|
||||
ok (refreshAttempted, "onRefreshAttempted was called.");
|
||||
ok (true, "onStateChange was called.");
|
||||
window.close();
|
||||
test.finish();
|
||||
}
|
||||
},
|
||||
onStatusChange: function(webProgress, request, status, message) {
|
||||
},
|
||||
onProgressChange64 : function(webProgress, request, curSelfProgress,
|
||||
maxSelfProgress, curTotalProgress,
|
||||
maxTotalProgress) {
|
||||
|
||||
progressChanged = true;
|
||||
},
|
||||
onRefreshAttempted : function(webProgress, uri, millis, sameURI)
|
||||
{
|
||||
refreshAttempted = true;
|
||||
return true;
|
||||
},
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
|
||||
iid.equals(Components.interfaces.nsIWebProgressListener2) ||
|
||||
iid.equals(Components.interfaces.nsISupportsWeakReference)) {
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
function EndTest() {
|
||||
var test = SimpleTest;
|
||||
window.close();
|
||||
test.finish();
|
||||
}
|
||||
function RunTest()
|
||||
{
|
||||
var browser = document.getElementById('page');
|
||||
var flags = Ci.nsIWebProgress.NOTIFY_ALL;
|
||||
|
||||
browser.webProgress.addProgressListener(listener, flags);
|
||||
|
||||
var script = "refreshURI = docShell.QueryInterface(Components.interfaces.nsIRefreshURI);"
|
||||
+ "var ioServ = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);"
|
||||
+ "var uri = ioServ.newURI('http://localhost:8888/tests/content/base/test/chrome/bug514705.html', null, null);"
|
||||
+ "refreshURI.refreshURI(uri, 100, false, false);";
|
||||
messageManager.loadFrameScript("data:," + script, true);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
|
||||
<browser type="content" flex="1" id="page" remote="true"/>
|
||||
|
||||
</window>
|
@ -1,30 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Bug 514705"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="RunTest();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=421622"
|
||||
target="_blank">Mozilla Bug 421622</a>
|
||||
</body>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
//SimpleTest.waitForExplicitFinish();
|
||||
todo(false, "Enable this test");
|
||||
|
||||
function RunTest()
|
||||
{
|
||||
//window.open("bug514705_helper.xul", "bug514705",
|
||||
// "chrome,width=100,height=100");
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
58
content/base/test/test_bug499656.html
Normal file
58
content/base/test/test_bug499656.html
Normal file
@ -0,0 +1,58 @@
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=499656
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 499656</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=499656">Mozilla Bug 499655</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 499655 **/
|
||||
|
||||
div1 = document.createElementNS("http://www.w3.org/1999/xhtml","test");
|
||||
div2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst");
|
||||
div3 = document.createElementNS("test","test");
|
||||
div4 = document.createElementNS("test","TEst");
|
||||
div5 = document.createElement("test");
|
||||
div6 = document.createElement("TEst");
|
||||
|
||||
content = document.getElementById("content");
|
||||
|
||||
content.appendChild(div1);
|
||||
content.appendChild(div2);
|
||||
content.appendChild(div3);
|
||||
content.appendChild(div4);
|
||||
content.appendChild(div5);
|
||||
content.appendChild(div6);
|
||||
|
||||
list = document.getElementsByTagName('test');
|
||||
is(list.length, 4, "Number of elements found");
|
||||
ok(list[0] == div1, "First element didn't match");
|
||||
ok(list[1] == div3, "Third element didn't match");
|
||||
ok(list[2] == div5, "Fifth element didn't match");
|
||||
ok(list[3] == div6, "Sixth element didn't match");
|
||||
|
||||
list = document.getElementsByTagName('TEst');
|
||||
is(list.length, 4, "Wrong number of elements found");
|
||||
ok(list[0] == div1, "First element didn't match");
|
||||
ok(list[1] == div4, "Fourth element didn't match");
|
||||
ok(list[2] == div5, "Fifth element didn't match");
|
||||
ok(list[3] == div6, "Sixth element didn't match");
|
||||
|
||||
list = document.getElementsByTagNameNS('test', 'test');
|
||||
is(list.length, 1, "Wrong number of elements found");
|
||||
ok(list[0] == div3, "Third element didn't match");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
58
content/base/test/test_bug499656.xhtml
Normal file
58
content/base/test/test_bug499656.xhtml
Normal file
@ -0,0 +1,58 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=499655
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 499655</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/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=499655">Mozilla Bug 499655</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
div1 = document.createElementNS("http://www.w3.org/1999/xhtml","test");
|
||||
div2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst");
|
||||
div3 = document.createElementNS("test","test");
|
||||
div4 = document.createElementNS("test","TEst");
|
||||
div5 = document.createElement("test");
|
||||
div6 = document.createElement("TEst");
|
||||
|
||||
content = document.getElementById("content");
|
||||
|
||||
content.appendChild(div1);
|
||||
content.appendChild(div2);
|
||||
content.appendChild(div3);
|
||||
content.appendChild(div4);
|
||||
content.appendChild(div5);
|
||||
content.appendChild(div6);
|
||||
|
||||
|
||||
list = document.getElementsByTagName('test');
|
||||
is(list.length, 3, "Number of elements found");
|
||||
ok(list[0] == div1, "First element didn't match");
|
||||
ok(list[1] == div3, "Third element didn't match");
|
||||
ok(list[2] == div5, "Fifth element didn't match");
|
||||
|
||||
list = document.getElementsByTagName('TEst');
|
||||
is(list.length, 3, "Number of elements found");
|
||||
ok(list[0] == div2, "Second element didn't match");
|
||||
ok(list[1] == div4, "Fourth element didn't match");
|
||||
ok(list[2] == div6, "Sixth element didn't match");
|
||||
|
||||
list = document.getElementsByTagNameNS('test', 'test');
|
||||
is(list.length, 1, "Wrong number of elements found");
|
||||
ok(list[0] == div3, "Third element didn't match");
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -116,13 +116,10 @@ nsHTMLMapElement::GetAreas(nsIDOMHTMLCollection** aAreas)
|
||||
if (!mAreas) {
|
||||
// Not using NS_GetContentList because this should not be cached
|
||||
mAreas = new nsContentList(this,
|
||||
nsGkAtoms::area,
|
||||
mNodeInfo->NamespaceID(),
|
||||
nsGkAtoms::area,
|
||||
nsGkAtoms::area,
|
||||
PR_FALSE);
|
||||
|
||||
if (!mAreas) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(*aAreas = mAreas);
|
||||
|
@ -169,10 +169,11 @@ nsresult
|
||||
TableRowsCollection::Init()
|
||||
{
|
||||
mOrphanRows = new nsContentList(mParent,
|
||||
nsGkAtoms::tr,
|
||||
mParent->NodeInfo()->NamespaceID(),
|
||||
nsGkAtoms::tr,
|
||||
nsGkAtoms::tr,
|
||||
PR_FALSE);
|
||||
return mOrphanRows ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Macro that can be used to avoid copy/pasting code to iterate over the
|
||||
@ -599,11 +600,10 @@ nsHTMLTableElement::GetTBodies(nsIDOMHTMLCollection** aValue)
|
||||
if (!mTBodies) {
|
||||
// Not using NS_GetContentList because this should not be cached
|
||||
mTBodies = new nsContentList(this,
|
||||
nsGkAtoms::tbody,
|
||||
mNodeInfo->NamespaceID(),
|
||||
nsGkAtoms::tbody,
|
||||
nsGkAtoms::tbody,
|
||||
PR_FALSE);
|
||||
|
||||
NS_ENSURE_TRUE(mTBodies, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aValue = mTBodies);
|
||||
|
@ -133,8 +133,9 @@ nsHTMLTableSectionElement::GetRows(nsIDOMHTMLCollection** aValue)
|
||||
|
||||
if (!mRows) {
|
||||
mRows = new nsContentList(this,
|
||||
nsGkAtoms::tr,
|
||||
mNodeInfo->NamespaceID(),
|
||||
nsGkAtoms::tr,
|
||||
nsGkAtoms::tr,
|
||||
PR_FALSE);
|
||||
|
||||
NS_ENSURE_TRUE(mRows, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -1174,9 +1174,8 @@ nsIDOMHTMLMapElement *
|
||||
nsHTMLDocument::GetImageMap(const nsAString& aMapName)
|
||||
{
|
||||
if (!mImageMaps) {
|
||||
mImageMaps = new nsContentList(this, nsGkAtoms::map, kNameSpaceID_XHTML);
|
||||
mImageMaps = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::map, nsGkAtoms::map);
|
||||
}
|
||||
NS_ASSERTION(mImageMaps, "Infallible malloc failed.");
|
||||
|
||||
nsIDOMHTMLMapElement* firstMatch = nsnull;
|
||||
nsAutoString name;
|
||||
@ -1550,12 +1549,7 @@ nsHTMLDocument::GetBody(nsresult *aResult)
|
||||
// The document is most likely a frameset document so look for the
|
||||
// outer most frameset element
|
||||
nsRefPtr<nsContentList> nodeList =
|
||||
NS_GetContentList(this, nsGkAtoms::frameset, kNameSpaceID_XHTML);
|
||||
if (!nodeList) {
|
||||
*aResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
NS_GetContentList(this, kNameSpaceID_XHTML, nsGkAtoms::frameset);
|
||||
|
||||
return nodeList->GetNodeAt(0);
|
||||
}
|
||||
@ -1613,10 +1607,7 @@ NS_IMETHODIMP
|
||||
nsHTMLDocument::GetImages(nsIDOMHTMLCollection** aImages)
|
||||
{
|
||||
if (!mImages) {
|
||||
mImages = new nsContentList(this, nsGkAtoms::img, kNameSpaceID_XHTML);
|
||||
if (!mImages) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mImages = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::img, nsGkAtoms::img);
|
||||
}
|
||||
|
||||
*aImages = mImages;
|
||||
@ -1629,10 +1620,7 @@ NS_IMETHODIMP
|
||||
nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets)
|
||||
{
|
||||
if (!mApplets) {
|
||||
mApplets = new nsContentList(this, nsGkAtoms::applet, kNameSpaceID_XHTML);
|
||||
if (!mApplets) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mApplets = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::applet, nsGkAtoms::applet);
|
||||
}
|
||||
|
||||
*aApplets = mApplets;
|
||||
@ -1678,9 +1666,6 @@ nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
|
||||
{
|
||||
if (!mLinks) {
|
||||
mLinks = new nsContentList(this, MatchLinks, nsnull, nsnull);
|
||||
if (!mLinks) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
*aLinks = mLinks;
|
||||
@ -1718,9 +1703,6 @@ nsHTMLDocument::GetAnchors(nsIDOMHTMLCollection** aAnchors)
|
||||
{
|
||||
if (!mAnchors) {
|
||||
mAnchors = new nsContentList(this, MatchAnchors, nsnull, nsnull);
|
||||
if (!mAnchors) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
*aAnchors = mAnchors;
|
||||
@ -2516,10 +2498,7 @@ NS_IMETHODIMP
|
||||
nsHTMLDocument::GetEmbeds(nsIDOMHTMLCollection** aEmbeds)
|
||||
{
|
||||
if (!mEmbeds) {
|
||||
mEmbeds = new nsContentList(this, nsGkAtoms::embed, kNameSpaceID_XHTML);
|
||||
if (!mEmbeds) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mEmbeds = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::embed, nsGkAtoms::embed);
|
||||
}
|
||||
|
||||
*aEmbeds = mEmbeds;
|
||||
@ -2809,8 +2788,9 @@ nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms)
|
||||
nsContentList*
|
||||
nsHTMLDocument::GetForms()
|
||||
{
|
||||
if (!mForms)
|
||||
mForms = new nsContentList(this, nsGkAtoms::form, kNameSpaceID_XHTML);
|
||||
if (!mForms) {
|
||||
mForms = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::form, nsGkAtoms::form);
|
||||
}
|
||||
|
||||
return mForms;
|
||||
}
|
||||
|
@ -1124,7 +1124,9 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
||||
if (!clazz ||
|
||||
(~clazz->flags &
|
||||
(JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) ||
|
||||
JSCLASS_RESERVED_SLOTS(clazz) != 1) {
|
||||
JSCLASS_RESERVED_SLOTS(clazz) != 1 ||
|
||||
clazz->resolve != (JSResolveOp)XBLResolve ||
|
||||
clazz->finalize != XBLFinalize) {
|
||||
// Clearly not the right class
|
||||
continue;
|
||||
}
|
||||
@ -1342,6 +1344,10 @@ nsXBLBinding::DoInitJSClass(JSContext *cx, JSObject *global, JSObject *obj,
|
||||
|
||||
// Keep this proto binding alive while we're alive. Do this first so that
|
||||
// we can guarantee that in XBLFinalize this will be non-null.
|
||||
// Note that we can't just store aProtoBinding in the private and
|
||||
// addref/release the nsXBLDocumentInfo through it, because cycle
|
||||
// collection doesn't seem to work right if the private is not an
|
||||
// nsISupports.
|
||||
nsXBLDocumentInfo* docInfo = aProtoBinding->XBLDocumentInfo();
|
||||
::JS_SetPrivate(cx, proto, docInfo);
|
||||
NS_ADDREF(docInfo);
|
||||
|
@ -1633,6 +1633,7 @@ jsid nsDOMClassInfo::sOnended_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sOnratechange_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sOndurationchange_id= JSID_VOID;
|
||||
jsid nsDOMClassInfo::sOnvolumechange_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sOnmessage_id = JSID_VOID;
|
||||
|
||||
static const JSClass *sObjectClass = nsnull;
|
||||
JSPropertyOp nsDOMClassInfo::sXPCNativeWrapperGetPropertyOp = nsnull;
|
||||
@ -1856,6 +1857,7 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx)
|
||||
SET_JSID_TO_STRING(sOnratechange_id, cx, "onratechange");
|
||||
SET_JSID_TO_STRING(sOndurationchange_id,cx, "ondurationchange");
|
||||
SET_JSID_TO_STRING(sOnvolumechange_id, cx, "onvolumechange");
|
||||
SET_JSID_TO_STRING(sOnmessage_id, cx, "onmessage");
|
||||
#endif // MOZ_MEDIA
|
||||
|
||||
return NS_OK;
|
||||
@ -4928,6 +4930,7 @@ nsDOMClassInfo::ShutDown()
|
||||
sOnratechange_id = JSID_VOID;
|
||||
sOndurationchange_id= JSID_VOID;
|
||||
sOnvolumechange_id = JSID_VOID;
|
||||
sOnmessage_id = JSID_VOID;
|
||||
|
||||
NS_IF_RELEASE(sXPConnect);
|
||||
NS_IF_RELEASE(sSecMan);
|
||||
@ -7777,7 +7780,8 @@ nsEventReceiverSH::ReallyIsEventName(jsid id, jschar aFirstChar)
|
||||
id == sOnmouseout_id ||
|
||||
id == sOnmouseover_id ||
|
||||
id == sOnmouseup_id ||
|
||||
id == sOnmousedown_id);
|
||||
id == sOnmousedown_id ||
|
||||
id == sOnmessage_id);
|
||||
case 'p' :
|
||||
return (id == sOnpaint_id ||
|
||||
id == sOnpageshow_id ||
|
||||
|
@ -380,6 +380,7 @@ protected:
|
||||
static jsid sOnratechange_id;
|
||||
static jsid sOndurationchange_id;
|
||||
static jsid sOnvolumechange_id;
|
||||
static jsid sOnmessage_id;
|
||||
|
||||
static JSPropertyOp sXPCNativeWrapperGetPropertyOp;
|
||||
static JSPropertyOp sXrayWrapperPropertyHolderGetPropertyOp;
|
||||
|
@ -180,6 +180,41 @@ private:
|
||||
PrefObserver& operator=(const PrefObserver&);
|
||||
};
|
||||
|
||||
class AlertObserver
|
||||
{
|
||||
public:
|
||||
|
||||
AlertObserver(nsIObserver *aObserver, const nsString& aData)
|
||||
: mData(aData)
|
||||
, mObserver(aObserver)
|
||||
{
|
||||
}
|
||||
|
||||
~AlertObserver() {}
|
||||
|
||||
bool ShouldRemoveFrom(nsIObserver* aObserver,
|
||||
const nsString& aData) const
|
||||
{
|
||||
return (mObserver == aObserver &&
|
||||
mData == aData);
|
||||
}
|
||||
|
||||
bool Observes(const nsString& aData) const
|
||||
{
|
||||
return mData.Equals(aData);
|
||||
}
|
||||
|
||||
bool Notify(const nsCString& aType) const
|
||||
{
|
||||
mObserver->Observe(nsnull, aType.get(), mData.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIObserver> mObserver;
|
||||
nsString mData;
|
||||
};
|
||||
|
||||
|
||||
ContentChild* ContentChild::sSingleton;
|
||||
|
||||
@ -309,7 +344,7 @@ ContentChild::ActorDestroy(ActorDestroyReason why)
|
||||
// |if (mDead)| special case below and we're safe.
|
||||
mDead = true;
|
||||
mPrefObservers.Clear();
|
||||
|
||||
mAlertObservers.Clear();
|
||||
XRE_ShutdownChildProcess();
|
||||
}
|
||||
|
||||
@ -381,6 +416,15 @@ ContentChild::RemoveRemotePrefObserver(const nsCString& aDomain,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ContentChild::AddRemoteAlertObserver(const nsString& aData,
|
||||
nsIObserver* aObserver)
|
||||
{
|
||||
NS_ASSERTION(aObserver, "Adding a null observer?");
|
||||
mAlertObservers.AppendElement(new AlertObserver(aObserver, aData));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvNotifyRemotePrefObserver(const nsCString& aPref)
|
||||
{
|
||||
@ -399,6 +443,27 @@ ContentChild::RecvNotifyRemotePrefObserver(const nsCString& aPref)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData)
|
||||
{
|
||||
printf("ContentChild::RecvNotifyAlertsObserver %s\n", aType.get() );
|
||||
|
||||
for (PRUint32 i = 0; i < mAlertObservers.Length();
|
||||
/*we mutate the array during the loop; ++i iff no mutation*/) {
|
||||
AlertObserver* observer = mAlertObservers[i];
|
||||
if (observer->Observes(aData) && observer->Notify(aType)) {
|
||||
// if aType == alertfinished, this alert is done. we can
|
||||
// remove the observer.
|
||||
if (aType.Equals(nsDependentCString("alertfinished"))) {
|
||||
mAlertObservers.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvNotifyVisited(const IPC::URI& aURI)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ struct OverrideMapping;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AlertObserver;
|
||||
class PrefObserver;
|
||||
|
||||
class ContentChild : public PContentChild
|
||||
@ -101,8 +102,13 @@ public:
|
||||
const nsCString& aPrefRoot,
|
||||
nsIObserver* aObserver);
|
||||
|
||||
// auto remove when alertfinished is received.
|
||||
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
|
||||
|
||||
virtual bool RecvNotifyRemotePrefObserver(const nsCString& aDomain);
|
||||
|
||||
virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
|
||||
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON);
|
||||
|
||||
private:
|
||||
@ -118,6 +124,7 @@ private:
|
||||
*/
|
||||
NS_NORETURN void QuickExit();
|
||||
|
||||
nsTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
|
||||
nsTArray<nsAutoPtr<PrefObserver> > mPrefObservers;
|
||||
bool mDead;
|
||||
|
||||
|
@ -56,6 +56,8 @@
|
||||
#include "nsExternalHelperAppService.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsIAlertsService.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
@ -367,6 +369,13 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
if (!SendSetOffline(!strcmp(offline, "true") ? true : false))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
// listening for alert notifications
|
||||
else if (!strcmp(aTopic, "alertfinished") ||
|
||||
!strcmp(aTopic, "alertclickcallback") ) {
|
||||
if (!SendNotifyAlertsObserver(nsDependentCString(aTopic),
|
||||
nsDependentString(aData)))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -558,6 +567,19 @@ ContentParent::RecvNotifyIME(const int& aType, const int& aStatus)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
|
||||
const nsString& aText, const PRBool& aTextClickable,
|
||||
const nsString& aCookie, const nsString& aName)
|
||||
{
|
||||
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
|
||||
if (sysAlerts) {
|
||||
sysAlerts->ShowAlertNotification(aImageUrl, aTitle, aText, aTextClickable,
|
||||
aCookie, this, aName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvSyncMessage(const nsString& aMsg, const nsString& aJSON,
|
||||
|
@ -158,9 +158,11 @@ private:
|
||||
virtual bool RecvNotifyIME(const int&, const int&);
|
||||
|
||||
virtual bool RecvNotifyIMEChange(const nsString&, const PRUint32&, const int&,
|
||||
const int&, const int&)
|
||||
;
|
||||
const int&, const int&);
|
||||
|
||||
virtual bool RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
|
||||
const nsString& aText, const PRBool& aTextClickable,
|
||||
const nsString& aCookie, const nsString& aName);
|
||||
|
||||
virtual bool RecvLoadURIExternal(const IPC::URI& uri);
|
||||
|
||||
|
@ -87,27 +87,6 @@ parent:
|
||||
|
||||
Event(RemoteDOMEvent aEvent);
|
||||
|
||||
NotifyStateChange(PRUint32 stateFlags, nsresult status);
|
||||
|
||||
NotifyProgressChange(PRInt64 curSelfProgress,
|
||||
PRInt64 maxSelfProgress,
|
||||
PRInt64 curTotalProgress,
|
||||
PRInt64 maxTotalProgress);
|
||||
|
||||
NotifyLocationChange(nsCString uri);
|
||||
|
||||
NotifyStatusChange(nsresult status,
|
||||
nsString message);
|
||||
|
||||
NotifySecurityChange(PRUint32 aState,
|
||||
PRBool aUseSSLStatusObject,
|
||||
nsString aTooltip,
|
||||
nsCString aSecInfoAsString);
|
||||
|
||||
sync RefreshAttempted(nsCString uri, PRInt32 millis,
|
||||
bool sameURI) returns (bool retval);
|
||||
|
||||
|
||||
rpc CreateWindow() returns (PBrowser window);
|
||||
|
||||
sync SyncMessage(nsString aMessage, nsString aJSON)
|
||||
|
@ -71,6 +71,8 @@ child:
|
||||
|
||||
NotifyRemotePrefObserver(nsCString aDomain);
|
||||
|
||||
NotifyAlertsObserver(nsCString topic, nsString data);
|
||||
|
||||
parent:
|
||||
PNecko();
|
||||
|
||||
@ -101,6 +103,13 @@ parent:
|
||||
sync SyncMessage(nsString aMessage, nsString aJSON)
|
||||
returns (nsString[] retval);
|
||||
|
||||
ShowAlertNotification(nsString imageUrl,
|
||||
nsString title,
|
||||
nsString text,
|
||||
PRBool textClickable,
|
||||
nsString cookie,
|
||||
nsString name);
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, nsString aJSON);
|
||||
|
||||
|
@ -134,10 +134,6 @@ TabChild::Init()
|
||||
}
|
||||
|
||||
webBrowser->SetContainerWindow(this);
|
||||
nsCOMPtr<nsIWeakReference> weak =
|
||||
do_GetWeakReference(static_cast<nsSupportsWeakReference*>(this));
|
||||
webBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
|
||||
|
||||
mWebNav = do_QueryInterface(webBrowser);
|
||||
NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
|
||||
|
||||
@ -147,7 +143,6 @@ TabChild::Init()
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(TabChild)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebProgressListener2)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
|
||||
@ -155,11 +150,9 @@ NS_INTERFACE_MAP_BEGIN(TabChild)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener2)
|
||||
NS_INTERFACE_MAP_ENTRY(nsSupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITabChild)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDialogCreator)
|
||||
NS_INTERFACE_MAP_ENTRY(nsSupportsWeakReference)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(TabChild)
|
||||
@ -444,10 +437,6 @@ TabChild::ActorDestroy(ActorDestroyReason why)
|
||||
TabChild::~TabChild()
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(mWebNav);
|
||||
nsCOMPtr<nsIWeakReference> weak =
|
||||
do_GetWeakReference(static_cast<nsSupportsWeakReference*>(this));
|
||||
webBrowser->RemoveWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
|
||||
|
||||
if (webBrowser) {
|
||||
webBrowser->SetContainerWindow(nsnull);
|
||||
}
|
||||
@ -462,141 +451,6 @@ TabChild::~TabChild()
|
||||
mTabChildGlobal->mTabChild = nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnStateChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRUint32 aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
SendNotifyStateChange(aStateFlags, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Only one of OnProgressChange / OnProgressChange64 will be called.
|
||||
// According to interface, it should be OnProgressChange64, but looks
|
||||
// like docLoader only sends the former.
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
SendNotifyProgressChange(aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar* aMessage)
|
||||
{
|
||||
nsDependentString message(aMessage);
|
||||
SendNotifyStatusChange(aStatus, message);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRUint32 aState)
|
||||
{
|
||||
nsCString secInfoAsString;
|
||||
if (aState & nsIWebProgressListener::STATE_IS_SECURE) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (channel) {
|
||||
nsCOMPtr<nsISupports> secInfoSupports;
|
||||
channel->GetSecurityInfo(getter_AddRefs(secInfoSupports));
|
||||
|
||||
nsCOMPtr<nsISerializable> secInfoSerializable =
|
||||
do_QueryInterface(secInfoSupports);
|
||||
NS_SerializeToString(secInfoSerializable, secInfoAsString);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool useSSLStatusObject = PR_FALSE;
|
||||
nsAutoString securityTooltip;
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aWebProgress);
|
||||
if (docShell) {
|
||||
nsCOMPtr<nsISecureBrowserUI> secureUI;
|
||||
docShell->GetSecurityUI(getter_AddRefs(secureUI));
|
||||
if (secureUI) {
|
||||
secureUI->GetTooltipText(securityTooltip);
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsCOMPtr<nsISSLStatusProvider> provider = do_QueryInterface(secureUI);
|
||||
nsresult rv = provider->GetSSLStatus(getter_AddRefs(supports));
|
||||
if (NS_SUCCEEDED(rv) && supports) {
|
||||
/*
|
||||
* useSSLStatusObject: Security UI internally holds 4 states: secure, mixed,
|
||||
* broken, no security. In cases of secure, mixed and broken it holds reference
|
||||
* to a valid SSL status object. But, in case of the 'broken' state it doesn't
|
||||
* return the SSL status object (returns null), in contrary to the 'mixed' state
|
||||
* for which it returns.
|
||||
*
|
||||
* However, mixed and broken states are both reported to the upper level
|
||||
* as nsIWebProgressListener::STATE_IS_BROKEN, i.e. states are merged,
|
||||
* so we cannot determine, if to return the status object or not.
|
||||
*
|
||||
* TabParent is extracting the SSL status object from the security info
|
||||
* serialization (string). SSL status object is always present there
|
||||
* even security UI implementation doesn't present it. This argument
|
||||
* tells the parent if the SSL status object is being presented by
|
||||
* the security UI here, on the child process, and so if it has to be
|
||||
* presented also on the parent process.
|
||||
*/
|
||||
useSSLStatusObject = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendNotifySecurityChange(aState, useSSLStatusObject, securityTooltip,
|
||||
secInfoAsString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *aLocation)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLocation);
|
||||
nsCString uri;
|
||||
aLocation->GetSpec(uri);
|
||||
SendNotifyLocationChange(uri);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnProgressChange64(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt64 aCurSelfProgress,
|
||||
PRInt64 aMaxSelfProgress,
|
||||
PRInt64 aCurTotalProgress,
|
||||
PRInt64 aMaxTotalProgress)
|
||||
{
|
||||
SendNotifyProgressChange(aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnRefreshAttempted(nsIWebProgress *aWebProgress,
|
||||
nsIURI *aURI, PRInt32 aMillis,
|
||||
PRBool aSameURL, PRBool *aRefreshAllowed)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
nsCString uri;
|
||||
aURI->GetSpec(uri);
|
||||
bool sameURL = aSameURL;
|
||||
bool refreshAllowed;
|
||||
SendRefreshAttempted(uri, aMillis, sameURL, &refreshAllowed);
|
||||
*aRefreshAllowed = refreshAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvLoadURL(const nsCString& uri)
|
||||
{
|
||||
|
@ -48,8 +48,6 @@
|
||||
#include "nsIWebBrowserChrome2.h"
|
||||
#include "nsIEmbeddingSiteWindow2.h"
|
||||
#include "nsIWebBrowserChromeFocus.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebProgressListener2.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
@ -150,7 +148,6 @@ protected:
|
||||
|
||||
class TabChild : public PBrowserChild,
|
||||
public nsFrameScriptExecutor,
|
||||
public nsIWebProgressListener2,
|
||||
public nsIWebBrowserChrome2,
|
||||
public nsIEmbeddingSiteWindow2,
|
||||
public nsIWebBrowserChromeFocus,
|
||||
@ -168,8 +165,6 @@ public:
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER2
|
||||
NS_DECL_NSIWEBBROWSERCHROME
|
||||
NS_DECL_NSIWEBBROWSERCHROME2
|
||||
NS_DECL_NSIEMBEDDINGSITEWINDOW
|
||||
|
@ -59,7 +59,6 @@
|
||||
#include "TabChild.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIWebProgressListener2.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "jsarray.h"
|
||||
@ -89,10 +88,10 @@ using namespace mozilla::layout;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS5(TabParent, nsITabParent, nsIWebProgress, nsIAuthPromptProvider, nsISSLStatusProvider, nsISecureBrowserUI)
|
||||
NS_IMPL_ISUPPORTS4(TabParent, nsITabParent, nsIAuthPromptProvider, nsISSLStatusProvider, nsISecureBrowserUI)
|
||||
|
||||
TabParent::TabParent()
|
||||
: mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE)
|
||||
: mSecurityState(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -137,269 +136,6 @@ TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyProgressChange(const PRInt64& aProgress,
|
||||
const PRInt64& aProgressMax,
|
||||
const PRInt64& aTotalProgress,
|
||||
const PRInt64& aMaxTotalProgress)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new progress info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener2> listener2 =
|
||||
do_QueryReferent(info->mWeakListener);
|
||||
if (listener2) {
|
||||
listener2->OnProgressChange64(this, nsnull, aProgress, aProgressMax,
|
||||
aTotalProgress, aMaxTotalProgress);
|
||||
} else {
|
||||
listener->OnProgressChange(this, nsnull, PRInt32(aProgress),
|
||||
PRInt32(aProgressMax),
|
||||
PRInt32(aTotalProgress),
|
||||
PRInt32(aMaxTotalProgress));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyStateChange(const PRUint32& aStateFlags,
|
||||
const nsresult& aStatus)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
|
||||
// The flags used in listener registration are shifted over
|
||||
// 16 bits from the ones sent in the notification, so we shift
|
||||
// to see if the listener is interested in this change.
|
||||
// Note that the flags are not changed in the notification we
|
||||
// send along. Flags are defined in nsIWebProgressListener and
|
||||
// nsIWebProgress.
|
||||
// See nsDocLoader for another example of this.
|
||||
if (!(info->mNotifyMask & (aStateFlags >> NOTIFY_FLAG_SHIFT))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnStateChange(this, nsnull, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyLocationChange(const nsCString& aUri)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnLocationChange(this, nsnull, uri);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyStatusChange(const nsresult& status,
|
||||
const nsString& message)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnStatusChange(this, nsnull, status, message.BeginReading());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifySecurityChange(const PRUint32& aState,
|
||||
const PRBool& aUseSSLStatusObject,
|
||||
const nsString& aTooltip,
|
||||
const nsCString& aSecInfoAsString)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
|
||||
mSecurityState = aState;
|
||||
mSecurityTooltipText = aTooltip;
|
||||
|
||||
if (!aSecInfoAsString.IsEmpty()) {
|
||||
nsCOMPtr<nsISupports> secInfoSupports;
|
||||
nsresult rv = NS_DeserializeObject(aSecInfoAsString, getter_AddRefs(secInfoSupports));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIIdentityInfo> idInfo = do_QueryInterface(secInfoSupports);
|
||||
if (idInfo) {
|
||||
PRBool isEV;
|
||||
if (NS_SUCCEEDED(idInfo->GetIsExtendedValidation(&isEV)) && isEV)
|
||||
mSecurityState |= nsIWebProgressListener::STATE_IDENTITY_EV_TOPLEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
mSecurityStatusObject = nsnull;
|
||||
if (aUseSSLStatusObject)
|
||||
{
|
||||
nsCOMPtr<nsISSLStatusProvider> sslStatusProvider =
|
||||
do_QueryInterface(secInfoSupports);
|
||||
if (sslStatusProvider)
|
||||
sslStatusProvider->GetSSLStatus(getter_AddRefs(mSecurityStatusObject));
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnSecurityChange(this, nsnull, mSecurityState);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvRefreshAttempted(const nsCString& aURI, const PRInt32& aMillis,
|
||||
const bool& aSameURI, bool* refreshAllowed)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
*refreshAllowed = true;
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener2> listener2 =
|
||||
do_QueryReferent(info->mWeakListener);
|
||||
if (!listener2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// some listeners don't seem to set this at all...
|
||||
PRBool allowed = true;
|
||||
listener2->OnRefreshAttempted(this, uri,
|
||||
aMillis, aSameURI, &allowed);
|
||||
*refreshAllowed = allowed && *refreshAllowed;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::AnswerCreateWindow(PBrowserParent** retval)
|
||||
{
|
||||
@ -465,6 +201,7 @@ NS_IMETHODIMP
|
||||
TabParent::GetState(PRUint32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG(aState);
|
||||
NS_WARNING("SecurityState not valid here");
|
||||
*aState = mSecurityState;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -635,71 +372,6 @@ TabParent::ReceiveMessage(const nsString& aMessage,
|
||||
return true;
|
||||
}
|
||||
|
||||
// nsIWebProgress
|
||||
nsresult
|
||||
TabParent::AddProgressListener(nsIWebProgressListener* aListener,
|
||||
PRUint32 aNotifyMask)
|
||||
{
|
||||
if (GetListenerInfo(aListener)) {
|
||||
// The listener is already registered!
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsWeakPtr listener = do_GetWeakReference(aListener);
|
||||
if (!listener) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
TabParentListenerInfo info(listener, aNotifyMask);
|
||||
|
||||
if (!mListenerInfoList.AppendElement(info))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::RemoveProgressListener(nsIWebProgressListener *aListener)
|
||||
{
|
||||
nsAutoPtr<TabParentListenerInfo> info(GetListenerInfo(aListener));
|
||||
|
||||
return info && mListenerInfoList.RemoveElement(*info) ?
|
||||
NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
TabParentListenerInfo *
|
||||
TabParent::GetListenerInfo(nsIWebProgressListener *aListener)
|
||||
{
|
||||
PRUint32 i, count;
|
||||
TabParentListenerInfo *info;
|
||||
|
||||
nsCOMPtr<nsISupports> listener1 = do_QueryInterface(aListener);
|
||||
count = mListenerInfoList.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
info = &mListenerInfoList[i];
|
||||
|
||||
if (info) {
|
||||
nsCOMPtr<nsISupports> listener2 = do_QueryReferent(info->mWeakListener);
|
||||
if (listener1 == listener2) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::GetDOMWindow(nsIDOMWindow **aResult)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::GetIsLoadingDocument(PRBool *aIsLoadingDocument)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// nsIAuthPromptProvider
|
||||
|
||||
// This method is largely copied from nsDocShell::GetAuthPrompt
|
||||
|
@ -48,8 +48,6 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITabParent.h"
|
||||
#include "nsIBrowserDOMWindow.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIDialogParamBlock.h"
|
||||
#include "nsIAuthPromptProvider.h"
|
||||
@ -66,34 +64,11 @@ struct JSObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
struct TabParentListenerInfo
|
||||
{
|
||||
TabParentListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask)
|
||||
: mWeakListener(aListener), mNotifyMask(aNotifyMask)
|
||||
{
|
||||
}
|
||||
|
||||
TabParentListenerInfo(const TabParentListenerInfo& obj)
|
||||
: mWeakListener(obj.mWeakListener), mNotifyMask(obj.mNotifyMask)
|
||||
{
|
||||
}
|
||||
|
||||
nsWeakPtr mWeakListener;
|
||||
|
||||
PRUint32 mNotifyMask;
|
||||
};
|
||||
|
||||
inline
|
||||
bool operator==(const TabParentListenerInfo& lhs, const TabParentListenerInfo& rhs)
|
||||
{
|
||||
return &lhs == &rhs;
|
||||
}
|
||||
|
||||
class ContentDialogParent : public PContentDialogParent {};
|
||||
|
||||
class TabParent : public PBrowserParent
|
||||
, public nsITabParent
|
||||
, public nsIWebProgress
|
||||
, public nsIAuthPromptProvider
|
||||
, public nsISecureBrowserUI
|
||||
, public nsISSLStatusProvider
|
||||
@ -110,24 +85,6 @@ public:
|
||||
|
||||
virtual bool RecvMoveFocus(const bool& aForward);
|
||||
virtual bool RecvEvent(const RemoteDOMEvent& aEvent);
|
||||
virtual bool RecvNotifyProgressChange(const PRInt64& aProgress,
|
||||
const PRInt64& aProgressMax,
|
||||
const PRInt64& aTotalProgress,
|
||||
const PRInt64& aMaxTotalProgress);
|
||||
virtual bool RecvNotifyStateChange(const PRUint32& aStateFlags,
|
||||
const nsresult& aStatus);
|
||||
virtual bool RecvNotifyLocationChange(const nsCString& aUri);
|
||||
virtual bool RecvNotifyStatusChange(const nsresult& status,
|
||||
const nsString& message);
|
||||
virtual bool RecvNotifySecurityChange(const PRUint32& aState,
|
||||
const PRBool& aUseSSLStatusObject,
|
||||
const nsString& aTooltip,
|
||||
const nsCString& aSecInfoAsString);
|
||||
|
||||
virtual bool RecvRefreshAttempted(const nsCString& aURI,
|
||||
const PRInt32& aMillis,
|
||||
const bool& aSameURI,
|
||||
bool* aAllowRefresh);
|
||||
|
||||
virtual bool AnswerCreateWindow(PBrowserParent** retval);
|
||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||
@ -210,7 +167,6 @@ public:
|
||||
JSBool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESS
|
||||
NS_DECL_NSIAUTHPROMPTPROVIDER
|
||||
NS_DECL_NSISECUREBROWSERUI
|
||||
NS_DECL_NSISSLSTATUSPROVIDER
|
||||
@ -222,15 +178,11 @@ protected:
|
||||
const nsString& aJSON,
|
||||
nsTArray<nsString>* aJSONRetVal = nsnull);
|
||||
|
||||
TabParentListenerInfo* GetListenerInfo(nsIWebProgressListener *aListener);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
nsIDOMElement* mFrameElement;
|
||||
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
|
||||
|
||||
nsTArray<TabParentListenerInfo> mListenerInfoList;
|
||||
|
||||
struct DelayedDialogData
|
||||
{
|
||||
DelayedDialogData(PContentDialogParent* aDialog, PRUint32 aType,
|
||||
|
@ -52,10 +52,30 @@ using NPRect;
|
||||
using NPNURLVariable;
|
||||
using NPCoordinateSpace;
|
||||
using mozilla::plugins::NativeWindowHandle;
|
||||
using mozilla::gfxSurfaceType;
|
||||
using gfxIntSize;
|
||||
using mozilla::null_t;
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
struct SurfaceDescriptorX11 {
|
||||
int XID;
|
||||
int xrenderPictID;
|
||||
gfxIntSize size;
|
||||
};
|
||||
|
||||
union SurfaceDescriptor {
|
||||
Shmem;
|
||||
SurfaceDescriptorX11;
|
||||
// Descriptor can be null here in case
|
||||
// 1) of first Show call (prevSurface is null)
|
||||
// 2) when child is going to destroy
|
||||
// and it just want to grab prevSurface
|
||||
// back without giving new surface
|
||||
null_t;
|
||||
};
|
||||
|
||||
rpc protocol PPluginInstance
|
||||
{
|
||||
manager PPluginModule;
|
||||
@ -92,6 +112,20 @@ child:
|
||||
// this is only used on windows to forward WM_WINDOWPOSCHANGE
|
||||
async WindowPosChanged(NPRemoteEvent event);
|
||||
|
||||
// ********************** Async plugins rendering
|
||||
// see https://wiki.mozilla.org/Gecko:AsyncPluginPainting
|
||||
// **********************
|
||||
|
||||
// Plugin parent notify child that plugin frame
|
||||
// has been painted to the screen
|
||||
async PaintFinished();
|
||||
|
||||
// Async version of SetWindow call
|
||||
// @param surfaceType - gfxASurface::gfxSurfaceType
|
||||
// plugin child must create offscreen buffer
|
||||
// with type equals to surfaceType
|
||||
async AsyncSetWindow(gfxSurfaceType surfaceType, NPRemoteWindow window);
|
||||
|
||||
rpc NPP_Destroy()
|
||||
returns (NPError rv);
|
||||
|
||||
@ -134,6 +168,16 @@ parent:
|
||||
|
||||
async NPN_InvalidateRect(NPRect rect);
|
||||
|
||||
// Give |newSurface|, containing this instance's updated pixels, to
|
||||
// the browser for compositing. Get back |prevSurface|, containing
|
||||
// old pixels, to be recycled
|
||||
// @param rect - actually updated rectangle, comparing to prevSurface content
|
||||
// could be used for partial render of layer to topLevel context
|
||||
// @param newSurface - remotable surface
|
||||
// @param prevSurface - return surface for recycling
|
||||
sync Show(NPRect updatedRect, SurfaceDescriptor newSurface)
|
||||
returns (SurfaceDescriptor prevSurface);
|
||||
|
||||
rpc NPN_PushPopupsEnabledState(bool aState);
|
||||
|
||||
rpc NPN_PopPopupsEnabledState();
|
||||
|
@ -43,6 +43,14 @@
|
||||
#include "PluginStreamChild.h"
|
||||
#include "StreamNotifyChild.h"
|
||||
#include "PluginProcessChild.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxContext.h"
|
||||
#ifdef MOZ_X11
|
||||
#include "gfxXlibSurface.h"
|
||||
#endif
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "gfxAlphaRecovery.h"
|
||||
|
||||
#include "mozilla/ipc/SyncChannel.h"
|
||||
|
||||
@ -90,6 +98,13 @@ const int kFlashWMUSERMessageThrottleDelayMs = 5;
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif // defined(XP_MACOSX)
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<PluginInstanceChild>
|
||||
{
|
||||
static void RetainCallee(PluginInstanceChild* obj) { }
|
||||
static void ReleaseCallee(PluginInstanceChild* obj) { }
|
||||
};
|
||||
|
||||
PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
||||
const nsCString& aMimeType)
|
||||
: mPluginIface(aPluginIface)
|
||||
@ -111,6 +126,18 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
||||
, mShContext(nsnull)
|
||||
, mDrawingModel(NPDrawingModelCoreGraphics)
|
||||
, mCurrentEvent(nsnull)
|
||||
#endif
|
||||
, mLayersRendering(PR_FALSE)
|
||||
, mAccumulatedInvalidRect(0,0,0,0)
|
||||
, mIsTransparent(PR_FALSE)
|
||||
, mSurfaceType(gfxASurface::SurfaceTypeMax)
|
||||
, mPendingForcePaint(PR_FALSE)
|
||||
, mCurrentInvalidateTask(nsnull)
|
||||
, mPendingPluginCall(PR_FALSE)
|
||||
, mDoAlphaExtraction(PR_FALSE)
|
||||
, mSurfaceDifferenceRect(0,0,0,0)
|
||||
#ifdef MOZ_X11
|
||||
, mFlash10Quirks(PR_FALSE)
|
||||
#endif
|
||||
{
|
||||
memset(&mWindow, 0, sizeof(mWindow));
|
||||
@ -128,6 +155,15 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
||||
#if defined(OS_WIN)
|
||||
InitPopupMenuHook();
|
||||
#endif // OS_WIN
|
||||
#ifdef MOZ_X11
|
||||
const char *description = NULL;
|
||||
mPluginIface->getvalue(GetNPP(), NPPVpluginDescriptionString,
|
||||
&description);
|
||||
if (description) {
|
||||
NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
|
||||
mFlash10Quirks = StringBeginsWith(nsDependentCString(description), flash10Head);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PluginInstanceChild::~PluginInstanceChild()
|
||||
@ -401,9 +437,9 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
|
||||
|
||||
case NPPVpluginTransparentBool: {
|
||||
NPError rv;
|
||||
bool transparent = (NPBool) (intptr_t) aValue;
|
||||
mIsTransparent = (NPBool) (intptr_t) aValue;
|
||||
|
||||
if (!CallNPN_SetValue_NPPVpluginTransparent(transparent, &rv))
|
||||
if (!CallNPN_SetValue_NPPVpluginTransparent(mIsTransparent, &rv))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
return rv;
|
||||
@ -814,6 +850,8 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
&mWsInfo.visual, &mWsInfo.depth))
|
||||
return false;
|
||||
|
||||
mLayersRendering = PR_FALSE;
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
if (gtk_check_version(2,18,7) != NULL) { // older
|
||||
if (aWindow.type == NPWindowTypeWindow) {
|
||||
@ -1938,6 +1976,460 @@ PluginInstanceChild::NPN_NewStream(NPMIMEType aMIMEType, const char* aWindow,
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::RecvPaintFinished(void)
|
||||
{
|
||||
if (mPendingForcePaint) {
|
||||
nsIntRect r(0, 0, mWindow.width, mWindow.height);
|
||||
mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect);
|
||||
mPendingForcePaint = PR_FALSE;
|
||||
}
|
||||
if (!mAccumulatedInvalidRect.IsEmpty()) {
|
||||
AsyncShowPluginFrame();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
|
||||
const NPRemoteWindow& aWindow)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
if (mWindow.width != aWindow.width || mWindow.height != aWindow.height) {
|
||||
mCurrentSurface = nsnull;
|
||||
mHelperSurface = nsnull;
|
||||
mPendingForcePaint = PR_TRUE;
|
||||
}
|
||||
mWindow.x = aWindow.x;
|
||||
mWindow.y = aWindow.y;
|
||||
mWindow.width = aWindow.width;
|
||||
mWindow.height = aWindow.height;
|
||||
mWindow.clipRect = aWindow.clipRect;
|
||||
mWindow.type = aWindow.type;
|
||||
|
||||
mLayersRendering = PR_TRUE;
|
||||
mSurfaceType = aSurfaceType;
|
||||
UpdateWindowAttributes(PR_TRUE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline gfxRect
|
||||
GfxFromNsRect(const nsIntRect& aRect)
|
||||
{
|
||||
return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
PRBool
|
||||
PluginInstanceChild::CreateOptSurface(void)
|
||||
{
|
||||
nsRefPtr<gfxASurface> retsurf;
|
||||
gfxASurface::gfxImageFormat format =
|
||||
mIsTransparent ? gfxASurface::ImageFormatARGB32 :
|
||||
gfxASurface::ImageFormatRGB24;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
Display* dpy = mWsInfo.display;
|
||||
Screen* screen = DefaultScreenOfDisplay(dpy);
|
||||
if (format == gfxASurface::ImageFormatRGB24 &&
|
||||
DefaultDepth(dpy, DefaultScreen(dpy)) == 16) {
|
||||
format = gfxASurface::ImageFormatRGB16_565;
|
||||
}
|
||||
|
||||
if (mSurfaceType == gfxASurface::SurfaceTypeXlib) {
|
||||
XRenderPictFormat* xfmt = gfxXlibSurface::FindRenderFormat(dpy, format);
|
||||
if (!xfmt) {
|
||||
NS_ERROR("Need X falback surface, but FindRenderFormat failed");
|
||||
return PR_FALSE;
|
||||
}
|
||||
mCurrentSurface =
|
||||
gfxXlibSurface::Create(screen, xfmt,
|
||||
gfxIntSize(mWindow.width,
|
||||
mWindow.height));
|
||||
return mCurrentSurface != nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make common shmem implementation working for any platform
|
||||
mCurrentSurface = new gfxSharedImageSurface();
|
||||
if (NS_FAILED(static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->
|
||||
Init(this, gfxIntSize(mWindow.width, mWindow.height), format))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
PluginInstanceChild::MaybeCreatePlatformHelperSurface(void)
|
||||
{
|
||||
if (!mCurrentSurface) {
|
||||
NS_ERROR("Cannot create helper surface without mCurrentSurface");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifdef MOZ_PLATFORM_MAEMO
|
||||
// On maemo plugins support non-default visual rendering
|
||||
PRBool supportNonDefaultVisual = PR_TRUE;
|
||||
#else
|
||||
PRBool supportNonDefaultVisual = PR_FALSE;
|
||||
#endif
|
||||
#ifdef MOZ_X11
|
||||
Screen* screen = DefaultScreenOfDisplay(mWsInfo.display);
|
||||
Visual* defaultVisual = DefaultVisualOfScreen(screen);
|
||||
Visual* visual = nsnull;
|
||||
Colormap colormap = 0;
|
||||
mDoAlphaExtraction = PR_FALSE;
|
||||
PRBool createHelperSurface = PR_FALSE;
|
||||
|
||||
if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||
static_cast<gfxXlibSurface*>(mCurrentSurface.get())->
|
||||
GetColormapAndVisual(&colormap, &visual);
|
||||
// Create helper surface if layer surface visual not same as default
|
||||
// and we don't support non-default visual rendering
|
||||
if (!visual || (defaultVisual != visual && !supportNonDefaultVisual)) {
|
||||
createHelperSurface = PR_TRUE;
|
||||
visual = defaultVisual;
|
||||
mDoAlphaExtraction = mIsTransparent;
|
||||
}
|
||||
} else if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
// For image layer surface we should always create helper surface
|
||||
createHelperSurface = PR_TRUE;
|
||||
// Check if we can create helper surface with non-default visual
|
||||
visual = gfxXlibSurface::FindVisual(screen,
|
||||
static_cast<gfxImageSurface*>(mCurrentSurface.get())->Format());
|
||||
if (visual && defaultVisual != visual && !supportNonDefaultVisual) {
|
||||
visual = defaultVisual;
|
||||
mDoAlphaExtraction = mIsTransparent;
|
||||
}
|
||||
}
|
||||
|
||||
if (createHelperSurface) {
|
||||
if (!visual) {
|
||||
NS_ERROR("Need X falback surface, but visual failed");
|
||||
return PR_FALSE;
|
||||
}
|
||||
mHelperSurface =
|
||||
gfxXlibSurface::Create(screen, visual,
|
||||
mCurrentSurface->GetSize());
|
||||
if (!mHelperSurface) {
|
||||
NS_WARNING("Fail to create create helper surface");
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
PluginInstanceChild::EnsureCurrentBuffer(void)
|
||||
{
|
||||
if (mCurrentSurface) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (!mWindow.width || !mWindow.height) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!CreateOptSurface()) {
|
||||
NS_ERROR("Cannot create optimized surface");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!MaybeCreatePlatformHelperSurface()) {
|
||||
NS_ERROR("Cannot create helper surface");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::UpdateWindowAttributes(PRBool aForceSetWindow)
|
||||
{
|
||||
nsRefPtr<gfxASurface> curSurface = mHelperSurface ? mHelperSurface : mCurrentSurface;
|
||||
PRBool needWindowUpdate = aForceSetWindow;
|
||||
#ifdef MOZ_X11
|
||||
Visual* visual = nsnull;
|
||||
Colormap colormap = 0;
|
||||
if (curSurface && curSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||
static_cast<gfxXlibSurface*>(curSurface.get())->
|
||||
GetColormapAndVisual(&colormap, &visual);
|
||||
if (visual != mWsInfo.visual || colormap != mWsInfo.colormap) {
|
||||
mWsInfo.visual = visual;
|
||||
mWsInfo.colormap = colormap;
|
||||
needWindowUpdate = PR_TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!needWindowUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The clip rect is relative to drawable top-left.
|
||||
nsIntRect clipRect;
|
||||
mWindow.x = mWindow.y = 0;
|
||||
clipRect.SetRect(mWindow.x, mWindow.y, mWindow.width, mWindow.height);
|
||||
// Don't ask the plugin to draw outside the drawable.
|
||||
// This also ensures that the unsigned clip rectangle offsets won't be -ve.
|
||||
|
||||
NPRect newClipRect;
|
||||
newClipRect.left = clipRect.x;
|
||||
newClipRect.top = clipRect.y;
|
||||
newClipRect.right = clipRect.XMost();
|
||||
newClipRect.bottom = clipRect.YMost();
|
||||
mWindow.clipRect = newClipRect;
|
||||
|
||||
if (mPluginIface->setwindow) {
|
||||
mPluginIface->setwindow(&mData, &mWindow);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
|
||||
gfxASurface* aSurface)
|
||||
{
|
||||
UpdateWindowAttributes();
|
||||
#ifdef MOZ_X11
|
||||
NS_ASSERTION(aSurface->GetType() == gfxASurface::SurfaceTypeXlib,
|
||||
"Non supported platform surface type");
|
||||
|
||||
mPendingPluginCall = PR_TRUE;
|
||||
NPEvent pluginEvent;
|
||||
XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
|
||||
exposeEvent.type = GraphicsExpose;
|
||||
exposeEvent.display = mWsInfo.display;
|
||||
exposeEvent.drawable = static_cast<gfxXlibSurface*>(aSurface)->XDrawable();
|
||||
exposeEvent.x = aRect.x;
|
||||
exposeEvent.y = aRect.y;
|
||||
exposeEvent.width = aRect.width;
|
||||
exposeEvent.height = aRect.height;
|
||||
exposeEvent.count = 0;
|
||||
// information not set:
|
||||
exposeEvent.serial = 0;
|
||||
exposeEvent.send_event = False;
|
||||
exposeEvent.major_code = 0;
|
||||
exposeEvent.minor_code = 0;
|
||||
mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
|
||||
mPendingPluginCall = PR_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::PaintRectToSurface(const nsIntRect& aRect,
|
||||
gfxASurface* aSurface,
|
||||
const gfxRGBA& aColor)
|
||||
{
|
||||
// Render using temporary X surface, with copy to image surface
|
||||
nsIntRect plPaintRect(aRect);
|
||||
nsRefPtr<gfxASurface> renderSurface = aSurface;
|
||||
#ifdef MOZ_X11
|
||||
if (mIsTransparent && mFlash10Quirks) {
|
||||
// Work around a bug in Flash up to 10.1 d51 at least, where expose event
|
||||
// top left coordinates within the plugin-rect and not at the drawable
|
||||
// origin are misinterpreted. (We can move the top left coordinate
|
||||
// provided it is within the clipRect.), see bug 574583
|
||||
plPaintRect.SetRect(0, 0, aRect.XMost(), aRect.YMost());
|
||||
}
|
||||
if (renderSurface->GetType() != gfxASurface::SurfaceTypeXlib) {
|
||||
// On X11 we can paint to non Xlib surface only with HelperSurface
|
||||
renderSurface = mHelperSurface;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mIsTransparent) {
|
||||
// Clear surface content for transparent rendering
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(renderSurface);
|
||||
ctx->SetColor(aColor);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->Rectangle(GfxFromNsRect(plPaintRect));
|
||||
ctx->Fill();
|
||||
}
|
||||
|
||||
PaintRectToPlatformSurface(plPaintRect, renderSurface);
|
||||
|
||||
if (renderSurface != aSurface) {
|
||||
// Copy helper surface content to target
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
|
||||
ctx->SetSource(renderSurface);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->Rectangle(GfxFromNsRect(aRect));
|
||||
ctx->Fill();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect,
|
||||
gfxASurface* aSurface)
|
||||
{
|
||||
// Paint onto black image
|
||||
PRBool needImageSurface = PR_TRUE;
|
||||
nsRefPtr<gfxImageSurface> blackImage;
|
||||
gfxIntSize clipSize(aRect.width, aRect.height);
|
||||
gfxPoint deviceOffset(-aRect.x, -aRect.y);
|
||||
// Try to re-use existing image surface, and avoid one copy
|
||||
if (aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
gfxImageSurface *surface = static_cast<gfxImageSurface*>(aSurface);
|
||||
if (surface->Format() == gfxASurface::ImageFormatARGB32) {
|
||||
needImageSurface = PR_FALSE;
|
||||
blackImage = surface->GetSubimage(GfxFromNsRect(aRect));
|
||||
}
|
||||
}
|
||||
// otherwise create new helper surface
|
||||
if (needImageSurface) {
|
||||
blackImage = new gfxImageSurface(clipSize, gfxASurface::ImageFormatARGB32);
|
||||
}
|
||||
|
||||
// Paint to black image
|
||||
blackImage->SetDeviceOffset(deviceOffset);
|
||||
PaintRectToSurface(aRect, blackImage, gfxRGBA(0.0, 0.0, 0.0));
|
||||
|
||||
// Paint onto white image
|
||||
nsRefPtr<gfxImageSurface> whiteImage =
|
||||
new gfxImageSurface(clipSize, gfxASurface::ImageFormatRGB24);
|
||||
|
||||
whiteImage->SetDeviceOffset(deviceOffset);
|
||||
PaintRectToSurface(aRect, whiteImage, gfxRGBA(1.0, 1.0, 1.0));
|
||||
|
||||
// Extract Alpha from black and white image and store to black Image
|
||||
gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage, nsnull)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (needImageSurface) {
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(blackImage);
|
||||
ctx->Rectangle(GfxFromNsRect(aRect));
|
||||
ctx->Fill();
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
PluginInstanceChild::ShowPluginFrame()
|
||||
{
|
||||
if (mPendingPluginCall) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!EnsureCurrentBuffer()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Make expose rect not bigger than clip rect
|
||||
mAccumulatedInvalidRect.IntersectRect(mAccumulatedInvalidRect,
|
||||
nsIntRect(mWindow.clipRect.left, mWindow.clipRect.top,
|
||||
mWindow.clipRect.right - mWindow.clipRect.left,
|
||||
mWindow.clipRect.bottom - mWindow.clipRect.top));
|
||||
|
||||
// Cleare accRect here to be able to pass test_invalidate_during_plugin_paint test
|
||||
nsIntRect rect = mAccumulatedInvalidRect;
|
||||
mAccumulatedInvalidRect.Empty();
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// We can read safetly from XSurface, because PluginHost is not able to modify that surface
|
||||
if (mBackSurface && mBackSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||
if (!mSurfaceDifferenceRect.IsEmpty()) {
|
||||
// Read back previous content
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mCurrentSurface);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(mBackSurface);
|
||||
// Subtract from mSurfaceDifferenceRect area which is overlapping with rect
|
||||
nsIntRegion result;
|
||||
result.Sub(mSurfaceDifferenceRect, nsIntRegion(rect));
|
||||
nsIntRegionRectIterator iter(result);
|
||||
const nsIntRect* r;
|
||||
while ((r = iter.Next()) != nsnull) {
|
||||
ctx->Rectangle(GfxFromNsRect(*r));
|
||||
}
|
||||
ctx->Fill();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Just repaint whole plugin, because we cannot read back from Shmem which is owned by another process
|
||||
rect.SetRect(0, 0, mWindow.width, mWindow.height);
|
||||
}
|
||||
|
||||
if (mDoAlphaExtraction) {
|
||||
PaintRectWithAlphaExtraction(rect, mCurrentSurface);
|
||||
} else {
|
||||
PaintRectToSurface(rect, mCurrentSurface, gfxRGBA(0.0, 0.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
NPRect r = { rect.y, rect.x, rect.YMost(), rect.XMost() };
|
||||
SurfaceDescriptor currSurf;
|
||||
SurfaceDescriptor outSurf = null_t();
|
||||
#ifdef MOZ_X11
|
||||
if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||
gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(mCurrentSurface.get());
|
||||
currSurf = SurfaceDescriptorX11(xsurf->XDrawable(), xsurf->XRenderFormat()->id,
|
||||
mCurrentSurface->GetSize());
|
||||
// Need to sync all pending x-paint requests
|
||||
// before giving drawable to another process
|
||||
XSync(mWsInfo.display, False);
|
||||
} else
|
||||
#endif
|
||||
if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface)) {
|
||||
currSurf = static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem();
|
||||
} else {
|
||||
NS_RUNTIMEABORT("Surface type is not remotable");
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (!SendShow(r, currSurf, &outSurf)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> tmp = mCurrentSurface;
|
||||
mCurrentSurface = mBackSurface;
|
||||
mBackSurface = tmp;
|
||||
// Outdated back surface... not usable anymore due to changed plugin size.
|
||||
// Dropping obsolete surface
|
||||
if (mCurrentSurface && mBackSurface &&
|
||||
mCurrentSurface->GetSize() != mBackSurface->GetSize()) {
|
||||
mCurrentSurface = nsnull;
|
||||
}
|
||||
mSurfaceDifferenceRect = rect;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::InvalidateRectDelayed(void)
|
||||
{
|
||||
if (!mCurrentInvalidateTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCurrentInvalidateTask = nsnull;
|
||||
if (mAccumulatedInvalidRect.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ShowPluginFrame()) {
|
||||
AsyncShowPluginFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::AsyncShowPluginFrame(void)
|
||||
{
|
||||
if (mCurrentInvalidateTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCurrentInvalidateTask =
|
||||
NewRunnableMethod(this, &PluginInstanceChild::InvalidateRectDelayed);
|
||||
MessageLoop::current()->PostTask(FROM_HERE, mCurrentInvalidateTask);
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
|
||||
{
|
||||
@ -1954,6 +2446,17 @@ PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mLayersRendering) {
|
||||
nsIntRect r(aInvalidRect->left, aInvalidRect->top,
|
||||
aInvalidRect->right - aInvalidRect->left,
|
||||
aInvalidRect->bottom - aInvalidRect->top);
|
||||
|
||||
mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect);
|
||||
// If we are able to paint and invalidate sent, then reset
|
||||
// accumulated rectangle
|
||||
AsyncShowPluginFrame();
|
||||
return;
|
||||
}
|
||||
SendNPN_InvalidateRect(*aInvalidRect);
|
||||
}
|
||||
|
||||
@ -2031,6 +2534,19 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
|
||||
PLUGIN_LOG_DEBUG_METHOD;
|
||||
AssertPluginThread();
|
||||
|
||||
if (mBackSurface) {
|
||||
// Get last surface back, and drop it
|
||||
SurfaceDescriptor temp = null_t();
|
||||
NPRect r = { 0, 0, 1, 1 };
|
||||
SendShow(r, temp, &temp);
|
||||
}
|
||||
if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface))
|
||||
DeallocShmem(static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem());
|
||||
if (gfxSharedImageSurface::IsSharedImage(mBackSurface))
|
||||
DeallocShmem(static_cast<gfxSharedImageSurface*>(mBackSurface.get())->GetShmem());
|
||||
mCurrentSurface = nsnull;
|
||||
mBackSurface = nsnull;
|
||||
|
||||
nsTArray<PBrowserStreamChild*> streams;
|
||||
ManagedPBrowserStreamChild(streams);
|
||||
|
||||
@ -2052,6 +2568,10 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
|
||||
}
|
||||
|
||||
mTimers.Clear();
|
||||
if (mCurrentInvalidateTask) {
|
||||
mCurrentInvalidateTask->Cancel();
|
||||
mCurrentInvalidateTask = nsnull;
|
||||
}
|
||||
|
||||
PluginModuleChild::current()->NPP_Destroy(this);
|
||||
mData.ndata = 0;
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "nsRect.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "mozilla/PaintTracker.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
@ -97,6 +98,12 @@ protected:
|
||||
virtual bool
|
||||
AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event, const uint32_t& surface, int16_t* handled);
|
||||
|
||||
// Async rendering
|
||||
virtual bool
|
||||
RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
|
||||
const NPRemoteWindow& aWindow);
|
||||
virtual bool RecvPaintFinished(void);
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual bool
|
||||
AnswerPaint(const NPRemoteEvent& event, int16_t* handled)
|
||||
@ -372,6 +379,102 @@ public:
|
||||
private:
|
||||
const NPCocoaEvent *mCurrentEvent;
|
||||
#endif
|
||||
|
||||
// ShowPluginFrame - in general does four things:
|
||||
// 1) Create mCurrentSurface optimized for rendering to parent process
|
||||
// 2) Updated mCurrentSurface to be a complete copy of mBackSurface
|
||||
// 3) Draw the invalidated plugin area into mCurrentSurface
|
||||
// 4) Send it to parent process.
|
||||
PRBool ShowPluginFrame(void);
|
||||
|
||||
// Post ShowPluginFrame task
|
||||
void AsyncShowPluginFrame(void);
|
||||
|
||||
// In the PaintRect functions, aSurface is the size of the full plugin window. Each PaintRect function
|
||||
// renders into the subrectangle aRect of aSurface (possibly more if we're working around a Flash bug).
|
||||
|
||||
// Paint plugin content rectangle to surface with bg color filling
|
||||
void PaintRectToSurface(const nsIntRect& aRect,
|
||||
gfxASurface* aSurface,
|
||||
const gfxRGBA& aColor);
|
||||
|
||||
// Render plugin content to surface using
|
||||
// white/black image alpha extraction algorithm
|
||||
void PaintRectWithAlphaExtraction(const nsIntRect& aRect,
|
||||
gfxASurface* aSurface);
|
||||
|
||||
// Call plugin NPAPI function to render plugin content to surface
|
||||
// @param - aSurface - should be compatible with current platform plugin rendering
|
||||
// @return - FALSE if plugin not painted to surface
|
||||
void PaintRectToPlatformSurface(const nsIntRect& aRect,
|
||||
gfxASurface* aSurface);
|
||||
|
||||
// Update NPWindow platform attributes and call plugin "setwindow"
|
||||
// @param - aForceSetWindow - call setwindow even if platform attributes are the same
|
||||
void UpdateWindowAttributes(PRBool aForceSetWindow = PR_FALSE);
|
||||
|
||||
// Create optimized mCurrentSurface for parent process rendering
|
||||
// @return FALSE if optimized surface not created
|
||||
PRBool CreateOptSurface(void);
|
||||
|
||||
// Create mHelperSurface if mCurrentSurface non compatible with plugins
|
||||
// @return TRUE if helper surface created successfully, or not needed
|
||||
PRBool MaybeCreatePlatformHelperSurface(void);
|
||||
|
||||
// Make sure that we have surface for rendering
|
||||
PRBool EnsureCurrentBuffer(void);
|
||||
|
||||
// Helper function for delayed InvalidateRect call
|
||||
// non null mCurrentInvalidateTask will call this function
|
||||
void InvalidateRectDelayed(void);
|
||||
|
||||
// Set as true when SetupLayer called
|
||||
// and go with different path in InvalidateRect function
|
||||
PRPackedBool mLayersRendering;
|
||||
// Current surface available for rendering
|
||||
nsRefPtr<gfxASurface> mCurrentSurface;
|
||||
// Back surface, just keeping reference to
|
||||
// surface which is on ParentProcess side
|
||||
nsRefPtr<gfxASurface> mBackSurface;
|
||||
// Accumulated invalidate rect, while back buffer is not accessible
|
||||
nsIntRect mAccumulatedInvalidRect;
|
||||
// Plugin only call SetTransparent
|
||||
// and does not remember their transparent state
|
||||
// and p->getvalue return always false
|
||||
PRPackedBool mIsTransparent;
|
||||
// Surface type optimized of parent process
|
||||
gfxSurfaceType mSurfaceType;
|
||||
|
||||
// set TRUE if plugin surface dropped in asyncSetWindow
|
||||
// if TRUE then initiate full repaint in RecvPaintFinished
|
||||
PRPackedBool mPendingForcePaint;
|
||||
|
||||
// Keep InvalidateRect task pointer to be able Cancel it on Destroy
|
||||
CancelableTask *mCurrentInvalidateTask;
|
||||
|
||||
// True while plugin-child in plugin call
|
||||
// Use to prevent plugin paint re-enter
|
||||
PRPackedBool mPendingPluginCall;
|
||||
|
||||
// On some platforms, plugins may not support rendering to a surface with
|
||||
// alpha, or not support rendering to an image surface.
|
||||
// In those cases we need to draw to a temporary platform surface; we cache
|
||||
// that surface here.
|
||||
nsRefPtr<gfxASurface> mHelperSurface;
|
||||
|
||||
// true when plugin does not support painting to ARGB32 surface
|
||||
// this is false for maemo platform, and false if plugin
|
||||
// supports NPPVpluginTransparentAlphaBool (which is not part of NPAPI yet)
|
||||
PRPackedBool mDoAlphaExtraction;
|
||||
|
||||
// Cached rectangle rendered to previous surface(mBackSurface)
|
||||
// Used for reading back to current surface and syncing data
|
||||
nsIntRect mSurfaceDifferenceRect;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// Used with windowless flash plugin only, see bug 574583
|
||||
PRPackedBool mFlash10Quirks;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
|
@ -46,6 +46,16 @@
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#ifdef MOZ_X11
|
||||
#include "gfxXlibSurface.h"
|
||||
#endif
|
||||
#include "gfxContext.h"
|
||||
#include "gfxColor.h"
|
||||
#include "gfxUtils.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windowsx.h>
|
||||
@ -88,6 +98,7 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
|
||||
, mDrawingModel(NPDrawingModelCoreGraphics)
|
||||
, mIOSurface(nsnull)
|
||||
#endif
|
||||
, mSentPaintNotification(PR_FALSE)
|
||||
{
|
||||
InitQuirksModes(aMimeType);
|
||||
}
|
||||
@ -460,22 +471,109 @@ PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::RecvShow(const NPRect& updatedRect,
|
||||
const SurfaceDescriptor& newSurface,
|
||||
SurfaceDescriptor* prevSurface)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
if (newSurface.type() == SurfaceDescriptor::TShmem) {
|
||||
if (!newSurface.get_Shmem().IsReadable()) {
|
||||
NS_WARNING("back surface not readable");
|
||||
return false;
|
||||
}
|
||||
surface = new gfxSharedImageSurface(newSurface.get_Shmem());
|
||||
}
|
||||
#ifdef MOZ_X11
|
||||
else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
|
||||
SurfaceDescriptorX11 xdesc = newSurface.get_SurfaceDescriptorX11();
|
||||
XRenderPictFormat pf;
|
||||
pf.id = xdesc.xrenderPictID();
|
||||
XRenderPictFormat *incFormat =
|
||||
XRenderFindFormat(DefaultXDisplay(), PictFormatID, &pf, 0);
|
||||
surface =
|
||||
new gfxXlibSurface(DefaultScreenOfDisplay(DefaultXDisplay()),
|
||||
xdesc.XID(), incFormat, xdesc.size());
|
||||
}
|
||||
#endif
|
||||
|
||||
mSentPaintNotification = PR_FALSE;
|
||||
if (mFrontSurface) {
|
||||
#ifdef MOZ_X11
|
||||
if (mFrontSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||
gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(mFrontSurface.get());
|
||||
*prevSurface =
|
||||
SurfaceDescriptorX11(xsurf->XDrawable(), xsurf->XRenderFormat()->id,
|
||||
mFrontSurface->GetSize());
|
||||
} else
|
||||
#endif
|
||||
if (gfxSharedImageSurface::IsSharedImage(mFrontSurface)) {
|
||||
*prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
|
||||
} else {
|
||||
*prevSurface = null_t();
|
||||
}
|
||||
} else {
|
||||
*prevSurface = null_t();
|
||||
}
|
||||
mFrontSurface = surface;
|
||||
RecvNPN_InvalidateRect(updatedRect);
|
||||
#ifdef MOZ_X11
|
||||
// Sync prevSurface before sending to child
|
||||
if (prevSurface->type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
|
||||
XSync(DefaultXDisplay(), False);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
NPRemoteWindow window;
|
||||
mWindowType = aWindow->type;
|
||||
window.window = reinterpret_cast<unsigned long>(aWindow->window);
|
||||
window.x = aWindow->x;
|
||||
window.y = aWindow->y;
|
||||
window.width = aWindow->width;
|
||||
window.height = aWindow->height;
|
||||
window.clipRect = aWindow->clipRect;
|
||||
window.type = aWindow->type;
|
||||
mSentPaintNotification = PR_FALSE;
|
||||
if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
|
||||
window))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginInstanceParent::NotifyPainted(void)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
bool rv = true;
|
||||
if (!mSentPaintNotification) {
|
||||
rv = SendPaintFinished();
|
||||
mSentPaintNotification = rv;
|
||||
}
|
||||
return rv ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginInstanceParent::GetSurface(gfxASurface** aSurface)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (mFrontSurface) {
|
||||
NS_ADDREF(*aSurface = mFrontSurface);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginInstanceParent::UseAsyncPainting(PRBool* aIsAsync)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsAsync);
|
||||
*aIsAsync = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NPError
|
||||
|
@ -52,6 +52,10 @@
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsRect.h"
|
||||
#include "gfxASurface.h"
|
||||
#ifdef MOZ_X11
|
||||
class gfxXlibSurface;
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
@ -165,6 +169,12 @@ public:
|
||||
virtual bool
|
||||
RecvNPN_InvalidateRect(const NPRect& rect);
|
||||
|
||||
// Async rendering
|
||||
virtual bool
|
||||
RecvShow(const NPRect& updatedRect,
|
||||
const SurfaceDescriptor& newSurface,
|
||||
SurfaceDescriptor* prevSurface);
|
||||
|
||||
virtual bool
|
||||
AnswerNPN_PushPopupsEnabledState(const bool& aState);
|
||||
|
||||
@ -253,6 +263,7 @@ public:
|
||||
nsresult AsyncSetWindow(NPWindow* window);
|
||||
nsresult NotifyPainted(void);
|
||||
nsresult GetSurface(gfxASurface** aSurface);
|
||||
nsresult UseAsyncPainting(PRBool* aIsAsync);
|
||||
|
||||
private:
|
||||
// Quirks mode support for various plugin mime types
|
||||
@ -308,6 +319,12 @@ private:
|
||||
int16_t mDrawingModel;
|
||||
nsIOSurface *mIOSurface;
|
||||
#endif // definied(OS_MACOSX)
|
||||
|
||||
// ObjectFrame layer wrapper
|
||||
nsRefPtr<gfxASurface> mFrontSurface;
|
||||
|
||||
// Don't spam plugin process with extra paint notifications
|
||||
PRPackedBool mSentPaintNotification;
|
||||
};
|
||||
|
||||
|
||||
|
@ -82,6 +82,7 @@ public:
|
||||
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0;
|
||||
virtual nsresult NotifyPainted(NPP instance) = 0;
|
||||
virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface) = 0;
|
||||
virtual nsresult UseAsyncPainting(NPP instance, PRBool* aIsAsync) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -643,6 +643,16 @@ PluginModuleParent::GetSurface(NPP instance, gfxASurface** aSurface)
|
||||
return i->GetSurface(aSurface);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginModuleParent::UseAsyncPainting(NPP instance, PRBool* aIsAsync)
|
||||
{
|
||||
PluginInstanceParent* i = InstCast(instance);
|
||||
if (!i)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return i->UseAsyncPainting(aIsAsync);
|
||||
}
|
||||
|
||||
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
nsresult
|
||||
|
@ -224,6 +224,7 @@ private:
|
||||
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
|
||||
virtual nsresult NotifyPainted(NPP instance);
|
||||
virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
|
||||
virtual nsresult UseAsyncPainting(NPP instance, PRBool* aIsAsync);
|
||||
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error);
|
||||
|
@ -90,6 +90,11 @@ PluginProcessChild::Init()
|
||||
# error Sorry
|
||||
#endif
|
||||
|
||||
if (NS_FAILED(nsRegion::InitStatic())) {
|
||||
NS_ERROR("Could not initialize nsRegion");
|
||||
return false;
|
||||
}
|
||||
|
||||
mPlugin.Init(pluginFilename, ParentHandle(),
|
||||
IOThreadChild::message_loop(),
|
||||
IOThreadChild::channel());
|
||||
@ -103,6 +108,7 @@ PluginProcessChild::CleanUp()
|
||||
#ifdef XP_WIN
|
||||
::OleUninitialize();
|
||||
#endif
|
||||
nsRegion::ShutdownStatic();
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -120,6 +120,7 @@ _TEST_FILES = \
|
||||
test_DOMWindowCreated_chromeonly.html \
|
||||
test_bug581072.html \
|
||||
test_bug583225.html \
|
||||
test_bug585240.html \
|
||||
test_bug585819.html \
|
||||
test_bug369306.html \
|
||||
$(NULL)
|
||||
|
34
dom/tests/mochitest/bugs/test_bug585240.html
Normal file
34
dom/tests/mochitest/bugs/test_bug585240.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=585240
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 585240</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/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=585240">Mozilla Bug 585240</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 585240 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.onmessage = function(event) {
|
||||
ok(true, "message event should fire!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
window.postMessage("hello", "*");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -158,6 +158,7 @@ ContainerLayerD3D9::RenderLayer()
|
||||
nsRefPtr<IDirect3DSurface9> renderSurface;
|
||||
renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
|
||||
device()->SetRenderTarget(0, renderSurface);
|
||||
device()->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0);
|
||||
device()->GetVertexShaderConstantF(12, previousRenderTargetOffset, 1);
|
||||
renderTargetOffset[0] = (float)visibleRect.x;
|
||||
renderTargetOffset[1] = (float)visibleRect.y;
|
||||
|
@ -192,3 +192,27 @@ gfxImageSurface::CopyFrom(gfxImageSurface *other)
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxSubimageSurface>
|
||||
gfxImageSurface::GetSubimage(const gfxRect& aRect)
|
||||
{
|
||||
gfxRect r(aRect);
|
||||
r.Round();
|
||||
unsigned char* subData = Data() +
|
||||
(Stride() * (int)r.Y()) +
|
||||
(int)r.X() * gfxASurface::BytePerPixelFromFormat(Format());
|
||||
|
||||
nsRefPtr<gfxSubimageSurface> image =
|
||||
new gfxSubimageSurface(this, subData,
|
||||
gfxIntSize((int)r.Width(), (int)r.Height()));
|
||||
|
||||
return image.forget().get();
|
||||
}
|
||||
|
||||
gfxSubimageSurface::gfxSubimageSurface(gfxImageSurface* aParent,
|
||||
unsigned char* aData,
|
||||
const gfxIntSize& aSize)
|
||||
: gfxImageSurface(aData, aSize, aParent->Stride(), aParent->Format())
|
||||
, mParent(aParent)
|
||||
{
|
||||
}
|
||||
|
@ -43,6 +43,8 @@
|
||||
|
||||
// ARGB -- raw buffer.. wont be changed.. good for storing data.
|
||||
|
||||
class gfxSubimageSurface;
|
||||
|
||||
/**
|
||||
* A raw image buffer. The format can be set in the constructor. Its main
|
||||
* purpose is for storing read-only images and using it as a source surface,
|
||||
@ -99,6 +101,11 @@ public:
|
||||
/* Fast copy from another image surface; returns TRUE if successful, FALSE otherwise */
|
||||
PRBool CopyFrom (gfxImageSurface *other);
|
||||
|
||||
/* return new Subimage with pointing to original image starting from aRect.pos
|
||||
* and size of aRect.size. New subimage keeping current image reference
|
||||
*/
|
||||
already_AddRefed<gfxSubimageSurface> GetSubimage(const gfxRect& aRect);
|
||||
|
||||
protected:
|
||||
gfxImageSurface();
|
||||
void InitFromSurface(cairo_surface_t *csurf);
|
||||
@ -111,4 +118,14 @@ protected:
|
||||
long mStride;
|
||||
};
|
||||
|
||||
class THEBES_API gfxSubimageSurface : public gfxImageSurface {
|
||||
protected:
|
||||
friend class gfxImageSurface;
|
||||
gfxSubimageSurface(gfxImageSurface* aParent,
|
||||
unsigned char* aData,
|
||||
const gfxIntSize& aSize);
|
||||
private:
|
||||
nsRefPtr<gfxImageSurface> mParent;
|
||||
};
|
||||
|
||||
#endif /* GFX_IMAGESURFACE_H */
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "gfxPattern.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsRegion.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4800 )
|
||||
@ -59,6 +60,7 @@
|
||||
namespace mozilla {
|
||||
|
||||
typedef gfxPattern::GraphicsFilter GraphicsFilterType;
|
||||
typedef gfxASurface::gfxSurfaceType gfxSurfaceType;
|
||||
|
||||
// XXX there are out of place and might be generally useful. Could
|
||||
// move to nscore.h or something.
|
||||
@ -314,24 +316,6 @@ struct ParamTraits<float>
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<gfxIntSize>
|
||||
{
|
||||
typedef gfxIntSize paramType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.width);
|
||||
WriteParam(msg, param.height);
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
{
|
||||
return (ReadParam(msg, iter, &result->width) &&
|
||||
ReadParam(msg, iter, &result->height));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<gfxMatrix>
|
||||
{
|
||||
@ -437,6 +421,38 @@ struct ParamTraits<mozilla::GraphicsFilterType>
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::gfxSurfaceType>
|
||||
{
|
||||
typedef mozilla::gfxSurfaceType paramType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
if (gfxASurface::SurfaceTypeImage <= param &&
|
||||
param < gfxASurface::SurfaceTypeMax) {
|
||||
WriteParam(msg, int32(param));
|
||||
return;
|
||||
}
|
||||
NS_RUNTIMEABORT("surface type not reached");
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
{
|
||||
int32 filter;
|
||||
if (!ReadParam(msg, iter, &filter))
|
||||
return false;
|
||||
|
||||
if (gfxASurface::SurfaceTypeImage <= filter &&
|
||||
filter < gfxASurface::SurfaceTypeMax) {
|
||||
*result = paramType(filter);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct ParamTraits<gfxRGBA>
|
||||
{
|
||||
@ -570,6 +586,24 @@ struct ParamTraits<nsIntSize>
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<gfxIntSize>
|
||||
{
|
||||
typedef gfxIntSize paramType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.width);
|
||||
WriteParam(msg, param.height);
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
{
|
||||
return (ReadParam(msg, iter, &result->width) &&
|
||||
ReadParam(msg, iter, &result->height));
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace IPC */
|
||||
|
||||
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
|
||||
|
@ -900,9 +900,6 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
|
||||
/* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
|
||||
#if (WTF_CPU_X86 \
|
||||
|| WTF_CPU_X86_64 \
|
||||
|| WTF_CPU_ARM_THUMB2 \
|
||||
|| WTF_CPU_ARM_TRADITIONAL \
|
||||
|| WTF_CPU_ARM_TRADITIONAL \
|
||||
|| WTF_CPU_X86)
|
||||
#define ENABLE_YARR_JIT 1
|
||||
#else
|
||||
|
@ -2357,5 +2357,5 @@ CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
|
||||
libs export libs::
|
||||
$(CHECK_FROZEN_VARIABLES)
|
||||
|
||||
default::
|
||||
default all::
|
||||
if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
|
||||
|
9
layout/reftests/bugs/594737-1-ref.html
Normal file
9
layout/reftests/bugs/594737-1-ref.html
Normal file
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<select disabled size="4">
|
||||
<option>One</option>
|
||||
<option>Two</option>
|
||||
<option>Three</option>
|
||||
<option>Four</option>
|
||||
</select>
|
||||
</body>
|
9
layout/reftests/bugs/594737-1.html
Normal file
9
layout/reftests/bugs/594737-1.html
Normal file
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<select disabled multiple size="4">
|
||||
<option>One</option>
|
||||
<option>Two</option>
|
||||
<option>Three</option>
|
||||
<option>Four</option>
|
||||
</select>
|
||||
</body>
|
@ -1503,4 +1503,5 @@ random-if(layersGPUAccelerated) == 581317-1.html 581317-1-ref.html
|
||||
== 589672-1.html 589672-1-ref.html
|
||||
== 586400-1.html 586400-1-ref.html
|
||||
== 593544-1.html 593544-1-ref.html
|
||||
== 594737-1.html 594737-1-ref.html
|
||||
== 594624-1.html 594624-1-ref.html
|
||||
|
29
layout/style/crashtests/592698-1.html
Executable file
29
layout/style/crashtests/592698-1.html
Executable file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<iframe id="x"
|
||||
src="data:text/html;charset=utf-8,%3Cdiv%20id%3D%22a%22%3Eaaa"></iframe>
|
||||
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window.frames[0].document.getElementById("a").setAttribute("style",
|
||||
'-moz-transition-property: color;' +
|
||||
'-moz-transition-duration: 10s;' +
|
||||
'transition-property: color;' +
|
||||
'transition-duration: 10s; ' +
|
||||
'color: red;');
|
||||
|
||||
// And start the transition
|
||||
window.frames[0].document.documentElement.getBoundingClientRect();
|
||||
|
||||
// Now kill off the presshell
|
||||
var frame = document.getElementById("x");
|
||||
frame.style.display = "none";
|
||||
document.documentElement.getBoundingClientRect();
|
||||
|
||||
// And wait for the refresh driver to fire
|
||||
setTimeout(function() {
|
||||
document.documentElement.className = "";
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
</html>
|
@ -60,3 +60,4 @@ load 558943-1.xhtml
|
||||
load 571105-1.xhtml
|
||||
load 573127-1.html
|
||||
load 580685.html
|
||||
load 592698-1.html
|
||||
|
@ -360,7 +360,9 @@ input[disabled],
|
||||
textarea[disabled],
|
||||
option[disabled],
|
||||
optgroup[disabled],
|
||||
select[disabled] {
|
||||
select[disabled][disabled] /* Need the attr twice to have the specificity be at
|
||||
least the same as select[size][multiple] above */
|
||||
{
|
||||
-moz-user-input: disabled;
|
||||
-moz-user-focus: ignore;
|
||||
color: GrayText;
|
||||
|
@ -279,13 +279,19 @@ void
|
||||
nsTransitionManager::Disconnect()
|
||||
{
|
||||
// Content nodes might outlive the transition manager.
|
||||
RemoveAllTransitions();
|
||||
|
||||
mPresContext = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsTransitionManager::RemoveAllTransitions()
|
||||
{
|
||||
while (!PR_CLIST_IS_EMPTY(&mElementTransitions)) {
|
||||
ElementTransitions *head = static_cast<ElementTransitions*>(
|
||||
PR_LIST_HEAD(&mElementTransitions));
|
||||
head->Destroy();
|
||||
}
|
||||
|
||||
mPresContext = nsnull;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
@ -868,6 +874,14 @@ nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime)
|
||||
NS_ABORT_IF_FALSE(mPresContext,
|
||||
"refresh driver should not notify additional observers "
|
||||
"after pres context has been destroyed");
|
||||
if (!mPresContext->GetPresShell()) {
|
||||
// Someone might be keeping mPresContext alive past the point
|
||||
// where it has been torn down; don't bother doing anything in
|
||||
// this case. But do get rid of all our transitions so we stop
|
||||
// triggering refreshes.
|
||||
RemoveAllTransitions();
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<TransitionEventInfo> events;
|
||||
|
||||
|
@ -122,6 +122,8 @@ private:
|
||||
void WalkTransitionRule(RuleProcessorData* aData,
|
||||
nsCSSPseudoElements::Type aPseudoType);
|
||||
|
||||
void RemoveAllTransitions();
|
||||
|
||||
PRCList mElementTransitions;
|
||||
nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
|
||||
};
|
||||
|
@ -1368,6 +1368,13 @@ nsMenuFrame::SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize)
|
||||
return PR_FALSE;
|
||||
tmpSize = mPopupFrame->GetPrefSize(aState);
|
||||
aSize.width = tmpSize.width;
|
||||
|
||||
// if there is a scroll frame, add the desired width of the scrollbar as well
|
||||
nsIScrollableFrame* scrollFrame = do_QueryFrame(mPopupFrame->GetFirstChild(nsnull));
|
||||
if (scrollFrame) {
|
||||
aSize.width += scrollFrame->GetDesiredScrollbarSizes(&aState).LeftRight();
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,11 @@ pref("general.warnOnAboutConfig", true);
|
||||
pref("browser.bookmarks.max_backups", 5);
|
||||
|
||||
pref("browser.cache.disk.enable", true);
|
||||
// Is this the first-time smartsizing has been introduced?
|
||||
pref("browser.cache.disk.smart_size.first_run", true);
|
||||
// Does the user want smart-sizing?
|
||||
pref("browser.cache.disk.smart_size.enabled", true);
|
||||
// Size explicitly set by the user. Used when smart_size.enabled == false
|
||||
#ifndef WINCE
|
||||
pref("browser.cache.disk.capacity", 256000);
|
||||
#else
|
||||
@ -798,12 +803,23 @@ pref("network.IDN.whitelist.vn", true);
|
||||
// IDN ccTLDs
|
||||
// ae, UAE, .<Emarat>
|
||||
pref("network.IDN.whitelist.xn--mgbaam7a8h", true);
|
||||
// sa, Saudi Arabia, .<al-Saudiah>
|
||||
pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true);
|
||||
// ru, Russian Federation, .<RF>
|
||||
pref("network.IDN.whitelist.xn--p1ai", true);
|
||||
// cn, China, .<China> with variants
|
||||
pref("network.IDN.whitelist.xn--fiqz9s", true); // Traditional
|
||||
pref("network.IDN.whitelist.xn--fiqs8s", true); // Simplified
|
||||
// hk, Hong Kong, .<Hong Kong>
|
||||
pref("network.IDN.whitelist.xn--j6w193g", true);
|
||||
// jo, Jordan, .<Al-Ordon>
|
||||
pref("network.IDN.whitelist.xn--mgbayh7gpa", true);
|
||||
// ru, Russian Federation, .<RF>
|
||||
pref("network.IDN.whitelist.xn--p1ai", true);
|
||||
// sa, Saudi Arabia, .<al-Saudiah> with variants
|
||||
pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true);
|
||||
pref("network.IDN.whitelist.xn--mgberp4a5d4a87g", true);
|
||||
pref("network.IDN.whitelist.xn--mgbqly7c0a67fbc", true);
|
||||
pref("network.IDN.whitelist.xn--mgbqly7cvafr", true);
|
||||
// tw, Taiwan, <.Taiwan> with variants
|
||||
pref("network.IDN.whitelist.xn--kpry57d", true); // Traditional
|
||||
pref("network.IDN.whitelist.xn--kprw13d", true); // Simplified
|
||||
|
||||
// gTLDs
|
||||
pref("network.IDN.whitelist.biz", true);
|
||||
|
@ -241,4 +241,9 @@ interface nsIPluginInstance : nsISupports
|
||||
* This should return a valid gfxASurface pointer, or null if there is nothing to render yet.
|
||||
*/
|
||||
void getSurface(out gfxASurfacePtr aSurface);
|
||||
|
||||
/**
|
||||
* @return true if plugin module supports async rendering
|
||||
*/
|
||||
PRBool useAsyncPainting();
|
||||
};
|
||||
|
@ -191,7 +191,7 @@ PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window)
|
||||
{
|
||||
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
|
||||
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
|
||||
return inst->AsyncSetWindow(window);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -199,7 +199,7 @@ PluginPRLibrary::NotifyPainted(NPP instance)
|
||||
{
|
||||
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
|
||||
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
|
||||
return inst->NotifyPainted();
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -211,5 +211,13 @@ PluginPRLibrary::GetSurface(NPP instance, gfxASurface** aSurface)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginPRLibrary::UseAsyncPainting(NPP instance, PRBool* aIsAsync)
|
||||
{
|
||||
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
|
||||
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
|
||||
aIsAsync = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -136,6 +136,7 @@ public:
|
||||
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
|
||||
virtual nsresult NotifyPainted(NPP instance);
|
||||
virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
|
||||
virtual nsresult UseAsyncPainting(NPP instance, PRBool* aIsAsync);
|
||||
|
||||
private:
|
||||
NP_InitializeFunc mNP_Initialize;
|
||||
|
@ -875,6 +875,23 @@ nsNPAPIPluginInstance::NotifyPainted(void)
|
||||
return library->NotifyPainted(&mNPP);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNPAPIPluginInstance::UseAsyncPainting(PRBool* aIsAsync)
|
||||
{
|
||||
if (RUNNING != mRunning)
|
||||
return NS_OK;
|
||||
|
||||
PluginDestructionGuard guard(this);
|
||||
|
||||
if (!mPlugin)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PluginLibrary* library = mPlugin->GetLibrary();
|
||||
if (!library)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return library->UseAsyncPainting(&mNPP, aIsAsync);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNPAPIPluginInstance::IsTransparent(PRBool* isTransparent)
|
||||
|
264
netwerk/cache/nsCacheService.cpp
vendored
264
netwerk/cache/nsCacheService.cpp
vendored
@ -1,5 +1,6 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -84,6 +85,11 @@
|
||||
|
||||
#define DISK_CACHE_ENABLE_PREF "browser.cache.disk.enable"
|
||||
#define DISK_CACHE_DIR_PREF "browser.cache.disk.parent_directory"
|
||||
#define DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF\
|
||||
"browser.cache.disk.smart_size.first_run"
|
||||
#define DISK_CACHE_SMART_SIZE_ENABLED_PREF \
|
||||
"browser.cache.disk.smart_size.enabled"
|
||||
#define DISK_CACHE_SMART_SIZE_PREF "browser.cache.disk.smart_size_cached_value"
|
||||
#define DISK_CACHE_CAPACITY_PREF "browser.cache.disk.capacity"
|
||||
#define DISK_CACHE_MAX_ENTRY_SIZE_PREF "browser.cache.disk.max_entry_size"
|
||||
#define DISK_CACHE_CAPACITY 256000
|
||||
@ -106,6 +112,7 @@ static const char * observerList[] = {
|
||||
static const char * prefList[] = {
|
||||
#ifdef NECKO_DISK_CACHE
|
||||
DISK_CACHE_ENABLE_PREF,
|
||||
DISK_CACHE_SMART_SIZE_ENABLED_PREF,
|
||||
DISK_CACHE_CAPACITY_PREF,
|
||||
DISK_CACHE_DIR_PREF,
|
||||
#endif
|
||||
@ -118,6 +125,12 @@ static const char * prefList[] = {
|
||||
MEMORY_CACHE_CAPACITY_PREF
|
||||
};
|
||||
|
||||
// Let our base line be 250MB.
|
||||
const PRInt32 BASE_LINE = 250 * 1024 * 1024;
|
||||
const PRInt32 MIN_SIZE = 50 * 1024 * 1024;
|
||||
const PRInt32 MAX_SIZE = 1024 * 1024 * 1024;
|
||||
|
||||
|
||||
class nsCacheProfilePrefObserver : public nsIObserver
|
||||
{
|
||||
public:
|
||||
@ -144,6 +157,7 @@ public:
|
||||
|
||||
PRBool DiskCacheEnabled();
|
||||
PRInt32 DiskCacheCapacity() { return mDiskCacheCapacity; }
|
||||
void SetDiskCacheCapacity(PRInt32);
|
||||
nsILocalFile * DiskCacheParentDirectory() { return mDiskCacheParentDirectory; }
|
||||
|
||||
PRBool OfflineCacheEnabled();
|
||||
@ -153,7 +167,10 @@ public:
|
||||
PRBool MemoryCacheEnabled();
|
||||
PRInt32 MemoryCacheCapacity();
|
||||
|
||||
static PRUint32 GetSmartCacheSize(void);
|
||||
|
||||
private:
|
||||
bool PermittedToSmartSize(nsIPrefBranch*, PRBool firstRun);
|
||||
PRBool mHaveProfile;
|
||||
|
||||
PRBool mDiskCacheEnabled;
|
||||
@ -170,7 +187,75 @@ private:
|
||||
PRBool mInPrivateBrowsing;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCacheProfilePrefObserver, nsIObserver)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheProfilePrefObserver, nsIObserver)
|
||||
|
||||
// Runnable sent to main thread after the cache IO thread calculates available
|
||||
// disk space, so that there is no race in setting mDiskCacheCapacity.
|
||||
class nsSetSmartSizeEvent: public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsSetSmartSizeEvent(bool firstRun, PRInt32 smartSize)
|
||||
: mFirstRun(firstRun) , mSmartSize(smartSize) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(NS_IsMainThread(),
|
||||
"Setting smart size data off the main thread");
|
||||
|
||||
// Main thread may have already called nsCacheService::Shutdown
|
||||
if (!nsCacheService::gService || !nsCacheService::gService->mObserver)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
PRBool smartSizeEnabled;
|
||||
nsCOMPtr<nsIPrefBranch2> branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (!branch) {
|
||||
NS_WARNING("Failed to get pref service!");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
// ensure smart sizing wasn't switched off while event was pending
|
||||
rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF,
|
||||
&smartSizeEnabled);
|
||||
if (NS_FAILED(rv))
|
||||
smartSizeEnabled = PR_FALSE;
|
||||
if (smartSizeEnabled) {
|
||||
nsCacheService::SetDiskCacheCapacity(mSmartSize);
|
||||
// also set on observer, in case mDiskDevice not init'd yet.
|
||||
nsCacheService::gService->mObserver->SetDiskCacheCapacity(mSmartSize);
|
||||
rv = branch->SetIntPref(DISK_CACHE_SMART_SIZE_PREF, mSmartSize);
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("Failed to set smart size pref");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mFirstRun;
|
||||
PRInt32 mSmartSize;
|
||||
};
|
||||
|
||||
|
||||
// Runnable sent from main thread to cacheIO thread
|
||||
class nsGetSmartSizeEvent: public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsGetSmartSizeEvent(bool firstRun) : mFirstRun(firstRun) , mSmartSize(0) {}
|
||||
|
||||
// Calculates user's disk space available on a background thread and
|
||||
// dispatches this value back to the main thread.
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mSmartSize = nsCacheProfilePrefObserver::GetSmartCacheSize() / 1024;
|
||||
nsCOMPtr<nsIRunnable> event = new nsSetSmartSizeEvent(mFirstRun,
|
||||
mSmartSize);
|
||||
NS_DispatchToMainThread(event);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mFirstRun;
|
||||
PRInt32 mSmartSize;
|
||||
};
|
||||
|
||||
|
||||
nsresult
|
||||
@ -246,6 +331,12 @@ nsCacheProfilePrefObserver::Remove()
|
||||
prefs->RemoveObserver(prefList[i], this); // remove cache pref observers
|
||||
}
|
||||
|
||||
void
|
||||
nsCacheProfilePrefObserver::SetDiskCacheCapacity(PRInt32 capacity)
|
||||
{
|
||||
mDiskCacheCapacity = PR_MAX(0, capacity);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCacheProfilePrefObserver::Observe(nsISupports * subject,
|
||||
@ -302,6 +393,30 @@ nsCacheProfilePrefObserver::Observe(nsISupports * subject,
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mDiskCacheCapacity = PR_MAX(0, capacity);
|
||||
nsCacheService::SetDiskCacheCapacity(mDiskCacheCapacity);
|
||||
|
||||
// Update the cache capacity when smart sizing is turned on/off
|
||||
} else if (!strcmp(DISK_CACHE_SMART_SIZE_ENABLED_PREF, data.get())) {
|
||||
// Is the update because smartsizing was turned on, or off?
|
||||
PRBool smartSizeEnabled;
|
||||
rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF,
|
||||
&smartSizeEnabled);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
PRInt32 newCapacity = 0;
|
||||
if (smartSizeEnabled) {
|
||||
// Smart sizing switched on: recalculate the capacity.
|
||||
nsCOMPtr<nsIRunnable> event = new nsGetSmartSizeEvent(false);
|
||||
rv = nsCacheService::DispatchToCacheIOThread(event);
|
||||
// If the dispatch failed, just use our base line for the size
|
||||
if (NS_FAILED(rv)) mDiskCacheCapacity = BASE_LINE;
|
||||
} else {
|
||||
// Smart sizing switched off: use user specified size
|
||||
rv = branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &newCapacity);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mDiskCacheCapacity = PR_MAX(0, newCapacity);
|
||||
nsCacheService::SetDiskCacheCapacity(mDiskCacheCapacity);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
} else if (!strcmp(DISK_CACHE_DIR_PREF, data.get())) {
|
||||
// XXX We probaby don't want to respond to this pref except after
|
||||
@ -397,6 +512,108 @@ nsCacheProfilePrefObserver::Observe(nsISupports * subject,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Computes our best guess for the default size of the user's disk cache,
|
||||
* based on the amount of space they have free on their hard drive.
|
||||
* We use a tiered scheme: the more space available,
|
||||
* the larger the disk cache will be. However, we do not want
|
||||
* to enable the disk cache to grow to an unbounded size, so the larger the
|
||||
* user's available space is, the smaller of a percentage we take. We set a
|
||||
* lower bound of 50MB and an upper bound of 1GB.
|
||||
*
|
||||
*@param: None.
|
||||
*@return: The size that the user's disk cache should default to, in bytes.
|
||||
*/
|
||||
PRUint32
|
||||
nsCacheProfilePrefObserver::GetSmartCacheSize(void) {
|
||||
// Get a handle to disk where cache lives, so we can check for free space
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> profileDirectory;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(profileDirectory));
|
||||
if (NS_FAILED(rv)) {
|
||||
return BASE_LINE;
|
||||
}
|
||||
nsCOMPtr<nsILocalFile> diskHandle = do_QueryInterface(profileDirectory);
|
||||
PRInt64 bytesAvailable;
|
||||
diskHandle->GetDiskSpaceAvailable(&bytesAvailable);
|
||||
|
||||
/* 0MB <= Available < 500MB
|
||||
* Use between 50MB and 200MB
|
||||
*/
|
||||
if (bytesAvailable < BASE_LINE * 2) {
|
||||
return PR_MAX(MIN_SIZE, bytesAvailable * 4 / 10);
|
||||
}
|
||||
|
||||
/* 500MB <= Available < 2500MB
|
||||
* Use 250MB
|
||||
*/
|
||||
if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 10) {
|
||||
return BASE_LINE;
|
||||
}
|
||||
|
||||
/* 2500MB <= Available < 5000MB
|
||||
* Use between 250MB and 500MB
|
||||
*/
|
||||
if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 20) {
|
||||
return bytesAvailable / 10;
|
||||
}
|
||||
|
||||
/* 5000MB <= Available < 50000MB
|
||||
* Use 625MB
|
||||
*/
|
||||
if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 200 ) {
|
||||
return BASE_LINE * 5 / 2;
|
||||
}
|
||||
|
||||
/* 50000MB <= Available < 75000MB
|
||||
* Use 800MB
|
||||
*/
|
||||
if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 300) {
|
||||
return BASE_LINE / 5 * 16;
|
||||
}
|
||||
|
||||
/* We have come within range of the ceiling
|
||||
* Use 1GB
|
||||
*/
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
/* Determine if we are permitted to dynamically size the user's disk cache based
|
||||
* on their disk space available. We may do this so long as the pref
|
||||
* smart_size.enabled is true.
|
||||
*/
|
||||
bool
|
||||
nsCacheProfilePrefObserver::PermittedToSmartSize(nsIPrefBranch* branch, PRBool
|
||||
firstRun)
|
||||
{
|
||||
nsresult rv;
|
||||
// If user has explicitly set cache size to be smaller than previous default
|
||||
// of 250MB, then smart sizing is off by default. Otherwise, smart sizing is
|
||||
// on by default.
|
||||
if (firstRun) {
|
||||
// check if user has set cache size in the past
|
||||
PRBool userSet;
|
||||
rv = branch->PrefHasUserValue(DISK_CACHE_CAPACITY_PREF, &userSet);
|
||||
if (NS_FAILED(rv)) userSet = PR_TRUE;
|
||||
if (userSet) {
|
||||
PRInt32 oldCapacity;
|
||||
rv = branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &oldCapacity);
|
||||
if (oldCapacity < BASE_LINE / 1024) {
|
||||
branch->SetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF,
|
||||
PR_FALSE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
PRBool smartSizeEnabled;
|
||||
rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF,
|
||||
&smartSizeEnabled);
|
||||
if (NS_FAILED(rv)) return false;
|
||||
return !!smartSizeEnabled;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
@ -456,6 +673,37 @@ nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch)
|
||||
if (directory)
|
||||
mDiskCacheParentDirectory = do_QueryInterface(directory, &rv);
|
||||
}
|
||||
if (mDiskCacheParentDirectory) {
|
||||
PRBool firstSmartSizeRun;
|
||||
rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF,
|
||||
&firstSmartSizeRun);
|
||||
if (NS_FAILED(rv)) firstSmartSizeRun = PR_FALSE;
|
||||
if (PermittedToSmartSize(branch, firstSmartSizeRun)) {
|
||||
// Prevent unnecessary eviction before smart size event returns
|
||||
if (!firstSmartSizeRun) {
|
||||
PRInt32 oldSmartSize;
|
||||
rv = branch->GetIntPref(DISK_CACHE_SMART_SIZE_PREF,
|
||||
&oldSmartSize);
|
||||
mDiskCacheCapacity = oldSmartSize;
|
||||
} else {
|
||||
rv = branch->SetIntPref(DISK_CACHE_CAPACITY_PREF,
|
||||
MAX_SIZE / 1024);
|
||||
if (NS_FAILED(rv)) NS_WARNING("Failed setting capacity pref");
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
new nsGetSmartSizeEvent(!!firstSmartSizeRun);
|
||||
rv = nsCacheService::DispatchToCacheIOThread(event);
|
||||
if (NS_FAILED(rv)) mDiskCacheCapacity = BASE_LINE;
|
||||
}
|
||||
|
||||
if (firstSmartSizeRun) {
|
||||
// It is no longer our first run
|
||||
rv = branch->SetBoolPref(DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF,
|
||||
PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("Failed setting first_run pref in ReadPrefs.");
|
||||
}
|
||||
}
|
||||
#endif // !NECKO_DISK_CACHE
|
||||
|
||||
#ifdef NECKO_OFFLINE_CACHE
|
||||
@ -513,6 +761,13 @@ nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch)
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCacheService::DispatchToCacheIOThread(nsIRunnable* event)
|
||||
{
|
||||
if (!gService->mCacheIOThread) return NS_ERROR_NOT_AVAILABLE;
|
||||
return gService->mCacheIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsCacheProfilePrefObserver::DiskCacheEnabled()
|
||||
@ -1718,7 +1973,8 @@ nsCacheService::SetDiskCacheCapacity(PRInt32 capacity)
|
||||
}
|
||||
#endif // !NECKO_DISK_CACHE
|
||||
|
||||
gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled();
|
||||
if (gService->mObserver)
|
||||
gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled();
|
||||
}
|
||||
|
||||
void
|
||||
|
4
netwerk/cache/nsCacheService.h
vendored
4
netwerk/cache/nsCacheService.h
vendored
@ -143,6 +143,9 @@ public:
|
||||
static void ReleaseObject_Locked(nsISupports * object,
|
||||
nsIEventTarget * target = nsnull);
|
||||
|
||||
static nsresult DispatchToCacheIOThread(nsIRunnable* event);
|
||||
|
||||
|
||||
/**
|
||||
* Methods called by nsCacheProfilePrefObserver
|
||||
*/
|
||||
@ -167,6 +170,7 @@ private:
|
||||
friend class nsCacheServiceAutoLock;
|
||||
friend class nsOfflineCacheDevice;
|
||||
friend class nsProcessRequestEvent;
|
||||
friend class nsSetSmartSizeEvent;
|
||||
|
||||
/**
|
||||
* Internal Methods
|
||||
|
@ -177,11 +177,11 @@ nsWifiMonitor::DoScanOld()
|
||||
&managed_access_points,
|
||||
&adhoc_access_points,
|
||||
0) != noErr) {
|
||||
continue;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (managed_access_points == NULL) {
|
||||
continue;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int accessPointsCount = CFArrayGetCount(managed_access_points);
|
||||
|
@ -55,6 +55,8 @@ CPPSRCS = \
|
||||
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/build/
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
|
||||
|
@ -38,6 +38,12 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
using mozilla::dom::ContentChild;
|
||||
#endif
|
||||
|
||||
#include "nsAlertsService.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
@ -82,6 +88,23 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
|
||||
nsIObserver * aAlertListener,
|
||||
const nsAString & aAlertName)
|
||||
{
|
||||
#ifdef MOZ_IPC
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
ContentChild* cpc = ContentChild::GetSingleton();
|
||||
|
||||
if (aAlertListener)
|
||||
cpc->AddRemoteAlertObserver(nsDependentString(aAlertCookie), aAlertListener);
|
||||
|
||||
cpc->SendShowAlertNotification(nsAutoString(aImageUrl),
|
||||
nsAutoString(aAlertTitle),
|
||||
nsAutoString(aAlertText),
|
||||
aAlertTextClickable,
|
||||
nsAutoString(aAlertCookie),
|
||||
nsAutoString(aAlertName));
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
mozilla::AndroidBridge::Bridge()->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertCookie,
|
||||
aAlertListener, aAlertName);
|
||||
|
@ -2287,7 +2287,7 @@ HUD_SERVICE.prototype =
|
||||
msgObject.messageNode.appendChild(
|
||||
msgObject.textFactory(
|
||||
msgObject.prefix +
|
||||
self.getFormatStr("networkUrlWithStatus", data)));
|
||||
self.getFormatStr("networkUrlWithStatus", data) + "\n"));
|
||||
|
||||
break;
|
||||
|
||||
@ -2312,7 +2312,8 @@ HUD_SERVICE.prototype =
|
||||
msgObject.messageNode.appendChild(
|
||||
msgObject.textFactory(
|
||||
msgObject.prefix +
|
||||
self.getFormatStr("networkUrlWithStatusAndDuration", data)));
|
||||
self.getFormatStr("networkUrlWithStatusAndDuration",
|
||||
data) + "\n"));
|
||||
|
||||
delete self.openRequests[item.id];
|
||||
updatePanel = true;
|
||||
@ -3324,7 +3325,7 @@ function HUDConsole(aHeadsUpDisplay)
|
||||
|
||||
let message = argumentArray.join(' ');
|
||||
let timestampedMessage = ConsoleUtils.timestampString(ts) + ": " +
|
||||
message;
|
||||
message + "\n";
|
||||
|
||||
messageNode.appendChild(chromeDocument.createTextNode(timestampedMessage));
|
||||
|
||||
@ -4022,7 +4023,7 @@ JSTerm.prototype = {
|
||||
// TODO: format the aOutputObject and don't just use the
|
||||
// aOuputObject.toString() function: [object object] -> Object {prop, ...}
|
||||
// See bug 586249.
|
||||
let textNode = this.textFactory(aOutputObject);
|
||||
let textNode = this.textFactory(aOutputObject + "\n");
|
||||
node.appendChild(textNode);
|
||||
|
||||
lastGroupNode.appendChild(node);
|
||||
@ -4062,7 +4063,7 @@ JSTerm.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
var textNode = this.textFactory(aOutputMessage);
|
||||
var textNode = this.textFactory(aOutputMessage + "\n");
|
||||
node.appendChild(textNode);
|
||||
|
||||
lastGroupNode.appendChild(node);
|
||||
@ -4552,7 +4553,7 @@ LogMessage.prototype = {
|
||||
var ts = ConsoleUtils.timestamp();
|
||||
this.timestampedMessage = ConsoleUtils.timestampString(ts) + ": " +
|
||||
this.message.message;
|
||||
var messageTxtNode = this.textFactory(this.timestampedMessage);
|
||||
var messageTxtNode = this.textFactory(this.timestampedMessage + "\n");
|
||||
|
||||
this.messageNode.appendChild(messageTxtNode);
|
||||
|
||||
|
@ -49,6 +49,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_HUDServiceTestsAll.js \
|
||||
browser_warn_user_about_replaced_api.js \
|
||||
browser_webconsole_bug_585237_line_limit.js \
|
||||
browser_webconsole_bug_586142_insert_newlines.js \
|
||||
browser_webconsole_bug_586388_select_all.js \
|
||||
browser_webconsole_bug_588967_input_expansion.js \
|
||||
browser_webconsole_bug_580454_timestamp_l10n.js \
|
||||
@ -56,6 +57,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_webconsole_bug_593003_iframe_wrong_hud.js \
|
||||
browser_webconsole_bug_581231_close_button.js \
|
||||
browser_webconsole_consoleonpage.js \
|
||||
browser_webconsole_bug_587617_output_copy.js \
|
||||
$(NULL)
|
||||
|
||||
_BROWSER_TEST_PAGES = \
|
||||
|
@ -445,7 +445,7 @@ function testNullUndefinedOutput()
|
||||
is(group.childNodes.length, 2, "Three children in output");
|
||||
let outputChildren = group.childNodes;
|
||||
|
||||
is (outputChildren[1].childNodes[0].nodeValue, "null",
|
||||
is (outputChildren[1].childNodes[0].nodeValue, "null\n",
|
||||
"'null' printed to output");
|
||||
|
||||
jsterm.clearOutput();
|
||||
@ -455,7 +455,7 @@ function testNullUndefinedOutput()
|
||||
is(group.childNodes.length, 2, "Three children in output");
|
||||
outputChildren = group.childNodes;
|
||||
|
||||
is (outputChildren[1].childNodes[0].nodeValue, "undefined",
|
||||
is (outputChildren[1].childNodes[0].nodeValue, "undefined\n",
|
||||
"'undefined' printed to output");
|
||||
}
|
||||
|
||||
@ -1036,39 +1036,40 @@ function testJSTermHelper()
|
||||
jsterm.clearOutput();
|
||||
jsterm.execute("'id=' + $('header').getAttribute('id')");
|
||||
let group = jsterm.outputNode.querySelector(".hud-group");
|
||||
is(group.childNodes[1].textContent, "id=header", "$() worked");
|
||||
is(group.childNodes[1].textContent, "id=header\n", "$() worked");
|
||||
|
||||
jsterm.clearOutput();
|
||||
jsterm.execute("headerQuery = $$('h1')");
|
||||
jsterm.execute("'length=' + headerQuery.length");
|
||||
let group = jsterm.outputNode.querySelector(".hud-group");
|
||||
is(group.childNodes[3].textContent, "length=1", "$$() worked");
|
||||
is(group.childNodes[3].textContent, "length=1\n", "$$() worked");
|
||||
|
||||
jsterm.clearOutput();
|
||||
jsterm.execute("xpathQuery = $x('.//*', document.body);");
|
||||
jsterm.execute("'headerFound=' + (xpathQuery[0] == headerQuery[0])");
|
||||
let group = jsterm.outputNode.querySelector(".hud-group");
|
||||
is(group.childNodes[3].textContent, "headerFound=true", "$x() worked");
|
||||
is(group.childNodes[3].textContent, "headerFound=true\n", "$x() worked");
|
||||
|
||||
// no jsterm.clearOutput() here as we clear the output using the clear() fn.
|
||||
jsterm.execute("clear()");
|
||||
let group = jsterm.outputNode.querySelector(".hud-group");
|
||||
is(group.childNodes[0].textContent, "undefined", "clear() worked");
|
||||
is(group.childNodes[0].textContent, "undefined\n", "clear() worked");
|
||||
|
||||
jsterm.clearOutput();
|
||||
jsterm.execute("'keysResult=' + (keys({b:1})[0] == 'b')");
|
||||
let group = jsterm.outputNode.querySelector(".hud-group");
|
||||
is(group.childNodes[1].textContent, "keysResult=true", "keys() worked");
|
||||
is(group.childNodes[1].textContent, "keysResult=true\n", "keys() worked");
|
||||
|
||||
jsterm.clearOutput();
|
||||
jsterm.execute("'valuesResult=' + (values({b:1})[0] == 1)");
|
||||
let group = jsterm.outputNode.querySelector(".hud-group");
|
||||
is(group.childNodes[1].textContent, "valuesResult=true", "values() worked");
|
||||
is(group.childNodes[1].textContent, "valuesResult=true\n",
|
||||
"values() worked");
|
||||
|
||||
jsterm.clearOutput();
|
||||
jsterm.execute("pprint({b:2, a:1})");
|
||||
let group = jsterm.outputNode.querySelector(".hud-group");
|
||||
is(group.childNodes[1].textContent, " a: 1\n b: 2", "pprint() worked");
|
||||
is(group.childNodes[1].textContent, " a: 1\n b: 2\n", "pprint() worked");
|
||||
}
|
||||
|
||||
function testPropertyPanel()
|
||||
|
@ -0,0 +1,72 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Contributor(s):
|
||||
* Patrick Walton <pcwalton@mozilla.com>
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Tests that newlines are present in the output of the console, so that
|
||||
// copying works properly.
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const TEST_URI = "http://example.com/";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "HUDService", function () {
|
||||
Cu.import("resource://gre/modules/HUDService.jsm");
|
||||
return HUDService;
|
||||
});
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab(TEST_URI);
|
||||
gBrowser.selectedBrowser.addEventListener("DOMContentLoaded", onLoad, false);
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("DOMContentLoaded", onLoad,
|
||||
false);
|
||||
executeSoon(testNewlines);
|
||||
}
|
||||
|
||||
function testNewlines() {
|
||||
HUDService.activateHUDForContext(gBrowser.selectedTab);
|
||||
let hudId = HUDService.displaysIndex()[0];
|
||||
ok(hudId != null, "we have the HUD ID");
|
||||
|
||||
HUDService.clearDisplay(hudId);
|
||||
|
||||
let contentWindow = gBrowser.selectedTab.linkedBrowser.contentWindow;
|
||||
let console = contentWindow.wrappedJSObject.console;
|
||||
ok(console != null, "we have the console object");
|
||||
|
||||
for (let i = 0; i < 20; i++) {
|
||||
console.log("Hello world!");
|
||||
}
|
||||
|
||||
let hudNode = HUDService.getOutputNodeById(hudId);
|
||||
let outputNode = hudNode.querySelector(".hud-output-node");
|
||||
ok(outputNode != null, "we have the output node");
|
||||
|
||||
let labels = outputNode.querySelectorAll("label");
|
||||
is(labels.length, 20, "we found 20 labels in the output node");
|
||||
|
||||
for (let i = 0; i < labels.length; i++) {
|
||||
let value = labels[i].textContent;
|
||||
is(value[value.length - 1], "\n", "the value of label " + i + " ends " +
|
||||
"with a newline");
|
||||
}
|
||||
|
||||
HUDService.deactivateHUDForContext(gBrowser.selectedTab);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/HUDService.jsm");
|
||||
|
||||
const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
|
||||
|
||||
function tabLoaded() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", tabLoaded, true);
|
||||
|
||||
waitForFocus(function () {
|
||||
HUDService.activateHUDForContext(gBrowser.selectedTab);
|
||||
|
||||
// See bugs 574036, 586386 and 587617.
|
||||
|
||||
let HUD = HUDService.getDisplayByURISpec(content.location.href);
|
||||
let filterBox = HUD.querySelector(".hud-filter-box");
|
||||
let outputNode = HUD.querySelector(".hud-output-node");
|
||||
let selection = getSelection();
|
||||
let jstermInput = HUD.querySelector(".jsterm-input-node");
|
||||
let console = content.wrappedJSObject.console;
|
||||
let contentSelection = content.getSelection();
|
||||
|
||||
let make_selection = function () {
|
||||
let controller = top.document.commandDispatcher.
|
||||
getControllerForCommand("cmd_copy");
|
||||
is(controller.isCommandEnabled("cmd_copy"), false, "cmd_copy is disabled");
|
||||
|
||||
console.log("Hello world!");
|
||||
|
||||
let range = document.createRange();
|
||||
let selectedNode = outputNode.querySelector(".hud-group > label:last-child");
|
||||
range.selectNode(selectedNode);
|
||||
selection.addRange(range);
|
||||
|
||||
selectedNode.focus();
|
||||
|
||||
goUpdateCommand("cmd_copy");
|
||||
|
||||
controller = top.document.commandDispatcher.
|
||||
getControllerForCommand("cmd_copy");
|
||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||
|
||||
waitForClipboard(selectedNode.textContent, clipboard_setup,
|
||||
clipboard_copy_done, clipboard_copy_done);
|
||||
};
|
||||
|
||||
let clipboard_setup = function () {
|
||||
goDoCommand("cmd_copy");
|
||||
};
|
||||
|
||||
let clipboard_copy_done = function () {
|
||||
selection.removeAllRanges();
|
||||
testEnd();
|
||||
};
|
||||
|
||||
// Check if we first need to clear any existing selections.
|
||||
if (selection.rangeCount > 0 || contentSelection.rangeCount > 0 ||
|
||||
jstermInput.selectionStart != jstermInput.selectionEnd) {
|
||||
if (jstermInput.selectionStart != jstermInput.selectionEnd) {
|
||||
jstermInput.selectionStart = jstermInput.selectionEnd = 0;
|
||||
}
|
||||
|
||||
if (selection.rangeCount > 0) {
|
||||
selection.removeAllRanges();
|
||||
}
|
||||
|
||||
if (contentSelection.rangeCount > 0) {
|
||||
contentSelection.removeAllRanges();
|
||||
}
|
||||
|
||||
goUpdateCommand("cmd_copy");
|
||||
make_selection();
|
||||
}
|
||||
else {
|
||||
make_selection();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testEnd() {
|
||||
HUDService.deactivateHUDForContext(gBrowser.selectedTab);
|
||||
finish();
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", tabLoaded, true);
|
||||
|
||||
content.location = TEST_URI;
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ _TEST_FILES = test_bug360220.xul \
|
||||
test_closemenu_attribute.xul \
|
||||
test_colorpicker_popup.xul \
|
||||
test_deck.xul \
|
||||
test_menulist.xul \
|
||||
test_menuitem_blink.xul \
|
||||
test_menulist_keynav.xul \
|
||||
test_menulist_null_value.xul \
|
||||
|
241
toolkit/content/tests/widgets/test_menulist.xul
Normal file
241
toolkit/content/tests/widgets/test_menulist.xul
Normal file
@ -0,0 +1,241 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Menulist Tests"
|
||||
onload="setTimeout(testtag_menulists, 0);"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="xul_selectcontrol.js"></script>
|
||||
|
||||
<vbox id="scroller" style="overflow: auto" height="60">
|
||||
<menulist id="menulist" onpopupshown="test_menulist_open(this, this.parentNode)"
|
||||
onpopuphidden="$('menulist-in-listbox').open = true;">
|
||||
<menupopup id="menulist-popup"/>
|
||||
</menulist>
|
||||
<button label="Two"/>
|
||||
<button label="Three"/>
|
||||
</vbox>
|
||||
<listbox id="scroller-in-listbox" style="overflow: auto" height="60">
|
||||
<listitem allowevents="true">
|
||||
<menulist id="menulist-in-listbox" onpopupshown="test_menulist_open(this, this.parentNode.parentNode)"
|
||||
onpopuphidden="SimpleTest.executeSoon(checkScrollAndFinish)">
|
||||
<menupopup id="menulist-in-listbox-popup">
|
||||
<menuitem label="One" value="one"/>
|
||||
<menuitem label="Two" value="two"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</listitem>
|
||||
<listitem label="Two"/>
|
||||
<listitem label="Three"/>
|
||||
<listitem label="Four"/>
|
||||
<listitem label="Five"/>
|
||||
<listitem label="Six"/>
|
||||
</listbox>
|
||||
|
||||
<hbox>
|
||||
<menulist id="menulist-size">
|
||||
<menupopup>
|
||||
<menuitem label="Menuitem Label" width="200"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
|
||||
<menulist id="menulist-editable" editable="true">
|
||||
<menupopup id="menulist-popup-editable"/>
|
||||
</menulist>
|
||||
|
||||
<menulist id="menulist-initwithvalue" value="two">
|
||||
<menupopup>
|
||||
<menuitem label="One" value="one"/>
|
||||
<menuitem label="Two" value="two"/>
|
||||
<menuitem label="Three" value="three"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<menulist id="menulist-initwithselected" value="two">
|
||||
<menupopup>
|
||||
<menuitem label="One" value="one"/>
|
||||
<menuitem label="Two" value="two"/>
|
||||
<menuitem label="Three" value="three" selected="true"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<menulist id="menulist-editable-initwithvalue" editable="true" value="Two">
|
||||
<menupopup>
|
||||
<menuitem label="One" value="one"/>
|
||||
<menuitem label="Two" value="two"/>
|
||||
<menuitem label="Three" value="three"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<menulist id="menulist-editable-initwithselected" editable="true" value="two">
|
||||
<menupopup>
|
||||
<menuitem label="One" value="one"/>
|
||||
<menuitem label="Two" value="two"/>
|
||||
<menuitem label="Three" value="three" selected="true"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function testtag_menulists()
|
||||
{
|
||||
testtag_menulist_UI_start($("menulist"), false);
|
||||
testtag_menulist_UI_start($("menulist-editable"), true);
|
||||
|
||||
// bug 566154, the menulist width should account for vertical scrollbar
|
||||
ok(document.getElementById("menulist-size").getBoundingClientRect().width >= 210,
|
||||
"menulist popup width includes scrollbar width");
|
||||
|
||||
$("menulist").open = true;
|
||||
}
|
||||
|
||||
function testtag_menulist_UI_start(element, editable)
|
||||
{
|
||||
var testprefix = editable ? "editable" : "";
|
||||
|
||||
// check the menupopup property
|
||||
var popup = element.menupopup;
|
||||
ok(popup && popup.localName == "menupopup" &&
|
||||
popup.parentNode == element, testprefix + " menupopup");
|
||||
|
||||
// test the interfaces that menulist implements
|
||||
test_nsIDOMXULMenuListElement(element, testprefix, editable);
|
||||
|
||||
element.value = "";
|
||||
|
||||
test_nsIDOMXULSelectControlElement(element, "menuitem",
|
||||
editable ? "editable" : null);
|
||||
}
|
||||
|
||||
function test_nsIDOMXULMenuListElement(element, testprefix, editable)
|
||||
{
|
||||
is(element.open, false, testprefix + " open");
|
||||
is(element.editable, editable, testprefix + " editable");
|
||||
|
||||
if (editable) {
|
||||
var inputField = element.inputField;
|
||||
is(inputField &&
|
||||
inputField instanceof Components.interfaces.nsIDOMHTMLInputElement,
|
||||
true, testprefix + " inputField");
|
||||
|
||||
// check if the select method works
|
||||
inputField.select();
|
||||
is(inputField.selectionStart, 0, testprefix + " empty select selectionStart");
|
||||
is(inputField.selectionEnd, 0, testprefix + " empty select selectionEnd");
|
||||
|
||||
element.value = "Some Text";
|
||||
inputField.select();
|
||||
is(inputField.selectionStart, 0, testprefix + " empty select selectionStart");
|
||||
is(inputField.selectionEnd, 9, testprefix + " empty select selectionEnd");
|
||||
}
|
||||
else {
|
||||
is(element.inputField, null , testprefix + " inputField");
|
||||
}
|
||||
|
||||
element.appendItem("Item One", "one");
|
||||
var seconditem = element.appendItem("Item Two", "two");
|
||||
var thirditem = element.appendItem("Item Three", "three");
|
||||
element.appendItem("Item Four", "four");
|
||||
|
||||
seconditem.image = "happy.png";
|
||||
seconditem.setAttribute("description", "This is the second description");
|
||||
thirditem.image = "happy.png";
|
||||
thirditem.setAttribute("description", "This is the third description");
|
||||
|
||||
// check the image and description properties
|
||||
// editable menulists don't use the image or description properties currently
|
||||
if (editable) {
|
||||
element.selectedIndex = 1;
|
||||
is(element.image, "", testprefix + " image set to selected");
|
||||
is(element.description, "", testprefix + " description set to selected");
|
||||
}
|
||||
else {
|
||||
element.selectedIndex = 1;
|
||||
is(element.image, "happy.png", testprefix + " image set to selected");
|
||||
is(element.description, "This is the second description", testprefix + " description set to selected");
|
||||
element.selectedIndex = -1;
|
||||
is(element.image, "", testprefix + " image set when none selected");
|
||||
is(element.description, "", testprefix + " description set when none selected");
|
||||
element.selectedIndex = 2;
|
||||
is(element.image, "happy.png", testprefix + " image set to selected again");
|
||||
is(element.description, "This is the third description", testprefix + " description set to selected again");
|
||||
|
||||
// check that changing the properties of the selected item changes the menulist's properties
|
||||
thirditem.label = "Item Number Three";
|
||||
is(element.label, "Item Number Three", testprefix + " label modified");
|
||||
thirditem.value = "item-three";
|
||||
is(element.value, "item-three", testprefix + " value modified");
|
||||
thirditem.image = "smile.png";
|
||||
is(element.image, "smile.png", testprefix + " image modified");
|
||||
thirditem.setAttribute("description", "Changed description");
|
||||
is(element.description, "Changed description", testprefix + " description modified");
|
||||
seconditem.label = "Changed Label 2";
|
||||
is(element.label, "Item Number Three", testprefix + " label of another item modified");
|
||||
|
||||
element.selectedIndex = 0;
|
||||
is(element.image, "", testprefix + " image set to selected with no image");
|
||||
is(element.description, "", testprefix + " description set to selected with no description");
|
||||
}
|
||||
|
||||
// check the removeAllItems method
|
||||
element.appendItem("An Item", "anitem");
|
||||
element.appendItem("Another Item", "anotheritem");
|
||||
element.removeAllItems();
|
||||
is(element.itemCount, 0, testprefix + " removeAllItems");
|
||||
}
|
||||
|
||||
function test_menulist_open(element, scroller)
|
||||
{
|
||||
element.appendItem("Scroll Item 1", "scrollitem1");
|
||||
element.appendItem("Scroll Item 2", "scrollitem2");
|
||||
element.focus();
|
||||
|
||||
/*
|
||||
// bug 530504, mousewheel while menulist is open should not scroll menulist
|
||||
// items or parent
|
||||
var scrolled = false;
|
||||
var mouseScrolled = function (event) { scrolled = true; }
|
||||
window.addEventListener("DOMMouseScroll", mouseScrolled, false);
|
||||
synthesizeMouseScroll(element, 2, 2, { delta: 10 });
|
||||
is(scrolled, true, "mousescroll " + element.id);
|
||||
is(scroller.scrollTop, 0, "scroll position on mousescroll " + element.id);
|
||||
window.removeEventListener("DOMMouseScroll", mouseScrolled, false);
|
||||
*/
|
||||
|
||||
// bug 543065, hovering the mouse over an item should highlight it and not
|
||||
// scroll the parent
|
||||
var item = element.menupopup.childNodes[1];
|
||||
|
||||
synthesizeMouse(element.menupopup.childNodes[1], 2, 2, { type: "mousemove" });
|
||||
synthesizeMouse(element.menupopup.childNodes[1], 6, 6, { type: "mousemove" });
|
||||
is(element.menuBoxObject.activeChild, item, "activeChild after menu highlight " + element.id);
|
||||
is(scroller.scrollTop, 0, "scroll position after menu highlight " + element.id);
|
||||
|
||||
element.open = false;
|
||||
}
|
||||
|
||||
function checkScrollAndFinish()
|
||||
{
|
||||
is($("scroller").scrollTop, 0, "mousewheel on menulist does not scroll vbox parent");
|
||||
is($("scroller-in-listbox").scrollTop, 0, "mousewheel on menulist does not scroll listbox parent");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display">
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
</window>
|
@ -5,6 +5,8 @@
|
||||
// flag behaviours that differ for certain elements
|
||||
// allow-other-value - alternate values for the value property may be used
|
||||
// besides those in the list
|
||||
// other-value-clears-selection - alternative values for the value property
|
||||
// clears the selected item
|
||||
// selection-required - an item must be selected in the list, unless there
|
||||
// aren't any to select
|
||||
// activate-disabled-menuitem - disabled menuitems can be highlighted
|
||||
@ -15,7 +17,7 @@
|
||||
// The win:, mac: and gtk: or other prefixes may be used for platform specific behaviour
|
||||
var behaviours = {
|
||||
menu: "win:activate-disabled-menuitem activate-disabled-menuitem-mousemove select-keynav-wraps select-extended-keynav",
|
||||
menulist: "allow-other-value",
|
||||
menulist: "allow-other-value other-value-clears-selection",
|
||||
listbox: "select-extended-keynav",
|
||||
richlistbox: "select-extended-keynav",
|
||||
radiogroup: "select-keynav-wraps dont-select-disabled allow-other-value",
|
||||
@ -102,17 +104,22 @@ function test_nsIDOMXULSelectControlElement(element, childtag, testprefix)
|
||||
is(element.getItemAtIndex(2), null, testid + "getItemAtIndex - index 2 is null");
|
||||
|
||||
// check if setting the value changes the selection
|
||||
element.value = "first";
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "set value 1", 2, firstitem, 0, "first");
|
||||
element.value = "second";
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "set value 2", 2, seconditem, 1, "second");
|
||||
element.value = firstvalue;
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "set value 1", 2, firstitem, 0, firstvalue);
|
||||
element.value = secondvalue;
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "set value 2", 2, seconditem, 1, secondvalue);
|
||||
// setting the value attribute to one not in the list doesn't change the selection.
|
||||
// The value is only changed for elements which support having a value other than the
|
||||
// selection.
|
||||
element.value = "other";
|
||||
var allowOtherValue = behaviourContains(element.localName, "allow-other-value");
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "set value other", 2, seconditem, 1,
|
||||
allowOtherValue ? "other" : "second");
|
||||
var otherValueClearsSelection = behaviourContains(element.localName, "other-value-clears-selection");
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "set value other", 2,
|
||||
otherValueClearsSelection ? null : seconditem,
|
||||
otherValueClearsSelection ? -1 : 1,
|
||||
allowOtherValue ? "other" : secondvalue);
|
||||
if (allowOtherValue)
|
||||
element.value = "";
|
||||
|
||||
// 'removeItemAt' - check if removeItemAt removes the right item
|
||||
if (selectionRequired)
|
||||
@ -170,7 +177,8 @@ function test_nsIDOMXULSelectControlElement(element, childtag, testprefix)
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt 6", 1, fourthitem, 0, fourthvalue);
|
||||
|
||||
// 'insertItemAt' - check if insertItemAt inserts items at the right locations
|
||||
var fifthitem = test_nsIDOMXULSelectControlElement_insertItemAt(element, 0, 0, testid, 5);
|
||||
element.selectedIndex = 0;
|
||||
test_nsIDOMXULSelectControlElement_insertItemAt(element, 0, 0, testid, 5);
|
||||
test_nsIDOMXULSelectControlElement_insertItemAt(element, 2, 2, testid, 6);
|
||||
test_nsIDOMXULSelectControlElement_insertItemAt(element, -1, 3, testid, 7);
|
||||
test_nsIDOMXULSelectControlElement_insertItemAt(element, 6, 4, testid, 8);
|
||||
@ -194,19 +202,24 @@ function test_nsIDOMXULSelectControlElement(element, childtag, testprefix)
|
||||
|
||||
function test_nsIDOMXULSelectControlElement_init(element, testprefix)
|
||||
{
|
||||
// editable menulists use the label as the value
|
||||
var isEditable = (element.localName == "menulist" && element.editable);
|
||||
|
||||
var id = element.id;
|
||||
element = document.getElementById(id + "-initwithvalue");
|
||||
if (element) {
|
||||
var seconditem = element.getItemAtIndex(1);
|
||||
test_nsIDOMXULSelectControlElement_States(element, testprefix + " value initialization",
|
||||
3, seconditem, 1, seconditem.value);
|
||||
3, seconditem, 1,
|
||||
isEditable ? seconditem.label : seconditem.value);
|
||||
}
|
||||
|
||||
element = document.getElementById(id + "-initwithselected");
|
||||
if (element) {
|
||||
var thirditem = element.getItemAtIndex(2);
|
||||
test_nsIDOMXULSelectControlElement_States(element, testprefix + " selected initialization",
|
||||
3, thirditem, 2, thirditem.value);
|
||||
3, thirditem, 2,
|
||||
isEditable ? thirditem.label : thirditem.value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,7 +253,7 @@ function test_nsIDOMXULSelectControlElement_insertItemAt(element, index, expecte
|
||||
if (expectedSelIndex >= expectedindex)
|
||||
expectedSelIndex++;
|
||||
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "insertItemAt " + expectedindex,
|
||||
test_nsIDOMXULSelectControlElement_States(element, testid + "insertItemAt " + index,
|
||||
expectedCount, expectedSelItem,
|
||||
expectedSelIndex, expectedSelValue);
|
||||
return newitem;
|
||||
|
@ -318,7 +318,7 @@
|
||||
|
||||
<property name="webProgress"
|
||||
readonly="true"
|
||||
onget="return this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.webProgress;"/>
|
||||
onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/>
|
||||
|
||||
<field name="_contentWindow">null</field>
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
<!ENTITY listEmpty.findUpdates.label "Check For Updates">
|
||||
<!ENTITY listEmpty.search.label "Could not find any matching add-ons">
|
||||
<!ENTITY listEmpty.button.label "Learn more about add-ons">
|
||||
<!ENTITY installFromFile.label "Install From File…">
|
||||
<!ENTITY installFromFile.accesskey "I">
|
||||
<!ENTITY installAddonFromFile.label "Install Add-on From File…">
|
||||
<!ENTITY installAddonFromFile.accesskey "I">
|
||||
|
||||
<!ENTITY cmd.back.tooltip "Go back one page">
|
||||
<!ENTITY cmd.forward.tooltip "Go forward one page">
|
||||
@ -40,8 +40,6 @@
|
||||
<!ENTITY updates.updateAddonsNow.accesskey "U">
|
||||
<!ENTITY updates.viewUpdates.label "View Recent Updates">
|
||||
<!ENTITY updates.viewUpdates.accesskey "V">
|
||||
<!ENTITY updates.backgroudUpdateCheck.label "Check for Updates Automatically">
|
||||
<!ENTITY updates.backgroudUpdateCheck.accesskey "C">
|
||||
<!ENTITY updates.updateAddonsAutomatically.label "Update Add-ons Automatically">
|
||||
<!ENTITY updates.updateAddonsAutomatically.accesskey "A">
|
||||
<!ENTITY updates.resetUpdatesToAutomatic.label "Reset All Add-ons to Update Automatically">
|
||||
|
@ -91,15 +91,20 @@ const PROP_MULTI = ["developers", "screenshots"]
|
||||
const STRING_KEY_MAP = {
|
||||
name: "name",
|
||||
version: "version",
|
||||
summary: "description",
|
||||
description: "fullDescription",
|
||||
developer_comments: "developerComments",
|
||||
eula: "eula",
|
||||
icon: "iconURL",
|
||||
homepage: "homepageURL",
|
||||
support: "supportURL"
|
||||
};
|
||||
|
||||
// A map between XML keys to AddonSearchResult keys for string values
|
||||
// that require parsing from HTML
|
||||
const HTML_KEY_MAP = {
|
||||
summary: "description",
|
||||
description: "fullDescription",
|
||||
developer_comments: "developerComments",
|
||||
eula: "eula"
|
||||
};
|
||||
|
||||
// A map between XML keys to AddonSearchResult keys for integer values
|
||||
// that require no extra parsing from XML
|
||||
const INTEGER_KEY_MAP = {
|
||||
@ -109,6 +114,25 @@ const INTEGER_KEY_MAP = {
|
||||
};
|
||||
|
||||
|
||||
function convertHTMLToPlainText(html) {
|
||||
if (!html)
|
||||
return html;
|
||||
var converter = Cc["@mozilla.org/widget/htmlformatconverter;1"].
|
||||
createInstance(Ci.nsIFormatConverter);
|
||||
|
||||
var input = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
input.data = html.replace("\n", "<br>", "g");
|
||||
|
||||
var output = {};
|
||||
converter.convert("text/html", input, input.data.length, "text/unicode",
|
||||
output, {});
|
||||
|
||||
if (output.value instanceof Ci.nsISupportsString)
|
||||
return output.value.data.replace("\r\n", "\n", "g");
|
||||
return html;
|
||||
}
|
||||
|
||||
function AddonSearchResult(aId) {
|
||||
this.id = aId;
|
||||
}
|
||||
@ -787,6 +811,12 @@ var AddonRepository = {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle case where the wanted string value is html located in text content
|
||||
if (localName in HTML_KEY_MAP) {
|
||||
addon[HTML_KEY_MAP[localName]] = convertHTMLToPlainText(this._getTextContent(node));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle case where the wanted integer value is located in text content
|
||||
if (localName in INTEGER_KEY_MAP) {
|
||||
let value = parseInt(this._getTextContent(node));
|
||||
|
@ -4085,6 +4085,11 @@ function AddonInstall(aCallback, aInstallLocation, aUrl, aHash, aName, aType,
|
||||
this.listeners = [];
|
||||
this.existingAddon = aExistingAddon;
|
||||
this.error = 0;
|
||||
if (aLoadGroup)
|
||||
this.window = aLoadGroup.notificationCallbacks
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
else
|
||||
this.window = null;
|
||||
|
||||
if (aUrl instanceof Ci.nsIFileURL) {
|
||||
this.file = aUrl.file.QueryInterface(Ci.nsILocalFile);
|
||||
@ -4968,7 +4973,7 @@ AddonInstall.prototype = {
|
||||
if (iid.equals(Ci.nsIAuthPrompt2)) {
|
||||
var factory = Cc["@mozilla.org/prompter;1"].
|
||||
getService(Ci.nsIPromptFactory);
|
||||
return factory.getPrompt(null, Ci.nsIAuthPrompt);
|
||||
return factory.getPrompt(this.window, Ci.nsIAuthPrompt);
|
||||
}
|
||||
else if (iid.equals(Ci.nsIChannelEventSink)) {
|
||||
return this;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user