mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
8bdcfde7af
@ -15,12 +15,12 @@
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsIAccessibleRelation.h"
|
||||
#include "nsWinUtils.h"
|
||||
#include "ServiceProvider.h"
|
||||
#include "Relation.h"
|
||||
#include "Role.h"
|
||||
#include "RootAccessible.h"
|
||||
#include "sdnAccessible.h"
|
||||
#include "States.h"
|
||||
#include "uiaRawElmProvider.h"
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
@ -90,7 +90,7 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
|
||||
*ppv = static_cast<IEnumVARIANT*>(new ChildrenEnumVariant(this));
|
||||
} else if (IID_IServiceProvider == iid)
|
||||
*ppv = static_cast<IServiceProvider*>(this);
|
||||
*ppv = new ServiceProvider(this);
|
||||
else if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off())
|
||||
*ppv = static_cast<IAccessible2*>(this);
|
||||
else if (IID_ISimpleDOMNode == iid) {
|
||||
@ -127,32 +127,6 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
A11Y_TRYBLOCK_END
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// IServiceProvider
|
||||
|
||||
STDMETHODIMP
|
||||
AccessibleWrap::QueryService(REFGUID aGuidService, REFIID aIID,
|
||||
void** aInstancePtr)
|
||||
{
|
||||
if (!aInstancePtr)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*aInstancePtr = NULL;
|
||||
|
||||
// UIA IAccessibleEx
|
||||
if (aGuidService == IID_IAccessibleEx &&
|
||||
Preferences::GetBool("accessibility.uia.enable")) {
|
||||
uiaRawElmProvider* accEx = new uiaRawElmProvider(this);
|
||||
HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
|
||||
if (FAILED(hr))
|
||||
delete accEx;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
return nsAccessNodeWrap::QueryService(aGuidService, aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// IAccessible methods
|
||||
//-----------------------------------------------------
|
||||
|
@ -138,11 +138,6 @@ public: // construction, destruction
|
||||
// Return the registered OLE class ID of this object's CfDataObj.
|
||||
CLSID GetClassID() const;
|
||||
|
||||
// IServiceProvider
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
|
||||
REFIID aIID,
|
||||
void** aInstancePtr);
|
||||
|
||||
public: // COM interface IAccessible
|
||||
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
|
||||
/* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent);
|
||||
|
@ -29,6 +29,7 @@ CPPSRCS = \
|
||||
Compatibility.cpp \
|
||||
EnumVariant.cpp \
|
||||
Platform.cpp \
|
||||
ServiceProvider.cpp \
|
||||
RootAccessibleWrap.cpp \
|
||||
TextLeafAccessibleWrap.cpp \
|
||||
$(NULL)
|
||||
|
117
accessible/src/msaa/ServiceProvider.cpp
Normal file
117
accessible/src/msaa/ServiceProvider.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ServiceProvider.h"
|
||||
|
||||
#include "ApplicationAccessibleWrap.h"
|
||||
#include "Compatibility.h"
|
||||
#include "DocAccessible.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "uiaRawElmProvider.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
#include "ISimpleDOMNode_i.c"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
IMPL_IUNKNOWN_QUERY_HEAD(ServiceProvider)
|
||||
IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider)
|
||||
return mAccessible->QueryInterface(aIID, aInstancePtr);
|
||||
A11Y_TRYBLOCK_END
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// IServiceProvider
|
||||
|
||||
STDMETHODIMP
|
||||
ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID,
|
||||
void** aInstancePtr)
|
||||
{
|
||||
if (!aInstancePtr)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*aInstancePtr = NULL;
|
||||
|
||||
// UIA IAccessibleEx
|
||||
if (aGuidService == IID_IAccessibleEx &&
|
||||
Preferences::GetBool("accessibility.uia.enable")) {
|
||||
uiaRawElmProvider* accEx = new uiaRawElmProvider(mAccessible);
|
||||
HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
|
||||
if (FAILED(hr))
|
||||
delete accEx;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Provide a special service ID for getting the accessible for the browser tab
|
||||
// document that contains this accessible object. If this accessible object
|
||||
// is not inside a browser tab then the service fails with E_NOINTERFACE.
|
||||
// A use case for this is for screen readers that need to switch context or
|
||||
// 'virtual buffer' when focus moves from one browser tab area to another.
|
||||
static const GUID SID_IAccessibleContentDocument =
|
||||
{ 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
|
||||
if (aGuidService == SID_IAccessibleContentDocument) {
|
||||
if (aIID != IID_IAccessible)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell =
|
||||
nsCoreUtils::GetDocShellFor(mAccessible->GetNode());
|
||||
if (!docShell)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
// Walk up the parent chain without crossing the boundary at which item
|
||||
// types change, preventing us from walking up out of tab content.
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
if (!root)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
|
||||
// If the item type is typeContent, we assume we are in browser tab content.
|
||||
// Note this includes content such as about:addons, for consistency.
|
||||
int32_t itemType;
|
||||
root->GetItemType(&itemType);
|
||||
if (itemType != nsIDocShellTreeItem::typeContent)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
// Make sure this is a document.
|
||||
DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
|
||||
if (!docAcc)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
*aInstancePtr = static_cast<IAccessible*>(docAcc);
|
||||
|
||||
(reinterpret_cast<IUnknown*>(*aInstancePtr))->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Can get to IAccessibleApplication from any node via QS
|
||||
if (aGuidService == IID_IAccessibleApplication ||
|
||||
(Compatibility::IsJAWS() && aIID == IID_IAccessibleApplication)) {
|
||||
ApplicationAccessibleWrap* applicationAcc =
|
||||
static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
|
||||
if (!applicationAcc)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
return applicationAcc->QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
static const GUID IID_SimpleDOMDeprecated =
|
||||
{ 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
|
||||
if (aGuidService == IID_ISimpleDOMNode ||
|
||||
aGuidService == IID_SimpleDOMDeprecated ||
|
||||
aGuidService == IID_IAccessible || aGuidService == IID_IAccessible2)
|
||||
return mAccessible->QueryInterface(aIID, aInstancePtr);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
37
accessible/src/msaa/ServiceProvider.h
Normal file
37
accessible/src/msaa/ServiceProvider.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_ServiceProvider_h_
|
||||
#define mozilla_a11y_ServiceProvider_h_
|
||||
|
||||
#include <servprov.h>
|
||||
|
||||
#include "AccessibleWrap.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class ServiceProvider MOZ_FINAL : public IServiceProvider
|
||||
{
|
||||
public:
|
||||
ServiceProvider(AccessibleWrap* aAcc) : mRefCnt(0), mAccessible(aAcc) {}
|
||||
~ServiceProvider() {}
|
||||
|
||||
DECL_IUNKNOWN
|
||||
|
||||
// IServiceProvider
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
|
||||
REFIID aIID,
|
||||
void** aInstancePtr);
|
||||
|
||||
private:
|
||||
nsRefPtr<AccessibleWrap> mAccessible;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -5,22 +5,9 @@
|
||||
|
||||
#include "nsAccessNodeWrap.h"
|
||||
|
||||
#include "AccessibleApplication.h"
|
||||
#include "ApplicationAccessibleWrap.h"
|
||||
#include "sdnAccessible.h"
|
||||
|
||||
#include "Compatibility.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "DocAccessible.h"
|
||||
#include "nsWinUtils.h"
|
||||
#include "RootAccessible.h"
|
||||
#include "Statistics.h"
|
||||
|
||||
#include "nsAttrName.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
@ -47,101 +34,6 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsAccessNodeWrap, nsAccessNode)
|
||||
|
||||
STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
{
|
||||
*ppv = nullptr;
|
||||
|
||||
if (IID_IUnknown == iid) {
|
||||
*ppv = static_cast<IUnknown*>(this);
|
||||
} else {
|
||||
return E_NOINTERFACE; //iid not supported.
|
||||
}
|
||||
|
||||
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
|
||||
{
|
||||
*ppv = nullptr;
|
||||
|
||||
// Provide a special service ID for getting the accessible for the browser tab
|
||||
// document that contains this accessible object. If this accessible object
|
||||
// is not inside a browser tab then the service fails with E_NOINTERFACE.
|
||||
// A use case for this is for screen readers that need to switch context or
|
||||
// 'virtual buffer' when focus moves from one browser tab area to another.
|
||||
static const GUID SID_IAccessibleContentDocument =
|
||||
{ 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
|
||||
if (guidService == SID_IAccessibleContentDocument) {
|
||||
if (iid != IID_IAccessible)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mContent);
|
||||
if (!docShell)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
// Walk up the parent chain without crossing the boundary at which item
|
||||
// types change, preventing us from walking up out of tab content.
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
if (!root)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
|
||||
// If the item type is typeContent, we assume we are in browser tab content.
|
||||
// Note this includes content such as about:addons, for consistency.
|
||||
int32_t itemType;
|
||||
root->GetItemType(&itemType);
|
||||
if (itemType != nsIDocShellTreeItem::typeContent)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
// Make sure this is a document.
|
||||
DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
|
||||
if (!docAcc)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
*ppv = static_cast<IAccessible*>(docAcc);
|
||||
|
||||
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Can get to IAccessibleApplication from any node via QS
|
||||
if (guidService == IID_IAccessibleApplication ||
|
||||
(Compatibility::IsJAWS() && iid == IID_IAccessibleApplication)) {
|
||||
ApplicationAccessibleWrap* applicationAcc =
|
||||
static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
|
||||
if (!applicationAcc)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
return applicationAcc->QueryInterface(iid, ppv);
|
||||
}
|
||||
|
||||
/**
|
||||
* To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
|
||||
* or any IAccessible2 interface on should use IServiceProvider like this:
|
||||
* -----------------------------------------------------------------------
|
||||
* ISimpleDOMDocument *pAccDoc = NULL;
|
||||
* IServiceProvider *pServProv = NULL;
|
||||
* pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
|
||||
* if (pServProv) {
|
||||
* const GUID unused;
|
||||
* pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
|
||||
* pServProv->Release();
|
||||
* }
|
||||
*/
|
||||
|
||||
static const GUID IID_SimpleDOMDeprecated =
|
||||
{ 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
|
||||
if (guidService == IID_ISimpleDOMNode ||
|
||||
guidService == IID_SimpleDOMDeprecated ||
|
||||
guidService == IID_IAccessible || guidService == IID_IAccessible2)
|
||||
return QueryInterface(iid, ppv);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo)
|
||||
{
|
||||
if (aCode == EXCEPTION_ACCESS_VIOLATION) {
|
||||
|
@ -53,8 +53,7 @@ namespace a11y {
|
||||
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
|
||||
#endif
|
||||
|
||||
class nsAccessNodeWrap : public nsAccessNode,
|
||||
public IServiceProvider
|
||||
class nsAccessNodeWrap : public nsAccessNode
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -63,15 +62,6 @@ public: // construction, destruction
|
||||
nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc);
|
||||
virtual ~nsAccessNodeWrap();
|
||||
|
||||
// IUnknown
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID,
|
||||
void** aInstancePtr);
|
||||
|
||||
// IServiceProvider
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
|
||||
REFIID aIID,
|
||||
void** aInstancePtr);
|
||||
|
||||
static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
|
||||
|
||||
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg,
|
||||
|
@ -54,7 +54,16 @@ DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
|
||||
let actorPool = new ActorPool(this.conn);
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
let actor = this._tabActors.get(this.browser);
|
||||
// Get the chrome debugger actor.
|
||||
let actor = this._chromeDebugger;
|
||||
if (!actor) {
|
||||
actor = new ChromeDebuggerActor(this);
|
||||
actor.parentID = this.actorID;
|
||||
this._chromeDebugger = actor;
|
||||
actorPool.addActor(actor);
|
||||
}
|
||||
|
||||
actor = this._tabActors.get(this.browser);
|
||||
if (!actor) {
|
||||
actor = new DeviceTabActor(this.conn, this.browser);
|
||||
// this.actorID is set by ActorPool when an actor is put into one.
|
||||
@ -78,7 +87,8 @@ DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
|
||||
'from': 'root',
|
||||
'selected': 0,
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
'tabs': [actor.grip()]
|
||||
'tabs': [actor.grip()],
|
||||
"chromeDebugger": this._chromeDebugger.actorID
|
||||
#else
|
||||
'tabs': []
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
[{
|
||||
"size": 608318343,
|
||||
"digest": "9ab6487eccf44b0781cc96c2af9ba497f720a8d289bde40e29417f9db82788d6c8653c7dafa7443069f5898635eef45fa048ee99c03a9d0113c019a2f80f5aa8",
|
||||
"size": 606070399,
|
||||
"digest": "3d3899e2537bee5e3f969bb6d0e90fed93345512123e3133b1de793d59a8993d8174d9456cb92d86a880f6813d6049933de924cd522a433ef26c4bfa997777a7",
|
||||
"algorithm": "sha512",
|
||||
"filename": "emulator.zip"
|
||||
}]
|
||||
|
@ -312,7 +312,8 @@ static int do_main(int argc, char* argv[], nsIFile *xreDirectory)
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
newArgc--;
|
||||
if (ptr == newArgv[newArgc-1])
|
||||
newArgc--;
|
||||
int result = XRE_main(newArgc, newArgv, appData, mainFlags);
|
||||
XRE_FreeAppData(appData);
|
||||
return result;
|
||||
|
@ -877,9 +877,12 @@ pref("browser.zoom.updateBackgroundTabs", true);
|
||||
// The breakpad report server to link to in about:crashes
|
||||
pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
// Override submission of plugin hang reports to a different processing server
|
||||
// for the smaller-volume nightly/aurora populations.
|
||||
pref("toolkit.crashreporter.pluginHangSubmitURL",
|
||||
"https://hang-reports.mozilla.org/submit");
|
||||
#endif
|
||||
|
||||
// URL for "Learn More" for Crash Reporter
|
||||
pref("toolkit.crashreporter.infoURL",
|
||||
|
@ -4374,7 +4374,7 @@ var XULBrowserWindow = {
|
||||
if (e.target.readyState != "interactive" && e.target.readyState != "complete")
|
||||
return;
|
||||
|
||||
e.target.removeEventListener("readystate", onContentRSChange);
|
||||
e.target.removeEventListener("readystatechange", onContentRSChange);
|
||||
disableFindCommands(shouldDisableFind(e.target));
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ DIRS += \
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_FILES = \
|
||||
head.js \
|
||||
head_plain.js \
|
||||
test_feed_discovery.html \
|
||||
feed_discovery.html \
|
||||
test_bug395533.html \
|
||||
@ -161,6 +161,7 @@ _BROWSER_FILES = \
|
||||
browser_bug783614.js \
|
||||
browser_bug797677.js \
|
||||
browser_bug816527.js \
|
||||
browser_bug822367.js \
|
||||
browser_bug832435.js \
|
||||
browser_canonizeURL.js \
|
||||
browser_customize.js \
|
||||
@ -237,6 +238,15 @@ _BROWSER_FILES = \
|
||||
disablechrome.html \
|
||||
discovery.html \
|
||||
domplate_test.js \
|
||||
file_bug822367_1.html \
|
||||
file_bug822367_1.js \
|
||||
file_bug822367_2.html \
|
||||
file_bug822367_3.html \
|
||||
file_bug822367_4.html \
|
||||
file_bug822367_4.js \
|
||||
file_bug822367_4B.html \
|
||||
file_bug822367_5.html \
|
||||
file_bug822367_6.html \
|
||||
moz.png \
|
||||
video.ogg \
|
||||
test_bug435035.html \
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
const PREF_DISPLAY = "security.mixed_content.block_display_content";
|
||||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
const gHttpTestRoot = "https://example.com/tests/content/base/test/";
|
||||
const gHttpTestRoot = "https://example.com/browser/browser/base/content/test/";
|
||||
var origBlockDisplay;
|
||||
var origBlockActive;
|
||||
var gTestBrowser = null;
|
@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
<p id="p1"></p>
|
||||
<img src="http://example.com/tests/image/test/mochitest/blue.png" onload="foo()">
|
||||
</div>
|
||||
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/tests/content/base/test/file_bug822367_4.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_4.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1
browser/base/content/test/file_bug822367_4.js
Normal file
1
browser/base/content/test/file_bug822367_4.js
Normal file
@ -0,0 +1 @@
|
||||
document.location = "https://example.com/browser/browser/base/content/test/file_bug822367_4B.html";
|
@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
function createDoc()
|
||||
{
|
||||
var doc=document.open("text/html","replace");
|
||||
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/tests/content/base/test/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
|
||||
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
|
||||
doc.close();
|
||||
}
|
||||
</script>
|
@ -10,7 +10,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<iframe name="f1" id="f1" src="https://example.com/tests/content/base/test/file_bug822367_5.html"></iframe>
|
||||
<iframe name="f1" id="f1" src="https://example.com/browser/browser/base/content/test/file_bug822367_5.html"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +1,3 @@
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
|
15
browser/base/content/test/head_plain.js
Normal file
15
browser/base/content/test/head_plain.js
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
function waitForCondition(condition, nextTest, errorMsg) {
|
||||
var tries = 0;
|
||||
var interval = setInterval(function() {
|
||||
if (tries >= 30) {
|
||||
ok(false, errorMsg);
|
||||
moveOn();
|
||||
}
|
||||
if (condition()) {
|
||||
moveOn();
|
||||
}
|
||||
tries++;
|
||||
}, 100);
|
||||
var moveOn = function() { clearInterval(interval); nextTest(); };
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript;version=1.7" src="head.js"></script>
|
||||
<script type="application/javascript;version=1.7" src="head_plain.js"></script>
|
||||
<script>
|
||||
SpecialPowers.setBoolPref('plugins.click_to_play', true);
|
||||
</script>
|
||||
|
@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html dir="ltr" mozdisallowselectionprint>
|
||||
<html dir="ltr" mozdisallowselectionprint moznomarginboxes>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
|
@ -23,12 +23,16 @@ var ContextCommands = {
|
||||
* Context menu handlers
|
||||
*/
|
||||
|
||||
// Text specific
|
||||
|
||||
copy: function cc_copy() {
|
||||
let target = ContextMenuUI.popupState.target;
|
||||
if (target.localName == "browser") {
|
||||
// content
|
||||
if (ContextMenuUI.popupState.string != "undefined") {
|
||||
this.clipboard.copyString(ContextMenuUI.popupState.string,
|
||||
this.docRef);
|
||||
this.showToast(Strings.browser.GetStringFromName("selectionHelper.textCopied"));
|
||||
} else {
|
||||
let x = ContextMenuUI.popupState.x;
|
||||
let y = ContextMenuUI.popupState.y;
|
||||
@ -36,7 +40,9 @@ var ContextCommands = {
|
||||
target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
|
||||
}
|
||||
} else {
|
||||
// chrome
|
||||
target.editor.copy();
|
||||
this.showToast(Strings.browser.GetStringFromName("selectionHelper.textCopied"));
|
||||
}
|
||||
|
||||
if (target)
|
||||
@ -46,11 +52,13 @@ var ContextCommands = {
|
||||
paste: function cc_paste() {
|
||||
let target = ContextMenuUI.popupState.target;
|
||||
if (target.localName == "browser") {
|
||||
// content
|
||||
let x = ContextMenuUI.popupState.x;
|
||||
let y = ContextMenuUI.popupState.y;
|
||||
let json = {x: x, y: y, command: "paste" };
|
||||
target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
|
||||
} else {
|
||||
// chrome
|
||||
target.editor.paste(Ci.nsIClipboard.kGlobalClipboard);
|
||||
target.focus();
|
||||
}
|
||||
@ -63,24 +71,157 @@ var ContextCommands = {
|
||||
BrowserUI.goToURI();
|
||||
},
|
||||
|
||||
select: function cc_select() {
|
||||
let contextInfo = { name: "",
|
||||
json: ContextMenuUI.popupState,
|
||||
target: ContextMenuUI.popupState.target };
|
||||
SelectionHelperUI.openEditSession(contextInfo);
|
||||
},
|
||||
|
||||
selectAll: function cc_selectAll() {
|
||||
let target = ContextMenuUI.popupState.target;
|
||||
if (target.localName == "browser") {
|
||||
// content
|
||||
let x = ContextMenuUI.popupState.x;
|
||||
let y = ContextMenuUI.popupState.y;
|
||||
let json = {x: x, y: y, command: "select-all" };
|
||||
target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
|
||||
let contextInfo = { name: "",
|
||||
json: ContextMenuUI.popupState,
|
||||
target: ContextMenuUI.popupState.target };
|
||||
SelectionHelperUI.attachEditSession(contextInfo);
|
||||
} else {
|
||||
// chrome
|
||||
target.editor.selectAll();
|
||||
target.focus();
|
||||
}
|
||||
},
|
||||
|
||||
openInNewTab: function cc_openInNewTab() {
|
||||
Browser.addTab(ContextMenuUI.popupState.linkURL, false, Browser.selectedTab);
|
||||
ContextUI.peekTabs();
|
||||
// called on display of the search text menu item
|
||||
searchTextSetup: function cc_searchTextSetup(aRichListItem, aSearchString) {
|
||||
let defaultURI;
|
||||
let defaultName;
|
||||
try {
|
||||
let defaultPB = Services.prefs.getDefaultBranch(null);
|
||||
const nsIPLS = Ci.nsIPrefLocalizedString;
|
||||
defaultName = defaultPB.getComplexValue("browser.search.defaultenginename", nsIPLS).data;
|
||||
let defaultEngine = Services.search.getEngineByName(defaultName);
|
||||
defaultURI = defaultEngine.getSubmission(aSearchString).uri.spec;
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
return false;
|
||||
}
|
||||
// label child node
|
||||
let label = Services.strings
|
||||
.createBundle("chrome://browser/locale/browser.properties")
|
||||
.formatStringFromName("browser.search.contextTextSearchLabel",
|
||||
[defaultName], 1);
|
||||
aRichListItem.childNodes[0].setAttribute("value", label);
|
||||
aRichListItem.setAttribute("searchString", defaultURI);
|
||||
return true;
|
||||
},
|
||||
|
||||
searchText: function cc_searchText(aRichListItem) {
|
||||
let defaultURI = aRichListItem.getAttribute("searchString");
|
||||
aRichListItem.childNodes[0].setAttribute("value", "");
|
||||
aRichListItem.setAttribute("searchString", "");
|
||||
BrowserUI.newTab(defaultURI, Browser.selectedTab);
|
||||
},
|
||||
|
||||
// Link specific
|
||||
|
||||
openLinkInNewTab: function cc_openLinkInNewTab() {
|
||||
BrowserUI.newTab(ContextMenuUI.popupState.linkURL, Browser.selectedTab);
|
||||
},
|
||||
|
||||
copyLink: function cc_copyLink() {
|
||||
this.clipboard.copyString(ContextMenuUI.popupState.linkURL,
|
||||
this.docRef);
|
||||
this.showToast(Strings.browser.GetStringFromName("selectionHelper.linkCopied"));
|
||||
},
|
||||
|
||||
bookmarkLink: function cc_bookmarkLink() {
|
||||
let state = ContextMenuUI.popupState;
|
||||
let uri = Util.makeURI(state.linkURL);
|
||||
let title = state.linkTitle || state.linkURL;
|
||||
|
||||
try {
|
||||
Bookmarks.addForURI(uri, title);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showToast(Strings.browser.GetStringFromName("alertLinkBookmarked"));
|
||||
},
|
||||
|
||||
// Image specific
|
||||
|
||||
saveImageToLib: function cc_saveImageToLib() {
|
||||
this.saveToWinLibrary("Pict");
|
||||
},
|
||||
|
||||
copyImage: function cc_copyImage() {
|
||||
// copy to clibboard
|
||||
this.sendCommand("copy-image-contents");
|
||||
},
|
||||
|
||||
copyImageSrc: function cc_copyImageSrc() {
|
||||
this.clipboard.copyString(ContextMenuUI.popupState.mediaURL,
|
||||
this.docRef);
|
||||
this.showToast(Strings.browser.GetStringFromName("selectionHelper.linkCopied"));
|
||||
},
|
||||
|
||||
openImageInNewTab: function cc_openImageInNewTab() {
|
||||
BrowserUI.newTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab);
|
||||
},
|
||||
|
||||
// Video specific
|
||||
|
||||
saveVideoToLib: function cc_saveVideoToLib() {
|
||||
this.saveToWinLibrary("Vids");
|
||||
},
|
||||
|
||||
copyVideoSrc: function cc_copyVideoSrc() {
|
||||
this.clipboard.copyString(ContextMenuUI.popupState.mediaURL,
|
||||
this.docRef);
|
||||
this.showToast(Strings.browser.GetStringFromName("selectionHelper.linkCopied"));
|
||||
},
|
||||
|
||||
openVideoInNewTab: function cc_openVideoInNewTab() {
|
||||
BrowserUI.newTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab);
|
||||
},
|
||||
|
||||
openVideoInFullscreen: function cc_openVideoInFullscreen() {
|
||||
// XXX currently isn't working.
|
||||
this.sendCommand('videotab');
|
||||
},
|
||||
|
||||
// Bookmarks
|
||||
|
||||
editBookmark: function cc_editBookmark() {
|
||||
let target = ContextMenuUI.popupState.target;
|
||||
target.startEditing();
|
||||
},
|
||||
|
||||
removeBookmark: function cc_removeBookmark() {
|
||||
let target = ContextMenuUI.popupState.target;
|
||||
target.remove();
|
||||
},
|
||||
|
||||
// App bar
|
||||
|
||||
findInPage: function cc_findInPage() {
|
||||
FindHelperUI.show();
|
||||
},
|
||||
|
||||
viewOnDesktop: function cc_viewOnDesktop() {
|
||||
Appbar.onViewOnDesktop();
|
||||
},
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
|
||||
saveToWinLibrary: function cc_saveToWinLibrary(aType) {
|
||||
let popupState = ContextMenuUI.popupState;
|
||||
let browser = popupState.target;
|
||||
@ -116,55 +257,9 @@ var ContextCommands = {
|
||||
});
|
||||
},
|
||||
|
||||
saveVideo: function cc_saveVideo() {
|
||||
this.saveToWinLibrary("Vids");
|
||||
},
|
||||
|
||||
saveVideoTo: function cc_saveVideoTo() {
|
||||
this.saveFileAs(ContextMenuUI.popupState);
|
||||
},
|
||||
|
||||
saveImage: function cc_saveImage() {
|
||||
this.saveToWinLibrary("Pict");
|
||||
},
|
||||
|
||||
saveImageTo: function cc_saveImageTo() {
|
||||
this.saveFileAs(ContextMenuUI.popupState);
|
||||
},
|
||||
|
||||
copyLink: function cc_copyLink() {
|
||||
this.clipboard.copyString(ContextMenuUI.popupState.linkURL,
|
||||
this.docRef);
|
||||
},
|
||||
|
||||
copyEmail: function cc_copyEmail() {
|
||||
this.clipboard.copyString(ContextMenuUI.popupState.linkURL.substr(ContextMenuUI.popupState.linkURL.indexOf(':')+1),
|
||||
this.docRef);
|
||||
},
|
||||
|
||||
copyPhone: function cc_copyPhone() {
|
||||
this.clipboard.copyString(ContextMenuUI.popupState.linkURL.substr(ContextMenuUI.popupState.linkURL.indexOf(':')+1),
|
||||
this.docRef);
|
||||
},
|
||||
|
||||
copyImage: function cc_copyImage() {
|
||||
this.sendCommand("copy-image-contents");
|
||||
},
|
||||
|
||||
bookmarkLink: function cc_bookmarkLink() {
|
||||
let state = ContextMenuUI.popupState;
|
||||
let uri = Util.makeURI(state.linkURL);
|
||||
let title = state.linkTitle || state.linkURL;
|
||||
|
||||
try {
|
||||
Bookmarks.addForURI(uri, title);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
let message = Strings.browser.GetStringFromName("alertLinkBookmarked");
|
||||
showToast: function showToast(aString) {
|
||||
let toaster = Cc["@mozilla.org/toaster-alerts-service;1"].getService(Ci.nsIAlertsService);
|
||||
toaster.showAlertNotification(null, message, "", false, "", null);
|
||||
toaster.showAlertNotification(null, aString, "", false, "", null);
|
||||
},
|
||||
|
||||
sendCommand: function cc_playVideo(aCommand) {
|
||||
@ -173,28 +268,6 @@ var ContextCommands = {
|
||||
browser.messageManager.sendAsyncMessage("Browser:ContextCommand", { command: aCommand });
|
||||
},
|
||||
|
||||
editBookmark: function cc_editBookmark() {
|
||||
let target = ContextMenuUI.popupState.target;
|
||||
target.startEditing();
|
||||
},
|
||||
|
||||
removeBookmark: function cc_removeBookmark() {
|
||||
let target = ContextMenuUI.popupState.target;
|
||||
target.remove();
|
||||
},
|
||||
|
||||
findInPage: function cc_findInPage() {
|
||||
FindHelperUI.show();
|
||||
},
|
||||
|
||||
viewOnDesktop: function cc_viewOnDesktop() {
|
||||
Appbar.onViewOnDesktop();
|
||||
},
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
|
||||
/*
|
||||
* isAccessibleDirectory
|
||||
*
|
||||
|
@ -57,21 +57,21 @@
|
||||
|
||||
<commandset id="mainCommandSet">
|
||||
<!-- basic navigation -->
|
||||
<command id="cmd_back" label="&back.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_forward" label="&forward.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);" observes="bcast_urlbarState"/>
|
||||
<command id="cmd_back" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_forward" disabled="true" oncommand="CommandUpdater.doCommand(this.id);" observes="bcast_urlbarState"/>
|
||||
<command id="cmd_handleBackspace" oncommand="BrowserUI.handleBackspace();" />
|
||||
<command id="cmd_handleShiftBackspace" oncommand="BrowserUI.handleShiftBackspace();" />
|
||||
<command id="cmd_reload" label="&reload.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_reload" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_forceReload" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_stop" label="&stop.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_go" label="&go.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_stop" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_go" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_openLocation" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_home" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- tabs -->
|
||||
<command id="cmd_newTab" label="&newtab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_closeTab" label="&closetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_undoCloseTab" label="&undoclosetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_newTab" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_closeTab" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_undoCloseTab" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<command id="cmd_remoteTabs" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
#endif
|
||||
@ -101,12 +101,12 @@
|
||||
<command id="cmd_scrollPageDown" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- editing -->
|
||||
<command id="cmd_cut" label="&cut.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_copy" label="©.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_copylink" label="©link.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_paste" label="&paste.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_delete" label="&delete.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_selectAll" label="&selectAll.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_cut" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_copy" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_copylink" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_paste" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_delete" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_selectAll" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- forms navigation -->
|
||||
<command id="cmd_formPrevious" oncommand="FormHelperUI.goToPrevious();"/>
|
||||
@ -195,10 +195,10 @@
|
||||
forwarddisabled="true"
|
||||
title="Back/Forward">
|
||||
<toolbarbutton id="back-button" class="toolbarbutton"
|
||||
label="Back"
|
||||
label="&back.label;"
|
||||
command="cmd_back"/>
|
||||
<toolbarbutton id="forward-button" class="toolbarbutton"
|
||||
label="Forward"
|
||||
label="&forward.label;"
|
||||
command="cmd_forward"/>
|
||||
<dummyobservertarget hidden="true"
|
||||
onbroadcast="if (this.getAttribute('disabled') == 'true')
|
||||
@ -245,7 +245,7 @@
|
||||
</toolbar>
|
||||
|
||||
<box id="toolbar-transition" observes="bcast_windowState" >
|
||||
<toolbarbutton id="tool-new-tab" command="cmd_newTab"/>
|
||||
<toolbarbutton id="tool-new-tab" command="cmd_newTab" label="&newtab.label;"/>
|
||||
</box>
|
||||
</hbox>
|
||||
|
||||
@ -559,78 +559,83 @@
|
||||
<box id="context-container" class="menu-container" hidden="true">
|
||||
<vbox id="context-popup" class="menu-popup">
|
||||
<richlistbox id="context-commands" bindingType="contextmenu" flex="1">
|
||||
<!-- priority="low" items are hidden by default when a context is being displayed
|
||||
for two or more media types. (e.g. a linked image) -->
|
||||
<!-- Note the order of richlistitem here is important as it is reflected in the
|
||||
menu itself. -->
|
||||
<!-- ux spec: https://bug782810.bugzilla.mozilla.org/attachment.cgi?id=714804 -->
|
||||
|
||||
<!-- Text related -->
|
||||
<richlistitem id="context-copy" type="copy" onclick="ContextCommands.copy();">
|
||||
<label value="©.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-copy-all" type="copy-all" onclick="ContextCommands.copy();">
|
||||
<label value="©All.label;"/>
|
||||
<!-- for text inputs, this will copy selected text, or if no text is selected, copy all -->
|
||||
<richlistitem id="context-copy" type="copy,selectable" onclick="ContextCommands.copy();">
|
||||
<label value="&contextTextCopy.label;"/>
|
||||
</richlistitem>
|
||||
<!-- only displayed if there is text on the clipboard -->
|
||||
<richlistitem id="context-paste" type="paste" onclick="ContextCommands.paste();">
|
||||
<label value="&paste.label;"/>
|
||||
<label value="&contextTextPaste.label;"/>
|
||||
</richlistitem>
|
||||
<!-- Search Bing for "..." -->
|
||||
<richlistitem id="context-search" type="copy,selected-text" onclick="ContextCommands.searchText(this);">
|
||||
<label id="context-search-label" value=""/>
|
||||
</richlistitem>
|
||||
<!-- only display if there is text on the clipboard and the target is the urlbar -->
|
||||
<richlistitem id="context-paste-n-go" type="paste-url" onclick="ContextCommands.pasteAndGo();">
|
||||
<label value="&pasteAndGo.label;"/>
|
||||
<label value="&contextTextPasteAndGo.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-select-all" type="select-all" onclick="ContextCommands.selectAll();">
|
||||
<label value="&selectAll.label;"/>
|
||||
<!-- only displayed in inputs with text that do not have selection -->
|
||||
<richlistitem id="context-select" type="selectable" onclick="ContextCommands.select();">
|
||||
<label value="&contextTextSelect.label;"/>
|
||||
</richlistitem>
|
||||
<!-- only displayed in inputs with text that do not have selection -->
|
||||
<richlistitem id="context-select-all" type="selectable" onclick="ContextCommands.selectAll();">
|
||||
<label value="&contextTextSelectAll.label;"/>
|
||||
</richlistitem>
|
||||
|
||||
<!-- Image related -->
|
||||
<richlistitem id="context-viewinnewtab" type="image" onclick="ContextCommands.openInNewTab();">
|
||||
<label value="&contextViewInNewTab.label;"/>
|
||||
<!-- save image to user pictures library -->
|
||||
<richlistitem id="context-save-image-lib" type="image" onclick="ContextCommands.saveImageToLib();">
|
||||
<label value="&contextSaveImageLib.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-copy-image" type="image-loaded" onclick="ContextCommands.copyImage();">
|
||||
<!-- copy image data to clipboard -->
|
||||
<richlistitem id="context-copy-image" type="image" onclick="ContextCommands.copyImage();">
|
||||
<label value="&contextCopyImage.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-save-image" type="image-loaded" onclick="ContextCommands.saveImage();">
|
||||
<label value="&contextSaveImage.label;"/>
|
||||
<!-- copy the uri of the image src -->
|
||||
<richlistitem id="context-copy-image-loc" type="image" onclick="ContextCommands.copyImageSrc();">
|
||||
<label value="&contextCopyImageLocation.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-save-image-to" type="image-loaded" onclick="ContextCommands.saveImageTo();">
|
||||
<label value="&contextSaveImageTo.label;"/>
|
||||
</richlistitem>
|
||||
|
||||
<!-- Link related -->
|
||||
<richlistitem id="context-openinnewtab" type="link-openable" onclick="ContextCommands.openInNewTab();">
|
||||
<label value="&contextOpenInNewTab.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-bookmark-link" type="link" onclick="ContextCommands.bookmarkLink();">
|
||||
<label value="&contextBookmarkLink.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-copy-link" type="link" onclick="ContextCommands.copyLink();">
|
||||
<label value="&contextCopyLink.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-copy-email" type="mailto" onclick="ContextCommands.copyEmail();">
|
||||
<label value="&contextCopyEmail.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-copy-phone" type="callto" onclick="ContextCommands.copyPhone();">
|
||||
<label value="&contextCopyPhone.label;"/>
|
||||
<!-- open the uri of the image src in a new tab -->
|
||||
<richlistitem id="context-open-image-tab" type="image" priority="low" onclick="ContextCommands.openImageInNewTab();">
|
||||
<label value="&contextOpenImageTab.label;"/>
|
||||
</richlistitem>
|
||||
|
||||
<!-- Video related -->
|
||||
<richlistitem id="context-play-media" type="media-paused" onclick="ContextCommands.sendCommand('play');">
|
||||
<label value="&contextPlayMedia.label;"/>
|
||||
<!-- save video to user videos library -->
|
||||
<richlistitem id="context-save-video-lib" type="video" onclick="ContextCommands.saveVideoToLib();">
|
||||
<label value="&contextSaveVideoLib.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-pause-video" type="media-playing" onclick="ContextCommands.sendCommand('pause');">
|
||||
<label value="&contextPauseMedia.label;"/>
|
||||
<!-- copy the uri of the video src -->
|
||||
<richlistitem id="context-copy-video-loc" type="video" onclick="ContextCommands.copyVideoSrc();">
|
||||
<label value="&contextCopyVideoLocation.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-videotab" type="video" onclick="ContextCommands.sendCommand('videotab');">
|
||||
<label value="&contextVideoTab.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-save-video" type="video" onclick="ContextCommands.saveVideo();">
|
||||
<label value="&contextSaveVideo.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-save-video-to" type="video" onclick="ContextCommands.saveVideoTo();">
|
||||
<label value="&contextSaveVideoTo.label;"/>
|
||||
<!-- open the uri of the video src in a new tab -->
|
||||
<richlistitem id="context-open-video-tab" type="video" priority="low" onclick="ContextCommands.openVideoInNewTab();">
|
||||
<label value="&contextOpenVideoTab.label;"/>
|
||||
</richlistitem>
|
||||
|
||||
<!-- Misc. related -->
|
||||
<richlistitem id="context-editbookmark" type="edit-bookmark" onclick="ContextCommands.editBookmark();">
|
||||
<label value="&contextEditBookmark.label;"/>
|
||||
<!-- Link related -->
|
||||
<!-- all of these apply to underlying link href values -->
|
||||
<richlistitem id="context-open-in-new-tab" type="link" onclick="ContextCommands.openLinkInNewTab();">
|
||||
<label value="&contextOpenLinkTab.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-removebookmark" type="edit-bookmark" onclick="ContextCommands.removeBookmark();">
|
||||
<label value="&contextRemoveBookmark.label;"/>
|
||||
<richlistitem id="context-copy-link" type="link" onclick="ContextCommands.copyLink();">
|
||||
<label value="&contextCopyLinkHref.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="context-bookmark-link" type="link" priority="low" onclick="ContextCommands.bookmarkLink();">
|
||||
<label value="&contextBookmarkLinkHref.label;"/>
|
||||
</richlistitem>
|
||||
|
||||
<!-- App bar: 'more' button context menu -->
|
||||
<richlistitem id="context-findinpage" type="find-in-page" onclick="ContextCommands.findInPage();">
|
||||
<label value="&appbarFindInPage.label;"/>
|
||||
</richlistitem>
|
||||
|
@ -175,6 +175,8 @@ var ContextMenuHandler = {
|
||||
linkUrl = state.linkURL;
|
||||
state.linkTitle = popupNode.textContent || popupNode.title;
|
||||
state.linkProtocol = this._getProtocol(this._getURI(state.linkURL));
|
||||
// mark as text so we can pickup on selection below
|
||||
isText = true;
|
||||
break;
|
||||
} else if (this._isTextInput(elem)) {
|
||||
let selectionStart = elem.selectionStart;
|
||||
@ -188,16 +190,13 @@ var ContextMenuHandler = {
|
||||
if (selectionStart != selectionEnd) {
|
||||
state.types.push("copy");
|
||||
state.string = elem.value.slice(selectionStart, selectionEnd);
|
||||
} else if (elem.value) {
|
||||
state.types.push("copy-all");
|
||||
}
|
||||
if (elem.value && (selectionStart > 0 || selectionEnd < elem.textLength)) {
|
||||
state.types.push("selectable");
|
||||
state.string = elem.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectionStart > 0 || selectionEnd < elem.textLength) {
|
||||
state.types.push("select-all");
|
||||
}
|
||||
|
||||
if (!elem.textLength) {
|
||||
state.types.push("input-empty");
|
||||
}
|
||||
@ -227,6 +226,7 @@ var ContextMenuHandler = {
|
||||
elem = elem.parentNode;
|
||||
}
|
||||
|
||||
// Over arching text tests
|
||||
if (isText) {
|
||||
// If this is text and has a selection, we want to bring
|
||||
// up the copy option on the context menu.
|
||||
@ -334,36 +334,3 @@ var ContextMenuHandler = {
|
||||
};
|
||||
|
||||
ContextMenuHandler.init();
|
||||
|
||||
ContextMenuHandler.registerType("mailto", function(aState, aElement) {
|
||||
return aState.linkProtocol == "mailto";
|
||||
});
|
||||
|
||||
ContextMenuHandler.registerType("callto", function(aState, aElement) {
|
||||
let protocol = aState.linkProtocol;
|
||||
return protocol == "tel" || protocol == "callto" || protocol == "sip" || protocol == "voipto";
|
||||
});
|
||||
|
||||
ContextMenuHandler.registerType("link-openable", function(aState, aElement) {
|
||||
return Util.isOpenableScheme(aState.linkProtocol);
|
||||
});
|
||||
|
||||
["image", "video"].forEach(function(aType) {
|
||||
ContextMenuHandler.registerType(aType+"-shareable", function(aState, aElement) {
|
||||
if (aState.types.indexOf(aType) == -1)
|
||||
return false;
|
||||
|
||||
let protocol = ContextMenuHandler._getProtocol(ContextMenuHandler._getURI(aState.mediaURL));
|
||||
return Util.isShareableScheme(protocol);
|
||||
});
|
||||
});
|
||||
|
||||
ContextMenuHandler.registerType("image-loaded", function(aState, aElement) {
|
||||
if (aState.types.indexOf("image") != -1) {
|
||||
let request = aElement.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
|
||||
if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
|
@ -55,6 +55,7 @@ var SelectionHandler = {
|
||||
|
||||
init: function init() {
|
||||
addMessageListener("Browser:SelectionStart", this);
|
||||
addMessageListener("Browser:SelectionAttach", this);
|
||||
addMessageListener("Browser:SelectionEnd", this);
|
||||
addMessageListener("Browser:SelectionMoveStart", this);
|
||||
addMessageListener("Browser:SelectionMove", this);
|
||||
@ -68,6 +69,7 @@ var SelectionHandler = {
|
||||
|
||||
shutdown: function shutdown() {
|
||||
removeMessageListener("Browser:SelectionStart", this);
|
||||
removeMessageListener("Browser:SelectionAttach", this);
|
||||
removeMessageListener("Browser:SelectionEnd", this);
|
||||
removeMessageListener("Browser:SelectionMoveStart", this);
|
||||
removeMessageListener("Browser:SelectionMove", this);
|
||||
@ -114,6 +116,17 @@ var SelectionHandler = {
|
||||
this._updateSelectionUI(true, true);
|
||||
},
|
||||
|
||||
_onSelectionAttach: function _onSelectionAttach(aX, aY) {
|
||||
// Init content window information
|
||||
if (!this._initTargetInfo(aX, aY)) {
|
||||
this._onFail("failed to get frame offset");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the position of our selection monocles
|
||||
this._updateSelectionUI(true, true);
|
||||
},
|
||||
|
||||
/*
|
||||
* Selection monocle start move event handler
|
||||
*/
|
||||
@ -894,6 +907,10 @@ var SelectionHandler = {
|
||||
this._onSelectionStart(json.xPos, json.yPos);
|
||||
break;
|
||||
|
||||
case "Browser:SelectionAttach":
|
||||
this._onSelectionAttach(json.xPos, json.yPos);
|
||||
break;
|
||||
|
||||
case "Browser:SelectionClose":
|
||||
this._onSelectionClose();
|
||||
break;
|
||||
|
@ -118,14 +118,54 @@ var ContextMenuUI = {
|
||||
this._popupState.target = aMessage.target;
|
||||
let contentTypes = this._popupState.types;
|
||||
|
||||
let optionsAvailable = false;
|
||||
for (let i = 0; i < this._commands.childElementCount; i++) {
|
||||
let command = this._commands.childNodes[i];
|
||||
command.hidden = true;
|
||||
/*
|
||||
* Types in ContextMenuHandler:
|
||||
* image
|
||||
* link
|
||||
* input-text - generic form input control
|
||||
* copy - form input that has some selected text
|
||||
* selectable - form input with text that can be selected
|
||||
* input-empty - form input (empty)
|
||||
* paste - form input and there's text on the clipboard
|
||||
* selected-text - generic content text that is selected
|
||||
* content-text - generic content text
|
||||
* video
|
||||
* media-paused, media-playing
|
||||
* paste-url - url bar w/text on the clipboard
|
||||
*/
|
||||
|
||||
Util.dumpLn("contentTypes:", contentTypes);
|
||||
|
||||
// Defines whether or not low priority items in images, text, and
|
||||
// links are displayed.
|
||||
let multipleMediaTypes = false;
|
||||
if (contentTypes.indexOf("link") != -1 &&
|
||||
(contentTypes.indexOf("image") != -1 ||
|
||||
contentTypes.indexOf("video") != -1 ||
|
||||
contentTypes.indexOf("selected-text") != -1))
|
||||
multipleMediaTypes = true;
|
||||
|
||||
for (let command of Array.slice(this._commands.childNodes)) {
|
||||
command.hidden = true;
|
||||
}
|
||||
|
||||
let optionsAvailable = false;
|
||||
for (let command of Array.slice(this._commands.childNodes)) {
|
||||
let types = command.getAttribute("type").split(",");
|
||||
let lowPriority = (command.hasAttribute("priority") &&
|
||||
command.getAttribute("priority") == "low");
|
||||
let searchTextItem = (command.id == "context-search");
|
||||
|
||||
// filter low priority items if we have more than one media type.
|
||||
if (multipleMediaTypes && lowPriority)
|
||||
continue;
|
||||
|
||||
let types = command.getAttribute("type").split(/\s+/);
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
if (contentTypes.indexOf(types[i]) != -1) {
|
||||
// If this is the special search text item, we need to set its label dynamically.
|
||||
if (searchTextItem && !ContextCommands.searchTextSetup(command, this._popupState.string)) {
|
||||
break;
|
||||
}
|
||||
optionsAvailable = true;
|
||||
command.hidden = false;
|
||||
break;
|
||||
@ -138,14 +178,7 @@ var ContextMenuUI = {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
this._menuPopup.show(this._popupState);
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("CancelTouchSequence", true, false);
|
||||
if (this._popupState.target) {
|
||||
this._popupState.target.dispatchEvent(event);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -303,6 +336,10 @@ MenuPopup.prototype = {
|
||||
this._panel.addEventListener("transitionend", function () {
|
||||
self._panel.removeEventListener("transitionend", arguments.callee);
|
||||
self._panel.removeAttribute("showingfrom");
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("popupshown", true, false);
|
||||
document.dispatchEvent(event);
|
||||
});
|
||||
|
||||
let popupFrom = (aPositionOptions.forcePosition && !aPositionOptions.bottomAligned) ? "above" : "below";
|
||||
@ -326,6 +363,9 @@ MenuPopup.prototype = {
|
||||
self._panel.removeEventListener("transitionend", arguments.callee);
|
||||
self._panel.hidden = true;
|
||||
self._popupState = null;
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("popuphidden", true, false);
|
||||
document.dispatchEvent(event);
|
||||
});
|
||||
|
||||
this._panel.removeAttribute("showing");
|
||||
|
@ -226,9 +226,6 @@ var SelectionHelperUI = {
|
||||
* the section.
|
||||
*/
|
||||
openEditSession: function openEditSession(aMessage) {
|
||||
if (!this.canHandle(aMessage))
|
||||
return;
|
||||
|
||||
/*
|
||||
* aMessage - from _onContentContextMenu in ContextMenuHandler
|
||||
* name: aMessage.name,
|
||||
@ -265,22 +262,42 @@ var SelectionHelperUI = {
|
||||
this._setupDebugOptions();
|
||||
},
|
||||
|
||||
/*
|
||||
* attachEditSession
|
||||
*
|
||||
* Attaches to existing selection and begins editing.
|
||||
*/
|
||||
attachEditSession: function attachEditSession(aMessage) {
|
||||
this._popupState = aMessage.json;
|
||||
this._popupState._target = aMessage.target;
|
||||
|
||||
this._init();
|
||||
|
||||
Util.dumpLn("enableSelection target:", this._popupState._target);
|
||||
|
||||
// Set the track bounds for each marker NIY
|
||||
this.startMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
|
||||
this.endMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
|
||||
|
||||
// Send this over to SelectionHandler in content, they'll message us
|
||||
// back with information on the current selection.
|
||||
this._popupState._target.messageManager.sendAsyncMessage(
|
||||
"Browser:SelectionAttach",
|
||||
{ xPos: this._popupState.xPos,
|
||||
yPos: this._popupState.yPos });
|
||||
|
||||
this._setupDebugOptions();
|
||||
},
|
||||
|
||||
/*
|
||||
* canHandle
|
||||
*
|
||||
* Determines if we can handle a ContextMenuHandler message.
|
||||
*/
|
||||
canHandle: function canHandle(aMessage) {
|
||||
// Reject empty text inputs, nothing to do here
|
||||
if (aMessage.json.types.indexOf("input-empty") != -1) {
|
||||
return false;
|
||||
}
|
||||
// Input with text or general text in a page
|
||||
if (aMessage.json.types.indexOf("content-text") == -1 &&
|
||||
aMessage.json.types.indexOf("input-text") == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (aMessage.json.types.indexOf("content-text") != -1)
|
||||
return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -165,8 +165,6 @@ var TouchModule = {
|
||||
|
||||
this._targetScrollbox = null;
|
||||
this._targetScrollInterface = null;
|
||||
|
||||
this._cleanClickBuffer();
|
||||
},
|
||||
|
||||
_onContextMenu: function _onContextMenu(aEvent) {
|
||||
|
@ -11,7 +11,7 @@ relativesrcdir = @relativesrcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_BROWSER_FILES = \
|
||||
BROWSER_TESTS = \
|
||||
head.js \
|
||||
browser_test.js \
|
||||
browser_canonizeURL.js \
|
||||
@ -23,7 +23,17 @@ _BROWSER_FILES = \
|
||||
browser_plugin_input.html \
|
||||
browser_plugin_input_mouse.js \
|
||||
browser_plugin_input_keyboard.js \
|
||||
browser_context_menu_tests.js \
|
||||
browser_context_menu_tests_01.html \
|
||||
browser_context_menu_tests_02.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_FILES)
|
||||
BROWSER_TEST_RESOURCES = \
|
||||
res\image01.png \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(BROWSER_TESTS)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/
|
||||
|
||||
libs:: $(BROWSER_TEST_RESOURCES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/res
|
||||
|
402
browser/metro/base/tests/browser_context_menu_tests.js
Normal file
402
browser/metro/base/tests/browser_context_menu_tests.js
Normal file
@ -0,0 +1,402 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
function debugClipFlavors(aClip)
|
||||
{
|
||||
let xfer = Cc["@mozilla.org/widget/transferable;1"].
|
||||
createInstance(Ci.nsITransferable);
|
||||
xfer.init(null);
|
||||
aClip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard);
|
||||
let array = xfer.flavorsTransferableCanExport();
|
||||
let count = array.Count();
|
||||
info("flavors:" + count);
|
||||
for (let idx = 0; idx < count; idx++) {
|
||||
let string = array.GetElementAt(idx).QueryInterface(Ci.nsISupportsString);
|
||||
info("[" + idx + "] " + string);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX won't work with out of process content
|
||||
function emptyClipboard() {
|
||||
Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard)
|
||||
.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
|
||||
}
|
||||
|
||||
// Image context menu tests
|
||||
gTests.push({
|
||||
desc: "text context menu",
|
||||
run: function test() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
info(chromeRoot + "browser_context_menu_tests_02.html");
|
||||
yield addTab(chromeRoot + "browser_context_menu_tests_02.html");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
let win = Browser.selectedTab.browser.contentWindow;
|
||||
|
||||
yield hideContextUI();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Context menu in content on selected text
|
||||
|
||||
// select some text
|
||||
let span = win.document.getElementById("text1");
|
||||
win.getSelection().selectAllChildren(span);
|
||||
|
||||
// invoke selection context menu
|
||||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, span, 85, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
// selected text context:
|
||||
checkContextUIMenuItemVisibility(["context-copy",
|
||||
"context-search"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
win.getSelection().removeAllRanges();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Context menu in content on selected text that includes a link
|
||||
|
||||
// invoke selection with link context menu
|
||||
let link = win.document.getElementById("text2-link");
|
||||
win.getSelection().selectAllChildren(link);
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, link, 40, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
// selected text context:
|
||||
checkContextUIMenuItemVisibility(["context-copy",
|
||||
"context-search",
|
||||
"context-open-in-new-tab",
|
||||
"context-copy-link"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
win.getSelection().removeAllRanges();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Context menu in content on a link
|
||||
|
||||
link = win.document.getElementById("text2-link");
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, link, 40, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
// selected text context:
|
||||
checkContextUIMenuItemVisibility(["context-open-in-new-tab",
|
||||
"context-copy-link",
|
||||
"context-bookmark-link"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in input with no selection, no data on clipboard
|
||||
|
||||
emptyClipboard();
|
||||
|
||||
let input = win.document.getElementById("text3-input");
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
checkContextUIMenuItemVisibility(["context-copy",
|
||||
"context-select",
|
||||
"context-select-all"]);
|
||||
|
||||
// copy menu item should copy all text
|
||||
let menuItem = document.getElementById("context-copy");
|
||||
ok(menuItem, "menu item exists");
|
||||
ok(!menuItem.hidden, "menu item visible");
|
||||
|
||||
let popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
let string = SpecialPowers.getClipboardData("text/unicode");
|
||||
ok(string, "hello, I'm sorry but I must be going.", "copy all");
|
||||
|
||||
emptyClipboard();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in input with text selection, no data on clipboard
|
||||
|
||||
input = win.document.getElementById("text3-input");
|
||||
input.select();
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
// selected text context:
|
||||
checkContextUIMenuItemVisibility(["context-copy",
|
||||
"context-search"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in input with no selection, data on clipboard
|
||||
|
||||
SpecialPowers.clipboardCopyString("foo");
|
||||
input = win.document.getElementById("text3-input");
|
||||
input.select();
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
// selected text context:
|
||||
checkContextUIMenuItemVisibility(["context-copy",
|
||||
"context-search",
|
||||
"context-paste"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in empty input, data on clipboard (paste operation)
|
||||
|
||||
SpecialPowers.clipboardCopyString("foo");
|
||||
input = win.document.getElementById("text3-input");
|
||||
input.value = "";
|
||||
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
// selected text context:
|
||||
checkContextUIMenuItemVisibility(["context-paste"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in empty input, no data on clipboard (??)
|
||||
|
||||
emptyClipboard();
|
||||
|
||||
input = win.document.getElementById("text3-input");
|
||||
input.value = "";
|
||||
|
||||
promise = waitForEvent(Elements.tray, "transitionend");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should *not* be visible
|
||||
ok(!ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
// the test above will invoke the app bar
|
||||
yield hideContextUI();
|
||||
|
||||
Browser.closeTab(Browser.selectedTab);
|
||||
purgeEventQueue();
|
||||
}
|
||||
});
|
||||
|
||||
// Image context menu tests
|
||||
gTests.push({
|
||||
desc: "image context menu",
|
||||
run: function test() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
info(chromeRoot + "browser_context_menu_tests_01.html");
|
||||
yield addTab(chromeRoot + "browser_context_menu_tests_01.html");
|
||||
|
||||
let win = Browser.selectedTab.browser.contentWindow;
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
yield hideContextUI();
|
||||
|
||||
// If we don't do this, sometimes the first sendContextMenuClick
|
||||
// will trigger the app bar.
|
||||
yield waitForImageLoad(win, "image01");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Context menu options
|
||||
|
||||
// image01 - 1x1x100x100
|
||||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClick(win, 10, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
checkContextUIMenuItemVisibility(["context-save-image-lib",
|
||||
"context-copy-image",
|
||||
"context-copy-image-loc",
|
||||
"context-open-image-tab"]);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Save to image library
|
||||
|
||||
let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
let saveLocationPath = dirSvc.get("Pict", Components.interfaces.nsIFile);
|
||||
saveLocationPath.append("image01.png");
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
saveLocationPath.remove(false);
|
||||
});
|
||||
|
||||
if (saveLocationPath.exists()) {
|
||||
info("had to remove old image!");
|
||||
saveLocationPath.remove(false);
|
||||
}
|
||||
|
||||
let menuItem = document.getElementById("context-save-image-lib");
|
||||
ok(menuItem, "menu item exists");
|
||||
ok(!menuItem.hidden, "menu item visible");
|
||||
|
||||
let downloadPromise = waitForObserver("dl-done");
|
||||
let popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
yield downloadPromise;
|
||||
ok(downloadPromise && !(downloadPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
ok(saveLocationPath.exists(), "image saved");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Copy image
|
||||
|
||||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClick(win, 20, 20);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
menuItem = document.getElementById("context-copy-image");
|
||||
ok(menuItem, "menu item exists");
|
||||
ok(!menuItem.hidden, "menu item visible");
|
||||
popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
|
||||
let flavors = ["image/png"];
|
||||
ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my png flavor");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Copy image location
|
||||
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClick(win, 30, 30);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
menuItem = document.getElementById("context-copy-image-loc");
|
||||
ok(menuItem, "menu item exists");
|
||||
ok(!menuItem.hidden, "menu item visible");
|
||||
popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
|
||||
let flavors = ["text/unicode"];
|
||||
ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my text flavor");
|
||||
|
||||
let xfer = Cc["@mozilla.org/widget/transferable;1"].
|
||||
createInstance(Ci.nsITransferable);
|
||||
xfer.init(null);
|
||||
xfer.addDataFlavor("text/unicode");
|
||||
clip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard);
|
||||
let str = new Object();
|
||||
let strLength = new Object();
|
||||
xfer.getTransferData("text/unicode", str, strLength);
|
||||
str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
ok(str == "chrome://mochitests/content/metro/res/image01.png", "url copied");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Open image in new tab
|
||||
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClick(win, 40, 40);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
menuItem = document.getElementById("context-open-image-tab");
|
||||
ok(menuItem, "menu item exists");
|
||||
ok(!menuItem.hidden, "menu item visible");
|
||||
let tabPromise = waitForEvent(document, "TabOpen");
|
||||
popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
let event = yield tabPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
ok(tabPromise && !(tabPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
let imagetab = Browser.getTabFromChrome(event.originalTarget);
|
||||
ok(imagetab != null, "tab created");
|
||||
ok(imagetab.browser.currentURI.spec == "chrome://mochitests/content/metro/res/image01.png", "tab location");
|
||||
|
||||
Browser.closeTab(imagetab);
|
||||
}
|
||||
});
|
||||
|
||||
function test() {
|
||||
runTests();
|
||||
}
|
14
browser/metro/base/tests/browser_context_menu_tests_01.html
Normal file
14
browser/metro/base/tests/browser_context_menu_tests_01.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body style="padding: 1px; margin: 1px;">
|
||||
<div style="margin: 0; padding: 0;">
|
||||
<span>
|
||||
<img id="image01" width="100" height="100" src="./res/image01.png" />
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
18
browser/metro/base/tests/browser_context_menu_tests_02.html
Normal file
18
browser/metro/base/tests/browser_context_menu_tests_02.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body style="padding: 10px; margin: 10px;">
|
||||
<div style="margin: 0; padding: 5px;">
|
||||
<span id="text1">hello, I'm sorry but I must be going.</span>
|
||||
</div>
|
||||
<div style="margin: 0; padding: 5px;">
|
||||
<span id="text2"><a id="text2-link" href="#test">hello, I'm sorry but</a> I must be going.</span>
|
||||
</div>
|
||||
<div style="margin: 0; padding: 5px;">
|
||||
<span id="text3"><input id="text3-input" value="hello, I'm sorry but I must be going." style="width:200px;"/></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -18,6 +18,53 @@ const chromeRoot = getRootDirectory(gTestPath);
|
||||
const kDefaultWait = 10000;
|
||||
const kDefaultInterval = 50;
|
||||
|
||||
/*=============================================================================
|
||||
Metro ui helpers
|
||||
=============================================================================*/
|
||||
|
||||
function checkContextUIMenuItemCount(aCount)
|
||||
{
|
||||
let visibleCount = 0;
|
||||
for (let idx = 0; idx < ContextMenuUI._commands.childNodes.length; idx++) {
|
||||
if (!ContextMenuUI._commands.childNodes[idx].hidden)
|
||||
visibleCount++;
|
||||
}
|
||||
is(visibleCount, aCount, "command list count");
|
||||
}
|
||||
|
||||
function checkContextUIMenuItemVisibility(aVisibleList)
|
||||
{
|
||||
let errors = 0;
|
||||
for (let idx = 0; idx < ContextMenuUI._commands.childNodes.length; idx++) {
|
||||
let item = ContextMenuUI._commands.childNodes[idx];
|
||||
if (aVisibleList.indexOf(item.id) != -1 && item.hidden) {
|
||||
// item should be visible
|
||||
errors++;
|
||||
info("should be visible:" + item.id);
|
||||
} else if (aVisibleList.indexOf(item.id) == -1 && !item.hidden) {
|
||||
// item should be hidden
|
||||
errors++;
|
||||
info("should be hidden:" + item.id);
|
||||
}
|
||||
}
|
||||
is(errors, 0, "context menu item list visibility");
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Asynchronous Metro ui helpers
|
||||
=============================================================================*/
|
||||
|
||||
function hideContextUI()
|
||||
{
|
||||
purgeEventQueue();
|
||||
if (ContextUI.isVisible) {
|
||||
info("is visible, waiting...");
|
||||
let promise = waitForEvent(Elements.tray, "transitionend");
|
||||
ContextUI.dismiss();
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Asynchronous test helpers
|
||||
=============================================================================*/
|
||||
@ -66,6 +113,7 @@ function addTab(aUrl) {
|
||||
* @returns a Promise that resolves to the received event, or to an Error
|
||||
*/
|
||||
function waitForEvent(aSubject, aEventName, aTimeoutMs) {
|
||||
info("waitForEvent: on " + aSubject + " event: " + aEventName);
|
||||
let eventDeferred = Promise.defer();
|
||||
let timeoutMs = aTimeoutMs || kDefaultWait;
|
||||
let timerID = setTimeout(function wfe_canceller() {
|
||||
@ -162,6 +210,78 @@ function waitForCondition(aCondition, aTimeoutMs, aIntervalMs) {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/*
|
||||
* Waits for an image in a page to load. Wrapper around waitForCondition.
|
||||
*
|
||||
* @param aWindow the tab or window that contains the image.
|
||||
* @param aImageId the id of the image in the page.
|
||||
* @returns a Promise that resolves to true, or to an Error
|
||||
*/
|
||||
function waitForImageLoad(aWindow, aImageId) {
|
||||
let elem = aWindow.document.getElementById(aImageId);
|
||||
return waitForCondition(function () {
|
||||
let request = elem.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
|
||||
if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
|
||||
return true;
|
||||
return false;
|
||||
}, 5000, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits a specified number of miliseconds for an observer event.
|
||||
*
|
||||
* @param aObsEvent the observer event to wait for
|
||||
* @param aTimeoutMs the number of miliseconds to wait before giving up
|
||||
* @returns a Promise that resolves to true, or to an Error
|
||||
*/
|
||||
function waitForObserver(aObsEvent, aTimeoutMs) {
|
||||
try {
|
||||
|
||||
let deferred = Promise.defer();
|
||||
let timeoutMs = aTimeoutMs || kDefaultWait;
|
||||
let timerID = 0;
|
||||
|
||||
var observeWatcher = {
|
||||
onEvent: function () {
|
||||
clearTimeout(timerID);
|
||||
Services.obs.removeObserver(this, aObsEvent);
|
||||
deferred.resolve();
|
||||
},
|
||||
|
||||
onError: function () {
|
||||
clearTimeout(timerID);
|
||||
Services.obs.removeObserver(this, aObsEvent);
|
||||
deferred.reject(new Error(aObsEvent + " event timeout"));
|
||||
},
|
||||
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
if (aTopic == aObsEvent) {
|
||||
this.onEvent();
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: function (aIID) {
|
||||
if (!aIID.equals(Ci.nsIObserver) &&
|
||||
!aIID.equals(Ci.nsISupportsWeakReference) &&
|
||||
!aIID.equals(Ci.nsISupports)) {
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
}
|
||||
|
||||
timerID = setTimeout(function wfo_canceller() {
|
||||
observeWatcher.onError();
|
||||
}, timeoutMs);
|
||||
|
||||
Services.obs.addObserver(observeWatcher, aObsEvent, true);
|
||||
return deferred.promise;
|
||||
|
||||
} catch (ex) {
|
||||
info(ex.message);
|
||||
}
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Native input synthesis helpers
|
||||
=============================================================================*/
|
||||
@ -246,6 +366,41 @@ function synthesizeNativeMouseMUp(aElement, aOffsetX, aOffsetY) {
|
||||
0x0040); // MOUSEEVENTF_MIDDLEUP
|
||||
}
|
||||
|
||||
/*
|
||||
* sendContextMenuClick - simulates a press-hold touch input event.
|
||||
*/
|
||||
function sendContextMenuClick(aWindow, aX, aY) {
|
||||
let utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
|
||||
utils.sendMouseEventToWindow("contextmenu", aX, aY, 2, 1, 0, true,
|
||||
1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH);
|
||||
}
|
||||
|
||||
function sendContextMenuClickToElement(aWindow, aElement, aX, aY) {
|
||||
let utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
let rect = aElement.getBoundingClientRect();
|
||||
utils.sendMouseEventToWindow("contextmenu", rect.left + aX, rect.top + aY, 2, 1, 0, true,
|
||||
1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH);
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
System utilities
|
||||
=============================================================================*/
|
||||
|
||||
/*
|
||||
* purgeEventQueue - purges the event queue on the calling thread.
|
||||
* Pumps latent in-process message manager events awaiting delivery.
|
||||
*/
|
||||
function purgeEventQueue() {
|
||||
let thread = Services.tm.currentThread;
|
||||
while (thread.hasPendingEvents()) {
|
||||
if (!thread.processNextEvent(true))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Test-running helpers
|
||||
=============================================================================*/
|
||||
|
BIN
browser/metro/base/tests/res/image01.png
Normal file
BIN
browser/metro/base/tests/res/image01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
@ -7,26 +7,12 @@
|
||||
|
||||
<!ENTITY back.label "Back">
|
||||
<!ENTITY forward.label "Forward">
|
||||
<!ENTITY reload.label "Reload">
|
||||
<!ENTITY stop.label "Stop">
|
||||
<!ENTITY go.label "Go">
|
||||
<!ENTITY star.label "Star">
|
||||
|
||||
<!ENTITY toggleTabsOnly.label "Always show tabs">
|
||||
<!ENTITY showTabs.label "Show Tabs">
|
||||
<!ENTITY newtab.label "New Tab">
|
||||
<!ENTITY closetab.label "Close Tab">
|
||||
<!ENTITY undoclosetab.label "Undo Close Tab">
|
||||
|
||||
<!ENTITY cut.label "Cut">
|
||||
<!ENTITY copy.label "Copy">
|
||||
<!ENTITY copyAll.label "Copy All">
|
||||
<!ENTITY copylink.label "Copy Link Location">
|
||||
<!ENTITY paste.label "Paste">
|
||||
<!ENTITY pasteAndGo.label "Paste & Go">
|
||||
<!ENTITY delete.label "Delete">
|
||||
<!ENTITY selectAll.label "Select All">
|
||||
|
||||
<!ENTITY appbarFindInPage.label "Find in Page">
|
||||
<!ENTITY appbarViewOnDesktop.label "View on Desktop">
|
||||
|
||||
@ -38,8 +24,6 @@
|
||||
<!ENTITY autocompleteResultsHeader.label "Your Results">
|
||||
<!ENTITY autocompleteSearchesHeader.label "Internet Searches">
|
||||
|
||||
<!ENTITY selectHelper.done "Done">
|
||||
|
||||
<!ENTITY downloadsHeader.label "Downloads">
|
||||
<!ENTITY downloadShowPage.label "Go to Page">
|
||||
<!ENTITY downloadShow2.label "Find">
|
||||
@ -76,26 +60,31 @@
|
||||
<!ENTITY consoleErrLine.label "Line:">
|
||||
<!ENTITY consoleErrColumn.label "Column:">
|
||||
|
||||
<!ENTITY contextOpenInNewTab.label "Open Link in New Tab">
|
||||
<!ENTITY contextViewInNewTab.label "View in New Tab">
|
||||
<!ENTITY contextSaveImage.label "Save Image">
|
||||
<!ENTITY contextSaveImageTo.label "Save Image To">
|
||||
<!ENTITY contextCopyLink.label "Copy Link">
|
||||
<!ENTITY contextCopyEmail.label "Copy Email Address">
|
||||
<!ENTITY contextCopyPhone.label "Copy Phone Number">
|
||||
<!ENTITY contextCopyImage.label "Copy Image">
|
||||
<!ENTITY contextShareLink.label "Share Link">
|
||||
<!ENTITY contextShareImage.label "Share Image">
|
||||
<!ENTITY contextBookmarkLink.label "Bookmark Link">
|
||||
<!ENTITY contextSaveVideo.label "Save Video">
|
||||
<!ENTITY contextSaveVideoTo.label "Save Video To">
|
||||
<!ENTITY contextShareVideo.label "Share Video">
|
||||
<!ENTITY contextPlayMedia.label "Play">
|
||||
<!ENTITY contextPauseMedia.label "Pause">
|
||||
<!ENTITY contextVideoTab.label "Open In New Tab">
|
||||
<!ENTITY contextEditBookmark.label "Edit">
|
||||
<!ENTITY contextRemoveBookmark.label "Remove">
|
||||
<!ENTITY contextShortcutBookmark.label "Add to Home Screen">
|
||||
<!-- TEXT CONTEXT MENU -->
|
||||
<!ENTITY contextTextCopy.label "Copy">
|
||||
<!ENTITY contextTextPaste.label "Paste">
|
||||
<!-- unique item that is only added to the url bar context menu -->
|
||||
<!ENTITY contextTextPasteAndGo.label "Paste & go">
|
||||
<!ENTITY contextTextSelect.label "Select">
|
||||
<!ENTITY contextTextSelectAll.label "Select all">
|
||||
|
||||
<!-- LINK CONTEXT MENU -->
|
||||
<!ENTITY contextOpenLinkTab.label "Open link in new tab">
|
||||
<!ENTITY contextCopyLinkHref.label "Copy link">
|
||||
<!ENTITY contextBookmarkLinkHref.label "Bookmark link">
|
||||
|
||||
<!-- IMAGE CONTEXT MENU -->
|
||||
<!-- l10n: contextSaveImageLib saves an image to the users "pictures library"
|
||||
(Explorer -> left hand side navigation ppane -> Libraries -> Pictures) -->
|
||||
<!ENTITY contextSaveImageLib.label "Save to picture library">
|
||||
<!ENTITY contextCopyImage.label "Copy image">
|
||||
<!ENTITY contextCopyImageLocation.label "Copy image location">
|
||||
<!ENTITY contextOpenImageTab.label "Open image in new tab">
|
||||
|
||||
<!-- VIDEO CONTEXT MENU -->
|
||||
<!ENTITY contextSaveVideoLib.label "Save to video library">
|
||||
<!ENTITY contextCopyVideoLocation.label "Copy video location">
|
||||
<!ENTITY contextOpenVideoTab.label "Open video in new tab">
|
||||
|
||||
<!ENTITY pageactions.password.forget "Forget Password">
|
||||
<!ENTITY pageactions.reset "Clear Site Preferences">
|
||||
|
@ -10,6 +10,9 @@ browser.search.order.1=Bing
|
||||
browser.search.order.2=Google
|
||||
browser.search.order.3=Yahoo
|
||||
|
||||
# l10n: search context menu item text will be: |Search (browser.search.defaultenginename) for ".."
|
||||
browser.search.contextTextSearchLabel=Search %S for ".."
|
||||
|
||||
# Settings Charms
|
||||
aboutCharm1=About
|
||||
optionsCharm=Options
|
||||
@ -135,5 +138,6 @@ browser.menu.showCharacterEncoding=false
|
||||
# values for charsets that the user can select from in the Character Encoding menu.
|
||||
intl.charsetmenu.browser.static=iso-8859-1,utf-8,x-gbk,big5,iso-2022-jp,shift_jis,euc-jp
|
||||
|
||||
#Text Selection
|
||||
# Selection alerts
|
||||
selectionHelper.textCopied=Text copied to clipboard
|
||||
selectionHelper.linkCopied=Link copied to clipboard
|
||||
|
@ -22,7 +22,7 @@ pref("metro.debug.selection.dumpRanges", false);
|
||||
pref("metro.debug.selection.dumpEvents", false);
|
||||
|
||||
// Form helper options: 0 = disabled, 1 = enabled, 2 = dynamic depending on screen size
|
||||
pref("formhelper.mode", 1);
|
||||
pref("formhelper.mode", 0);
|
||||
// Auto zoom to form elements when they take focus
|
||||
pref("formhelper.autozoom", true);
|
||||
// Auto zoom to the caret
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <strsafe.h>
|
||||
#include <io.h>
|
||||
#include <shellapi.h>
|
||||
#include <wininet.h>
|
||||
|
||||
#ifdef SHOW_CONSOLE
|
||||
#define DEBUG_DELAY_SHUTDOWN 1
|
||||
@ -438,6 +439,46 @@ bool CExecuteCommandVerb::IsTargetBrowser()
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
const FORMATETC kPlainTextFormat =
|
||||
{CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
const FORMATETC kPlainTextWFormat =
|
||||
{CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
}
|
||||
|
||||
bool HasPlainText(IDataObject* aDataObj) {
|
||||
return SUCCEEDED(aDataObj->QueryGetData((FORMATETC*)&kPlainTextWFormat)) ||
|
||||
SUCCEEDED(aDataObj->QueryGetData((FORMATETC*)&kPlainTextFormat));
|
||||
}
|
||||
|
||||
bool GetPlainText(IDataObject* aDataObj, CStringW& cstrText)
|
||||
{
|
||||
if (!HasPlainText(aDataObj))
|
||||
return false;
|
||||
|
||||
STGMEDIUM store;
|
||||
|
||||
// unicode text
|
||||
if (SUCCEEDED(aDataObj->GetData((FORMATETC*)&kPlainTextWFormat, &store))) {
|
||||
// makes a copy
|
||||
cstrText = static_cast<LPCWSTR>(GlobalLock(store.hGlobal));
|
||||
GlobalUnlock(store.hGlobal);
|
||||
ReleaseStgMedium(&store);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ascii text
|
||||
if (SUCCEEDED(aDataObj->GetData((FORMATETC*)&kPlainTextFormat, &store))) {
|
||||
// makes a copy
|
||||
cstrText = static_cast<char*>(GlobalLock(store.hGlobal));
|
||||
GlobalUnlock(store.hGlobal);
|
||||
ReleaseStgMedium(&store);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates the current target based on the contents of
|
||||
* a shell item.
|
||||
@ -447,15 +488,42 @@ bool CExecuteCommandVerb::SetTargetPath(IShellItem* aItem)
|
||||
if (!aItem)
|
||||
return false;
|
||||
|
||||
CString cstrText;
|
||||
CComPtr<IDataObject> object;
|
||||
// Check the underlying data object first to insure we get
|
||||
// absolute uri. See chromium bug 157184.
|
||||
if (SUCCEEDED(aItem->BindToHandler(NULL, BHID_DataObject,
|
||||
IID_IDataObject,
|
||||
reinterpret_cast<void**>(&object))) &&
|
||||
GetPlainText(object, cstrText)) {
|
||||
wchar_t scheme[16];
|
||||
URL_COMPONENTS components = {0};
|
||||
components.lpszScheme = scheme;
|
||||
components.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
|
||||
components.dwStructSize = sizeof(components);
|
||||
// note, more advanced use may have issues with paths with spaces.
|
||||
if (!InternetCrackUrlW(cstrText, 0, 0, &components)) {
|
||||
Log(L"Failed to identify object text '%s'", cstrText);
|
||||
return false;
|
||||
}
|
||||
|
||||
mTargetIsFileSystemLink = (components.nScheme == INTERNET_SCHEME_FILE);
|
||||
mTarget = cstrText;
|
||||
return true;
|
||||
}
|
||||
|
||||
Log(L"No data object or data object has no text.");
|
||||
|
||||
// Use the shell item display name
|
||||
LPWSTR str = NULL;
|
||||
mTargetIsFileSystemLink = true;
|
||||
if (FAILED(aItem->GetDisplayName(SIGDN_FILESYSPATH, &str))) {
|
||||
mTargetIsFileSystemLink = false;
|
||||
if (FAILED(aItem->GetDisplayName(SIGDN_URL, &str))) {
|
||||
Log(L"Failed to get parameter string.");
|
||||
return false;
|
||||
}
|
||||
mTargetIsFileSystemLink = false;
|
||||
}
|
||||
|
||||
mTarget = str;
|
||||
CoTaskMemFree(str);
|
||||
return true;
|
||||
@ -477,7 +545,9 @@ void CExecuteCommandVerb::LaunchDesktopBrowser()
|
||||
CStringW params;
|
||||
if (!IsTargetBrowser()) {
|
||||
params += "-url ";
|
||||
params += "\"";
|
||||
params += mTarget;
|
||||
params += "\"";
|
||||
}
|
||||
|
||||
Log(L"Desktop Launch: verb:%s exe:%s params:%s", mVerb, browserPath, params);
|
||||
|
@ -35,6 +35,7 @@ OS_LIBS = \
|
||||
shlwapi.lib \
|
||||
propsys.lib \
|
||||
advapi32.lib \
|
||||
wininet.lib \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -DUNICODE -D_UNICODE -DNS_NO_XPCOM
|
||||
|
@ -125,7 +125,7 @@ select[size][multiple],
|
||||
|
||||
/* For both mouse and touch, single-selects are handled by the SelectHelper popup.
|
||||
* Suppress mouse events on the popup itself. See also ../base/content/cursor.css */
|
||||
select[size=1] :-moz-any(option, optgroup),
|
||||
select[size="1"] :-moz-any(option, optgroup),
|
||||
select:not([size]):not([multiple]) :-moz-any(option, optgroup) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ from automationutils import getDebuggerInfo, addCommonOptions
|
||||
|
||||
PORT = 8888
|
||||
PROFILE_DIRECTORY = os.path.abspath(os.path.join(SCRIPT_DIR, "./pgoprofile"))
|
||||
MOZ_JAR_LOG_DIR = os.path.abspath(os.getenv("JARLOG_DIR"))
|
||||
MOZ_JAR_LOG_FILE = os.path.abspath(os.getenv("JARLOG_FILE"))
|
||||
os.chdir(SCRIPT_DIR)
|
||||
|
||||
class EasyServer(SocketServer.TCPServer):
|
||||
@ -47,7 +47,7 @@ if __name__ == '__main__':
|
||||
automation.initializeProfile(PROFILE_DIRECTORY)
|
||||
browserEnv = automation.environment()
|
||||
browserEnv["XPCOM_DEBUG_BREAK"] = "warn"
|
||||
browserEnv["MOZ_JAR_LOG_DIR"] = MOZ_JAR_LOG_DIR
|
||||
browserEnv["MOZ_JAR_LOG_FILE"] = MOZ_JAR_LOG_FILE
|
||||
|
||||
url = "http://localhost:%d/index.html" % PORT
|
||||
appPath = os.path.join(SCRIPT_DIR, automation.DEFAULT_APP)
|
||||
|
@ -203,7 +203,8 @@ endif
|
||||
profiledbuild::
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1 MOZ_PGO_INSTRUMENTED=1
|
||||
$(MAKE) -C $(PGO_OBJDIR) package MOZ_PGO_INSTRUMENTED=1 MOZ_INTERNAL_SIGNING_FORMAT= MOZ_EXTERNAL_SIGNING_FORMAT=
|
||||
MOZ_PGO_INSTRUMENTED=1 OBJDIR=${PGO_OBJDIR} JARLOG_DIR=${PGO_OBJDIR}/jarlog/en-US $(PROFILE_GEN_SCRIPT)
|
||||
rm -f ${PGO_OBJDIR}/jarlog/en-US.log
|
||||
MOZ_PGO_INSTRUMENTED=1 OBJDIR=${PGO_OBJDIR} JARLOG_FILE=${PGO_OBJDIR}/jarlog/en-US.log $(PROFILE_GEN_SCRIPT)
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1
|
||||
|
||||
|
@ -1207,17 +1207,9 @@ ifneq (,$(DIST_SUBDIR)$(XPI_NAME)$(LIBXUL_SDK))
|
||||
PREF_DIR = defaults/preferences
|
||||
endif
|
||||
|
||||
ifneq ($(PREF_JS_EXPORTS),)
|
||||
# on win32, pref files need CRLF line endings... see bug 206029
|
||||
ifeq (WINNT,$(OS_ARCH))
|
||||
PREF_PPFLAGS = --line-endings=crlf
|
||||
endif
|
||||
|
||||
ifndef NO_DIST_INSTALL
|
||||
PREF_JS_EXPORTS_PATH := $(FINAL_TARGET)/$(PREF_DIR)
|
||||
PREF_JS_EXPORTS_FLAGS := $(PREF_PPFLAGS)
|
||||
PP_TARGETS += PREF_JS_EXPORTS
|
||||
endif
|
||||
PREF_PPFLAGS += --line-endings=crlf
|
||||
endif
|
||||
|
||||
# Set a flag that can be used in pref files to disable features if
|
||||
@ -1226,6 +1218,14 @@ ifeq (,$(findstring a,$(GRE_MILESTONE)))
|
||||
PREF_PPFLAGS += -DRELEASE_BUILD
|
||||
endif
|
||||
|
||||
ifneq ($(PREF_JS_EXPORTS),)
|
||||
ifndef NO_DIST_INSTALL
|
||||
PREF_JS_EXPORTS_PATH := $(FINAL_TARGET)/$(PREF_DIR)
|
||||
PREF_JS_EXPORTS_FLAGS := $(PREF_PPFLAGS)
|
||||
PP_TARGETS += PREF_JS_EXPORTS
|
||||
endif
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Copy each element of AUTOCFG_JS_EXPORTS to $(FINAL_TARGET)/defaults/autoconfig
|
||||
|
||||
|
@ -21,27 +21,6 @@ interface nsIDOMBlob;
|
||||
#include "jsapi.h"
|
||||
%}
|
||||
|
||||
/**
|
||||
* Parameters for instantiating an XMLHttpRequest. They are passed as an
|
||||
* optional argument to the constructor:
|
||||
*
|
||||
* new XMLHttpRequest({anon: true, system: true});
|
||||
*
|
||||
*/
|
||||
dictionary XMLHttpRequestParameters
|
||||
{
|
||||
/**
|
||||
* If true, the request will be sent without cookie and authentication
|
||||
* headers.
|
||||
*/
|
||||
boolean mozAnon;
|
||||
|
||||
/**
|
||||
* If true, the same origin policy will not be enforced on the request.
|
||||
*/
|
||||
boolean mozSystem;
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(a137d5e6-81e2-4fa3-a791-26459df723ff)]
|
||||
interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
|
||||
// event handler attributes
|
||||
|
@ -238,13 +238,18 @@ DoesNotParticipateInAutoDirection(const Element* aElement)
|
||||
return (!aElement->IsHTML() ||
|
||||
nodeInfo->Equals(nsGkAtoms::script) ||
|
||||
nodeInfo->Equals(nsGkAtoms::style) ||
|
||||
nodeInfo->Equals(nsGkAtoms::textarea));
|
||||
nodeInfo->Equals(nsGkAtoms::textarea) ||
|
||||
aElement->IsInAnonymousSubtree());
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsBdiWithoutDirAuto(const Element* aElement)
|
||||
{
|
||||
return aElement->IsHTML(nsGkAtoms::bdi) && !aElement->HasDirAuto();
|
||||
// We are testing for bdi elements without explicit dir="auto", so we can't
|
||||
// use the HasDirAuto() flag, since that will return true for bdi element with
|
||||
// no dir attribute or an invalid dir attribute
|
||||
return (aElement->IsHTML(nsGkAtoms::bdi) &&
|
||||
(!aElement->HasValidDir() || aElement->HasFixedDir()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1111,7 +1111,8 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
}
|
||||
|
||||
bool
|
||||
nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
|
||||
nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope,
|
||||
const nsACString& aID)
|
||||
{
|
||||
|
||||
nsCOMPtr<nsIJSRuntimeService> runtimeSvc =
|
||||
@ -1151,6 +1152,11 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
JS_SetGlobalObject(cx, global);
|
||||
|
||||
// Set the location information for the new global, so that tools like
|
||||
// about:memory may use that information.
|
||||
xpc::SetLocationForGlobal(global, aID);
|
||||
|
||||
DidCreateCx();
|
||||
return true;
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ protected:
|
||||
enum CacheFailedBehavior { EXECUTE_IF_CANT_CACHE, DONT_EXECUTE };
|
||||
void TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
CacheFailedBehavior aBehavior = DONT_EXECUTE);
|
||||
bool InitTabChildGlobalInternal(nsISupports* aScope);
|
||||
bool InitTabChildGlobalInternal(nsISupports* aScope, const nsACString& aID);
|
||||
static void Traverse(nsFrameScriptExecutor *tmp,
|
||||
nsCycleCollectionTraversalCallback &cb);
|
||||
static void Unlink(nsFrameScriptExecutor* aTmp);
|
||||
|
@ -38,6 +38,7 @@ GK_ATOM(mozallowfullscreen, "mozallowfullscreen")
|
||||
GK_ATOM(moztype, "_moz-type")
|
||||
GK_ATOM(mozdirty, "_moz_dirty")
|
||||
GK_ATOM(mozdisallowselectionprint, "mozdisallowselectionprint")
|
||||
GK_ATOM(moznomarginboxes, "moznomarginboxes")
|
||||
GK_ATOM(mozdonotsend, "moz-do-not-send")
|
||||
GK_ATOM(mozeditorbogusnode, "_moz_editor_bogus_node")
|
||||
GK_ATOM(mozgeneratedcontentbefore, "_moz_generated_content_before")
|
||||
|
@ -143,15 +143,6 @@ nsInProcessTabChildGlobal::Init()
|
||||
nullptr,
|
||||
mCx,
|
||||
mozilla::dom::ipc::MM_CHILD);
|
||||
|
||||
// Set the location information for the new global, so that tools like
|
||||
// about:memory may use that information.
|
||||
JSObject *global;
|
||||
nsIURI* docURI = mOwner->OwnerDoc()->GetDocumentURI();
|
||||
if (mGlobal && NS_SUCCEEDED(mGlobal->GetJSObject(&global)) && docURI) {
|
||||
xpc::SetLocationForGlobal(global, docURI);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -307,10 +298,18 @@ nsInProcessTabChildGlobal::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
nsresult
|
||||
nsInProcessTabChildGlobal::InitTabChildGlobal()
|
||||
{
|
||||
|
||||
nsAutoCString id;
|
||||
id.AssignLiteral("inProcessTabChildGlobal");
|
||||
nsIURI* uri = mOwner->OwnerDoc()->GetDocumentURI();
|
||||
if (uri) {
|
||||
nsAutoCString u;
|
||||
uri->GetSpec(u);
|
||||
id.AppendLiteral("?ownedBy=");
|
||||
id.Append(u);
|
||||
}
|
||||
nsISupports* scopeSupports =
|
||||
NS_ISUPPORTS_CAST(nsIDOMEventTarget*, this);
|
||||
NS_ENSURE_STATE(InitTabChildGlobalInternal(scopeSupports));
|
||||
NS_ENSURE_STATE(InitTabChildGlobalInternal(scopeSupports, id));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -470,43 +470,6 @@ nsXMLHttpRequest::Init(nsIPrincipal* aPrincipal,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This Initialize method is called from XPConnect via nsIJSNativeInitializer.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||
uint32_t argc, jsval *argv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> owner = do_QueryInterface(aOwner);
|
||||
if (!owner) {
|
||||
NS_WARNING("Unexpected nsIJSNativeInitializer owner");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This XHR object is bound to a |window|,
|
||||
// so re-set principal and script context.
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(aOwner);
|
||||
NS_ENSURE_STATE(scriptPrincipal);
|
||||
|
||||
Construct(scriptPrincipal->GetPrincipal(), owner);
|
||||
if (argc) {
|
||||
nsresult rv = InitParameters(cx, argv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLHttpRequest::InitParameters(JSContext* aCx, const jsval* aParams)
|
||||
{
|
||||
mozilla::idl::XMLHttpRequestParameters params;
|
||||
nsresult rv = params.Init(aCx, aParams);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
InitParameters(params.mozAnon, params.mozSystem);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLHttpRequest::InitParameters(bool aAnon, bool aSystem)
|
||||
{
|
||||
@ -638,7 +601,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISizeOfEventTarget)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsIDOMLSProgressEvent.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
@ -124,7 +123,6 @@ class nsXMLHttpRequest : public nsXHREventTarget,
|
||||
public nsIProgressEventSink,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIJSNativeInitializer,
|
||||
public nsITimerCallback,
|
||||
public nsISizeOfEventTarget
|
||||
{
|
||||
@ -193,8 +191,6 @@ public:
|
||||
mBaseURI = aBaseURI;
|
||||
}
|
||||
|
||||
// Initialize XMLHttpRequestParameter object.
|
||||
nsresult InitParameters(JSContext* aCx, const jsval* aParams);
|
||||
void InitParameters(bool aAnon, bool aSystem);
|
||||
|
||||
void SetParameters(bool aAnon, bool aSystem)
|
||||
@ -228,10 +224,6 @@ public:
|
||||
// nsITimerCallback
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||
uint32_t argc, jsval* argv);
|
||||
|
||||
// nsISizeOfEventTarget
|
||||
virtual size_t
|
||||
SizeOfEventTargetIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
|
@ -613,15 +613,6 @@ MOCHITEST_FILES_C= \
|
||||
test_mixed_content_blocker_bug803225.html \
|
||||
file_mixed_content_main_bug803225.html \
|
||||
file_mixed_content_main_bug803225_websocket_wsh.py \
|
||||
file_bug822367_1.html \
|
||||
file_bug822367_1.js \
|
||||
file_bug822367_2.html \
|
||||
file_bug822367_3.html \
|
||||
file_bug822367_4.html \
|
||||
file_bug822367_4.js \
|
||||
file_bug822367_4B.html \
|
||||
file_bug822367_5.html \
|
||||
file_bug822367_6.html \
|
||||
bug803225_test_mailto.html \
|
||||
test_bug789856.html \
|
||||
file_bug804395.jar \
|
||||
|
@ -57,7 +57,4 @@ MOCHITEST_CHROME_FILES = \
|
||||
frame_bug814638.xul \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_BROWSER_FILES = \
|
||||
browser_bug822367.js \
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -1 +0,0 @@
|
||||
document.location = "https://example.com/tests/content/base/test/file_bug822367_4B.html";
|
@ -50,9 +50,10 @@
|
||||
#include "Layers.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gl;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -109,6 +110,7 @@ WebGLContext::WebGLContext()
|
||||
|
||||
mGeneration = 0;
|
||||
mInvalidated = false;
|
||||
mShouldPresent = true;
|
||||
mResetLayer = true;
|
||||
mOptionsFrozen = false;
|
||||
|
||||
@ -156,7 +158,6 @@ WebGLContext::WebGLContext()
|
||||
|
||||
mScissorTestEnabled = 0;
|
||||
mDitherEnabled = 1;
|
||||
mBackbufferClearingStatus = BackbufferClearingStatus::NotClearedSinceLastPresented;
|
||||
|
||||
// initialize some GL values: we're going to get them from the GL and use them as the sizes of arrays,
|
||||
// so in case glGetIntegerv leaves them uninitialized because of a GL bug, we would have very weird crashes.
|
||||
@ -193,6 +194,8 @@ WebGLContext::WebGLContext()
|
||||
|
||||
mMinInUseAttribArrayLengthCached = false;
|
||||
mMinInUseAttribArrayLength = 0;
|
||||
|
||||
mIsScreenCleared = false;
|
||||
}
|
||||
|
||||
WebGLContext::~WebGLContext()
|
||||
@ -382,11 +385,13 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
// It's unlikely that we'll get a proper-sized context if we recreate if we didn't on resize
|
||||
|
||||
// everything's good, we're done here
|
||||
mWidth = gl->OffscreenActualSize().width;
|
||||
mHeight = gl->OffscreenActualSize().height;
|
||||
mWidth = gl->OffscreenSize().width;
|
||||
mHeight = gl->OffscreenSize().height;
|
||||
mResetLayer = true;
|
||||
|
||||
ScopedBindFramebuffer autoFB(gl, 0);
|
||||
gl->ClearSafely();
|
||||
mShouldPresent = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -436,43 +441,19 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
if (!(mGeneration + 1).isValid())
|
||||
return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
|
||||
|
||||
gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
|
||||
if (mOptions.depth) {
|
||||
format.depth = 24;
|
||||
format.minDepth = 16;
|
||||
}
|
||||
SurfaceCaps caps;
|
||||
|
||||
if (mOptions.stencil) {
|
||||
format.stencil = 8;
|
||||
format.minStencil = 8;
|
||||
}
|
||||
|
||||
if (!mOptions.alpha) {
|
||||
format.alpha = 0;
|
||||
format.minAlpha = 0;
|
||||
}
|
||||
caps.color = true;
|
||||
caps.alpha = mOptions.alpha;
|
||||
caps.depth = mOptions.depth;
|
||||
caps.stencil = mOptions.stencil;
|
||||
|
||||
// we should really have this behind a
|
||||
// |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but
|
||||
// for now it's just behind a pref for testing/evaluation.
|
||||
if (prefer16bit) {
|
||||
// Select 4444 or 565 on 16-bit displays; we won't/shouldn't
|
||||
// hit this on the desktop, but let mobile know we're ok with
|
||||
// it. Note that we don't just set this to 4440 if no alpha,
|
||||
// because that might cause us to choose 4444 anyway and we
|
||||
// don't want that.
|
||||
if (mOptions.alpha) {
|
||||
format.red = 4;
|
||||
format.green = 4;
|
||||
format.blue = 4;
|
||||
format.alpha = 4;
|
||||
} else {
|
||||
format.red = 5;
|
||||
format.green = 6;
|
||||
format.blue = 5;
|
||||
format.alpha = 0;
|
||||
}
|
||||
}
|
||||
caps.bpp16 = prefer16bit;
|
||||
|
||||
caps.preserve = mOptions.preserveDrawingBuffer;
|
||||
|
||||
bool forceMSAA =
|
||||
Preferences::GetBool("webgl.msaa-force", false);
|
||||
@ -483,8 +464,7 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
gfxInfo &&
|
||||
NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_MSAA, &status))) {
|
||||
if (status == nsIGfxInfo::FEATURE_NO_INFO || forceMSAA) {
|
||||
uint32_t msaaLevel = Preferences::GetUint("webgl.msaa-level", 2);
|
||||
format.samples = msaaLevel*msaaLevel;
|
||||
caps.antialias = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -525,10 +505,12 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
}
|
||||
#endif
|
||||
|
||||
gfxIntSize size(width, height);
|
||||
|
||||
#ifdef XP_WIN
|
||||
// if we want EGL, try it now
|
||||
if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
|
||||
gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
|
||||
gl = gl::GLContextProviderEGL::CreateOffscreen(size, caps);
|
||||
if (!gl || !InitAndValidateGL()) {
|
||||
GenerateWarning("Error during ANGLE OpenGL ES initialization");
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -541,8 +523,7 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
GLContext::ContextFlags flag = useMesaLlvmPipe
|
||||
? GLContext::ContextFlagsMesaLLVMPipe
|
||||
: GLContext::ContextFlagsNone;
|
||||
gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height),
|
||||
format, flag);
|
||||
gl = gl::GLContextProvider::CreateOffscreen(size, caps, flag);
|
||||
if (gl && !InitAndValidateGL()) {
|
||||
GenerateWarning("Error during %s initialization",
|
||||
useMesaLlvmPipe ? "Mesa LLVMpipe" : "OpenGL");
|
||||
@ -581,7 +562,7 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
|
||||
// Make sure that we clear this out, otherwise
|
||||
// we'll end up displaying random memory
|
||||
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, gl->GetOffscreenFBO());
|
||||
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
|
||||
gl->fViewport(0, 0, mWidth, mHeight);
|
||||
gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@ -590,6 +571,15 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
|
||||
gl->ClearSafely();
|
||||
|
||||
mShouldPresent = true;
|
||||
|
||||
MOZ_ASSERT(gl->Caps().color == caps.color);
|
||||
MOZ_ASSERT(gl->Caps().alpha == caps.alpha);
|
||||
MOZ_ASSERT(gl->Caps().depth == caps.depth || !gl->Caps().depth);
|
||||
MOZ_ASSERT(gl->Caps().stencil == caps.stencil || !gl->Caps().stencil);
|
||||
MOZ_ASSERT(gl->Caps().antialias == caps.antialias || !gl->Caps().antialias);
|
||||
MOZ_ASSERT(gl->Caps().preserve == caps.preserve);
|
||||
|
||||
reporter.SetSuccessful();
|
||||
return NS_OK;
|
||||
}
|
||||
@ -803,25 +793,39 @@ namespace mozilla {
|
||||
class WebGLContextUserData : public LayerUserData {
|
||||
public:
|
||||
WebGLContextUserData(HTMLCanvasElement *aContent)
|
||||
: mContent(aContent) {}
|
||||
: mContent(aContent)
|
||||
{}
|
||||
|
||||
/** DidTransactionCallback gets called by the Layers code everytime the WebGL canvas gets composite,
|
||||
* so it really is the right place to put actions that have to be performed upon compositing
|
||||
*/
|
||||
static void DidTransactionCallback(void* aData)
|
||||
{
|
||||
WebGLContextUserData *userdata = static_cast<WebGLContextUserData*>(aData);
|
||||
HTMLCanvasElement *canvas = userdata->mContent;
|
||||
WebGLContext *context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
|
||||
/* PreTransactionCallback gets called by the Layers code every time the
|
||||
* WebGL canvas is going to be composited.
|
||||
*/
|
||||
static void PreTransactionCallback(void* data)
|
||||
{
|
||||
WebGLContextUserData* userdata = static_cast<WebGLContextUserData*>(data);
|
||||
HTMLCanvasElement* canvas = userdata->mContent;
|
||||
WebGLContext* context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
|
||||
|
||||
context->mBackbufferClearingStatus = BackbufferClearingStatus::NotClearedSinceLastPresented;
|
||||
canvas->MarkContextClean();
|
||||
// Present our screenbuffer, if needed.
|
||||
context->PresentScreenBuffer();
|
||||
}
|
||||
|
||||
context->UpdateLastUseIndex();
|
||||
}
|
||||
/** DidTransactionCallback gets called by the Layers code everytime the WebGL canvas gets composite,
|
||||
* so it really is the right place to put actions that have to be performed upon compositing
|
||||
*/
|
||||
static void DidTransactionCallback(void* aData)
|
||||
{
|
||||
WebGLContextUserData *userdata = static_cast<WebGLContextUserData*>(aData);
|
||||
HTMLCanvasElement *canvas = userdata->mContent;
|
||||
WebGLContext *context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
|
||||
|
||||
// Mark ourselves as no longer invalidated.
|
||||
context->MarkContextClean();
|
||||
|
||||
context->UpdateLastUseIndex();
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<HTMLCanvasElement> mContent;
|
||||
nsRefPtr<HTMLCanvasElement> mContent;
|
||||
};
|
||||
|
||||
} // end namespace mozilla
|
||||
@ -862,28 +866,18 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
userData = new WebGLContextUserData(mCanvasElement);
|
||||
canvasLayer->SetDidTransactionCallback(
|
||||
WebGLContextUserData::DidTransactionCallback, userData);
|
||||
canvasLayer->SetPreTransactionCallback(
|
||||
WebGLContextUserData::PreTransactionCallback, userData);
|
||||
}
|
||||
canvasLayer->SetUserData(&gWebGLLayerUserData, userData);
|
||||
|
||||
CanvasLayer::Data data;
|
||||
|
||||
// the gl context may either provide a native PBuffer, in which case we want to initialize
|
||||
// data with the gl context directly, or may provide a surface to which it renders (this is the case
|
||||
// of OSMesa contexts), in which case we want to initialize data with that surface.
|
||||
|
||||
void* native_surface = gl->GetNativeData(gl::GLContext::NativeImageSurface);
|
||||
|
||||
if (native_surface) {
|
||||
data.mSurface = static_cast<gfxASurface*>(native_surface);
|
||||
} else {
|
||||
data.mGLContext = gl.get();
|
||||
}
|
||||
|
||||
data.mGLContext = gl;
|
||||
data.mSize = nsIntSize(mWidth, mHeight);
|
||||
data.mGLBufferIsPremultiplied = mOptions.premultipliedAlpha ? true : false;
|
||||
data.mIsGLAlphaPremult = IsPremultAlpha();
|
||||
|
||||
canvasLayer->Initialize(data);
|
||||
uint32_t flags = gl->CreationFormat().alpha == 0 ? Layer::CONTENT_OPAQUE : 0;
|
||||
uint32_t flags = gl->Caps().alpha ? 0 : Layer::CONTENT_OPAQUE;
|
||||
canvasLayer->SetContentFlags(flags);
|
||||
canvasLayer->Updated();
|
||||
|
||||
@ -901,11 +895,12 @@ WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializ
|
||||
|
||||
dom::WebGLContextAttributes& result = retval.SetValue();
|
||||
|
||||
gl::ContextFormat cf = gl->ActualFormat();
|
||||
result.mAlpha = cf.alpha > 0;
|
||||
result.mDepth = cf.depth > 0;
|
||||
result.mStencil = cf.stencil > 0;
|
||||
result.mAntialias = cf.samples > 1;
|
||||
const PixelBufferFormat& format = gl->GetPixelFormat();
|
||||
|
||||
result.mAlpha = format.alpha > 0;
|
||||
result.mDepth = format.depth > 0;
|
||||
result.mStencil = format.stencil > 0;
|
||||
result.mAntialias = format.samples > 1;
|
||||
result.mPremultipliedAlpha = mOptions.premultipliedAlpha;
|
||||
result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer;
|
||||
}
|
||||
@ -1109,7 +1104,23 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntRect& viewportRect)
|
||||
WebGLContext::ClearScreen()
|
||||
{
|
||||
MakeContextCurrent();
|
||||
ScopedBindFramebuffer autoFB(gl, 0);
|
||||
|
||||
GLbitfield clearMask = LOCAL_GL_COLOR_BUFFER_BIT;
|
||||
if (mOptions.depth)
|
||||
clearMask |= LOCAL_GL_DEPTH_BUFFER_BIT;
|
||||
if (mOptions.stencil)
|
||||
clearMask |= LOCAL_GL_STENCIL_BUFFER_BIT;
|
||||
|
||||
ForceClearFramebufferWithDefaultValues(clearMask);
|
||||
mIsScreenCleared = true;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield mask)
|
||||
{
|
||||
MakeContextCurrent();
|
||||
|
||||
@ -1117,16 +1128,71 @@ WebGLContext::ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntR
|
||||
bool initializeDepthBuffer = 0 != (mask & LOCAL_GL_DEPTH_BUFFER_BIT);
|
||||
bool initializeStencilBuffer = 0 != (mask & LOCAL_GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
// fun GL fact: no need to worry about the viewport here, glViewport is just setting up a coordinates transformation,
|
||||
// it doesn't affect glClear at all
|
||||
// Fun GL fact: No need to worry about the viewport here, glViewport is just
|
||||
// setting up a coordinates transformation, it doesn't affect glClear at all.
|
||||
|
||||
// prepare GL state for clearing
|
||||
#ifdef DEBUG
|
||||
// Scope to hide our variables.
|
||||
{
|
||||
// Sanity-check that all our state is set properly. Otherwise, when we
|
||||
// reset out state to what we *think* it is, we'll get it wrong.
|
||||
|
||||
// Dither shouldn't matter when we're clearing to {0,0,0,0}.
|
||||
MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled);
|
||||
|
||||
realGLboolean colorWriteMask[4] = {2, 2, 2, 2};
|
||||
GLfloat colorClearValue[4] = {-1.0f, -1.0f, -1.0f, -1.0f};
|
||||
|
||||
gl->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorWriteMask);
|
||||
gl->fGetFloatv(LOCAL_GL_COLOR_CLEAR_VALUE, colorClearValue);
|
||||
|
||||
MOZ_ASSERT(colorWriteMask[0] == mColorWriteMask[0] &&
|
||||
colorWriteMask[1] == mColorWriteMask[1] &&
|
||||
colorWriteMask[2] == mColorWriteMask[2] &&
|
||||
colorWriteMask[3] == mColorWriteMask[3]);
|
||||
MOZ_ASSERT(colorClearValue[0] == mColorClearValue[0] &&
|
||||
colorClearValue[1] == mColorClearValue[1] &&
|
||||
colorClearValue[2] == mColorClearValue[2] &&
|
||||
colorClearValue[3] == mColorClearValue[3]);
|
||||
|
||||
|
||||
realGLboolean depthWriteMask = 2;
|
||||
GLfloat depthClearValue = -1.0f;
|
||||
|
||||
gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask);
|
||||
gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
|
||||
|
||||
MOZ_ASSERT(depthWriteMask == mDepthWriteMask);
|
||||
MOZ_ASSERT(depthClearValue == mDepthClearValue);
|
||||
|
||||
|
||||
GLuint stencilWriteMaskFront = 0xdeadbad1;
|
||||
GLuint stencilWriteMaskBack = 0xdeadbad1;
|
||||
GLuint stencilClearValue = 0xdeadbad1;
|
||||
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_WRITEMASK, &stencilWriteMaskFront);
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &stencilWriteMaskBack);
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_CLEAR_VALUE, &stencilClearValue);
|
||||
|
||||
GLuint stencilBits = 0;
|
||||
gl->GetUIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
|
||||
GLuint stencilMask = (GLuint(1) << stencilBits) - 1;
|
||||
|
||||
MOZ_ASSERT( ( stencilWriteMaskFront & stencilMask) ==
|
||||
(mStencilWriteMaskFront & stencilMask) );
|
||||
MOZ_ASSERT( ( stencilWriteMaskBack & stencilMask) ==
|
||||
(mStencilWriteMaskBack & stencilMask) );
|
||||
MOZ_ASSERT( ( stencilClearValue & stencilMask) ==
|
||||
(mStencilClearValue & stencilMask) );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Prepare GL state for clearing.
|
||||
gl->fDisable(LOCAL_GL_SCISSOR_TEST);
|
||||
gl->fDisable(LOCAL_GL_DITHER);
|
||||
|
||||
if (initializeColorBuffer) {
|
||||
gl->fColorMask(1, 1, 1, 1);
|
||||
gl->fClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
if (initializeDepthBuffer) {
|
||||
@ -1135,14 +1201,21 @@ WebGLContext::ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntR
|
||||
}
|
||||
|
||||
if (initializeStencilBuffer) {
|
||||
gl->fStencilMask(0xffffffff);
|
||||
// "The clear operation always uses the front stencil write mask
|
||||
// when clearing the stencil buffer."
|
||||
gl->fStencilMaskSeparate(LOCAL_GL_FRONT, 0xffffffff);
|
||||
gl->fStencilMaskSeparate(LOCAL_GL_BACK, 0xffffffff);
|
||||
gl->fClearStencil(0);
|
||||
}
|
||||
|
||||
// do clear
|
||||
// Do the clear!
|
||||
gl->fClear(mask);
|
||||
|
||||
// restore GL state after clearing
|
||||
// And reset!
|
||||
if (mScissorTestEnabled)
|
||||
gl->fEnable(LOCAL_GL_SCISSOR_TEST);
|
||||
|
||||
// Restore GL state after clearing.
|
||||
if (initializeColorBuffer) {
|
||||
gl->fColorMask(mColorWriteMask[0],
|
||||
mColorWriteMask[1],
|
||||
@ -1161,41 +1234,33 @@ WebGLContext::ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntR
|
||||
|
||||
if (initializeStencilBuffer) {
|
||||
gl->fStencilMaskSeparate(LOCAL_GL_FRONT, mStencilWriteMaskFront);
|
||||
gl->fStencilMaskSeparate(LOCAL_GL_BACK, mStencilWriteMaskBack);
|
||||
gl->fStencilMaskSeparate(LOCAL_GL_BACK, mStencilWriteMaskBack);
|
||||
gl->fClearStencil(mStencilClearValue);
|
||||
}
|
||||
|
||||
if (mDitherEnabled)
|
||||
gl->fEnable(LOCAL_GL_DITHER);
|
||||
else
|
||||
gl->fDisable(LOCAL_GL_DITHER);
|
||||
|
||||
if (mScissorTestEnabled)
|
||||
gl->fEnable(LOCAL_GL_SCISSOR_TEST);
|
||||
else
|
||||
gl->fDisable(LOCAL_GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::EnsureBackbufferClearedAsNeeded()
|
||||
// For an overview of how WebGL compositing works, see:
|
||||
// https://wiki.mozilla.org/Platform/GFX/WebGL/Compositing
|
||||
bool
|
||||
WebGLContext::PresentScreenBuffer()
|
||||
{
|
||||
if (mOptions.preserveDrawingBuffer)
|
||||
return;
|
||||
if (!mShouldPresent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(!mBoundFramebuffer,
|
||||
"EnsureBackbufferClearedAsNeeded must not be called when a FBO is bound");
|
||||
gl->MakeCurrent();
|
||||
if (!gl->PublishFrame()) {
|
||||
this->ForceLoseContext();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mBackbufferClearingStatus != BackbufferClearingStatus::NotClearedSinceLastPresented)
|
||||
return;
|
||||
if (!mOptions.preserveDrawingBuffer) {
|
||||
ClearScreen();
|
||||
}
|
||||
|
||||
mBackbufferClearingStatus = BackbufferClearingStatus::ClearedToDefaultValues;
|
||||
mShouldPresent = false;
|
||||
|
||||
ForceClearFramebufferWithDefaultValues(LOCAL_GL_COLOR_BUFFER_BIT |
|
||||
LOCAL_GL_DEPTH_BUFFER_BIT |
|
||||
LOCAL_GL_STENCIL_BUFFER_BIT,
|
||||
nsIntRect(0, 0, mWidth, mHeight));
|
||||
|
||||
Invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -86,10 +86,6 @@ struct VertexAttrib0Status {
|
||||
enum { Default, EmulatedUninitializedArray, EmulatedInitializedArray };
|
||||
};
|
||||
|
||||
struct BackbufferClearingStatus {
|
||||
enum { NotClearedSinceLastPresented, ClearedToDefaultValues, HasBeenDrawnTo };
|
||||
};
|
||||
|
||||
namespace WebGLTexelConversions {
|
||||
|
||||
/*
|
||||
@ -261,23 +257,35 @@ public:
|
||||
already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
LayerManager *aManager);
|
||||
|
||||
// Note that 'clean' here refers to its invalidation state, not the
|
||||
// contents of the buffer.
|
||||
void MarkContextClean() { mInvalidated = false; }
|
||||
|
||||
gl::GLContext* GL() const {
|
||||
return gl;
|
||||
}
|
||||
|
||||
bool IsPremultAlpha() const {
|
||||
return mOptions.premultipliedAlpha;
|
||||
}
|
||||
|
||||
bool PresentScreenBuffer();
|
||||
|
||||
// a number that increments every time we have an event that causes
|
||||
// all context resources to be lost.
|
||||
uint32_t Generation() { return mGeneration.value(); }
|
||||
|
||||
const WebGLRectangleObject *FramebufferRectangleObject() const;
|
||||
|
||||
// this is similar to GLContext::ClearSafely, but is more comprehensive
|
||||
// (takes care of scissor, stencil write mask, dithering, viewport...)
|
||||
// WebGL has more complex needs than GLContext as content controls GL state.
|
||||
void ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntRect& viewportRect);
|
||||
// This is similar to GLContext::ClearSafely, but tries to minimize the
|
||||
// amount of work it does.
|
||||
// It only clears the buffers we specify, and can reset its state without
|
||||
// first having to query anything, as WebGL knows its state at all times.
|
||||
void ForceClearFramebufferWithDefaultValues(GLbitfield mask);
|
||||
|
||||
// if the preserveDrawingBuffer context option is false, we need to clear the back buffer
|
||||
// after it's been presented to the compositor. This function does that if needed.
|
||||
// See section 2.2 in the WebGL spec.
|
||||
void EnsureBackbufferClearedAsNeeded();
|
||||
// Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
|
||||
void ClearScreen();
|
||||
|
||||
// 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
|
||||
@ -844,6 +852,8 @@ protected:
|
||||
bool mIsMesa;
|
||||
bool mLoseContextOnHeapMinimize;
|
||||
bool mCanLoseContextInForeground;
|
||||
bool mShouldPresent;
|
||||
bool mIsScreenCleared;
|
||||
|
||||
template<typename WebGLObjectType>
|
||||
void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
|
||||
@ -1106,8 +1116,6 @@ protected:
|
||||
WebGLint mStencilClearValue;
|
||||
WebGLfloat mDepthClearValue;
|
||||
|
||||
int mBackbufferClearingStatus;
|
||||
|
||||
nsCOMPtr<nsITimer> mContextRestorer;
|
||||
bool mAllowRestore;
|
||||
bool mContextLossTimerRunning;
|
||||
|
@ -171,7 +171,7 @@ WebGLContext::BindFramebuffer(WebGLenum target, WebGLFramebuffer *wfb)
|
||||
MakeContextCurrent();
|
||||
|
||||
if (!wfb) {
|
||||
gl->fBindFramebuffer(target, gl->GetOffscreenFBO());
|
||||
gl->fBindFramebuffer(target, 0);
|
||||
} else {
|
||||
WebGLuint framebuffername = wfb->GLName();
|
||||
gl->fBindFramebuffer(target, framebuffername);
|
||||
@ -575,32 +575,52 @@ WebGLContext::Clear(WebGLbitfield mask)
|
||||
if (mask != m)
|
||||
return ErrorInvalidValue("clear: invalid mask bits");
|
||||
|
||||
bool needClearCallHere = true;
|
||||
|
||||
if (mBoundFramebuffer) {
|
||||
if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
|
||||
return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
|
||||
} else {
|
||||
// no FBO is bound, so we are clearing the backbuffer here
|
||||
EnsureBackbufferClearedAsNeeded();
|
||||
bool valuesAreDefault = mColorClearValue[0] == 0.0f &&
|
||||
mColorClearValue[1] == 0.0f &&
|
||||
mColorClearValue[2] == 0.0f &&
|
||||
mColorClearValue[3] == 0.0f &&
|
||||
mDepthClearValue == 1.0f &&
|
||||
mStencilClearValue == 0;
|
||||
if (valuesAreDefault &&
|
||||
mBackbufferClearingStatus == BackbufferClearingStatus::ClearedToDefaultValues)
|
||||
{
|
||||
needClearCallHere = false;
|
||||
}
|
||||
|
||||
gl->fClear(mask);
|
||||
return;
|
||||
}
|
||||
|
||||
if (needClearCallHere) {
|
||||
gl->fClear(mask);
|
||||
mBackbufferClearingStatus = BackbufferClearingStatus::HasBeenDrawnTo;
|
||||
Invalidate();
|
||||
// Ok, we're clearing the default framebuffer/screen.
|
||||
|
||||
bool needsClear = true;
|
||||
if (mIsScreenCleared) {
|
||||
bool isClearRedundant = true;
|
||||
if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
|
||||
if (mColorClearValue[0] != 0.0f ||
|
||||
mColorClearValue[1] != 0.0f ||
|
||||
mColorClearValue[2] != 0.0f ||
|
||||
mColorClearValue[3] != 0.0f)
|
||||
{
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
|
||||
if (mDepthClearValue != 1.0f) {
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
|
||||
if (mStencilClearValue != 0) {
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isClearRedundant)
|
||||
needsClear = false;
|
||||
}
|
||||
|
||||
if (needsClear) {
|
||||
gl->fClear(mask);
|
||||
mIsScreenCleared = false;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
mShouldPresent = true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -815,7 +835,7 @@ WebGLContext::CopyTexImage2D(WebGLenum target,
|
||||
internalformat == LOCAL_GL_ALPHA ||
|
||||
internalformat == LOCAL_GL_LUMINANCE_ALPHA;
|
||||
bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
|
||||
: bool(gl->ActualFormat().alpha > 0);
|
||||
: bool(gl->GetPixelFormat().alpha > 0);
|
||||
if (texFormatRequiresAlpha && !fboFormatHasAlpha)
|
||||
return ErrorInvalidOperation("copyTexImage2D: texture format requires an alpha channel "
|
||||
"but the framebuffer doesn't have one");
|
||||
@ -925,7 +945,7 @@ WebGLContext::CopyTexSubImage2D(WebGLenum target,
|
||||
format == LOCAL_GL_ALPHA ||
|
||||
format == LOCAL_GL_LUMINANCE_ALPHA;
|
||||
bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
|
||||
: bool(gl->ActualFormat().alpha > 0);
|
||||
: bool(gl->GetPixelFormat().alpha > 0);
|
||||
|
||||
if (texFormatRequiresAlpha && !fboFormatHasAlpha)
|
||||
return ErrorInvalidOperation("copyTexSubImage2D: texture format requires an alpha channel "
|
||||
@ -1440,8 +1460,6 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
|
||||
if (mBoundFramebuffer) {
|
||||
if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
|
||||
return ErrorInvalidFramebufferOperation("drawArrays: incomplete framebuffer");
|
||||
} else {
|
||||
EnsureBackbufferClearedAsNeeded();
|
||||
}
|
||||
|
||||
BindFakeBlackTextures();
|
||||
@ -1454,8 +1472,11 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
|
||||
UndoFakeVertexAttrib0();
|
||||
UnbindFakeBlackTextures();
|
||||
|
||||
mBackbufferClearingStatus = BackbufferClearingStatus::HasBeenDrawnTo;
|
||||
Invalidate();
|
||||
if (!mBoundFramebuffer) {
|
||||
Invalidate();
|
||||
mShouldPresent = true;
|
||||
mIsScreenCleared = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1533,8 +1554,6 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
||||
if (mBoundFramebuffer) {
|
||||
if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
|
||||
return ErrorInvalidFramebufferOperation("drawElements: incomplete framebuffer");
|
||||
} else {
|
||||
EnsureBackbufferClearedAsNeeded();
|
||||
}
|
||||
|
||||
BindFakeBlackTextures();
|
||||
@ -1547,8 +1566,11 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
||||
UndoFakeVertexAttrib0();
|
||||
UnbindFakeBlackTextures();
|
||||
|
||||
mBackbufferClearingStatus = BackbufferClearingStatus::HasBeenDrawnTo;
|
||||
Invalidate();
|
||||
if (!mBoundFramebuffer) {
|
||||
Invalidate();
|
||||
mShouldPresent = true;
|
||||
mIsScreenCleared = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -3332,7 +3354,7 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
|
||||
if (mBoundFramebuffer) {
|
||||
needAlphaFixup = !mBoundFramebuffer->ColorAttachment().HasAlpha();
|
||||
} else {
|
||||
needAlphaFixup = gl->ActualFormat().alpha == 0;
|
||||
needAlphaFixup = gl->GetPixelFormat().alpha == 0;
|
||||
}
|
||||
|
||||
if (needAlphaFixup) {
|
||||
|
@ -352,7 +352,7 @@ WebGLFramebuffer::CheckAndInitializeRenderbuffers()
|
||||
mask |= LOCAL_GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
mContext->ForceClearFramebufferWithDefaultValues(mask, nsIntRect(0, 0, rect->Width(), rect->Height()));
|
||||
mContext->ForceClearFramebufferWithDefaultValues(mask);
|
||||
|
||||
if (mColorAttachment.HasUninitializedRenderbuffer())
|
||||
mColorAttachment.Renderbuffer()->SetInitialized(true);
|
||||
|
@ -11,175 +11,175 @@ pref(webgl.disabled,true) == webgl-disable-test.html wrapper.html?green.p
|
||||
# Test: {aa, alpha, preserve, readback} = 16
|
||||
== webgl-clear-test.html?nogl wrapper.html?green.png
|
||||
|
||||
== webgl-clear-test.html?__&_____&________ wrapper.html?green.png
|
||||
== webgl-clear-test.html?aa&_____&________ wrapper.html?green.png
|
||||
== webgl-clear-test.html?__&alpha&________ wrapper.html?green.png
|
||||
== webgl-clear-test.html?aa&alpha&________ wrapper.html?green.png
|
||||
== webgl-clear-test.html?__&_____&preserve wrapper.html?green.png
|
||||
== webgl-clear-test.html?aa&_____&preserve wrapper.html?green.png
|
||||
== webgl-clear-test.html?__&alpha&preserve wrapper.html?green.png
|
||||
== webgl-clear-test.html?aa&alpha&preserve wrapper.html?green.png
|
||||
== webgl-clear-test.html?__&_____&________ wrapper.html?green.png
|
||||
== webgl-clear-test.html?aa&_____&________ wrapper.html?green.png
|
||||
fuzzy-if(B2G,256,83) == webgl-clear-test.html?__&alpha&________ wrapper.html?green.png
|
||||
fuzzy-if(B2G,256,83) == webgl-clear-test.html?aa&alpha&________ wrapper.html?green.png
|
||||
== webgl-clear-test.html?__&_____&preserve wrapper.html?green.png
|
||||
== webgl-clear-test.html?aa&_____&preserve wrapper.html?green.png
|
||||
fuzzy-if(B2G,256,83) == webgl-clear-test.html?__&alpha&preserve wrapper.html?green.png
|
||||
fuzzy-if(B2G,256,83) == webgl-clear-test.html?aa&alpha&preserve wrapper.html?green.png
|
||||
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&__&_____&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&aa&_____&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&alpha&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&alpha&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&__&_____&preserve wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&aa&_____&preserve wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&alpha&preserve wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&alpha&preserve wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&_____&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&_____&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-clear-test.html?readback&__&alpha&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-clear-test.html?readback&aa&alpha&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&_____&preserve wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&_____&preserve wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-clear-test.html?readback&__&alpha&preserve wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-clear-test.html?readback&aa&alpha&preserve wrapper.html?green.png
|
||||
|
||||
# Check orientation:
|
||||
== webgl-orientation-test.html?nogl wrapper.html?white-top-left.png
|
||||
|
||||
== webgl-orientation-test.html?__&_____&________ wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?aa&_____&________ wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?__&alpha&________ wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?aa&alpha&________ wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?__&_____&preserve wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?aa&_____&preserve wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?__&alpha&preserve wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?aa&alpha&preserve wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?__&_____&________ wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?aa&_____&________ wrapper.html?white-top-left.png
|
||||
fuzzy-if(B2G,256,83) == webgl-orientation-test.html?__&alpha&________ wrapper.html?white-top-left.png
|
||||
fuzzy-if(B2G,256,83) == webgl-orientation-test.html?aa&alpha&________ wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?__&_____&preserve wrapper.html?white-top-left.png
|
||||
== webgl-orientation-test.html?aa&_____&preserve wrapper.html?white-top-left.png
|
||||
fuzzy-if(B2G,256,83) == webgl-orientation-test.html?__&alpha&preserve wrapper.html?white-top-left.png
|
||||
fuzzy-if(B2G,256,83) == webgl-orientation-test.html?aa&alpha&preserve wrapper.html?white-top-left.png
|
||||
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&__&_____&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&aa&_____&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&alpha&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&alpha&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&__&_____&preserve wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&aa&_____&preserve wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&alpha&preserve wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&alpha&preserve wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&_____&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&_____&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-orientation-test.html?readback&__&alpha&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-orientation-test.html?readback&aa&alpha&________ wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&_____&preserve wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&_____&preserve wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-orientation-test.html?readback&__&alpha&preserve wrapper.html?white-top-left.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-orientation-test.html?readback&aa&alpha&preserve wrapper.html?white-top-left.png
|
||||
|
||||
# Does we draw the correct color in the correct places with all context creation options?
|
||||
# (Note that our context creation option matrix is 2^6 = 64)
|
||||
== webgl-color-test.html?nogl wrapper.html?colors.png
|
||||
|
||||
== webgl-color-test.html?__&_____&_____&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&_______&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&_____&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&depth&_______&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&depth&_______&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&premult&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&_____&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&________&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&depth&premult&________&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&depth&premult&________&_______ wrapper.html?colors.png
|
||||
|
||||
== webgl-color-test.html?__&_____&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
fails-if(B2G) == webgl-color-test.html?__&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
fails-if(B2G) == webgl-color-test.html?aa&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
|
||||
|
||||
== webgl-color-test.html?__&_____&_____&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&________&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&_______&________&stencil wrapper.html?colors.png
|
||||
fails-if(B2G) == webgl-color-test.html?aa&alpha&_____&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&________&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&depth&_______&________&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&depth&_______&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&________&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&premult&________&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&_____&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&________&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&________&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&depth&premult&________&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&depth&premult&________&stencil wrapper.html?colors.png
|
||||
|
||||
== webgl-color-test.html?__&_____&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?__&_____&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
== webgl-color-test.html?aa&_____&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?__&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-test.html?aa&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
|
||||
|
||||
|
||||
# Check a smaller selection for readback:
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&__&_____&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&aa&_____&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&alpha&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&alpha&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&__&_____&preserve wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&aa&_____&preserve wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&alpha&preserve wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&alpha&preserve wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&_____&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&_____&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-color-test.html?readback&__&alpha&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-color-test.html?readback&aa&alpha&________ wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&_____&preserve wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&_____&preserve wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-color-test.html?readback&__&alpha&preserve wrapper.html?colors.png
|
||||
pref(webgl.force-layers-readback,true) fuzzy-if(B2G,256,83) == webgl-color-test.html?readback&aa&alpha&preserve wrapper.html?colors.png
|
||||
|
||||
|
||||
# Check alpha behavior:
|
||||
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0&nogl wrapper.html?colors.png
|
||||
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0 wrapper.html?colors.png
|
||||
== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0&nogl wrapper.html?black.png
|
||||
== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0 wrapper.html?black.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0&nogl wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0 wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0&nogl wrapper.html?black.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0 wrapper.html?black.png
|
||||
|
||||
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&nogl wrapper.html?colors.png
|
||||
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0 wrapper.html?colors.png
|
||||
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha&nogl wrapper.html?white.png
|
||||
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha wrapper.html?white.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&nogl wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0 wrapper.html?colors.png
|
||||
fuzzy-if(B2G,256,83) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha&nogl wrapper.html?white.png
|
||||
fails-if(B2G) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha wrapper.html?white.png
|
||||
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0&nogl wrapper.html?half-colors.png
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0 wrapper.html?half-colors.png
|
||||
fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0&nogl wrapper.html?half-colors.png
|
||||
fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0 wrapper.html?half-colors.png
|
||||
|
||||
# Test premult:
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&nogl wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&nogl wrapper.html?half-colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) fails-if(cocoaWidget||Android) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha wrapper.html?half-colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&nogl wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fails-if(B2G) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&nogl wrapper.html?half-colors-half-alpha.png
|
||||
fuzzy(1,65536) fails-if(B2G) fuzzy-if(Android,9,65536) fails-if(cocoaWidget||Android) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha wrapper.html?half-colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fails-if(B2G) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
|
||||
|
||||
# Test over-bright premult:
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
|
||||
fuzzy(1,65536) fails-if(B2G) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
|
||||
|
||||
|
||||
# Check for hanging framebuffer bindings:
|
||||
== webgl-hanging-fb-test.html?nogl wrapper.html?green.png
|
||||
|
||||
== webgl-hanging-fb-test.html wrapper.html?green.png
|
||||
== webgl-hanging-fb-test.html?aa wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-fb-test.html?readback wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-fb-test.html?readback&aa wrapper.html?green.png
|
||||
== webgl-hanging-fb-test.html?__&________ wrapper.html?green.png
|
||||
== webgl-hanging-fb-test.html?aa&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-hanging-fb-test.html?__&readback wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-hanging-fb-test.html?aa&readback wrapper.html?green.png
|
||||
|
||||
== webgl-hanging-scissor-test.html wrapper.html?green.png
|
||||
== webgl-hanging-scissor-test.html?aa wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-scissor-test.html?readback wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-scissor-test.html?readback&aa wrapper.html?green.png
|
||||
== webgl-hanging-scissor-test.html?__&________ wrapper.html?green.png
|
||||
== webgl-hanging-scissor-test.html?aa&________ wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-hanging-scissor-test.html?__&readback wrapper.html?green.png
|
||||
pref(webgl.force-layers-readback,true) == webgl-hanging-scissor-test.html?aa&readback wrapper.html?green.png
|
||||
|
||||
|
||||
# Check that our experimental prefs still work:
|
||||
|
||||
# 16bpp:
|
||||
pref(webgl.prefer-16bpp,true) == webgl-color-test.html?16bpp wrapper.html?colors.png
|
||||
pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?16bpp&readback wrapper.html?colors.png
|
||||
skip-if(winWidget) pref(webgl.prefer-16bpp,true) == webgl-color-test.html?16bpp wrapper.html?colors.png
|
||||
skip-if(winWidget) pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true) == webgl-color-test.html?16bpp&readback wrapper.html?colors.png
|
||||
|
||||
# Force native GL (Windows):
|
||||
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-clear-test.html?native-gl wrapper.html?green.png
|
||||
@ -187,6 +187,9 @@ skip-if(!winWidget) pref(webgl.prefer-native-gl,true)
|
||||
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-color-test.html?native-gl wrapper.html?colors.png
|
||||
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) pref(webgl.prefer-16bpp,true) == webgl-color-test.html?native-gl&16bpp wrapper.html?colors.png
|
||||
|
||||
|
||||
# Non-WebGL Reftests!
|
||||
|
||||
# Do we correctly handle multiple clip paths?
|
||||
!= clip-multiple-paths.html clip-multiple-paths-badref.html
|
||||
|
||||
|
@ -823,11 +823,11 @@ nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
} else {
|
||||
ClearHasValidDir();
|
||||
ClearHasFixedDir();
|
||||
ClearHasDirAuto();
|
||||
ClearHasDirAutoSet();
|
||||
if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
|
||||
SetHasDirAuto();
|
||||
} else {
|
||||
ClearHasDirAuto();
|
||||
ClearHasDirAutoSet();
|
||||
dir = RecomputeDirectionality(this, aNotify);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,9 @@
|
||||
#include "ImageTypes.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
@ -27,17 +30,14 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultVideoSource, nsITimerCallback)
|
||||
* Default video source.
|
||||
*/
|
||||
|
||||
// Cannot be initialized in the class definition
|
||||
const MediaEngineVideoOptions MediaEngineDefaultVideoSource::mOpts = {
|
||||
DEFAULT_WIDTH,
|
||||
DEFAULT_HEIGHT,
|
||||
DEFAULT_FPS,
|
||||
kVideoCodecI420
|
||||
};
|
||||
|
||||
MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource()
|
||||
MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource(int32_t aWidth,
|
||||
int32_t aHeight,
|
||||
int32_t aFPS)
|
||||
: mTimer(nullptr)
|
||||
{
|
||||
mOpts.mWidth = aWidth;
|
||||
mOpts.mHeight = aHeight;
|
||||
mOpts.mMaxFPS = aFPS;
|
||||
mState = kReleased;
|
||||
}
|
||||
|
||||
@ -143,14 +143,15 @@ MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
||||
// Allocate a single blank Image
|
||||
mCb = 16;
|
||||
mCr = 16;
|
||||
AllocateSolidColorFrame(data, DEFAULT_WIDTH, DEFAULT_HEIGHT, 0x80, mCb, mCr);
|
||||
AllocateSolidColorFrame(data, mOpts.mWidth, mOpts.mHeight, 0x80, mCb, mCr);
|
||||
// SetData copies data, so we can free the frame
|
||||
mImage->SetData(data);
|
||||
ReleaseFrame(data);
|
||||
|
||||
// AddTrack takes ownership of segment
|
||||
VideoSegment *segment = new VideoSegment();
|
||||
segment->AppendFrame(image.forget(), USECS_PER_S / DEFAULT_FPS, gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT));
|
||||
segment->AppendFrame(image.forget(), USECS_PER_S / mOpts.mMaxFPS,
|
||||
gfxIntSize(mOpts.mWidth, mOpts.mHeight));
|
||||
mSource->AddTrack(aID, VIDEO_RATE, 0, segment);
|
||||
|
||||
// We aren't going to add any more tracks
|
||||
@ -160,7 +161,7 @@ MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
||||
mTrackID = aID;
|
||||
|
||||
// Start timer for subsequent frames
|
||||
mTimer->InitWithCallback(this, 1000 / DEFAULT_FPS, nsITimer::TYPE_REPEATING_SLACK);
|
||||
mTimer->InitWithCallback(this, 1000 / mOpts.mMaxFPS, nsITimer::TYPE_REPEATING_SLACK);
|
||||
mState = kStarted;
|
||||
|
||||
return NS_OK;
|
||||
@ -242,14 +243,15 @@ MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
|
||||
nsRefPtr<layers::PlanarYCbCrImage> ycbcr_image =
|
||||
static_cast<layers::PlanarYCbCrImage*>(image.get());
|
||||
layers::PlanarYCbCrImage::Data data;
|
||||
AllocateSolidColorFrame(data, DEFAULT_WIDTH, DEFAULT_HEIGHT, 0x80, mCb, mCr);
|
||||
AllocateSolidColorFrame(data, mOpts.mWidth, mOpts.mHeight, 0x80, mCb, mCr);
|
||||
ycbcr_image->SetData(data);
|
||||
// SetData copies data, so we can free the frame
|
||||
ReleaseFrame(data);
|
||||
|
||||
// AddTrack takes ownership of segment
|
||||
VideoSegment segment;
|
||||
segment.AppendFrame(ycbcr_image.forget(), USECS_PER_S / DEFAULT_FPS, gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT));
|
||||
segment.AppendFrame(ycbcr_image.forget(), USECS_PER_S / mOpts.mMaxFPS,
|
||||
gfxIntSize(mOpts.mWidth, mOpts.mHeight));
|
||||
mSource->AppendToTrack(mTrackID, &segment);
|
||||
|
||||
return NS_OK;
|
||||
@ -344,7 +346,8 @@ MediaEngineDefaultAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
|
||||
mTrackID = aID;
|
||||
|
||||
// 1 Audio frame per Video frame
|
||||
mTimer->InitWithCallback(this, 1000 / MediaEngineDefaultVideoSource::DEFAULT_FPS, nsITimer::TYPE_REPEATING_SLACK);
|
||||
mTimer->InitWithCallback(this, 1000 / MediaEngineDefaultVideoSource::DEFAULT_VIDEO_FPS,
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
mState = kStarted;
|
||||
|
||||
return NS_OK;
|
||||
@ -393,18 +396,39 @@ MediaEngineDefault::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSour
|
||||
int32_t found = false;
|
||||
int32_t len = mVSources.Length();
|
||||
|
||||
int32_t width = MediaEngineDefaultVideoSource::DEFAULT_VIDEO_WIDTH;
|
||||
int32_t height = MediaEngineDefaultVideoSource::DEFAULT_VIDEO_HEIGHT;
|
||||
int32_t fps = MediaEngineDefaultVideoSource::DEFAULT_VIDEO_FPS;
|
||||
|
||||
// FIX - these should be passed in originating in prefs and/or getUserMedia constraints
|
||||
// Bug 778801
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
|
||||
|
||||
if (branch) {
|
||||
// these very rarely change
|
||||
branch->GetIntPref("media.navigator.video.default_width", &width);
|
||||
branch->GetIntPref("media.navigator.video.default_height", &height);
|
||||
branch->GetIntPref("media.navigator.video.default_fps", &fps);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < len; i++) {
|
||||
nsRefPtr<MediaEngineVideoSource> source = mVSources.ElementAt(i);
|
||||
aVSources->AppendElement(source);
|
||||
if (source->IsAvailable()) {
|
||||
const MediaEngineVideoOptions *opts = source->GetOptions();
|
||||
if (source->IsAvailable() &&
|
||||
opts->mWidth == width && opts->mHeight == height && opts->mMaxFPS == fps) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// All streams are currently busy, just make a new one.
|
||||
// All streams are currently busy (or wrong resolution), just make a new one.
|
||||
if (!found) {
|
||||
nsRefPtr<MediaEngineVideoSource> newSource =
|
||||
new MediaEngineDefaultVideoSource();
|
||||
new MediaEngineDefaultVideoSource(width, height, fps);
|
||||
mVSources.AppendElement(newSource);
|
||||
aVSources->AppendElement(newSource);
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ class ImageContainer;
|
||||
class PlanarYCbCrImage;
|
||||
}
|
||||
|
||||
class MediaEngineDefault;
|
||||
|
||||
/**
|
||||
* The default implementation of the MediaEngine interface.
|
||||
*/
|
||||
@ -32,7 +34,7 @@ class MediaEngineDefaultVideoSource : public nsITimerCallback,
|
||||
public MediaEngineVideoSource
|
||||
{
|
||||
public:
|
||||
MediaEngineDefaultVideoSource();
|
||||
MediaEngineDefaultVideoSource(int aWidth, int aHeight, int aFPS);
|
||||
~MediaEngineDefaultVideoSource();
|
||||
|
||||
virtual void GetName(nsAString&);
|
||||
@ -57,19 +59,21 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
// Need something better...
|
||||
static const int DEFAULT_WIDTH=640;
|
||||
static const int DEFAULT_HEIGHT=480;
|
||||
static const int DEFAULT_FPS=30;
|
||||
static const int DEFAULT_VIDEO_FPS = 60;
|
||||
static const int DEFAULT_VIDEO_MIN_FPS = 10;
|
||||
static const int DEFAULT_VIDEO_WIDTH = 640;
|
||||
static const int DEFAULT_VIDEO_HEIGHT = 480;
|
||||
|
||||
protected:
|
||||
friend class MediaEngineDefault;
|
||||
|
||||
TrackID mTrackID;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsRefPtr<layers::ImageContainer> mImageContainer;
|
||||
|
||||
SourceMediaStream* mSource;
|
||||
layers::PlanarYCbCrImage* mImage;
|
||||
static const MediaEngineVideoOptions mOpts;
|
||||
MediaEngineVideoOptions mOpts;
|
||||
int mCb;
|
||||
int mCr;
|
||||
};
|
||||
|
@ -10,6 +10,9 @@
|
||||
#error "This file must be #included before any IPDL-generated files or other files that #include prlog.h"
|
||||
#endif
|
||||
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
|
||||
#include "CSFLog.h"
|
||||
#include "prenv.h"
|
||||
|
||||
@ -40,6 +43,36 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
||||
// We spawn threads to handle gUM runnables, so we must protect the member vars
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
int32_t width = MediaEngineWebRTCVideoSource::DEFAULT_VIDEO_WIDTH;
|
||||
int32_t height = MediaEngineWebRTCVideoSource::DEFAULT_VIDEO_HEIGHT;
|
||||
int32_t fps = MediaEngineWebRTCVideoSource::DEFAULT_VIDEO_FPS;
|
||||
int32_t minfps = MediaEngineWebRTCVideoSource::DEFAULT_VIDEO_MIN_FPS;
|
||||
|
||||
// FIX - these should be passed in originating in prefs and/or getUserMedia constraints
|
||||
// Bug 778801
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
|
||||
|
||||
if (branch) {
|
||||
branch->GetIntPref("media.navigator.video.default_width", &width);
|
||||
branch->GetIntPref("media.navigator.video.default_height", &height);
|
||||
branch->GetIntPref("media.navigator.video.default_fps", &fps);
|
||||
branch->GetIntPref("media.navigator.video.default_min_fps", &minfps);
|
||||
}
|
||||
}
|
||||
LOG(("%s: %dx%d @%dfps (min %d)", __FUNCTION__, width, height, fps, minfps));
|
||||
|
||||
bool changed = false;
|
||||
if (width != mWidth || height != mHeight || fps != mFPS || minfps != mMinFPS) {
|
||||
changed = true;
|
||||
}
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFPS = fps;
|
||||
mMinFPS = minfps;
|
||||
|
||||
if (!mVideoEngine) {
|
||||
if (!(mVideoEngine = webrtc::VideoEngine::Create())) {
|
||||
return;
|
||||
@ -134,11 +167,12 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
||||
|
||||
nsRefPtr<MediaEngineWebRTCVideoSource> vSource;
|
||||
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
||||
if (mVideoSources.Get(uuid, getter_AddRefs(vSource))) {
|
||||
if (!changed && mVideoSources.Get(uuid, getter_AddRefs(vSource))) {
|
||||
// We've already seen this device, just append.
|
||||
aVSources->AppendElement(vSource.get());
|
||||
} else {
|
||||
vSource = new MediaEngineWebRTCVideoSource(mVideoEngine, i);
|
||||
vSource = new MediaEngineWebRTCVideoSource(mVideoEngine, i,
|
||||
width, height, fps, minfps);
|
||||
mVideoSources.Put(uuid, vSource); // Hashtable takes ownership.
|
||||
aVSources->AppendElement(vSource);
|
||||
}
|
||||
|
@ -57,22 +57,26 @@ class MediaEngineWebRTCVideoSource : public MediaEngineVideoSource,
|
||||
{
|
||||
public:
|
||||
static const int DEFAULT_VIDEO_FPS = 60;
|
||||
static const int DEFAULT_MIN_VIDEO_FPS = 10;
|
||||
static const int DEFAULT_VIDEO_MIN_FPS = 10;
|
||||
static const int DEFAULT_VIDEO_WIDTH = 640;
|
||||
static const int DEFAULT_VIDEO_HEIGHT = 480;
|
||||
|
||||
// ViEExternalRenderer.
|
||||
virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int);
|
||||
virtual int DeliverFrame(unsigned char*, int, uint32_t, int64_t);
|
||||
|
||||
MediaEngineWebRTCVideoSource(webrtc::VideoEngine* aVideoEnginePtr,
|
||||
int aIndex, int aMinFps = DEFAULT_MIN_VIDEO_FPS)
|
||||
int aIndex,
|
||||
int aWidth = DEFAULT_VIDEO_WIDTH, int aHeight = DEFAULT_VIDEO_HEIGHT,
|
||||
int aFps = DEFAULT_VIDEO_FPS, int aMinFps = DEFAULT_VIDEO_MIN_FPS)
|
||||
: mVideoEngine(aVideoEnginePtr)
|
||||
, mCaptureIndex(aIndex)
|
||||
, mCapabilityChosen(false)
|
||||
, mWidth(640)
|
||||
, mHeight(480)
|
||||
, mWidth(aWidth)
|
||||
, mHeight(aHeight)
|
||||
, mLastEndTime(0)
|
||||
, mMonitor("WebRTCCamera.Monitor")
|
||||
, mFps(DEFAULT_VIDEO_FPS)
|
||||
, mFps(aFps)
|
||||
, mMinFps(aMinFps)
|
||||
, mInitDone(false)
|
||||
, mInSnapshotMode(false)
|
||||
@ -287,6 +291,9 @@ private:
|
||||
bool mVideoEngineInit;
|
||||
bool mAudioEngineInit;
|
||||
|
||||
// the last set of selection vars for video sources
|
||||
int mHeight, mWidth, mFPS, mMinFPS;
|
||||
|
||||
// Store devices we've already seen in a hashtable for quick return.
|
||||
// Maps UUID to MediaEngineSource (one set for audio, one for video).
|
||||
nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCVideoSource > mVideoSources;
|
||||
|
@ -31,6 +31,7 @@ MediaEngineWebRTCVideoSource::FrameSizeChange(
|
||||
{
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
LOG(("Video FrameSizeChange: %ux%u", w, h));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -82,7 +83,8 @@ MediaEngineWebRTCVideoSource::DeliverFrame(
|
||||
|
||||
#ifdef DEBUG
|
||||
static uint32_t frame_num = 0;
|
||||
LOGFRAME(("frame %d; timestamp %u, render_time %lu", frame_num++, time_stamp, render_time));
|
||||
LOGFRAME(("frame %d (%dx%d); timestamp %u, render_time %lu", frame_num++,
|
||||
mWidth, mHeight, time_stamp, render_time));
|
||||
#endif
|
||||
|
||||
// we don't touch anything in 'this' until here (except for snapshot,
|
||||
@ -178,6 +180,7 @@ MediaEngineWebRTCVideoSource::ChooseCapability(uint32_t aWidth, uint32_t aHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(("chose cap %dx%d @%dfps", mOpts.mWidth, mOpts.mHeight, mOpts.mMaxFPS));
|
||||
mCapabilityChosen = true;
|
||||
}
|
||||
|
||||
|
19
content/svg/content/src/crashtests/719779-1.svg
Normal file
19
content/svg/content/src/crashtests/719779-1.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="80" y="80" width="300" height="180" viewBox="0 0 200 120">
|
||||
|
||||
<defs>
|
||||
<filter id="MyFilter" filterUnits="userSpaceOnUse" >
|
||||
<feGaussianBlur />
|
||||
<feOffset />
|
||||
<feSpecularLighting >
|
||||
<fePointLight />
|
||||
</feSpecularLighting>
|
||||
<feComposite />
|
||||
<feMerge>
|
||||
<feMergeNode />
|
||||
<feMergeNode />
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<g transform="matrix(100,-2562303,3000,100,300,300) " filter="url(#MyFilter)"/>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 634 B |
@ -58,10 +58,10 @@ load 603145-1.svg
|
||||
load 613899-1.svg
|
||||
load 613899-2.svg
|
||||
load zero-size-image.svg
|
||||
load 719779-1.svg
|
||||
load 723441-1.html
|
||||
load 751515-1.svg
|
||||
load 761507-1.svg
|
||||
load 831561.html
|
||||
load 837450-1.svg
|
||||
load 842463-1.html
|
||||
|
||||
|
@ -4890,14 +4890,22 @@ nsSVGFELightingElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChan
|
||||
|
||||
static int32_t
|
||||
Convolve3x3(const uint8_t *index, int32_t stride,
|
||||
const int8_t kernel[3][3])
|
||||
const int8_t kernel[3][3]
|
||||
#ifdef DEBUG
|
||||
, const uint8_t *minData, const uint8_t *maxData
|
||||
#endif // DEBUG
|
||||
)
|
||||
{
|
||||
int32_t sum = 0;
|
||||
for (int32_t y = 0; y < 3; y++) {
|
||||
for (int32_t x = 0; x < 3; x++) {
|
||||
int8_t k = kernel[y][x];
|
||||
if (k)
|
||||
sum += k * index[4 * (x - 1) + stride * (y - 1)];
|
||||
if (k) {
|
||||
const uint8_t *valPtr = index + (4 * (x - 1) + stride * (y - 1));
|
||||
NS_ASSERTION(valPtr >= minData, "out of bounds read (before buffer)");
|
||||
NS_ASSERTION(valPtr < maxData, "out of bounds read (after buffer)");
|
||||
sum += k * (*valPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
@ -4966,10 +4974,30 @@ GenerateNormal(float *N, const uint8_t *data, int32_t stride,
|
||||
|
||||
const uint8_t *index = data + y * stride + 4 * x + GFX_ARGB32_OFFSET_A;
|
||||
|
||||
#ifdef DEBUG
|
||||
// For sanity-checking, to be sure we're not reading outside source buffer:
|
||||
const uint8_t* minData = data;
|
||||
const uint8_t* maxData = minData + (surfaceHeight * surfaceWidth * stride);
|
||||
|
||||
// We'll sanity-check each value we read inside of Convolve3x3, but we
|
||||
// might as well ensure we're passing it a valid pointer to start with, too:
|
||||
NS_ASSERTION(index >= minData, "index points before buffer start");
|
||||
NS_ASSERTION(index < maxData, "index points after buffer end");
|
||||
#endif // DEBUG
|
||||
|
||||
N[0] = -surfaceScale * FACTORx[yflag][xflag] *
|
||||
Convolve3x3(index, stride, Kx[yflag][xflag]);
|
||||
Convolve3x3(index, stride, Kx[yflag][xflag]
|
||||
#ifdef DEBUG
|
||||
, minData, maxData
|
||||
#endif // DEBUG
|
||||
);
|
||||
|
||||
N[1] = -surfaceScale * FACTORy[yflag][xflag] *
|
||||
Convolve3x3(index, stride, Ky[yflag][xflag]);
|
||||
Convolve3x3(index, stride, Ky[yflag][xflag]
|
||||
#ifdef DEBUG
|
||||
, minData, maxData
|
||||
#endif // DEBUG
|
||||
);
|
||||
N[2] = 255;
|
||||
NORMALIZE(N);
|
||||
}
|
||||
|
@ -64,6 +64,10 @@ NS_IMPL_RELEASE(nsHistory)
|
||||
NS_IMETHODIMP
|
||||
nsHistory::GetLength(int32_t* aLength)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !nsContentUtils::CanCallerAccess(win->GetOuterWindow()))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
nsCOMPtr<nsISHistory> sHistory;
|
||||
|
||||
// Get session History from docshell
|
||||
@ -171,6 +175,10 @@ nsHistory::GetNext(nsAString& aNext)
|
||||
NS_IMETHODIMP
|
||||
nsHistory::Back()
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !nsContentUtils::CanCallerAccess(win->GetOuterWindow()))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
nsCOMPtr<nsISHistory> sHistory;
|
||||
|
||||
GetSessionHistoryFromDocShell(GetDocShell(), getter_AddRefs(sHistory));
|
||||
@ -187,6 +195,10 @@ nsHistory::Back()
|
||||
NS_IMETHODIMP
|
||||
nsHistory::Forward()
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !nsContentUtils::CanCallerAccess(win->GetOuterWindow()))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
nsCOMPtr<nsISHistory> sHistory;
|
||||
|
||||
GetSessionHistoryFromDocShell(GetDocShell(), getter_AddRefs(sHistory));
|
||||
@ -203,6 +215,10 @@ nsHistory::Forward()
|
||||
NS_IMETHODIMP
|
||||
nsHistory::Go(int32_t aDelta)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !nsContentUtils::CanCallerAccess(win->GetOuterWindow()))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
if (aDelta == 0) {
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(GetDocShell()));
|
||||
|
||||
|
@ -3588,95 +3588,67 @@ nsJSRuntime::Init()
|
||||
SetDOMCallbacks(sRuntime, &DOMcallbacks);
|
||||
|
||||
// Set these global xpconnect options...
|
||||
Preferences::RegisterCallback(MaxScriptRunTimePrefChangedCallback,
|
||||
"dom.max_script_run_time");
|
||||
MaxScriptRunTimePrefChangedCallback("dom.max_script_run_time", nullptr);
|
||||
Preferences::RegisterCallbackAndCall(MaxScriptRunTimePrefChangedCallback,
|
||||
"dom.max_script_run_time");
|
||||
|
||||
Preferences::RegisterCallback(MaxScriptRunTimePrefChangedCallback,
|
||||
"dom.max_chrome_script_run_time");
|
||||
MaxScriptRunTimePrefChangedCallback("dom.max_chrome_script_run_time",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(MaxScriptRunTimePrefChangedCallback,
|
||||
"dom.max_chrome_script_run_time");
|
||||
|
||||
Preferences::RegisterCallback(ReportAllJSExceptionsPrefChangedCallback,
|
||||
"dom.report_all_js_exceptions");
|
||||
ReportAllJSExceptionsPrefChangedCallback("dom.report_all_js_exceptions",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(ReportAllJSExceptionsPrefChangedCallback,
|
||||
"dom.report_all_js_exceptions");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryHighWaterMarkPrefChangedCallback,
|
||||
"javascript.options.mem.high_water_mark");
|
||||
SetMemoryHighWaterMarkPrefChangedCallback("javascript.options.mem.high_water_mark",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryHighWaterMarkPrefChangedCallback,
|
||||
"javascript.options.mem.high_water_mark");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryMaxPrefChangedCallback,
|
||||
"javascript.options.mem.max");
|
||||
SetMemoryMaxPrefChangedCallback("javascript.options.mem.max",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryMaxPrefChangedCallback,
|
||||
"javascript.options.mem.max");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCModePrefChangedCallback,
|
||||
"javascript.options.mem.gc_per_compartment");
|
||||
SetMemoryGCModePrefChangedCallback("javascript.options.mem.gc_per_compartment",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCModePrefChangedCallback,
|
||||
"javascript.options.mem.gc_per_compartment");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCModePrefChangedCallback,
|
||||
"javascript.options.mem.gc_incremental");
|
||||
SetMemoryGCModePrefChangedCallback("javascript.options.mem.gc_incremental",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCModePrefChangedCallback,
|
||||
"javascript.options.mem.gc_incremental");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCSliceTimePrefChangedCallback,
|
||||
"javascript.options.mem.gc_incremental_slice_ms");
|
||||
SetMemoryGCSliceTimePrefChangedCallback("javascript.options.mem.gc_incremental_slice_ms",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCSliceTimePrefChangedCallback,
|
||||
"javascript.options.mem.gc_incremental_slice_ms");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_time_limit_ms");
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_time_limit_ms",
|
||||
(void *)JSGC_HIGH_FREQUENCY_TIME_LIMIT);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_time_limit_ms",
|
||||
(void *)JSGC_HIGH_FREQUENCY_TIME_LIMIT);
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCDynamicMarkSlicePrefChangedCallback,
|
||||
"javascript.options.mem.gc_dynamic_mark_slice");
|
||||
SetMemoryGCDynamicMarkSlicePrefChangedCallback("javascript.options.mem.gc_dynamic_mark_slice",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCDynamicMarkSlicePrefChangedCallback,
|
||||
"javascript.options.mem.gc_dynamic_mark_slice");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCDynamicHeapGrowthPrefChangedCallback,
|
||||
"javascript.options.mem.gc_dynamic_heap_growth");
|
||||
SetMemoryGCDynamicHeapGrowthPrefChangedCallback("javascript.options.mem.gc_dynamic_heap_growth",
|
||||
nullptr);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCDynamicHeapGrowthPrefChangedCallback,
|
||||
"javascript.options.mem.gc_dynamic_heap_growth");
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_low_frequency_heap_growth");
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_low_frequency_heap_growth",
|
||||
(void *)JSGC_LOW_FREQUENCY_HEAP_GROWTH);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_low_frequency_heap_growth",
|
||||
(void *)JSGC_LOW_FREQUENCY_HEAP_GROWTH);
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_heap_growth_min");
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_heap_growth_min",
|
||||
(void *)JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_heap_growth_min",
|
||||
(void *)JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN);
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_heap_growth_max");
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_heap_growth_max",
|
||||
(void *)JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_heap_growth_max",
|
||||
(void *)JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX);
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_low_limit_mb");
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_low_limit_mb",
|
||||
(void *)JSGC_HIGH_FREQUENCY_LOW_LIMIT);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_low_limit_mb",
|
||||
(void *)JSGC_HIGH_FREQUENCY_LOW_LIMIT);
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_high_limit_mb");
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_high_limit_mb",
|
||||
(void *)JSGC_HIGH_FREQUENCY_HIGH_LIMIT);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_high_frequency_high_limit_mb",
|
||||
(void *)JSGC_HIGH_FREQUENCY_HIGH_LIMIT);
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.analysis_purge_mb",
|
||||
(void *)JSGC_ANALYSIS_PURGE_TRIGGER);
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.analysis_purge_mb",
|
||||
(void *)JSGC_ANALYSIS_PURGE_TRIGGER);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.analysis_purge_mb",
|
||||
(void *)JSGC_ANALYSIS_PURGE_TRIGGER);
|
||||
|
||||
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_allocation_threshold_mb");
|
||||
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_allocation_threshold_mb",
|
||||
(void *)JSGC_ALLOCATION_THRESHOLD);
|
||||
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
|
||||
"javascript.options.mem.gc_allocation_threshold_mb",
|
||||
(void *)JSGC_ALLOCATION_THRESHOLD);
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (!obs)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -23,7 +23,13 @@
|
||||
todo(false, "WebGL not supported");
|
||||
return;
|
||||
}
|
||||
is(gl.getError(), 0, "Should not start in an error state");
|
||||
var error = gl.getError()
|
||||
|
||||
// on the b2g emulator we get GL_INVALID_FRAMEBUFFER_OPERATION
|
||||
if (error == 0x0506) // GL_INVALID_FRAMEBUFFER_OPERATION
|
||||
return;
|
||||
|
||||
is(error, 0, "Should not start in an error state");
|
||||
|
||||
var b = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, b);
|
||||
|
@ -210,8 +210,10 @@ this.DOMContactManager = {
|
||||
break;
|
||||
case "child-process-shutdown":
|
||||
if (DEBUG) debug("Unregister");
|
||||
this._db.releaseCursors(this._liveCursors[mm]);
|
||||
delete this._liveCursors[mm];
|
||||
if (this._liveCursors[mm]) {
|
||||
this._db.releaseCursors(this._liveCursors[mm]);
|
||||
delete this._liveCursors[mm];
|
||||
}
|
||||
let index = this._children.indexOf(mm);
|
||||
if (index != -1) {
|
||||
if (DEBUG) debug("Unregister index: " + index);
|
||||
|
@ -15,6 +15,13 @@ dictionary MozStkTextMessage
|
||||
*/
|
||||
DOMString text;
|
||||
|
||||
/**
|
||||
* The length of time for which the ME shall display the dialog.
|
||||
*
|
||||
* @see MozStkDuration
|
||||
*/
|
||||
jsval duration;
|
||||
|
||||
/**
|
||||
* Indicate this text message is high priority or normal priority.
|
||||
*
|
||||
@ -249,6 +256,13 @@ dictionary MozStkSetUpCall
|
||||
* callMessage.
|
||||
*/
|
||||
jsval callMessage;
|
||||
|
||||
/**
|
||||
* The Optional maximum duration for the redial mechanism.
|
||||
* The time elapsed since the first call set-up attempt has exceeded the duration
|
||||
* requested by the UICC, the redial mechanism is terminated.
|
||||
*/
|
||||
jsval duration;
|
||||
};
|
||||
|
||||
dictionary MozStkSetUpEventList
|
||||
|
@ -151,6 +151,26 @@ function testSetupCall(cmd) {
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
function testDisplayTextVariableTimeOut(cmd) {
|
||||
log("STK CMD " + JSON.stringify(cmd));
|
||||
is(cmd.typeOfCommand, icc.STK_CMD_DISPLAY_TEXT);
|
||||
is(cmd.commandNumber, 0x01);
|
||||
is(cmd.options.duration.timeUnit, icc.STK_TIME_UNIT_SECOND);
|
||||
is(cmd.options.duration.timeInterval, 0x0A);
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
function testSetUpCallVariableTimeOut(cmd) {
|
||||
log("STK CMD " + JSON.stringify(cmd));
|
||||
is(cmd.typeOfCommand, icc.STK_CMD_SET_UP_CALL);
|
||||
is(cmd.commandNumber, 0x01);
|
||||
is(cmd.options.duration.timeUnit, icc.STK_TIME_UNIT_SECOND);
|
||||
is(cmd.options.duration.timeInterval, 0x0A);
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
let tests = [
|
||||
{command: "d0288103012180820281020d1d00d3309bfc06c95c301aa8e80259c3ec34b9ac07c9602f58ed159bb940",
|
||||
func: testDisplayTextGsm7BitEncoding},
|
||||
@ -180,6 +200,10 @@ let tests = [
|
||||
func: testSetupCall},
|
||||
{command: "D0198103012200820281828D0A04456E74657220222B228402010A",
|
||||
func: testGetInKeyVariableTimeout},
|
||||
{command: "d0198103012180820281028D0A043130205365636F6E648402010A",
|
||||
func: testDisplayTextVariableTimeOut},
|
||||
{command: "d02281030110008202818385084E6F7420627573798609911032042143651C2C8402010A",
|
||||
func: testSetUpCallVariableTimeOut},
|
||||
];
|
||||
|
||||
let pendingEmulatorCmdCount = 0;
|
||||
|
@ -2060,7 +2060,8 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
|
||||
|
||||
nsISupports* scopeSupports = NS_ISUPPORTS_CAST(nsIDOMEventTarget*, scope);
|
||||
|
||||
NS_ENSURE_TRUE(InitTabChildGlobalInternal(scopeSupports), false);
|
||||
NS_NAMED_LITERAL_CSTRING(globalId, "outOfProcessTabChildGlobal");
|
||||
NS_ENSURE_TRUE(InitTabChildGlobalInternal(scopeSupports, globalId), false);
|
||||
|
||||
scope->Init();
|
||||
|
||||
|
@ -613,14 +613,18 @@ public:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* We're allowing multiple tabs to access the same camera for parity
|
||||
* with Chrome. See bug 811757 for some of the issues surrounding
|
||||
* this decision. To disallow, we'd filter by IsAvailable() as we used
|
||||
* to.
|
||||
*/
|
||||
// Pick the first available device.
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRefPtr<MediaEngineVideoSource> vSource = videoSources[i];
|
||||
if (vSource->IsAvailable()) {
|
||||
found = true;
|
||||
mVideoDevice = new MediaDevice(videoSources[i]);
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
mVideoDevice = new MediaDevice(videoSources[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
@ -647,11 +651,9 @@ public:
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRefPtr<MediaEngineAudioSource> aSource = audioSources[i];
|
||||
if (aSource->IsAvailable()) {
|
||||
found = true;
|
||||
mAudioDevice = new MediaDevice(audioSources[i]);
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
mAudioDevice = new MediaDevice(audioSources[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
|
@ -104,7 +104,8 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
||||
* Find out about the status of an ICC lock (e.g. the PIN lock).
|
||||
*
|
||||
* @param lockType
|
||||
* Identifies the lock type, e.g. "pin" for the PIN lock.
|
||||
* Identifies the lock type, e.g. "pin" for the PIN lock, "fdn" for
|
||||
* the FDN lock.
|
||||
*
|
||||
* @return a DOM Request.
|
||||
* The request's result will be an object containing
|
||||
@ -151,7 +152,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: false,
|
||||
* success: false,
|
||||
* retryCount: 2
|
||||
* }
|
||||
*
|
||||
@ -159,7 +160,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: true
|
||||
* success: true
|
||||
* }
|
||||
*/
|
||||
nsIDOMDOMRequest unlockCardLock(in jsval info);
|
||||
@ -176,12 +177,18 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* (1) Disabling the PIN lock:
|
||||
* (1a) Disabling the PIN lock:
|
||||
*
|
||||
* setCardLock({lockType: "pin",
|
||||
* pin: "...",
|
||||
* enabled: false});
|
||||
*
|
||||
* (1b) Disabling the FDN lock:
|
||||
*
|
||||
* setCardLock({lockType: "fdn",
|
||||
* pin2: "...",
|
||||
* enabled: false});
|
||||
*
|
||||
* (2) Changing the PIN:
|
||||
*
|
||||
* setCardLock({lockType: "pin",
|
||||
@ -198,7 +205,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: false,
|
||||
* success: false,
|
||||
* retryCount: 2
|
||||
* }
|
||||
*
|
||||
@ -206,7 +213,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
|
||||
*
|
||||
* {
|
||||
* lockType: "pin",
|
||||
* result: true
|
||||
* success: true
|
||||
* }
|
||||
*/
|
||||
nsIDOMDOMRequest setCardLock(in jsval info);
|
||||
|
@ -14,14 +14,97 @@ this.PhoneNumber = (function (dataBase) {
|
||||
// Use strict in our context only - users might not want it
|
||||
'use strict';
|
||||
|
||||
// The minimum length of the national significant number.
|
||||
const MIN_LENGTH_FOR_NSN = 2;
|
||||
|
||||
const STAR_SIGN = "*";
|
||||
const UNICODE_DIGITS = /[\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9]/g;
|
||||
const ALPHA_CHARS = /[a-zA-Z]/g;
|
||||
const NON_ALPHA_CHARS = /[^a-zA-Z]/g;
|
||||
const NON_DIALABLE_CHARS = /[^,#+\*\d]/g;
|
||||
const PLUS_CHARS = /^[+\uFF0B]+/g;
|
||||
const PLUS_CHARS = "+\uFF0B";
|
||||
const BACKSLASH = /\\/g;
|
||||
const SPLIT_FIRST_GROUP = /^(\d+)(.*)$/;
|
||||
|
||||
/**
|
||||
* Regular expression of acceptable punctuation found in phone numbers. This
|
||||
* excludes punctuation found as a leading character only. This consists of
|
||||
* dash characters, white space characters, full stops, slashes, square
|
||||
* brackets, parentheses and tildes. It also includes the letter 'x' as that
|
||||
* is found as a placeholder for carrier information in some phone numbers.
|
||||
* Full-width variants are also present.
|
||||
*/
|
||||
const VALID_PUNCTUATION = "-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F \u00A0"
|
||||
+ "\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D."
|
||||
+ "\\[\\]/~\u2053\u223C\uFF5E";
|
||||
const VALID_DIGITS = "0-9\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9";
|
||||
const VALID_ALPHA = "a-zA-Z";
|
||||
|
||||
/**
|
||||
* Regular expression of viable phone numbers. This is location independent.
|
||||
* Checks we have at least three leading digits, and only valid punctuation,
|
||||
* alpha characters and digits in the phone number. Does not include extension
|
||||
* data. The symbol 'x' is allowed here as valid punctuation since it is often
|
||||
* used as a placeholder for carrier codes, for example in Brazilian phone
|
||||
* numbers. We also allow multiple '+' characters at the start.
|
||||
* Corresponds to the following:
|
||||
* [digits]{minLengthNsn}|
|
||||
* plus_sign*
|
||||
* (([punctuation]|[star])*[digits]){3,}([punctuation]|[star]|[digits]|[alpha])*
|
||||
*
|
||||
* The first reg-ex is to allow short numbers (two digits long) to be parsed
|
||||
* if they are entered as "15" etc, but only if there is no punctuation in
|
||||
* them. The second expression restricts the number of digits to three or
|
||||
* more, but then allows them to be in international form, and to have
|
||||
* alpha-characters and punctuation. We split up the two reg-exes here and
|
||||
* combine them when creating the reg-ex VALID_PHONE_NUMBER_PATTERN itself so
|
||||
* we can prefix it with ^ and append $ to each branch.
|
||||
*
|
||||
* Note VALID_PUNCTUATION starts with a -, so must be the first in the range.
|
||||
*/
|
||||
const MIN_LENGTH_PHONE_NUMBER
|
||||
= "[" + VALID_DIGITS + "]{" + MIN_LENGTH_FOR_NSN + "}";
|
||||
const VALID_PHONE_NUMBER
|
||||
= "[" + PLUS_CHARS + "]*"
|
||||
+ "(?:[" + VALID_PUNCTUATION + STAR_SIGN + "]*" + "[" + VALID_DIGITS + "]){3,}"
|
||||
+ "[" + VALID_PUNCTUATION + STAR_SIGN + VALID_ALPHA + VALID_DIGITS + "]*";
|
||||
|
||||
/**
|
||||
* Pattern to capture digits used in an extension.
|
||||
* Places a maximum length of '7' for an extension.
|
||||
*/
|
||||
const CAPTURING_EXTN_DIGITS = "([" + VALID_DIGITS + "]{1,7})";
|
||||
|
||||
/**
|
||||
* Regexp of all possible ways to write extensions, for use when parsing. This
|
||||
* will be run as a case-insensitive regexp match. Wide character versions are
|
||||
* also provided after each ASCII version. There are three regular expressions
|
||||
* here. The first covers RFC 3966 format, where the extension is added using
|
||||
* ';ext='. The second more generic one starts with optional white space and
|
||||
* ends with an optional full stop (.), followed by zero or more spaces/tabs and
|
||||
* then the numbers themselves. The other one covers the special case of
|
||||
* American numbers where the extension is written with a hash at the end, such
|
||||
* as '- 503#'. Note that the only capturing groups should be around the digits
|
||||
* that you want to capture as part of the extension, or else parsing will fail!
|
||||
* We allow two options for representing the accented o - the character itself,
|
||||
* and one in the unicode decomposed form with the combining acute accent.
|
||||
*/
|
||||
const EXTN_PATTERNS_FOR_PARSING
|
||||
= ";ext=" + CAPTURING_EXTN_DIGITS + "|" + "[ \u00A0\\t,]*"
|
||||
+ "(?:e?xt(?:ensi(?:o\u0301?|\u00F3))?n?|\uFF45?\uFF58\uFF54\uFF4E?|"
|
||||
+ "[,x\uFF58#\uFF03~\uFF5E]|int|anexo|\uFF49\uFF4E\uFF54)"
|
||||
+ "[:\\.\uFF0E]?[ \u00A0\\t,-]*" + CAPTURING_EXTN_DIGITS + "#?|"
|
||||
+ "[- ]+([" + VALID_DIGITS + "]{1,5})#";
|
||||
|
||||
const VALID_ALPHA_PATTERN = new RegExp("[" + VALID_ALPHA + "]", "g");
|
||||
const LEADING_PLUS_CHARS_PATTERN = new RegExp("^[" + PLUS_CHARS + "]+", "g");
|
||||
|
||||
// We append optionally the extension pattern to the end here, as a valid
|
||||
// phone number may have an extension prefix appended, followed by 1 or more
|
||||
// digits.
|
||||
const VALID_PHONE_NUMBER_PATTERN =
|
||||
new RegExp("^" + MIN_LENGTH_PHONE_NUMBER + "$|"
|
||||
+ "^" + VALID_PHONE_NUMBER + "(?:" + EXTN_PATTERNS_FOR_PARSING + ")?$", "i");
|
||||
|
||||
// Format of the string encoded meta data. If the name contains "^" or "$"
|
||||
// we will generate a regular expression from the value, with those special
|
||||
// characters as prefix/suffix.
|
||||
@ -222,11 +305,11 @@ this.PhoneNumber = (function (dataBase) {
|
||||
function (ch) {
|
||||
return String.fromCharCode(48 + (ch.charCodeAt(0) & 0xf));
|
||||
});
|
||||
number = number.replace(ALPHA_CHARS,
|
||||
number = number.replace(VALID_ALPHA_PATTERN,
|
||||
function (ch) {
|
||||
return (ch.toLowerCase().charCodeAt(0) - 97)/3+2 | 0;
|
||||
});
|
||||
number = number.replace(PLUS_CHARS, "+");
|
||||
number = number.replace(LEADING_PLUS_CHARS_PATTERN, "+");
|
||||
number = number.replace(NON_DIALABLE_CHARS, "");
|
||||
return number;
|
||||
}
|
||||
@ -307,7 +390,7 @@ this.PhoneNumber = (function (dataBase) {
|
||||
|
||||
// Detect and strip leading '+'.
|
||||
if (number[0] === '+')
|
||||
return ParseInternationalNumber(number.replace(PLUS_CHARS, ""));
|
||||
return ParseInternationalNumber(number.replace(LEADING_PLUS_CHARS_PATTERN, ""));
|
||||
|
||||
// Lookup the meta data for the given region.
|
||||
var md = FindMetaDataForRegion(defaultRegion.toUpperCase());
|
||||
@ -360,7 +443,21 @@ this.PhoneNumber = (function (dataBase) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function IsViablePhoneNumber(number) {
|
||||
if (number == null || number.length < MIN_LENGTH_FOR_NSN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let matchedGroups = number.match(VALID_PHONE_NUMBER_PATTERN);
|
||||
if (matchedGroups && matchedGroups[0].length == number.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
IsViable: IsViablePhoneNumber,
|
||||
Parse: ParseNumber,
|
||||
Normalize: NormalizeNumber
|
||||
};
|
||||
|
@ -83,5 +83,11 @@ this.PhoneNumberUtils = {
|
||||
let countryName = MCC_ISO3166_TABLE[aMCC];
|
||||
if (DEBUG) debug("found country name: " + countryName);
|
||||
return PhoneNumber.Parse(aNumber, countryName);
|
||||
},
|
||||
|
||||
isViablePhoneNumber: function IsViablePhoneNumber(aNumber) {
|
||||
let viable = PhoneNumber.IsViable(aNumber);
|
||||
if (DEBUG) debug("IsViable(" + aNumber + "): " + viable);
|
||||
return viable;
|
||||
}
|
||||
};
|
||||
|
@ -22,6 +22,15 @@
|
||||
|
||||
Components.utils.import("resource://gre/modules/PhoneNumber.jsm");
|
||||
|
||||
function IsViable(dial, expected) {
|
||||
var result = PhoneNumber.IsViable(dial);
|
||||
if (result != expected) {
|
||||
ok(false, dial + " is " + (result ? "" : "not ") + "viable, expects otherwise.");
|
||||
} else {
|
||||
ok(true, dial + " is " + (result ? "" : "not ") + "viable as expected.");
|
||||
}
|
||||
}
|
||||
|
||||
function CantParse(dial, currentRegion) {
|
||||
var result = PhoneNumber.Parse(dial, currentRegion);
|
||||
if (result) {
|
||||
@ -73,6 +82,37 @@ function Format(dial, currentRegion, nationalNumber, region, nationalFormat, int
|
||||
}
|
||||
}
|
||||
|
||||
// Test whether could a string be a phone number.
|
||||
IsViable(null, false);
|
||||
IsViable("", false);
|
||||
IsViable("1", false);
|
||||
IsViable("12", true); // MIN_LENGTH_PHONE_NUMBER
|
||||
IsViable("123", true); // MIN_LENGTH_PHONE_NUMBER
|
||||
IsViable("1a2", false);
|
||||
IsViable("12a", false);
|
||||
IsViable("1234", true); // MIN_LENGTH_PHONE_NUMBER
|
||||
IsViable("123a", true);
|
||||
IsViable("+", false);
|
||||
IsViable("+1", false);
|
||||
IsViable("+12", false);
|
||||
IsViable("+123", true);
|
||||
IsViable("()123", true);
|
||||
IsViable("(1)23", true);
|
||||
IsViable("(12)3", true);
|
||||
IsViable("(123)", true);
|
||||
IsViable("(123)4", true);
|
||||
IsViable("(123)4", true);
|
||||
IsViable("123;ext=", false);
|
||||
IsViable("123;ext=1", true);
|
||||
IsViable("123;ext=1234567", true);
|
||||
IsViable("123;ext=12345678", false);
|
||||
IsViable("123 ext:1", true);
|
||||
IsViable("123 ext:1#", true);
|
||||
IsViable("123-1#", true);
|
||||
IsViable("123 1#", true);
|
||||
IsViable("123 12345#", true);
|
||||
IsViable("123 +123456#", false);
|
||||
|
||||
// Test parsing national numbers.
|
||||
Parse("033316005", "NZ");
|
||||
Parse("03-331 6005", "NZ");
|
||||
|
@ -82,7 +82,9 @@ static nsRefPtr<GLContext> sPluginContext = nullptr;
|
||||
static bool EnsureGLContext()
|
||||
{
|
||||
if (!sPluginContext) {
|
||||
sPluginContext = GLContextProvider::CreateOffscreen(gfxIntSize(16, 16));
|
||||
gfxIntSize dummySize(16, 16);
|
||||
GLContext::SurfaceCaps dummyCaps;
|
||||
sPluginContext = GLContextProvider::CreateOffscreen(dummySize, dummyCaps);
|
||||
}
|
||||
|
||||
return sPluginContext != nullptr;
|
||||
|
@ -126,15 +126,15 @@ nsPluginByteRangeStreamListener::OnStartRequest(nsIRequest *request, nsISupports
|
||||
}
|
||||
|
||||
if (responseCode != 200) {
|
||||
bool bWantsAllNetworkStreams = false;
|
||||
uint32_t wantsAllNetworkStreams = 0;
|
||||
rv = pslp->GetPluginInstance()->GetValueFromPlugin(NPPVpluginWantsAllNetworkStreams,
|
||||
&bWantsAllNetworkStreams);
|
||||
&wantsAllNetworkStreams);
|
||||
// If the call returned an error code make sure we still use our default value.
|
||||
if (NS_FAILED(rv)) {
|
||||
bWantsAllNetworkStreams = false;
|
||||
wantsAllNetworkStreams = 0;
|
||||
}
|
||||
|
||||
if (!bWantsAllNetworkStreams){
|
||||
if (!wantsAllNetworkStreams){
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -476,20 +476,20 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
}
|
||||
|
||||
if (responseCode > 206) { // not normal
|
||||
bool bWantsAllNetworkStreams = false;
|
||||
uint32_t wantsAllNetworkStreams = 0;
|
||||
|
||||
// We don't always have an instance here already, but if we do, check
|
||||
// to see if it wants all streams.
|
||||
if (mPluginInstance) {
|
||||
rv = mPluginInstance->GetValueFromPlugin(NPPVpluginWantsAllNetworkStreams,
|
||||
&bWantsAllNetworkStreams);
|
||||
&wantsAllNetworkStreams);
|
||||
// If the call returned an error code make sure we still use our default value.
|
||||
if (NS_FAILED(rv)) {
|
||||
bWantsAllNetworkStreams = false;
|
||||
wantsAllNetworkStreams = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bWantsAllNetworkStreams) {
|
||||
if (!wantsAllNetworkStreams) {
|
||||
mRequestFailed = true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1511,11 +1511,13 @@ NPP_GetValue(NPP instance, NPPVariable variable, void* value)
|
||||
}
|
||||
if (variable == NPPVpluginNeedsXEmbed) {
|
||||
// Only relevant for X plugins
|
||||
*(NPBool*)value = instanceData->hasWidget;
|
||||
// use 4-byte writes like some plugins may do
|
||||
*(uint32_t*)value = instanceData->hasWidget;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
if (variable == NPPVpluginWantsAllNetworkStreams) {
|
||||
*(NPBool*)value = instanceData->wantsAllStreams;
|
||||
// use 4-byte writes like some plugins may do
|
||||
*(uint32_t*)value = instanceData->wantsAllStreams;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -395,11 +395,12 @@ NetworkManager.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the active network is already of the preferred type, nothing to do.
|
||||
// The active network is already our preferred type.
|
||||
if (this.active &&
|
||||
this.active.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED &&
|
||||
this.active.type == this._preferredNetworkType) {
|
||||
debug("Active network is already our preferred type. Not doing anything.");
|
||||
debug("Active network is already our preferred type.");
|
||||
this.setDefaultRouteAndDNS(oldActive);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,12 @@ XPCOMUtils.defineLazyGetter(this, "WAP", function () {
|
||||
return WAP;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () {
|
||||
let ns = {};
|
||||
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns);
|
||||
return ns.PhoneNumberUtils;
|
||||
});
|
||||
|
||||
function convertRILCallState(state) {
|
||||
switch (state) {
|
||||
case RIL.CALL_STATE_ACTIVE:
|
||||
@ -1984,6 +1990,14 @@ RadioInterfaceLayer.prototype = {
|
||||
|
||||
dial: function dial(number) {
|
||||
debug("Dialing " + number);
|
||||
if (!PhoneNumberUtils.isViablePhoneNumber(number)) {
|
||||
this.handleCallError({
|
||||
callIndex: -1,
|
||||
error: RIL.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[RIL.CALL_FAIL_UNOBTAINABLE_NUMBER]
|
||||
});
|
||||
debug("Number '" + number + "' doesn't seem to be a viable number. Drop.");
|
||||
return;
|
||||
}
|
||||
this.worker.postMessage({rilMessageType: "dial",
|
||||
number: number,
|
||||
isDialEmergency: false});
|
||||
|
@ -514,6 +514,7 @@ this.ICC_STATUS_ERROR_WRONG_PARAMETERS = 0x6a;
|
||||
// ICC call barring facility.
|
||||
// TS 27.007, clause 7.4, +CLCK
|
||||
this.ICC_CB_FACILITY_SIM = "SC";
|
||||
this.ICC_CB_FACILITY_FDN = "FD";
|
||||
|
||||
// ICC service class
|
||||
// TS 27.007, clause 7.4, +CLCK
|
||||
|
@ -1010,11 +1010,11 @@ let RIL = {
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
/**
|
||||
/**
|
||||
* Helper function for changing ICC locks.
|
||||
*/
|
||||
iccSetCardLock: function iccSetCardLock(options) {
|
||||
if (options.newPin !== undefined) {
|
||||
if (options.newPin !== undefined) { // Change PIN lock.
|
||||
switch (options.lockType) {
|
||||
case "pin":
|
||||
this.changeICCPIN(options);
|
||||
@ -1027,14 +1027,27 @@ let RIL = {
|
||||
options.success = false;
|
||||
this.sendDOMMessage(options);
|
||||
}
|
||||
} else { // Enable/Disable pin lock.
|
||||
if (options.lockType != "pin") {
|
||||
options.errorMsg = "Unsupported Card Lock.";
|
||||
options.success = false;
|
||||
this.sendDOMMessage(options);
|
||||
return;
|
||||
} else { // Enable/Disable lock.
|
||||
switch (options.lockType) {
|
||||
case "pin":
|
||||
options.facility = ICC_CB_FACILITY_SIM;
|
||||
options.password = options.pin;
|
||||
break;
|
||||
case "fdn":
|
||||
options.facility = ICC_CB_FACILITY_FDN;
|
||||
options.password = options.pin2;
|
||||
break;
|
||||
default:
|
||||
options.errorMsg = "Unsupported Card Lock.";
|
||||
options.success = false;
|
||||
this.sendDOMMessage(options);
|
||||
return;
|
||||
}
|
||||
this.setICCPinLock(options);
|
||||
options.enabled = options.enabled;
|
||||
options.serviceClass = ICC_SERVICE_CLASS_VOICE |
|
||||
ICC_SERVICE_CLASS_DATA |
|
||||
ICC_SERVICE_CLASS_FAX;
|
||||
this.setICCFacilityLock(options);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1127,23 +1140,18 @@ let RIL = {
|
||||
iccGetCardLock: function iccGetCardLock(options) {
|
||||
switch (options.lockType) {
|
||||
case "pin":
|
||||
this.getICCPinLock(options);
|
||||
options.facility = ICC_CB_FACILITY_SIM;
|
||||
break;
|
||||
case "fdn":
|
||||
options.facility = ICC_CB_FACILITY_FDN;
|
||||
break;
|
||||
default:
|
||||
options.errorMsg = "Unsupported Card Lock.";
|
||||
options.success = false;
|
||||
this.sendDOMMessage(options);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get ICC Pin lock. A wrapper call to queryICCFacilityLock.
|
||||
*
|
||||
* @param requestId
|
||||
* Request Id from RadioInterfaceLayer.
|
||||
*/
|
||||
getICCPinLock: function getICCPinLock(options) {
|
||||
options.facility = ICC_CB_FACILITY_SIM;
|
||||
options.password = ""; // For query no need to provide pin.
|
||||
options.serviceClass = ICC_SERVICE_CLASS_VOICE |
|
||||
ICC_SERVICE_CLASS_DATA |
|
||||
@ -1175,26 +1183,6 @@ let RIL = {
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set ICC Pin lock. A wrapper call to setICCFacilityLock.
|
||||
*
|
||||
* @param enabled
|
||||
* true to enable, false to disable.
|
||||
* @param pin
|
||||
* Pin code.
|
||||
* @param requestId
|
||||
* Request Id from RadioInterfaceLayer.
|
||||
*/
|
||||
setICCPinLock: function setICCPinLock(options) {
|
||||
options.facility = ICC_CB_FACILITY_SIM;
|
||||
options.enabled = options.enabled;
|
||||
options.password = options.pin;
|
||||
options.serviceClass = ICC_SERVICE_CLASS_VOICE |
|
||||
ICC_SERVICE_CLASS_DATA |
|
||||
ICC_SERVICE_CLASS_FAX;
|
||||
this.setICCFacilityLock(options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set ICC facility lock.
|
||||
*
|
||||
@ -7424,6 +7412,11 @@ let StkCommandParamsFactory = {
|
||||
textMsg.responseNeeded = true;
|
||||
}
|
||||
|
||||
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_DURATION, ctlvs);
|
||||
if (ctlv) {
|
||||
textMsg.duration = ctlv.value;
|
||||
}
|
||||
|
||||
// High priority.
|
||||
if (cmdDetails.commandQualifier & 0x01) {
|
||||
textMsg.isHighPriority = true;
|
||||
@ -7588,6 +7581,12 @@ let StkCommandParamsFactory = {
|
||||
}
|
||||
call.address = ctlv.value.number;
|
||||
|
||||
// see 3GPP TS 31.111 section 6.4.13
|
||||
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_DURATION, ctlvs);
|
||||
if (ctlv) {
|
||||
call.duration = ctlv.value;
|
||||
}
|
||||
|
||||
return call;
|
||||
},
|
||||
|
||||
|
@ -506,6 +506,44 @@ add_test(function test_send_stk_terminal_profile() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify RIL.iccGetCardLock("fdn")
|
||||
*/
|
||||
add_test(function test_icc_get_card_lock_fdn() {
|
||||
let worker = newUint8Worker();
|
||||
let ril = worker.RIL;
|
||||
let buf = worker.Buf;
|
||||
|
||||
buf.sendParcel = function () {
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_QUERY_FACILITY_LOCK)
|
||||
|
||||
// Token : we don't care.
|
||||
this.readUint32();
|
||||
|
||||
// String Array Length.
|
||||
do_check_eq(this.readUint32(), 4);
|
||||
|
||||
// Facility.
|
||||
do_check_eq(this.readString(), ICC_CB_FACILITY_FDN);
|
||||
|
||||
// Password.
|
||||
do_check_eq(this.readString(), "");
|
||||
|
||||
// Service class.
|
||||
do_check_eq(this.readString(), (ICC_SERVICE_CLASS_VOICE |
|
||||
ICC_SERVICE_CLASS_DATA |
|
||||
ICC_SERVICE_CLASS_FAX).toString());
|
||||
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readUint32();
|
||||
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
ril.iccGetCardLock({lockType: "fdn"});
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ComprehensionTlvHelper.writeLocationInfoTlv
|
||||
*/
|
||||
|
@ -193,7 +193,7 @@ struct WorkerStructuredCloneCallbacks
|
||||
|
||||
// Read the information out of the stream.
|
||||
uint32_t width, height;
|
||||
jsval dataArray;
|
||||
JS::Value dataArray;
|
||||
if (!JS_ReadUint32Pair(aReader, &width, &height) ||
|
||||
!JS_ReadTypedArray(aReader, &dataArray))
|
||||
{
|
||||
@ -203,7 +203,7 @@ struct WorkerStructuredCloneCallbacks
|
||||
|
||||
// Construct the ImageData.
|
||||
JSObject* obj = imagedata::Create(aCx, width, height,
|
||||
JSVAL_TO_OBJECT(dataArray));
|
||||
&dataArray.toObject());
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ struct MainThreadWorkerStructuredCloneCallbacks
|
||||
|
||||
// nsIDOMFiles should be threadsafe, thus we will use the same instance
|
||||
// on the main thread.
|
||||
jsval wrappedFile;
|
||||
JS::Value wrappedFile;
|
||||
nsresult rv =
|
||||
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), file,
|
||||
&NS_GET_IID(nsIDOMFile), &wrappedFile);
|
||||
@ -315,7 +315,7 @@ struct MainThreadWorkerStructuredCloneCallbacks
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return JSVAL_TO_OBJECT(wrappedFile);
|
||||
return &wrappedFile.toObject();
|
||||
}
|
||||
}
|
||||
// See if object is a nsIDOMBlob pointer.
|
||||
@ -339,7 +339,7 @@ struct MainThreadWorkerStructuredCloneCallbacks
|
||||
|
||||
// nsIDOMBlobs should be threadsafe, thus we will use the same instance
|
||||
// on the main thread.
|
||||
jsval wrappedBlob;
|
||||
JS::Value wrappedBlob;
|
||||
nsresult rv =
|
||||
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), blob,
|
||||
&NS_GET_IID(nsIDOMBlob), &wrappedBlob);
|
||||
@ -348,7 +348,7 @@ struct MainThreadWorkerStructuredCloneCallbacks
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return JSVAL_TO_OBJECT(wrappedBlob);
|
||||
return &wrappedBlob.toObject();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2156,8 +2156,9 @@ WorkerPrivateParent<Derived>::ForgetMainThreadObjects(
|
||||
|
||||
template <class Derived>
|
||||
bool
|
||||
WorkerPrivateParent<Derived>::PostMessage(JSContext* aCx, jsval aMessage,
|
||||
jsval aTransferable)
|
||||
WorkerPrivateParent<Derived>::PostMessage(JSContext* aCx,
|
||||
JS::Value aMessage,
|
||||
JS::Value aTransferable)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
|
@ -349,7 +349,7 @@ public:
|
||||
ForgetMainThreadObjects(nsTArray<nsCOMPtr<nsISupports> >& aDoomed);
|
||||
|
||||
bool
|
||||
PostMessage(JSContext* aCx, jsval aMessage, jsval aTransferable);
|
||||
PostMessage(JSContext* aCx, JS::Value aMessage, JS::Value aTransferable);
|
||||
|
||||
uint64_t
|
||||
GetInnerWindowId();
|
||||
|
File diff suppressed because it is too large
Load Diff
1151
gfx/gl/GLContext.h
1151
gfx/gl/GLContext.h
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,7 @@
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxPoint.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "SurfaceTypes.h"
|
||||
|
||||
class nsIWidget;
|
||||
class gfxASurface;
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "sampler.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
@ -84,25 +86,14 @@ class GLContextCGL : public GLContext
|
||||
friend class GLContextProviderCGL;
|
||||
|
||||
public:
|
||||
GLContextCGL(const ContextFormat& aFormat,
|
||||
GLContext *aShareContext,
|
||||
NSOpenGLContext *aContext,
|
||||
bool aIsOffscreen = false)
|
||||
: GLContext(aFormat, aIsOffscreen, aShareContext),
|
||||
mContext(aContext),
|
||||
mPBuffer(nullptr),
|
||||
GLContextCGL(const SurfaceCaps& caps,
|
||||
GLContext *shareContext,
|
||||
NSOpenGLContext *context,
|
||||
bool isOffscreen = false)
|
||||
: GLContext(caps, shareContext, isOffscreen),
|
||||
mContext(context),
|
||||
mTempTextureName(0)
|
||||
{ }
|
||||
|
||||
GLContextCGL(const ContextFormat& aFormat,
|
||||
GLContext *aShareContext,
|
||||
NSOpenGLContext *aContext,
|
||||
NSOpenGLPixelBuffer *aPixelBuffer)
|
||||
: GLContext(aFormat, true, aShareContext),
|
||||
mContext(aContext),
|
||||
mPBuffer(aPixelBuffer),
|
||||
mTempTextureName(0)
|
||||
{ }
|
||||
{}
|
||||
|
||||
~GLContextCGL()
|
||||
{
|
||||
@ -110,9 +101,6 @@ public:
|
||||
|
||||
if (mContext)
|
||||
[mContext release];
|
||||
|
||||
if (mPBuffer)
|
||||
[mPBuffer release];
|
||||
}
|
||||
|
||||
GLContextType GetContextType() {
|
||||
@ -180,8 +168,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BindTex2DOffscreen(GLContext *aOffscreen);
|
||||
void UnbindTex2DOffscreen(GLContext *aOffscreen);
|
||||
bool ResizeOffscreen(const gfxIntSize& aNewSize);
|
||||
|
||||
virtual already_AddRefed<TextureImage>
|
||||
@ -193,99 +179,13 @@ public:
|
||||
TextureImage::Flags aFlags = TextureImage::NoFlags);
|
||||
|
||||
NSOpenGLContext *mContext;
|
||||
NSOpenGLPixelBuffer *mPBuffer;
|
||||
GLuint mTempTextureName;
|
||||
};
|
||||
|
||||
bool
|
||||
GLContextCGL::BindTex2DOffscreen(GLContext *aOffscreen)
|
||||
{
|
||||
if (aOffscreen->GetContextType() != ContextTypeCGL) {
|
||||
NS_WARNING("non-CGL context");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aOffscreen->IsOffscreen()) {
|
||||
NS_WARNING("non-offscreen context");
|
||||
return false;
|
||||
}
|
||||
|
||||
GLContextCGL *offs = static_cast<GLContextCGL*>(aOffscreen);
|
||||
|
||||
if (offs->mPBuffer) {
|
||||
fGenTextures(1, &mTempTextureName);
|
||||
fBindTexture(LOCAL_GL_TEXTURE_2D, mTempTextureName);
|
||||
|
||||
[mContext
|
||||
setTextureImageToPixelBuffer:offs->mPBuffer
|
||||
colorBuffer:LOCAL_GL_FRONT];
|
||||
} else if (offs->mOffscreenTexture) {
|
||||
if (offs->GetSharedContext() != GLContextProviderCGL::GetGlobalContext())
|
||||
{
|
||||
NS_WARNING("offscreen FBO context can only be bound with context sharing!");
|
||||
return false;
|
||||
}
|
||||
|
||||
fBindTexture(LOCAL_GL_TEXTURE_2D, offs->mOffscreenTexture);
|
||||
} else {
|
||||
NS_WARNING("don't know how to bind this!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GLContextCGL::UnbindTex2DOffscreen(GLContext *aOffscreen)
|
||||
{
|
||||
NS_ASSERTION(aOffscreen->GetContextType() == ContextTypeCGL, "wrong type");
|
||||
|
||||
GLContextCGL *offs = static_cast<GLContextCGL*>(aOffscreen);
|
||||
if (offs->mPBuffer) {
|
||||
NS_ASSERTION(mTempTextureName, "We didn't have an offscreen texture name?");
|
||||
fDeleteTextures(1, &mTempTextureName);
|
||||
mTempTextureName = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GLContextCGL::ResizeOffscreen(const gfxIntSize& aNewSize)
|
||||
{
|
||||
if (!IsOffscreenSizeAllowed(aNewSize))
|
||||
return false;
|
||||
|
||||
if (mPBuffer) {
|
||||
NSOpenGLPixelBuffer *pb = [[NSOpenGLPixelBuffer alloc]
|
||||
initWithTextureTarget:LOCAL_GL_TEXTURE_2D
|
||||
textureInternalFormat:(mCreationFormat.alpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB)
|
||||
textureMaxMipMapLevel:0
|
||||
pixelsWide:aNewSize.width
|
||||
pixelsHigh:aNewSize.height];
|
||||
if (!pb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ResizeOffscreenFBOs(aNewSize, false)) {
|
||||
[pb release];
|
||||
return false;
|
||||
}
|
||||
|
||||
[mPBuffer release];
|
||||
mPBuffer = pb;
|
||||
|
||||
mOffscreenSize = aNewSize;
|
||||
mOffscreenActualSize = aNewSize;
|
||||
|
||||
[mContext setPixelBuffer:pb cubeMapFace:0 mipMapLevel:0
|
||||
currentVirtualScreen:[mContext currentVirtualScreen]];
|
||||
|
||||
MakeCurrent();
|
||||
ClearSafely();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return ResizeOffscreenFBOs(aNewSize, true);
|
||||
return ResizeScreenBuffer(aNewSize);
|
||||
}
|
||||
|
||||
class TextureImageCGL : public BasicTextureImage
|
||||
@ -431,7 +331,8 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
|
||||
}
|
||||
|
||||
// make the context transparent
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(ContextFormat(ContextFormat::BasicRGB24),
|
||||
SurfaceCaps caps = SurfaceCaps::ForRGBA();
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(caps,
|
||||
shareContext,
|
||||
context);
|
||||
if (!glContext->Init()) {
|
||||
@ -442,102 +343,7 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContextCGL>
|
||||
CreateOffscreenPBufferContext(const gfxIntSize& aSize,
|
||||
const ContextFormat& aFormat,
|
||||
bool aShare = false)
|
||||
{
|
||||
if (!sCGLLibrary.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
|
||||
if (aShare && !shareContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTArray<NSOpenGLPixelFormatAttribute> attribs;
|
||||
|
||||
#define A_(_x) attribs.AppendElement(NSOpenGLPixelFormatAttribute(_x))
|
||||
A_(NSOpenGLPFAAccelerated);
|
||||
A_(NSOpenGLPFAPixelBuffer);
|
||||
A_(NSOpenGLPFAMinimumPolicy);
|
||||
|
||||
A_(NSOpenGLPFAColorSize);
|
||||
A_(aFormat.colorBits());
|
||||
|
||||
A_(NSOpenGLPFAAlphaSize);
|
||||
A_(aFormat.alpha);
|
||||
|
||||
A_(NSOpenGLPFADepthSize);
|
||||
A_(aFormat.depth);
|
||||
|
||||
A_(NSOpenGLPFAStencilSize);
|
||||
A_(aFormat.stencil);
|
||||
|
||||
A_(0);
|
||||
#undef A_
|
||||
|
||||
NSOpenGLPixelFormat *pbFormat = [[NSOpenGLPixelFormat alloc]
|
||||
initWithAttributes:attribs.Elements()];
|
||||
if (!pbFormat) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If we ask for any of these to be on/off and we get the opposite, we stop
|
||||
// creating a pbuffer and instead create an FBO.
|
||||
GLint alphaBits, depthBits, stencilBits;
|
||||
[pbFormat getValues: &alphaBits forAttribute: NSOpenGLPFAAlphaSize forVirtualScreen: 0];
|
||||
[pbFormat getValues: &depthBits forAttribute: NSOpenGLPFADepthSize forVirtualScreen: 0];
|
||||
[pbFormat getValues: &stencilBits forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: 0];
|
||||
if ((alphaBits && !aFormat.alpha) || (!alphaBits && aFormat.alpha) ||
|
||||
(depthBits && !aFormat.alpha) || (!depthBits && aFormat.depth) ||
|
||||
(stencilBits && !aFormat.stencil) || (!stencilBits && aFormat.stencil))
|
||||
{
|
||||
[pbFormat release];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NSOpenGLPixelBuffer *pb = [[NSOpenGLPixelBuffer alloc]
|
||||
initWithTextureTarget:LOCAL_GL_TEXTURE_2D
|
||||
textureInternalFormat:(aFormat.alpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB)
|
||||
textureMaxMipMapLevel:0
|
||||
pixelsWide:aSize.width
|
||||
pixelsHigh:aSize.height];
|
||||
if (!pb) {
|
||||
[pbFormat release];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NSOpenGLContext *context = [[NSOpenGLContext alloc]
|
||||
initWithFormat:pbFormat
|
||||
shareContext:shareContext ? shareContext->mContext : NULL];
|
||||
if (!context) {
|
||||
[pbFormat release];
|
||||
[pb release];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[context
|
||||
setPixelBuffer:pb
|
||||
cubeMapFace:0
|
||||
mipMapLevel:0
|
||||
currentVirtualScreen:[context currentVirtualScreen]];
|
||||
|
||||
{
|
||||
GLint l;
|
||||
[pbFormat getValues:&l forAttribute:NSOpenGLPFADepthSize forVirtualScreen:[context currentVirtualScreen]];
|
||||
}
|
||||
|
||||
[pbFormat release];
|
||||
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(aFormat, shareContext, context, pb);
|
||||
|
||||
return glContext.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContextCGL>
|
||||
CreateOffscreenFBOContext(const ContextFormat& aFormat,
|
||||
bool aShare = true)
|
||||
CreateOffscreenFBOContext(bool aShare = true)
|
||||
{
|
||||
if (!sCGLLibrary.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
@ -556,41 +362,21 @@ CreateOffscreenFBOContext(const ContextFormat& aFormat,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(aFormat, shareContext, context, true);
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
|
||||
|
||||
return glContext.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderCGL::CreateOffscreen(const gfxIntSize& aSize,
|
||||
const ContextFormat& aFormat,
|
||||
GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
|
||||
const SurfaceCaps& caps,
|
||||
const ContextFlags flags)
|
||||
{
|
||||
ContextFormat actualFormat(aFormat);
|
||||
|
||||
nsRefPtr<GLContextCGL> glContext;
|
||||
|
||||
NS_ENSURE_TRUE(Preferences::GetRootBranch(), nullptr);
|
||||
const bool preferFBOs = Preferences::GetBool("cgl.prefer-fbo", true);
|
||||
if (!preferFBOs)
|
||||
{
|
||||
glContext = CreateOffscreenPBufferContext(aSize, actualFormat);
|
||||
if (glContext &&
|
||||
glContext->Init() &&
|
||||
glContext->ResizeOffscreenFBOs(aSize, false))
|
||||
{
|
||||
glContext->mOffscreenSize = aSize;
|
||||
glContext->mOffscreenActualSize = aSize;
|
||||
|
||||
return glContext.forget();
|
||||
}
|
||||
}
|
||||
|
||||
// try a FBO as second choice
|
||||
glContext = CreateOffscreenFBOContext(actualFormat);
|
||||
nsRefPtr<GLContextCGL> glContext = CreateOffscreenFBOContext();
|
||||
if (glContext &&
|
||||
glContext->Init() &&
|
||||
glContext->ResizeOffscreenFBOs(aSize, true))
|
||||
glContext->InitOffscreen(size, caps))
|
||||
{
|
||||
return glContext.forget();
|
||||
}
|
||||
@ -613,8 +399,7 @@ GLContextProviderCGL::GetGlobalContext(const ContextFlags)
|
||||
// than 16x16 in size; also 16x16 is POT so that we can do
|
||||
// a FBO with it on older video cards. A FBO context for
|
||||
// sharing is preferred since it has no associated target.
|
||||
gGlobalContext = CreateOffscreenFBOContext(ContextFormat(ContextFormat::BasicRGB24),
|
||||
false);
|
||||
gGlobalContext = CreateOffscreenFBOContext(false);
|
||||
if (!gGlobalContext || !static_cast<GLContextCGL*>(gGlobalContext.get())->Init()) {
|
||||
NS_WARNING("Couldn't init gGlobalContext.");
|
||||
gGlobalContext = nullptr;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user