mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team, a=merge CLOSED TREE
This commit is contained in:
commit
4df9511095
@ -11,6 +11,7 @@
|
||||
#include "InterfaceInitFuncs.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "mozilla/a11y/PDocAccessible.h"
|
||||
#include "OuterDocAccessible.h"
|
||||
#include "ProxyAccessible.h"
|
||||
#include "RootAccessible.h"
|
||||
#include "nsMai.h"
|
||||
@ -96,7 +97,7 @@ static GType GetAtkTypeForMai(MaiInterfaceType type)
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
||||
static const char* kNonUserInputEvent = ":system";
|
||||
#define NON_USER_EVENT ":system"
|
||||
|
||||
static const GInterfaceInfo atk_if_infos[] = {
|
||||
{(GInterfaceInitFunc)componentInterfaceInitCB,
|
||||
@ -828,26 +829,45 @@ getChildCountCB(AtkObject *aAtkObj)
|
||||
AtkObject *
|
||||
refChildCB(AtkObject *aAtkObj, gint aChildIndex)
|
||||
{
|
||||
// aChildIndex should not be less than zero
|
||||
if (aChildIndex < 0) {
|
||||
// aChildIndex should not be less than zero
|
||||
if (aChildIndex < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AtkObject* childAtkObj = nullptr;
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
||||
if (accWrap) {
|
||||
if (nsAccUtils::MustPrune(accWrap)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
||||
if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Accessible* accChild = accWrap->GetEmbeddedChildAt(aChildIndex);
|
||||
if (!accChild)
|
||||
return nullptr;
|
||||
if (accChild) {
|
||||
childAtkObj = AccessibleWrap::GetAtkObject(accChild);
|
||||
} else {
|
||||
OuterDocAccessible* docOwner = accWrap->AsOuterDoc();
|
||||
if (docOwner) {
|
||||
ProxyAccessible* proxyDoc = docOwner->RemoteChildDoc();
|
||||
if (proxyDoc)
|
||||
childAtkObj = GetWrapperFor(proxyDoc);
|
||||
}
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
|
||||
if (proxy->MustPruneChildren())
|
||||
return nullptr;
|
||||
|
||||
AtkObject* childAtkObj = AccessibleWrap::GetAtkObject(accChild);
|
||||
ProxyAccessible* child = proxy->EmbeddedChildAt(aChildIndex);
|
||||
if (child)
|
||||
childAtkObj = GetWrapperFor(child);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
|
||||
if (!childAtkObj)
|
||||
return nullptr;
|
||||
g_object_ref(childAtkObj);
|
||||
NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
|
||||
if (!childAtkObj)
|
||||
return nullptr;
|
||||
|
||||
g_object_ref(childAtkObj);
|
||||
|
||||
if (aAtkObj != childAtkObj->accessible_parent)
|
||||
atk_object_set_parent(childAtkObj, aAtkObj);
|
||||
@ -1431,6 +1451,21 @@ MaiAtkObject::FireStateChangeEvent(uint64_t aState, bool aEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
#define OLD_TEXT_INSERTED "text_changed::insert"
|
||||
#define OLD_TEXT_REMOVED "text_changed::delete"
|
||||
static const char* oldTextChangeStrings[2][2] = {
|
||||
{ OLD_TEXT_REMOVED NON_USER_EVENT, OLD_TEXT_INSERTED NON_USER_EVENT },
|
||||
{ OLD_TEXT_REMOVED, OLD_TEXT_INSERTED }
|
||||
};
|
||||
|
||||
#define TEXT_INSERTED "text-insert"
|
||||
#define TEXT_REMOVED "text-remove"
|
||||
#define NON_USER_DETAIL "::system"
|
||||
static const char* textChangedStrings[2][2] = {
|
||||
{ TEXT_REMOVED NON_USER_DETAIL, TEXT_INSERTED NON_USER_DETAIL },
|
||||
{ TEXT_REMOVED, TEXT_INSERTED}
|
||||
};
|
||||
|
||||
nsresult
|
||||
AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
|
||||
AtkObject* aObject)
|
||||
@ -1442,7 +1477,6 @@ AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
|
||||
uint32_t length = event->GetLength();
|
||||
bool isInserted = event->IsTextInserted();
|
||||
bool isFromUserInput = aEvent->IsFromUserInput();
|
||||
char* signal_name = nullptr;
|
||||
|
||||
if (gAvailableAtkSignals == eUnknown)
|
||||
gAvailableAtkSignals =
|
||||
@ -1453,23 +1487,29 @@ AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
|
||||
// XXX remove this code and the gHaveNewTextSignals check when we can
|
||||
// stop supporting old atk since it doesn't really work anyway
|
||||
// see bug 619002
|
||||
signal_name = g_strconcat(isInserted ? "text_changed::insert" :
|
||||
"text_changed::delete",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, nullptr);
|
||||
const char* signal_name =
|
||||
oldTextChangeStrings[isFromUserInput][isInserted];
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length);
|
||||
} else {
|
||||
nsAutoString text;
|
||||
event->GetModifiedText(text);
|
||||
signal_name = g_strconcat(isInserted ? "text-insert" : "text-remove",
|
||||
isFromUserInput ? "" : "::system", nullptr);
|
||||
const char* signal_name =
|
||||
textChangedStrings[isFromUserInput][isInserted];
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length,
|
||||
NS_ConvertUTF16toUTF8(text).get());
|
||||
}
|
||||
|
||||
g_free(signal_name);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define ADD_EVENT "children_changed::add"
|
||||
#define HIDE_EVENT "children_changed::remove"
|
||||
|
||||
static const char *kMutationStrings[2][2] = {
|
||||
{ HIDE_EVENT NON_USER_EVENT, ADD_EVENT NON_USER_EVENT },
|
||||
{ HIDE_EVENT, ADD_EVENT },
|
||||
};
|
||||
|
||||
nsresult
|
||||
AccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
|
||||
AtkObject* aObject, bool aIsAdded)
|
||||
@ -1479,10 +1519,8 @@ AccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
|
||||
NS_ENSURE_STATE(parentObject);
|
||||
|
||||
bool isFromUserInput = aEvent->IsFromUserInput();
|
||||
char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" : "children_changed::remove",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, nullptr);
|
||||
const char *signal_name = kMutationStrings[isFromUserInput][aIsAdded];
|
||||
g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, nullptr);
|
||||
g_free(signal_name);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class HTMLLIAccessible;
|
||||
class HyperTextAccessible;
|
||||
class ImageAccessible;
|
||||
class KeyBinding;
|
||||
class OuterDocAccessible;
|
||||
class ProxyAccessible;
|
||||
class Relation;
|
||||
class RootAccessible;
|
||||
@ -619,6 +620,9 @@ public:
|
||||
return mBits.proxy;
|
||||
}
|
||||
|
||||
bool IsOuterDoc() const { return mType == eOuterDocType; }
|
||||
OuterDocAccessible* AsOuterDoc();
|
||||
|
||||
bool IsProgress() const { return mType == eProgressType; }
|
||||
|
||||
bool IsRoot() const { return mType == eRootType; }
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "Accessible-inl.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "DocAccessible-inl.h"
|
||||
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
|
||||
@ -26,6 +28,7 @@ OuterDocAccessible::
|
||||
OuterDocAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
AccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
mType = eOuterDocType;
|
||||
}
|
||||
|
||||
OuterDocAccessible::~OuterDocAccessible()
|
||||
@ -181,3 +184,24 @@ OuterDocAccessible::CacheChildren()
|
||||
GetAccService()->GetDocAccessible(innerDoc);
|
||||
}
|
||||
}
|
||||
|
||||
ProxyAccessible*
|
||||
OuterDocAccessible::RemoteChildDoc() const
|
||||
{
|
||||
dom::TabParent* tab = dom::TabParent::GetFrom(GetContent());
|
||||
if (!tab)
|
||||
return nullptr;
|
||||
|
||||
// XXX Consider managing non top level remote documents with there parent
|
||||
// document.
|
||||
const nsTArray<PDocAccessibleParent*>& docs = tab->ManagedPDocAccessibleParent();
|
||||
size_t docCount = docs.Length();
|
||||
for (size_t i = 0; i < docCount; i++) {
|
||||
auto doc = static_cast<DocAccessibleParent*>(docs[i]);
|
||||
if (!doc->ParentDoc())
|
||||
return doc;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false, "no top level tab document?");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
class ProxyAccessible;
|
||||
|
||||
/**
|
||||
* Used for <browser>, <frame>, <iframe>, <page> or editor> elements.
|
||||
@ -27,6 +28,8 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
ProxyAccessible* RemoteChildDoc() const;
|
||||
|
||||
// Accessible
|
||||
virtual void Shutdown() override;
|
||||
virtual mozilla::a11y::role NativeRole() override;
|
||||
@ -44,6 +47,11 @@ protected:
|
||||
virtual void CacheChildren() override;
|
||||
};
|
||||
|
||||
inline OuterDocAccessible*
|
||||
Accessible::AsOuterDoc()
|
||||
{
|
||||
return IsOuterDoc() ? static_cast<OuterDocAccessible*>(this) : nullptr;
|
||||
}
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -1637,6 +1637,21 @@ DocAccessibleChild::RecvIndexOfEmbeddedChild(const uint64_t& aID,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvEmbeddedChildAt(const uint64_t& aID,
|
||||
const uint32_t& aIdx,
|
||||
uint64_t* aChildID)
|
||||
{
|
||||
*aChildID = 0;
|
||||
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (!acc)
|
||||
return true;
|
||||
|
||||
*aChildID = reinterpret_cast<uintptr_t>(acc->GetEmbeddedChildAt(aIdx));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvChildAtPoint(const uint64_t& aID,
|
||||
const int32_t& aX,
|
||||
|
@ -408,6 +408,9 @@ public:
|
||||
const uint64_t& aChildID,
|
||||
uint32_t* aChildIdx) override final;
|
||||
|
||||
virtual bool RecvEmbeddedChildAt(const uint64_t& aID, const uint32_t& aIdx,
|
||||
uint64_t* aChildID) override final;
|
||||
|
||||
virtual bool RecvChildAtPoint(const uint64_t& aID,
|
||||
const int32_t& aX,
|
||||
const int32_t& aY,
|
||||
|
@ -213,8 +213,11 @@ DocAccessibleParent::Destroy()
|
||||
|
||||
mAccessibles.EnumerateEntries(ShutdownAccessibles, nullptr);
|
||||
ProxyDestroyed(this);
|
||||
mParentDoc ? mParentDoc->RemoveChildDoc(this)
|
||||
: GetAccService()->RemoteDocShutdown(this);
|
||||
}
|
||||
}
|
||||
if (mParentDoc)
|
||||
mParentDoc->RemoveChildDoc(this);
|
||||
else if (IsTopLevel())
|
||||
GetAccService()->RemoteDocShutdown(this);
|
||||
}
|
||||
|
||||
} // a11y
|
||||
} // mozilla
|
||||
|
@ -26,7 +26,8 @@ class DocAccessibleParent : public ProxyAccessible,
|
||||
{
|
||||
public:
|
||||
DocAccessibleParent() :
|
||||
ProxyAccessible(this), mParentDoc(nullptr), mShutdown(false)
|
||||
ProxyAccessible(this), mParentDoc(nullptr),
|
||||
mTopLevel(false), mShutdown(false)
|
||||
{ MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
|
||||
~DocAccessibleParent()
|
||||
{
|
||||
@ -35,6 +36,9 @@ public:
|
||||
MOZ_ASSERT(!ParentDoc());
|
||||
}
|
||||
|
||||
void SetTopLevel() { mTopLevel = true; }
|
||||
bool IsTopLevel() const { return mTopLevel; }
|
||||
|
||||
/*
|
||||
* Called when a message from a document in a child process notifies the main
|
||||
* process it is firing an event.
|
||||
@ -151,6 +155,7 @@ private:
|
||||
* proxy object so we can't use a real map.
|
||||
*/
|
||||
nsTHashtable<ProxyEntry> mAccessibles;
|
||||
bool mTopLevel;
|
||||
bool mShutdown;
|
||||
};
|
||||
|
||||
|
@ -218,6 +218,8 @@ child:
|
||||
prio(high) sync TakeFocus(uint64_t aID);
|
||||
prio(high) sync IndexOfEmbeddedChild(uint64_t aID, uint64_t aChildID)
|
||||
returns(uint32_t childIdx);
|
||||
prio(high) sync EmbeddedChildAt(uint64_t aID, uint32_t aChildIdx)
|
||||
returns(uint64_t aChild);
|
||||
prio(high) sync ChildAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aWhich)
|
||||
returns(uint64_t aChild, bool aOk);
|
||||
prio(high) sync Bounds(uint64_t aID) returns(nsIntRect aRect);
|
||||
|
@ -916,6 +916,14 @@ ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
|
||||
return childIdx;
|
||||
}
|
||||
|
||||
ProxyAccessible*
|
||||
ProxyAccessible::EmbeddedChildAt(size_t aChildIdx)
|
||||
{
|
||||
uint64_t childID;
|
||||
unused << mDoc->SendEmbeddedChildAt(mID, aChildIdx, &childID);
|
||||
return mDoc->GetAccessible(childID);
|
||||
}
|
||||
|
||||
ProxyAccessible*
|
||||
ProxyAccessible::ChildAtPoint(int32_t aX, int32_t aY,
|
||||
Accessible::EWhichChildAtPoint aWhichChild)
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
// XXX evaluate if this is fast enough.
|
||||
size_t IndexInParent() const { return Parent()->mChildren.IndexOf(this); }
|
||||
int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
|
||||
ProxyAccessible* EmbeddedChildAt(size_t aChildIdx);
|
||||
bool MustPruneChildren() const;
|
||||
|
||||
void Shutdown();
|
||||
|
@ -600,12 +600,13 @@ struct RoleDescrComparator
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
if (accWrap->IsDefunct())
|
||||
return nil;
|
||||
|
||||
nsAutoString desc;
|
||||
accWrap->Description(desc);
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
accWrap->Description(desc);
|
||||
else if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
proxy->Description(desc);
|
||||
else
|
||||
return nil;
|
||||
|
||||
return nsCocoaUtils::ToNSString(desc);
|
||||
|
||||
|
@ -1004,6 +1004,10 @@ pref("network.proxy.browsing.app_origins", "app://system.gaiamobile.org");
|
||||
// Enable Web Speech synthesis API
|
||||
pref("media.webspeech.synth.enabled", true);
|
||||
|
||||
// Enable Web Speech recognition API
|
||||
pref("media.webspeech.recognition.enable", true);
|
||||
pref("media.webspeech.service.default", "pocketsphinx");
|
||||
|
||||
// Downloads API
|
||||
pref("dom.mozDownloads.enabled", true);
|
||||
pref("dom.downloads.max_retention_days", 7);
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "d2f31eb85837aae6eca04d022d1f5b2023bc778c",
|
||||
"git_revision": "9f36b711af7597a6a32471c3305cf1e2d6947d39",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "2e9a1e5808b983fe4aa50a169b0e36fb3f0b43a3",
|
||||
"revision": "8583025b84cda74c63e83bbbdfd7a4f33b917f20",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
@ -29,13 +29,12 @@ NSS_DISABLE_DBM=1
|
||||
MOZ_NO_EV_CERTS=1
|
||||
MOZ_DISABLE_EXPORT_JS=1
|
||||
|
||||
# Bug 1171082 - Broken on Windows B2G Desktop
|
||||
if test "$OS_TARGET" != "WINNT"; then
|
||||
MOZ_WEBSPEECH=1
|
||||
if test -n "$NIGHTLY_BUILD"; then
|
||||
MOZ_WEBSPEECH_MODELS=1
|
||||
MOZ_WEBSPEECH_POCKETSPHINX=1
|
||||
fi
|
||||
MOZ_WEBSPEECH_TEST_BACKEND=1
|
||||
fi # !WINNT
|
||||
|
||||
if test "$OS_TARGET" = "Android"; then
|
||||
MOZ_CAPTURE=1
|
||||
|
@ -1235,9 +1235,14 @@
|
||||
|
||||
<svg:svg height="0">
|
||||
#include tab-shape.inc.svg
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
<svg:clipPath id="urlbar-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
<svg:path d="m 1,-5 l 0,50 l 10000,0 l 0,-50 z"/>
|
||||
</svg:clipPath>
|
||||
#endif
|
||||
<svg:clipPath id="urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
#ifndef XP_MACOSX
|
||||
<svg:path d="m 1,-5 l 0,7.8 c 2.5,3.2 4,6.2 4,10.2 c 0,4 -1.5,7 -4,10 l 0,22l10000,0 l 0,-50 l -10000,0 z"/>
|
||||
<svg:path d="m 1,-5 l 0,7.8 c 2.5,3.2 4,6.2 4,10.2 c 0,4 -1.5,7 -4,10 l 0,22 l 10000,0 l 0,-50 l -10000,0 z"/>
|
||||
#else
|
||||
<svg:path d="M -11,-5 a 16 16 0 0 1 0,34 l 10000,0 l 0,-34 l -10000,0 z"/>
|
||||
#endif
|
||||
|
@ -107,7 +107,8 @@ a setTimeout.
|
||||
|
||||
## GarbageCollection
|
||||
|
||||
Emitted after a full GC has occurred (which will emit past incremental events).
|
||||
Emitted after a full GC cycle has completed (which is after any number of
|
||||
incremental slices).
|
||||
|
||||
* DOMString causeName - The reason for a GC event to occur. A full list of
|
||||
GC reasons can be found [on MDN](https://developer.mozilla.org/en-US/docs/Tools/Debugger-API/Debugger.Memory#Debugger.Memory_Handler_Functions).
|
||||
@ -115,6 +116,17 @@ Emitted after a full GC has occurred (which will emit past incremental events).
|
||||
GC (smaller, quick GC events), and we have to walk the entire heap and
|
||||
GC everything marked, then the reason listed here is why.
|
||||
|
||||
## nsCycleCollector::Collect
|
||||
|
||||
An `nsCycleCollector::Collect` marker is emitted for each incremental cycle
|
||||
collection slice and each non-incremental cycle collection.
|
||||
|
||||
# nsCycleCollector::ForgetSkippable
|
||||
|
||||
`nsCycleCollector::ForgetSkippable` is presented as "Cycle Collection", but in
|
||||
reality it is preparation/pre-optimization for cycle collection, and not the
|
||||
actual tracing of edges and collecting of cycles.
|
||||
|
||||
## ConsoleTime
|
||||
|
||||
A marker generated via `console.time()` and `console.timeEnd()`.
|
||||
|
@ -435,6 +435,13 @@ const Formatters = {
|
||||
return { "Restyle Hint": marker.restyleHint.replace(/eRestyle_/g, "") };
|
||||
}
|
||||
},
|
||||
|
||||
CycleCollectionFields: function (marker) {
|
||||
let Type = PREFS["show-platform-data"]
|
||||
? marker.name
|
||||
: marker.name.replace(/nsCycleCollector::/g, "");
|
||||
return { Type };
|
||||
},
|
||||
};
|
||||
|
||||
exports.getMarkerLabel = getMarkerLabel;
|
||||
|
@ -113,6 +113,20 @@ const TIMELINE_BLUEPRINT = {
|
||||
{ property: "nonincrementalReason", label: "Non-incremental Reason:" }
|
||||
],
|
||||
},
|
||||
"nsCycleCollector::Collect": {
|
||||
group: 1,
|
||||
colorName: "graphs-red",
|
||||
collapseFunc: either(collapse.parent, collapse.child),
|
||||
label: "Cycle Collection",
|
||||
fields: Formatters.CycleCollectionFields,
|
||||
},
|
||||
"nsCycleCollector::ForgetSkippable": {
|
||||
group: 1,
|
||||
colorName: "graphs-red",
|
||||
collapseFunc: either(collapse.parent, collapse.child),
|
||||
label: "Cycle Collection",
|
||||
fields: Formatters.CycleCollectionFields,
|
||||
},
|
||||
|
||||
/* Group 2 - User Controlled */
|
||||
"ConsoleTime": {
|
||||
|
@ -2,6 +2,7 @@
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
doc_force_cc.html
|
||||
doc_force_gc.html
|
||||
doc_innerHTML.html
|
||||
doc_markers.html
|
||||
@ -13,6 +14,7 @@ support-files =
|
||||
|
||||
[browser_aaa-run-first-leaktest.js]
|
||||
[browser_marker-utils.js]
|
||||
[browser_markers-cycle-collection.js]
|
||||
[browser_markers-gc.js]
|
||||
[browser_markers-parse-html.js]
|
||||
[browser_markers-styles.js]
|
||||
|
@ -0,0 +1,50 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we get "nsCycleCollector::Collect" and
|
||||
* "nsCycleCollector::ForgetSkippable" markers when we force cycle collection.
|
||||
*/
|
||||
|
||||
const TEST_URL = EXAMPLE_URL + "doc_force_cc.html"
|
||||
|
||||
function waitForMarkerType(front, type) {
|
||||
info("Waiting for marker of type = " + type);
|
||||
const { promise, resolve } = Promise.defer();
|
||||
|
||||
const handler = (_, name, markers) => {
|
||||
if (name !== "markers") {
|
||||
return;
|
||||
}
|
||||
|
||||
info("Got markers: " + JSON.stringify(markers, null, 2));
|
||||
|
||||
if (markers.some(m => m.name === type)) {
|
||||
ok(true, "Found marker of type = " + type);
|
||||
front.off("timeline-data", handler);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
front.on("timeline-data", handler);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function* spawnTest () {
|
||||
// This test runs very slowly on linux32 debug EC2 instances.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let { target, front } = yield initBackend(TEST_URL);
|
||||
|
||||
yield front.startRecording({ withMarkers: true, withTicks: true });
|
||||
|
||||
yield Promise.all([
|
||||
waitForMarkerType(front, "nsCycleCollector::Collect"),
|
||||
waitForMarkerType(front, "nsCycleCollector::ForgetSkippable")
|
||||
]);
|
||||
ok(true, "Got expected cycle collection events");
|
||||
|
||||
yield front.stopRecording();
|
||||
yield removeTab(target.tab);
|
||||
finish();
|
||||
}
|
29
browser/devtools/performance/test/doc_force_cc.html
Normal file
29
browser/devtools/performance/test/doc_force_cc.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Performance tool + cycle collection test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
window.test = function () {
|
||||
document.body.expando1 = { cycle: document.body };
|
||||
SpecialPowers.Cu.forceCC();
|
||||
|
||||
document.body.expando2 = { cycle: document.body };
|
||||
SpecialPowers.Cu.forceCC();
|
||||
|
||||
document.body.expando3 = { cycle: document.body };
|
||||
SpecialPowers.Cu.forceCC();
|
||||
|
||||
setTimeout(window.test, 100);
|
||||
};
|
||||
test();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,6 +1,6 @@
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
skip-if = buildapp == 'b2g'
|
||||
skip-if = buildapp == 'b2g' || (os == "mac" && (os_version == "10.8" || os_version == "10.10") && debug) # Bug 1135315 - assertions
|
||||
support-files =
|
||||
app/index.html
|
||||
app/manifest.webapp
|
||||
|
@ -1,6 +1,6 @@
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
skip-if = buildapp == 'b2g'
|
||||
skip-if = buildapp == 'b2g' || (os == "mac" && (os_version == "10.8" || os_version == "10.10") && debug) # Bug 1135315 - assertions
|
||||
support-files =
|
||||
../app/index.html
|
||||
../app/manifest.webapp
|
||||
|
@ -313,6 +313,7 @@ let ProcessHangMonitor = {
|
||||
for (let [otherReport, otherTimer] of this._activeReports) {
|
||||
if (otherTimer === timer) {
|
||||
this.removeReport(otherReport);
|
||||
otherReport.userCanceled();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -680,17 +680,17 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
|
||||
}
|
||||
|
||||
#back-button {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
-moz-padding-start: 5px;
|
||||
-moz-padding-end: 0;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
-moz-margin-start: 5px;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 0 10000px 10000px 0;
|
||||
border-radius: 10000px;
|
||||
}
|
||||
|
||||
#back-button:-moz-locale-dir(rtl) {
|
||||
border-radius: 10000px 0 0 10000px;
|
||||
#back-button:not(:-moz-lwtheme) {
|
||||
background-color: -moz-dialog;
|
||||
}
|
||||
|
||||
#back-button > menupopup {
|
||||
@ -894,13 +894,17 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@ {
|
||||
clip-path: url("chrome://browser/content/browser.xul#urlbar-back-button-clip-path");
|
||||
clip-path: url("chrome://browser/content/browser.xul#urlbar-clip-path");
|
||||
-moz-margin-start: -5px;
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@:-moz-lwtheme {
|
||||
clip-path: url("chrome://browser/content/browser.xul#urlbar-back-button-clip-path");
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@:-moz-locale-dir(rtl),
|
||||
@conditionalForwardWithUrlbar@ > #urlbar:-moz-locale-dir(rtl) {
|
||||
/* let urlbar-back-button-clip-path clip the urlbar's right side for RTL */
|
||||
/* Let clip-path clip the urlbar-wrapper's right side for RTL. */
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,12 @@ OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
|
||||
return usp->ForEach(iterator);
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::CookieJar(nsACString& aStr)
|
||||
{
|
||||
mozilla::GetJarPrefix(mAppId, mInBrowser, aStr);
|
||||
}
|
||||
|
||||
BasePrincipal::BasePrincipal()
|
||||
{}
|
||||
|
||||
@ -223,7 +229,7 @@ BasePrincipal::GetJarPrefix(nsACString& aJarPrefix)
|
||||
{
|
||||
MOZ_ASSERT(AppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
mozilla::GetJarPrefix(AppId(), IsInBrowserElement(), aJarPrefix);
|
||||
mOriginAttributes.CookieJar(aJarPrefix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -246,10 +252,8 @@ BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetCookieJar(nsACString& aCookieJar)
|
||||
{
|
||||
// We just forward to .jarPrefix for now, which is a nice compact
|
||||
// stringification of the (appId, inBrowser) tuple. This will eventaully be
|
||||
// swapped out for an origin attribute - see the comment in nsIPrincipal.idl.
|
||||
return GetJarPrefix(aCookieJar);
|
||||
mOriginAttributes.CookieJar(aCookieJar);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
|
||||
#include "mozilla/dom/SystemDictionariesBinding.h"
|
||||
#include "mozilla/dom/ChromeUtilsBinding.h"
|
||||
|
||||
class nsIContentSecurityPolicy;
|
||||
class nsIObjectOutputStream;
|
||||
@ -28,6 +28,8 @@ public:
|
||||
mAppId = aAppId;
|
||||
mInBrowser = aInBrowser;
|
||||
}
|
||||
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
|
||||
: OriginAttributesDictionary(aOther) {}
|
||||
|
||||
bool operator==(const OriginAttributes& aOther) const
|
||||
{
|
||||
@ -44,6 +46,8 @@ public:
|
||||
// returns an empty string.
|
||||
void CreateSuffix(nsACString& aStr) const;
|
||||
bool PopulateFromSuffix(const nsACString& aStr);
|
||||
|
||||
void CookieJar(nsACString& aStr);
|
||||
};
|
||||
|
||||
/*
|
||||
|
10
configure.in
10
configure.in
@ -5132,11 +5132,6 @@ fi
|
||||
dnl ========================================================
|
||||
dnl = Disable Speech API pocketsphinx backend
|
||||
dnl ========================================================
|
||||
MOZ_ARG_DISABLE_BOOL(webspeechpocketsphinx,
|
||||
[ --disable-webspeechpocketsphinx Disable support for HTML Speech API Pocketsphinx Backend],
|
||||
MOZ_WEBSPEECH_POCKETSPHINX=,
|
||||
MOZ_WEBSPEECH_POCKETSPHINX=1)
|
||||
|
||||
if test -n "$MOZ_WEBSPEECH_POCKETSPHINX"; then
|
||||
AC_DEFINE(MOZ_WEBSPEECH_POCKETSPHINX)
|
||||
fi
|
||||
@ -5178,11 +5173,6 @@ AC_SUBST(MOZ_WEBSPEECH_TEST_BACKEND)
|
||||
dnl ========================================================
|
||||
dnl = Disable Speech API models
|
||||
dnl ========================================================
|
||||
MOZ_ARG_DISABLE_BOOL(webspeechmodels,
|
||||
[ --disable-webspeechmodels Disable support for HTML Speech API Models],
|
||||
MOZ_WEBSPEECH_MODELS=,
|
||||
MOZ_WEBSPEECH_MODELS=1)
|
||||
|
||||
if test -z "$MOZ_WEBSPEECH"; then
|
||||
MOZ_WEBSPEECH_MODELS=
|
||||
fi
|
||||
|
105
docshell/base/AutoTimelineMarker.cpp
Normal file
105
docshell/base/AutoTimelineMarker.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/* -*- 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 "mozilla/AutoTimelineMarker.h"
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
bool
|
||||
AutoTimelineMarker::DocShellIsRecording(nsDocShell& aDocShell)
|
||||
{
|
||||
bool isRecording = false;
|
||||
if (nsDocShell::gProfileTimelineRecordingsCount > 0) {
|
||||
aDocShell.GetRecordProfileTimelineMarkers(&isRecording);
|
||||
}
|
||||
return isRecording;
|
||||
}
|
||||
|
||||
AutoTimelineMarker::AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: mDocShell(nullptr)
|
||||
, mName(aName)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsDocShell* docShell = static_cast<nsDocShell*>(aDocShell);
|
||||
if (docShell && DocShellIsRecording(*docShell)) {
|
||||
mDocShell = docShell;
|
||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
|
||||
}
|
||||
}
|
||||
|
||||
AutoTimelineMarker::~AutoTimelineMarker()
|
||||
{
|
||||
if (mDocShell) {
|
||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoGlobalTimelineMarker::PopulateDocShells()
|
||||
{
|
||||
const LinkedList<nsDocShell::ObservedDocShell>& docShells =
|
||||
nsDocShell::GetObservedDocShells();
|
||||
MOZ_ASSERT(!docShells.isEmpty());
|
||||
|
||||
for (const nsDocShell::ObservedDocShell* ds = docShells.getFirst();
|
||||
ds;
|
||||
ds = ds->getNext()) {
|
||||
mOk = mDocShells.append(**ds);
|
||||
if (!mOk) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AutoGlobalTimelineMarker::AutoGlobalTimelineMarker(const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: mOk(true)
|
||||
, mDocShells()
|
||||
, mName(aName)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (nsDocShell::gProfileTimelineRecordingsCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
PopulateDocShells();
|
||||
if (!mOk) {
|
||||
// If we don't successfully populate our vector with *all* docshells being
|
||||
// observed, don't add markers to *any* of them.
|
||||
return;
|
||||
}
|
||||
|
||||
for (Vector<nsRefPtr<nsDocShell>>::Range range = mDocShells.all();
|
||||
!range.empty();
|
||||
range.popFront()) {
|
||||
range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
|
||||
}
|
||||
}
|
||||
|
||||
AutoGlobalTimelineMarker::~AutoGlobalTimelineMarker()
|
||||
{
|
||||
if (!mOk) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Vector<nsRefPtr<nsDocShell>>::Range range = mDocShells.all();
|
||||
!range.empty();
|
||||
range.popFront()) {
|
||||
range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace mozilla
|
@ -8,10 +8,13 @@
|
||||
#define AutoTimelineMarker_h__
|
||||
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include "nsRefPtr.h"
|
||||
|
||||
class nsIDocShell;
|
||||
class nsDocShell;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// # AutoTimelineMarker
|
||||
@ -27,7 +30,6 @@ namespace mozilla {
|
||||
// nsresult rv = ParseTheCSSFile(mFile);
|
||||
// ...
|
||||
// }
|
||||
|
||||
class MOZ_STACK_CLASS AutoTimelineMarker
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||
@ -35,42 +37,57 @@ class MOZ_STACK_CLASS AutoTimelineMarker
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
const char* mName;
|
||||
|
||||
bool
|
||||
DocShellIsRecording(nsDocShell& aDocShell)
|
||||
{
|
||||
bool isRecording = false;
|
||||
if (nsDocShell::gProfileTimelineRecordingsCount > 0) {
|
||||
aDocShell.GetRecordProfileTimelineMarkers(&isRecording);
|
||||
}
|
||||
return isRecording;
|
||||
}
|
||||
bool DocShellIsRecording(nsDocShell& aDocShell);
|
||||
|
||||
public:
|
||||
explicit AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mDocShell(nullptr)
|
||||
, mName(aName)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
nsDocShell* docShell = static_cast<nsDocShell*>(aDocShell);
|
||||
if (docShell && DocShellIsRecording(*docShell)) {
|
||||
mDocShell = docShell;
|
||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
|
||||
}
|
||||
}
|
||||
|
||||
~AutoTimelineMarker()
|
||||
{
|
||||
if (mDocShell) {
|
||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
|
||||
}
|
||||
}
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
~AutoTimelineMarker();
|
||||
|
||||
AutoTimelineMarker(const AutoTimelineMarker& aOther) = delete;
|
||||
void operator=(const AutoTimelineMarker& aOther) = delete;
|
||||
};
|
||||
|
||||
// # AutoGlobalTimelineMarker
|
||||
//
|
||||
// Similar to `AutoTimelineMarker`, but adds its traced marker to all docshells,
|
||||
// not a single particular one. This is useful for operations that aren't
|
||||
// associated with any one particular doc shell, or when it isn't clear which
|
||||
// doc shell triggered the operation.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// {
|
||||
// AutoGlobalTimelineMarker marker("Cycle Collection");
|
||||
// nsCycleCollector* cc = GetCycleCollector();
|
||||
// cc->Collect();
|
||||
// ...
|
||||
// }
|
||||
class MOZ_STACK_CLASS AutoGlobalTimelineMarker
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||
|
||||
// True as long as no operation has failed, eg due to OOM.
|
||||
bool mOk;
|
||||
|
||||
// The set of docshells that are being observed and will get markers.
|
||||
mozilla::Vector<nsRefPtr<nsDocShell>> mDocShells;
|
||||
|
||||
// The name of the marker we are adding.
|
||||
const char* mName;
|
||||
|
||||
void PopulateDocShells();
|
||||
|
||||
public:
|
||||
explicit AutoGlobalTimelineMarker(const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
~AutoGlobalTimelineMarker();
|
||||
|
||||
AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete;
|
||||
void operator=(const AutoGlobalTimelineMarker& aOther) = delete;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* AutoTimelineMarker_h__ */
|
||||
|
@ -48,6 +48,7 @@ EXPORTS.mozilla += [
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AutoTimelineMarker.cpp',
|
||||
'LoadContext.cpp',
|
||||
'nsAboutRedirector.cpp',
|
||||
'nsDefaultURIFixup.cpp',
|
||||
|
@ -200,6 +200,12 @@
|
||||
#include "nsIBrowserSearchService.h"
|
||||
#endif
|
||||
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
// Values for the network.cookie.cookieBehavior pref are documented in
|
||||
// nsCookieService.cpp
|
||||
#define COOKIE_BEHAVIOR_ACCEPT 0 // Allow all cookies.
|
||||
#define COOKIE_BEHAVIOR_REJECT_FOREIGN 1 // Reject all third-party cookies.
|
||||
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
|
||||
#if defined(DEBUG_bryner) || defined(DEBUG_chb)
|
||||
@ -944,7 +950,7 @@ nsDocShell::nsDocShell()
|
||||
|
||||
nsDocShell::~nsDocShell()
|
||||
{
|
||||
MOZ_ASSERT(!mProfileTimelineRecording);
|
||||
MOZ_ASSERT(!IsObserved());
|
||||
|
||||
Destroy();
|
||||
|
||||
@ -2927,6 +2933,8 @@ nsDocShell::HistoryTransactionRemoved(int32_t aIndex)
|
||||
|
||||
unsigned long nsDocShell::gProfileTimelineRecordingsCount = 0;
|
||||
|
||||
mozilla::LinkedList<nsDocShell::ObservedDocShell>* nsDocShell::gObservedDocShells = nullptr;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
||||
{
|
||||
@ -2935,11 +2943,16 @@ nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
||||
if (aValue) {
|
||||
++gProfileTimelineRecordingsCount;
|
||||
UseEntryScriptProfiling();
|
||||
mProfileTimelineRecording = true;
|
||||
|
||||
MOZ_ASSERT(!mObserved);
|
||||
mObserved.reset(new ObservedDocShell(this));
|
||||
GetOrCreateObservedDocShells().insertFront(mObserved.get());
|
||||
} else {
|
||||
--gProfileTimelineRecordingsCount;
|
||||
UnuseEntryScriptProfiling();
|
||||
mProfileTimelineRecording = false;
|
||||
|
||||
mObserved.reset(nullptr);
|
||||
|
||||
ClearProfileTimelineMarkers();
|
||||
}
|
||||
}
|
||||
@ -2950,7 +2963,7 @@ nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetRecordProfileTimelineMarkers(bool* aValue)
|
||||
{
|
||||
*aValue = mProfileTimelineRecording;
|
||||
*aValue = IsObserved();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3090,7 +3103,7 @@ void
|
||||
nsDocShell::AddProfileTimelineMarker(const char* aName,
|
||||
TracingMetadata aMetaData)
|
||||
{
|
||||
if (mProfileTimelineRecording) {
|
||||
if (IsObserved()) {
|
||||
TimelineMarker* marker = new TimelineMarker(this, aName, aMetaData);
|
||||
mProfileTimelineMarkers.AppendElement(marker);
|
||||
}
|
||||
@ -3099,7 +3112,7 @@ nsDocShell::AddProfileTimelineMarker(const char* aName,
|
||||
void
|
||||
nsDocShell::AddProfileTimelineMarker(UniquePtr<TimelineMarker>&& aMarker)
|
||||
{
|
||||
if (mProfileTimelineRecording) {
|
||||
if (IsObserved()) {
|
||||
mProfileTimelineMarkers.AppendElement(Move(aMarker));
|
||||
}
|
||||
}
|
||||
@ -14044,6 +14057,32 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNavigate,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult result;
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID, &result);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (mCurrentURI) {
|
||||
nsAutoCString uriSpec;
|
||||
mCurrentURI->GetSpec(uriSpec);
|
||||
if (!(uriSpec.EqualsLiteral("about:blank"))) {
|
||||
// Reject the interception of third-party iframes if the cookie behaviour
|
||||
// is set to reject all third-party cookies (1). In case that this pref
|
||||
// is not set or can't be read, we default to allow all cookies (0) as
|
||||
// this is the default value in all.js.
|
||||
bool isThirdPartyURI = true;
|
||||
result = thirdPartyUtil->IsThirdPartyURI(mCurrentURI, aURI,
|
||||
&isThirdPartyURI);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
if (isThirdPartyURI &&
|
||||
(Preferences::GetInt("network.cookie.cookieBehavior",
|
||||
COOKIE_BEHAVIOR_ACCEPT) ==
|
||||
COOKIE_BEHAVIOR_REJECT_FOREIGN)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aIsNavigate) {
|
||||
OriginAttributes attrs(GetAppId(), GetIsInBrowserElement());
|
||||
*aShouldIntercept = swm->IsAvailable(attrs, aURI);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
// Helper Classes
|
||||
@ -266,6 +267,43 @@ public:
|
||||
// timeline markers
|
||||
static unsigned long gProfileTimelineRecordingsCount;
|
||||
|
||||
class ObservedDocShell : public mozilla::LinkedListElement<ObservedDocShell>
|
||||
{
|
||||
public:
|
||||
explicit ObservedDocShell(nsDocShell* aDocShell)
|
||||
: mDocShell(aDocShell)
|
||||
{ }
|
||||
|
||||
nsDocShell* operator*() const { return mDocShell.get(); }
|
||||
|
||||
private:
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
};
|
||||
|
||||
private:
|
||||
static mozilla::LinkedList<ObservedDocShell>* gObservedDocShells;
|
||||
|
||||
static mozilla::LinkedList<ObservedDocShell>& GetOrCreateObservedDocShells()
|
||||
{
|
||||
if (!gObservedDocShells) {
|
||||
gObservedDocShells = new mozilla::LinkedList<ObservedDocShell>();
|
||||
}
|
||||
return *gObservedDocShells;
|
||||
}
|
||||
|
||||
// Never null if timeline markers are being observed.
|
||||
mozilla::UniquePtr<ObservedDocShell> mObserved;
|
||||
|
||||
// Return true if timeline markers are being observed for this docshell. False
|
||||
// otherwise.
|
||||
bool IsObserved() const { return !!mObserved; }
|
||||
|
||||
public:
|
||||
static const mozilla::LinkedList<ObservedDocShell>& GetObservedDocShells()
|
||||
{
|
||||
return GetOrCreateObservedDocShells();
|
||||
}
|
||||
|
||||
// Tell the favicon service that aNewURI has the same favicon as aOldURI.
|
||||
static void CopyFavicon(nsIURI* aOldURI,
|
||||
nsIURI* aNewURI,
|
||||
@ -973,9 +1011,6 @@ private:
|
||||
// has been called without a matching NotifyRunToCompletionStop.
|
||||
uint32_t mJSRunToCompletionDepth;
|
||||
|
||||
// True if recording profiles.
|
||||
bool mProfileTimelineRecording;
|
||||
|
||||
nsTArray<mozilla::UniquePtr<TimelineMarker>> mProfileTimelineMarkers;
|
||||
|
||||
// Get rid of all the timeline markers accumulated so far
|
||||
|
@ -71,6 +71,10 @@ this.timelineContentTest = function(tests) {
|
||||
info("Waiting for new markers on the docShell");
|
||||
let markers = yield onMarkers;
|
||||
|
||||
// Cycle collection markers are non-deterministic, and none of these tests
|
||||
// expect them to show up.
|
||||
markers = markers.filter(m => m.name.indexOf("nsCycleCollector") === -1);
|
||||
|
||||
info("Running the test check function");
|
||||
check(markers);
|
||||
}
|
||||
|
@ -186,7 +186,14 @@ TextInputProcessor::BeginInputTransactionInternal(
|
||||
|
||||
// This instance has finished preparing to link to the dispatcher. Therefore,
|
||||
// let's forget the old dispatcher and purpose.
|
||||
UnlinkFromTextEventDispatcher();
|
||||
if (mDispatcher) {
|
||||
mDispatcher->EndInputTransaction(this);
|
||||
if (NS_WARN_IF(mDispatcher)) {
|
||||
// Forcibly initialize the members if we failed to end the input
|
||||
// transaction.
|
||||
UnlinkFromTextEventDispatcher();
|
||||
}
|
||||
}
|
||||
|
||||
if (aForTests) {
|
||||
rv = dispatcher->BeginInputTransactionForTests(this);
|
||||
|
@ -139,9 +139,25 @@ URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
|
||||
nsAString& aResult,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
CreateObjectURLInternal(aGlobal, &aSource,
|
||||
NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME), aOptions,
|
||||
aResult, aError);
|
||||
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
|
||||
|
||||
nsCString url;
|
||||
nsresult rv = nsHostObjectProtocolHandler::
|
||||
AddDataEntry(NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME),
|
||||
&aSource, principal, url);
|
||||
if (NS_FAILED(rv)) {
|
||||
aError.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
|
||||
[url] {
|
||||
nsHostObjectProtocolHandler::RemoveDataEntry(url);
|
||||
});
|
||||
|
||||
nsContentUtils::RunInStableState(revocation.forget());
|
||||
|
||||
CopyASCIItoUTF16(url, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -92,6 +92,7 @@
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsHtml5Module.h"
|
||||
#include "nsHtml5StringParser.h"
|
||||
#include "nsIAppShell.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
@ -182,6 +183,7 @@
|
||||
#include "nsUnicodeProperties.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsViewportInfo.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "xpcprivate.h" // nsXPConnect
|
||||
@ -337,6 +339,7 @@ namespace {
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
|
||||
static PLDHashTable* sEventListenerManagersHash;
|
||||
|
||||
@ -5148,6 +5151,20 @@ nsContentUtils::AddScriptRunner(nsIRunnable* aRunnable)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsContentUtils::RunInStableState(already_AddRefed<nsIRunnable> aRunnable,
|
||||
DispatchFailureHandling aHandling)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = aRunnable;
|
||||
nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
|
||||
if (!appShell) {
|
||||
MOZ_ASSERT(aHandling == DispatchFailureHandling::IgnoreFailure);
|
||||
return;
|
||||
}
|
||||
appShell->RunInStableState(runnable.forget());
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::EnterMicroTask()
|
||||
{
|
||||
@ -7414,7 +7431,9 @@ nsContentUtils::GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
|
||||
size_t* aLength, int32_t* aStride)
|
||||
{
|
||||
mozilla::gfx::DataSourceSurface::MappedSurface map;
|
||||
aSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map);
|
||||
if (NS_WARN_IF(!aSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map))) {
|
||||
return nullptr;
|
||||
}
|
||||
mozilla::gfx::IntSize size = aSurface->GetSize();
|
||||
mozilla::CheckedInt32 requiredBytes =
|
||||
mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
|
||||
|
@ -1576,6 +1576,27 @@ public:
|
||||
*/
|
||||
static void WarnScriptWasIgnored(nsIDocument* aDocument);
|
||||
|
||||
/**
|
||||
* Whether to assert that RunInStableState() succeeds, or ignore failure,
|
||||
* which may happen late in shutdown.
|
||||
*/
|
||||
enum class DispatchFailureHandling { AssertSuccess, IgnoreFailure };
|
||||
|
||||
/**
|
||||
* Add a "synchronous section", in the form of an nsIRunnable run once the
|
||||
* event loop has reached a "stable state". |aRunnable| must not cause any
|
||||
* queued events to be processed (i.e. must not spin the event loop).
|
||||
* We've reached a stable state when the currently executing task/event has
|
||||
* finished, see
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#synchronous-section
|
||||
* In practice this runs aRunnable once the currently executing event
|
||||
* finishes. If called multiple times per task/event, all the runnables will
|
||||
* be executed, in the order in which RunInStableState() was called.
|
||||
*/
|
||||
static void RunInStableState(already_AddRefed<nsIRunnable> aRunnable,
|
||||
DispatchFailureHandling aHandling =
|
||||
DispatchFailureHandling::AssertSuccess);
|
||||
|
||||
/**
|
||||
* Retrieve information about the viewport as a data structure.
|
||||
* This will return information in the viewport META data section
|
||||
|
@ -1509,18 +1509,23 @@ nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
|
||||
RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(aCanvas1);
|
||||
RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(aCanvas2);
|
||||
|
||||
DataSourceSurface::ScopedMap map1(img1, DataSourceSurface::READ);
|
||||
DataSourceSurface::ScopedMap map2(img2, DataSourceSurface::READ);
|
||||
|
||||
if (img1 == nullptr || img2 == nullptr ||
|
||||
!map1.IsMapped() || !map2.IsMapped() ||
|
||||
img1->GetSize() != img2->GetSize() ||
|
||||
img1->Stride() != img2->Stride())
|
||||
map1.GetStride() != map2.GetStride()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int v;
|
||||
IntSize size = img1->GetSize();
|
||||
uint32_t stride = img1->Stride();
|
||||
int32_t stride = map1.GetStride();
|
||||
|
||||
// we can optimize for the common all-pass case
|
||||
if (stride == (uint32_t) size.width * 4) {
|
||||
v = memcmp(img1->GetData(), img2->GetData(), size.width * size.height * 4);
|
||||
if (stride == size.width * 4) {
|
||||
v = memcmp(map1.GetData(), map2.GetData(), size.width * size.height * 4);
|
||||
if (v == 0) {
|
||||
if (aMaxDifference)
|
||||
*aMaxDifference = 0;
|
||||
@ -1533,8 +1538,8 @@ nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
|
||||
uint32_t different = 0;
|
||||
|
||||
for (int j = 0; j < size.height; j++) {
|
||||
unsigned char *p1 = img1->GetData() + j*stride;
|
||||
unsigned char *p2 = img2->GetData() + j*stride;
|
||||
unsigned char *p1 = map1.GetData() + j*stride;
|
||||
unsigned char *p2 = map2.GetData() + j*stride;
|
||||
v = memcmp(p1, p2, stride);
|
||||
|
||||
if (v) {
|
||||
@ -3441,16 +3446,14 @@ nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::RunInStableState(nsIRunnable *runnable)
|
||||
nsDOMWindowUtils::RunInStableState(nsIRunnable *aRunnable)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
|
||||
if (!appShell) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> runnable = aRunnable;
|
||||
nsContentUtils::RunInStableState(runnable.forget());
|
||||
|
||||
return appShell->RunInStableState(runnable);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -711,17 +711,6 @@ public:
|
||||
nsIDocument *mSubDocument;
|
||||
};
|
||||
|
||||
struct FindContentData
|
||||
{
|
||||
explicit FindContentData(nsIDocument* aSubDoc)
|
||||
: mSubDocument(aSubDoc), mResult(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsISupports *mSubDocument;
|
||||
Element *mResult;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A struct that holds all the information about a radio group.
|
||||
@ -1858,22 +1847,6 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDocument)
|
||||
return Element::CanSkipThis(tmp);
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
|
||||
|
||||
static PLDHashOperator
|
||||
SubDocTraverser(PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number,
|
||||
void *arg)
|
||||
{
|
||||
SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
|
||||
nsCycleCollectionTraversalCallback *cb =
|
||||
static_cast<nsCycleCollectionTraversalCallback*>(arg);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mSubDocuments entry->mKey");
|
||||
cb->NoteXPCOMChild(entry->mKey);
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mSubDocuments entry->mSubDocument");
|
||||
cb->NoteXPCOMChild(entry->mSubDocument);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
RadioGroupsTraverser(const nsAString& aKey, nsRadioGroupStruct* aData,
|
||||
void* aClosure)
|
||||
@ -2033,7 +2006,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
}
|
||||
|
||||
if (tmp->mSubDocuments) {
|
||||
PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb);
|
||||
PLDHashTable::Iterator iter(tmp->mSubDocuments);
|
||||
while (iter.HasMoreEntries()) {
|
||||
auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mSubDocuments entry->mKey");
|
||||
cb.NoteXPCOMChild(entry->mKey);
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mSubDocuments entry->mSubDocument");
|
||||
cb.NoteXPCOMChild(entry->mSubDocument);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader)
|
||||
@ -4031,22 +4014,6 @@ nsDocument::GetSubDocumentFor(nsIContent *aContent) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
FindContentEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
uint32_t number, void *arg)
|
||||
{
|
||||
SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
|
||||
FindContentData *data = static_cast<FindContentData*>(arg);
|
||||
|
||||
if (entry->mSubDocument == data->mSubDocument) {
|
||||
data->mResult = entry->mKey;
|
||||
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::FindContentForSubDocument(nsIDocument *aDocument) const
|
||||
{
|
||||
@ -4056,10 +4023,14 @@ nsDocument::FindContentForSubDocument(nsIDocument *aDocument) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FindContentData data(aDocument);
|
||||
PL_DHashTableEnumerate(mSubDocuments, FindContentEnumerator, &data);
|
||||
|
||||
return data.mResult;
|
||||
PLDHashTable::Iterator iter(mSubDocuments);
|
||||
while (iter.HasMoreEntries()) {
|
||||
auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
|
||||
if (entry->mSubDocument == aDocument) {
|
||||
return entry->mKey;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -8739,45 +8710,22 @@ struct SubDocEnumArgs
|
||||
void *data;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
SubDocHashEnum(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
uint32_t number, void *arg)
|
||||
{
|
||||
SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
|
||||
SubDocEnumArgs *args = static_cast<SubDocEnumArgs*>(arg);
|
||||
|
||||
nsIDocument *subdoc = entry->mSubDocument;
|
||||
bool next = subdoc ? args->callback(subdoc, args->data) : true;
|
||||
|
||||
return next ? PL_DHASH_NEXT : PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::EnumerateSubDocuments(nsSubDocEnumFunc aCallback, void *aData)
|
||||
{
|
||||
if (mSubDocuments) {
|
||||
SubDocEnumArgs args = { aCallback, aData };
|
||||
PL_DHashTableEnumerate(mSubDocuments, SubDocHashEnum, &args);
|
||||
}
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
CanCacheSubDocument(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
uint32_t number, void *arg)
|
||||
{
|
||||
SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
|
||||
bool *canCacheArg = static_cast<bool*>(arg);
|
||||
|
||||
nsIDocument *subdoc = entry->mSubDocument;
|
||||
|
||||
// The aIgnoreRequest we were passed is only for us, so don't pass it on.
|
||||
bool canCache = subdoc ? subdoc->CanSavePresentation(nullptr) : false;
|
||||
if (!canCache) {
|
||||
*canCacheArg = false;
|
||||
return PL_DHASH_STOP;
|
||||
if (!mSubDocuments) {
|
||||
return;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
PLDHashTable::Iterator iter(mSubDocuments);
|
||||
while (iter.HasMoreEntries()) {
|
||||
auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
|
||||
nsIDocument* subdoc = entry->mSubDocument;
|
||||
bool next = subdoc ? aCallback(subdoc, aData) : true;
|
||||
if (!next) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_bryner
|
||||
@ -8878,11 +8826,21 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool canCache = true;
|
||||
if (mSubDocuments)
|
||||
PL_DHashTableEnumerate(mSubDocuments, CanCacheSubDocument, &canCache);
|
||||
if (mSubDocuments) {
|
||||
PLDHashTable::Iterator iter(mSubDocuments);
|
||||
while (iter.HasMoreEntries()) {
|
||||
auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
|
||||
nsIDocument* subdoc = entry->mSubDocument;
|
||||
|
||||
return canCache;
|
||||
// The aIgnoreRequest we were passed is only for us, so don't pass it on.
|
||||
bool canCache = subdoc ? subdoc->CanSavePresentation(nullptr) : false;
|
||||
if (!canCache) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -133,30 +133,16 @@ nsPropertyTable::Enumerate(nsPropertyOwner aObject,
|
||||
}
|
||||
}
|
||||
|
||||
struct PropertyEnumeratorData
|
||||
{
|
||||
nsIAtom* mName;
|
||||
NSPropertyFunc mCallBack;
|
||||
void* mData;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
PropertyEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg)
|
||||
{
|
||||
PropertyListMapEntry* entry = static_cast<PropertyListMapEntry*>(aHdr);
|
||||
PropertyEnumeratorData* data = static_cast<PropertyEnumeratorData*>(aArg);
|
||||
data->mCallBack(const_cast<void*>(entry->key), data->mName, entry->value,
|
||||
data->mData);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsPropertyTable::EnumerateAll(NSPropertyFunc aCallBack, void* aData)
|
||||
{
|
||||
for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) {
|
||||
PropertyEnumeratorData data = { prop->mName, aCallBack, aData };
|
||||
PL_DHashTableEnumerate(&prop->mObjectValueMap, PropertyEnumerator, &data);
|
||||
PLDHashTable::Iterator iter(&prop->mObjectValueMap);
|
||||
while (iter.HasMoreEntries()) {
|
||||
auto entry = static_cast<PropertyListMapEntry*>(iter.NextEntry());
|
||||
aCallBack(const_cast<void*>(entry->key), prop->mName, entry->value,
|
||||
aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,25 +280,17 @@ nsPropertyTable::PropertyList::~PropertyList()
|
||||
{
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
uint32_t number, void *arg)
|
||||
{
|
||||
nsPropertyTable::PropertyList *propList =
|
||||
static_cast<nsPropertyTable::PropertyList*>(arg);
|
||||
PropertyListMapEntry* entry = static_cast<PropertyListMapEntry*>(hdr);
|
||||
|
||||
propList->mDtorFunc(const_cast<void*>(entry->key), propList->mName,
|
||||
entry->value, propList->mDtorData);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsPropertyTable::PropertyList::Destroy()
|
||||
{
|
||||
// Enumerate any remaining object/value pairs and destroy the value object
|
||||
if (mDtorFunc)
|
||||
PL_DHashTableEnumerate(&mObjectValueMap, DestroyPropertyEnumerator, this);
|
||||
// Enumerate any remaining object/value pairs and destroy the value object.
|
||||
if (mDtorFunc) {
|
||||
PLDHashTable::Iterator iter(&mObjectValueMap);
|
||||
while (iter.HasMoreEntries()) {
|
||||
auto entry = static_cast<PropertyListMapEntry*>(iter.NextEntry());
|
||||
mDtorFunc(const_cast<void*>(entry->key), mName, entry->value, mDtorData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -47,7 +47,7 @@ nsReferencedElement::Reset(nsIContent* aFromContent, nsIURI* aURI,
|
||||
return;
|
||||
|
||||
// Get the current document
|
||||
nsIDocument *doc = aFromContent->GetComposedDoc();
|
||||
nsIDocument *doc = aFromContent->OwnerDoc();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
@ -124,7 +124,7 @@ void
|
||||
nsReferencedElement::ResetWithID(nsIContent* aFromContent, const nsString& aID,
|
||||
bool aWatch)
|
||||
{
|
||||
nsIDocument *doc = aFromContent->GetComposedDoc();
|
||||
nsIDocument *doc = aFromContent->OwnerDoc();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
|
@ -3205,6 +3205,12 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||
"That seems rather unlikely.",
|
||||
[self.location])
|
||||
|
||||
if self.getExtendedAttribute("NewObject"):
|
||||
if self.dependsOn == "Nothing" or self.dependsOn == "DOMState":
|
||||
raise WebIDLError("A [NewObject] method is not idempotent, "
|
||||
"so it has to depend on something other than DOM state.",
|
||||
[self.location])
|
||||
|
||||
def _setDependsOn(self, dependsOn):
|
||||
if self.dependsOn != "Everything":
|
||||
raise WebIDLError("Trying to specify multiple different DependsOn, "
|
||||
|
@ -42,17 +42,6 @@ UuidToString(const BluetoothUuid& aUuid, nsAString& aString)
|
||||
aString.AssignLiteral(uuidStr);
|
||||
}
|
||||
|
||||
void
|
||||
ReversedUuidToString(const BluetoothUuid& aUuid, nsAString& aString)
|
||||
{
|
||||
BluetoothUuid uuid;
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
uuid.mUuid[i] = aUuid.mUuid[15 - i];
|
||||
}
|
||||
|
||||
UuidToString(uuid, aString);
|
||||
}
|
||||
|
||||
void
|
||||
StringToUuid(const char* aString, BluetoothUuid& aUuid)
|
||||
{
|
||||
@ -98,24 +87,16 @@ GenerateUuid(nsAString &aUuidString)
|
||||
aUuidString.Assign(Substring(uuidString, 1, NSID_LENGTH - 3));
|
||||
}
|
||||
|
||||
void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
nsAString& aPath,
|
||||
nsAString& aUuidStr)
|
||||
{
|
||||
ReversedUuidToString(aId.mUuid, aUuidStr);
|
||||
|
||||
aPath.Assign(aUuidStr);
|
||||
aPath.AppendLiteral("_");
|
||||
aPath.AppendInt(aId.mInstanceId);
|
||||
}
|
||||
|
||||
void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
nsAString& aPath)
|
||||
{
|
||||
nsString uuidStr;
|
||||
GeneratePathFromGattId(aId, aPath, uuidStr);
|
||||
UuidToString(aId.mUuid, uuidStr);
|
||||
|
||||
aPath.Assign(uuidStr);
|
||||
aPath.AppendLiteral("_");
|
||||
aPath.AppendInt(aId.mInstanceId);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -29,19 +29,6 @@ class BluetoothValue;
|
||||
void
|
||||
UuidToString(const BluetoothUuid& aUuid, nsAString& aString);
|
||||
|
||||
/**
|
||||
* Convert BluetoothUuid object in a reversed byte order to
|
||||
* xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string.
|
||||
* Bluedroid stack reports the BluetoothUuid in a reversed byte order for
|
||||
* GATT service, characteristic, descriptor uuids.
|
||||
*
|
||||
* Note: This utility function is used by gecko internal only to convert
|
||||
* BluetoothUuid in a reversed byte order created by bluetooth stack to uuid
|
||||
* string representation.
|
||||
*/
|
||||
void
|
||||
ReversedUuidToString(const BluetoothUuid& aUuid, nsAString& aString);
|
||||
|
||||
/**
|
||||
* Convert xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string to BluetoothUuid object.
|
||||
*
|
||||
@ -63,18 +50,6 @@ GenerateUuid(nsAString &aUuidString);
|
||||
// Generate bluetooth signal path from GattId
|
||||
//
|
||||
|
||||
/**
|
||||
* Generate bluetooth signal path and UUID string from a GattId.
|
||||
*
|
||||
* @param aId [in] GattId value to convert.
|
||||
* @param aPath [out] Bluetooth signal path generated from aId.
|
||||
* @param aUuidStr [out] UUID string generated from aId.
|
||||
*/
|
||||
void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
nsAString& aPath,
|
||||
nsAString& aUuidStr);
|
||||
|
||||
/**
|
||||
* Generate bluetooth signal path from a GattId.
|
||||
*
|
||||
|
@ -259,7 +259,9 @@ BluetoothDaemonGattModule::ClientSearchServiceCmd(
|
||||
16)); // UUID
|
||||
|
||||
nsresult rv = PackPDU(PackConversion<int, int32_t>(aConnId),
|
||||
PackConversion<bool, uint8_t>(aFiltered), aUuid, *pdu);
|
||||
PackConversion<bool, uint8_t>(aFiltered),
|
||||
PackReversed<BluetoothUuid>(aUuid),
|
||||
*pdu);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1409,7 +1409,7 @@ PackPDU(const BluetoothUuid& aIn, BluetoothDaemonPDU& aPDU)
|
||||
nsresult
|
||||
PackPDU(const BluetoothGattId& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn.mUuid, aPDU);
|
||||
nsresult rv = PackPDU(PackReversed<BluetoothUuid>(aIn.mUuid), aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -1734,7 +1734,7 @@ nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattId& aOut)
|
||||
{
|
||||
/* unpack UUID */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mUuid);
|
||||
nsresult rv = UnpackPDU(aPDU, UnpackReversed<BluetoothUuid>(aOut.mUuid));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -579,6 +579,57 @@ PackPDU(const PackCString0& aIn, BluetoothDaemonPDU& aPDU)
|
||||
aIn.mString.Length() + 1), aPDU);
|
||||
}
|
||||
|
||||
/* |PackReversed| is a helper for packing data in reversed order. Pass an
|
||||
* instance of this structure as the first argument to |PackPDU| to pack data
|
||||
* in reversed order.
|
||||
*/
|
||||
template<typename T>
|
||||
struct PackReversed
|
||||
{
|
||||
PackReversed(const T& aValue)
|
||||
: mValue(aValue)
|
||||
{ }
|
||||
|
||||
const T& mValue;
|
||||
};
|
||||
|
||||
/* No general rules to pack data in reversed order. Signal a link error if the
|
||||
* type |T| of |PackReversed| is not defined explicitly.
|
||||
*/
|
||||
template<typename T>
|
||||
nsresult
|
||||
PackPDU(const PackReversed<T>& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
/* This implementation of |PackPDU| packs elements in |PackArray| in reversed
|
||||
* order. (ex. reversed GATT UUID, see bug 1171866)
|
||||
*/
|
||||
template<typename U>
|
||||
inline nsresult
|
||||
PackPDU(const PackReversed<PackArray<U>>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
for (size_t i = 0; i < aIn.mValue.mLength; ++i) {
|
||||
nsresult rv = PackPDU(aIn.mValue.mData[aIn.mValue.mLength - i - 1], aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* This implementation of |PackPDU| packs |BluetoothUuid| in reversed order.
|
||||
* (ex. reversed GATT UUID, see bug 1171866)
|
||||
*/
|
||||
template <>
|
||||
inline nsresult
|
||||
PackPDU<BluetoothUuid>(const PackReversed<BluetoothUuid>& aIn,
|
||||
BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackReversed<PackArray<uint8_t>>(
|
||||
PackArray<uint8_t>(aIn.mValue.mUuid, sizeof(aIn.mValue.mUuid))),
|
||||
aPDU);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, BluetoothDaemonPDU& aPDU)
|
||||
@ -1099,6 +1150,59 @@ struct UnpackString0
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut);
|
||||
|
||||
/* |UnpackReversed| is a helper for unpacking data in reversed order. Pass an
|
||||
* instance of this structure as the second argument to |UnpackPDU| to unpack
|
||||
* data in reversed order.
|
||||
*/
|
||||
template<typename T>
|
||||
struct UnpackReversed
|
||||
{
|
||||
UnpackReversed(T& aValue)
|
||||
: mValue(&aValue)
|
||||
{ }
|
||||
|
||||
UnpackReversed(T&& aValue)
|
||||
: mValue(&aValue)
|
||||
{ }
|
||||
|
||||
T* mValue;
|
||||
};
|
||||
|
||||
/* No general rules to unpack data in reversed order. Signal a link error if
|
||||
* the type |T| of |UnpackReversed| is not defined explicitly.
|
||||
*/
|
||||
template<typename T>
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackReversed<T>& aOut);
|
||||
|
||||
template<typename U>
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackReversed<UnpackArray<U>>& aOut)
|
||||
{
|
||||
for (size_t i = 0; i < aOut.mValue->mLength; ++i) {
|
||||
nsresult rv = UnpackPDU(aPDU,
|
||||
aOut.mValue->mData[aOut.mValue->mLength - i - 1]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* This implementation of |UnpackPDU| unpacks |BluetoothUuid| in reversed
|
||||
* order. (ex. reversed GATT UUID, see bug 1171866)
|
||||
*/
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<BluetoothUuid>(BluetoothDaemonPDU& aPDU,
|
||||
const UnpackReversed<BluetoothUuid>& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU,
|
||||
UnpackReversed<UnpackArray<uint8_t>>(
|
||||
UnpackArray<uint8_t>(aOut.mValue->mUuid, sizeof(aOut.mValue->mUuid))));
|
||||
}
|
||||
|
||||
//
|
||||
// Init operators
|
||||
//
|
||||
|
@ -234,15 +234,35 @@ Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut)
|
||||
nsresult
|
||||
Convert(const BluetoothGattId& aIn, btgatt_gatt_id_t& aOut)
|
||||
{
|
||||
nsresult rv = Convert(aIn.mUuid, aOut.uuid);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// HAL uses reversed UUID for GATT
|
||||
for (uint8_t i = 0; i < sizeof(aOut.uuid.uu) / 2; i++) {
|
||||
auto temp = aOut.uuid.uu[i];
|
||||
aOut.uuid.uu[i] = aOut.uuid.uu[sizeof(aOut.uuid.uu) - i - 1];
|
||||
aOut.uuid.uu[sizeof(aOut.uuid.uu) - i - 1] = temp;
|
||||
}
|
||||
aOut.inst_id = aIn.mInstanceId;
|
||||
return Convert(aIn.mUuid, aOut.uuid);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const btgatt_gatt_id_t& aIn, BluetoothGattId& aOut)
|
||||
{
|
||||
nsresult rv = Convert(aIn.uuid, aOut.mUuid);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// HAL uses reversed UUID for GATT
|
||||
for (uint8_t i = 0; i < sizeof(aOut.mUuid.mUuid) / 2; i++) {
|
||||
auto temp = aOut.mUuid.mUuid[i];
|
||||
aOut.mUuid.mUuid[i] = aOut.mUuid.mUuid[sizeof(aOut.mUuid.mUuid) - i - 1];
|
||||
aOut.mUuid.mUuid[sizeof(aOut.mUuid.mUuid) - i - 1] = temp;
|
||||
}
|
||||
aOut.mInstanceId = aIn.inst_id;
|
||||
return Convert(aIn.uuid, aOut.mUuid);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -68,10 +68,11 @@ BluetoothGattCharacteristic::BluetoothGattCharacteristic(
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(mService);
|
||||
|
||||
// Generate bluetooth signal path and a string representation to provide uuid
|
||||
// of this characteristic to applications
|
||||
UuidToString(mCharId.mUuid, mUuidStr);
|
||||
|
||||
// Generate bluetooth signal path of this characteristic to applications
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mCharId, path, mUuidStr);
|
||||
GeneratePathFromGattId(mCharId, path);
|
||||
RegisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
|
@ -63,10 +63,11 @@ BluetoothGattDescriptor::BluetoothGattDescriptor(
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(aCharacteristic);
|
||||
|
||||
// Generate bluetooth signal path and a string representation to provide uuid
|
||||
// of this descriptor to applications
|
||||
UuidToString(mDescriptorId.mUuid, mUuidStr);
|
||||
|
||||
// Generate bluetooth signal path of this descriptor to applications
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mDescriptorId, path, mUuidStr);
|
||||
GeneratePathFromGattId(mDescriptorId, path);
|
||||
RegisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
|
@ -62,10 +62,11 @@ BluetoothGattService::BluetoothGattService(
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(!mAppUuid.IsEmpty());
|
||||
|
||||
// Generate bluetooth signal path and a string representation to provide
|
||||
// uuid of this service to applications
|
||||
UuidToString(mServiceId.mId.mUuid, mUuidStr);
|
||||
|
||||
// Generate bluetooth signal path of this service to applications
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mServiceId.mId, path, mUuidStr);
|
||||
GeneratePathFromGattId(mServiceId.mId, path);
|
||||
RegisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,10 @@ BrowserElementChild.prototype = {
|
||||
"activate-next-paint-listener": this._activateNextPaintListener.bind(this),
|
||||
"set-input-method-active": this._recvSetInputMethodActive.bind(this),
|
||||
"deactivate-next-paint-listener": this._deactivateNextPaintListener.bind(this),
|
||||
"do-command": this._recvDoCommand
|
||||
"do-command": this._recvDoCommand,
|
||||
"find-all": this._recvFindAll.bind(this),
|
||||
"find-next": this._recvFindNext.bind(this),
|
||||
"clear-match": this._recvClearMatch.bind(this),
|
||||
}
|
||||
|
||||
addMessageListener("browser-element-api:call", function(aMessage) {
|
||||
@ -1240,6 +1243,57 @@ BrowserElementChild.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_initFinder: function() {
|
||||
if (!this._finder) {
|
||||
try {
|
||||
this._findLimit = Services.prefs.getIntPref("accessibility.typeaheadfind.matchesCountLimit");
|
||||
} catch (e) {
|
||||
// Pref not available, assume 0, no match counting.
|
||||
this._findLimit = 0;
|
||||
}
|
||||
|
||||
let {Finder} = Components.utils.import("resource://gre/modules/Finder.jsm", {});
|
||||
this._finder = new Finder(docShell);
|
||||
this._finder.addResultListener({
|
||||
onMatchesCountResult: (data) => {
|
||||
sendAsyncMsg('findchange', {
|
||||
active: true,
|
||||
searchString: this._finder.searchString,
|
||||
searchLimit: this._findLimit,
|
||||
activeMatchOrdinal: data.current,
|
||||
numberOfMatches: data.total
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_recvFindAll: function(data) {
|
||||
this._initFinder();
|
||||
let searchString = data.json.searchString;
|
||||
this._finder.caseSensitive = data.json.caseSensitive;
|
||||
this._finder.fastFind(searchString, false, false);
|
||||
this._finder.requestMatchesCount(searchString, this._findLimit, false);
|
||||
},
|
||||
|
||||
_recvFindNext: function(data) {
|
||||
if (!this._finder) {
|
||||
debug("findNext() called before findAll()");
|
||||
return;
|
||||
}
|
||||
this._finder.findAgain(data.json.backward, false, false);
|
||||
this._finder.requestMatchesCount(this._finder.searchString, this._findLimit, false);
|
||||
},
|
||||
|
||||
_recvClearMatch: function(data) {
|
||||
if (!this._finder) {
|
||||
debug("clearMach() called before findAll()");
|
||||
return;
|
||||
}
|
||||
this._finder.removeSelection();
|
||||
sendAsyncMsg('findchange', {active: false});
|
||||
},
|
||||
|
||||
_recvSetInputMethodActive: function(data) {
|
||||
let msgData = { id: data.json.id };
|
||||
if (!this._isContentWindowCreated) {
|
||||
|
@ -206,6 +206,7 @@ BrowserElementParent.prototype = {
|
||||
"selectionstatechanged": this._handleSelectionStateChanged,
|
||||
"scrollviewchange": this._handleScrollViewChange,
|
||||
"caretstatechanged": this._handleCaretStateChanged,
|
||||
"findchange": this._handleFindChange
|
||||
};
|
||||
|
||||
let mmSecuritySensitiveCalls = {
|
||||
@ -475,6 +476,12 @@ BrowserElementParent.prototype = {
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
_handleFindChange: function(data) {
|
||||
let evt = this._createEvent("findchange", data.json,
|
||||
/* cancelable = */ false);
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
_createEvent: function(evtName, detail, cancelable) {
|
||||
// This will have to change if we ever want to send a CustomEvent with null
|
||||
// detail. For now, it's OK.
|
||||
@ -646,6 +653,23 @@ BrowserElementParent.prototype = {
|
||||
getCanGoForward: defineDOMRequestMethod('get-can-go-forward'),
|
||||
getContentDimensions: defineDOMRequestMethod('get-contentdimensions'),
|
||||
|
||||
findAll: defineNoReturnMethod(function(searchString, caseSensitivity) {
|
||||
return this._sendAsyncMsg('find-all', {
|
||||
searchString,
|
||||
caseSensitive: caseSensitivity == Ci.nsIBrowserElementAPI.FIND_CASE_SENSITIVE
|
||||
});
|
||||
}),
|
||||
|
||||
findNext: defineNoReturnMethod(function(direction) {
|
||||
return this._sendAsyncMsg('find-next', {
|
||||
backward: direction == Ci.nsIBrowserElementAPI.FIND_BACKWARD
|
||||
});
|
||||
}),
|
||||
|
||||
clearMatch: defineNoReturnMethod(function() {
|
||||
return this._sendAsyncMsg('clear-match');
|
||||
}),
|
||||
|
||||
goBack: defineNoReturnMethod(function() {
|
||||
this._sendAsyncMsg('go-back');
|
||||
}),
|
||||
|
146
dom/browser-element/mochitest/browserElement_Find.js
Normal file
146
dom/browser-element/mochitest/browserElement_Find.js
Normal file
@ -0,0 +1,146 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 1163961 - Test search API
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
function runTest() {
|
||||
|
||||
let iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
iframe.src = 'data:text/html,foo bar foo XXX Foo BAR foobar foobar';
|
||||
|
||||
const once = (eventName) => {
|
||||
return new Promise((resolve) => {
|
||||
iframe.addEventListener(eventName, function onEvent(...args) {
|
||||
iframe.removeEventListener(eventName, onEvent);
|
||||
resolve(...args);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Test if all key=>value pairs in o1 are present in o2.
|
||||
const c = (o1, o2) => Object.keys(o1).every(k => o1[k] == o2[k]);
|
||||
|
||||
let testCount = 0;
|
||||
|
||||
once('mozbrowserloadend').then(() => {
|
||||
iframe.findAll('foo', 'case-insensitive');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'foo',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 1,
|
||||
numberOfMatches: 5,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findNext('forward');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'foo',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 2,
|
||||
numberOfMatches: 5,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findNext('backward');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'foo',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 1,
|
||||
numberOfMatches: 5,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findAll('xxx', 'case-sensitive');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'xxx',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 0,
|
||||
numberOfMatches: 0,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findAll('bar', 'case-insensitive');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'bar',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 1,
|
||||
numberOfMatches: 4,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findNext('forward');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'bar',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 2,
|
||||
numberOfMatches: 4,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findNext('forward');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'bar',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 3,
|
||||
numberOfMatches: 4,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findNext('forward');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'bar',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 4,
|
||||
numberOfMatches: 4,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.findNext('forward');
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: true,
|
||||
searchString: 'bar',
|
||||
searchLimit: 100,
|
||||
activeMatchOrdinal: 1,
|
||||
numberOfMatches: 4,
|
||||
}), `test ${testCount++}`);
|
||||
iframe.clearMatch();
|
||||
return once('mozbrowserfindchange');
|
||||
}).then(({detail}) => {
|
||||
ok(c(detail, {
|
||||
msg_name: "findchange",
|
||||
active: false
|
||||
}), `test ${testCount++}`);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
}
|
||||
|
||||
addEventListener('testready', runTest);
|
@ -7,6 +7,7 @@ skip-if = os == "android" || (toolkit == "cocoa" && debug) || buildapp == 'mulet
|
||||
support-files =
|
||||
browserElement_OpenMixedProcess.js
|
||||
file_browserElement_OpenMixedProcess.html
|
||||
browserElement_Find.js
|
||||
browserElement_OpenTab.js
|
||||
|
||||
[test_browserElement_oop_Viewmode.html]
|
||||
@ -41,6 +42,7 @@ skip-if = (toolkit == 'gonk' && !debug)
|
||||
disabled = bug 1022281
|
||||
[test_browserElement_oop_ErrorSecurity.html]
|
||||
skip-if = (toolkit == 'gonk' && !debug)
|
||||
[test_browserElement_oop_Find.html]
|
||||
[test_browserElement_oop_FirstPaint.html]
|
||||
[test_browserElement_oop_ForwardName.html]
|
||||
[test_browserElement_oop_FrameWrongURI.html]
|
||||
|
@ -29,6 +29,7 @@ support-files =
|
||||
browserElement_Download.js
|
||||
browserElement_ErrorSecurity.js
|
||||
browserElement_ExposableURI.js
|
||||
browserElement_Find.js
|
||||
browserElement_FirstPaint.js
|
||||
browserElement_ForwardName.js
|
||||
browserElement_FrameWrongURI.js
|
||||
@ -159,6 +160,7 @@ skip-if = os == "android" || toolkit == 'gonk' # embed-apps doesn't work in the
|
||||
[test_browserElement_inproc_Download.html]
|
||||
disabled = bug 1022281
|
||||
[test_browserElement_inproc_ExposableURI.html]
|
||||
[test_browserElement_inproc_Find.html]
|
||||
[test_browserElement_inproc_FirstPaint.html]
|
||||
[test_browserElement_inproc_ForwardName.html]
|
||||
[test_browserElement_inproc_FrameWrongURI.html]
|
||||
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1163961
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1163961</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1163961">Mozilla Bug 1163961</a>
|
||||
|
||||
<script type="application/javascript;version=1.7" src="browserElement_Find.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1163961
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1163961</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1163961">Mozilla Bug 1163961</a>
|
||||
|
||||
<script type="application/javascript;version=1.7" src="browserElement_Find.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -26,9 +26,15 @@ interface nsIBrowserElementNextPaintListener : nsISupports
|
||||
* Interface to the BrowserElementParent implementation. All methods
|
||||
* but setFrameLoader throw when the remote process is dead.
|
||||
*/
|
||||
[scriptable, uuid(3811446f-90bb-42c1-b2b6-aae3603b61e1)]
|
||||
[scriptable, uuid(8ecb598c-f886-11e4-9915-778f934fbf93)]
|
||||
interface nsIBrowserElementAPI : nsISupports
|
||||
{
|
||||
const long FIND_CASE_SENSITIVE = 0;
|
||||
const long FIND_CASE_INSENSITIVE = 1;
|
||||
|
||||
const long FIND_FORWARD = 0;
|
||||
const long FIND_BACKWARD = 1;
|
||||
|
||||
void setFrameLoader(in nsIFrameLoader frameLoader);
|
||||
|
||||
void setVisible(in boolean visible);
|
||||
@ -67,6 +73,10 @@ interface nsIBrowserElementAPI : nsISupports
|
||||
nsIDOMDOMRequest getCanGoForward();
|
||||
nsIDOMDOMRequest getContentDimensions();
|
||||
|
||||
void findAll(in DOMString searchString, in long caseSensitivity);
|
||||
void findNext(in long direction);
|
||||
void clearMatch();
|
||||
|
||||
void addNextPaintListener(in nsIBrowserElementNextPaintListener listener);
|
||||
void removeNextPaintListener(in nsIBrowserElementNextPaintListener listener);
|
||||
|
||||
|
@ -2352,11 +2352,16 @@ private:
|
||||
void
|
||||
CanvasRenderingContext2D::UpdateFilter()
|
||||
{
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
if (!presShell || presShell->IsDestroying()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The filter might reference an SVG filter that is declared inside this
|
||||
// document. Flush frames so that we'll have an nsSVGFilterFrame to work
|
||||
// with.
|
||||
presShell->FlushPendingNotifications(Flush_Frames);
|
||||
|
||||
CurrentState().filter =
|
||||
nsFilterInstance::GetFilterDescription(mCanvasElement,
|
||||
CurrentState().filterChain,
|
||||
@ -4700,11 +4705,17 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& window, double x,
|
||||
RefPtr<SourceSurface> snapshot = drawDT->Snapshot();
|
||||
RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
|
||||
|
||||
DataSourceSurface::MappedSurface rawData;
|
||||
if (NS_WARN_IF(!data->Map(DataSourceSurface::READ, &rawData))) {
|
||||
error.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
RefPtr<SourceSurface> source =
|
||||
mTarget->CreateSourceSurfaceFromData(data->GetData(),
|
||||
mTarget->CreateSourceSurfaceFromData(rawData.mData,
|
||||
data->GetSize(),
|
||||
data->Stride(),
|
||||
rawData.mStride,
|
||||
data->GetFormat());
|
||||
data->Unmap();
|
||||
|
||||
if (!source) {
|
||||
error.Throw(NS_ERROR_FAILURE);
|
||||
@ -4979,12 +4990,13 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||
IntRect destRect(aX, aY, aWidth, aHeight);
|
||||
IntRect srcReadRect = srcRect.Intersect(destRect);
|
||||
RefPtr<DataSourceSurface> readback;
|
||||
DataSourceSurface::MappedSurface rawData;
|
||||
if (!srcReadRect.IsEmpty() && !mZero) {
|
||||
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
|
||||
if (snapshot) {
|
||||
readback = snapshot->GetDataSurface();
|
||||
}
|
||||
if (!readback || !readback->GetData()) {
|
||||
if (!readback || !readback->Map(DataSourceSurface::READ, &rawData)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
@ -5006,8 +5018,8 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||
uint32_t srcStride;
|
||||
|
||||
if (readback) {
|
||||
srcStride = readback->Stride();
|
||||
src = readback->GetData() + srcReadRect.y * srcStride + srcReadRect.x * 4;
|
||||
srcStride = rawData.mStride;
|
||||
src = rawData.mData + srcReadRect.y * srcStride + srcReadRect.x * 4;
|
||||
}
|
||||
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
@ -5071,6 +5083,10 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||
dst += (aWidth * 4) - (dstWriteRect.width * 4);
|
||||
}
|
||||
|
||||
if (readback) {
|
||||
readback->Unmap();
|
||||
}
|
||||
|
||||
*aRetval = darray;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -884,6 +884,7 @@ protected:
|
||||
fillRule(mozilla::gfx::FillRule::FILL_WINDING),
|
||||
lineCap(mozilla::gfx::CapStyle::BUTT),
|
||||
lineJoin(mozilla::gfx::JoinStyle::MITER_OR_BEVEL),
|
||||
filterString(MOZ_UTF16("none")),
|
||||
imageSmoothingEnabled(true),
|
||||
fontExplicitLanguage(false)
|
||||
{ }
|
||||
|
@ -324,6 +324,7 @@ public:
|
||||
void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
|
||||
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
|
||||
*/
|
||||
virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) override;
|
||||
void GetIndexedParameter(GLenum target, GLuint index,
|
||||
dom::Nullable<dom::OwningWebGLBufferOrLongLong>& retval);
|
||||
void GetUniformIndices(WebGLProgram* program,
|
||||
|
@ -36,6 +36,12 @@ WebGL2Context::DeleteSampler(WebGLSampler* sampler)
|
||||
if (!sampler || sampler->IsDeleted())
|
||||
return;
|
||||
|
||||
for (int n = 0; n < mGLMaxTextureUnits; n++) {
|
||||
if (mBoundSamplers[n] == sampler) {
|
||||
mBoundSamplers[n] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
sampler->RequestDelete();
|
||||
}
|
||||
|
||||
@ -74,6 +80,8 @@ WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler)
|
||||
return ErrorInvalidOperation("bindSampler: binding deleted sampler");
|
||||
|
||||
WebGLContextUnchecked::BindSampler(unit, sampler);
|
||||
|
||||
mBoundSamplers[unit] = sampler;
|
||||
}
|
||||
|
||||
void
|
||||
|
177
dom/canvas/WebGL2ContextState.cpp
Normal file
177
dom/canvas/WebGL2ContextState.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
/* -*- 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 "WebGL2Context.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
JS::Value
|
||||
WebGL2Context::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
{
|
||||
// The following cases are handled in WebGLContext::GetParameter():
|
||||
// case LOCAL_GL_MAX_COLOR_ATTACHMENTS:
|
||||
// case LOCAL_GL_MAX_DRAW_BUFFERS:
|
||||
// case LOCAL_GL_DRAW_BUFFERi:
|
||||
|
||||
if (IsContextLost())
|
||||
return JS::NullValue();
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
switch (pname) {
|
||||
/* GLboolean */
|
||||
case LOCAL_GL_RASTERIZER_DISCARD:
|
||||
case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
|
||||
case LOCAL_GL_SAMPLE_COVERAGE:
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED:
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE:
|
||||
case LOCAL_GL_UNPACK_SKIP_IMAGES:
|
||||
case LOCAL_GL_UNPACK_SKIP_PIXELS:
|
||||
case LOCAL_GL_UNPACK_SKIP_ROWS: {
|
||||
realGLboolean b = 0;
|
||||
gl->fGetBooleanv(pname, &b);
|
||||
return JS::BooleanValue(bool(b));
|
||||
}
|
||||
|
||||
/* GLenum */
|
||||
case LOCAL_GL_READ_BUFFER: {
|
||||
if (mBoundReadFramebuffer) {
|
||||
GLint val = LOCAL_GL_NONE;
|
||||
gl->fGetIntegerv(pname, &val);
|
||||
return JS::Int32Value(val);
|
||||
}
|
||||
|
||||
return JS::Int32Value(LOCAL_GL_BACK);
|
||||
}
|
||||
|
||||
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
|
||||
/* fall through */
|
||||
|
||||
/* GLint */
|
||||
case LOCAL_GL_MAX_3D_TEXTURE_SIZE:
|
||||
case LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS:
|
||||
case LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS:
|
||||
case LOCAL_GL_MAX_ELEMENTS_INDICES:
|
||||
case LOCAL_GL_MAX_ELEMENTS_VERTICES:
|
||||
case LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS:
|
||||
case LOCAL_GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
|
||||
case LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
|
||||
case LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET:
|
||||
case LOCAL_GL_MAX_SAMPLES:
|
||||
case LOCAL_GL_MAX_TEXTURE_LOD_BIAS:
|
||||
case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
|
||||
case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
|
||||
case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
|
||||
case LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS:
|
||||
case LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS:
|
||||
case LOCAL_GL_MAX_VERTEX_UNIFORM_BLOCKS:
|
||||
case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS:
|
||||
case LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET:
|
||||
case LOCAL_GL_PACK_ROW_LENGTH:
|
||||
case LOCAL_GL_PACK_SKIP_PIXELS:
|
||||
case LOCAL_GL_PACK_SKIP_ROWS:
|
||||
case LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
|
||||
case LOCAL_GL_UNPACK_IMAGE_HEIGHT:
|
||||
case LOCAL_GL_UNPACK_ROW_LENGTH: {
|
||||
GLint val;
|
||||
gl->fGetIntegerv(pname, &val);
|
||||
return JS::Int32Value(val);
|
||||
}
|
||||
|
||||
case LOCAL_GL_MAX_VARYING_COMPONENTS: {
|
||||
// On OS X Core Profile this is buggy. The spec says that the
|
||||
// value is 4 * GL_MAX_VARYING_VECTORS
|
||||
GLint val;
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &val);
|
||||
return JS::Int32Value(4*val);
|
||||
}
|
||||
|
||||
/* GLint64 */
|
||||
case LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
|
||||
return JS::NumberValue(0); // TODO
|
||||
|
||||
case LOCAL_GL_MAX_ELEMENT_INDEX:
|
||||
// GL_MAX_ELEMENT_INDEX becomes available in GL 4.3 or via ES3
|
||||
// compatibility
|
||||
if (!gl->IsSupported(gl::GLFeature::ES3_compatibility))
|
||||
return JS::NumberValue(0);
|
||||
|
||||
/*** fall through to fGetInteger64v ***/
|
||||
|
||||
case LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
|
||||
case LOCAL_GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
|
||||
case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE: {
|
||||
GLint64 val;
|
||||
gl->fGetInteger64v(pname, &val);
|
||||
return JS::DoubleValue(static_cast<double>(val));
|
||||
}
|
||||
|
||||
|
||||
/* GLuint64 */
|
||||
case LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT: {
|
||||
GLuint64 val;
|
||||
gl->fGetInteger64v(pname, (GLint64*) &val);
|
||||
return JS::DoubleValue(static_cast<double>(val));
|
||||
}
|
||||
|
||||
case LOCAL_GL_COPY_READ_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
|
||||
|
||||
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
|
||||
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_SAMPLER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundSamplers[mActiveTexture].get(), rv);
|
||||
|
||||
case LOCAL_GL_TEXTURE_BINDING_2D_ARRAY:
|
||||
// TODO: Implement gl.TEXTURE_2D_ARRAY
|
||||
// return WebGLObjectAsJSValue(cx, mBound2DTextureArrays[mActiveTexture].get(), rv);
|
||||
return JS::NullValue();
|
||||
|
||||
case LOCAL_GL_TEXTURE_BINDING_3D:
|
||||
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
|
||||
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BINDING: {
|
||||
WebGLTransformFeedback* tf =
|
||||
(mBoundTransformFeedback != mDefaultTransformFeedback) ? mBoundTransformFeedback.get() : nullptr;
|
||||
return WebGLObjectAsJSValue(cx, tf, rv);
|
||||
}
|
||||
|
||||
case LOCAL_GL_VERTEX_ARRAY_BINDING: {
|
||||
WebGLVertexArray* vao =
|
||||
(mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr;
|
||||
return WebGLObjectAsJSValue(cx, vao, rv);
|
||||
}
|
||||
|
||||
case LOCAL_GL_VERSION:
|
||||
return StringValue(cx, "WebGL 2.0", rv);
|
||||
|
||||
case LOCAL_GL_SHADING_LANGUAGE_VERSION:
|
||||
return StringValue(cx, "WebGL GLSL ES 3.00", rv);
|
||||
|
||||
default:
|
||||
return WebGLContext::GetParameter(cx, pname, rv);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -325,6 +325,7 @@ WebGLContext::DestroyResourcesAndContext()
|
||||
mBound2DTextures.Clear();
|
||||
mBoundCubeMapTextures.Clear();
|
||||
mBound3DTextures.Clear();
|
||||
mBoundSamplers.Clear();
|
||||
mBoundArrayBuffer = nullptr;
|
||||
mBoundCopyReadBuffer = nullptr;
|
||||
mBoundCopyWriteBuffer = nullptr;
|
||||
@ -1949,6 +1950,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLContext,
|
||||
mBound2DTextures,
|
||||
mBoundCubeMapTextures,
|
||||
mBound3DTextures,
|
||||
mBoundSamplers,
|
||||
mBoundArrayBuffer,
|
||||
mBoundCopyReadBuffer,
|
||||
mBoundCopyWriteBuffer,
|
||||
|
@ -65,6 +65,16 @@ class nsIDocShell;
|
||||
#define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164
|
||||
#define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164
|
||||
|
||||
/*
|
||||
* WebGL-only GLenums
|
||||
*/
|
||||
#define LOCAL_GL_BROWSER_DEFAULT_WEBGL 0x9244
|
||||
#define LOCAL_GL_CONTEXT_LOST_WEBGL 0x9242
|
||||
#define LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL 0x9247
|
||||
#define LOCAL_GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243
|
||||
#define LOCAL_GL_UNPACK_FLIP_Y_WEBGL 0x9240
|
||||
#define LOCAL_GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLActiveInfo;
|
||||
@ -955,7 +965,7 @@ public:
|
||||
void Disable(GLenum cap);
|
||||
void Enable(GLenum cap);
|
||||
bool GetStencilBits(GLint* out_stencilBits);
|
||||
JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
|
||||
virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
|
||||
|
||||
void GetParameter(JSContext* cx, GLenum pname,
|
||||
JS::MutableHandle<JS::Value> retval, ErrorResult& rv)
|
||||
@ -1435,6 +1445,7 @@ protected:
|
||||
nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures;
|
||||
nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
|
||||
nsTArray<WebGLRefPtr<WebGLTexture> > mBound3DTextures;
|
||||
nsTArray<WebGLRefPtr<WebGLSampler> > mBoundSamplers;
|
||||
|
||||
void ResolveTexturesForDraw() const;
|
||||
|
||||
|
@ -58,18 +58,6 @@ WebGLContext::Enable(GLenum cap)
|
||||
gl->fEnable(cap);
|
||||
}
|
||||
|
||||
static JS::Value
|
||||
StringValue(JSContext* cx, const char* chars, ErrorResult& rv)
|
||||
{
|
||||
JSString* str = JS_NewStringCopyZ(cx, chars);
|
||||
if (!str) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return JS::NullValue();
|
||||
}
|
||||
|
||||
return JS::StringValue(str);
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::GetStencilBits(GLint* out_stencilBits)
|
||||
{
|
||||
@ -150,18 +138,15 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
} else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
|
||||
pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
|
||||
{
|
||||
if (mBoundDrawFramebuffer) {
|
||||
GLint iv = 0;
|
||||
gl->fGetIntegerv(pname, &iv);
|
||||
return JS::Int32Value(iv);
|
||||
}
|
||||
|
||||
GLint iv = 0;
|
||||
gl->fGetIntegerv(pname, &iv);
|
||||
|
||||
if (iv == GLint(LOCAL_GL_COLOR_ATTACHMENT0 + pname - LOCAL_GL_DRAW_BUFFER0)) {
|
||||
if (mBoundDrawFramebuffer)
|
||||
return JS::Int32Value(iv);
|
||||
|
||||
const GLint index = (pname - LOCAL_GL_DRAW_BUFFER0);
|
||||
if (iv == LOCAL_GL_COLOR_ATTACHMENT0 + index)
|
||||
return JS::Int32Value(LOCAL_GL_BACK);
|
||||
}
|
||||
|
||||
return JS::Int32Value(LOCAL_GL_NONE);
|
||||
}
|
||||
@ -169,11 +154,9 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
|
||||
if (IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
|
||||
if (pname == LOCAL_GL_VERTEX_ARRAY_BINDING) {
|
||||
if (mBoundVertexArray == mDefaultVertexArray){
|
||||
return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv);
|
||||
}
|
||||
|
||||
return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv);
|
||||
WebGLVertexArray* vao =
|
||||
(mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr;
|
||||
return WebGLObjectAsJSValue(cx, vao, rv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,10 +164,12 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
if (pname == LOCAL_GL_TIMESTAMP_EXT) {
|
||||
GLuint64 iv = 0;
|
||||
gl->fGetInteger64v(pname, (GLint64*) &iv);
|
||||
return JS::NumberValue(uint64_t(iv));
|
||||
// TODO: JS doesn't support 64-bit integers. Be lossy and
|
||||
// cast to double (53 bits)
|
||||
return JS::NumberValue(static_cast<double>(iv));
|
||||
} else if (pname == LOCAL_GL_GPU_DISJOINT_EXT) {
|
||||
// When disjoint isn't supported, leave as false.
|
||||
realGLboolean disjoint = 0;
|
||||
realGLboolean disjoint = LOCAL_GL_FALSE;
|
||||
if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) {
|
||||
gl->fGetBooleanv(pname, &disjoint);
|
||||
}
|
||||
@ -192,40 +177,35 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsWebGL2()) {
|
||||
// Privileged string params exposed by WEBGL_debug_renderer_info:
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) {
|
||||
switch (pname) {
|
||||
case LOCAL_GL_MAX_SAMPLES:
|
||||
case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE:
|
||||
case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS: {
|
||||
GLint val;
|
||||
gl->fGetIntegerv(pname, &val);
|
||||
return JS::NumberValue(uint32_t(val));
|
||||
case UNMASKED_VENDOR_WEBGL:
|
||||
case UNMASKED_RENDERER_WEBGL:
|
||||
GLenum glstringname = LOCAL_GL_NONE;
|
||||
if (pname == UNMASKED_VENDOR_WEBGL) {
|
||||
glstringname = LOCAL_GL_VENDOR;
|
||||
} else if (pname == UNMASKED_RENDERER_WEBGL) {
|
||||
glstringname = LOCAL_GL_RENDERER;
|
||||
}
|
||||
const GLchar* string = (const GLchar*) gl->fGetString(glstringname);
|
||||
return StringValue(cx, string, rv);
|
||||
}
|
||||
}
|
||||
|
||||
case LOCAL_GL_TEXTURE_BINDING_3D:
|
||||
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
|
||||
if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) {
|
||||
if (pname == LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT) {
|
||||
GLint i = 0;
|
||||
gl->fGetIntegerv(pname, &i);
|
||||
return JS::Int32Value(i);
|
||||
}
|
||||
}
|
||||
|
||||
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
|
||||
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_COPY_READ_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
|
||||
|
||||
case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
|
||||
return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
|
||||
if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
|
||||
if (pname == LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) {
|
||||
GLfloat f = 0.f;
|
||||
gl->fGetFloatv(pname, &f);
|
||||
return JS::NumberValue(f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,42 +214,13 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
// String params
|
||||
//
|
||||
case LOCAL_GL_VENDOR:
|
||||
return StringValue(cx, "Mozilla", rv);
|
||||
case LOCAL_GL_RENDERER:
|
||||
return StringValue(cx, "Mozilla", rv);
|
||||
case LOCAL_GL_VERSION: {
|
||||
const char* version = 0;
|
||||
|
||||
if (IsWebGL2()) {
|
||||
version = "WebGL 2.0";
|
||||
} else {
|
||||
version = "WebGL 1.0";
|
||||
}
|
||||
|
||||
MOZ_ASSERT(version != 0);
|
||||
return StringValue(cx, version, rv);
|
||||
}
|
||||
case LOCAL_GL_VERSION:
|
||||
return StringValue(cx, "WebGL 1.0", rv);
|
||||
case LOCAL_GL_SHADING_LANGUAGE_VERSION:
|
||||
return StringValue(cx, "WebGL GLSL ES 1.0", rv);
|
||||
|
||||
// Privileged string params exposed by WEBGL_debug_renderer_info:
|
||||
case UNMASKED_VENDOR_WEBGL:
|
||||
case UNMASKED_RENDERER_WEBGL: {
|
||||
// The privilege check is done in WebGLContext::IsExtensionSupported.
|
||||
// So here we just have to check that the extension is enabled.
|
||||
if (!IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) {
|
||||
break;
|
||||
}
|
||||
GLenum glstringname = LOCAL_GL_NONE;
|
||||
if (pname == UNMASKED_VENDOR_WEBGL) {
|
||||
glstringname = LOCAL_GL_VENDOR;
|
||||
} else if (pname == UNMASKED_RENDERER_WEBGL) {
|
||||
glstringname = LOCAL_GL_RENDERER;
|
||||
}
|
||||
const char* string = reinterpret_cast<const char*>(gl->fGetString(glstringname));
|
||||
return StringValue(cx, string, rv);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// Single-value params
|
||||
|
||||
@ -380,15 +331,6 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
}
|
||||
return JS::Int32Value(i);
|
||||
}
|
||||
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT: {
|
||||
if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) {
|
||||
GLint i = 0;
|
||||
gl->fGetIntegerv(pname, &i);
|
||||
return JS::Int32Value(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case LOCAL_GL_MAX_TEXTURE_SIZE:
|
||||
return JS::Int32Value(mGLMaxTextureSize);
|
||||
|
||||
@ -417,38 +359,22 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||
}
|
||||
return JS::ObjectOrNullValue(obj);
|
||||
}
|
||||
case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: {
|
||||
if (!IsWebGL2()) {
|
||||
break;
|
||||
}
|
||||
return JS::Int32Value(mGLMaxTransformFeedbackSeparateAttribs);
|
||||
}
|
||||
|
||||
// unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as
|
||||
// javascript integer values. We just return them as doubles and javascript doesn't care.
|
||||
case LOCAL_GL_STENCIL_BACK_VALUE_MASK: {
|
||||
case LOCAL_GL_STENCIL_BACK_VALUE_MASK:
|
||||
return JS::DoubleValue(mStencilValueMaskBack); // pass as FP value to allow large values such as 2^32-1.
|
||||
}
|
||||
case LOCAL_GL_STENCIL_BACK_WRITEMASK: {
|
||||
|
||||
case LOCAL_GL_STENCIL_BACK_WRITEMASK:
|
||||
return JS::DoubleValue(mStencilWriteMaskBack);
|
||||
}
|
||||
case LOCAL_GL_STENCIL_VALUE_MASK: {
|
||||
|
||||
case LOCAL_GL_STENCIL_VALUE_MASK:
|
||||
return JS::DoubleValue(mStencilValueMaskFront);
|
||||
}
|
||||
case LOCAL_GL_STENCIL_WRITEMASK: {
|
||||
|
||||
case LOCAL_GL_STENCIL_WRITEMASK:
|
||||
return JS::DoubleValue(mStencilWriteMaskFront);
|
||||
}
|
||||
|
||||
// float
|
||||
case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
|
||||
if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
|
||||
GLfloat f = 0.f;
|
||||
gl->fGetFloatv(pname, &f);
|
||||
return JS::DoubleValue(f);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case LOCAL_GL_DEPTH_CLEAR_VALUE:
|
||||
case LOCAL_GL_LINE_WIDTH:
|
||||
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
|
||||
|
@ -75,6 +75,18 @@ TexImageTargetToTexTarget(TexImageTarget texImageTarget)
|
||||
}
|
||||
}
|
||||
|
||||
JS::Value
|
||||
StringValue(JSContext* cx, const char* chars, ErrorResult& rv)
|
||||
{
|
||||
JSString* str = JS_NewStringCopyZ(cx, chars);
|
||||
if (!str) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return JS::NullValue();
|
||||
}
|
||||
|
||||
return JS::StringValue(str);
|
||||
}
|
||||
|
||||
GLComponents::GLComponents(TexInternalFormat internalformat)
|
||||
{
|
||||
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||
|
@ -56,6 +56,9 @@ size_t GetBitsPerTexel(TexInternalFormat effectiveinternalformat);
|
||||
// Returns GL_NONE if passed an invalid texture image target
|
||||
TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
|
||||
|
||||
// Helper function to create a JS::Value from a C string
|
||||
JS::Value StringValue(JSContext* cx, const char* str, ErrorResult& rv);
|
||||
|
||||
struct GLComponents
|
||||
{
|
||||
unsigned char mComponents;
|
||||
|
@ -1755,6 +1755,7 @@ WebGLContext::InitAndValidateGL()
|
||||
mBound2DTextures.Clear();
|
||||
mBoundCubeMapTextures.Clear();
|
||||
mBound3DTextures.Clear();
|
||||
mBoundSamplers.Clear();
|
||||
|
||||
mBoundArrayBuffer = nullptr;
|
||||
mBoundTransformFeedbackBuffer = nullptr;
|
||||
@ -1798,6 +1799,7 @@ WebGLContext::InitAndValidateGL()
|
||||
mBound2DTextures.SetLength(mGLMaxTextureUnits);
|
||||
mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
|
||||
mBound3DTextures.SetLength(mGLMaxTextureUnits);
|
||||
mBoundSamplers.SetLength(mGLMaxTextureUnits);
|
||||
|
||||
if (MinCapabilityMode()) {
|
||||
mGLMaxTextureSize = MINVALUE_GL_MAX_TEXTURE_SIZE;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef WEBGL_TIMER_QUERY_H_
|
||||
#define WEBGL_TIMER_QUERY_H_
|
||||
|
||||
#include "GLConsts.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
|
||||
|
@ -61,6 +61,7 @@ UNIFIED_SOURCES += [
|
||||
'WebGL2ContextPrograms.cpp',
|
||||
'WebGL2ContextQueries.cpp',
|
||||
'WebGL2ContextSamplers.cpp',
|
||||
'WebGL2ContextState.cpp',
|
||||
'WebGL2ContextSync.cpp',
|
||||
'WebGL2ContextTextures.cpp',
|
||||
'WebGL2ContextTransformFeedback.cpp',
|
||||
|
@ -249,3 +249,4 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # bug 1040965
|
||||
[test_2d_composite_canvaspattern_setTransform.html]
|
||||
[test_createPattern_broken.html]
|
||||
[test_setlinedash.html]
|
||||
[test_filter.html]
|
||||
|
16
dom/canvas/test/reftest/filters/default-color.html
Normal file
16
dom/canvas/test/reftest/filters/default-color.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.filter = 'drop-shadow(0 10px)';
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
17
dom/canvas/test/reftest/filters/drop-shadow-transformed.html
Normal file
17
dom/canvas/test/reftest/filters/drop-shadow-transformed.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.scale(-1, -1);
|
||||
ctx.filter = 'drop-shadow(0 10px black)';
|
||||
ctx.fillRect(-75, -65, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
16
dom/canvas/test/reftest/filters/drop-shadow.html
Normal file
16
dom/canvas/test/reftest/filters/drop-shadow.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.filter = 'drop-shadow(0 10px black)';
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
18
dom/canvas/test/reftest/filters/global-alpha-ref.html
Normal file
18
dom/canvas/test/reftest/filters/global-alpha-ref.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.fillRect(25, 35, 50, 40);
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
17
dom/canvas/test/reftest/filters/global-alpha.html
Normal file
17
dom/canvas/test/reftest/filters/global-alpha.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.filter = 'drop-shadow(0 10px black)';
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.arc(50, 50, 25, 0, Math.PI * 2, true);
|
||||
ctx.fill();
|
||||
|
||||
var tmp_canvas = canvas.cloneNode();
|
||||
var tmp_ctx = tmp_canvas.getContext('2d');
|
||||
tmp_ctx.fillStyle = '#0f0';
|
||||
tmp_ctx.fillRect(25, 25, 50, 50);
|
||||
tmp_ctx.fillStyle = '#000';
|
||||
tmp_ctx.fillRect(25, 65, 50, 10);
|
||||
|
||||
ctx.globalCompositeOperation = 'source-in';
|
||||
ctx.drawImage(tmp_canvas, 0, 0);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.arc(50, 50, 25, 0, Math.PI * 2, true);
|
||||
ctx.fill();
|
||||
|
||||
ctx.filter = 'drop-shadow(0 10px black)';
|
||||
ctx.globalCompositeOperation = 'source-in';
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
18
dom/canvas/test/reftest/filters/liveness.html
Normal file
18
dom/canvas/test/reftest/filters/liveness.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.font = '10px sans-serif';
|
||||
ctx.filter = 'drop-shadow(0 .5em black)';
|
||||
ctx.font = '20px sans-serif';
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
16
dom/canvas/test/reftest/filters/multiple-drop-shadows.html
Normal file
16
dom/canvas/test/reftest/filters/multiple-drop-shadows.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.filter = 'drop-shadow(0 10px black) drop-shadow(10px 0 #ccc)';
|
||||
ctx.fillRect(20, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
17
dom/canvas/test/reftest/filters/ref.html
Normal file
17
dom/canvas/test/reftest/filters/ref.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 40);
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.fillRect(25, 65, 50, 10);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
20
dom/canvas/test/reftest/filters/reftest.list
Normal file
20
dom/canvas/test/reftest/filters/reftest.list
Normal file
@ -0,0 +1,20 @@
|
||||
default-preferences pref(canvas.filters.enabled,true)
|
||||
|
||||
== default-color.html ref.html
|
||||
== drop-shadow.html ref.html
|
||||
== drop-shadow-transformed.html ref.html
|
||||
== global-alpha.html global-alpha-ref.html
|
||||
== global-composite-operation.html global-composite-operation-ref.html
|
||||
== liveness.html ref.html
|
||||
== multiple-drop-shadows.html shadow-ref.html
|
||||
== shadow.html shadow-ref.html
|
||||
== subregion-fill-paint.html subregion-ref.html
|
||||
== subregion-stroke-paint.html subregion-ref.html
|
||||
== svg-bbox.html svg-bbox-ref.html
|
||||
== svg-inline.html ref.html
|
||||
== svg-liveness.html ref.html
|
||||
== svg-off-screen.html ref.html
|
||||
== units.html ref.html
|
||||
== units-em.html ref.html
|
||||
== units-ex.html ref.html
|
||||
== units-off-screen.html ref.html
|
19
dom/canvas/test/reftest/filters/shadow-ref.html
Normal file
19
dom/canvas/test/reftest/filters/shadow-ref.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.shadowOffsetX = 10;
|
||||
ctx.shadowColor = '#ccc';
|
||||
ctx.fillRect(20, 25, 50, 40);
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.fillRect(20, 65, 50, 10);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
18
dom/canvas/test/reftest/filters/shadow.html
Normal file
18
dom/canvas/test/reftest/filters/shadow.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.filter = 'drop-shadow(0 10px black)';
|
||||
ctx.shadowOffsetX = 10;
|
||||
ctx.shadowColor = '#ccc';
|
||||
ctx.fillRect(20, 25, 50, 40);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
27
dom/canvas/test/reftest/filters/subregion-fill-paint.html
Normal file
27
dom/canvas/test/reftest/filters/subregion-fill-paint.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<svg style="display: block; width: 0; height: 0">
|
||||
<defs>
|
||||
<filter id="merge" primitiveUnits="objectBoundingBox">
|
||||
<feMerge x="25%" y="25%" width="50%" height="50%">
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
<feMergeNode in="FillPaint"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.filter = 'url(#merge)';
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.arc(50, 50, 25, 0, Math.PI * 2, true);
|
||||
ctx.fill();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
15
dom/canvas/test/reftest/filters/subregion-ref.html
Normal file
15
dom/canvas/test/reftest/filters/subregion-ref.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(25, 25, 50, 50);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user