mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to services-central.
This commit is contained in:
commit
16918a2d25
@ -1,193 +1,201 @@
|
||||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1306529826000">
|
||||
<emItems>
|
||||
<emItem id="fdm_ffext@freedownloadmanager.org">
|
||||
<versionRange minVersion="1.0" maxVersion="1.3.1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="firefox@bandoo.com">
|
||||
<versionRange minVersion="5.0" maxVersion="5.0" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="langpack-vi-VN@firefox.mozilla.org">
|
||||
<versionRange minVersion="2.0" maxVersion="2.0"/>
|
||||
</emItem>
|
||||
<emItem id="masterfiler@gmail.com">
|
||||
<versionRange severity="3"/>
|
||||
</emItem>
|
||||
<emItem id="mozilla_cc@internetdownloadmanager.com">
|
||||
<versionRange minVersion=" " maxVersion="6.9.8">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
<versionRange minVersion="2.1" maxVersion="3.3">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="msntoolbar@msn.com">
|
||||
<versionRange minVersion=" " maxVersion="6.*"/>
|
||||
</emItem>
|
||||
<emItem id="personas@christopher.beard">
|
||||
<versionRange minVersion="1.6" maxVersion="1.6">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.6" maxVersion="3.6.*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="ShopperReports@ShopperReports.com">
|
||||
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0"/>
|
||||
</emItem>
|
||||
<emItem id="support@daemon-tools.cc">
|
||||
<versionRange minVersion=" " maxVersion="1.0.0.5"/>
|
||||
</emItem>
|
||||
<emItem id="support@update-firefox.com"/>
|
||||
<emItem id="yslow@yahoo-inc.com">
|
||||
<versionRange minVersion="2.0.5" maxVersion="2.0.5">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.5.7" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="{2224e955-00e9-4613-a844-ce69fccaae91}"/>
|
||||
<emItem id="{27182e60-b5f3-411c-b545-b44205977502}">
|
||||
<versionRange minVersion="1.0" maxVersion="1.0"/>
|
||||
</emItem>
|
||||
<emItem id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
|
||||
<versionRange minVersion="2.2" maxVersion="2.2"/>
|
||||
</emItem>
|
||||
<emItem id="{3f963a5b-e555-4543-90e2-c3908898db71}">
|
||||
<versionRange minVersion=" " maxVersion="8.5"/>
|
||||
</emItem>
|
||||
<emItem id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
|
||||
<versionRange minVersion="1.1b1" maxVersion="1.1b1"/>
|
||||
</emItem>
|
||||
<emItem id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
|
||||
<versionRange minVersion="1.2" maxVersion="1.2">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="{6E19037A-12E3-4295-8915-ED48BC341614}">
|
||||
<versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="{8CE11043-9A15-4207-A565-0C94C42D590D}"/>
|
||||
<emItem id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
|
||||
<versionRange minVersion="0.1" maxVersion="5.2.0.7164" severity="1"/>
|
||||
</emItem>
|
||||
<emItem id="{B13721C7-F507-4982-B2E5-502A71474FED}">
|
||||
<versionRange severity="1"/>
|
||||
</emItem>
|
||||
<emItem id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
|
||||
<versionRange minVersion="0.1" maxVersion="3.3.0.*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
<versionRange minVersion="3.3.1" maxVersion="*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="5.0a1" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="{E8E88AB0-7182-11DF-904E-6045E0D72085}"/>
|
||||
</emItems>
|
||||
<pluginItems>
|
||||
<pluginItem>
|
||||
<match name="name" exp="^Yahoo Application State Plugin$"/>
|
||||
<match name="description" exp="^Yahoo Application State Plugin$"/>
|
||||
<match name="filename" exp="npYState.dll"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="name" exp="QuickTime Plug-in 7[.]1[.]"/>
|
||||
<match name="filename" exp="npqtplugin.?[.]dll"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="filename" exp="NPFFAddOn.dll"/>
|
||||
<versionRange>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="filename" exp="NPMySrch.dll"/>
|
||||
<versionRange>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="filename" exp="npViewpoint.dll"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+"/>
|
||||
<match name="filename" exp="npdeploytk.dll"/>
|
||||
<versionRange severity="1">
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.6a1pre" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
</pluginItems>
|
||||
<gfxItems>
|
||||
<gfxBlacklistEntry>
|
||||
<os>WINNT 6.1</os>
|
||||
<vendor>0x10de</vendor>
|
||||
<devices>
|
||||
<device>0x0a6c</device>
|
||||
</devices>
|
||||
<feature>DIRECT2D</feature>
|
||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
||||
<driverVersion>8.17.12.5896</driverVersion>
|
||||
<driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
|
||||
</gfxBlacklistEntry>
|
||||
<gfxBlacklistEntry>
|
||||
<os>WINNT 6.1</os>
|
||||
<vendor>0x10de</vendor>
|
||||
<devices>
|
||||
<device>0x0a6c</device>
|
||||
</devices>
|
||||
<feature>DIRECT3D_9_LAYERS</feature>
|
||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
||||
<driverVersion>8.17.12.5896</driverVersion>
|
||||
<driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
|
||||
</gfxBlacklistEntry>
|
||||
<gfxBlacklistEntry>
|
||||
<os>WINNT 5.1</os>
|
||||
<vendor>0x10de</vendor>
|
||||
<feature>DIRECT3D_9_LAYERS</feature>
|
||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
||||
<driverVersion>7.0.0.0</driverVersion>
|
||||
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
|
||||
</gfxBlacklistEntry>
|
||||
</gfxItems>
|
||||
</blocklist>
|
||||
<emItem blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
|
||||
<versionRange minVersion=" " severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
|
||||
<versionRange minVersion="0.1" maxVersion="3.3.0.*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
<versionRange minVersion="3.3.1" maxVersion="*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="5.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
|
||||
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
|
||||
<versionRange minVersion="1.0" maxVersion="1.0">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
|
||||
</emItem>
|
||||
<emItem blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
|
||||
<versionRange minVersion="2.1" maxVersion="3.3">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
<versionRange minVersion=" " maxVersion="6.9.8">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i18" id="msntoolbar@msn.com">
|
||||
<versionRange minVersion=" " maxVersion="6.*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
|
||||
</emItem>
|
||||
<emItem blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
|
||||
<versionRange minVersion="1.2" maxVersion="1.2">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i23" id="firefox@bandoo.com">
|
||||
<versionRange minVersion="5.0" maxVersion="5.0" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i22" id="ShopperReports@ShopperReports.com">
|
||||
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i2" id="fdm_ffext@freedownloadmanager.org">
|
||||
<versionRange minVersion="1.0" maxVersion="1.3.1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i5" id="support@daemon-tools.cc">
|
||||
<versionRange minVersion=" " maxVersion="1.0.0.5">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
|
||||
<versionRange minVersion=" " maxVersion="8.5">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i12" id="masterfiler@gmail.com">
|
||||
<versionRange severity="3">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
|
||||
<versionRange minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i11" id="yslow@yahoo-inc.com">
|
||||
<versionRange minVersion="2.0.5" maxVersion="2.0.5">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.5.7" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
|
||||
<versionRange minVersion="2.2" maxVersion="2.2">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
|
||||
<versionRange minVersion="2.0" maxVersion="2.0">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
|
||||
</emItem>
|
||||
<emItem blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
|
||||
<versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i15" id="personas@christopher.beard">
|
||||
<versionRange minVersion="1.6" maxVersion="1.6">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.6" maxVersion="3.6.*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i21" id="support@update-firefox.com">
|
||||
</emItem>
|
||||
</emItems>
|
||||
|
||||
<pluginItems>
|
||||
<pluginItem blockID="p26">
|
||||
<match name="name" exp="^Yahoo Application State Plugin$" /> <match name="description" exp="^Yahoo Application State Plugin$" /> <match name="filename" exp="npYState.dll" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p27">
|
||||
<match name="name" exp="QuickTime Plug-in 7[.]1[.]" /> <match name="filename" exp="npqtplugin.?[.]dll" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p28">
|
||||
<match name="filename" exp="NPFFAddOn.dll" /> <versionRange >
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p31">
|
||||
<match name="filename" exp="NPMySrch.dll" /> <versionRange >
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p32">
|
||||
<match name="filename" exp="npViewpoint.dll" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p33">
|
||||
<match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" /> <match name="filename" exp="npdeploytk.dll" /> <versionRange severity="1">
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p34">
|
||||
<match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.6a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
</pluginItems>
|
||||
|
||||
<gfxItems>
|
||||
<gfxBlacklistEntry blockID="g35">
|
||||
<os>WINNT 6.1</os>
|
||||
<vendor>0x10de</vendor>
|
||||
<devices>
|
||||
<device>0x0a6c</device>
|
||||
</devices>
|
||||
<feature>DIRECT2D</feature>
|
||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
||||
<driverVersion>8.17.12.5896</driverVersion>
|
||||
<driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
|
||||
</gfxBlacklistEntry>
|
||||
<gfxBlacklistEntry blockID="g36">
|
||||
<os>WINNT 6.1</os>
|
||||
<vendor>0x10de</vendor>
|
||||
<devices>
|
||||
<device>0x0a6c</device>
|
||||
</devices>
|
||||
<feature>DIRECT3D_9_LAYERS</feature>
|
||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
||||
<driverVersion>8.17.12.5896</driverVersion>
|
||||
<driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
|
||||
</gfxBlacklistEntry>
|
||||
<gfxBlacklistEntry blockID="g37">
|
||||
<os>WINNT 5.1</os>
|
||||
<vendor>0x10de</vendor>
|
||||
<feature>DIRECT3D_9_LAYERS</feature>
|
||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
||||
<driverVersion>7.0.0.0</driverVersion>
|
||||
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
|
||||
</gfxBlacklistEntry>
|
||||
</gfxItems>
|
||||
|
||||
|
||||
</blocklist>
|
@ -900,6 +900,10 @@ pref("dom.ipc.plugins.enabled.x86_64", true);
|
||||
pref("dom.ipc.plugins.enabled", true);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
pref("browser.tabs.remote", true);
|
||||
#endif
|
||||
|
||||
// This pref governs whether we attempt to work around problems caused by
|
||||
// plugins using OS calls to manipulate the cursor while running out-of-
|
||||
// process. These workarounds all involve intercepting (hooking) certain
|
||||
|
@ -595,6 +595,7 @@ var allTabs = {
|
||||
delete this.tabCloseButton;
|
||||
return this.tabCloseButton = document.getElementById("allTabs-tab-close-button");
|
||||
},
|
||||
get toolbarButton() document.getElementById("alltabs-button"),
|
||||
get previews () this.container.getElementsByClassName("allTabs-preview"),
|
||||
get isOpen () this.panel.state == "open" || this.panel.state == "showing",
|
||||
|
||||
@ -632,7 +633,7 @@ var allTabs = {
|
||||
|
||||
prefName: "browser.allTabs.previews",
|
||||
readPref: function allTabs_readPref() {
|
||||
var allTabsButton = document.getElementById("alltabs-button");
|
||||
var allTabsButton = this.toolbarButton;
|
||||
if (!allTabsButton)
|
||||
return;
|
||||
|
||||
@ -697,6 +698,17 @@ var allTabs = {
|
||||
},
|
||||
|
||||
open: function allTabs_open() {
|
||||
var allTabsButton = this.toolbarButton;
|
||||
if (allTabsButton &&
|
||||
allTabsButton.getAttribute("type") == "menu") {
|
||||
// Without setTimeout, the menupopup won't stay open when invoking
|
||||
// "View > Show All Tabs" and the menu bar auto-hides.
|
||||
setTimeout(function () {
|
||||
allTabsButton.open = true;
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
this.init();
|
||||
|
||||
if (this.isOpen)
|
||||
|
@ -1459,9 +1459,13 @@ function prepareForStartup() {
|
||||
Components.utils.reportError("Places database may be locked: " + ex);
|
||||
}
|
||||
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666801 - WebProgress support for e10s
|
||||
#else
|
||||
// hook up UI through progress listener
|
||||
gBrowser.addProgressListener(window.XULBrowserWindow);
|
||||
gBrowser.addTabsProgressListener(window.TabsProgressListener);
|
||||
#endif
|
||||
|
||||
// setup our common DOMLinkAdded listener
|
||||
gBrowser.addEventListener("DOMLinkAdded", DOMLinkHandler, false);
|
||||
@ -1583,9 +1587,13 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
Components.utils.reportError("Failed to init content pref service:\n" + ex);
|
||||
}
|
||||
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666804 - NetworkPrioritizer support for e10s
|
||||
#else
|
||||
let NP = {};
|
||||
Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
|
||||
NP.trackBrowserWindow(window);
|
||||
#endif
|
||||
|
||||
// initialize the session-restore service (in case it's not already running)
|
||||
try {
|
||||
@ -1636,8 +1644,12 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
|
||||
gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
|
||||
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666808 - AeroPeek support for e10s
|
||||
#else
|
||||
if (Win7Features)
|
||||
Win7Features.onOpenWindow();
|
||||
#endif
|
||||
|
||||
// called when we go into full screen, even if it is
|
||||
// initiated by a web page script
|
||||
@ -4157,11 +4169,15 @@ var XULBrowserWindow = {
|
||||
init: function () {
|
||||
this.throbberElement = document.getElementById("navigator-throbber");
|
||||
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666809 - SecurityUI support for e10s
|
||||
#else
|
||||
// Initialize the security button's state and tooltip text. Remember to reset
|
||||
// _hostChanged, otherwise onSecurityChange will short circuit.
|
||||
var securityUI = gBrowser.securityUI;
|
||||
this._hostChanged = true;
|
||||
this.onSecurityChange(null, null, securityUI.state);
|
||||
#endif
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
|
@ -96,8 +96,9 @@ function open()
|
||||
{
|
||||
var url;
|
||||
var postData = {};
|
||||
var mayInheritPrincipal = {value: false};
|
||||
if (browser)
|
||||
url = browser.getShortcutOrURI(dialog.input.value, postData);
|
||||
url = browser.getShortcutOrURI(dialog.input.value, postData, mayInheritPrincipal);
|
||||
else
|
||||
url = dialog.input.value;
|
||||
|
||||
@ -106,7 +107,11 @@ function open()
|
||||
// fixup the URI
|
||||
switch (dialog.openWhereList.value) {
|
||||
case "0":
|
||||
browser.loadURI(url, null, postData.value, true);
|
||||
var webNav = Components.interfaces.nsIWebNavigation;
|
||||
var flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
|
||||
if (!mayInheritPrincipal.value)
|
||||
flags |= webNav.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
|
||||
browser.gBrowser.loadURIWithFlags(url, flags, null, null, postData.value);
|
||||
break;
|
||||
case "1":
|
||||
window.opener.delayedOpenWindow(getBrowserURL(), "all,dialog=no",
|
||||
|
@ -777,12 +777,10 @@
|
||||
<body>
|
||||
<![CDATA[
|
||||
var newTitle = "";
|
||||
var docTitle;
|
||||
var docElement = this.ownerDocument.documentElement;
|
||||
var sep = docElement.getAttribute("titlemenuseparator");
|
||||
|
||||
if (aBrowser.docShell.contentViewer)
|
||||
docTitle = aBrowser.contentTitle;
|
||||
var docTitle = aBrowser.contentTitle;
|
||||
|
||||
if (!docTitle)
|
||||
docTitle = docElement.getAttribute("titledefault");
|
||||
@ -859,7 +857,7 @@
|
||||
var oldBrowser = this.mCurrentBrowser;
|
||||
if (oldBrowser) {
|
||||
oldBrowser.setAttribute("type", "content-targetable");
|
||||
oldBrowser.docShell.isActive = false;
|
||||
oldBrowser.docShellIsActive = false;
|
||||
}
|
||||
|
||||
var updatePageReport = false;
|
||||
@ -869,7 +867,7 @@
|
||||
updatePageReport = true;
|
||||
|
||||
newBrowser.setAttribute("type", "content-primary");
|
||||
newBrowser.docShell.isActive = true;
|
||||
newBrowser.docShellIsActive = true;
|
||||
this.mCurrentBrowser = newBrowser;
|
||||
this.mCurrentTab = this.selectedTab;
|
||||
this.showTab(this.mCurrentTab);
|
||||
@ -880,6 +878,10 @@
|
||||
// Update the URL bar.
|
||||
var loc = this.mCurrentBrowser.currentURI;
|
||||
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666801 - WebProgress support for e10s and
|
||||
// Bug 666809 - SecurityUI support for e10s
|
||||
#else
|
||||
var webProgress = this.mCurrentBrowser.webProgress;
|
||||
var securityUI = this.mCurrentBrowser.securityUI;
|
||||
|
||||
@ -890,6 +892,7 @@
|
||||
this._callProgressListeners(null, "onSecurityChange",
|
||||
[webProgress, null, securityUI.state], true, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
var listener = this.mTabListeners[this.tabContainer.selectedIndex] || null;
|
||||
if (listener && listener.mStateFlags) {
|
||||
@ -901,7 +904,11 @@
|
||||
|
||||
// Don't switch the fast find or update the titlebar (bug 540248) - this tab switch is temporary
|
||||
if (!this._previewMode) {
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666816 - TypeAheadFind support for e10s
|
||||
#else
|
||||
this._fastFind.setDocShell(this.mCurrentBrowser.docShell);
|
||||
#endif
|
||||
|
||||
this.updateTitlebar();
|
||||
|
||||
@ -1263,6 +1270,11 @@
|
||||
b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
|
||||
b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
|
||||
|
||||
if (Services.prefs.getPrefType("browser.tabs.remote") == Services.prefs.PREF_BOOL &&
|
||||
Services.prefs.getBoolPref("browser.tabs.remote")) {
|
||||
b.setAttribute("remote", "true");
|
||||
}
|
||||
|
||||
if (window.gShowPageResizers && document.getElementById("addon-bar").collapsed &&
|
||||
window.windowState == window.STATE_NORMAL) {
|
||||
b.setAttribute("showresizer", "true");
|
||||
@ -1310,7 +1322,11 @@
|
||||
const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
|
||||
.createInstance(Components.interfaces.nsIWebProgress);
|
||||
filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666801 - WebProgress support for e10s
|
||||
#else
|
||||
b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
|
||||
#endif
|
||||
this.mTabListeners[position] = tabListener;
|
||||
this.mTabFilters[position] = filter;
|
||||
|
||||
@ -1348,7 +1364,7 @@
|
||||
|
||||
// We start our browsers out as inactive, and then maintain
|
||||
// activeness in the tab switcher.
|
||||
b.docShell.isActive = false;
|
||||
b.docShellIsActive = false;
|
||||
|
||||
// Check if we're opening a tab related to the current tab and
|
||||
// move it to after the current tab.
|
||||
@ -1567,7 +1583,11 @@
|
||||
|
||||
// Remove the tab's filter and progress listener.
|
||||
const filter = this.mTabFilters[aTab._tPos];
|
||||
#ifdef MOZ_E10S_COMPAT
|
||||
// Bug 666801 - WebProgress support for e10s
|
||||
#else
|
||||
browser.webProgress.removeProgressListener(filter);
|
||||
#endif
|
||||
filter.removeProgressListener(this.mTabListeners[aTab._tPos]);
|
||||
this.mTabListeners[aTab._tPos].destroy();
|
||||
|
||||
|
@ -265,8 +265,11 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
let tabData = null;
|
||||
let self = this;
|
||||
let imageDataCb = function(imageData) {
|
||||
// we could have been unlinked while waiting for the thumbnail to load
|
||||
if (!self.tab)
|
||||
return;
|
||||
|
||||
Utils.assertThrow(tabData, "tabData");
|
||||
|
||||
tabData.imageData = imageData;
|
||||
|
||||
let currentUrl = self.tab.linkedBrowser.currentURI.spec;
|
||||
|
@ -220,6 +220,7 @@ _BROWSER_FILES = \
|
||||
browser_tabfocus.js \
|
||||
browser_tabs_isActive.js \
|
||||
browser_tabs_owner.js \
|
||||
browser_urlbarCopying.js \
|
||||
browser_urlbarTrimURLs.js \
|
||||
browser_urlHighlight.js \
|
||||
browser_visibleFindSelection.js \
|
||||
|
@ -1,5 +1,11 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref(allTabs.prefName, true);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(allTabs.prefName);
|
||||
});
|
||||
|
||||
allTabs.init();
|
||||
nextSequence();
|
||||
}
|
||||
|
165
browser/base/content/test/browser_urlbarCopying.js
Normal file
165
browser/base/content/test/browser_urlbarCopying.js
Normal file
@ -0,0 +1,165 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const trimPref = "browser.urlbar.trimURLs";
|
||||
|
||||
function test() {
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gBrowser.removeCurrentTab();
|
||||
Services.prefs.clearUserPref(trimPref);
|
||||
URLBarSetURI();
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref(trimPref, true);
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// pageproxystate="invalid"
|
||||
{
|
||||
setURL: "http://example.com/",
|
||||
expectedURL: "example.com",
|
||||
copyExpected: "example.com"
|
||||
},
|
||||
{
|
||||
copyVal: "<e>xample.com",
|
||||
copyExpected: "e"
|
||||
},
|
||||
|
||||
|
||||
// pageproxystate="valid" from this point on (due to the load)
|
||||
{
|
||||
loadURL: "http://example.com/",
|
||||
expectedURL: "example.com",
|
||||
copyExpected: "http://example.com/"
|
||||
},
|
||||
{
|
||||
copyVal: "<example.co>m",
|
||||
copyExpected: "http://example.co"
|
||||
},
|
||||
{
|
||||
copyVal: "e<x>ample.com",
|
||||
copyExpected: "x"
|
||||
},
|
||||
{
|
||||
copyVal: "<e>xample.com",
|
||||
copyExpected: "http://e"
|
||||
},
|
||||
|
||||
// Test escaping
|
||||
{
|
||||
loadURL: "http://example.com/()%C3%A9",
|
||||
expectedURL: "example.com/()\xe9",
|
||||
copyExpected: "http://example.com/%28%29%C3%A9"
|
||||
},
|
||||
{
|
||||
copyVal: "<example.com/(>)\xe9",
|
||||
copyExpected: "http://example.com/("
|
||||
},
|
||||
{
|
||||
copyVal: "e<xample.com/(>)\xe9",
|
||||
copyExpected: "xample.com/("
|
||||
},
|
||||
|
||||
{
|
||||
loadURL: "http://example.com/%C3%A9%C3%A9",
|
||||
expectedURL: "example.com/\xe9\xe9",
|
||||
copyExpected: "http://example.com/%C3%A9%C3%A9"
|
||||
},
|
||||
{
|
||||
copyVal: "e<xample.com/\xe9>\xe9",
|
||||
copyExpected: "xample.com/\xe9"
|
||||
},
|
||||
{
|
||||
copyVal: "<example.com/\xe9>\xe9",
|
||||
copyExpected: "http://example.com/\xe9"
|
||||
},
|
||||
|
||||
// data: and javsacript: URIs shouldn't be encoded
|
||||
{
|
||||
loadURL: "javascript:('%C3%A9')",
|
||||
expectedURL: "javascript:('\xe9')",
|
||||
copyExpected: "javascript:('\xe9')"
|
||||
},
|
||||
{
|
||||
copyVal: "<javascript:(>'\xe9')",
|
||||
copyExpected: "javascript:("
|
||||
},
|
||||
|
||||
{
|
||||
loadURL: "data:text/html,(%C3%A9)",
|
||||
expectedURL: "data:text/html,(\xe9)",
|
||||
copyExpected: "data:text/html,(\xe9)"
|
||||
},
|
||||
{
|
||||
copyVal: "<data:text/html,(>\xe9)",
|
||||
copyExpected: "data:text/html,("
|
||||
},
|
||||
{
|
||||
copyVal: "data:<text/html,(\xe9>)",
|
||||
copyExpected: "text/html,(\xe9"
|
||||
}
|
||||
];
|
||||
|
||||
function nextTest() {
|
||||
let test = tests.shift();
|
||||
if (tests.length == 0)
|
||||
runTest(test, finish);
|
||||
else
|
||||
runTest(test, nextTest);
|
||||
}
|
||||
|
||||
function runTest(test, cb) {
|
||||
function doCheck() {
|
||||
if (test.setURL || test.loadURL)
|
||||
is(gURLBar.value, test.expectedURL, "url bar value set");
|
||||
|
||||
testCopy(test.copyVal, test.copyExpected, cb);
|
||||
}
|
||||
|
||||
if (test.loadURL) {
|
||||
loadURL(test.loadURL, doCheck);
|
||||
} else {
|
||||
if (test.setURL)
|
||||
gURLBar.value = test.setURL;
|
||||
doCheck();
|
||||
}
|
||||
}
|
||||
|
||||
function testCopy(copyVal, targetValue, cb) {
|
||||
info("Expecting copy of: " + targetValue);
|
||||
waitForClipboard(targetValue, function () {
|
||||
gURLBar.focus();
|
||||
if (copyVal) {
|
||||
let startBracket = copyVal.indexOf("<");
|
||||
let endBracket = copyVal.indexOf(">");
|
||||
if (startBracket == -1 || endBracket == -1 ||
|
||||
startBracket > endBracket ||
|
||||
copyVal.replace("<", "").replace(">", "") != gURLBar.value) {
|
||||
ok(false, "invalid copyVal: " + copyVal);
|
||||
}
|
||||
gURLBar.selectionStart = startBracket;
|
||||
gURLBar.selectionEnd = endBracket - 1;
|
||||
} else {
|
||||
gURLBar.select();
|
||||
}
|
||||
|
||||
goDoCommand("cmd_copy");
|
||||
}, cb, cb);
|
||||
}
|
||||
|
||||
function loadURL(aURL, aCB) {
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
is(gBrowser.currentURI.spec, aURL, "loaded expected URL");
|
||||
aCB();
|
||||
}, true);
|
||||
|
||||
gBrowser.loadURI(aURL);
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
|
||||
function testVal(originalValue, targetValue) {
|
||||
gURLBar.value = originalValue;
|
||||
is(gURLBar.value, targetValue || originalValue, "original value: " + originalValue);
|
||||
is(gURLBar.value, targetValue || originalValue, "url bar value set");
|
||||
}
|
||||
|
||||
function test() {
|
||||
@ -72,7 +72,7 @@ function test() {
|
||||
|
||||
function testCopy(originalValue, targetValue, cb) {
|
||||
waitForClipboard(targetValue, function () {
|
||||
is(gURLBar.value, originalValue);
|
||||
is(gURLBar.value, originalValue, "url bar copy value set");
|
||||
|
||||
gURLBar.focus();
|
||||
gURLBar.select();
|
||||
|
@ -505,23 +505,40 @@
|
||||
<body><![CDATA[
|
||||
// Grab the actual input field's value, not our value, which could include moz-action:
|
||||
var inputVal = this.inputField.value;
|
||||
var val = inputVal.substring(this.selectionStart, this.selectionEnd);
|
||||
var selectedVal = inputVal.substring(this.selectionStart, this.selectionEnd);
|
||||
|
||||
// If the entire value is selected and it's a valid non-javascript,
|
||||
// non-data URI, encode it.
|
||||
if (val == inputVal &&
|
||||
this.getAttribute("pageproxystate") == "valid") {
|
||||
let uri = gBrowser.currentURI;
|
||||
// If the selection doesn't start at the beginning or URL bar is
|
||||
// modified, nothing else to do here.
|
||||
if (this.getAttribute("pageproxystate") != "valid" || this.selectionStart > 0)
|
||||
return selectedVal;
|
||||
|
||||
if (uri && !uri.schemeIs("javascript") && !uri.schemeIs("data")) {
|
||||
val = uri.spec;
|
||||
let uri = gBrowser.currentURI;
|
||||
|
||||
// If the entire URL is selected, just use the actual loaded URI.
|
||||
if (inputVal == selectedVal) {
|
||||
// ... but only if isn't a javascript: or data: URI, since those
|
||||
// are hard to read when encoded
|
||||
if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
|
||||
// Parentheses are known to confuse third-party applications (bug 458565).
|
||||
val = val.replace(/[()]/g, function (c) escape(c));
|
||||
selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c));
|
||||
}
|
||||
|
||||
return selectedVal;
|
||||
}
|
||||
|
||||
return val;
|
||||
// Just the beginning of the URL is selected, check for a trimmed
|
||||
// value
|
||||
let spec = uri.spec;
|
||||
let trimmedSpec = this.trimValue(spec);
|
||||
if (spec != trimmedSpec) {
|
||||
// Prepend the portion that trimValue removed from the beginning.
|
||||
// This assumes trimValue will only truncate the URL at
|
||||
// the beginning or end (or both).
|
||||
let trimmedSegments = spec.split(trimmedSpec);
|
||||
selectedVal = trimmedSegments[0] + selectedVal;
|
||||
}
|
||||
|
||||
return selectedVal;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -9,7 +9,7 @@ pref("app.update.interval", 28800);
|
||||
pref("app.update.download.backgroundInterval", 60);
|
||||
// URL user can browse to manually if for some reason all update installation
|
||||
// attempts fail.
|
||||
pref("app.update.url.manual", "http://nightly.mozilla.org/");
|
||||
pref("app.update.url.manual", "http://www.mozilla.com/firefox/channel/");
|
||||
// A default value for the "More information about this update" link
|
||||
// supplied in the "An update is available" page of the update wizard.
|
||||
pref("app.update.url.details", "http://www.mozilla.org/projects/%APP%/");
|
||||
|
@ -24,12 +24,10 @@ let PlacesOrganizer;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
openLibrary(onLibraryReady);
|
||||
gLibrary = openLibrary(onLibraryReady);
|
||||
}
|
||||
|
||||
function onLibraryReady(library) {
|
||||
gLibrary = library;
|
||||
|
||||
function onLibraryReady() {
|
||||
ok(PlacesUtils, "PlacesUtils in scope");
|
||||
ok(PlacesUIUtils, "PlacesUIUtils in scope");
|
||||
|
||||
|
@ -6,13 +6,14 @@ const TEST_URL = "http://example.com/";
|
||||
|
||||
let gLibrary;
|
||||
let gItemId;
|
||||
let PlacesOrganizer;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
gLibrary = openLibrary(onLibraryReady);
|
||||
}
|
||||
|
||||
function onLibraryReady(library) {
|
||||
function onLibraryReady() {
|
||||
PlacesOrganizer = gLibrary.PlacesOrganizer;
|
||||
|
||||
// Sanity checks.
|
||||
|
@ -96,10 +96,7 @@ function test() {
|
||||
.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
});
|
||||
|
||||
openLibrary(function (library) {
|
||||
gLibrary = library;
|
||||
executeSoon(nextTest);
|
||||
});
|
||||
gLibrary = openLibrary(nextTest);
|
||||
}
|
||||
|
||||
function nextTest() {
|
||||
@ -111,6 +108,6 @@ function nextTest() {
|
||||
else {
|
||||
// Close Library window.
|
||||
gLibrary.close();
|
||||
executeSoon(finish);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
@ -180,8 +180,5 @@ function test() {
|
||||
ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
|
||||
|
||||
// Open Library.
|
||||
openLibrary(function (library) {
|
||||
gLibrary = library;
|
||||
nextTest();
|
||||
});
|
||||
gLibrary = openLibrary(nextTest);
|
||||
}
|
||||
|
@ -45,6 +45,9 @@
|
||||
@BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
|
||||
#ifdef MOZ_MEMORY_DARWIN
|
||||
@BINPATH@/@DLL_PREFIX@jemalloc@DLL_SUFFIX@
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
@BINPATH@/XUL
|
||||
#else
|
||||
|
@ -602,8 +602,8 @@ menuitem.bookmark-item {
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize=large][mode=icons] > #nav-bar {
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
-moz-padding-start: 0;
|
||||
-moz-padding-end: 2px;
|
||||
}
|
||||
|
||||
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button,
|
||||
@ -665,17 +665,18 @@ menuitem.bookmark-item {
|
||||
}
|
||||
|
||||
#nav-bar .toolbarbutton-1[disabled="true"] {
|
||||
opacity: .8;
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
#nav-bar .toolbarbutton-1[disabled="true"] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
|
||||
#nav-bar .toolbarbutton-1[disabled="true"] > .toolbarbutton-icon {
|
||||
opacity: .5;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled="true"]):not(:active):hover,
|
||||
#nav-bar .toolbarbutton-1:not([open="true"]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]),
|
||||
#nav-bar .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover {
|
||||
#nav-bar .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover,
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):not([open]):not(:active):hover > .toolbarbutton-icon {
|
||||
background-color: hsla(190,60%,70%,.5);
|
||||
border-color: hsla(190,50%,65%,.8) hsla(190,50%,50%,.8) hsla(190,50%,40%,.8);
|
||||
box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
|
||||
@ -794,14 +795,26 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button {
|
||||
border-radius: 10000px;
|
||||
padding: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: -5px 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
-moz-padding-start: 5px;
|
||||
-moz-padding-end: 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-top: -2px;
|
||||
margin-bottom: -2px;
|
||||
border-radius: 0 10000px 10000px 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:-moz-locale-dir(rtl) {
|
||||
border-radius: 10000px 0 0 10000px;
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button > .toolbarbutton-icon {
|
||||
border-radius: 10000px;
|
||||
padding: 5px;
|
||||
border: none;
|
||||
background-image: -moz-linear-gradient(rgba(251,252,253,.97), rgba(246,247,248,.5) 49%,
|
||||
rgba(231,232,233,.45) 51%, rgba(225,226,229,.2));
|
||||
@ -812,7 +825,7 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
0 1px 1px rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover {
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover > .toolbarbutton-icon {
|
||||
box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
|
||||
0 0 0 2px rgba(255,255,255,.1) inset,
|
||||
0 0 0 1px hsla(190,50%,40%,.3),
|
||||
@ -821,8 +834,8 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
0 0 5px 1px hsl(190,90%,80%);
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):hover:active,
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button[open="true"] {
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):hover:active > .toolbarbutton-icon,
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button[open="true"] > .toolbarbutton-icon {
|
||||
box-shadow: 0 0 6.5px rgba(0,0,0,.4) inset,
|
||||
0 0 2px rgba(0,0,0,.4) inset,
|
||||
0 0 0 1px rgba(0,0,0,.65),
|
||||
|
@ -763,7 +763,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
self.lastTestSeen = line.split("|")[1].strip()
|
||||
if stackFixerFunction:
|
||||
line = stackFixerFunction(line)
|
||||
self.log.info(line.rstrip())
|
||||
self.log.info(line.rstrip().decode("UTF-8", "ignore"))
|
||||
if self.UNIXISH and not debuggerInfo and not self.haveDumpedScreen and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
|
||||
self.dumpScreen(utilityPath)
|
||||
|
||||
|
@ -39,6 +39,7 @@ class DeviceManagerADB(DeviceManager):
|
||||
def mkDir(self, name):
|
||||
try:
|
||||
self.checkCmd(["shell", "mkdir", name])
|
||||
self.chmodDir(name)
|
||||
return name
|
||||
except:
|
||||
return None
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
NS_DECL_NSIPRINCIPAL
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
||||
nsresult Init();
|
||||
nsresult Init(JSPrincipals **jsprin);
|
||||
|
||||
nsSystemPrincipal();
|
||||
|
||||
|
@ -3379,7 +3379,8 @@ nsresult nsScriptSecurityManager::Init()
|
||||
nsRefPtr<nsSystemPrincipal> system = new nsSystemPrincipal();
|
||||
NS_ENSURE_TRUE(system, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = system->Init();
|
||||
JSPrincipals *jsprin;
|
||||
rv = system->Init(&jsprin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mSystemPrincipal = system;
|
||||
@ -3406,6 +3407,8 @@ nsresult nsScriptSecurityManager::Init()
|
||||
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
|
||||
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
|
||||
|
||||
JS_SetTrustedPrincipals(sRuntime, jsprin);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3429,6 +3432,7 @@ nsScriptSecurityManager::Shutdown()
|
||||
{
|
||||
if (sRuntime) {
|
||||
JS_SetRuntimeSecurityCallbacks(sRuntime, NULL);
|
||||
JS_SetTrustedPrincipals(sRuntime, NULL);
|
||||
sRuntime = nsnull;
|
||||
}
|
||||
sEnabledID = JSID_VOID;
|
||||
|
@ -314,7 +314,7 @@ nsSystemPrincipal::nsSystemPrincipal()
|
||||
#define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
|
||||
|
||||
nsresult
|
||||
nsSystemPrincipal::Init()
|
||||
nsSystemPrincipal::Init(JSPrincipals **jsprin)
|
||||
{
|
||||
// Use an nsCString so we only do the allocation once here and then
|
||||
// share with nsJSPrincipals
|
||||
@ -324,7 +324,11 @@ nsSystemPrincipal::Init()
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return mJSPrincipals.Init(this, str);
|
||||
nsresult rv = mJSPrincipals.Init(this, str);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*jsprin = &mJSPrincipals;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsSystemPrincipal::~nsSystemPrincipal(void)
|
||||
|
23
configure.in
23
configure.in
@ -5680,6 +5680,23 @@ fi
|
||||
|
||||
AC_SUBST(MOZ_IPDL_TESTS)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Turns off code necessary for e10s compatibility
|
||||
dnl ========================================================
|
||||
dnl This is a temporary flag to be removed in bug 662601 when
|
||||
dnl it's no longer needed
|
||||
|
||||
MOZ_E10S_COMPAT=
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(e10s-compat,
|
||||
[ --enable-e10s-compat Turns off code for e10s compat],
|
||||
MOZ_E10S_COMPAT=1,
|
||||
MOZ_E10S_COMPAT=)
|
||||
|
||||
if test -n "$MOZ_E10S_COMPAT"; then
|
||||
AC_DEFINE(MOZ_E10S_COMPAT)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Disable building dbm
|
||||
dnl ========================================================
|
||||
@ -7459,12 +7476,12 @@ else
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$OS_ARCH" != "Darwin"; then
|
||||
if test "$OS_ARCH" != "WINNT"; then
|
||||
dnl NB: this must be kept in sync with jemalloc.h
|
||||
AC_DEFINE(HAVE_JEMALLOC_VALLOC)
|
||||
AC_DEFINE(HAVE_JEMALLOC_POSIX_MEMALIGN)
|
||||
AC_DEFINE(HAVE_JEMALLOC_MEMALIGN)
|
||||
fi
|
||||
AC_DEFINE(HAVE_JEMALLOC_POSIX_MEMALIGN)
|
||||
AC_DEFINE(HAVE_JEMALLOC_MEMALIGN)
|
||||
fi # MOZ_MEMORY
|
||||
AC_SUBST(MOZ_MEMORY)
|
||||
AC_SUBST(MOZ_MEMORY_LDFLAGS)
|
||||
|
@ -141,7 +141,7 @@ interface nsIContentViewManager : nsISupports
|
||||
readonly attribute nsIContentView rootContentView;
|
||||
};
|
||||
|
||||
[scriptable, uuid(13c512d6-fba0-402a-9244-fe7941c43965)]
|
||||
[scriptable, uuid(12905a29-4246-475a-81d4-fc389197df02)]
|
||||
interface nsIFrameLoader : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -187,6 +187,12 @@ interface nsIFrameLoader : nsISupports
|
||||
*/
|
||||
void activateRemoteFrame();
|
||||
|
||||
/**
|
||||
* Deactivate remote frame.
|
||||
* Throws an exception with non-remote frames.
|
||||
*/
|
||||
void deactivateRemoteFrame();
|
||||
|
||||
/**
|
||||
* @see nsIDOMWindowUtils sendMouseEvent.
|
||||
*/
|
||||
@ -234,6 +240,24 @@ interface nsIFrameLoader : nsISupports
|
||||
const unsigned long RENDER_MODE_ASYNC_SCROLL = 0x00000001;
|
||||
|
||||
attribute unsigned long renderMode;
|
||||
|
||||
/**
|
||||
* The default event mode automatically forwards the events
|
||||
* handled in nsEventStateManager::HandleCrossProcessEvent to
|
||||
* the child content process when these events are targeted to
|
||||
* the remote browser element.
|
||||
*
|
||||
* Used primarly for input events (mouse, keyboard)
|
||||
*/
|
||||
const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000;
|
||||
|
||||
/**
|
||||
* With this event mode, it's the application's responsability to
|
||||
* convert and forward events to the content process
|
||||
*/
|
||||
const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
|
||||
|
||||
attribute unsigned long eventMode;
|
||||
};
|
||||
|
||||
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
|
||||
|
@ -327,6 +327,7 @@ nsFrameLoader::nsFrameLoader(nsIContent *aOwner, PRBool aNetworkCreated)
|
||||
, mCurrentRemoteFrame(nsnull)
|
||||
, mRemoteBrowser(nsnull)
|
||||
, mRenderMode(RENDER_MODE_DEFAULT)
|
||||
, mEventMode(EVENT_MODE_NORMAL_DISPATCH)
|
||||
{
|
||||
}
|
||||
|
||||
@ -537,6 +538,7 @@ NS_IMETHODIMP
|
||||
nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
|
||||
{
|
||||
*aDocShell = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// If we have an owner, make sure we have a docshell and return
|
||||
// that. If not, we're most likely in the middle of being torn down,
|
||||
@ -547,7 +549,7 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
|
||||
return rv;
|
||||
if (mRemoteFrame) {
|
||||
NS_WARNING("No docshells for remote frames!");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
return rv;
|
||||
}
|
||||
NS_ASSERTION(mDocShell,
|
||||
"MaybeCreateDocShell succeeded, but null mDocShell");
|
||||
@ -556,7 +558,7 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
|
||||
*aDocShell = mDocShell;
|
||||
NS_IF_ADDREF(*aDocShell);
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1340,36 +1342,19 @@ nsFrameLoader::SetOwnerContent(nsIContent* aContent)
|
||||
bool
|
||||
nsFrameLoader::ShouldUseRemoteProcess()
|
||||
{
|
||||
// Check for *disabled* multi-process first: environment, prefs, attribute
|
||||
// Then check for *enabled* multi-process pref: attribute, prefs
|
||||
// Check for *disabled* multi-process first: environment, pref
|
||||
// Then check for *enabled* multi-process attribute
|
||||
// Default is not-remote.
|
||||
|
||||
if (PR_GetEnv("MOZ_DISABLE_OOP_TABS")) {
|
||||
if (PR_GetEnv("MOZ_DISABLE_OOP_TABS") ||
|
||||
Preferences::GetBool("dom.ipc.tabs.disabled", PR_FALSE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PRBool remoteDisabled =
|
||||
Preferences::GetBool("dom.ipc.tabs.disabled", PR_FALSE);
|
||||
if (remoteDisabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static nsIAtom* const *const remoteValues[] = {
|
||||
&nsGkAtoms::_false,
|
||||
&nsGkAtoms::_true,
|
||||
nsnull
|
||||
};
|
||||
|
||||
switch (mOwnerContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::Remote,
|
||||
remoteValues, eCaseMatters)) {
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
return true;
|
||||
}
|
||||
|
||||
PRBool remoteEnabled = Preferences::GetBool("dom.ipc.tabs.enabled", PR_FALSE);
|
||||
return (bool) remoteEnabled;
|
||||
return (bool) mOwnerContent->AttrValueIs(kNameSpaceID_None,
|
||||
nsGkAtoms::Remote,
|
||||
nsGkAtoms::_true,
|
||||
eCaseMatters);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1676,6 +1661,20 @@ nsFrameLoader::SetRenderMode(PRUint32 aRenderMode)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetEventMode(PRUint32* aEventMode)
|
||||
{
|
||||
*aEventMode = mEventMode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::SetEventMode(PRUint32 aEventMode)
|
||||
{
|
||||
mEventMode = aEventMode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntSize
|
||||
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
|
||||
{
|
||||
@ -1787,6 +1786,15 @@ nsFrameLoader::ActivateRemoteFrame() {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::DeactivateRemoteFrame() {
|
||||
if (mRemoteBrowser) {
|
||||
mRemoteBrowser->Deactivate();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType,
|
||||
float aX,
|
||||
|
@ -342,6 +342,10 @@ private:
|
||||
// RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
|
||||
// favor of what content tells.
|
||||
PRUint32 mRenderMode;
|
||||
|
||||
// See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
|
||||
// forwards some input events to out-of-process content.
|
||||
PRUint32 mEventMode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -515,7 +515,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
|
||||
nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> clone;
|
||||
PRBool isDeepDocumentClone = PR_FALSE;
|
||||
if (aClone) {
|
||||
rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -528,7 +527,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (aDeep && clone->IsNodeOfType(nsINode::eDOCUMENT)) {
|
||||
isDeepDocumentClone = PR_TRUE;
|
||||
// After cloning the document itself, we want to clone the children into
|
||||
// the cloned document (somewhat like cloning and importing them into the
|
||||
// cloned document).
|
||||
|
@ -502,6 +502,7 @@ _TEST_FILES2 = \
|
||||
somedatas.resource \
|
||||
somedatas.resource^headers^ \
|
||||
delayedServerEvents.sjs \
|
||||
test_bug664916.html \
|
||||
test_bug666604.html \
|
||||
$(NULL)
|
||||
|
||||
|
40
content/base/test/test_bug664916.html
Normal file
40
content/base/test/test_bug664916.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=664916
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 664916</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=664916">Mozilla Bug 664916</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
|
||||
/** Test for Bug 664916 **/
|
||||
var div = document.createElement("div");
|
||||
var textNode = document.createTextNode("x")
|
||||
var tagNameGetter = div.__lookupGetter__("tagName");
|
||||
|
||||
var tagName = "";
|
||||
try {
|
||||
tagName = tagNameGetter.call(textNode);
|
||||
ok(false, "Should throw when calling tagname getter on text node");
|
||||
} catch(e) {
|
||||
ok(true, "Should throw when calling tagname getter on text node");
|
||||
}
|
||||
is(tagName, "", "Should not have changed tagName yet");
|
||||
tagName = tagNameGetter.call(div);
|
||||
is(tagName, "DIV", "Should get the right tag name");
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -122,6 +122,11 @@ public:
|
||||
CanvasLayer *aOldLayer,
|
||||
LayerManager *aManager) = 0;
|
||||
|
||||
// Return true if the canvas should be forced to be "inactive" to ensure
|
||||
// it can be drawn to the screen even if it's too large to be blitted by
|
||||
// an accelerated CanvasLayer.
|
||||
virtual PRBool ShouldForceInactiveLayer(LayerManager *aManager) { return PR_FALSE; }
|
||||
|
||||
virtual void MarkContextClean() = 0;
|
||||
|
||||
// Redraw the dirty rectangle of this canvas.
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -68,10 +67,140 @@
|
||||
|
||||
#include "prenv.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gl;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
WebGLMemoryReporter* WebGLMemoryReporter::sUniqueInstance = nsnull;
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureMemoryUsed,
|
||||
"webgl-texture-memory",
|
||||
KIND_OTHER,
|
||||
UNITS_BYTES,
|
||||
WebGLMemoryReporter::GetTextureMemoryUsed,
|
||||
"Memory used by WebGL textures. The OpenGL implementation is free to store these textures in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureCount,
|
||||
"webgl-texture-count",
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
WebGLMemoryReporter::GetTextureCount,
|
||||
"Number of WebGL textures.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferMemoryUsed,
|
||||
"webgl-buffer-memory",
|
||||
KIND_OTHER,
|
||||
UNITS_BYTES,
|
||||
WebGLMemoryReporter::GetBufferMemoryUsed,
|
||||
"Memory used by WebGL buffers. The OpenGL implementation is free to store these buffers in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferCacheMemoryUsed,
|
||||
"webgl-buffer-cache-memory",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
WebGLMemoryReporter::GetBufferCacheMemoryUsed,
|
||||
"Memory used by WebGL buffer caches. The WebGL implementation caches the contents of element array buffers only. This adds up with the webgl-buffer-memory value, but contrary to it, this one represents bytes on the heap, not managed by OpenGL.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferCount,
|
||||
"webgl-buffer-count",
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
WebGLMemoryReporter::GetBufferCount,
|
||||
"Number of WebGL buffers.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLRenderbufferMemoryUsed,
|
||||
"webgl-renderbuffer-memory",
|
||||
KIND_OTHER,
|
||||
UNITS_BYTES,
|
||||
WebGLMemoryReporter::GetRenderbufferMemoryUsed,
|
||||
"Memory used by WebGL renderbuffers. The OpenGL implementation is free to store these renderbuffers in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLRenderbufferCount,
|
||||
"webgl-renderbuffer-count",
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
WebGLMemoryReporter::GetRenderbufferCount,
|
||||
"Number of WebGL renderbuffers.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderSourcesSize,
|
||||
"webgl-shader-sources-size",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
WebGLMemoryReporter::GetShaderSourcesSize,
|
||||
"Combined size of WebGL shader ASCII sources, cached on the heap. This should always be at most a few kilobytes, or dozen kilobytes for very shader-intensive WebGL demos.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderTranslationLogsSize,
|
||||
"webgl-shader-translationlogs-size",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
WebGLMemoryReporter::GetShaderTranslationLogsSize,
|
||||
"Combined size of WebGL shader ASCII translation logs, cached on the heap.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderCount,
|
||||
"webgl-shader-count",
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
WebGLMemoryReporter::GetShaderCount,
|
||||
"Number of WebGL shaders.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLContextCount,
|
||||
"webgl-context-count",
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
WebGLMemoryReporter::GetContextCount,
|
||||
"Number of WebGL contexts.")
|
||||
|
||||
WebGLMemoryReporter* WebGLMemoryReporter::UniqueInstance()
|
||||
{
|
||||
if (!sUniqueInstance) {
|
||||
sUniqueInstance = new WebGLMemoryReporter;
|
||||
}
|
||||
return sUniqueInstance;
|
||||
}
|
||||
|
||||
WebGLMemoryReporter::WebGLMemoryReporter()
|
||||
: mTextureMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureMemoryUsed))
|
||||
, mTextureCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureCount))
|
||||
, mBufferMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferMemoryUsed))
|
||||
, mBufferCacheMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferCacheMemoryUsed))
|
||||
, mBufferCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferCount))
|
||||
, mRenderbufferMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLRenderbufferMemoryUsed))
|
||||
, mRenderbufferCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLRenderbufferCount))
|
||||
, mShaderSourcesSizeReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderSourcesSize))
|
||||
, mShaderTranslationLogsSizeReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderTranslationLogsSize))
|
||||
, mShaderCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderCount))
|
||||
, mContextCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLContextCount))
|
||||
{
|
||||
NS_RegisterMemoryReporter(mTextureMemoryUsageReporter);
|
||||
NS_RegisterMemoryReporter(mTextureCountReporter);
|
||||
NS_RegisterMemoryReporter(mBufferMemoryUsageReporter);
|
||||
NS_RegisterMemoryReporter(mBufferCacheMemoryUsageReporter);
|
||||
NS_RegisterMemoryReporter(mBufferCountReporter);
|
||||
NS_RegisterMemoryReporter(mRenderbufferMemoryUsageReporter);
|
||||
NS_RegisterMemoryReporter(mRenderbufferCountReporter);
|
||||
NS_RegisterMemoryReporter(mShaderSourcesSizeReporter);
|
||||
NS_RegisterMemoryReporter(mShaderTranslationLogsSizeReporter);
|
||||
NS_RegisterMemoryReporter(mShaderCountReporter);
|
||||
NS_RegisterMemoryReporter(mContextCountReporter);
|
||||
}
|
||||
|
||||
WebGLMemoryReporter::~WebGLMemoryReporter()
|
||||
{
|
||||
NS_UnregisterMemoryReporter(mTextureMemoryUsageReporter);
|
||||
NS_UnregisterMemoryReporter(mTextureCountReporter);
|
||||
NS_UnregisterMemoryReporter(mBufferMemoryUsageReporter);
|
||||
NS_UnregisterMemoryReporter(mBufferCacheMemoryUsageReporter);
|
||||
NS_UnregisterMemoryReporter(mBufferCountReporter);
|
||||
NS_UnregisterMemoryReporter(mRenderbufferMemoryUsageReporter);
|
||||
NS_UnregisterMemoryReporter(mRenderbufferCountReporter);
|
||||
NS_UnregisterMemoryReporter(mShaderSourcesSizeReporter);
|
||||
NS_UnregisterMemoryReporter(mShaderTranslationLogsSizeReporter);
|
||||
NS_UnregisterMemoryReporter(mShaderCountReporter);
|
||||
NS_UnregisterMemoryReporter(mContextCountReporter);
|
||||
}
|
||||
|
||||
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
|
||||
|
||||
nsresult
|
||||
@ -97,7 +226,7 @@ WebGLContext::WebGLContext()
|
||||
mOptionsFrozen = PR_FALSE;
|
||||
|
||||
mActiveTexture = 0;
|
||||
mSynthesizedGLError = LOCAL_GL_NO_ERROR;
|
||||
mWebGLError = LOCAL_GL_NO_ERROR;
|
||||
mPixelStoreFlipY = PR_FALSE;
|
||||
mPixelStorePremultiplyAlpha = PR_FALSE;
|
||||
mPixelStoreColorspaceConversion = BROWSER_DEFAULT_WEBGL;
|
||||
@ -164,11 +293,14 @@ WebGLContext::WebGLContext()
|
||||
// See OpenGL ES 2.0.25 spec, 6.2 State Tables, table 6.13
|
||||
mPixelStorePackAlignment = 4;
|
||||
mPixelStoreUnpackAlignment = 4;
|
||||
|
||||
WebGLMemoryReporter::AddWebGLContext(this);
|
||||
}
|
||||
|
||||
WebGLContext::~WebGLContext()
|
||||
{
|
||||
DestroyResourcesAndContext();
|
||||
WebGLMemoryReporter::RemoveWebGLContext(this);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
@ -413,22 +545,20 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
DestroyResourcesAndContext();
|
||||
|
||||
// Get some prefs for some preferred/overriden things
|
||||
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
|
||||
|
||||
PRBool forceOSMesa = PR_FALSE;
|
||||
PRBool preferEGL = PR_FALSE;
|
||||
PRBool preferOpenGL = PR_FALSE;
|
||||
PRBool forceEnabled = PR_FALSE;
|
||||
PRBool disabled = PR_FALSE;
|
||||
PRBool verbose = PR_FALSE;
|
||||
|
||||
prefService->GetBoolPref("webgl.force_osmesa", &forceOSMesa);
|
||||
prefService->GetBoolPref("webgl.prefer-egl", &preferEGL);
|
||||
prefService->GetBoolPref("webgl.prefer-native-gl", &preferOpenGL);
|
||||
prefService->GetBoolPref("webgl.force-enabled", &forceEnabled);
|
||||
prefService->GetBoolPref("webgl.disabled", &disabled);
|
||||
prefService->GetBoolPref("webgl.verbose", &verbose);
|
||||
PRBool forceOSMesa =
|
||||
Preferences::GetBool("webgl.force_osmesa", PR_FALSE);
|
||||
PRBool preferEGL =
|
||||
Preferences::GetBool("webgl.prefer-egl", PR_FALSE);
|
||||
PRBool preferOpenGL =
|
||||
Preferences::GetBool("webgl.prefer-native-gl", PR_FALSE);
|
||||
PRBool forceEnabled =
|
||||
Preferences::GetBool("webgl.force-enabled", PR_FALSE);
|
||||
PRBool disabled =
|
||||
Preferences::GetBool("webgl.disabled", PR_FALSE);
|
||||
PRBool verbose =
|
||||
Preferences::GetBool("webgl.verbose", PR_FALSE);
|
||||
|
||||
if (disabled)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
#include "GLContextProvider.h"
|
||||
#include "Layers.h"
|
||||
@ -320,6 +321,8 @@ class WebGLContext :
|
||||
public nsICanvasRenderingContextInternal,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
friend class WebGLMemoryReporter;
|
||||
|
||||
public:
|
||||
WebGLContext();
|
||||
virtual ~WebGLContext();
|
||||
@ -367,6 +370,8 @@ public:
|
||||
return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue);
|
||||
}
|
||||
nsresult ErrorOutOfMemory(const char *fmt = 0, ...);
|
||||
|
||||
const char *ErrorName(GLenum error);
|
||||
|
||||
WebGLTexture *activeBoundTextureForTarget(WebGLenum target) {
|
||||
return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
|
||||
@ -392,6 +397,23 @@ public:
|
||||
// See section 2.2 in the WebGL spec.
|
||||
void EnsureBackbufferClearedAsNeeded();
|
||||
|
||||
// checks for GL errors, clears any pending GL error, stores the current GL error in currentGLError,
|
||||
// and copies it into mWebGLError if it doesn't already have an error set
|
||||
void UpdateWebGLErrorAndClearGLError(GLenum *currentGLError) {
|
||||
// get and clear GL error in ALL cases
|
||||
*currentGLError = gl->GetAndClearError();
|
||||
// only store in mWebGLError if is hasn't already recorded an error
|
||||
if (!mWebGLError)
|
||||
mWebGLError = *currentGLError;
|
||||
}
|
||||
|
||||
// checks for GL errors, clears any pending GL error,
|
||||
// and stores the current GL error into mWebGLError if it doesn't already have an error set
|
||||
void UpdateWebGLErrorAndClearGLError() {
|
||||
GLenum currentGLError;
|
||||
UpdateWebGLErrorAndClearGLError(¤tGLError);
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetDontKnowIfNeedFakeBlack() {
|
||||
mFakeBlackStatus = DontKnowIfNeedFakeBlack;
|
||||
@ -424,7 +446,7 @@ protected:
|
||||
PRPackedBool mOptionsFrozen;
|
||||
|
||||
WebGLuint mActiveTexture;
|
||||
WebGLenum mSynthesizedGLError;
|
||||
WebGLenum mWebGLError;
|
||||
|
||||
// whether shader validation is supported
|
||||
PRBool mShaderValidation;
|
||||
@ -468,6 +490,8 @@ protected:
|
||||
PRBool ValidateDrawModeEnum(WebGLenum mode, const char *info);
|
||||
PRBool ValidateAttribIndex(WebGLuint index, const char *info);
|
||||
PRBool ValidateStencilParamsForDrawCall();
|
||||
|
||||
static PRUint32 GetTexelSize(WebGLenum format, WebGLenum type);
|
||||
|
||||
void Invalidate();
|
||||
void DestroyResourcesAndContext();
|
||||
@ -548,6 +572,24 @@ protected:
|
||||
PRInt32 MaxTextureSizeForTarget(WebGLenum target) const {
|
||||
return target == LOCAL_GL_TEXTURE_2D ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
|
||||
}
|
||||
|
||||
/** like glBufferData but if the call may change the buffer size, checks any GL error generated
|
||||
* by this glBufferData call and returns it */
|
||||
GLenum CheckedBufferData(GLenum target,
|
||||
GLsizeiptr size,
|
||||
const GLvoid *data,
|
||||
GLenum usage);
|
||||
/** like glTexImage2D but if the call may change the texture size, checks any GL error generated
|
||||
* by this glTexImage2D call and returns it */
|
||||
GLenum CheckedTexImage2D(GLenum target,
|
||||
GLint level,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
const GLvoid *data);
|
||||
|
||||
// the buffers bound to the current program's attribs
|
||||
nsTArray<WebGLVertexAttribData> mAttribBuffers;
|
||||
@ -659,10 +701,10 @@ protected:
|
||||
: mWidth(0), mHeight(0) { }
|
||||
|
||||
public:
|
||||
WebGLsizei width() { return mWidth; }
|
||||
WebGLsizei width() const { return mWidth; }
|
||||
void width(WebGLsizei value) { mWidth = value; }
|
||||
|
||||
WebGLsizei height() { return mHeight; }
|
||||
WebGLsizei height() const { return mHeight; }
|
||||
void height(WebGLsizei value) { mHeight = value; }
|
||||
|
||||
void setDimensions(WebGLsizei width, WebGLsizei height) {
|
||||
@ -680,6 +722,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool HasSameDimensionsAs(const WebGLRectangleObject& other) const {
|
||||
return width() == other.width() && height() == other.height();
|
||||
}
|
||||
|
||||
protected:
|
||||
WebGLsizei mWidth;
|
||||
WebGLsizei mHeight;
|
||||
@ -720,7 +766,7 @@ public:
|
||||
WebGLContextBoundObject(context),
|
||||
mName(name), mDeleted(PR_FALSE), mHasEverBeenBound(PR_FALSE),
|
||||
mByteLength(0), mTarget(LOCAL_GL_NONE), mData(nsnull)
|
||||
{ }
|
||||
{}
|
||||
|
||||
~WebGLBuffer() {
|
||||
Delete();
|
||||
@ -843,7 +889,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(WebGLBuffer, WEBGLBUFFER_PRIVATE_IID)
|
||||
class WebGLTexture :
|
||||
public nsIWebGLTexture,
|
||||
public WebGLZeroingObject,
|
||||
public WebGLRectangleObject,
|
||||
public WebGLContextBoundObject
|
||||
{
|
||||
public:
|
||||
@ -890,8 +935,14 @@ protected:
|
||||
// we store information about the various images that are part of
|
||||
// this texture (cubemap faces, mipmap levels)
|
||||
|
||||
public:
|
||||
|
||||
struct ImageInfo {
|
||||
ImageInfo() : mWidth(0), mHeight(0), mFormat(0), mType(0), mIsDefined(PR_FALSE) {}
|
||||
ImageInfo(WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type)
|
||||
: mWidth(width), mHeight(height), mFormat(format), mType(type), mIsDefined(PR_TRUE) {}
|
||||
|
||||
PRBool operator==(const ImageInfo& a) const {
|
||||
return mWidth == a.mWidth && mHeight == a.mHeight &&
|
||||
mFormat == a.mFormat && mType == a.mType;
|
||||
@ -909,13 +960,17 @@ protected:
|
||||
return is_pot_assuming_nonnegative(mWidth) &&
|
||||
is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
|
||||
}
|
||||
PRInt64 MemoryUsage() const {
|
||||
if (!mIsDefined)
|
||||
return 0;
|
||||
PRInt64 texelSize = WebGLContext::GetTexelSize(mFormat, mType);
|
||||
return PRInt64(mWidth) * PRInt64(mHeight) * texelSize;
|
||||
}
|
||||
WebGLsizei mWidth, mHeight;
|
||||
WebGLenum mFormat, mType;
|
||||
PRBool mIsDefined;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
ImageInfo& ImageInfoAt(size_t level, size_t face = 0) {
|
||||
#ifdef DEBUG
|
||||
if (face >= mFacesCount)
|
||||
@ -939,6 +994,22 @@ public:
|
||||
return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
}
|
||||
|
||||
PRInt64 MemoryUsage() const {
|
||||
PRInt64 result = 0;
|
||||
for(size_t face = 0; face < mFacesCount; face++) {
|
||||
if (mHaveGeneratedMipmap) {
|
||||
// Each mipmap level is 1/4 the size of the previous level
|
||||
// 1 + x + x^2 + ... = 1/(1-x)
|
||||
// for x = 1/4, we get 1/(1-1/4) = 4/3
|
||||
result += ImageInfoAt(0, face).MemoryUsage() * 4 / 3;
|
||||
} else {
|
||||
for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++)
|
||||
result += ImageInfoAt(level, face).MemoryUsage();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
WebGLenum mTarget;
|
||||
@ -1035,7 +1106,7 @@ public:
|
||||
|
||||
void SetImageInfo(WebGLenum aTarget, WebGLint aLevel,
|
||||
WebGLsizei aWidth, WebGLsizei aHeight,
|
||||
WebGLenum aFormat = 0, WebGLenum aType = 0)
|
||||
WebGLenum aFormat, WebGLenum aType)
|
||||
{
|
||||
if ( (aTarget == LOCAL_GL_TEXTURE_2D) != (mTarget == LOCAL_GL_TEXTURE_2D) )
|
||||
return;
|
||||
@ -1044,14 +1115,7 @@ public:
|
||||
|
||||
EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
|
||||
|
||||
ImageInfo& imageInfo = ImageInfoAt(aLevel, face);
|
||||
imageInfo.mWidth = aWidth;
|
||||
imageInfo.mHeight = aHeight;
|
||||
if (aFormat)
|
||||
imageInfo.mFormat = aFormat;
|
||||
if (aType)
|
||||
imageInfo.mType = aType;
|
||||
imageInfo.mIsDefined = PR_TRUE;
|
||||
ImageInfoAt(aLevel, face) = ImageInfo(aWidth, aHeight, aFormat, aType);
|
||||
|
||||
if (aLevel > 0)
|
||||
SetCustomMipmap();
|
||||
@ -1466,6 +1530,7 @@ public:
|
||||
WebGLContextBoundObject(context),
|
||||
mName(name),
|
||||
mInternalFormat(0),
|
||||
mInternalFormatForGL(0),
|
||||
mDeleted(PR_FALSE), mHasEverBeenBound(PR_FALSE), mInitialized(PR_FALSE)
|
||||
{ }
|
||||
|
||||
@ -1485,6 +1550,32 @@ public:
|
||||
|
||||
WebGLenum InternalFormat() const { return mInternalFormat; }
|
||||
void SetInternalFormat(WebGLenum aInternalFormat) { mInternalFormat = aInternalFormat; }
|
||||
|
||||
WebGLenum InternalFormatForGL() const { return mInternalFormatForGL; }
|
||||
void SetInternalFormatForGL(WebGLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; }
|
||||
|
||||
PRInt64 MemoryUsage() const {
|
||||
PRInt64 pixels = PRInt64(width()) * PRInt64(height());
|
||||
switch (mInternalFormatForGL) {
|
||||
case LOCAL_GL_STENCIL_INDEX8:
|
||||
return pixels;
|
||||
case LOCAL_GL_RGBA4:
|
||||
case LOCAL_GL_RGB5_A1:
|
||||
case LOCAL_GL_RGB565:
|
||||
case LOCAL_GL_DEPTH_COMPONENT16:
|
||||
return 2 * pixels;
|
||||
case LOCAL_GL_RGB8:
|
||||
case LOCAL_GL_DEPTH_COMPONENT24:
|
||||
return 3*pixels;
|
||||
case LOCAL_GL_RGBA8:
|
||||
case LOCAL_GL_DEPTH24_STENCIL8:
|
||||
return 4*pixels;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
NS_ABORT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBGLRENDERBUFFER
|
||||
@ -1492,6 +1583,7 @@ public:
|
||||
protected:
|
||||
WebGLuint mName;
|
||||
WebGLenum mInternalFormat;
|
||||
WebGLenum mInternalFormatForGL;
|
||||
|
||||
PRBool mDeleted;
|
||||
PRBool mHasEverBeenBound;
|
||||
@ -1503,6 +1595,7 @@ protected:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLRenderbuffer, WEBGLRENDERBUFFER_PRIVATE_IID)
|
||||
|
||||
class WebGLFramebufferAttachment
|
||||
: public WebGLRectangleObject
|
||||
{
|
||||
// deleting a texture or renderbuffer immediately detaches it
|
||||
WebGLObjectRefPtr<WebGLTexture> mTexturePtr;
|
||||
@ -1538,10 +1631,17 @@ public:
|
||||
mRenderbufferPtr = nsnull;
|
||||
mTextureLevel = level;
|
||||
mTextureCubeMapFace = face;
|
||||
if (tex) {
|
||||
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
|
||||
setDimensions(imageInfo.mWidth, imageInfo.mHeight);
|
||||
} else {
|
||||
setDimensions(0, 0);
|
||||
}
|
||||
}
|
||||
void SetRenderbuffer(WebGLRenderbuffer *rb) {
|
||||
mTexturePtr = nsnull;
|
||||
mRenderbufferPtr = rb;
|
||||
setDimensions(rb);
|
||||
}
|
||||
WebGLTexture *Texture() const {
|
||||
return mTexturePtr.get();
|
||||
@ -1591,7 +1691,6 @@ public:
|
||||
class WebGLFramebuffer :
|
||||
public nsIWebGLFramebuffer,
|
||||
public WebGLZeroingObject,
|
||||
public WebGLRectangleObject,
|
||||
public WebGLContextBoundObject
|
||||
{
|
||||
public:
|
||||
@ -1616,6 +1715,9 @@ public:
|
||||
PRBool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||
void SetHasEverBeenBound(PRBool x) { mHasEverBeenBound = x; }
|
||||
WebGLuint GLName() { return mName; }
|
||||
|
||||
WebGLsizei width() { return mColorAttachment.width(); }
|
||||
WebGLsizei height() { return mColorAttachment.height(); }
|
||||
|
||||
nsresult FramebufferRenderbuffer(WebGLenum target,
|
||||
WebGLenum attachment,
|
||||
@ -1652,11 +1754,7 @@ public:
|
||||
// finish checking that the 'attachment' parameter is among the allowed values
|
||||
if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
|
||||
return mContext->ErrorInvalidEnumInfo("framebufferRenderbuffer: attachment", attachment);
|
||||
if (!isNull) {
|
||||
// ReadPixels needs alpha and size information, but only
|
||||
// for COLOR_ATTACHMENT0
|
||||
setDimensions(wrb);
|
||||
}
|
||||
|
||||
mColorAttachment.SetRenderbuffer(wrb);
|
||||
break;
|
||||
}
|
||||
@ -1691,15 +1789,15 @@ public:
|
||||
if (target != LOCAL_GL_FRAMEBUFFER)
|
||||
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
|
||||
|
||||
if (!isNull && textarget != LOCAL_GL_TEXTURE_2D &&
|
||||
if (textarget != LOCAL_GL_TEXTURE_2D &&
|
||||
(textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
|
||||
textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
|
||||
textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
|
||||
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
|
||||
|
||||
if (!isNull && level > 0)
|
||||
if (level != 0)
|
||||
return mContext->ErrorInvalidValue("framebufferTexture2D: level must be 0");
|
||||
|
||||
WebGLint face = (textarget == LOCAL_GL_TEXTURE_2D) ? 0 : textarget;
|
||||
size_t face = WebGLTexture::FaceForTarget(textarget);
|
||||
switch (attachment) {
|
||||
case LOCAL_GL_DEPTH_ATTACHMENT:
|
||||
mDepthAttachment.SetTexture(wtex, level, face);
|
||||
@ -1714,9 +1812,6 @@ public:
|
||||
if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
|
||||
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: attachment", attachment);
|
||||
|
||||
// keep data for readPixels, function only uses COLOR_ATTACHMENT0
|
||||
setDimensions(wtex);
|
||||
|
||||
mColorAttachment.SetTexture(wtex, level, face);
|
||||
break;
|
||||
}
|
||||
@ -1759,13 +1854,22 @@ public:
|
||||
// some attachment is incompatible with its attachment point
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if (int(mDepthAttachment.IsNull()) +
|
||||
int(mStencilAttachment.IsNull()) +
|
||||
int(mDepthStencilAttachment.IsNull()) <= 1)
|
||||
|
||||
if (int(mDepthAttachment.IsNull()) +
|
||||
int(mStencilAttachment.IsNull()) +
|
||||
int(mDepthStencilAttachment.IsNull()) <= 1)
|
||||
{
|
||||
// has at least two among Depth, Stencil, DepthStencil
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (!mDepthAttachment.IsNull() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment))
|
||||
return PR_TRUE;
|
||||
if (!mStencilAttachment.IsNull() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment))
|
||||
return PR_TRUE;
|
||||
if (!mDepthStencilAttachment.IsNull() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment))
|
||||
return PR_TRUE;
|
||||
|
||||
else return PR_FALSE;
|
||||
}
|
||||
|
||||
@ -2066,6 +2170,199 @@ WebGLContext::CanGetConcreteObject(const char *info,
|
||||
return GetConcreteObject(info, aInterface, &aConcreteObject, isNull, isDeleted, PR_FALSE);
|
||||
}
|
||||
|
||||
class WebGLMemoryReporter
|
||||
{
|
||||
WebGLMemoryReporter();
|
||||
~WebGLMemoryReporter();
|
||||
static WebGLMemoryReporter* sUniqueInstance;
|
||||
|
||||
// here we store plain pointers, not RefPtrs: we don't want the WebGLMemoryReporter unique instance to keep alive all
|
||||
// WebGLContexts ever created.
|
||||
typedef nsTArray<const WebGLContext*> ContextsArrayType;
|
||||
ContextsArrayType mContexts;
|
||||
|
||||
nsIMemoryReporter *mTextureMemoryUsageReporter;
|
||||
nsIMemoryReporter *mTextureCountReporter;
|
||||
nsIMemoryReporter *mBufferMemoryUsageReporter;
|
||||
nsIMemoryReporter *mBufferCacheMemoryUsageReporter;
|
||||
nsIMemoryReporter *mBufferCountReporter;
|
||||
nsIMemoryReporter *mRenderbufferMemoryUsageReporter;
|
||||
nsIMemoryReporter *mRenderbufferCountReporter;
|
||||
nsIMemoryReporter *mShaderSourcesSizeReporter;
|
||||
nsIMemoryReporter *mShaderTranslationLogsSizeReporter;
|
||||
nsIMemoryReporter *mShaderCountReporter;
|
||||
nsIMemoryReporter *mContextCountReporter;
|
||||
|
||||
static WebGLMemoryReporter* UniqueInstance();
|
||||
|
||||
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
|
||||
|
||||
public:
|
||||
|
||||
static void AddWebGLContext(const WebGLContext* c) {
|
||||
Contexts().AppendElement(c);
|
||||
}
|
||||
|
||||
static void RemoveWebGLContext(const WebGLContext* c) {
|
||||
ContextsArrayType & contexts = Contexts();
|
||||
contexts.RemoveElement(c);
|
||||
if (contexts.IsEmpty()) {
|
||||
delete sUniqueInstance;
|
||||
sUniqueInstance = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
static PLDHashOperator TextureMemoryUsageFunction(const PRUint32&, WebGLTexture *aValue, void *aData)
|
||||
{
|
||||
PRInt64 *result = (PRInt64*) aData;
|
||||
*result += aValue->MemoryUsage();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PRInt64 GetTextureMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
PRInt64 textureMemoryUsageForThisContext = 0;
|
||||
contexts[i]->mMapTextures.EnumerateRead(TextureMemoryUsageFunction, &textureMemoryUsageForThisContext);
|
||||
result += textureMemoryUsageForThisContext;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetTextureCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
result += contexts[i]->mMapTextures.Count();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PLDHashOperator BufferMemoryUsageFunction(const PRUint32&, WebGLBuffer *aValue, void *aData)
|
||||
{
|
||||
PRInt64 *result = (PRInt64*) aData;
|
||||
*result += aValue->ByteLength();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PRInt64 GetBufferMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
PRInt64 bufferMemoryUsageForThisContext = 0;
|
||||
contexts[i]->mMapBuffers.EnumerateRead(BufferMemoryUsageFunction, &bufferMemoryUsageForThisContext);
|
||||
result += bufferMemoryUsageForThisContext;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PLDHashOperator BufferCacheMemoryUsageFunction(const PRUint32&, WebGLBuffer *aValue, void *aData)
|
||||
{
|
||||
PRInt64 *result = (PRInt64*) aData;
|
||||
// element array buffers are cached in the WebGL implementation. Other buffers aren't.
|
||||
if (aValue->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
*result += aValue->ByteLength();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PRInt64 GetBufferCacheMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
PRInt64 bufferCacheMemoryUsageForThisContext = 0;
|
||||
contexts[i]->mMapBuffers.EnumerateRead(BufferCacheMemoryUsageFunction, &bufferCacheMemoryUsageForThisContext);
|
||||
result += bufferCacheMemoryUsageForThisContext;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetBufferCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
result += contexts[i]->mMapBuffers.Count();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PLDHashOperator RenderbufferMemoryUsageFunction(const PRUint32&, WebGLRenderbuffer *aValue, void *aData)
|
||||
{
|
||||
PRInt64 *result = (PRInt64*) aData;
|
||||
*result += aValue->MemoryUsage();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PRInt64 GetRenderbufferMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
PRInt64 bufferMemoryUsageForThisContext = 0;
|
||||
contexts[i]->mMapRenderbuffers.EnumerateRead(RenderbufferMemoryUsageFunction, &bufferMemoryUsageForThisContext);
|
||||
result += bufferMemoryUsageForThisContext;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetRenderbufferCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
result += contexts[i]->mMapRenderbuffers.Count();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PLDHashOperator ShaderSourceSizeFunction(const PRUint32&, WebGLShader *aValue, void *aData)
|
||||
{
|
||||
PRInt64 *result = (PRInt64*) aData;
|
||||
*result += aValue->Source().Length();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator ShaderTranslationLogSizeFunction(const PRUint32&, WebGLShader *aValue, void *aData)
|
||||
{
|
||||
PRInt64 *result = (PRInt64*) aData;
|
||||
*result += aValue->TranslationLog().Length();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PRInt64 GetShaderSourcesSize() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
PRInt64 shaderSourcesSizeForThisContext = 0;
|
||||
contexts[i]->mMapShaders.EnumerateRead(ShaderSourceSizeFunction, &shaderSourcesSizeForThisContext);
|
||||
result += shaderSourcesSizeForThisContext;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetShaderTranslationLogsSize() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
PRInt64 shaderTranslationLogsSizeForThisContext = 0;
|
||||
contexts[i]->mMapShaders.EnumerateRead(ShaderTranslationLogSizeFunction, &shaderTranslationLogsSizeForThisContext);
|
||||
result += shaderTranslationLogsSizeForThisContext;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetShaderCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
result += contexts[i]->mMapShaders.Count();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetContextCount() {
|
||||
return Contexts().Length();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
@ -367,6 +368,32 @@ WebGLContext::BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GLenum WebGLContext::CheckedBufferData(GLenum target,
|
||||
GLsizeiptr size,
|
||||
const GLvoid *data,
|
||||
GLenum usage)
|
||||
{
|
||||
WebGLBuffer *boundBuffer = NULL;
|
||||
if (target == LOCAL_GL_ARRAY_BUFFER) {
|
||||
boundBuffer = mBoundArrayBuffer;
|
||||
} else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
|
||||
boundBuffer = mBoundElementArrayBuffer;
|
||||
}
|
||||
NS_ABORT_IF_FALSE(boundBuffer != nsnull, "no buffer bound for this target");
|
||||
|
||||
bool sizeChanges = PRUint32(size) != boundBuffer->ByteLength();
|
||||
if (sizeChanges) {
|
||||
UpdateWebGLErrorAndClearGLError();
|
||||
gl->fBufferData(target, size, data, usage);
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
UpdateWebGLErrorAndClearGLError(&error);
|
||||
return error;
|
||||
} else {
|
||||
gl->fBufferData(target, size, data, usage);
|
||||
return LOCAL_GL_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::BufferData(PRInt32 dummy)
|
||||
{
|
||||
@ -406,13 +433,17 @@ WebGLContext::BufferData_size(WebGLenum target, WebGLsizei size, WebGLenum usage
|
||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
GLenum error = CheckedBufferData(target, size, 0, usage);
|
||||
if (error) {
|
||||
LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
boundBuffer->SetByteLength(size);
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
if (!boundBuffer->ZeroDataIfElementArray())
|
||||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
|
||||
gl->fBufferData(target, size, 0, usage);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -438,12 +469,19 @@ WebGLContext::BufferData_buf(WebGLenum target, JSObject *wb, WebGLenum usage)
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
GLenum error = CheckedBufferData(target,
|
||||
JS_GetArrayBufferByteLength(wb),
|
||||
JS_GetArrayBufferData(wb),
|
||||
usage);
|
||||
if (error) {
|
||||
LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
boundBuffer->SetByteLength(JS_GetArrayBufferByteLength(wb));
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
if (!boundBuffer->CopyDataIfElementArray(JS_GetArrayBufferData(wb)))
|
||||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
|
||||
gl->fBufferData(target, JS_GetArrayBufferByteLength(wb), JS_GetArrayBufferData(wb), usage);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -469,12 +507,19 @@ WebGLContext::BufferData_array(WebGLenum target, js::TypedArray *wa, WebGLenum u
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
GLenum error = CheckedBufferData(target,
|
||||
wa->byteLength,
|
||||
wa->data,
|
||||
usage);
|
||||
if (error) {
|
||||
LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
boundBuffer->SetByteLength(wa->byteLength);
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
if (!boundBuffer->CopyDataIfElementArray(wa->data))
|
||||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
boundBuffer->InvalidateCachedMaxElements();
|
||||
|
||||
gl->fBufferData(target, wa->byteLength, wa->data, usage);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -685,9 +730,9 @@ WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
|
||||
|
||||
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
|
||||
if (sub)
|
||||
gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
||||
gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
||||
else
|
||||
gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, 0);
|
||||
gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, 0);
|
||||
} else {
|
||||
|
||||
// the rect doesn't fit in the framebuffer
|
||||
@ -728,10 +773,11 @@ WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
|
||||
// now initialize the texture as black
|
||||
|
||||
if (sub)
|
||||
gl->fTexSubImage2D(target, level, 0, 0, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
||||
gl->fTexSubImage2D(target, level, 0, 0, width, height,
|
||||
internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
||||
else
|
||||
gl->fTexImage2D(target, level, internalformat, width, height, 0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
||||
|
||||
gl->fTexImage2D(target, level, internalformat, width, height,
|
||||
0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
||||
free(tempZeroData);
|
||||
|
||||
// if we are completely outside of the framebuffer, we can exit now with our black texture
|
||||
@ -830,9 +876,31 @@ WebGLContext::CopyTexImage2D(WebGLenum target,
|
||||
if (!tex)
|
||||
return ErrorInvalidOperation("copyTexImage2D: no texture bound to this target");
|
||||
|
||||
tex->SetImageInfo(target, level, width, height);
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, WebGLTexture::FaceForTarget(target));
|
||||
|
||||
return CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
|
||||
// copyTexImage2D only generates textures with type = UNSIGNED_BYTE
|
||||
GLenum type = LOCAL_GL_UNSIGNED_BYTE;
|
||||
|
||||
bool sizeMayChange = width != imageInfo.mWidth ||
|
||||
height != imageInfo.mHeight ||
|
||||
internalformat != imageInfo.mFormat ||
|
||||
type != imageInfo.mType;
|
||||
|
||||
if (sizeMayChange) {
|
||||
UpdateWebGLErrorAndClearGLError();
|
||||
CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
UpdateWebGLErrorAndClearGLError(&error);
|
||||
if (error) {
|
||||
LogMessageIfVerbose("copyTexImage2D generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
|
||||
}
|
||||
|
||||
tex->SetImageInfo(target, level, width, height, internalformat, type);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2226,18 +2294,9 @@ WebGLContext::GetError(WebGLenum *_retval)
|
||||
{
|
||||
MakeContextCurrent();
|
||||
|
||||
// Always call glGetError to clear any pending
|
||||
// real GL error.
|
||||
WebGLenum err = gl->fGetError();
|
||||
|
||||
// mSynthesizedGLError has the first error that occurred,
|
||||
// whether synthesized or real; if it's not NO_ERROR, use it.
|
||||
if (mSynthesizedGLError != LOCAL_GL_NO_ERROR) {
|
||||
err = mSynthesizedGLError;
|
||||
mSynthesizedGLError = LOCAL_GL_NO_ERROR;
|
||||
}
|
||||
|
||||
*_retval = err;
|
||||
UpdateWebGLErrorAndClearGLError();
|
||||
*_retval = mWebGLError;
|
||||
mWebGLError = LOCAL_GL_NO_ERROR;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3107,8 +3166,6 @@ WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, We
|
||||
if (!mBoundRenderbuffer || !mBoundRenderbuffer->GLName())
|
||||
return ErrorInvalidOperation("renderbufferStorage called on renderbuffer 0");
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
// certain OpenGL ES renderbuffer formats may not exist on desktop OpenGL
|
||||
WebGLenum internalformatForGL = internalformat;
|
||||
|
||||
@ -3144,9 +3201,26 @@ WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, We
|
||||
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
|
||||
}
|
||||
|
||||
gl->fRenderbufferStorage(target, internalformatForGL, width, height);
|
||||
MakeContextCurrent();
|
||||
|
||||
bool sizeChanges = width != mBoundRenderbuffer->width() ||
|
||||
height != mBoundRenderbuffer->height() ||
|
||||
internalformat != mBoundRenderbuffer->InternalFormat();
|
||||
if (sizeChanges) {
|
||||
UpdateWebGLErrorAndClearGLError();
|
||||
gl->fRenderbufferStorage(target, internalformatForGL, width, height);
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
UpdateWebGLErrorAndClearGLError(&error);
|
||||
if (error) {
|
||||
LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
gl->fRenderbufferStorage(target, internalformatForGL, width, height);
|
||||
}
|
||||
|
||||
mBoundRenderbuffer->SetInternalFormat(internalformat);
|
||||
mBoundRenderbuffer->SetInternalFormatForGL(internalformatForGL);
|
||||
mBoundRenderbuffer->setDimensions(width, height);
|
||||
mBoundRenderbuffer->SetInitialized(PR_FALSE);
|
||||
|
||||
@ -4044,11 +4118,19 @@ WebGLContext::ShaderSource(nsIWebGLShader *sobj, const nsAString& source)
|
||||
WebGLuint shadername;
|
||||
if (!GetConcreteObjectAndGLName("shaderSource: shader", sobj, &shader, &shadername))
|
||||
return NS_OK;
|
||||
|
||||
const nsPromiseFlatString& flatSource = PromiseFlatString(source);
|
||||
|
||||
if (!NS_IsAscii(nsPromiseFlatString(source).get()))
|
||||
if (!NS_IsAscii(flatSource.get()))
|
||||
return ErrorInvalidValue("shaderSource: non-ascii characters found in source");
|
||||
|
||||
shader->SetSource(NS_LossyConvertUTF16toASCII(source));
|
||||
const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource);
|
||||
|
||||
const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
|
||||
if (sourceCString.Length() > maxSourceLength)
|
||||
return ErrorInvalidValue("shaderSource: source has more than %d characters", maxSourceLength);
|
||||
|
||||
shader->SetSource(sourceCString);
|
||||
|
||||
shader->SetNeedsTranslation();
|
||||
|
||||
@ -4136,6 +4218,35 @@ WebGLContext::TexImage2D(PRInt32)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
GLenum WebGLContext::CheckedTexImage2D(GLenum target,
|
||||
GLint level,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
const GLvoid *data)
|
||||
{
|
||||
WebGLTexture *tex = activeBoundTextureForTarget(target);
|
||||
NS_ABORT_IF_FALSE(tex != nsnull, "no texture bound");
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, WebGLTexture::FaceForTarget(target));
|
||||
bool sizeMayChange = width != imageInfo.mWidth ||
|
||||
height != imageInfo.mHeight ||
|
||||
format != imageInfo.mFormat ||
|
||||
type != imageInfo.mType;
|
||||
if (sizeMayChange) {
|
||||
UpdateWebGLErrorAndClearGLError();
|
||||
gl->fTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
UpdateWebGLErrorAndClearGLError(&error);
|
||||
return error;
|
||||
} else {
|
||||
gl->fTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
|
||||
return LOCAL_GL_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero,
|
||||
@ -4227,14 +4338,14 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
|
||||
if (!tex)
|
||||
return ErrorInvalidOperation("texImage2D: no texture is bound to this target");
|
||||
|
||||
tex->SetImageInfo(target, level, width, height, format, type);
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
// Handle ES2 and GL differences in floating point internal formats. Note that
|
||||
// format == internalformat, as checked above and as required by ES.
|
||||
internalformat = InternalFormatForFormatAndType(format, type, gl->IsGLES2());
|
||||
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
|
||||
if (byteLength) {
|
||||
int dstFormat = GetWebGLTexelFormat(format, type);
|
||||
int actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
||||
@ -4250,16 +4361,18 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
|
||||
!mPixelStoreFlipY)
|
||||
{
|
||||
// no conversion, no flipping, so we avoid copying anything and just pass the source pointer
|
||||
gl->fTexImage2D(target, level, internalformat, width, height, border, format, type, data);
|
||||
error = CheckedTexImage2D(target, level, internalformat,
|
||||
width, height, border, format, type, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsAutoArrayPtr<PRUint8> convertedData(new PRUint8[bytesNeeded]);
|
||||
ConvertImage(width, height, srcStride, dstStride,
|
||||
(PRUint8*)data, convertedData,
|
||||
actualSrcFormat, srcPremultiplied,
|
||||
dstFormat, mPixelStorePremultiplyAlpha, texelSize);
|
||||
gl->fTexImage2D(target, level, internalformat, width, height, border, format, type, convertedData);
|
||||
(PRUint8*)data, convertedData,
|
||||
actualSrcFormat, srcPremultiplied,
|
||||
dstFormat, mPixelStorePremultiplyAlpha, texelSize);
|
||||
error = CheckedTexImage2D(target, level, internalformat,
|
||||
width, height, border, format, type, convertedData);
|
||||
}
|
||||
} else {
|
||||
// We need some zero pages, because GL doesn't guarantee the
|
||||
@ -4269,12 +4382,18 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
|
||||
if (!tempZeroData)
|
||||
return ErrorOutOfMemory("texImage2D: could not allocate %d bytes (for zero fill)", bytesNeeded);
|
||||
|
||||
gl->fTexImage2D(target, level, internalformat, width, height, border, format, type, tempZeroData);
|
||||
error = CheckedTexImage2D(target, level, internalformat,
|
||||
width, height, border, format, type, tempZeroData);
|
||||
|
||||
free(tempZeroData);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
LogMessageIfVerbose("texImage2D generated error %s", ErrorName(error));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
tex->setDimensions(width, height);
|
||||
tex->SetImageInfo(target, level, width, height, format, type);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -4418,10 +4537,11 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
|
||||
if (!tex)
|
||||
return ErrorInvalidOperation("texSubImage2D: no texture is bound to this target");
|
||||
|
||||
if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, tex->width(), tex->height()))
|
||||
size_t face = WebGLTexture::FaceForTarget(target);
|
||||
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
|
||||
if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.mWidth, imageInfo.mHeight))
|
||||
return ErrorInvalidValue("texSubImage2D: subtexture rectangle out of bounds");
|
||||
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
int dstFormat = GetWebGLTexelFormat(format, type);
|
||||
|
@ -46,10 +46,7 @@
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIVariant.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
@ -59,6 +56,7 @@
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#if 0
|
||||
#include "nsIContentURIGrouper.h"
|
||||
@ -126,15 +124,13 @@ WebGLContext::SynthesizeGLError(WebGLenum err)
|
||||
// but if there isn't, then we need to check for a gl error
|
||||
// that may have occurred before this one and use that code
|
||||
// instead.
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
if (mSynthesizedGLError == LOCAL_GL_NO_ERROR) {
|
||||
MakeContextCurrent();
|
||||
UpdateWebGLErrorAndClearGLError();
|
||||
|
||||
mSynthesizedGLError = gl->fGetError();
|
||||
|
||||
if (mSynthesizedGLError == LOCAL_GL_NO_ERROR)
|
||||
mSynthesizedGLError = err;
|
||||
}
|
||||
if (!mWebGLError)
|
||||
mWebGLError = err;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -194,3 +190,24 @@ WebGLContext::ErrorOutOfMemory(const char *fmt, ...)
|
||||
return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
const char *
|
||||
WebGLContext::ErrorName(GLenum error)
|
||||
{
|
||||
switch(error) {
|
||||
case LOCAL_GL_INVALID_ENUM:
|
||||
return "INVALID_ENUM";
|
||||
case LOCAL_GL_INVALID_OPERATION:
|
||||
return "INVALID_OPERATION";
|
||||
case LOCAL_GL_INVALID_VALUE:
|
||||
return "INVALID_VALUE";
|
||||
case LOCAL_GL_OUT_OF_MEMORY:
|
||||
return "OUT_OF_MEMORY";
|
||||
case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
return "INVALID_FRAMEBUFFER_OPERATION";
|
||||
case LOCAL_GL_NO_ERROR:
|
||||
return "NO_ERROR";
|
||||
default:
|
||||
NS_ABORT();
|
||||
return "[unknown WebGL error!]";
|
||||
}
|
||||
};
|
||||
|
@ -39,8 +39,7 @@
|
||||
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "CheckedInt.h"
|
||||
|
||||
@ -329,6 +328,34 @@ PRBool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info)
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 WebGLContext::GetTexelSize(WebGLenum format, WebGLenum type)
|
||||
{
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
|
||||
int multiplier = type == LOCAL_GL_FLOAT ? 4 : 1;
|
||||
switch (format) {
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
return 1 * multiplier;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
return 2 * multiplier;
|
||||
case LOCAL_GL_RGB:
|
||||
return 3 * multiplier;
|
||||
case LOCAL_GL_RGBA:
|
||||
return 4 * multiplier;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
NS_ABORT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRBool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
|
||||
PRUint32 *texelSize, const char *info)
|
||||
{
|
||||
@ -449,7 +476,7 @@ WebGLContext::InitAndValidateGL()
|
||||
}
|
||||
|
||||
mActiveTexture = 0;
|
||||
mSynthesizedGLError = LOCAL_GL_NO_ERROR;
|
||||
mWebGLError = LOCAL_GL_NO_ERROR;
|
||||
|
||||
mAttribBuffers.Clear();
|
||||
|
||||
@ -519,7 +546,7 @@ WebGLContext::InitAndValidateGL()
|
||||
// and check OpenGL error for INVALID_ENUM.
|
||||
|
||||
// before we start, we check that no error already occurred, to prevent hiding it in our subsequent error handling
|
||||
error = gl->fGetError();
|
||||
error = gl->GetAndClearError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return PR_FALSE;
|
||||
@ -572,10 +599,10 @@ WebGLContext::InitAndValidateGL()
|
||||
}
|
||||
|
||||
// Check the shader validator pref
|
||||
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
|
||||
|
||||
prefService->GetBoolPref("webgl.shader_validator", &mShaderValidation);
|
||||
mShaderValidation =
|
||||
Preferences::GetBool("webgl.shader_validator", mShaderValidation);
|
||||
|
||||
#if defined(USE_ANGLE)
|
||||
// initialize shader translator
|
||||
@ -587,9 +614,9 @@ WebGLContext::InitAndValidateGL()
|
||||
}
|
||||
#endif
|
||||
|
||||
// notice that the point of calling GetError here is not only to check for error,
|
||||
// it is also to reset the error flag so that a subsequent WebGL getError call will give the correct result.
|
||||
error = gl->fGetError();
|
||||
// notice that the point of calling GetAndClearError here is not only to check for error,
|
||||
// it is also to reset the error flags so that a subsequent WebGL getError call will give the correct result.
|
||||
error = gl->GetAndClearError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return PR_FALSE;
|
||||
|
@ -349,10 +349,11 @@ public:
|
||||
|
||||
NS_IMETHOD SetIsOpaque(PRBool isOpaque);
|
||||
NS_IMETHOD Reset();
|
||||
already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
LayerManager *aManager);
|
||||
void MarkContextClean();
|
||||
virtual already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
LayerManager *aManager);
|
||||
virtual PRBool ShouldForceInactiveLayer(LayerManager *aManager);
|
||||
virtual void MarkContextClean();
|
||||
NS_IMETHOD SetIsIPC(PRBool isIPC);
|
||||
// this rect is in canvas device space
|
||||
NS_IMETHOD Redraw(const gfxRect &r);
|
||||
@ -1071,9 +1072,7 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
|
||||
gfxASurface::gfxImageFormat format = GetImageFormat();
|
||||
|
||||
if (PR_GetEnv("MOZ_CANVAS_IMAGE_SURFACE")) {
|
||||
surface = new gfxImageSurface(gfxIntSize(width, height), format);
|
||||
} else {
|
||||
if (!PR_GetEnv("MOZ_CANVAS_IMAGE_SURFACE")) {
|
||||
nsCOMPtr<nsIContent> content =
|
||||
do_QueryInterface(static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement));
|
||||
nsIDocument* ownerDoc = nsnull;
|
||||
@ -1093,8 +1092,15 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
}
|
||||
}
|
||||
|
||||
if (surface && surface->CairoStatus() != 0)
|
||||
surface = NULL;
|
||||
if (!surface || surface->CairoStatus()) {
|
||||
// If we couldn't create a surface of the type we want, fall back
|
||||
// to an image surface. This lets us handle surface sizes that
|
||||
// the underlying cairo backend might not handle.
|
||||
surface = new gfxImageSurface(gfxIntSize(width, height), format);
|
||||
if (!surface || surface->CairoStatus()) {
|
||||
surface = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (surface) {
|
||||
if (gCanvasMemoryReporter == nsnull) {
|
||||
@ -4017,6 +4023,12 @@ nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
return canvasLayer.forget();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager *aManager)
|
||||
{
|
||||
return !aManager->CanUseCanvasLayerForSize(gfxIntSize(mWidth, mHeight));
|
||||
}
|
||||
|
||||
void
|
||||
nsCanvasRenderingContext2D::MarkContextClean()
|
||||
{
|
||||
|
@ -194,79 +194,6 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
nsCanvasGradientAzure(Type aType) : mType(aType)
|
||||
{}
|
||||
|
||||
nsTArray<GradientStop> mRawStops;
|
||||
RefPtr<GradientStops> mStops;
|
||||
Type mType;
|
||||
};
|
||||
|
||||
class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
|
||||
{
|
||||
public:
|
||||
nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
|
||||
const Point &aEndOrigin, Float aEndRadius)
|
||||
: nsCanvasGradientAzure(RADIAL)
|
||||
, mCenter(aEndOrigin)
|
||||
, mRadius(aEndRadius)
|
||||
{
|
||||
mOffsetStart = aBeginRadius / mRadius;
|
||||
|
||||
mOffsetRatio = 1 - mOffsetStart;
|
||||
mOrigin = ((mCenter * aBeginRadius) - (aBeginOrigin * mRadius)) /
|
||||
(aBeginRadius - mRadius);
|
||||
}
|
||||
|
||||
|
||||
/* nsIDOMCanvasGradient */
|
||||
NS_IMETHOD AddColorStop (float offset,
|
||||
const nsAString& colorstr)
|
||||
{
|
||||
if (!FloatValidate(offset) || offset < 0.0 || offset > 1.0) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
}
|
||||
|
||||
nscolor color;
|
||||
nsCSSParser parser;
|
||||
nsresult rv = parser.ParseColorString(nsString(colorstr),
|
||||
nsnull, 0, &color);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
mStops = nsnull;
|
||||
|
||||
GradientStop newStop;
|
||||
|
||||
newStop.offset = offset * mOffsetRatio + mOffsetStart;
|
||||
newStop.color = Color::FromABGR(color);
|
||||
|
||||
mRawStops.AppendElement(newStop);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX - Temporary gradient code, this will be fixed soon as per bug 666097
|
||||
Point mCenter;
|
||||
Float mRadius;
|
||||
Point mOrigin;
|
||||
|
||||
Float mOffsetStart;
|
||||
Float mOffsetRatio;
|
||||
};
|
||||
|
||||
class nsCanvasLinearGradientAzure : public nsCanvasGradientAzure
|
||||
{
|
||||
public:
|
||||
nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
|
||||
: nsCanvasGradientAzure(LINEAR)
|
||||
, mBegin(aBegin)
|
||||
, mEnd(aEnd)
|
||||
{
|
||||
}
|
||||
|
||||
/* nsIDOMCanvasGradient */
|
||||
NS_IMETHOD AddColorStop (float offset,
|
||||
const nsAString& colorstr)
|
||||
@ -295,6 +222,44 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsCanvasGradientAzure(Type aType) : mType(aType)
|
||||
{}
|
||||
|
||||
nsTArray<GradientStop> mRawStops;
|
||||
RefPtr<GradientStops> mStops;
|
||||
Type mType;
|
||||
};
|
||||
|
||||
class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
|
||||
{
|
||||
public:
|
||||
nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
|
||||
const Point &aEndOrigin, Float aEndRadius)
|
||||
: nsCanvasGradientAzure(RADIAL)
|
||||
, mCenter1(aBeginOrigin)
|
||||
, mCenter2(aEndOrigin)
|
||||
, mRadius1(aBeginRadius)
|
||||
, mRadius2(aEndRadius)
|
||||
{
|
||||
}
|
||||
|
||||
Point mCenter1;
|
||||
Point mCenter2;
|
||||
Float mRadius1;
|
||||
Float mRadius2;
|
||||
};
|
||||
|
||||
class nsCanvasLinearGradientAzure : public nsCanvasGradientAzure
|
||||
{
|
||||
public:
|
||||
nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
|
||||
: nsCanvasGradientAzure(LINEAR)
|
||||
, mBegin(aBegin)
|
||||
, mEnd(aEnd)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class nsCanvasRenderingContext2DAzure;
|
||||
|
||||
@ -827,8 +792,8 @@ protected:
|
||||
static_cast<nsCanvasRadialGradientAzure*>(state.gradientStyles[aStyle].get());
|
||||
|
||||
mPattern = new (mRadialGradientPattern.addr())
|
||||
RadialGradientPattern(gradient->mCenter, gradient->mOrigin, gradient->mRadius,
|
||||
gradient->GetGradientStopsForTarget(aRT));
|
||||
RadialGradientPattern(gradient->mCenter1, gradient->mCenter2, gradient->mRadius1,
|
||||
gradient->mRadius2, gradient->GetGradientStopsForTarget(aRT));
|
||||
} else if (state.patternStyles[aStyle]) {
|
||||
if (aCtx->mCanvasElement) {
|
||||
CanvasUtils::DoDrawImageSecurityCheck(aCtx->HTMLCanvasElement(),
|
||||
|
@ -6,17 +6,6 @@
|
||||
<body>
|
||||
<canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<script>
|
||||
|
||||
function IsAzureEnabled() {
|
||||
var enabled = false;
|
||||
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
enabled = Components.classes["@mozilla.org/gfx/info;1"].getService(Components.interfaces.nsIGfxInfo).AzureEnabled;
|
||||
} catch (e) { }
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) {
|
||||
var pixel = ctx.getImageData(x, y, 1, 1);
|
||||
@ -59,28 +48,15 @@ g.addColorStop(1, '#0f0');
|
||||
ctx.fillStyle = g;
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
|
||||
if (IsAzureEnabled()) {
|
||||
// XXX - See Bug 666097.
|
||||
todo_isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
|
||||
todo_isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
|
||||
} else {
|
||||
isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
|
||||
isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
|
||||
isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
|
||||
isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
|
||||
isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
|
||||
isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
|
||||
isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
|
||||
isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
|
||||
isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
|
||||
}
|
||||
isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
|
||||
isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
|
||||
isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
|
||||
isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
|
||||
isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
|
||||
isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
|
||||
isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
|
||||
isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
|
||||
isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
|
@ -6399,28 +6399,15 @@ g.addColorStop(1, '#f00');
|
||||
ctx.fillStyle = g;
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
|
||||
if (IsAzureEnabled()) {
|
||||
// XXX - See Bug 666097.
|
||||
todo_isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
|
||||
} else {
|
||||
isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
|
||||
}
|
||||
isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -6570,29 +6557,15 @@ g.addColorStop(1, '#0f0');
|
||||
ctx.fillStyle = g;
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
|
||||
|
||||
if (IsAzureEnabled()) {
|
||||
// XXX - See Bug 666097.
|
||||
todo_isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
|
||||
todo_isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
|
||||
} else {
|
||||
isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
|
||||
}
|
||||
isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
|
||||
isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
|
||||
|
||||
}
|
||||
</script>
|
||||
|
@ -6,7 +6,6 @@ conformance/glsl-conformance.html
|
||||
conformance/invalid-passed-params.html
|
||||
conformance/more/conformance/quickCheckAPI.html
|
||||
conformance/more/functions/copyTexImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2DBadArgs.html
|
||||
conformance/more/functions/copyTexSubImage2D.html
|
||||
conformance/more/functions/deleteBufferBadArgs.html
|
||||
conformance/more/functions/texImage2DBadArgs.html
|
||||
|
@ -7,10 +7,8 @@ conformance/object-deletion-behaviour.html
|
||||
conformance/read-pixels-test.html
|
||||
conformance/tex-input-validation.html
|
||||
conformance/tex-sub-image-2d-bad-args.html
|
||||
conformance/uninitialized-test.html
|
||||
conformance/more/functions/copyTexImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2DBadArgs.html
|
||||
conformance/more/functions/deleteBufferBadArgs.html
|
||||
conformance/more/functions/texImage2DBadArgs.html
|
||||
conformance/more/functions/texSubImage2DBadArgs.html
|
||||
|
@ -4,11 +4,9 @@ conformance/invalid-passed-params.html
|
||||
conformance/object-deletion-behaviour.html
|
||||
conformance/read-pixels-test.html
|
||||
conformance/tex-sub-image-2d-bad-args.html
|
||||
conformance/uninitialized-test.html
|
||||
conformance/more/conformance/quickCheckAPI.html
|
||||
conformance/more/functions/copyTexImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2DBadArgs.html
|
||||
conformance/more/functions/deleteBufferBadArgs.html
|
||||
conformance/more/functions/texImage2DBadArgs.html
|
||||
conformance/more/functions/texSubImage2DBadArgs.html
|
||||
|
@ -368,6 +368,7 @@ function start() {
|
||||
testsExpectedToFail.push('conformance/gl-get-active-attribute.html'); // bug in NVIDIA 190.42, fixed in newer drivers
|
||||
testsExpectedToFail.push('conformance/gl-uniform-bool.html'); // bug in NVIDIA 190.42, fixed in newer drivers
|
||||
testsExpectedToFail.push('conformance/tex-image-and-sub-image-2d-with-array-buffer-view.html'); // ???
|
||||
testsExpectedToFail.push('conformance/uninitialized-test.html'); // bug in NVIDIA 190.42, fixed in newer drivers
|
||||
}
|
||||
|
||||
var testsToIgnore = [];
|
||||
|
@ -1657,6 +1657,93 @@ nsEventStateManager::HandleAccessKey(nsPresContext* aPresContext,
|
||||
}// if end. bubble up process
|
||||
}// end of HandleAccessKey
|
||||
|
||||
void
|
||||
nsEventStateManager::DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader* frameLoader) {
|
||||
nsFrameLoader* fml = static_cast<nsFrameLoader*>(frameLoader);
|
||||
PBrowserParent* remoteBrowser = fml->GetRemoteBrowser();
|
||||
TabParent* remote = static_cast<TabParent*>(remoteBrowser);
|
||||
if (!remote) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aEvent->eventStructType == NS_MOUSE_EVENT) {
|
||||
nsMouseEvent* mouseEvent = static_cast<nsMouseEvent*>(aEvent);
|
||||
remote->SendRealMouseEvent(*mouseEvent);
|
||||
}
|
||||
|
||||
if (aEvent->eventStructType == NS_KEY_EVENT) {
|
||||
nsKeyEvent* keyEvent = static_cast<nsKeyEvent*>(aEvent);
|
||||
remote->SendRealKeyEvent(*keyEvent);
|
||||
}
|
||||
|
||||
if (aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
nsMouseScrollEvent* scrollEvent = static_cast<nsMouseScrollEvent*>(aEvent);
|
||||
remote->SendMouseScrollEvent(*scrollEvent);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEventStateManager::IsRemoteTarget(nsIContent* target) {
|
||||
return target &&
|
||||
target->Tag() == nsGkAtoms::browser &&
|
||||
target->IsXUL() &&
|
||||
target->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
|
||||
nsGkAtoms::_true, eIgnoreCase);
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsEventStateManager::HandleCrossProcessEvent(nsEvent *aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus *aStatus) {
|
||||
|
||||
switch (aEvent->eventStructType) {
|
||||
case NS_KEY_EVENT:
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
break;
|
||||
case NS_MOUSE_EVENT:
|
||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN ||
|
||||
aEvent->message == NS_MOUSE_BUTTON_UP ||
|
||||
aEvent->message == NS_MOUSE_MOVE) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIContent* target = mCurrentTargetContent;
|
||||
if (!target && aTargetFrame) {
|
||||
target = aTargetFrame->GetContent();
|
||||
}
|
||||
|
||||
if (*aStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!target ||
|
||||
!IsRemoteTarget(target)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(target);
|
||||
if (!loaderOwner) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
|
||||
if (!frameLoader) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRUint32 eventMode;
|
||||
frameLoader->GetEventMode(&eventMode);
|
||||
if (eventMode == nsIFrameLoader::EVENT_MODE_DONT_FORWARD_TO_CHILD) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aTargetFrame);
|
||||
aEvent->refPoint = pt.ToNearestPixels(mPresContext->AppUnitsPerDevPixel());
|
||||
|
||||
DispatchCrossProcessEvent(aEvent, frameLoader);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// CreateClickHoldTimer
|
||||
@ -2905,6 +2992,8 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
NS_ENSURE_ARG(aPresContext);
|
||||
NS_ENSURE_ARG_POINTER(aStatus);
|
||||
|
||||
HandleCrossProcessEvent(aEvent, aTargetFrame, aStatus);
|
||||
|
||||
mCurrentTarget = aTargetFrame;
|
||||
mCurrentTargetContent = nsnull;
|
||||
|
||||
@ -3420,6 +3509,10 @@ nsEventStateManager::UpdateCursor(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIFrame* aTargetFrame,
|
||||
nsEventStatus* aStatus)
|
||||
{
|
||||
if (aTargetFrame && IsRemoteTarget(aTargetFrame->GetContent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRInt32 cursor = NS_STYLE_CURSOR_DEFAULT;
|
||||
imgIContainer* container = nsnull;
|
||||
PRBool haveHotspot = PR_FALSE;
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIFrameLoader.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIMarkupDocumentViewer.h"
|
||||
@ -427,6 +428,12 @@ protected:
|
||||
mozilla::dom::TabParent *GetCrossProcessTarget();
|
||||
PRBool IsTargetCrossProcess(nsGUIEvent *aEvent);
|
||||
|
||||
void DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader* remote);
|
||||
PRBool IsRemoteTarget(nsIContent* target);
|
||||
PRBool HandleCrossProcessEvent(nsEvent *aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus *aStatus);
|
||||
|
||||
private:
|
||||
static inline void DoStateChange(mozilla::dom::Element* aElement,
|
||||
nsEventStates aState, PRBool aAddState);
|
||||
|
@ -170,6 +170,10 @@ public:
|
||||
already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
LayerManager *aManager);
|
||||
// Should return true if the canvas layer should always be marked inactive.
|
||||
// We should return true here if we can't do accelerated compositing with
|
||||
// a non-BasicCanvasLayer.
|
||||
PRBool ShouldForceInactiveLayer(LayerManager *aManager);
|
||||
|
||||
// Call this whenever we need future changes to the canvas
|
||||
// to trigger fresh invalidation requests. This needs to be called
|
||||
@ -193,6 +197,7 @@ protected:
|
||||
const nsAString& aType,
|
||||
nsIDOMFile** aResult);
|
||||
nsresult GetContextHelper(const nsAString& aContextId,
|
||||
PRBool aForceThebes,
|
||||
nsICanvasRenderingContextInternal **aContext);
|
||||
|
||||
nsString mCurrentContextId;
|
||||
|
@ -4,7 +4,7 @@
|
||||
<script>
|
||||
function focusHandler()
|
||||
{
|
||||
setTimeout(document.documentElement.removeAttribute('class'), 0);
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
</script>
|
||||
<body>
|
||||
|
@ -380,11 +380,12 @@ nsHTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
|
||||
|
||||
nsresult
|
||||
nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
||||
PRBool aForceThebes,
|
||||
nsICanvasRenderingContextInternal **aContext)
|
||||
{
|
||||
NS_ENSURE_ARG(aContext);
|
||||
|
||||
NS_LossyConvertUTF16toASCII ctxId(aContextId);
|
||||
NS_ConvertUTF16toUTF8 ctxId(aContextId);
|
||||
|
||||
// check that ctxId is clamped to A-Za-z0-9_-
|
||||
for (PRUint32 i = 0; i < ctxId.Length(); i++) {
|
||||
@ -402,6 +403,10 @@ nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
||||
nsCString ctxString("@mozilla.org/content/canvas-rendering-context;1?id=");
|
||||
ctxString.Append(ctxId);
|
||||
|
||||
if (aForceThebes && ctxId.EqualsASCII("2d")) {
|
||||
ctxString.AssignASCII("@mozilla.org/content/2dthebes-canvas-rendering-context;1");
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICanvasRenderingContextInternal> ctx =
|
||||
do_CreateInstance(ctxString.get(), &rv);
|
||||
@ -433,8 +438,10 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (mCurrentContextId.IsEmpty()) {
|
||||
rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
|
||||
PRBool forceThebes = PR_FALSE;
|
||||
|
||||
while (mCurrentContextId.IsEmpty()) {
|
||||
rv = GetContextHelper(aContextId, forceThebes, getter_AddRefs(mCurrentContext));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mCurrentContext) {
|
||||
return NS_OK;
|
||||
@ -506,11 +513,18 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
|
||||
rv = UpdateContext(contextProps);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCurrentContext = nsnull;
|
||||
if (!forceThebes) {
|
||||
// Try again with a Thebes context
|
||||
forceThebes = PR_TRUE;
|
||||
continue;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentContextId.Assign(aContextId);
|
||||
} else if (!mCurrentContextId.Equals(aContextId)) {
|
||||
break;
|
||||
}
|
||||
if (!mCurrentContextId.Equals(aContextId)) {
|
||||
//XXX eventually allow for more than one active context on a given canvas
|
||||
return NS_OK;
|
||||
}
|
||||
@ -535,7 +549,7 @@ nsHTMLCanvasElement::MozGetIPCContext(const nsAString& aContextId,
|
||||
nsresult rv;
|
||||
|
||||
if (mCurrentContextId.IsEmpty()) {
|
||||
rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
|
||||
rv = GetContextHelper(aContextId, PR_FALSE, getter_AddRefs(mCurrentContext));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mCurrentContext) {
|
||||
return NS_OK;
|
||||
@ -700,6 +714,12 @@ nsHTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLCanvasElement::ShouldForceInactiveLayer(LayerManager *aManager)
|
||||
{
|
||||
return !mCurrentContext || mCurrentContext->ShouldForceInactiveLayer(aManager);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLCanvasElement::MarkContextClean()
|
||||
{
|
||||
|
@ -643,6 +643,12 @@ ImageDocument::CreateSyntheticDocument()
|
||||
nsresult rv = MediaDocument::CreateSyntheticDocument();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We must declare the image as a block element. If we stay as
|
||||
// an inline element, our parent LineBox will be inline too and
|
||||
// ignore the available height during reflow.
|
||||
// This is bad during printing, it means tall image frames won't know
|
||||
// the size of the paper and cannot break into continuations along
|
||||
// multiple pages.
|
||||
Element* body = GetBodyElement();
|
||||
if (!body) {
|
||||
NS_WARNING("no body on image document!");
|
||||
@ -650,6 +656,19 @@ ImageDocument::CreateSyntheticDocument()
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::style, nsnull,
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsRefPtr<nsGenericHTMLElement> styleContent = NS_NewHTMLStyleElement(nodeInfo.forget());
|
||||
if (!styleContent) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
styleContent->SetTextContent(NS_LITERAL_STRING("img { display: block; }"));
|
||||
body->AppendChildTo(styleContent, PR_FALSE);
|
||||
|
||||
// Add the image element
|
||||
nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::img, nsnull,
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
|
@ -2170,16 +2170,8 @@ nsHTMLDocument::GetEmbeds(nsIDOMHTMLCollection** aEmbeds)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLDocument::GetSelection(nsAString& aReturn)
|
||||
nsHTMLDocument::GetSelection(nsISelection** aReturn)
|
||||
{
|
||||
aReturn.Truncate();
|
||||
|
||||
nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
JSContext* ccx = nsnull;
|
||||
if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx) {
|
||||
JS_ReportWarning(ccx, "Deprecated method document.getSelection() called. Please use window.getSelection() instead.");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetScopeObject());
|
||||
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(window);
|
||||
NS_ENSURE_TRUE(pwin, NS_OK);
|
||||
@ -2188,17 +2180,8 @@ nsHTMLDocument::GetSelection(nsAString& aReturn)
|
||||
pwin->GetOuterWindow()->GetCurrentInnerWindow() == pwin,
|
||||
NS_OK);
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsresult rv = window->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_TRUE(selection && NS_SUCCEEDED(rv), rv);
|
||||
|
||||
nsXPIDLString str;
|
||||
|
||||
rv = selection->ToString(getter_Copies(str));
|
||||
|
||||
aReturn.Assign(str);
|
||||
|
||||
return rv;
|
||||
return window->GetSelection(aReturn);
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -310,6 +310,10 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
|
||||
|
||||
if (HasAudio()) {
|
||||
// Decode audio forward to the seek target.
|
||||
PRInt64 targetSample = 0;
|
||||
if (!UsecsToSamples(aTarget, mInfo.mAudioRate, targetSample)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
PRBool eof = PR_FALSE;
|
||||
while (HasAudio() && !eof) {
|
||||
while (!eof && mAudioQueue.GetSize() == 0) {
|
||||
@ -322,14 +326,53 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
|
||||
}
|
||||
}
|
||||
}
|
||||
nsAutoPtr<SoundData> audio(mAudioQueue.PeekFront());
|
||||
if (audio && audio->mTime + audio->mDuration <= aTarget) {
|
||||
mAudioQueue.PopFront();
|
||||
const SoundData* audio = mAudioQueue.PeekFront();
|
||||
if (!audio)
|
||||
break;
|
||||
PRInt64 startSample = 0;
|
||||
if (!UsecsToSamples(audio->mTime, mInfo.mAudioRate, startSample)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (startSample + audio->mSamples <= targetSample) {
|
||||
// Our seek target lies after the samples in this SoundData. Pop it
|
||||
// off the queue, and keep decoding forwards.
|
||||
delete mAudioQueue.PopFront();
|
||||
audio = nsnull;
|
||||
} else {
|
||||
audio.forget();
|
||||
continue;
|
||||
}
|
||||
|
||||
// The seek target lies somewhere in this SoundData's samples, strip off
|
||||
// any samples which lie before the seek target, so we'll begin playback
|
||||
// exactly at the seek target.
|
||||
NS_ASSERTION(targetSample >= startSample, "Target must at or be after data start.");
|
||||
NS_ASSERTION(startSample + audio->mSamples > targetSample, "Data must end after target.");
|
||||
|
||||
PRInt64 samplesToPrune = targetSample - startSample;
|
||||
if (samplesToPrune > audio->mSamples) {
|
||||
// We've messed up somehow. Don't try to trim samples, the |samples|
|
||||
// variable below will overflow.
|
||||
NS_WARNING("Can't prune more samples that we have!");
|
||||
break;
|
||||
}
|
||||
PRUint32 samples = audio->mSamples - static_cast<PRUint32>(samplesToPrune);
|
||||
PRUint32 channels = audio->mChannels;
|
||||
nsAutoArrayPtr<SoundDataValue> audioData(new SoundDataValue[samples * channels]);
|
||||
memcpy(audioData.get(),
|
||||
audio->mAudioData.get() + (samplesToPrune * channels),
|
||||
samples * channels * sizeof(SoundDataValue));
|
||||
PRInt64 duration;
|
||||
if (!SamplesToUsecs(samples, mInfo.mAudioRate, duration)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsAutoPtr<SoundData> data(new SoundData(audio->mOffset,
|
||||
aTarget,
|
||||
duration,
|
||||
samples,
|
||||
audioData.forget(),
|
||||
channels));
|
||||
delete mAudioQueue.PopFront();
|
||||
mAudioQueue.PushFront(data.forget());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1263,6 +1263,17 @@ nsresult nsOggReader::SeekBisection(PRInt64 aTarget,
|
||||
SEEK_LOG(PR_LOG_DEBUG, ("Backing off %d bytes, backsteps=%d",
|
||||
static_cast<PRInt32>(PAGE_STEP * pow(2.0, backsteps)), backsteps));
|
||||
guess -= PAGE_STEP * static_cast<ogg_int64_t>(pow(2.0, backsteps));
|
||||
|
||||
if (guess <= startOffset) {
|
||||
// We've tried to backoff to before the start offset of our seek
|
||||
// range. This means we couldn't find a seek termination position
|
||||
// near the end of the seek range, so just set the seek termination
|
||||
// condition, and break out of the bisection loop. We'll begin
|
||||
// decoding from the start of the seek range.
|
||||
interval = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
backsteps = NS_MIN(backsteps + 1, maxBackStep);
|
||||
// We reset mustBackoff. If we still need to backoff further, it will
|
||||
// be set to PR_TRUE again.
|
||||
@ -1329,14 +1340,14 @@ nsresult nsOggReader::SeekBisection(PRInt64 aTarget,
|
||||
ogg_int64_t granulepos = ogg_page_granulepos(&page);
|
||||
|
||||
if (HasAudio() &&
|
||||
granulepos != -1 &&
|
||||
granulepos > 0 &&
|
||||
serial == mVorbisState->mSerial &&
|
||||
audioTime == -1) {
|
||||
audioTime = mVorbisState->Time(granulepos);
|
||||
}
|
||||
|
||||
if (HasVideo() &&
|
||||
granulepos != -1 &&
|
||||
granulepos > 0 &&
|
||||
serial == mTheoraState->mSerial &&
|
||||
videoTime == -1) {
|
||||
videoTime = mTheoraState->StartTime(granulepos);
|
||||
|
@ -43,8 +43,7 @@
|
||||
#include "nsWebMReader.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "nsTimeRanges.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::layers;
|
||||
@ -309,9 +308,9 @@ nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo)
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
PRInt32 forceStereoMode;
|
||||
if (NS_SUCCEEDED(prefs->GetIntPref("media.webm.force_stereo_mode", &forceStereoMode))) {
|
||||
if (NS_SUCCEEDED(Preferences::GetInt("media.webm.force_stereo_mode",
|
||||
&forceStereoMode))) {
|
||||
switch (forceStereoMode) {
|
||||
case 1:
|
||||
mInfo.mStereoMode = STEREO_MODE_LEFT_RIGHT;
|
||||
|
@ -124,7 +124,7 @@ DOMSVGAnimatedLengthList::InternalBaseValListWillChangeTo(const SVGLengthList& a
|
||||
|
||||
nsRefPtr<DOMSVGAnimatedLengthList> kungFuDeathGrip;
|
||||
if (mBaseVal) {
|
||||
if (!aNewValue.Length()) {
|
||||
if (aNewValue.Length() < mBaseVal->Length()) {
|
||||
// InternalListLengthWillChange might clear last reference to |this|.
|
||||
// Retain a temporary reference to keep from dying before returning.
|
||||
kungFuDeathGrip = this;
|
||||
|
@ -123,7 +123,7 @@ DOMSVGAnimatedNumberList::InternalBaseValListWillChangeTo(const SVGNumberList& a
|
||||
|
||||
nsRefPtr<DOMSVGAnimatedNumberList> kungFuDeathGrip;
|
||||
if (mBaseVal) {
|
||||
if (!aNewValue.Length()) {
|
||||
if (aNewValue.Length() < mBaseVal->Length()) {
|
||||
// InternalListLengthWillChange might clear last reference to |this|.
|
||||
// Retain a temporary reference to keep from dying before returning.
|
||||
kungFuDeathGrip = this;
|
||||
|
@ -119,7 +119,7 @@ DOMSVGLengthList::InternalListLengthWillChange(PRUint32 aNewLength)
|
||||
}
|
||||
|
||||
nsRefPtr<DOMSVGLengthList> kungFuDeathGrip;
|
||||
if (oldLength && !aNewLength) {
|
||||
if (aNewLength < oldLength) {
|
||||
// RemovingFromList() might clear last reference to |this|.
|
||||
// Retain a temporary reference to keep from dying before returning.
|
||||
kungFuDeathGrip = this;
|
||||
|
@ -119,7 +119,7 @@ DOMSVGNumberList::InternalListLengthWillChange(PRUint32 aNewLength)
|
||||
}
|
||||
|
||||
nsRefPtr<DOMSVGNumberList> kungFuDeathGrip;
|
||||
if (oldLength && !aNewLength) {
|
||||
if (aNewLength < oldLength) {
|
||||
// RemovingFromList() might clear last reference to |this|.
|
||||
// Retain a temporary reference to keep from dying before returning.
|
||||
kungFuDeathGrip = this;
|
||||
|
@ -156,7 +156,7 @@ DOMSVGPathSegList::InternalListWillChangeTo(const SVGPathData& aNewValue)
|
||||
PRUint32 newSegType;
|
||||
|
||||
nsRefPtr<DOMSVGPathSegList> kungFuDeathGrip;
|
||||
if (length && aNewValue.IsEmpty()) {
|
||||
if (aNewValue.Length() < length) {
|
||||
// RemovingFromList() might clear last reference to |this|.
|
||||
// Retain a temporary reference to keep from dying before returning.
|
||||
kungFuDeathGrip = this;
|
||||
|
@ -148,7 +148,7 @@ DOMSVGPointList::InternalListWillChangeTo(const SVGPointList& aNewValue)
|
||||
}
|
||||
|
||||
nsRefPtr<DOMSVGPointList> kungFuDeathGrip;
|
||||
if (oldLength && !newLength) {
|
||||
if (newLength < oldLength) {
|
||||
// RemovingFromList() might clear last reference to |this|.
|
||||
// Retain a temporary reference to keep from dying before returning.
|
||||
kungFuDeathGrip = this;
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include "nsStyleUtil.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -72,14 +71,7 @@ nsSVGFeatures::HaveFeature(nsISupports* aObject, const nsAString& aFeature)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (prefs) {
|
||||
PRBool js;
|
||||
if (NS_SUCCEEDED(prefs->GetBoolPref("javascript.enabled", &js))) {
|
||||
return js;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
return Preferences::GetBool("javascript.enabled", PR_FALSE);
|
||||
}
|
||||
#define SVG_SUPPORTED_FEATURE(str) if (aFeature.EqualsLiteral(str)) return PR_TRUE;
|
||||
#define SVG_UNSUPPORTED_FEATURE(str)
|
||||
|
@ -4,7 +4,7 @@ load 226744-1.xhtml
|
||||
load 232095-1.xul
|
||||
load 277523-1.xhtml
|
||||
load 277950-1.xhtml
|
||||
load 336744-1.html
|
||||
skip-if(browserIsRemote) load 336744-1.html # no remote support for xul popups, bug 617653
|
||||
asserts(0-1) load 336960-1.html # maybe bug 429586
|
||||
load 342954-1.xhtml
|
||||
load 342954-2.xhtml
|
||||
|
@ -9192,7 +9192,17 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
|
||||
// Load attributes depend on load type...
|
||||
switch (mLoadType) {
|
||||
case LOAD_HISTORY:
|
||||
loadFlags |= nsIRequest::VALIDATE_NEVER;
|
||||
{
|
||||
// Only send VALIDATE_NEVER if mLSHE's URI was never changed via
|
||||
// push/replaceState (bug 669671).
|
||||
PRBool uriModified = PR_FALSE;
|
||||
if (mLSHE) {
|
||||
mLSHE->GetURIWasModified(&uriModified);
|
||||
}
|
||||
|
||||
if (!uriModified)
|
||||
loadFlags |= nsIRequest::VALIDATE_NEVER;
|
||||
}
|
||||
break;
|
||||
|
||||
case LOAD_RELOAD_CHARSET_CHANGE:
|
||||
@ -9854,6 +9864,15 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle,
|
||||
newSHEntry->SetStateData(scContainer);
|
||||
newSHEntry->SetPostData(nsnull);
|
||||
|
||||
// If this push/replaceState changed the document's current URI and the new
|
||||
// URI differs from the old URI in more than the hash, or if the old
|
||||
// SHEntry's URI was modified in this way by a push/replaceState call
|
||||
// set URIWasModified to true for the current SHEntry (bug 669671).
|
||||
PRBool sameExceptHashes = PR_TRUE, oldURIWasModified = PR_FALSE;
|
||||
newURI->EqualsExceptRef(mCurrentURI, &sameExceptHashes);
|
||||
oldOSHE->GetURIWasModified(&oldURIWasModified);
|
||||
newSHEntry->SetURIWasModified(!sameExceptHashes || oldURIWasModified);
|
||||
|
||||
// Step 5: If aReplace is false, indicating that we're doing a pushState
|
||||
// rather than a replaceState, notify bfcache that we've added a page to
|
||||
// the history so it can evict content viewers if appropriate.
|
||||
|
@ -59,7 +59,7 @@ class nsDocShellEditorData;
|
||||
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
|
||||
|
||||
|
||||
[scriptable, uuid(5f3ebf43-6944-45fb-b1b1-78a05bf9370b)]
|
||||
[scriptable, uuid(b92d403e-f5ec-4b81-b0e3-6e6c241cef2d)]
|
||||
interface nsISHEntry : nsIHistoryEntry
|
||||
{
|
||||
/** URI for the document */
|
||||
@ -169,6 +169,19 @@ interface nsISHEntry : nsIHistoryEntry
|
||||
* is a session history entry for
|
||||
*/
|
||||
attribute ACString contentType;
|
||||
|
||||
/**
|
||||
* If we created this SHEntry via history.pushState or modified it via
|
||||
* history.replaceState, and if we changed the SHEntry's URI via the
|
||||
* push/replaceState call, and if the SHEntry's new URI differs from its
|
||||
* old URI by more than just the hash, then we set this field to true.
|
||||
*
|
||||
* Additionally, if this SHEntry was created by calling pushState from a
|
||||
* SHEntry whose URI was modified, this SHEntry's URIWasModified field is
|
||||
* true.
|
||||
*
|
||||
*/
|
||||
attribute boolean URIWasModified;
|
||||
|
||||
/** Set/Get scrollers' positon in anchored pages */
|
||||
void setScrollPosition(in long x, in long y);
|
||||
|
@ -108,6 +108,7 @@ nsSHEntry::nsSHEntry()
|
||||
, mDocIdentifier(gEntryDocIdentifier++)
|
||||
, mScrollPositionX(0)
|
||||
, mScrollPositionY(0)
|
||||
, mURIWasModified(PR_FALSE)
|
||||
, mIsFrameNavigation(PR_FALSE)
|
||||
, mSaveLayoutState(PR_TRUE)
|
||||
, mExpired(PR_FALSE)
|
||||
@ -132,6 +133,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
|
||||
, mDocIdentifier(other.mDocIdentifier)
|
||||
, mScrollPositionX(0) // XXX why not copy?
|
||||
, mScrollPositionY(0) // XXX why not copy?
|
||||
, mURIWasModified(other.mURIWasModified)
|
||||
, mIsFrameNavigation(other.mIsFrameNavigation)
|
||||
, mSaveLayoutState(other.mSaveLayoutState)
|
||||
, mExpired(other.mExpired)
|
||||
@ -208,6 +210,18 @@ NS_IMETHODIMP nsSHEntry::GetScrollPosition(PRInt32 *x, PRInt32 *y)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::GetURIWasModified(PRBool* aOut)
|
||||
{
|
||||
*aOut = mURIWasModified;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::SetURIWasModified(PRBool aIn)
|
||||
{
|
||||
mURIWasModified = aIn;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::GetURI(nsIURI** aURI)
|
||||
{
|
||||
*aURI = mURI;
|
||||
|
@ -102,6 +102,7 @@ private:
|
||||
PRInt64 mDocIdentifier;
|
||||
PRInt32 mScrollPositionX;
|
||||
PRInt32 mScrollPositionY;
|
||||
PRPackedBool mURIWasModified;
|
||||
PRPackedBool mIsFrameNavigation;
|
||||
PRPackedBool mSaveLayoutState;
|
||||
PRPackedBool mExpired;
|
||||
|
@ -1496,6 +1496,7 @@ nsSHistory::LoadEntry(PRInt32 aIndex, long aLoadType, PRUint32 aHistCmd)
|
||||
if (!canNavigate) {
|
||||
// If the listener asked us not to proceed with
|
||||
// the operation, simply return.
|
||||
mRequestedIndex = -1;
|
||||
return NS_OK; // XXX Maybe I can return some other error code?
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,8 @@ _TEST_FILES = \
|
||||
test_bug668513.html \
|
||||
bug668513_redirect.html \
|
||||
bug668513_redirect.html^headers^ \
|
||||
test_bug669671.html \
|
||||
file_bug669671.sjs \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
|
13
docshell/test/file_bug669671.sjs
Normal file
13
docshell/test/file_bug669671.sjs
Normal file
@ -0,0 +1,13 @@
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var count = parseInt(getState('count'));
|
||||
if (!count)
|
||||
count = 0;
|
||||
setState('count', count + 1 + '');
|
||||
|
||||
response.setHeader('Content-Type', 'text/html', false);
|
||||
response.setHeader('Cache-Control', 'max-age=0');
|
||||
response.write('<html><body onload="opener.onChildLoad()" ' +
|
||||
'onunload="parseInt(\'0\')">' +
|
||||
count + '</body></html>');
|
||||
}
|
140
docshell/test/test_bug669671.html
Normal file
140
docshell/test/test_bug669671.html
Normal file
@ -0,0 +1,140 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=669671
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 669671</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=669671">Mozilla Bug 669671</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
/**
|
||||
* Test for Bug 669671.
|
||||
*
|
||||
* This is a bit complicated. We have a script, file_bug669671.sjs, which counts
|
||||
* how many times it's loaded and returns that count in the body of an HTML
|
||||
* document. For brevity, call this page X.
|
||||
*
|
||||
* X is sent with Cache-Control: max-age=0 and can't be bfcached (it has an
|
||||
* onunload handler). Our test does the following in a popup:
|
||||
*
|
||||
* 1) Load X?pushed, to prime the cache.
|
||||
* 2) Navigate to X.
|
||||
* 3) Call pushState and navigate from X to X?pushed.
|
||||
* 4) Navigate to X?navigated.
|
||||
* 5) Go back (to X?pushed).
|
||||
*
|
||||
* We do all this work so we can check that in step 5, we fetch X?pushed from
|
||||
* the network -- we shouldn't use our cached copy, because of the
|
||||
* cache-control header X sends.
|
||||
*
|
||||
* Then we go back and repeat the whole process but call history.replaceState
|
||||
* instead of pushState. And for good measure, we test once more, this time
|
||||
* modifying only the hash of the URI using replaceState. In this case, we
|
||||
* *should* load from the cache.
|
||||
*
|
||||
**/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function onChildLoad()
|
||||
{
|
||||
SimpleTest.executeSoon(function() { gGen.next() });
|
||||
}
|
||||
|
||||
var _loadCount = 0;
|
||||
function checkPopupLoadCount()
|
||||
{
|
||||
is(popup.document.body.innerHTML, _loadCount + '', 'Load count');
|
||||
|
||||
// We normally want to increment _loadCount here. But if the test fails
|
||||
// because we didn't do a load we should have, let's not cause a cascade of
|
||||
// failures by incrementing _loadCount.
|
||||
var origCount = _loadCount;
|
||||
if (popup.document.body.innerHTML >= _loadCount + '')
|
||||
_loadCount++;
|
||||
return origCount;
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
// Step 1 - The popup's body counts how many times we've requested the
|
||||
// resource. This is the first time we've requested it, so it should be '0'.
|
||||
checkPopupLoadCount();
|
||||
|
||||
// Step 2 - We'll get another onChildLoad when this finishes.
|
||||
popup.location = 'file_bug669671.sjs';
|
||||
yield;
|
||||
|
||||
// Step 3 - Call pushState and change the URI back to ?pushed.
|
||||
checkPopupLoadCount();
|
||||
popup.history.pushState('', '', '?pushed');
|
||||
|
||||
// Step 4 - Navigate away. This should trigger another onChildLoad.
|
||||
popup.location = 'file_bug669671.sjs?navigated-1';
|
||||
yield;
|
||||
|
||||
// Step 5 - Go back. This should result in another onload (because the file is
|
||||
// not in bfcache) and should be the fourth time we've requested the sjs file.
|
||||
checkPopupLoadCount();
|
||||
popup.back();
|
||||
yield;
|
||||
|
||||
// This is the check which was failing before we fixed the bug.
|
||||
checkPopupLoadCount();
|
||||
|
||||
popup.close();
|
||||
|
||||
// Do the whole thing again, but with replaceState.
|
||||
popup = window.open('file_bug669671.sjs?replaced');
|
||||
yield;
|
||||
checkPopupLoadCount();
|
||||
popup.location = 'file_bug669671.sjs';
|
||||
yield;
|
||||
checkPopupLoadCount();
|
||||
popup.history.replaceState('', '', '?replaced');
|
||||
popup.location = 'file_bug669671.sjs?navigated-2';
|
||||
yield;
|
||||
checkPopupLoadCount();
|
||||
popup.back();
|
||||
yield;
|
||||
checkPopupLoadCount();
|
||||
popup.close();
|
||||
|
||||
// Once more, with feeling. Notice that we don't have to prime the cache
|
||||
// with an extra load here, because X and X#hash share the same cache entry.
|
||||
popup = window.open('file_bug669671.sjs?hash-test');
|
||||
yield;
|
||||
var initialCount = checkPopupLoadCount();
|
||||
popup.history.replaceState('', '', '#hash');
|
||||
popup.location = 'file_bug669671.sjs?navigated-3';
|
||||
yield;
|
||||
checkPopupLoadCount();
|
||||
popup.back();
|
||||
yield;
|
||||
is(popup.document.body.innerHTML, initialCount + '',
|
||||
'Load count (should be cached)');
|
||||
popup.close();
|
||||
|
||||
SimpleTest.finish();
|
||||
yield;
|
||||
}
|
||||
|
||||
// This will call into onChildLoad once it loads.
|
||||
var popup = window.open('file_bug669671.sjs?pushed');
|
||||
|
||||
var gGen = test();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -54,31 +54,31 @@ nsDOMMemoryReporter::Init()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMemoryReporter::GetProcess(char** aProcess)
|
||||
nsDOMMemoryReporter::GetProcess(nsACString &aProcess)
|
||||
{
|
||||
// "" means the main process.
|
||||
*aProcess = strdup("");
|
||||
aProcess.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMemoryReporter::GetPath(char** aMemoryPath)
|
||||
nsDOMMemoryReporter::GetPath(nsACString &aMemoryPath)
|
||||
{
|
||||
*aMemoryPath = strdup("explicit/dom");
|
||||
aMemoryPath.AssignLiteral("explicit/dom");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMemoryReporter::GetKind(int* aKind)
|
||||
nsDOMMemoryReporter::GetKind(PRInt32* aKind)
|
||||
{
|
||||
*aKind = KIND_HEAP;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMemoryReporter::GetDescription(char** aDescription)
|
||||
nsDOMMemoryReporter::GetDescription(nsACString &aDescription)
|
||||
{
|
||||
*aDescription = strdup("Memory used by the DOM.");
|
||||
aDescription.AssignLiteral("Memory used by the DOM.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -44,16 +44,10 @@
|
||||
class nsDOMMemoryReporter: public nsIMemoryReporter {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
|
||||
static void Init();
|
||||
|
||||
NS_IMETHOD GetProcess(char** aProcess);
|
||||
NS_IMETHOD GetPath(char** aMemoryPath);
|
||||
NS_IMETHOD GetKind(int* aKnd);
|
||||
NS_IMETHOD GetDescription(char** aDescription);
|
||||
NS_IMETHOD GetUnits(PRInt32* aUnits);
|
||||
NS_IMETHOD GetAmount(PRInt64* aAmount);
|
||||
|
||||
private:
|
||||
// Protect ctor, use Init() instead.
|
||||
nsDOMMemoryReporter();
|
||||
|
@ -34,6 +34,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
#include "nsFocusManager.h"
|
||||
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
@ -1531,14 +1533,14 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
|
||||
NotifyFocusStateChange(content, shouldShowFocusRing, PR_FALSE);
|
||||
}
|
||||
|
||||
// if an object/plug-in is being blurred, move the system focus to the
|
||||
// parent window, otherwise events will still get fired at the plugin.
|
||||
// if an object/plug-in/remote browser is being blurred, move the system focus
|
||||
// to the parent window, otherwise events will still get fired at the plugin.
|
||||
// But don't do this if we are blurring due to the window being lowered,
|
||||
// otherwise, the parent window can get raised again.
|
||||
if (mActiveWindow && aAdjustWidgets) {
|
||||
if (mActiveWindow) {
|
||||
nsIFrame* contentFrame = content->GetPrimaryFrame();
|
||||
nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
|
||||
if (objectFrame) {
|
||||
if (aAdjustWidgets && objectFrame) {
|
||||
// note that the presshell's widget is being retrieved here, not the one
|
||||
// for the object frame.
|
||||
nsIViewManager* vm = presShell->GetViewManager();
|
||||
@ -1549,6 +1551,15 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
|
||||
widget->SetFocus(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// if the object being blurred is a remote browser, deactivate remote content
|
||||
TabParent* remote = GetRemoteForContent(content);
|
||||
if (remote) {
|
||||
remote->Deactivate();
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("*Remote browser deactivated\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1746,12 +1757,21 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
||||
|
||||
NotifyFocusStateChange(aContent, aWindow->ShouldShowFocusRing(), PR_TRUE);
|
||||
|
||||
// if this is an object/plug-in, focus the plugin's widget. Note that we might
|
||||
// if this is an object/plug-in/remote browser, focus its widget. Note that we might
|
||||
// no longer be in the same document, due to the events we fired above when
|
||||
// aIsNewDocument.
|
||||
if (aAdjustWidgets && presShell->GetDocument() == aContent->GetDocument()) {
|
||||
if (objectFrameWidget)
|
||||
if (presShell->GetDocument() == aContent->GetDocument()) {
|
||||
if (aAdjustWidgets && objectFrameWidget)
|
||||
objectFrameWidget->SetFocus(PR_FALSE);
|
||||
|
||||
// if the object being focused is a remote browser, activate remote content
|
||||
TabParent* remote = GetRemoteForContent(aContent);
|
||||
if (remote) {
|
||||
remote->Activate();
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("*Remote browser activated\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 reason = GetFocusMoveReason(aFlags);
|
||||
@ -2948,6 +2968,28 @@ nsFocusManager::GetRootForFocus(nsPIDOMWindow* aWindow,
|
||||
return rootElement;
|
||||
}
|
||||
|
||||
TabParent*
|
||||
nsFocusManager::GetRemoteForContent(nsIContent* aContent) {
|
||||
if (!aContent ||
|
||||
aContent->Tag() != nsGkAtoms::browser ||
|
||||
!aContent->IsXUL() ||
|
||||
!aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
|
||||
nsGkAtoms::_true, eIgnoreCase))
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
|
||||
if (!loaderOwner)
|
||||
return nsnull;
|
||||
|
||||
nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
|
||||
if (!frameLoader)
|
||||
return nsnull;
|
||||
|
||||
PBrowserParent* remoteBrowser = frameLoader->GetRemoteBrowser();
|
||||
TabParent* remote = static_cast<TabParent*>(remoteBrowser);
|
||||
return remote;
|
||||
}
|
||||
|
||||
void
|
||||
nsFocusManager::GetLastDocShell(nsIDocShellTreeItem* aItem,
|
||||
nsIDocShellTreeItem** aResult)
|
||||
|
@ -49,6 +49,13 @@
|
||||
|
||||
class nsIDocShellTreeItem;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class TabParent;
|
||||
}
|
||||
}
|
||||
|
||||
struct nsDelayedBlurOrFocusEvent;
|
||||
|
||||
/**
|
||||
@ -424,6 +431,12 @@ protected:
|
||||
PRBool aIsForDocNavigation,
|
||||
PRBool aCheckVisibility);
|
||||
|
||||
/**
|
||||
* Get the TabParent associated with aContent if it is a remote browser,
|
||||
* or null in all other cases.
|
||||
*/
|
||||
mozilla::dom::TabParent* GetRemoteForContent(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Get the last docshell child of aItem and return it in aResult.
|
||||
*/
|
||||
|
@ -9089,6 +9089,8 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
dummy_timeout.AddRef();
|
||||
|
||||
last_insertion_point = mTimeoutInsertionPoint;
|
||||
// If we ever start setting mTimeoutInsertionPoint to a non-dummy timeout,
|
||||
// the logic in ResetTimersForNonBackgroundWindow will need to change.
|
||||
mTimeoutInsertionPoint = &dummy_timeout;
|
||||
|
||||
for (timeout = FirstTimeout();
|
||||
@ -9426,7 +9428,16 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
for (nsTimeout *timeout = FirstTimeout(); IsTimeout(timeout); ) {
|
||||
// If mTimeoutInsertionPoint is non-null, we're in the middle of firing
|
||||
// timers and the timers we're planning to fire all come before
|
||||
// mTimeoutInsertionPoint; mTimeoutInsertionPoint itself is a dummy timeout
|
||||
// with an mWhen that may be semi-bogus. In that case, we don't need to do
|
||||
// anything with mTimeoutInsertionPoint or anything before it, so should
|
||||
// start at the timer after mTimeoutInsertionPoint, if there is one.
|
||||
// Otherwise, start at the beginning of the list.
|
||||
for (nsTimeout *timeout = mTimeoutInsertionPoint ?
|
||||
mTimeoutInsertionPoint->Next() : FirstTimeout();
|
||||
IsTimeout(timeout); ) {
|
||||
// It's important that this check be <= so that we guarantee that
|
||||
// taking NS_MAX with |now| won't make a quantity equal to
|
||||
// timeout->mWhen below.
|
||||
|
@ -914,8 +914,14 @@ protected:
|
||||
|
||||
// These member variable are used only on inner windows.
|
||||
nsRefPtr<nsEventListenerManager> mListenerManager;
|
||||
// mTimeouts is generally sorted by mWhen, unless mTimeoutInsertionPoint is
|
||||
// non-null. In that case, the dummy timeout pointed to by
|
||||
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
|
||||
// that come after it.
|
||||
PRCList mTimeouts;
|
||||
// If mTimeoutInsertionPoint is non-null, insertions should happen after it.
|
||||
// This is a dummy timeout at the moment; if that ever changes, the logic in
|
||||
// ResetTimersForNonBackgroundWindow needs to change.
|
||||
nsTimeout* mTimeoutInsertionPoint;
|
||||
PRUint32 mTimeoutPublicIdCounter;
|
||||
PRUint32 mTimeoutFiringDepth;
|
||||
|
@ -185,7 +185,10 @@ static PRTime sMaxChromeScriptRunTime;
|
||||
static nsIScriptSecurityManager *sSecurityManager;
|
||||
|
||||
// nsMemoryPressureObserver observes the memory-pressure notifications
|
||||
// and forces a garbage collection and cycle collection when it happens.
|
||||
// and forces a garbage collection and cycle collection when it happens, if
|
||||
// the appropriate pref is set.
|
||||
|
||||
static PRBool sGCOnMemoryPressure;
|
||||
|
||||
class nsMemoryPressureObserver : public nsIObserver
|
||||
{
|
||||
@ -200,8 +203,10 @@ NS_IMETHODIMP
|
||||
nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
nsJSContext::GarbageCollectNow();
|
||||
nsJSContext::CycleCollectNow();
|
||||
if (sGCOnMemoryPressure) {
|
||||
nsJSContext::GarbageCollectNow();
|
||||
nsJSContext::CycleCollectNow();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3795,6 +3800,10 @@ nsJSRuntime::Init()
|
||||
if (!obs)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
Preferences::AddBoolVarCache(&sGCOnMemoryPressure,
|
||||
"javascript.options.gc_on_memory_pressure",
|
||||
PR_TRUE);
|
||||
|
||||
nsIObserver* memPressureObserver = new nsMemoryPressureObserver();
|
||||
NS_ENSURE_TRUE(memPressureObserver, NS_ERROR_OUT_OF_MEMORY);
|
||||
obs->AddObserver(memPressureObserver, "memory-pressure", PR_FALSE);
|
||||
|
@ -49,8 +49,9 @@
|
||||
*
|
||||
* @see <http://www.whatwg.org/html/>
|
||||
*/
|
||||
interface nsISelection;
|
||||
|
||||
[scriptable, uuid(3c0ca40f-72c5-4d15-935e-ccaff7953f2c)]
|
||||
[scriptable, uuid(3ab3e856-361d-435a-8a4d-b462799945cd)]
|
||||
interface nsIDOMHTMLDocument : nsIDOMDocument
|
||||
{
|
||||
readonly attribute DOMString URL;
|
||||
@ -132,7 +133,7 @@ interface nsIDOMHTMLDocument : nsIDOMDocument
|
||||
|
||||
|
||||
// DOM Range
|
||||
DOMString getSelection();
|
||||
nsISelection getSelection();
|
||||
|
||||
|
||||
// Mozilla extensions
|
||||
|
@ -363,11 +363,11 @@ ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* chi
|
||||
PRInt32 units;
|
||||
PRInt64 amount;
|
||||
nsCString desc;
|
||||
r->GetPath(getter_Copies(path));
|
||||
r->GetPath(path);
|
||||
r->GetKind(&kind);
|
||||
r->GetUnits(&units);
|
||||
r->GetAmount(&amount);
|
||||
r->GetDescription(getter_Copies(desc));
|
||||
r->GetDescription(desc);
|
||||
|
||||
MemoryReport memreport(process, path, kind, units, amount, desc);
|
||||
reports.AppendElement(memreport);
|
||||
@ -377,13 +377,13 @@ ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* chi
|
||||
// one, whereupon the callback will turn each measurement into a
|
||||
// MemoryReport.
|
||||
mgr->EnumerateMultiReporters(getter_AddRefs(e));
|
||||
MemoryReportsWrapper wrappedReports(&reports);
|
||||
MemoryReportCallback cb(process);
|
||||
nsRefPtr<MemoryReportsWrapper> wrappedReports =
|
||||
new MemoryReportsWrapper(&reports);
|
||||
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
|
||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||
nsCOMPtr<nsIMemoryMultiReporter> r;
|
||||
e->GetNext(getter_AddRefs(r));
|
||||
|
||||
r->CollectReports(&cb, &wrappedReports);
|
||||
r->CollectReports(cb, wrappedReports);
|
||||
}
|
||||
|
||||
child->Send__delete__(child, reports);
|
||||
|
@ -58,6 +58,9 @@ using nsQueryContentEvent;
|
||||
using nsRect;
|
||||
using nsSelectionEvent;
|
||||
using nsTextEvent;
|
||||
using nsMouseEvent;
|
||||
using nsMouseScrollEvent;
|
||||
using nsKeyEvent;
|
||||
using RemoteDOMEvent;
|
||||
|
||||
namespace mozilla {
|
||||
@ -180,6 +183,8 @@ parent:
|
||||
*/
|
||||
sync GetDPI() returns (float value);
|
||||
|
||||
SetCursor(PRUint32 value);
|
||||
|
||||
PContentPermissionRequest(nsCString aType, URI uri);
|
||||
|
||||
PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures,
|
||||
@ -241,6 +246,8 @@ child:
|
||||
*/
|
||||
Activate();
|
||||
|
||||
Deactivate();
|
||||
|
||||
/**
|
||||
* @see nsIDOMWindowUtils sendMouseEvent.
|
||||
*/
|
||||
@ -252,6 +259,10 @@ child:
|
||||
PRInt32 aModifiers,
|
||||
bool aIgnoreRootScrollFrame);
|
||||
|
||||
RealMouseEvent(nsMouseEvent event);
|
||||
RealKeyEvent(nsKeyEvent event);
|
||||
MouseScrollEvent(nsMouseScrollEvent event);
|
||||
|
||||
/**
|
||||
* @see nsIDOMWindowUtils sendKeyEvent.
|
||||
*/
|
||||
|
@ -284,9 +284,8 @@ TabChild::GetVisibility(PRBool* aVisibility)
|
||||
NS_IMETHODIMP
|
||||
TabChild::SetVisibility(PRBool aVisibility)
|
||||
{
|
||||
NS_NOTREACHED("TabChild::SetVisibility not supported in TabChild");
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
// should the platform support this? Bug 666365
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -556,6 +555,13 @@ TabChild::RecvActivate()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TabChild::RecvDeactivate()
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
|
||||
browser->Deactivate();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvMouseEvent(const nsString& aType,
|
||||
const float& aX,
|
||||
@ -573,6 +579,31 @@ TabChild::RecvMouseEvent(const nsString& aType,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvRealMouseEvent(const nsMouseEvent& event)
|
||||
{
|
||||
nsMouseEvent localEvent(event);
|
||||
DispatchWidgetEvent(localEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvMouseScrollEvent(const nsMouseScrollEvent& event)
|
||||
{
|
||||
nsMouseScrollEvent localEvent(event);
|
||||
DispatchWidgetEvent(localEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TabChild::RecvRealKeyEvent(const nsKeyEvent& event)
|
||||
{
|
||||
nsKeyEvent localEvent(event);
|
||||
DispatchWidgetEvent(localEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvKeyEvent(const nsString& aType,
|
||||
const PRInt32& aKeyCode,
|
||||
|
@ -180,6 +180,7 @@ public:
|
||||
virtual bool RecvShow(const nsIntSize& size);
|
||||
virtual bool RecvMove(const nsIntSize& size);
|
||||
virtual bool RecvActivate();
|
||||
virtual bool RecvDeactivate();
|
||||
virtual bool RecvMouseEvent(const nsString& aType,
|
||||
const float& aX,
|
||||
const float& aY,
|
||||
@ -187,6 +188,9 @@ public:
|
||||
const PRInt32& aClickCount,
|
||||
const PRInt32& aModifiers,
|
||||
const bool& aIgnoreRootScrollFrame);
|
||||
virtual bool RecvRealMouseEvent(const nsMouseEvent& event);
|
||||
virtual bool RecvRealKeyEvent(const nsKeyEvent& event);
|
||||
virtual bool RecvMouseScrollEvent(const nsMouseScrollEvent& event);
|
||||
virtual bool RecvKeyEvent(const nsString& aType,
|
||||
const PRInt32& aKeyCode,
|
||||
const PRInt32& aCharCode,
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "nsSerializationHelper.h"
|
||||
#include "nsIPromptFactory.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
@ -219,6 +220,12 @@ TabParent::Activate()
|
||||
unused << SendActivate();
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::Deactivate()
|
||||
{
|
||||
unused << SendDeactivate();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::Init(nsIDOMWindow *window)
|
||||
{
|
||||
@ -293,6 +300,21 @@ TabParent::SendKeyEvent(const nsAString& aType,
|
||||
aModifiers, aPreventDefault);
|
||||
}
|
||||
|
||||
bool TabParent::SendRealMouseEvent(nsMouseEvent& event)
|
||||
{
|
||||
return PBrowserParent::SendRealMouseEvent(event);
|
||||
}
|
||||
|
||||
bool TabParent::SendMouseScrollEvent(nsMouseScrollEvent& event)
|
||||
{
|
||||
return PBrowserParent::SendMouseScrollEvent(event);
|
||||
}
|
||||
|
||||
bool TabParent::SendRealKeyEvent(nsKeyEvent& event)
|
||||
{
|
||||
return PBrowserParent::SendRealKeyEvent(event);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||
const nsString& aJSON,
|
||||
@ -308,6 +330,16 @@ TabParent::RecvAsyncMessage(const nsString& aMessage,
|
||||
return ReceiveMessage(aMessage, PR_FALSE, aJSON, nsnull);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSetCursor(const PRUint32& aCursor)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->SetCursor((nsCursor) aCursor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyIMEFocus(const PRBool& aFocus,
|
||||
nsIMEUpdatePreference* aPreference,
|
||||
|
@ -107,6 +107,7 @@ public:
|
||||
virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason);
|
||||
virtual bool RecvGetIMEOpenState(PRBool* aValue);
|
||||
virtual bool RecvSetIMEOpenState(const PRBool& aValue);
|
||||
virtual bool RecvSetCursor(const PRUint32& aValue);
|
||||
virtual bool RecvGetDPI(float* aValue);
|
||||
virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType,
|
||||
const nsCString& aName,
|
||||
@ -127,12 +128,16 @@ public:
|
||||
void Show(const nsIntSize& size);
|
||||
void Move(const nsIntSize& size);
|
||||
void Activate();
|
||||
void Deactivate();
|
||||
void SendMouseEvent(const nsAString& aType, float aX, float aY,
|
||||
PRInt32 aButton, PRInt32 aClickCount,
|
||||
PRInt32 aModifiers, PRBool aIgnoreRootScrollFrame);
|
||||
void SendKeyEvent(const nsAString& aType, PRInt32 aKeyCode,
|
||||
PRInt32 aCharCode, PRInt32 aModifiers,
|
||||
PRBool aPreventDefault);
|
||||
bool SendRealMouseEvent(nsMouseEvent& event);
|
||||
bool SendMouseScrollEvent(nsMouseScrollEvent& event);
|
||||
bool SendRealKeyEvent(nsKeyEvent& event);
|
||||
|
||||
virtual PDocumentRendererParent*
|
||||
AllocPDocumentRenderer(const nsRect& documentRect, const gfxMatrix& transform,
|
||||
|
@ -61,8 +61,7 @@
|
||||
function randomClick() {
|
||||
// First focus the remote frame, then dispatch click. This way remote frame gets focus before
|
||||
// mouse event.
|
||||
document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
|
||||
.frameLoader.activateRemoteFrame();
|
||||
document.getElementById('page').focus();
|
||||
var frameLoader = document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
|
||||
var x = parseInt(Math.random() * 100);
|
||||
var y = parseInt(Math.random() * 100);
|
||||
@ -73,8 +72,7 @@
|
||||
function keyPress() {
|
||||
// First focus the remote frame, then dispatch click. This way remote frame gets focus before
|
||||
// mouse event.
|
||||
document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
|
||||
.frameLoader.activateRemoteFrame();
|
||||
document.getElementById('page').focus();
|
||||
var frameLoader = document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
|
||||
|
||||
var keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_A;
|
||||
@ -280,7 +278,6 @@
|
||||
oncommand="document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.delayRemoteDialogs = this.checked;"/>
|
||||
</toolbar>
|
||||
|
||||
<browser type="content" src="http://www.google.com/" flex="1" id="page" remote="true"
|
||||
onfocus="this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.activateRemoteFrame();"/>
|
||||
<browser type="content" src="http://www.google.com/" flex="1" id="page" remote="true"/>
|
||||
<label id="messageLog" value="" crop="center"/>
|
||||
</window>
|
||||
|
@ -2300,8 +2300,9 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||
}
|
||||
|
||||
case NPPVpluginKeepLibraryInMemory: {
|
||||
NPBool bCached = (result != nsnull);
|
||||
return inst->SetCached(bCached);
|
||||
// This variable is not supported any more but we'll pretend it is
|
||||
// so that plugins don't fail on an error return.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case NPPVpluginUsesDOMForCursorBool: {
|
||||
|
@ -81,7 +81,6 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
|
||||
mWindowless(PR_FALSE),
|
||||
mWindowlessLocal(PR_FALSE),
|
||||
mTransparent(PR_FALSE),
|
||||
mCached(PR_FALSE),
|
||||
mUsesDOMForCursor(PR_FALSE),
|
||||
mInPluginInitCall(PR_FALSE),
|
||||
mPlugin(plugin),
|
||||
@ -129,12 +128,6 @@ nsNPAPIPluginInstance::Destroy()
|
||||
mPlugin = nsnull;
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
nsNPAPIPluginInstance::LastStopTime()
|
||||
{
|
||||
return mStopTime;
|
||||
}
|
||||
|
||||
nsresult nsNPAPIPluginInstance::Initialize(nsIPluginInstanceOwner* aOwner, const char* aMIMEType)
|
||||
{
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Initialize this=%p\n",this));
|
||||
@ -193,7 +186,6 @@ nsresult nsNPAPIPluginInstance::Stop()
|
||||
{
|
||||
AsyncCallbackAutoLock lock;
|
||||
mRunning = DESTROYING;
|
||||
mStopTime = TimeStamp::Now();
|
||||
}
|
||||
|
||||
OnPluginDestroy(&mNPP);
|
||||
@ -810,20 +802,6 @@ nsNPAPIPluginInstance::DefineJavaProperties()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPluginInstance::SetCached(PRBool aCache)
|
||||
{
|
||||
mCached = aCache;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPluginInstance::ShouldCache(PRBool* shouldCache)
|
||||
{
|
||||
*shouldCache = mCached;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPluginInstance::IsWindowless(PRBool* isWindowless)
|
||||
{
|
||||
|
@ -91,7 +91,6 @@ public:
|
||||
nsresult IsRemoteDrawingCoreAnimation(PRBool* aDrawing);
|
||||
nsresult GetJSObject(JSContext *cx, JSObject** outObject);
|
||||
nsresult DefineJavaProperties();
|
||||
nsresult ShouldCache(PRBool* shouldCache);
|
||||
nsresult IsWindowless(PRBool* isWindowless);
|
||||
nsresult AsyncSetWindow(NPWindow* window);
|
||||
nsresult GetImage(ImageContainer* aContainer, Image** aImage);
|
||||
@ -162,12 +161,6 @@ public:
|
||||
return mRunning == RUNNING || mRunning == DESTROYING;
|
||||
}
|
||||
|
||||
// return is only valid when the plugin is not running
|
||||
mozilla::TimeStamp LastStopTime();
|
||||
|
||||
// cache this NPAPI plugin
|
||||
nsresult SetCached(PRBool aCache);
|
||||
|
||||
already_AddRefed<nsPIDOMWindow> GetDOMWindow();
|
||||
|
||||
nsresult PrivateModeStateChanged();
|
||||
@ -223,7 +216,6 @@ protected:
|
||||
PRPackedBool mWindowless;
|
||||
PRPackedBool mWindowlessLocal;
|
||||
PRPackedBool mTransparent;
|
||||
PRPackedBool mCached;
|
||||
PRPackedBool mUsesDOMForCursor;
|
||||
|
||||
public:
|
||||
@ -252,10 +244,6 @@ private:
|
||||
// non-null during a HandleEvent call
|
||||
void* mCurrentPluginEvent;
|
||||
|
||||
// Timestamp for the last time this plugin was stopped.
|
||||
// This is only valid when the plugin is actually stopped!
|
||||
mozilla::TimeStamp mStopTime;
|
||||
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
PRPackedBool mUsePluginLayersPref;
|
||||
|
@ -226,10 +226,6 @@ PRLogModuleInfo* nsPluginLogging::gPluginLog = nsnull;
|
||||
#define BRAND_PROPERTIES_URL "chrome://branding/locale/brand.properties"
|
||||
#define PLUGIN_PROPERTIES_URL "chrome://global/locale/downloadProgress.properties"
|
||||
|
||||
// #defines for plugin cache and prefs
|
||||
#define NS_PREF_MAX_NUM_CACHED_PLUGINS "browser.plugins.max_num_cached_plugins"
|
||||
#define DEFAULT_NUMBER_OF_STOPPED_PLUGINS 10
|
||||
|
||||
#ifdef CALL_SAFETY_ON
|
||||
// By default we run OOPP, so we don't want to cover up crashes.
|
||||
PRBool gSkipPluginSafeCalls = PR_TRUE;
|
||||
@ -484,7 +480,7 @@ nsresult nsPluginHost::ReloadPlugins(PRBool reloadPages)
|
||||
|
||||
// we are re-scanning plugins. New plugins may have been added, also some
|
||||
// plugins may have been removed, so we should probably shut everything down
|
||||
// but don't touch running (active and not stopped) plugins
|
||||
// but don't touch running (active and not stopped) plugins
|
||||
|
||||
// check if plugins changed, no need to do anything else
|
||||
// if no changes to plugins have been made
|
||||
@ -959,8 +955,7 @@ nsresult nsPluginHost::InstantiatePluginForChannel(nsIChannel* aChannel,
|
||||
#endif
|
||||
|
||||
// Note that we're not setting up a plugin instance here; the stream
|
||||
// listener's OnStartRequest will handle doing that, looking for
|
||||
// stopped plugins, etc, etc.
|
||||
// listener's OnStartRequest will handle doing that.
|
||||
|
||||
return NewEmbeddedPluginStreamListener(uri, aOwner, nsnull, aListener);
|
||||
}
|
||||
@ -1055,20 +1050,6 @@ nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL,
|
||||
bCanHandleInternally = PR_TRUE;
|
||||
}
|
||||
|
||||
if (FindStoppedPluginForURL(aURL, aOwner) == NS_OK) {
|
||||
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||
("nsPluginHost::InstantiateEmbeddedPlugin FoundStopped mime=%s\n", aMimeType));
|
||||
|
||||
if (!isJava && bCanHandleInternally) {
|
||||
nsNPAPIPluginInstance* instance;
|
||||
aOwner->GetInstance(&instance);
|
||||
NewEmbeddedPluginStream(aURL, aOwner, instance);
|
||||
NS_IF_RELEASE(instance);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if we don't have a MIME type at this point, we still have one more chance by
|
||||
// opening the stream and seeing if the server hands one back
|
||||
if (!aMimeType)
|
||||
@ -1136,20 +1117,6 @@ nsresult nsPluginHost::InstantiateFullPagePlugin(const char *aMimeType,
|
||||
aMimeType, aOwner, urlSpec.get()));
|
||||
#endif
|
||||
|
||||
if (FindStoppedPluginForURL(aURI, aOwner) == NS_OK) {
|
||||
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||
("nsPluginHost::InstantiateFullPagePlugin FoundStopped mime=%s\n",aMimeType));
|
||||
|
||||
|
||||
nsPluginTag* pluginTag = FindPluginForType(aMimeType, PR_TRUE);
|
||||
if (!pluginTag || !pluginTag->mIsJavaPlugin) {
|
||||
nsRefPtr<nsNPAPIPluginInstance> instance;
|
||||
aOwner->GetInstance(getter_AddRefs(instance));
|
||||
NewFullPagePluginStream(aURI, instance.get(), aStreamListener);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = SetUpPluginInstance(aMimeType, aURI, aOwner);
|
||||
|
||||
if (NS_OK == rv) {
|
||||
@ -1206,31 +1173,6 @@ nsPluginHost::TagForPlugin(nsNPAPIPlugin* aPlugin)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult nsPluginHost::FindStoppedPluginForURL(nsIURI* aURL,
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
{
|
||||
nsCAutoString url;
|
||||
if (!aURL)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
aURL->GetAsciiSpec(url);
|
||||
|
||||
nsNPAPIPluginInstance *instance = FindStoppedInstance(url.get());
|
||||
if (instance && !instance->IsRunning()) {
|
||||
aOwner->SetInstance(instance);
|
||||
instance->SetOwner(aOwner);
|
||||
|
||||
instance->Start();
|
||||
aOwner->CreateWidget();
|
||||
|
||||
// If we've got a native window, the let the plugin know about it.
|
||||
aOwner->SetWindow();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult nsPluginHost::SetUpPluginInstance(const char *aMimeType,
|
||||
nsIURI *aURL,
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
@ -3255,39 +3197,17 @@ nsPluginHost::StopPluginInstance(nsNPAPIPluginInstance* aInstance)
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("nsPluginHost::StopPluginInstance called instance=%p\n",aInstance));
|
||||
|
||||
nsNPAPIPluginInstance* instance = aInstance;
|
||||
if (instance->HasStartedDestroying())
|
||||
if (aInstance->HasStartedDestroying()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPluginTag* pluginTag = TagForPlugin(aInstance->GetPlugin());
|
||||
|
||||
aInstance->Stop();
|
||||
aInstance->Destroy();
|
||||
mInstances.RemoveElement(aInstance);
|
||||
|
||||
// if the plugin does not want to be 'cached' just remove it
|
||||
PRBool doCache = PR_TRUE;
|
||||
aInstance->ShouldCache(&doCache);
|
||||
if (doCache) {
|
||||
// try to get the max cached plugins from a pref or use default
|
||||
PRUint32 cachedPluginLimit;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mPrefService)
|
||||
rv = mPrefService->GetIntPref(NS_PREF_MAX_NUM_CACHED_PLUGINS, (int*)&cachedPluginLimit);
|
||||
if (NS_FAILED(rv))
|
||||
cachedPluginLimit = DEFAULT_NUMBER_OF_STOPPED_PLUGINS;
|
||||
|
||||
if (StoppedInstanceCount() >= cachedPluginLimit) {
|
||||
nsNPAPIPluginInstance *oldestInstance = FindOldestStoppedInstance();
|
||||
if (oldestInstance) {
|
||||
nsPluginTag* pluginTag = TagForPlugin(oldestInstance->GetPlugin());
|
||||
oldestInstance->Destroy();
|
||||
mInstances.RemoveElement(oldestInstance);
|
||||
OnPluginInstanceDestroyed(pluginTag);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nsPluginTag* pluginTag = TagForPlugin(instance->GetPlugin());
|
||||
instance->Destroy();
|
||||
mInstances.RemoveElement(instance);
|
||||
OnPluginInstanceDestroyed(pluginTag);
|
||||
}
|
||||
OnPluginInstanceDestroyed(pluginTag);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -4013,57 +3933,6 @@ nsPluginHost::FindInstance(const char *mimetype)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance*
|
||||
nsPluginHost::FindStoppedInstance(const char *url)
|
||||
{
|
||||
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
||||
nsNPAPIPluginInstance *instance = mInstances[i];
|
||||
|
||||
nsIURI *uri = instance->GetURI();
|
||||
if (!uri)
|
||||
continue;
|
||||
|
||||
nsCAutoString spec;
|
||||
uri->GetSpec(spec);
|
||||
if (!PL_strcmp(url, spec.get()) && !instance->IsRunning())
|
||||
return instance;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance*
|
||||
nsPluginHost::FindOldestStoppedInstance()
|
||||
{
|
||||
nsNPAPIPluginInstance *oldestInstance = nsnull;
|
||||
TimeStamp oldestTime = TimeStamp::Now();
|
||||
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
||||
nsNPAPIPluginInstance *instance = mInstances[i];
|
||||
if (instance->IsRunning())
|
||||
continue;
|
||||
|
||||
TimeStamp time = instance->LastStopTime();
|
||||
if (time < oldestTime) {
|
||||
oldestTime = time;
|
||||
oldestInstance = instance;
|
||||
}
|
||||
}
|
||||
|
||||
return oldestInstance;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsPluginHost::StoppedInstanceCount()
|
||||
{
|
||||
PRUint32 stoppedCount = 0;
|
||||
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
||||
nsNPAPIPluginInstance *instance = mInstances[i];
|
||||
if (!instance->IsRunning())
|
||||
stoppedCount++;
|
||||
}
|
||||
return stoppedCount;
|
||||
}
|
||||
|
||||
nsTArray< nsRefPtr<nsNPAPIPluginInstance> >*
|
||||
nsPluginHost::InstanceArray()
|
||||
{
|
||||
|
@ -205,9 +205,6 @@ public:
|
||||
const nsAString& browserDumpID);
|
||||
|
||||
nsNPAPIPluginInstance *FindInstance(const char *mimetype);
|
||||
nsNPAPIPluginInstance *FindStoppedInstance(const char * url);
|
||||
nsNPAPIPluginInstance *FindOldestStoppedInstance();
|
||||
PRUint32 StoppedInstanceCount();
|
||||
|
||||
nsTArray< nsRefPtr<nsNPAPIPluginInstance> > *InstanceArray();
|
||||
|
||||
@ -256,9 +253,6 @@ private:
|
||||
nsPluginTag*
|
||||
FindPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
|
||||
|
||||
nsresult
|
||||
FindStoppedPluginForURL(nsIURI* aURL, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
nsresult
|
||||
FindPlugins(PRBool aCreatePluginList, PRBool * aPluginsChanged);
|
||||
|
||||
|
@ -545,9 +545,10 @@ nsJSONListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// This can happen with short UTF-8 messages
|
||||
// This can happen with short UTF-8 messages (<4 bytes)
|
||||
if (!mSniffBuffer.IsEmpty()) {
|
||||
rv = ProcessBytes(mSniffBuffer.get(), mSniffBuffer.Length());
|
||||
// Just consume mSniffBuffer
|
||||
rv = ProcessBytes(nsnull, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
@ -617,6 +618,9 @@ nsJSONListener::ProcessBytes(const char* aBuffer, PRUint32 aByteLength)
|
||||
buffer[2] != 0x00 && buffer[3] != 0x00) {
|
||||
charset = "UTF-8";
|
||||
}
|
||||
} else {
|
||||
// Not enough bytes to sniff, assume UTF-8
|
||||
charset = "UTF-8";
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,6 +639,9 @@ nsJSONListener::ProcessBytes(const char* aBuffer, PRUint32 aByteLength)
|
||||
mSniffBuffer.Truncate();
|
||||
}
|
||||
|
||||
if (!aBuffer)
|
||||
return NS_OK;
|
||||
|
||||
if (mNeedsConverter) {
|
||||
rv = ConsumeConverted(aBuffer, aByteLength);
|
||||
} else {
|
||||
|
1
dom/src/json/test/unit/decodeFromStream-small.json
Normal file
1
dom/src/json/test/unit/decodeFromStream-small.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
@ -23,4 +23,7 @@ function run_test()
|
||||
var x = read_file("decodeFromStream-01.json");
|
||||
do_check_eq(x["JSON Test Pattern pass3"]["The outermost value"], "must be an object or array.");
|
||||
do_check_eq(x["JSON Test Pattern pass3"]["In this test"], "It is an object.");
|
||||
|
||||
x = read_file("decodeFromStream-small.json");
|
||||
do_check_eq(x.toSource(), "({})", "empty object parsed");
|
||||
}
|
||||
|
@ -89,6 +89,7 @@
|
||||
<action android:name="org.mozilla.gecko.restart"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
#if MOZ_CRASHREPORTER
|
||||
<activity android:name="CrashReporter"
|
||||
android:label="@string/crash_reporter_title"
|
||||
@ -98,5 +99,14 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
#endif
|
||||
|
||||
<activity android:name="LauncherShortcuts"
|
||||
android:label="@string/launcher_shortcuts_title">
|
||||
<!-- This intent-filter allows your shortcuts to be created in the launcher. -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.CREATE_SHORTCUT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -303,7 +303,7 @@ abstract public class GeckoApp
|
||||
Log.i("GeckoApp", "Intent : ACTION_MAIN");
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(""));
|
||||
}
|
||||
else if (action.equals("org.mozilla.fennec.WEBAPP")) {
|
||||
else if (action.equals("org.mozilla.gecko.WEBAPP")) {
|
||||
String uri = intent.getStringExtra("args");
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
|
||||
Log.i("GeckoApp","Intent : WEBAPP - " + uri);
|
||||
|
@ -678,7 +678,7 @@ public class GeckoAppShell
|
||||
Log.w("GeckoAppJava", "installWebApplication for " + aURI + " [" + aTitle + "]");
|
||||
|
||||
// the intent to be launched by the shortcut
|
||||
Intent shortcutIntent = new Intent("org.mozilla.fennec.WEBAPP");
|
||||
Intent shortcutIntent = new Intent("org.mozilla.gecko.WEBAPP");
|
||||
shortcutIntent.setClassName(GeckoApp.mAppContext,
|
||||
GeckoApp.mAppContext.getPackageName() + ".App");
|
||||
shortcutIntent.putExtra("args", "--webapp=" + aURI);
|
||||
|
184
embedding/android/LauncherShortcuts.java.in
Normal file
184
embedding/android/LauncherShortcuts.java.in
Normal file
@ -0,0 +1,184 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Wes Johnston <wjohnston@mozilla.com>
|
||||
* Mark Finkle <mfinkle@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#filter substitution
|
||||
package @ANDROID_PACKAGE_NAME@;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import org.mozilla.gecko.*;
|
||||
|
||||
import android.os.*;
|
||||
import android.content.*;
|
||||
import android.app.*;
|
||||
import android.text.*;
|
||||
import android.util.*;
|
||||
import android.widget.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.database.*;
|
||||
import android.view.*;
|
||||
import android.net.Uri;
|
||||
import android.graphics.*;
|
||||
|
||||
|
||||
public class LauncherShortcuts extends ListActivity {
|
||||
public static final String CREATE_SHORTCUT = "org.mozilla.gecko.CREATE_SHORTCUT";
|
||||
|
||||
public class LauncherCursorAdapter extends SimpleCursorAdapter {
|
||||
private Cursor _cursor;
|
||||
private Context _context;
|
||||
|
||||
public LauncherCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
|
||||
// Using the older, deprecated constructor so we can work on API < 11
|
||||
super(context, layout, c, from, to);
|
||||
_cursor = c;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.favicon);
|
||||
|
||||
String favicon = cursor.getString(3);
|
||||
byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
|
||||
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), 48, 48, true);
|
||||
imageView.setImageBitmap(bitmap);
|
||||
|
||||
super.bindView(view, context, cursor);
|
||||
}
|
||||
}
|
||||
|
||||
private Cursor getCursor(Context context) {
|
||||
File home = new File(context.getFilesDir(), "mozilla");
|
||||
if (!home.exists())
|
||||
return null;
|
||||
|
||||
File profile = null;
|
||||
String[] files = home.list();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (files[i].endsWith(".default")) {
|
||||
profile = new File(home, files[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (profile == null)
|
||||
return null;
|
||||
|
||||
File webapps = new File(profile, "webapps.sqlite");
|
||||
if (!webapps.exists())
|
||||
return null;
|
||||
|
||||
Log.i("LauncherShortcuts", "Opening: " + webapps.getPath());
|
||||
mDb = SQLiteDatabase.openDatabase(webapps.getPath(), null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
|
||||
return mDb.rawQuery("SELECT rowid as _id, title, uri, icon FROM webapps", null);
|
||||
}
|
||||
|
||||
private Cursor mCursor;
|
||||
private SQLiteDatabase mDb;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.launch_app_list);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
|
||||
mCursor = getCursor(this);
|
||||
if (mCursor != null) {
|
||||
// After selecting an item, the empty view can flash on screen. Clear
|
||||
// the text so we don't see it.
|
||||
TextView emptyText = (TextView)findViewById(android.R.id.empty);
|
||||
emptyText.setText("");
|
||||
|
||||
// Load the list using a custom adapter so we can create the bitmaps
|
||||
ListAdapter adapter = new LauncherCursorAdapter(
|
||||
this,
|
||||
R.layout.launch_app_listitem,
|
||||
mCursor,
|
||||
new String[] {"title"},
|
||||
new int[] {R.id.title}
|
||||
);
|
||||
setListAdapter(adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
mCursor.moveToPosition(position);
|
||||
|
||||
Intent shortcutintent = new Intent("org.mozilla.gecko.WEBAPP");
|
||||
shortcutintent.setClass(this, App.class);
|
||||
shortcutintent.putExtra("args", "--webapp=" + mCursor.getString(2));
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mCursor.getString(1));
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutintent);
|
||||
|
||||
String favicon = mCursor.getString(3);
|
||||
byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
|
||||
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
int size;
|
||||
switch (dm.densityDpi) {
|
||||
case DisplayMetrics.DENSITY_MEDIUM:
|
||||
size = 48;
|
||||
break;
|
||||
case DisplayMetrics.DENSITY_HIGH:
|
||||
size = 72;
|
||||
break;
|
||||
default:
|
||||
size = 72;
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), size, size, true);
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
|
||||
|
||||
// Now, return the result to the launcher
|
||||
setResult(RESULT_OK, intent);
|
||||
mDb.close();
|
||||
mCursor.close();
|
||||
finish();
|
||||
}
|
||||
}
|
@ -59,6 +59,7 @@ PROCESSEDJAVAFILES = \
|
||||
App.java \
|
||||
Restarter.java \
|
||||
NotificationHandler.java \
|
||||
LauncherShortcuts.java \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@ -116,6 +117,8 @@ RES_LAYOUT = \
|
||||
res/layout/notification_progress.xml \
|
||||
res/layout/notification_progress_text.xml \
|
||||
res/layout/notification_icon_text.xml \
|
||||
res/layout/launch_app_list.xml \
|
||||
res/layout/launch_app_listitem.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES = res/values/colors.xml res/values/themes.xml
|
||||
|
@ -16,3 +16,6 @@
|
||||
<!ENTITY sending_crash_report "Sending crash report\u2026">
|
||||
<!ENTITY exit_label "Exit">
|
||||
<!ENTITY continue_label "Continue">
|
||||
|
||||
<!ENTITY launcher_shortcuts_title "&brandShortName; Web Apps">
|
||||
<!ENTITY launcher_shortcuts_empty "No web apps were found">
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user