Merge m-c --> cedar

This commit is contained in:
Chris Jones 2010-09-15 16:44:30 -05:00
commit 06ec6c6ee8
125 changed files with 2664 additions and 1250 deletions

View File

@ -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"

View File

@ -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">

View File

@ -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) {

View File

@ -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 &amp;&amp; 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"

View File

@ -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()

View File

@ -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 -->

View File

@ -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
}
}
};

View File

@ -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>

View File

@ -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 \

View 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();
}

View File

@ -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">

View File

@ -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">

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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,

View File

@ -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();
}
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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 \

View File

@ -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 \

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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>

View 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>

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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 ||

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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)

View 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>

View File

@ -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;

View File

@ -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)
{
}

View File

@ -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 */

View File

@ -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__ */

View File

@ -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

View File

@ -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

View 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>

View 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>

View File

@ -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

View 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>

View File

@ -60,3 +60,4 @@ load 558943-1.xhtml
load 571105-1.xhtml
load 573127-1.html
load 580685.html
load 592698-1.html

View File

@ -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;

View File

@ -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;

View File

@ -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)
};

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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();
};

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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 = \

View File

@ -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()

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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 \

View 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>

View File

@ -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;

View File

@ -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>

View File

@ -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">

View File

@ -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));

View File

@ -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