mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1222098 - Devicemotion event timestamp should return values from Android sensor API and not Gecko. r:smaug (0fb05341d5)
- Bug 1266701 - some header missing in dom/events, r=jwatt (59a8a30af3)
- namespace (c5796648b6)
- Bug 1243555: Remove unnecessary nsDocShell static_cast in EventListenerManager::HandleEventInternal(). r=smaug (21c559122c)
- Bug 1254629 - Let query events fail when content root is wrong; r=masayuki (64454249aa)
- Bug 1224233 - fix crashy usage of IMENotificationSender::Run using on-screen keyboard on Windows, r=smaug (ddcdf13ad0)
- Bug 1252058 IMEContentObserver::IMENotificationSender shouldn't post notifications when IMEContentObserver which is the owner of it stopped observing contents r=smaug (9f4a14f13a)
- Bug 1259671 part.1 Rename InternalScrollPortEvent::orientType to InternalScrollPortEvent::OrientType r=smaug (eaefa4472f)
- Bug 1259671 part.2 Rename InternalScrollPortEvent::vertical to InternalScrollPortEvent::eVertical r=smaug (91bcdcd1df)
- Bug 1259671 part.3 Rename InternalScrollPortEvent::horizontal to InternalScrollPortEvent::eHorizontal r=smaug (f3c206dc4c)
- Bug 1259671 part.4 Rename InternalScrollPortEvent::both to InternalScrollPortEvent::eBoth r=smaug (ac34dc95c1)
- Bug 1259671 part.5 Rename InternalScrollPortEvent::orient to InternalScrollPortEvent::mOrient r=smaug (6736862c75)
- Bug 1262324 (part 1) - Remove "locale.all" prefix from Unix charsets. r=emk. (b337137c3d)
- Bug 1255655 - Const-ify dom encodings and similar arrays. r=baku. (93d79e84a7)
- Bug 1262324 (part 2) - Introduce nsUConvProp. r=emk. (bad497dee6)
- Bug 1257877 - Remove UTF-16 support from TextEncoder. r=hsivonen (ad647b12a3)
- Bug 1120813 - Add support for the MS932 label of Shift_JIS. r=emk, r=Ms2ger (8a35fd93cf)
- Bug 1250930 - Use correct global when creating a key in GenerateAsymmetricKeyTask r=bz (ba65e0ae34)
- Bug 842818 - Allow calling WebCryptoTask::DispatchWithPromise() from workers r=keeler (e99301ba3e)
- Bug 1251390. Make timer queries available at the appropriate time. r=jgilbert (f1a0dcf7d3)
- Bug 1259696 - Check read buffer mode when doing CopyTexImage. r=jgilbert (fe51211b56)
- Bug 1241042 - Get correct frag varying from angle validator. r=jmuizelaar (29a4298a7e)
- Bug 1244611 - "Using named uniform buffer objects in the fragment shader fails". r=jgilbert (2e05e31d09)
- Bug 1263018 - Only update active prog info if linking active prog. - r=jrmuizel (1603ebdd8c)
- Bug 1257593 - Handle webgl FramebufferTexture2D() with an unbound texture. r=jgilbert (4d75981cb7)
- Bug 1257593 followup, fix bustage from believing a reviewer and then sending a different patch to try (7766b0cdb4)
- Bug 1258061 - Clarify FramebufferTexture2D handling for tex2D and cubeMap; r=jgilbert (0635d9412a)
- Bug 1259449 - Require GLFeature::sync for WebGL's disjoint_timer_query. - r=jrmuizel (b6017134a3)
- Bug 1247804 - Enable seamless cubemaps where available. - r=jrmuizel (e7fd3ec5ed)
- Bug 1247977: More information when we hit the OpenGL error in FakeBlackTexture. r=jgilbert (f6f2c82e33)
- Bug 1255655 - Const-ify sExtensionNames. r=mattwoodrow. (c0c60b34c7)
- Bug 1262757 - Use StaticRefPtr for the global context in GLContextProviderWGL, r=jrmuizel (0cc29a3385)
- Bug 1259811 - Require FBO support for GLContexts. - r=jrmuizel (ec3c1a6045)
- Bug 1234441 - Allow malformed ESSL version string. - r=jrmuizel (8fda1569ab)
- Bug 1199923 - Work around Intel Linux driver lying about max texture size - r=jgilbert (546b7dfe6a)
- Bug 1262265 - Cleanup GLContext symbol init. - r=jrmuizel (8da8ce647a)
- Bug 1232334 - [1.2] Only set context on successful attach. r=snorp (ca29c322bf)
- Bug 1261320 - Check DataSurface is vaild before using, r=milan (be9aebba47)
- Bug 1245868 - repalce pass by value with pass by pointer in IsHeadRequest. r=jst (f9d7f6185f)
- fix tests (3ccf9d1715)
- Bug 1232941 - Register Observer and listen to NS_XPCOM_SHUTDOWN_OBSERVER_ID for GATT, r=shuang (aa367807fa)
- Bug 1239979: Init and uninit all Bluetooth profile managers, r=shuang (78c1ebbd13)
- Bug 1239979: Uninitialized Bluetooth profile managers explictly to release refs, r=shuang (83b5389539)
- Bug 1262630. Replace workers::GetGlobalObjectForGlobal with xpc::NativeGlobal. r=khuey (9f639580be)
- Bug 1255817 part 6. Fix up some comments in CallbackObject that refer to things that no longer exist. r=bholley (575bf90c98)
- Bug 1259545. Remove the JS_SaveFrameChain bits in CallbackObject error reporting, since they are no longer needed. r=bholley (16181ddb38)
- Bug 1260511 part 2. Change XPConnect's handling of exceptions thrown from JS components so that if an nsresult integer is thrown we convert it into an actual exception object before handing it out to content instead of propagating out the numeric value. r=khuey (dc02854e3f)
- Bug 1260511 part 3. In dom::Throw, ignore the pending xpconnect exception if we were given a non-default message string (because we don't want to lose that string). Also, make sure to always clear the pending xpconnect exception there. r=khuey (978a1e9132)
- Bug 1250106 - Correctly set charging status and remaining time when battery level is rounded to 1.0 r=bz (662e18648c)
- Bug 1253641 - DOMException's CC participant should traverse mData. r=khuey. (0a48e3f8e7)
- Bug 1261115 - when Console is running in the main thread the existence of mWindow should always be ensured, r=smaug (caa1efd087)
- Bug 1257208 - Use the nsTextNode concrete type in several places in DirectionalityUtils.cpp instead of nsINode and nsIContent; r=peterv (69529fd8d4)
- Bug 1260982 - BlobFileImpl::GetType() should work also in workers, r=smaug (4b01d269bc)
- Bug 1262104 - Remove a non-used CTOR for BlobImplFile, r=ehsan (37ee0ec6d4)
- Bug 1259477 - Port test_document_register.html to mochitest-plain so that it can be turned on in e10s mode; r=mrbkap (411c220cda)
- Bug 1222128 - Turn test_bug1011748.html into a browser mochitest to make it run properly in e10s mode r=bzbarsky (45403d3d15)
- Bug 1259588 - new File("") throws TypeError exception, r=baku (05f6e7292d)
- Bug 1264710 - Catch IDB exceptions in IndexedDBHelper. r=fabrice (0d3c860a89)
- Bug 1263553 - Move MultipartBlobImpl into mozilla::dom namespace, r=smaug (e286c6cfe1)
- Bug 1263551 - Remove unused method in MultipartBlobImpl, r=smaug (54c2da9a12)
- Bug 1252687 - get rid of static nsStrings in PerformanceObserver.cpp r=bz (319f2697d4)
- Bug 1148535 - Check if the density descriptor in srcset consists of a valid floating-point number. r=jdm (79ac8d8dea)
- Bug 1257742 - Part 1: Follow the update-source-set rule to append default source into source set; r=jdm (853c69cc8c)
- Bug 1257742 - Part 2: Allow both width and static density candidates showing in same selector; r=jdm (4f1e00225d)
- Bug 1257742 - Part 3: Support using floating point in sizes descriptor; r=jdm (c1a7e36bb3)
- Bug 1257742 - Part 4: Update web-platform test expectation; r=jdm (e41044b88e)
- Bug 1262942 - Remove unnecessary warning message in ResponsiveImageSelector; r=jdm (ffb757204d)
- Bug 1158412 - Remove assertion for document prescontex and add crash test; r=jdm (947ccdfbfc)
- Bug 1237633 - Part 1: Percentages are not allowed in a <source-size-value>. r=jdm (614b560097)
- Bug 1237633 - Part 2: Avoid fatal assertion when a responsive image's size specifier is invalid. r=johns, r=jdm (4e90829d97)
- Bug 495546 - Add crashtest. (c2765ecbf4)
- fix some tests (d9b393b168)
- Bug 1256419. Null-check our nsDOMWindowList before trying to get its length. r=smaug (6c14430e5d)
- Bug 1162775: Make contentAreaDropListener use dataTransfer.files to get the files dropped. r=smaug (d2850f2008)
- Bug 1220679 - replace AutoSafeJSContext with AutoJSAPI. r=bz. (64538bdd44)
- reinstantiate assert, present in up to esr68 (221cec538a)
- Bug 1209329 - Improve comments about about: URIs in nsContentUtils::InternalStorageAllowedForPrincipal, r=bholley (71152e5639)
- Bug 1246250 - Deal with failure to create a blob actor. r=khuey (102686ac28)
- Bug 1265902 - part 1 - be more efficient when using nsContentUtils::GetSurfaceData(); r=mccr8 (ba2a52abd3)
- Bug 1258857 - Add empty items to an IPC transferable object for every flavor of the source object that did not have any data associated to it r=enndeakin (0a02b61566)
- Bug 1265902 - part 2 - don't construct unnecessary string temporaries in TransferablesToIPCTransferables; r=mccr8 (aec10c8fc6)
- remove unknown blob handling, not found in Tycho-dev repo, nor esr60 or TFF (eb6a24720a)
- Bug 1155486 - Convert nsDOMAttributeMap::mLocalName to void* to ensure that we can never dereference it; r=baku (34e2864340)
- Bug 1250926 - Remove unused SCRIPTABLE_FLAGS defines from nsDOMClassInfo; r=peterv (76917fb76b)
- No bug. Helper tool to partially autogenerate portions of the release notes. (3818e5534b)
- Bug 1203423 - Move call to AddClone outside nsMutationReceiver constructor; r=smaug (35c94ad785)
- Bug 1254096 - Update CaretPositionFromPoint() for type=number, r=ehsan (df31edca8f)
- Bug 1265771 P1 Only store active documents in the global observer list. r=bz (01502e91e5)
- Bug 1265771 P2 Expand navigate-window.https.html wpt test to cover uncontrolled windows. r=bz (3333906720)
- Bug 1265771 P3 Expand browser_force_refresh.js to verify Clients.matchAll() behavior on refresh. r=bz (01394ec8f1)
- stop hiding things for _LIBCPP_VERSION (5de86e8bbf)
This commit is contained in:
@@ -886,6 +886,8 @@ NS_INTERFACE_MAP_END
|
||||
/* static */ already_AddRefed<Console>
|
||||
Console::Create(nsPIDOMWindow* aWindow, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT_IF(NS_IsMainThread(), aWindow);
|
||||
|
||||
RefPtr<Console> console = new Console(aWindow);
|
||||
console->Initialize(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
@@ -904,6 +906,8 @@ Console::Console(nsPIDOMWindow* aWindow)
|
||||
, mInnerID(0)
|
||||
, mStatus(eUnknown)
|
||||
{
|
||||
MOZ_ASSERT_IF(NS_IsMainThread(), aWindow);
|
||||
|
||||
if (mWindow) {
|
||||
MOZ_ASSERT(mWindow->IsInnerWindow());
|
||||
mInnerID = mWindow->WindowID();
|
||||
|
||||
@@ -177,6 +177,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Exception)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mData)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
@@ -187,6 +188,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Exception)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mData)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->mThrownJSVal.setNull();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
@@ -386,7 +386,7 @@ GetDirectionFromText(const nsTextFragment* aFrag,
|
||||
* know not to return it
|
||||
* @return the text node containing the character that determined the direction
|
||||
*/
|
||||
static nsINode*
|
||||
static nsTextNode*
|
||||
WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true,
|
||||
nsINode* aChangedNode = nullptr)
|
||||
{
|
||||
@@ -412,7 +412,7 @@ WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true,
|
||||
// We found a descendant text node with strong directional characters.
|
||||
// Set the directionality of aElement to the corresponding value.
|
||||
aElement->SetDirectionality(textNodeDir, aNotify);
|
||||
return child;
|
||||
return static_cast<nsTextNode*>(child);
|
||||
}
|
||||
}
|
||||
child = child->GetNextNode(aElement);
|
||||
@@ -454,7 +454,7 @@ public:
|
||||
MOZ_COUNT_DTOR(nsTextNodeDirectionalityMap);
|
||||
}
|
||||
|
||||
void AddEntry(nsINode* aTextNode, Element* aElement)
|
||||
void AddEntry(nsTextNode* aTextNode, Element* aElement)
|
||||
{
|
||||
if (!mElements.Contains(aElement)) {
|
||||
mElements.Put(aElement);
|
||||
@@ -463,7 +463,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveEntry(nsINode* aTextNode, Element* aElement)
|
||||
void RemoveEntry(nsTextNode* aTextNode, Element* aElement)
|
||||
{
|
||||
NS_ASSERTION(mElements.Contains(aElement),
|
||||
"element already removed from map");
|
||||
@@ -505,7 +505,7 @@ private:
|
||||
// and remove the text node from the map
|
||||
nsINode* oldTextNode = static_cast<Element*>(aData);
|
||||
Element* rootNode = aEntry->GetKey();
|
||||
nsINode* newTextNode = nullptr;
|
||||
nsTextNode* newTextNode = nullptr;
|
||||
if (rootNode->GetParentNode() && rootNode->HasDirAuto()) {
|
||||
newTextNode = WalkDescendantsSetDirectionFromText(rootNode, true,
|
||||
oldTextNode);
|
||||
@@ -551,14 +551,14 @@ public:
|
||||
MOZ_ASSERT(clearedEntries == 0, "Map should be empty already");
|
||||
}
|
||||
|
||||
static void RemoveElementFromMap(nsINode* aTextNode, Element* aElement)
|
||||
static void RemoveElementFromMap(nsTextNode* aTextNode, Element* aElement)
|
||||
{
|
||||
if (aTextNode->HasTextNodeDirectionalityMap()) {
|
||||
GetDirectionalityMap(aTextNode)->RemoveEntry(aTextNode, aElement);
|
||||
}
|
||||
}
|
||||
|
||||
static void AddEntryToMap(nsINode* aTextNode, Element* aElement)
|
||||
static void AddEntryToMap(nsTextNode* aTextNode, Element* aElement)
|
||||
{
|
||||
nsTextNodeDirectionalityMap* map = GetDirectionalityMap(aTextNode);
|
||||
if (!map) {
|
||||
@@ -576,8 +576,8 @@ public:
|
||||
return GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir);
|
||||
}
|
||||
|
||||
static void ResetTextNodeDirection(nsINode* aTextNode,
|
||||
nsINode* aChangedTextNode)
|
||||
static void ResetTextNodeDirection(nsTextNode* aTextNode,
|
||||
nsTextNode* aChangedTextNode)
|
||||
{
|
||||
MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
|
||||
"Map missing in ResetTextNodeDirection");
|
||||
@@ -651,7 +651,7 @@ SetDirectionalityOnDescendants(Element* aElement, Directionality aDir,
|
||||
void
|
||||
WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify)
|
||||
{
|
||||
nsINode* setByNode;
|
||||
nsTextNode* setByNode;
|
||||
Element* parent = aElement->GetParentElement();
|
||||
|
||||
while (parent && parent->NodeOrAncestorHasDirAuto()) {
|
||||
@@ -661,7 +661,7 @@ WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify)
|
||||
// Remove it from the map and reset its direction by the downward
|
||||
// propagation algorithm
|
||||
setByNode =
|
||||
static_cast<nsINode*>(parent->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
static_cast<nsTextNode*>(parent->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
if (setByNode) {
|
||||
nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, parent);
|
||||
}
|
||||
@@ -687,11 +687,10 @@ WalkDescendantsResetAutoDirection(Element* aElement)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child->HasTextNodeDirectionalityMap()) {
|
||||
nsTextNodeDirectionalityMap::ResetTextNodeDirection(child, nullptr);
|
||||
// Don't call nsTextNodeDirectionalityMap::EnsureMapIsClearFor(child)
|
||||
// since ResetTextNodeDirection may have kept elements in child's
|
||||
// DirectionalityMap.
|
||||
if (child->NodeType() == nsIDOMNode::TEXT_NODE &&
|
||||
child->HasTextNodeDirectionalityMap()) {
|
||||
nsTextNodeDirectionalityMap::ResetTextNodeDirection(static_cast<nsTextNode*>(child), nullptr);
|
||||
nsTextNodeDirectionalityMap::EnsureMapIsClearFor(child);
|
||||
}
|
||||
child = child->GetNextNode(aElement);
|
||||
}
|
||||
@@ -733,7 +732,7 @@ WalkDescendantsSetDirAuto(Element* aElement, bool aNotify)
|
||||
}
|
||||
}
|
||||
|
||||
nsINode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify);
|
||||
nsTextNode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify);
|
||||
if (textNode) {
|
||||
nsTextNodeDirectionalityMap::AddEntryToMap(textNode, aElement);
|
||||
}
|
||||
@@ -754,7 +753,7 @@ WalkDescendantsClearAncestorDirAuto(Element* aElement)
|
||||
}
|
||||
}
|
||||
|
||||
void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir,
|
||||
void SetAncestorDirectionIfAuto(nsTextNode* aTextNode, Directionality aDir,
|
||||
bool aNotify = true)
|
||||
{
|
||||
MOZ_ASSERT(aTextNode->NodeType() == nsIDOMNode::TEXT_NODE,
|
||||
@@ -768,8 +767,8 @@ void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir,
|
||||
|
||||
if (parent->HasDirAuto()) {
|
||||
bool resetDirection = false;
|
||||
nsINode* directionWasSetByTextNode =
|
||||
static_cast<nsINode*>(parent->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
nsTextNode* directionWasSetByTextNode =
|
||||
static_cast<nsTextNode*>(parent->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
|
||||
if (!parent->HasDirAutoSet()) {
|
||||
// Fast path if parent's direction is not yet set by any descendant
|
||||
@@ -840,7 +839,7 @@ TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir,
|
||||
}
|
||||
|
||||
void
|
||||
TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir,
|
||||
TextNodeChangedDirection(nsTextNode* aTextNode, Directionality aOldDir,
|
||||
bool aNotify)
|
||||
{
|
||||
Directionality newDir = GetDirectionFromText(aTextNode->GetText());
|
||||
@@ -870,7 +869,7 @@ TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir,
|
||||
}
|
||||
|
||||
void
|
||||
SetDirectionFromNewTextNode(nsIContent* aTextNode)
|
||||
SetDirectionFromNewTextNode(nsTextNode* aTextNode)
|
||||
{
|
||||
if (!NodeAffectsDirAutoAncestor(aTextNode)) {
|
||||
return;
|
||||
@@ -957,8 +956,8 @@ OnSetDirAttr(Element* aElement, const nsAttrValue* aNewValue,
|
||||
WalkDescendantsSetDirAuto(aElement, aNotify);
|
||||
} else {
|
||||
if (aElement->HasDirAutoSet()) {
|
||||
nsINode* setByNode =
|
||||
static_cast<nsINode*>(aElement->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
nsTextNode* setByNode =
|
||||
static_cast<nsTextNode*>(aElement->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, aElement);
|
||||
}
|
||||
SetDirectionalityOnDescendants(aElement,
|
||||
@@ -1009,8 +1008,8 @@ SetDirOnBind(mozilla::dom::Element* aElement, nsIContent* aParent)
|
||||
void ResetDir(mozilla::dom::Element* aElement)
|
||||
{
|
||||
if (aElement->HasDirAutoSet()) {
|
||||
nsINode* setByNode =
|
||||
static_cast<nsINode*>(aElement->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
nsTextNode* setByNode =
|
||||
static_cast<nsTextNode*>(aElement->GetProperty(nsGkAtoms::dirAutoSetBy));
|
||||
nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, aElement);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,14 +89,14 @@ bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir,
|
||||
* After the contents of a text node have changed, change the directionality
|
||||
* of any elements whose directionality is determined by that node
|
||||
*/
|
||||
void TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir,
|
||||
void TextNodeChangedDirection(nsTextNode* aTextNode, Directionality aOldDir,
|
||||
bool aNotify);
|
||||
|
||||
/**
|
||||
* When a text node is appended to an element, find any ancestors with dir=auto
|
||||
* whose directionality will be determined by the text node
|
||||
*/
|
||||
void SetDirectionFromNewTextNode(nsIContent* aTextNode);
|
||||
void SetDirectionFromNewTextNode(nsTextNode* aTextNode);
|
||||
|
||||
/**
|
||||
* When a text node is removed from a document, find any ancestors whose
|
||||
|
||||
+71
-4
@@ -39,11 +39,14 @@
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
using namespace workers;
|
||||
|
||||
// XXXkhuey the input stream that we pass out of a File
|
||||
// can outlive the actual File object. Thus, we must
|
||||
// ensure that the buffer underlying the stream we get
|
||||
@@ -619,7 +622,7 @@ File::Constructor(const GlobalObject& aGlobal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
aRv.ThrowTypeError<MSG_MISSING_ARGUMENTS>(NS_LITERAL_STRING("File"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -703,8 +706,7 @@ BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv) const
|
||||
return;
|
||||
}
|
||||
|
||||
workers::WorkerPrivate* workerPrivate =
|
||||
workers::GetCurrentThreadWorkerPrivate();
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
if (workerPrivate->UsesSystemPrincipal()) {
|
||||
@@ -862,17 +864,82 @@ BlobImplFile::GetSize(ErrorResult& aRv)
|
||||
return mLength;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class GetTypeRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
GetTypeRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
nsIEventTarget* aSyncLoopTarget,
|
||||
BlobImpl* aBlobImpl)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
, mSyncLoopTarget(aSyncLoopTarget)
|
||||
, mBlobImpl(aBlobImpl)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aSyncLoopTarget);
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoString type;
|
||||
mBlobImpl->GetType(type);
|
||||
|
||||
RefPtr<MainThreadStopSyncLoopRunnable> runnable =
|
||||
new MainThreadStopSyncLoopRunnable(mWorkerPrivate,
|
||||
mSyncLoopTarget.forget(), true);
|
||||
NS_WARN_IF(!runnable->Dispatch());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~GetTypeRunnable()
|
||||
{}
|
||||
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
||||
RefPtr<BlobImpl> mBlobImpl;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
BlobImplFile::GetType(nsAString& aType)
|
||||
{
|
||||
aType.Truncate();
|
||||
|
||||
if (mContentType.IsVoid()) {
|
||||
NS_ASSERTION(mWholeFile,
|
||||
"Should only use lazy ContentType when using the whole file");
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
if (!workerPrivate) {
|
||||
// I have no idea in which thread this method is called. We cannot
|
||||
// return any valid value.
|
||||
return;
|
||||
}
|
||||
|
||||
AutoSyncLoopHolder syncLoop(workerPrivate);
|
||||
|
||||
RefPtr<GetTypeRunnable> runnable =
|
||||
new GetTypeRunnable(workerPrivate, syncLoop.EventTarget(), this);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
NS_WARN_IF(!syncLoop.Run());
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMIMEService> mimeService =
|
||||
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aType.Truncate();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+6
-11
@@ -183,6 +183,12 @@ public:
|
||||
const nsAString& aName, const nsAString& aContentType,
|
||||
int64_t aLastModifiedDate);
|
||||
|
||||
// This method creates a BlobFileImpl for the new File object. This is
|
||||
// thread-safe, cross-process, cross-thread as any other BlobImpl, but, when
|
||||
// GetType() is called, it must dispatch a runnable to the main-thread in
|
||||
// order to use nsIMIMEService.
|
||||
// Would be nice if we try to avoid to use this method outside the
|
||||
// main-thread to avoid extra runnables.
|
||||
static already_AddRefed<File>
|
||||
CreateFromFile(nsISupports* aParent, nsIFile* aFile, bool aTemporary = false);
|
||||
|
||||
@@ -689,17 +695,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Create as a file to be later initialized
|
||||
BlobImplFile()
|
||||
: BlobImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
, mWholeFile(true)
|
||||
, mIsTemporary(false)
|
||||
{
|
||||
// Lazily get the content type and size
|
||||
mContentType.SetIsVoid(true);
|
||||
mName.SetIsVoid(true);
|
||||
}
|
||||
|
||||
// Overrides
|
||||
virtual uint64_t GetSize(ErrorResult& aRv) override;
|
||||
virtual void GetType(nsAString& aType) override;
|
||||
|
||||
@@ -24,6 +24,10 @@ Cu.importGlobalProperties(["indexedDB"]);
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Services',
|
||||
'resource://gre/modules/Services.jsm');
|
||||
|
||||
function getErrorName(err) {
|
||||
return err && err.name || "UnknownError";
|
||||
}
|
||||
|
||||
this.IndexedDBHelper = function IndexedDBHelper() {
|
||||
}
|
||||
|
||||
@@ -62,7 +66,15 @@ IndexedDBHelper.prototype = {
|
||||
};
|
||||
|
||||
if (DEBUG) debug("Try to open database:" + self.dbName + " " + self.dbVersion);
|
||||
let req = indexedDB.open(this.dbName, this.dbVersion);
|
||||
let req;
|
||||
try {
|
||||
req = indexedDB.open(this.dbName, this.dbVersion);
|
||||
} catch (e) {
|
||||
if (DEBUG) debug("Error opening database: " + self.dbName);
|
||||
Services.tm.currentThread.dispatch(() => invokeCallbacks(getErrorName(e)),
|
||||
Ci.nsIThread.DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
req.onsuccess = function (event) {
|
||||
if (DEBUG) debug("Opened database:" + self.dbName + " " + self.dbVersion);
|
||||
self._db = event.target.result;
|
||||
@@ -83,7 +95,7 @@ IndexedDBHelper.prototype = {
|
||||
};
|
||||
req.onerror = function (aEvent) {
|
||||
if (DEBUG) debug("Failed to open database: " + self.dbName);
|
||||
invokeCallbacks(aEvent.target.error.name);
|
||||
invokeCallbacks(getErrorName(aEvent.target.error));
|
||||
};
|
||||
req.onblocked = function (aEvent) {
|
||||
if (DEBUG) debug("Opening database request is blocked.");
|
||||
@@ -135,8 +147,15 @@ IndexedDBHelper.prototype = {
|
||||
newTxn: function newTxn(txn_type, store_name, callback, successCb, failureCb) {
|
||||
this.ensureDB(function () {
|
||||
if (DEBUG) debug("Starting new transaction" + txn_type);
|
||||
let txn = this._db.transaction(Array.isArray(store_name) ? store_name : this.dbStoreNames, txn_type);
|
||||
if (DEBUG) debug("Retrieving object store", this.dbName);
|
||||
let txn;
|
||||
try {
|
||||
txn = this._db.transaction(Array.isArray(store_name) ? store_name : this.dbStoreNames, txn_type);
|
||||
} catch (e) {
|
||||
if (DEBUG) debug("Error starting transaction: " + this.dbName);
|
||||
failureCb(getErrorName(e));
|
||||
return;
|
||||
}
|
||||
if (DEBUG) debug("Retrieving object store: " + this.dbName);
|
||||
let stores;
|
||||
if (Array.isArray(store_name)) {
|
||||
stores = [];
|
||||
@@ -161,11 +180,7 @@ IndexedDBHelper.prototype = {
|
||||
* if txn was aborted by calling txn.abort()
|
||||
*/
|
||||
if (failureCb) {
|
||||
if (event.target.error) {
|
||||
failureCb(event.target.error.name);
|
||||
} else {
|
||||
failureCb("UnknownError");
|
||||
}
|
||||
failureCb(getErrorName(event.target.error));
|
||||
}
|
||||
};
|
||||
callback(txn, stores);
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#include <algorithm>
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class MultipartBlobImpl final : public BlobImplBase
|
||||
{
|
||||
@@ -104,11 +104,6 @@ public:
|
||||
mName = aName;
|
||||
}
|
||||
|
||||
void SetFromNsIFile(bool aValue)
|
||||
{
|
||||
mIsFromNsIFile = aValue;
|
||||
}
|
||||
|
||||
virtual bool MayBeClonedToOtherThreads() const override;
|
||||
|
||||
protected:
|
||||
@@ -137,4 +132,7 @@ protected:
|
||||
bool mIsFromNsIFile;
|
||||
};
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_MultipartBlobImpl_h
|
||||
|
||||
@@ -135,14 +135,14 @@ PerformanceObserver::QueueEntry(PerformanceEntry* aEntry)
|
||||
mQueuedEntries.AppendElement(aEntry);
|
||||
}
|
||||
|
||||
static nsString sValidTypeNames[7] = {
|
||||
NS_LITERAL_STRING("composite"),
|
||||
NS_LITERAL_STRING("mark"),
|
||||
NS_LITERAL_STRING("measure"),
|
||||
NS_LITERAL_STRING("navigation"),
|
||||
NS_LITERAL_STRING("render"),
|
||||
NS_LITERAL_STRING("resource"),
|
||||
NS_LITERAL_STRING("server")
|
||||
static const char16_t* sValidTypeNames[7] = {
|
||||
MOZ_UTF16("composite"),
|
||||
MOZ_UTF16("mark"),
|
||||
MOZ_UTF16("measure"),
|
||||
MOZ_UTF16("navigation"),
|
||||
MOZ_UTF16("render"),
|
||||
MOZ_UTF16("resource"),
|
||||
MOZ_UTF16("server")
|
||||
};
|
||||
|
||||
void
|
||||
@@ -156,7 +156,8 @@ PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
|
||||
|
||||
nsTArray<nsString> validEntryTypes;
|
||||
|
||||
for (const nsString& validTypeName : sValidTypeNames) {
|
||||
for (const char16_t* name : sValidTypeNames) {
|
||||
nsDependentString validTypeName(name);
|
||||
if (aOptions.mEntryTypes.Contains<nsString>(validTypeName) &&
|
||||
!validEntryTypes.Contains<nsString>(validTypeName)) {
|
||||
validEntryTypes.AppendElement(validTypeName);
|
||||
|
||||
@@ -43,6 +43,66 @@ ParseInteger(const nsAString& aString, int32_t& aInt)
|
||||
nsContentUtils::eParseHTMLInteger_NonStandard ));
|
||||
}
|
||||
|
||||
static bool
|
||||
ParseFloat(const nsAString& aString, double& aDouble)
|
||||
{
|
||||
// Check if it is a valid floating-point number first since the result of
|
||||
// nsString.ToDouble() is more lenient than the spec,
|
||||
// https://html.spec.whatwg.org/#valid-floating-point-number
|
||||
nsAString::const_iterator iter, end;
|
||||
aString.BeginReading(iter);
|
||||
aString.EndReading(end);
|
||||
|
||||
if (iter == end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*iter == char16_t('-') && ++iter == end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nsCRT::IsAsciiDigit(*iter)) {
|
||||
for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter);
|
||||
} else if (*iter == char16_t('.')) {
|
||||
// Do nothing, jumps to fraction part
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fraction
|
||||
if (*iter == char16_t('.')) {
|
||||
++iter;
|
||||
if (iter == end || !nsCRT::IsAsciiDigit(*iter)) {
|
||||
// U+002E FULL STOP character (.) must be followed by one or more ASCII digits
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter);
|
||||
}
|
||||
|
||||
if (iter != end && (*iter == char16_t('e') || *iter == char16_t('E'))) {
|
||||
++iter;
|
||||
if (*iter == char16_t('-') || *iter == char16_t('+')) {
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (iter == end || !nsCRT::IsAsciiDigit(*iter)) {
|
||||
// Should have one or more ASCII digits
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter);
|
||||
}
|
||||
|
||||
if (iter != end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
aDouble = PromiseFlatString(aString).ToDouble(&rv);
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
ResponsiveImageSelector::ResponsiveImageSelector(nsIContent *aContent)
|
||||
: mOwnerNode(aContent),
|
||||
mSelectedCandidateIndex(-1)
|
||||
@@ -72,14 +132,6 @@ ResponsiveImageSelector::SetCandidatesFromSourceSet(const nsAString & aSrcSet)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preserve the default source if we have one, it has a separate setter.
|
||||
uint32_t prevNumCandidates = mCandidates.Length();
|
||||
nsString defaultURLString;
|
||||
if (prevNumCandidates && (mCandidates[prevNumCandidates - 1].Type() ==
|
||||
ResponsiveImageCandidate::eCandidateType_Default)) {
|
||||
defaultURLString = mCandidates[prevNumCandidates - 1].URLString();
|
||||
}
|
||||
|
||||
mCandidates.Clear();
|
||||
|
||||
nsAString::const_iterator iter, end;
|
||||
@@ -127,9 +179,7 @@ ResponsiveImageSelector::SetCandidatesFromSourceSet(const nsAString & aSrcSet)
|
||||
bool parsedCandidates = mCandidates.Length() > 0;
|
||||
|
||||
// Re-add default to end of list
|
||||
if (!defaultURLString.IsEmpty()) {
|
||||
AppendDefaultCandidate(defaultURLString);
|
||||
}
|
||||
MaybeAppendDefaultCandidate();
|
||||
|
||||
return parsedCandidates;
|
||||
}
|
||||
@@ -173,10 +223,10 @@ ResponsiveImageSelector::SetDefaultSource(const nsAString& aURLString)
|
||||
mCandidates.RemoveElementAt(candidates - 1);
|
||||
}
|
||||
|
||||
// Add new default if set
|
||||
if (!aURLString.IsEmpty()) {
|
||||
AppendDefaultCandidate(aURLString);
|
||||
}
|
||||
mDefaultSourceURL = aURLString;
|
||||
|
||||
// Add new default to end of list
|
||||
MaybeAppendDefaultCandidate();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -209,9 +259,8 @@ ResponsiveImageSelector::AppendCandidateIfUnique(const ResponsiveImageCandidate
|
||||
int numCandidates = mCandidates.Length();
|
||||
|
||||
// With the exception of Default, which should not be added until we are done
|
||||
// building the list, the spec forbids mixing width and explicit density
|
||||
// selectors in the same set.
|
||||
if (numCandidates && mCandidates[0].Type() != aCandidate.Type()) {
|
||||
// building the list.
|
||||
if (aCandidate.Type() == ResponsiveImageCandidate::eCandidateType_Default) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -226,13 +275,31 @@ ResponsiveImageSelector::AppendCandidateIfUnique(const ResponsiveImageCandidate
|
||||
}
|
||||
|
||||
void
|
||||
ResponsiveImageSelector::AppendDefaultCandidate(const nsAString& aURLString)
|
||||
ResponsiveImageSelector::MaybeAppendDefaultCandidate()
|
||||
{
|
||||
NS_ENSURE_TRUE(!aURLString.IsEmpty(), /* void */);
|
||||
if (mDefaultSourceURL.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int numCandidates = mCandidates.Length();
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#update-the-source-set
|
||||
// step 4.1.3:
|
||||
// If child has a src attribute whose value is not the empty string and source
|
||||
// set does not contain an image source with a density descriptor value of 1,
|
||||
// and no image source with a width descriptor, append child's src attribute
|
||||
// value to source set.
|
||||
for (int i = 0; i < numCandidates; i++) {
|
||||
if (mCandidates[i].IsComputedFromWidth()) {
|
||||
return;
|
||||
} else if (mCandidates[i].Density(this) == 1.0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ResponsiveImageCandidate defaultCandidate;
|
||||
defaultCandidate.SetParameterDefault();
|
||||
defaultCandidate.SetURLSpec(aURLString);
|
||||
defaultCandidate.SetURLSpec(mDefaultSourceURL);
|
||||
// We don't use MaybeAppend since we want to keep this even if it can never
|
||||
// match, as it may if the source set changes.
|
||||
mCandidates.AppendElement(defaultCandidate);
|
||||
@@ -303,22 +370,15 @@ ResponsiveImageSelector::SelectImage(bool aReselect)
|
||||
// the greatest density available
|
||||
|
||||
// If the list contains computed width candidates, compute the current
|
||||
// effective image width. Note that we currently disallow both computed and
|
||||
// static density candidates in the same selector, so checking the first
|
||||
// candidate is sufficient.
|
||||
int32_t computedWidth = -1;
|
||||
if (numCandidates && mCandidates[0].IsComputedFromWidth()) {
|
||||
DebugOnly<bool> computeResult = \
|
||||
ComputeFinalWidthForCurrentViewport(&computedWidth);
|
||||
MOZ_ASSERT(computeResult,
|
||||
"Computed candidates not allowed without sizes data");
|
||||
|
||||
// If we have a default candidate in the list, don't consider it when using
|
||||
// computed widths. (It has a static 1.0 density that is inapplicable to a
|
||||
// sized-image)
|
||||
if (numCandidates > 1 && mCandidates[numCandidates - 1].Type() ==
|
||||
ResponsiveImageCandidate::eCandidateType_Default) {
|
||||
numCandidates--;
|
||||
// effective image width.
|
||||
double computedWidth = -1;
|
||||
for (int i = 0; i < numCandidates; i++) {
|
||||
if (mCandidates[i].IsComputedFromWidth()) {
|
||||
DebugOnly<bool> computeResult = \
|
||||
ComputeFinalWidthForCurrentViewport(&computedWidth);
|
||||
MOZ_ASSERT(computeResult,
|
||||
"Computed candidates not allowed without sizes data");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,7 +423,7 @@ ResponsiveImageSelector::GetSelectedCandidateIndex()
|
||||
}
|
||||
|
||||
bool
|
||||
ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(int32_t *aWidth)
|
||||
ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(double *aWidth)
|
||||
{
|
||||
unsigned int numSizes = mSizeQueries.Length();
|
||||
nsIDocument* doc = Document();
|
||||
@@ -371,7 +431,6 @@ ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(int32_t *aWidth)
|
||||
nsPresContext *pctx = presShell ? presShell->GetPresContext() : nullptr;
|
||||
|
||||
if (!pctx) {
|
||||
MOZ_ASSERT(false, "Unable to find presContext for this content");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -396,8 +455,7 @@ ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(int32_t *aWidth)
|
||||
mSizeValues[i]);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(effectiveWidth >= 0);
|
||||
*aWidth = nsPresContext::AppUnitsToIntCSSPixels(std::max(effectiveWidth, 0));
|
||||
*aWidth = nsPresContext::AppUnitsToDoubleCSSPixels(std::max(effectiveWidth, 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -533,9 +591,8 @@ ResponsiveImageDescriptors::AddDescriptor(const nsAString& aDescriptor)
|
||||
} else if (*descType == char16_t('x')) {
|
||||
// If the value is not a valid floating point number, it doesn't match this
|
||||
// descriptor, fall through.
|
||||
nsresult rv;
|
||||
double possibleDensity = PromiseFlatString(valueStr).ToDouble(&rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
double possibleDensity = 0.0;
|
||||
if (ParseFloat(valueStr, possibleDensity)) {
|
||||
if (possibleDensity >= 0.0 &&
|
||||
mWidth.isNothing() &&
|
||||
mDensity.isNothing() &&
|
||||
@@ -674,7 +731,7 @@ double
|
||||
ResponsiveImageCandidate::Density(ResponsiveImageSelector *aSelector) const
|
||||
{
|
||||
if (mType == eCandidateType_ComputedFromWidth) {
|
||||
int32_t width;
|
||||
double width;
|
||||
if (!aSelector->ComputeFinalWidthForCurrentViewport(&width)) {
|
||||
return 1.0;
|
||||
}
|
||||
@@ -688,7 +745,7 @@ ResponsiveImageCandidate::Density(ResponsiveImageSelector *aSelector) const
|
||||
}
|
||||
|
||||
double
|
||||
ResponsiveImageCandidate::Density(int32_t aMatchingWidth) const
|
||||
ResponsiveImageCandidate::Density(double aMatchingWidth) const
|
||||
{
|
||||
if (mType == eCandidateType_Invalid) {
|
||||
MOZ_ASSERT(false, "Getting density for uninitialized candidate");
|
||||
@@ -706,7 +763,7 @@ ResponsiveImageCandidate::Density(int32_t aMatchingWidth) const
|
||||
MOZ_ASSERT(false, "Don't expect to have a negative matching width at this point");
|
||||
return 1.0;
|
||||
}
|
||||
double density = double(mValue.mWidth) / double(aMatchingWidth);
|
||||
double density = double(mValue.mWidth) / aMatchingWidth;
|
||||
MOZ_ASSERT(density > 0.0);
|
||||
return density;
|
||||
}
|
||||
|
||||
@@ -86,9 +86,9 @@ private:
|
||||
// candidate
|
||||
void AppendCandidateIfUnique(const ResponsiveImageCandidate &aCandidate);
|
||||
|
||||
// Append a default candidate with this URL. Does not check if the array
|
||||
// already contains one, use SetDefaultSource instead.
|
||||
void AppendDefaultCandidate(const nsAString& aURLString);
|
||||
// Append a default candidate with this URL if necessary. Does not check if
|
||||
// the array already contains one, use SetDefaultSource instead.
|
||||
void MaybeAppendDefaultCandidate();
|
||||
|
||||
// Get index of selected candidate, triggering selection if necessary.
|
||||
int GetSelectedCandidateIndex();
|
||||
@@ -102,9 +102,11 @@ private:
|
||||
//
|
||||
// aContext is the presContext to use for current viewport sizing, null will
|
||||
// use the associated content's context.
|
||||
bool ComputeFinalWidthForCurrentViewport(int32_t *aWidth);
|
||||
bool ComputeFinalWidthForCurrentViewport(double* aWidth);
|
||||
|
||||
nsCOMPtr<nsINode> mOwnerNode;
|
||||
// The cached URL for default candidate.
|
||||
nsString mDefaultSourceURL;
|
||||
// If this array contains an eCandidateType_Default, it should be the last
|
||||
// element, such that the Setters can preserve/replace it respectively.
|
||||
nsTArray<ResponsiveImageCandidate> mCandidates;
|
||||
@@ -150,7 +152,7 @@ public:
|
||||
double Density(ResponsiveImageSelector *aSelector) const;
|
||||
// If the width is already known. Useful when iterating over candidates to
|
||||
// avoid having each call re-compute the width.
|
||||
double Density(int32_t aMatchingWidth) const;
|
||||
double Density(double aMatchingWidth) const;
|
||||
|
||||
// If this selector is computed from the selector's matching width.
|
||||
bool IsComputedFromWidth() const;
|
||||
|
||||
@@ -186,22 +186,24 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
|
||||
nsGlobalWindow* outer = win->GetOuterWindowInternal();
|
||||
if (outer) {
|
||||
nsDOMWindowList* childWindows = outer->GetWindowList();
|
||||
uint32_t length = childWindows->GetLength();
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item =
|
||||
childWindows->GetDocShellTreeItemAt(i);
|
||||
// This is a bit silly, since we could presumably just do
|
||||
// item->GetWindow(). But it's not obvious whether this does the same
|
||||
// thing as GetChildWindow() with the item's name (due to the complexity
|
||||
// of FindChildWithName). Since GetChildWindow is what we use in
|
||||
// getOwnPropDescriptor, let's try to be consistent.
|
||||
nsString name;
|
||||
item->GetName(name);
|
||||
if (!names.Contains(name)) {
|
||||
// Make sure we really would expose it from getOwnPropDescriptor.
|
||||
nsCOMPtr<nsPIDOMWindow> childWin = win->GetChildWindow(name);
|
||||
if (childWin && ShouldExposeChildWindow(name, childWin)) {
|
||||
names.AppendElement(name);
|
||||
if (childWindows) {
|
||||
uint32_t length = childWindows->GetLength();
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item =
|
||||
childWindows->GetDocShellTreeItemAt(i);
|
||||
// This is a bit silly, since we could presumably just do
|
||||
// item->GetWindow(). But it's not obvious whether this does the same
|
||||
// thing as GetChildWindow() with the item's name (due to the complexity
|
||||
// of FindChildWithName). Since GetChildWindow is what we use in
|
||||
// getOwnPropDescriptor, let's try to be consistent.
|
||||
nsString name;
|
||||
item->GetName(name);
|
||||
if (!names.Contains(name)) {
|
||||
// Make sure we really would expose it from getOwnPropDescriptor.
|
||||
nsCOMPtr<nsPIDOMWindow> childWin = win->GetChildWindow(name);
|
||||
if (childWin && ShouldExposeChildWindow(name, childWin)) {
|
||||
names.AppendElement(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
@@ -42,13 +43,9 @@ ContentAreaDropListener.prototype =
|
||||
// For shortcuts, we want to check for the file type last, so that the
|
||||
// url pointed to in one of the url types is found first before the file
|
||||
// type, which points to the actual file.
|
||||
let file = dt.mozGetDataAt("application/x-moz-file", 0);
|
||||
if (file instanceof Ci.nsIFile) {
|
||||
let ioService = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
let fileHandler = ioService.getProtocolHandler("file")
|
||||
.QueryInterface(Ci.nsIFileProtocolHandler);
|
||||
return [fileHandler.getURLSpecFromFile(file), file.leafName];
|
||||
let files = dt.files;
|
||||
if (files && files.length) {
|
||||
return [OS.Path.toFileURI(files[0].mozFullPath), files[0].name];
|
||||
}
|
||||
|
||||
return [ ];
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.styleSheetSets.expando = null;
|
||||
var otherDoc = document.implementation.createDocument("", "", null);
|
||||
var otherSpan = otherDoc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
|
||||
var img = document.createElementNS("http://www.w3.org/1999/xhtml", "img");
|
||||
img.srcset = "data:,a 1w, data:,b 1w";
|
||||
img.sizes = "1px";
|
||||
otherSpan.appendChild(img);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
||||
@@ -198,6 +198,7 @@ pref(dom.webcomponents.enabled,true) load 1027461-1.html
|
||||
pref(dom.webcomponents.enabled,true) load 1029710.html
|
||||
load 1154598.xhtml
|
||||
load 1157995.html
|
||||
load 1158412.html
|
||||
load 1181619.html
|
||||
load structured_clone_container_throws.html
|
||||
HTTP(..) load xhr_abortinprogress.html
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "ScriptSettings.h"
|
||||
|
||||
using mozilla::Unused; // <snicker>
|
||||
using namespace mozilla::dom;
|
||||
@@ -708,7 +709,10 @@ nsContentPermissionRequestProxy::Allow(JS::HandleValue aChoices)
|
||||
for (uint32_t i = 0; i < mPermissionRequests.Length(); ++i) {
|
||||
nsCString type = mPermissionRequests[i].type();
|
||||
|
||||
mozilla::AutoSafeJSContext cx;
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JSObject*> obj(cx, &aChoices.toObject());
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
@@ -716,10 +720,12 @@ nsContentPermissionRequestProxy::Allow(JS::HandleValue aChoices)
|
||||
|
||||
if (!JS_GetProperty(cx, obj, type.BeginReading(), &val) ||
|
||||
!val.isString()) {
|
||||
// no setting for the permission type, skip it
|
||||
// no setting for the permission type, clear exception and skip it
|
||||
jsapi.ClearException();
|
||||
} else {
|
||||
nsAutoJSString choice;
|
||||
if (!choice.init(cx, val)) {
|
||||
jsapi.ClearException();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
choices.AppendElement(PermissionChoice(type, choice));
|
||||
|
||||
+60
-37
@@ -2721,7 +2721,7 @@ nsContentUtils::SubjectPrincipal()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
JSContext* cx = GetCurrentJSContext();
|
||||
if (!cx) {
|
||||
return GetSystemPrincipal();
|
||||
MOZ_CRASH("Accessing the Subject Principal without an AutoJSAPI on the stack is forbidden");
|
||||
}
|
||||
|
||||
JSCompartment *compartment = js::GetContextCompartment(cx);
|
||||
@@ -5797,26 +5797,6 @@ nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (uri && uri != aURI) {
|
||||
return GetUTFOrigin(uri, aOrigin);
|
||||
}
|
||||
} else {
|
||||
// We are probably dealing with an unknown blob URL.
|
||||
bool isBlobURL = false;
|
||||
nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (isBlobURL) {
|
||||
nsAutoCString path;
|
||||
rv = aURI->GetPath(path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), path);
|
||||
if (NS_FAILED(rv)) {
|
||||
aOrigin.AssignLiteral("null");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return GetUTFOrigin(uri, aOrigin);
|
||||
}
|
||||
}
|
||||
@@ -7386,14 +7366,14 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
nsAutoString dataAsString;
|
||||
text->GetData(dataAsString);
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = nsString(dataAsString);
|
||||
item->flavor() = flavorStr;
|
||||
item->data() = dataAsString;
|
||||
} else if (ctext) {
|
||||
nsAutoCString dataAsString;
|
||||
ctext->GetData(dataAsString);
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = nsCString(dataAsString);
|
||||
item->flavor() = flavorStr;
|
||||
item->data() = dataAsString;
|
||||
} else {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> sip =
|
||||
do_QueryInterface(data);
|
||||
@@ -7405,7 +7385,7 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
nsCOMPtr<nsIInputStream> stream(do_QueryInterface(data));
|
||||
if (stream) {
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->flavor() = flavorStr;
|
||||
|
||||
nsCString imageData;
|
||||
NS_ConsumeStream(stream, UINT32_MAX, imageData);
|
||||
@@ -7428,8 +7408,10 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
nsContentUtils::GetSurfaceData(dataSurface, &length, &stride);
|
||||
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = nsCString(surfaceData.get(), length);
|
||||
item->flavor() = flavorStr;
|
||||
// Turn item->data() into an nsCString prior to accessing it.
|
||||
item->data() = EmptyCString();
|
||||
item->data().get_nsCString().Adopt(surfaceData.release(), length);
|
||||
|
||||
IPCDataTransferImage& imageDetails = item->imageDetails();
|
||||
mozilla::gfx::IntSize size = dataSurface->GetSize();
|
||||
@@ -7478,17 +7460,32 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
blobImpl = do_QueryInterface(data);
|
||||
}
|
||||
if (blobImpl) {
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
IPCDataTransferData data;
|
||||
|
||||
// If we failed to create the blob actor, then this blob probably
|
||||
// can't get the file size for the underlying file, ignore it for
|
||||
// now. TODO pass this through anyway.
|
||||
if (aChild) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobChild::GetOrCreate(aChild,
|
||||
static_cast<BlobImpl*>(blobImpl.get()));
|
||||
auto* child = mozilla::dom::BlobChild::GetOrCreate(aChild,
|
||||
static_cast<BlobImpl*>(blobImpl.get()));
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data = child;
|
||||
} else if (aParent) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobParent::GetOrCreate(aParent,
|
||||
static_cast<BlobImpl*>(blobImpl.get()));
|
||||
auto* parent = mozilla::dom::BlobParent::GetOrCreate(aParent,
|
||||
static_cast<BlobImpl*>(blobImpl.get()));
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data = parent;
|
||||
}
|
||||
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = flavorStr;
|
||||
item->data() = data;
|
||||
} else {
|
||||
// This is a hack to support kFilePromiseMime.
|
||||
// On Windows there just needs to be an entry for it,
|
||||
@@ -7496,8 +7493,14 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
// nsContentAreaDragDropDataProvider as nsIFlavorDataProvider.
|
||||
if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->flavor() = flavorStr;
|
||||
item->data() = NS_ConvertUTF8toUTF16(flavorStr);
|
||||
} else if (!data) {
|
||||
// Empty element, transfer only the flavor
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = flavorStr;
|
||||
item->data() = EmptyCString();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8147,6 +8150,26 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
||||
// About URIs are allowed to access storage, even if they don't have chrome
|
||||
// privileges. If this is not desired, than the consumer will have to
|
||||
// implement their own restriction functionality.
|
||||
//
|
||||
// This is due to backwards-compatibility and the state of storage access before
|
||||
// the introducton of nsContentUtils::InternalStorageAllowedForPrincipal:
|
||||
//
|
||||
// BEFORE:
|
||||
// localStorage, caches: allowed in 3rd-party iframes always
|
||||
// IndexedDB: allowed in 3rd-party iframes only if 3rd party URI is an about:
|
||||
// URI within a specific whitelist
|
||||
//
|
||||
// AFTER:
|
||||
// localStorage, caches: allowed in 3rd-party iframes by default. Preference
|
||||
// can be set to disable in 3rd-party, which will not disallow in about: URIs.
|
||||
// IndexedDB: allowed in 3rd-party iframes by default. Preference can be set to
|
||||
// disable in 3rd-party, which will disallow in about: URIs, unless they are
|
||||
// within a specific whitelist.
|
||||
//
|
||||
// This means that behavior for storage with internal about: URIs should not be
|
||||
// affected, which is desireable due to the lack of automated testing for about:
|
||||
// URIs with these preferences set, and the importance of the correct functioning
|
||||
// of these URIs even with custom preferences.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
if (NS_SUCCEEDED(rv) && uri) {
|
||||
|
||||
@@ -35,10 +35,10 @@ public:
|
||||
int32_t mNamespaceID;
|
||||
|
||||
/**
|
||||
* The atom for attribute, weak ref. is fine as we only use it for the
|
||||
* hashcode, we never dereference it.
|
||||
* The atom for attribute, stored as void*, to make sure that we only use it
|
||||
* for the hashcode, and we can never dereference it.
|
||||
*/
|
||||
nsIAtom* mLocalName;
|
||||
void* mLocalName;
|
||||
|
||||
nsAttrKey(int32_t aNs, nsIAtom* aName)
|
||||
: mNamespaceID(aNs), mLocalName(aName) {}
|
||||
|
||||
@@ -121,15 +121,6 @@ using namespace mozilla::dom;
|
||||
// NOTE: DEFAULT_SCRIPTABLE_FLAGS and DOM_DEFAULT_SCRIPTABLE_FLAGS
|
||||
// are defined in nsIDOMClassInfo.h.
|
||||
|
||||
#define ARRAY_SCRIPTABLE_FLAGS \
|
||||
(DOM_DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_GETPROPERTY | \
|
||||
nsIXPCScriptable::WANT_ENUMERATE)
|
||||
|
||||
#define EVENTTARGET_SCRIPTABLE_FLAGS \
|
||||
(DOM_DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY)
|
||||
|
||||
#define DOMCLASSINFO_STANDARD_FLAGS \
|
||||
(nsIClassInfo::MAIN_THREAD_ONLY | \
|
||||
nsIClassInfo::DOM_OBJECT | \
|
||||
|
||||
@@ -335,6 +335,7 @@ public:
|
||||
nsMutationReceiverBase* aParent)
|
||||
{
|
||||
nsMutationReceiver* r = new nsMutationReceiver(aRegisterTarget, aParent);
|
||||
aParent->AddClone(r);
|
||||
r->AddObserver();
|
||||
return r;
|
||||
}
|
||||
@@ -397,7 +398,6 @@ protected:
|
||||
{
|
||||
NS_ASSERTION(!static_cast<nsMutationReceiver*>(aParent)->GetParent(),
|
||||
"Shouldn't create deep observer hierarchies!");
|
||||
aParent->AddClone(this);
|
||||
}
|
||||
|
||||
virtual void AddMutationObserver() override
|
||||
@@ -421,6 +421,7 @@ public:
|
||||
nsMutationReceiverBase* aParent)
|
||||
{
|
||||
nsAnimationReceiver* r = new nsAnimationReceiver(aRegisterTarget, aParent);
|
||||
aParent->AddClone(r);
|
||||
r->AddObserver();
|
||||
return r;
|
||||
}
|
||||
|
||||
+34
-16
@@ -29,6 +29,7 @@
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsContentList.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
@@ -1676,11 +1677,6 @@ nsDocument::~nsDocument()
|
||||
mImageTracker.Clear();
|
||||
|
||||
mPlugins.Clear();
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->RemoveObserver(this, "service-worker-get-client");
|
||||
}
|
||||
}
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsDocument)
|
||||
@@ -2082,11 +2078,6 @@ nsDocument::Init()
|
||||
|
||||
mozilla::HoldJSObjects(this);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->AddObserver(this, "service-worker-get-client", /* ownsWeak */ true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -4684,6 +4675,28 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||
}
|
||||
swm->MaybeStopControlling(this);
|
||||
}
|
||||
|
||||
// Remove ourself from the list of clients. We only register
|
||||
// content principal documents in this list.
|
||||
if (!nsContentUtils::IsSystemPrincipal(GetPrincipal()) &&
|
||||
!GetPrincipal()->GetIsNullPrincipal()) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->RemoveObserver(this, "service-worker-get-client");
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!mScriptGlobalObject && aScriptGlobalObject &&
|
||||
mDocumentContainer && GetChannel() &&
|
||||
!nsContentUtils::IsSystemPrincipal(GetPrincipal()) &&
|
||||
!GetPrincipal()->GetIsNullPrincipal()) {
|
||||
// This document is being activated. Register it in the list of
|
||||
// clients. We only do this for content principal documents
|
||||
// since we can never observe system or null principals.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->AddObserver(this, "service-worker-get-client", /* ownsWeak */ false);
|
||||
}
|
||||
}
|
||||
|
||||
// BlockOnload() might be called before mScriptGlobalObject is set.
|
||||
@@ -10810,10 +10823,8 @@ nsIDocument::CaretPositionFromPoint(float aX, float aY)
|
||||
nsIContent* nonanon = node->FindFirstNonChromeOnlyAccessContent();
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(nonanon);
|
||||
nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(nonanon);
|
||||
bool isText;
|
||||
if (textArea || (input &&
|
||||
NS_SUCCEEDED(input->MozIsTextField(false, &isText)) &&
|
||||
isText)) {
|
||||
nsITextControlFrame* textFrame = do_QueryFrame(nonanon->GetPrimaryFrame());
|
||||
if (!!textFrame) {
|
||||
// If the anonymous content node has a child, then we need to make sure
|
||||
// that we get the appropriate child, as otherwise the offset may not be
|
||||
// correct when we construct a range for it.
|
||||
@@ -12422,11 +12433,18 @@ nsDocument::Observe(nsISupports *aSubject,
|
||||
OnAppThemeChanged();
|
||||
}
|
||||
} else if (strcmp("service-worker-get-client", aTopic) == 0) {
|
||||
nsAutoString clientId;
|
||||
GetOrCreateId(clientId);
|
||||
// No need to generate the ID if it doesn't exist here. The ID being
|
||||
// requested must already be generated in order to passed in as
|
||||
// aSubject.
|
||||
nsString clientId = GetId();
|
||||
if (!clientId.IsEmpty() && clientId.Equals(aData)) {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_QueryInterface(aSubject);
|
||||
if (ifptr) {
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsISupports> value;
|
||||
MOZ_ALWAYS_SUCCEEDS(ifptr->GetData(getter_AddRefs(value)));
|
||||
MOZ_ASSERT(!value);
|
||||
#endif
|
||||
ifptr->SetData(static_cast<nsIDocument*>(this));
|
||||
ifptr->SetDataIID(&NS_GET_IID(nsIDocument));
|
||||
}
|
||||
|
||||
@@ -371,7 +371,10 @@ nsGenericDOMDataNode::SetTextInternal(uint32_t aOffset, uint32_t aCount,
|
||||
}
|
||||
|
||||
if (dirAffectsAncestor) {
|
||||
TextNodeChangedDirection(this, oldDir, aNotify);
|
||||
// dirAffectsAncestor being true implies that we have a text node, see
|
||||
// above.
|
||||
MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE);
|
||||
TextNodeChangedDirection(static_cast<nsTextNode*>(this), oldDir, aNotify);
|
||||
}
|
||||
|
||||
// Notify observers
|
||||
|
||||
+5
-2
@@ -1598,8 +1598,11 @@ public:
|
||||
"ClearHasTextNodeDirectionalityMap on non-text node");
|
||||
ClearBoolFlag(NodeHasTextNodeDirectionalityMap);
|
||||
}
|
||||
bool HasTextNodeDirectionalityMap() const
|
||||
{ return GetBoolFlag(NodeHasTextNodeDirectionalityMap); }
|
||||
bool HasTextNodeDirectionalityMap() const {
|
||||
MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE,
|
||||
"HasTextNodeDirectionalityMap on non-text node");
|
||||
return GetBoolFlag(NodeHasTextNodeDirectionalityMap);
|
||||
}
|
||||
|
||||
void SetHasDirAuto() { SetBoolFlag(NodeHasDirAuto); }
|
||||
void ClearHasDirAuto() { ClearBoolFlag(NodeHasDirAuto); }
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE_TO_NSINODE
|
||||
using mozilla::dom::Text::GetParentElement;
|
||||
|
||||
// nsIDOMCharacterData
|
||||
NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
file_bug1011748_redirect.sjs
|
||||
file_bug1011748_OK.sjs
|
||||
file_messagemanager_unload.html
|
||||
file_use_counter_outer.html
|
||||
file_use_counter_svg_getElementById.svg
|
||||
@@ -28,3 +30,4 @@ skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.
|
||||
[browser_use_counters.js]
|
||||
[browser_bug1238440.js]
|
||||
skip-if = e10s
|
||||
[browser_bug1011748.js]
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
const gHttpTestRoot = "http://example.com/browser/dom/base/test/";
|
||||
|
||||
add_task(function* () {
|
||||
var statusTexts = [];
|
||||
var xhr = new XMLHttpRequest();
|
||||
var observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
try {
|
||||
var channel = aSubject.QueryInterface(Ci.nsIHttpChannel);
|
||||
channel.getResponseHeader("Location");
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
statusTexts.push(xhr.statusText);
|
||||
}
|
||||
};
|
||||
|
||||
Services.obs.addObserver(observer, "http-on-examine-response", false);
|
||||
yield new Promise((resolve) => {
|
||||
xhr.addEventListener("load", function() {
|
||||
statusTexts.push(this.statusText);
|
||||
is(statusTexts[0], "", "Empty statusText value for HTTP 302");
|
||||
is(statusTexts[1], "OK", "OK statusText value for the redirect.");
|
||||
resolve();
|
||||
});
|
||||
xhr.open("GET", gHttpTestRoot+ "file_bug1011748_redirect.sjs", true);
|
||||
xhr.send();
|
||||
});
|
||||
|
||||
Services.obs.removeObserver(observer, "http-on-examine-response");
|
||||
});
|
||||
@@ -70,7 +70,6 @@ skip-if = buildapp == 'mulet'
|
||||
[test_bug1346936.html]
|
||||
[test_cpows.xul]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_document_register.xul]
|
||||
[test_mutationobserver_anonymous.html]
|
||||
[test_registerElement_content.xul]
|
||||
[test_registerElement_ep.xul]
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=783129
|
||||
-->
|
||||
<window title="Mozilla Bug 549682"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129"
|
||||
target="_blank">Mozilla Bug 783129</a>
|
||||
<iframe onload="startTests()" id="fooframe" src="http://example.com"></iframe>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 783129 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function startTests() {
|
||||
var c = $("fooframe").contentDocument.registerElement("x-foo");
|
||||
var elem = new c();
|
||||
is(elem.tagName, "X-FOO", "Constructor should create an x-foo element.");
|
||||
|
||||
var anotherElem = $("fooframe").contentDocument.createElement("x-foo");
|
||||
is(anotherElem.tagName, "X-FOO", "createElement should create an x-foo element.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
]]></script>
|
||||
</window>
|
||||
@@ -122,7 +122,7 @@ function testCopyPaste (isXHTML) {
|
||||
function testPasteHTML(id, expected) {
|
||||
var contentEditable = $(id);
|
||||
contentEditable.focus();
|
||||
synthesizeKey("v", {accelKey: 1});
|
||||
synthesizeKey("v", {accelKey: true});
|
||||
is(contentEditable.innerHTML, expected, id+".innerHtml after the paste");
|
||||
}
|
||||
function testSelectionToString(expected) {
|
||||
|
||||
@@ -817,9 +817,6 @@ support-files = bug444546.sjs
|
||||
[test_bug503473.html]
|
||||
disabled = Disabled due to making the harness time out
|
||||
support-files = file_bug503473-frame.sjs
|
||||
[test_bug1011748.html]
|
||||
skip-if = buildapp == 'b2g' || e10s
|
||||
support-files = file_bug1011748_redirect.sjs file_bug1011748_OK.sjs
|
||||
[test_bug1025933.html]
|
||||
[test_bug1037687.html]
|
||||
[test_element.matches.html]
|
||||
@@ -855,3 +852,6 @@ skip-if = buildapp == 'b2g' #no ssl support
|
||||
[test_bug1187157.html]
|
||||
[test_bug769117.html]
|
||||
[test_bug1250148.html]
|
||||
[test_document_register.html]
|
||||
[test_bug962251.html]
|
||||
[test_bug1259588.html]
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1011748
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1011748</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1011748 **/
|
||||
"use strict";
|
||||
|
||||
var observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
try {
|
||||
var channel = aSubject.QueryInterface(SpecialPowers.Ci.nsIHttpChannel);
|
||||
channel.getResponseHeader("Location");
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
statusTexts.push(xhr.statusText);
|
||||
}
|
||||
};
|
||||
|
||||
var statusTexts = [];
|
||||
SpecialPowers.addObserver(observer, "http-on-examine-response", false);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.addEventListener("load", function() {
|
||||
statusTexts.push(this.statusText);
|
||||
SpecialPowers.removeObserver(observer, "http-on-examine-response");
|
||||
is(statusTexts[0], "", "Empty statusText value for HTTP 302");
|
||||
is(statusTexts[1], "OK", "OK statusText value for the redirect.");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
xhr.open("GET", "file_bug1011748_redirect.sjs", true);
|
||||
xhr.send();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1011748">Mozilla Bug 1011748</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for Bug 1259588</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
test(function() {
|
||||
assert_throws(new TypeError, function() {
|
||||
new File("");
|
||||
}, "new File(\"\") should throw TypeError exception");
|
||||
}, "Test new File(\"\") should throw exception");
|
||||
</script>
|
||||
@@ -91,6 +91,16 @@
|
||||
todo(false, "test5Rect: (" + test5Rect.top + ", " + test5Rect.left + ", " + test5Rect.width + ", " + test5Rect.height + ")");
|
||||
checkOffsetsFromPoint(test5x, test5y, 0, 'test5');
|
||||
|
||||
// Check the first and last characters of the numeric input.
|
||||
var test6Element = document.getElementById("test6");
|
||||
var test6Rect = test6Element.getBoundingClientRect();
|
||||
checkOffsetsFromPoint(Math.round(test6Rect.left + 5),
|
||||
Math.round(test6Rect.top + (test6Rect.height / 2)),
|
||||
0, "test6");
|
||||
checkOffsetsFromPoint(Math.round(test6Rect.left + test6Rect.width - 30),
|
||||
Math.round(test6Rect.top + (test6Rect.height / 2)),
|
||||
5, "test6");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@@ -104,5 +114,6 @@
|
||||
<marquee>marquee</marquee>
|
||||
</div>
|
||||
<input id="test5" value="The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly down, so suddenly that Alice had not a moment to think about stopping herself before she found herself falling down a very deep well. Either the well was very deep, or she fell very slowly, for she had plenty of time as she went down to look about her and to wonder what was going to happen next. First, she tried to look down and make out what she was coming to, but it was too dark to see anything; then she looked at the sides of the well, and noticed that they were filled with cupboards and book-shelves; here and there she saw maps and pictures hung upon pegs. She took down a jar from one of the shelves as she passed; it was labelled `ORANGE MARMALADE', but to her great disappointment it was empty: she did not like to drop the jar for fear of killing somebody, so managed to put it into one of the cupboards as she fell past it." type="text">
|
||||
<input id="test6" type="number" style="width:150px; height:57px;" value="31415"><br>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body onload="startTests()">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129" target="_blank">Mozilla Bug 783129</a>
|
||||
<iframe id="fooframe" src="/"></iframe>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 783129 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function startTests() {
|
||||
var c = document.getElementById("fooframe").contentDocument.registerElement("x-foo");
|
||||
var elem = new c();
|
||||
is(elem.tagName, "X-FOO", "Constructor should create an x-foo element.");
|
||||
|
||||
var anotherElem = $("fooframe").contentDocument.createElement("x-foo");
|
||||
is(anotherElem.tagName, "X-FOO", "createElement should create an x-foo element.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -140,15 +140,18 @@ BatteryManager::UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInf
|
||||
doc->NodePrincipal()->GetAppStatus(&status);
|
||||
}
|
||||
|
||||
mCharging = aBatteryInfo.charging();
|
||||
mRemainingTime = aBatteryInfo.remainingTime();
|
||||
|
||||
if (!nsContentUtils::IsChromeDoc(doc) &&
|
||||
status != nsIPrincipal::APP_STATUS_CERTIFIED)
|
||||
{
|
||||
mLevel = lround(mLevel * 10.0) / 10.0;
|
||||
if (mLevel == 1.0) {
|
||||
mRemainingTime = mCharging ? kDefaultRemainingTime : kUnknownRemainingTime;
|
||||
}
|
||||
}
|
||||
|
||||
mCharging = aBatteryInfo.charging();
|
||||
mRemainingTime = aBatteryInfo.remainingTime();
|
||||
|
||||
// Add some guards to make sure the values are coherent.
|
||||
if (mLevel == 1.0 && mCharging == true &&
|
||||
mRemainingTime != kDefaultRemainingTime) {
|
||||
|
||||
@@ -101,7 +101,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
|
||||
}
|
||||
} else {
|
||||
JSObject *global = js::GetGlobalForObjectCrossCompartment(realCallback);
|
||||
globalObject = workers::GetGlobalObjectForGlobal(global);
|
||||
globalObject = xpc::NativeGlobal(global);
|
||||
MOZ_ASSERT(globalObject);
|
||||
}
|
||||
|
||||
@@ -245,41 +245,13 @@ CallbackObject::CallSetup::~CallSetup()
|
||||
if (needToDealWithException) {
|
||||
// Either we're supposed to report our exceptions, or we're supposed to
|
||||
// re-throw them but we failed to get the exception value. Either way,
|
||||
// just report the pending exception, if any.
|
||||
//
|
||||
// We don't use nsJSUtils::ReportPendingException here because all it
|
||||
// does at this point is JS_SaveFrameChain and enter a compartment around
|
||||
// a JS_ReportPendingException call. But our mAutoEntryScript should
|
||||
// already do a JS_SaveFrameChain and we are already in the compartment
|
||||
// we want to be in, so all nsJSUtils::ReportPendingException would do is
|
||||
// screw up our compartment, which is exactly what we do not want.
|
||||
//
|
||||
// XXXbz FIXME: bug 979525 means we don't always JS_SaveFrameChain here,
|
||||
// so we need to go ahead and do that. This is also the reason we don't
|
||||
// just rely on ~AutoJSAPI reporting the exception for us. I think if we
|
||||
// didn't need to JS_SaveFrameChain here, we could just rely on that.
|
||||
JS::Rooted<JSObject*> oldGlobal(mCx, JS::CurrentGlobalOrNull(mCx));
|
||||
MOZ_ASSERT(oldGlobal, "How can we not have a global here??");
|
||||
bool saved = JS_SaveFrameChain(mCx);
|
||||
// Make sure the JSAutoCompartment goes out of scope before the
|
||||
// JS_RestoreFrameChain call!
|
||||
{
|
||||
JSAutoCompartment ac(mCx, oldGlobal);
|
||||
MOZ_ASSERT(!JS::DescribeScriptedCaller(mCx),
|
||||
"Our comment above about JS_SaveFrameChain having been "
|
||||
"called is a lie?");
|
||||
// Note that we don't JS_ReportPendingException here because we want to
|
||||
// go through our AutoEntryScript's reporting mechanism instead, since
|
||||
// it currently owns error reporting.
|
||||
mAutoEntryScript->ReportException();
|
||||
}
|
||||
if (saved) {
|
||||
JS_RestoreFrameChain(mCx);
|
||||
}
|
||||
|
||||
// we'll just report the pending exception, if any, once ~mAutoEntryScript
|
||||
// runs. Note that we've already run ~mAc, effectively, so we don't have
|
||||
// to worry about ordering here.
|
||||
if (mErrorResult.IsJSContextException()) {
|
||||
// XXXkhuey bug 1117269.
|
||||
// This isn't true anymore ... so throw something else.
|
||||
// This won't be true anymore because we will report the exception on
|
||||
// the JSContext ... so throw something else.
|
||||
mErrorResult.Throw(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,24 @@ ThrowExceptionObject(JSContext* aCx, Exception* aException)
|
||||
// thread.
|
||||
if (NS_IsMainThread() && !nsContentUtils::IsCallerChrome() &&
|
||||
aException->StealJSVal(thrown.address())) {
|
||||
// Now check for the case when thrown is a number which matches
|
||||
// aException->GetResult(). This would indicate that what actually got
|
||||
// thrown was an nsresult value. In that situation, we should go back
|
||||
// through dom::Throw with that nsresult value, because it will make sure to
|
||||
// create the right sort of Exception or DOMException, with the right
|
||||
// global.
|
||||
if (thrown.isNumber()) {
|
||||
nsresult exceptionResult;
|
||||
if (NS_SUCCEEDED(aException->GetResult(&exceptionResult)) &&
|
||||
double(exceptionResult) == thrown.toNumber()) {
|
||||
// The return value semantics here are a bit weird. Throw() always
|
||||
// returns false. But we want to return true if we managed to throw an
|
||||
// exception (otherwise our caller will assume OOM)... which Throw()
|
||||
// always will. So we just return true unconditionally.
|
||||
Throw(aCx, exceptionResult);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!JS_WrapValue(aCx, &thrown)) {
|
||||
return false;
|
||||
}
|
||||
@@ -103,15 +121,17 @@ Throw(JSContext* aCx, nsresult aRv, const nsACString& aMessage)
|
||||
|
||||
CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
|
||||
nsCOMPtr<nsIException> existingException = runtime->GetPendingException();
|
||||
if (existingException) {
|
||||
// Make sure to clear the pending exception now. Either we're going to reuse
|
||||
// it (and we already grabbed it), or we plan to throw something else and this
|
||||
// pending exception is no longer relevant.
|
||||
runtime->SetPendingException(nullptr);
|
||||
|
||||
// Ignore the pending exception if we have a non-default message passed in.
|
||||
if (aMessage.IsEmpty() && existingException) {
|
||||
nsresult nr;
|
||||
if (NS_SUCCEEDED(existingException->GetResult(&nr)) &&
|
||||
aRv == nr) {
|
||||
// Reuse the existing exception.
|
||||
|
||||
// Clear pending exception
|
||||
runtime->SetPendingException(nullptr);
|
||||
|
||||
if (!ThrowExceptionObject(aCx, existingException)) {
|
||||
// If we weren't able to throw an exception we're
|
||||
// most likely out of memory
|
||||
|
||||
@@ -228,6 +228,10 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
|
||||
}
|
||||
|
||||
BluetoothA2dpManager::~BluetoothA2dpManager()
|
||||
{ }
|
||||
|
||||
void
|
||||
BluetoothA2dpManager::Uninit()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
@@ -273,9 +277,9 @@ BluetoothA2dpManager::Get()
|
||||
// If we're in shutdown, don't create a new instance
|
||||
NS_ENSURE_FALSE(sInShutdown, nullptr);
|
||||
|
||||
// Create a new instance, register, and return
|
||||
BluetoothA2dpManager* manager = new BluetoothA2dpManager();
|
||||
sBluetoothA2dpManager = manager;
|
||||
// Create a new instance and return
|
||||
sBluetoothA2dpManager = new BluetoothA2dpManager();
|
||||
|
||||
return sBluetoothA2dpManager;
|
||||
}
|
||||
|
||||
@@ -297,6 +301,9 @@ public:
|
||||
sBtA2dpInterface->SetNotificationHandler(nullptr);
|
||||
sBtA2dpInterface = nullptr;
|
||||
|
||||
sBluetoothA2dpManager->Uninit();
|
||||
sBluetoothA2dpManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
@@ -309,6 +316,9 @@ public:
|
||||
sBtA2dpInterface->SetNotificationHandler(nullptr);
|
||||
sBtA2dpInterface = nullptr;
|
||||
|
||||
sBluetoothA2dpManager->Uninit();
|
||||
sBluetoothA2dpManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->Deinit();
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ private:
|
||||
|
||||
BluetoothA2dpManager();
|
||||
|
||||
void Uninit();
|
||||
void HandleShutdown();
|
||||
void NotifyConnectionStatusChanged();
|
||||
|
||||
|
||||
@@ -268,6 +268,10 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes)
|
||||
}
|
||||
|
||||
BluetoothAvrcpManager::~BluetoothAvrcpManager()
|
||||
{ }
|
||||
|
||||
void
|
||||
BluetoothAvrcpManager::Uninit()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
@@ -294,9 +298,9 @@ BluetoothAvrcpManager::Get()
|
||||
// If we're in shutdown, don't create a new instance
|
||||
NS_ENSURE_FALSE(sInShutdown, nullptr);
|
||||
|
||||
// Create a new instance, register, and return
|
||||
BluetoothAvrcpManager* manager = new BluetoothAvrcpManager();
|
||||
sBluetoothAvrcpManager = manager;
|
||||
// Create a new instance and return
|
||||
sBluetoothAvrcpManager = new BluetoothAvrcpManager();
|
||||
|
||||
return sBluetoothAvrcpManager;
|
||||
}
|
||||
|
||||
@@ -318,6 +322,9 @@ public:
|
||||
sBtAvrcpInterface->SetNotificationHandler(nullptr);
|
||||
sBtAvrcpInterface = nullptr;
|
||||
|
||||
sBluetoothAvrcpManager->Uninit();
|
||||
sBluetoothAvrcpManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
@@ -330,6 +337,9 @@ public:
|
||||
sBtAvrcpInterface->SetNotificationHandler(nullptr);
|
||||
sBtAvrcpInterface = nullptr;
|
||||
|
||||
sBluetoothAvrcpManager->Uninit();
|
||||
sBluetoothAvrcpManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->Deinit();
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ private:
|
||||
|
||||
BluetoothAvrcpManager();
|
||||
|
||||
void Uninit();
|
||||
void HandleShutdown();
|
||||
void NotifyConnectionStatusChanged();
|
||||
|
||||
|
||||
@@ -389,11 +389,41 @@ BluetoothGattManager::Get()
|
||||
NS_ENSURE_FALSE(mInShutdown, nullptr);
|
||||
|
||||
// Create a new instance, register, and return
|
||||
BluetoothGattManager* manager = new BluetoothGattManager();
|
||||
RefPtr<BluetoothGattManager> manager = new BluetoothGattManager();
|
||||
NS_ENSURE_SUCCESS(manager->Init(), nullptr);
|
||||
|
||||
sBluetoothGattManager = manager;
|
||||
|
||||
return sBluetoothGattManager;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothGattManager::Init()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE(obs, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("Failed to add observers!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattManager::Uninit()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
|
||||
BT_WARNING("Failed to remove shutdown observer!");
|
||||
}
|
||||
}
|
||||
|
||||
class BluetoothGattManager::RegisterModuleResultHandler final
|
||||
: public BluetoothSetupResultHandler
|
||||
{
|
||||
@@ -552,6 +582,11 @@ public:
|
||||
|
||||
sBluetoothGattInterface->SetNotificationHandler(nullptr);
|
||||
sBluetoothGattInterface = nullptr;
|
||||
sClients = nullptr;
|
||||
sServers = nullptr;
|
||||
|
||||
sBluetoothGattManager->Uninit();
|
||||
sBluetoothGattManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
@@ -567,6 +602,9 @@ public:
|
||||
sClients = nullptr;
|
||||
sServers = nullptr;
|
||||
|
||||
sBluetoothGattManager->Uninit();
|
||||
sBluetoothGattManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->Deinit();
|
||||
}
|
||||
@@ -4073,13 +4111,7 @@ BluetoothGattManager::BluetoothGattManager()
|
||||
{ }
|
||||
|
||||
BluetoothGattManager::~BluetoothGattManager()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
|
||||
BT_WARNING("Failed to remove shutdown observer!");
|
||||
}
|
||||
}
|
||||
{ }
|
||||
|
||||
NS_IMETHODIMP
|
||||
BluetoothGattManager::Observe(nsISupports* aSubject,
|
||||
|
||||
@@ -217,6 +217,8 @@ private:
|
||||
|
||||
BluetoothGattManager();
|
||||
|
||||
nsresult Init();
|
||||
void Uninit();
|
||||
void HandleShutdown();
|
||||
|
||||
void RegisterClientNotification(BluetoothGattStatus aStatus,
|
||||
|
||||
@@ -83,6 +83,8 @@ BluetoothMapSmsManager::HandleShutdown()
|
||||
|
||||
sInShutdown = true;
|
||||
Disconnect(nullptr);
|
||||
Uninit();
|
||||
|
||||
sMapSmsManager = nullptr;
|
||||
}
|
||||
|
||||
@@ -97,27 +99,19 @@ BluetoothMapSmsManager::BluetoothMapSmsManager()
|
||||
}
|
||||
|
||||
BluetoothMapSmsManager::~BluetoothMapSmsManager()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return;
|
||||
}
|
||||
{ }
|
||||
|
||||
NS_WARN_IF(NS_FAILED(
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
|
||||
}
|
||||
|
||||
bool
|
||||
nsresult
|
||||
BluetoothMapSmsManager::Init()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return false;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)))) {
|
||||
return false;
|
||||
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,7 +123,46 @@ BluetoothMapSmsManager::Init()
|
||||
* absence of read events when device boots up.
|
||||
*/
|
||||
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothMapSmsManager::Uninit()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_WARN_IF(NS_FAILED(
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothMapSmsManager::InitMapSmsInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aRes) {
|
||||
aRes->Init();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothMapSmsManager::DeinitMapSmsInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sMapSmsManager) {
|
||||
sMapSmsManager->Uninit();
|
||||
sMapSmsManager = nullptr;
|
||||
}
|
||||
|
||||
if (aRes) {
|
||||
aRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
@@ -149,8 +182,8 @@ BluetoothMapSmsManager::Get()
|
||||
}
|
||||
|
||||
// Create a new instance, register, and return
|
||||
BluetoothMapSmsManager *manager = new BluetoothMapSmsManager();
|
||||
if (NS_WARN_IF(!manager->Init())) {
|
||||
RefPtr<BluetoothMapSmsManager> manager = new BluetoothMapSmsManager();
|
||||
if (NS_WARN_IF(NS_FAILED(manager->Init()))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,10 @@ public:
|
||||
// By defualt SMS/MMS is default supported
|
||||
static const int SDP_SMS_MMS_INSTANCE_ID = 0;
|
||||
|
||||
static void InitMapSmsInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitMapSmsInterface(BluetoothProfileResultHandler* aRes);
|
||||
static BluetoothMapSmsManager* Get();
|
||||
|
||||
bool Listen();
|
||||
|
||||
/**
|
||||
@@ -194,7 +197,9 @@ protected:
|
||||
|
||||
private:
|
||||
BluetoothMapSmsManager();
|
||||
bool Init();
|
||||
|
||||
nsresult Init();
|
||||
void Uninit();
|
||||
void HandleShutdown();
|
||||
|
||||
void ReplyToConnect();
|
||||
|
||||
@@ -213,31 +213,24 @@ BluetoothOppManager::BluetoothOppManager() : mConnected(false)
|
||||
{ }
|
||||
|
||||
BluetoothOppManager::~BluetoothOppManager()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
|
||||
BT_WARNING("Failed to remove shutdown observer!");
|
||||
}
|
||||
{ }
|
||||
|
||||
if (NS_FAILED(obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED))) {
|
||||
BT_WARNING("Failed to remove volume observer!");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsresult
|
||||
BluetoothOppManager::Init()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE(obs, false);
|
||||
if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
|
||||
NS_ENSURE_TRUE(obs, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("Failed to add shutdown observer!");
|
||||
return false;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (NS_FAILED(obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false))) {
|
||||
rv = obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("Failed to add ns volume observer!");
|
||||
return false;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,7 +242,49 @@ BluetoothOppManager::Init()
|
||||
* absence of read events when device boots up.
|
||||
*/
|
||||
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::Uninit()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
|
||||
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
|
||||
BT_WARNING("Failed to remove shutdown observer!");
|
||||
}
|
||||
|
||||
if (NS_FAILED(obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED))) {
|
||||
BT_WARNING("Failed to remove volume observer!");
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothOppManager::InitOppInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aRes) {
|
||||
aRes->Init();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothOppManager::DeinitOppInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sBluetoothOppManager) {
|
||||
sBluetoothOppManager->Uninit();
|
||||
sBluetoothOppManager = nullptr;
|
||||
}
|
||||
|
||||
if (aRes) {
|
||||
aRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
@@ -267,10 +302,11 @@ BluetoothOppManager::Get()
|
||||
NS_ENSURE_FALSE(sInShutdown, nullptr);
|
||||
|
||||
// Create a new instance, register, and return
|
||||
BluetoothOppManager *manager = new BluetoothOppManager();
|
||||
NS_ENSURE_TRUE(manager->Init(), nullptr);
|
||||
RefPtr<BluetoothOppManager> manager = new BluetoothOppManager();
|
||||
NS_ENSURE_SUCCESS(manager->Init(), nullptr);
|
||||
|
||||
sBluetoothOppManager = manager;
|
||||
|
||||
return sBluetoothOppManager;
|
||||
}
|
||||
|
||||
@@ -309,6 +345,8 @@ BluetoothOppManager::HandleShutdown()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sInShutdown = true;
|
||||
Disconnect(nullptr);
|
||||
Uninit();
|
||||
|
||||
sBluetoothOppManager = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ class BluetoothOppManager : public BluetoothSocketObserver
|
||||
class SendSocketDataTask;
|
||||
|
||||
public:
|
||||
|
||||
BT_DECL_PROFILE_MGR_BASE
|
||||
BT_DECL_SOCKET_OBSERVER
|
||||
virtual void GetName(nsACString& aName)
|
||||
@@ -49,7 +50,10 @@ public:
|
||||
|
||||
static const int MAX_PACKET_LENGTH = 0xFFFE;
|
||||
|
||||
static void InitOppInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitOppInterface(BluetoothProfileResultHandler* aRes);
|
||||
static BluetoothOppManager* Get();
|
||||
|
||||
void ClientDataHandler(mozilla::ipc::UnixSocketBuffer* aMessage);
|
||||
void ServerDataHandler(mozilla::ipc::UnixSocketBuffer* aMessage);
|
||||
|
||||
@@ -75,7 +79,8 @@ protected:
|
||||
|
||||
private:
|
||||
BluetoothOppManager();
|
||||
bool Init();
|
||||
nsresult Init();
|
||||
void Uninit();
|
||||
void HandleShutdown();
|
||||
void HandleVolumeStateChanged(nsISupports* aSubject);
|
||||
|
||||
|
||||
@@ -93,6 +93,8 @@ BluetoothPbapManager::HandleShutdown()
|
||||
|
||||
sInShutdown = true;
|
||||
Disconnect(nullptr);
|
||||
Uninit();
|
||||
|
||||
sPbapManager = nullptr;
|
||||
}
|
||||
|
||||
@@ -104,27 +106,19 @@ BluetoothPbapManager::BluetoothPbapManager() : mPhonebookSizeRequired(false)
|
||||
}
|
||||
|
||||
BluetoothPbapManager::~BluetoothPbapManager()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return;
|
||||
}
|
||||
{ }
|
||||
|
||||
NS_WARN_IF(NS_FAILED(
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
|
||||
}
|
||||
|
||||
bool
|
||||
nsresult
|
||||
BluetoothPbapManager::Init()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return false;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)))) {
|
||||
return false;
|
||||
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,7 +130,46 @@ BluetoothPbapManager::Init()
|
||||
* absence of read events when device boots up.
|
||||
*/
|
||||
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothPbapManager::Uninit()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_WARN_IF(NS_FAILED(
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothPbapManager::InitPbapInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aRes) {
|
||||
aRes->Init();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothPbapManager::DeinitPbapInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sPbapManager) {
|
||||
sPbapManager->Uninit();
|
||||
sPbapManager = nullptr;
|
||||
}
|
||||
|
||||
if (aRes) {
|
||||
aRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
@@ -156,8 +189,8 @@ BluetoothPbapManager::Get()
|
||||
}
|
||||
|
||||
// Create a new instance, register, and return
|
||||
BluetoothPbapManager *manager = new BluetoothPbapManager();
|
||||
if (NS_WARN_IF(!manager->Init())) {
|
||||
RefPtr<BluetoothPbapManager> manager = new BluetoothPbapManager();
|
||||
if (NS_WARN_IF(NS_FAILED(manager->Init()))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,10 @@ public:
|
||||
static const int MAX_PACKET_LENGTH = 0xFFFE;
|
||||
static const int DIGEST_LENGTH = 16;
|
||||
|
||||
static void InitPbapInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitPbapInterface(BluetoothProfileResultHandler* aRes);
|
||||
static BluetoothPbapManager* Get();
|
||||
|
||||
bool Listen();
|
||||
|
||||
/**
|
||||
@@ -146,7 +149,9 @@ protected:
|
||||
|
||||
private:
|
||||
BluetoothPbapManager();
|
||||
bool Init();
|
||||
|
||||
nsresult Init();
|
||||
void Uninit();
|
||||
void HandleShutdown();
|
||||
|
||||
void ReplyToConnect(const nsAString& aPassword = EmptyString());
|
||||
|
||||
@@ -138,6 +138,10 @@ public:
|
||||
void Init() override
|
||||
{
|
||||
static void (* const sInitManager[])(BluetoothProfileResultHandler*) = {
|
||||
BluetoothMapSmsManager::InitMapSmsInterface,
|
||||
BluetoothOppManager::InitOppInterface,
|
||||
BluetoothPbapManager::InitPbapInterface,
|
||||
BluetoothHidManager::InitHidInterface,
|
||||
BluetoothHfpManager::InitHfpInterface,
|
||||
BluetoothA2dpManager::InitA2dpInterface,
|
||||
BluetoothAvrcpManager::InitAvrcpInterface,
|
||||
@@ -2037,7 +2041,11 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
|
||||
BluetoothGattManager::DeinitGattInterface,
|
||||
BluetoothAvrcpManager::DeinitAvrcpInterface,
|
||||
BluetoothA2dpManager::DeinitA2dpInterface,
|
||||
BluetoothHfpManager::DeinitHfpInterface
|
||||
BluetoothHfpManager::DeinitHfpInterface,
|
||||
BluetoothHidManager::DeinitHidInterface,
|
||||
BluetoothPbapManager::DeinitPbapInterface,
|
||||
BluetoothOppManager::DeinitOppInterface,
|
||||
BluetoothMapSmsManager::DeinitMapSmsInterface
|
||||
};
|
||||
|
||||
// Return error if BluetoothService is unavailable
|
||||
|
||||
@@ -176,6 +176,8 @@ BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
sBluetoothHfpManager = nullptr;
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* Implement DeinitHfpInterface() for applications that want to create SCO
|
||||
|
||||
@@ -446,6 +446,7 @@ public:
|
||||
|
||||
sBluetoothHfpInterface->SetNotificationHandler(nullptr);
|
||||
sBluetoothHfpInterface = nullptr;
|
||||
sBluetoothHfpManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
@@ -458,6 +459,7 @@ public:
|
||||
|
||||
sBluetoothHfpInterface->SetNotificationHandler(nullptr);
|
||||
sBluetoothHfpInterface = nullptr;
|
||||
sBluetoothHfpManager = nullptr;
|
||||
|
||||
if (mRes) {
|
||||
mRes->Deinit();
|
||||
|
||||
@@ -78,6 +78,30 @@ BluetoothHidManager::~BluetoothHidManager()
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothHidManager::InitHidInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aRes) {
|
||||
aRes->Init();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothHidManager::DeinitHidInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
sBluetoothHidManager = nullptr;
|
||||
|
||||
if (aRes) {
|
||||
aRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
BluetoothHidManager*
|
||||
BluetoothHidManager::Get()
|
||||
|
||||
@@ -22,6 +22,8 @@ public:
|
||||
aName.AssignLiteral("HID");
|
||||
}
|
||||
|
||||
static void InitHidInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitHidInterface(BluetoothProfileResultHandler* aRes);
|
||||
static BluetoothHidManager* Get();
|
||||
|
||||
// HID-specific functions
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace mozilla {
|
||||
namespace ipc {
|
||||
class BackgroundParentImpl;
|
||||
class PrincipalInfo;
|
||||
}
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ LOCAL_INCLUDES += [
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
||||
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
|
||||
BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[DEFAULT]
|
||||
skip-if = buildapp == 'b2g' || os == 'android'
|
||||
support-files =
|
||||
blank.html
|
||||
|
||||
[browser_private_browsing.js]
|
||||
@@ -0,0 +1,74 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const URL = "http://mochi.test:8888/browser/dom/broadcastchannel/tests/blank.html";
|
||||
|
||||
add_task(function*() {
|
||||
var win1 = OpenBrowserWindow({private: true});
|
||||
var win1Promise = new win1.Promise(resolve => {
|
||||
win1.addEventListener("load", function onLoad() {
|
||||
win1.removeEventListener("load", onLoad, false);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
yield win1Promise;
|
||||
|
||||
var win2 = OpenBrowserWindow({private: false});
|
||||
var win2Promise = new win2.Promise(resolve => {
|
||||
win2.addEventListener("load", function onLoad() {
|
||||
win2.removeEventListener("load", onLoad, false);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
yield win2Promise;
|
||||
|
||||
var tab1 = win1.gBrowser.addTab(URL);
|
||||
yield BrowserTestUtils.browserLoaded(win1.gBrowser.getBrowserForTab(tab1));
|
||||
var browser1 = gBrowser.getBrowserForTab(tab1);
|
||||
|
||||
var tab2 = win2.gBrowser.addTab(URL);
|
||||
yield BrowserTestUtils.browserLoaded(win2.gBrowser.getBrowserForTab(tab2));
|
||||
var browser2 = gBrowser.getBrowserForTab(tab2);
|
||||
|
||||
var p1 = ContentTask.spawn(browser1, null, function(opts) {
|
||||
return new content.window.Promise(resolve => {
|
||||
content.window.bc = new content.window.BroadcastChannel('foobar');
|
||||
content.window.bc.onmessage = function(e) { resolve(e.data); }
|
||||
});
|
||||
});
|
||||
|
||||
var p2 = ContentTask.spawn(browser2, null, function(opts) {
|
||||
return new content.window.Promise(resolve => {
|
||||
content.window.bc = new content.window.BroadcastChannel('foobar');
|
||||
content.window.bc.onmessage = function(e) { resolve(e.data); }
|
||||
});
|
||||
});
|
||||
|
||||
yield ContentTask.spawn(browser1, null, function(opts) {
|
||||
return new content.window.Promise(resolve => {
|
||||
var bc = new content.window.BroadcastChannel('foobar');
|
||||
bc.postMessage('hello world from private browsing');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
yield ContentTask.spawn(browser2, null, function(opts) {
|
||||
return new content.window.Promise(resolve => {
|
||||
var bc = new content.window.BroadcastChannel('foobar');
|
||||
bc.postMessage('hello world from non private browsing');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
var what1 = yield p1;
|
||||
ok(what1, 'hello world from private browsing', 'No messages received from the other window.');
|
||||
|
||||
var what2 = yield p2;
|
||||
ok(what1, 'hello world from non private browsing', 'No messages received from the other window.');
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab1);
|
||||
yield BrowserTestUtils.closeWindow(win1);
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab2);
|
||||
yield BrowserTestUtils.closeWindow(win2);
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
[DEFAULT]
|
||||
skip-if = e10s || buildapp == 'b2g'
|
||||
support-files =
|
||||
blank.html
|
||||
|
||||
[test_broadcastchannel_private_browsing.html]
|
||||
@@ -1,118 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Test for BroadcastChannel - Private Browsing</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
var mainWindow;
|
||||
|
||||
var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
prefBranch.setIntPref("browser.startup.page", 0);
|
||||
prefBranch.setCharPref("browser.startup.homepage_override.mstone", "ignore");
|
||||
|
||||
var contentPage = "http://mochi.test:8888/chrome/dom/broadcastchannel/tests/blank.html";
|
||||
|
||||
function testOnWindow(aIsPrivate, aCallback) {
|
||||
var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
win.addEventListener("DOMContentLoaded", function onInnerLoad() {
|
||||
if (win.content.location.href != contentPage) {
|
||||
win.gBrowser.loadURI(contentPage);
|
||||
return;
|
||||
}
|
||||
|
||||
win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
|
||||
SimpleTest.executeSoon(function() { aCallback(win); });
|
||||
}, true);
|
||||
|
||||
if (!aIsPrivate) {
|
||||
win.gBrowser.loadURI(contentPage);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
function setupWindow() {
|
||||
mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
runTest();
|
||||
}
|
||||
|
||||
var gCounter = 0;
|
||||
|
||||
function check(msg, private) {
|
||||
is(msg, private ? "private" : "public", "Correct context!");
|
||||
gCounter++;
|
||||
|
||||
if (gCounter > 1) {
|
||||
runTest();
|
||||
}
|
||||
}
|
||||
|
||||
var wN;
|
||||
var wP;
|
||||
|
||||
function doTests() {
|
||||
testOnWindow(false, function(aWin) {
|
||||
wN = aWin;
|
||||
|
||||
testOnWindow(true, function(aWin) {
|
||||
wP = aWin;
|
||||
|
||||
var bcP = new wP.content.BroadcastChannel('foobar');
|
||||
bcP.onmessage = function(e) { ok(false, "This should not be called!"); }
|
||||
|
||||
var bc = new wP.content.BroadcastChannel('foobar');
|
||||
bc.onmessage = function(e) { check(e.data, true); }
|
||||
|
||||
var bcN = new wN.content.BroadcastChannel('foobar');
|
||||
bcN.onmessage = function(e) { ok(false, "This should not be called!"); }
|
||||
|
||||
var bc = new wN.content.BroadcastChannel('foobar');
|
||||
bc.onmessage = function(e) { check(e.data, false); }
|
||||
|
||||
bcP.postMessage('private');
|
||||
bcN.postMessage('public');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var steps = [
|
||||
setupWindow,
|
||||
doTests
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!steps.length) {
|
||||
wN.close();
|
||||
wP.close();
|
||||
|
||||
prefBranch.clearUserPref("browser.startup.page")
|
||||
prefBranch.clearUserPref("browser.startup.homepage_override.mstone");
|
||||
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var step = steps.shift();
|
||||
step();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -147,12 +147,12 @@ private:
|
||||
nsTArray<nsID> mDeletedBodyIdList;
|
||||
};
|
||||
|
||||
bool IsHeadRequest(CacheRequest aRequest, CacheQueryParams aParams)
|
||||
bool IsHeadRequest(const CacheRequest& aRequest, const CacheQueryParams& aParams)
|
||||
{
|
||||
return !aParams.ignoreMethod() && aRequest.method().LowerCaseEqualsLiteral("head");
|
||||
}
|
||||
|
||||
bool IsHeadRequest(CacheRequestOrVoid aRequest, CacheQueryParams aParams)
|
||||
bool IsHeadRequest(const CacheRequestOrVoid& aRequest, const CacheQueryParams& aParams)
|
||||
{
|
||||
if (aRequest.type() == CacheRequestOrVoid::TCacheRequest) {
|
||||
return !aParams.ignoreMethod() &&
|
||||
|
||||
@@ -756,7 +756,13 @@ TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* f
|
||||
// call into GL, instead of trying to keep MakeCurrent-ed.
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> dataSurf = mSurf->GetDataSurface();
|
||||
MOZ_ASSERT(dataSurf);
|
||||
|
||||
if (!dataSurf) {
|
||||
// Since GetDataSurface didn't return error code, assume system
|
||||
// is out of memory
|
||||
*out_glError = LOCAL_GL_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
GLenum error;
|
||||
if (UploadDataSurface(isSubImage, webgl, target, level, dui, xOffset, yOffset,
|
||||
|
||||
@@ -556,6 +556,7 @@ WebGL2Context::ReadBuffer(GLenum mode)
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
mBoundReadFramebuffer->SetReadBufferMode(mode);
|
||||
gl->fReadBuffer(mode);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1472,7 +1472,7 @@ CheckContextLost(GLContext* gl, bool* const out_isGuilty)
|
||||
bool isEGL = gl->GetContextType() == gl::GLContextType::EGL;
|
||||
|
||||
GLenum resetStatus = LOCAL_GL_NO_ERROR;
|
||||
if (gl->HasRobustness()) {
|
||||
if (gl->IsSupported(GLFeature::robustness)) {
|
||||
gl->MakeCurrent();
|
||||
resetStatus = gl->fGetGraphicsResetStatus();
|
||||
} else if (isEGL) {
|
||||
@@ -1800,7 +1800,8 @@ WebGLContext::DidRefresh()
|
||||
bool
|
||||
WebGLContext::ValidateCurFBForRead(const char* funcName,
|
||||
const webgl::FormatUsageInfo** const out_format,
|
||||
uint32_t* const out_width, uint32_t* const out_height)
|
||||
uint32_t* const out_width, uint32_t* const out_height,
|
||||
GLenum* const out_mode)
|
||||
{
|
||||
if (!mBoundReadFramebuffer) {
|
||||
ClearBackbufferIfNeeded();
|
||||
@@ -1816,11 +1817,12 @@ WebGLContext::ValidateCurFBForRead(const char* funcName,
|
||||
|
||||
*out_width = mWidth;
|
||||
*out_height = mHeight;
|
||||
*out_mode = gl->Screen()->GetReadBufferMode();
|
||||
return true;
|
||||
}
|
||||
|
||||
return mBoundReadFramebuffer->ValidateForRead(funcName, out_format, out_width,
|
||||
out_height);
|
||||
out_height, out_mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1277,7 +1277,8 @@ protected:
|
||||
|
||||
bool ValidateCurFBForRead(const char* funcName,
|
||||
const webgl::FormatUsageInfo** const out_format,
|
||||
uint32_t* const out_width, uint32_t* const out_height);
|
||||
uint32_t* const out_width, uint32_t* const out_height,
|
||||
GLenum* const out_mode);
|
||||
|
||||
void Invalidate();
|
||||
void DestroyResourcesAndContext();
|
||||
|
||||
@@ -360,8 +360,10 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Any checks below this depend on a program being available.
|
||||
if (!mCurrentProgram) {
|
||||
// Any checks below this depend on mActiveProgramLinkInfo being available.
|
||||
if (!mActiveProgramLinkInfo) {
|
||||
// Technically, this will only be null iff CURRENT_PROGRAM is null.
|
||||
// But it's better to branch on what we actually care about.
|
||||
ErrorInvalidOperation("%s: null CURRENT_PROGRAM", info);
|
||||
return false;
|
||||
}
|
||||
@@ -841,19 +843,34 @@ WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget ta
|
||||
const webgl::DriverUnpackInfo dui = {texFormat, texFormat, LOCAL_GL_UNSIGNED_BYTE};
|
||||
UniqueBuffer zeros = moz_xcalloc(1, 16); // Infallible allocation.
|
||||
|
||||
MOZ_ASSERT(gl->IsCurrent());
|
||||
if (target == LOCAL_GL_TEXTURE_CUBE_MAP) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
const TexImageTarget curTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
|
||||
const GLenum error = DoTexImage(mGL, curTarget.get(), 0, &dui, 1, 1, 1,
|
||||
zeros.get());
|
||||
if (error)
|
||||
MOZ_CRASH("Unexpected error during FakeBlack creation.");
|
||||
if (error) {
|
||||
const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
|
||||
"for `curTarget`: 0x%04x, "
|
||||
"`dui`: {0x%04x, 0x%04x, 0x%04x}.",
|
||||
error, curTarget.get(), dui.internalFormat,
|
||||
dui.unpackFormat, dui.unpackType);
|
||||
gfxCriticalError() << text.BeginReading();
|
||||
MOZ_CRASH("Unexpected error during cube map FakeBlack creation.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const GLenum error = DoTexImage(mGL, target.get(), 0, &dui, 1, 1, 1,
|
||||
zeros.get());
|
||||
if (error)
|
||||
if (error) {
|
||||
const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
|
||||
"for `target`: 0x%04x, "
|
||||
"`dui`: {0x%04x, 0x%04x, 0x%04x}.",
|
||||
error, target.get(), dui.internalFormat,
|
||||
dui.unpackFormat, dui.unpackType);
|
||||
gfxCriticalError() << text.BeginReading();
|
||||
MOZ_CRASH("Unexpected error during FakeBlack creation.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1088,14 +1088,19 @@ WebGLContext::LinkProgram(WebGLProgram* prog)
|
||||
|
||||
prog->LinkProgram();
|
||||
|
||||
if (prog->IsLinked()) {
|
||||
if (!prog->IsLinked()) {
|
||||
// If we failed to link, but `prog == mCurrentProgram`, we are *not* supposed to
|
||||
// null out mActiveProgramLinkInfo.
|
||||
return;
|
||||
}
|
||||
|
||||
if (prog == mCurrentProgram) {
|
||||
mActiveProgramLinkInfo = prog->LinkInfo();
|
||||
|
||||
if (gl->WorkAroundDriverBugs() &&
|
||||
gl->Vendor() == gl::GLVendor::NVIDIA)
|
||||
{
|
||||
if (mCurrentProgram == prog)
|
||||
gl->fUseProgram(prog->mGLName);
|
||||
gl->fUseProgram(prog->mGLName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1571,7 +1576,8 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
|
||||
const webgl::FormatUsageInfo* srcFormat;
|
||||
uint32_t srcWidth;
|
||||
uint32_t srcHeight;
|
||||
if (!ValidateCurFBForRead("readPixels", &srcFormat, &srcWidth, &srcHeight))
|
||||
GLenum srcMode;
|
||||
if (!ValidateCurFBForRead("readPixels", &srcFormat, &srcWidth, &srcHeight, &srcMode))
|
||||
return;
|
||||
|
||||
// Check the format and type params to assure they are an acceptable pair (as per spec)
|
||||
|
||||
@@ -911,6 +911,10 @@ WebGLContext::InitAndValidateGL()
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gl->IsSupported(gl::GLFeature::seamless_cube_map_opt_in)) {
|
||||
gl->fEnable(LOCAL_GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
}
|
||||
|
||||
// Check the shader validator pref
|
||||
mBypassShaderValidation = gfxPrefs::WebGLBypassShaderValidator();
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "GLContext.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLTimerQuery.h"
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -117,6 +118,7 @@ WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target)
|
||||
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->GL()->fEndQuery(target);
|
||||
mActiveQuery->QueueAvailablity();
|
||||
mActiveQuery = nullptr;
|
||||
}
|
||||
|
||||
@@ -139,6 +141,7 @@ WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLTimerQuery* query,
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->GL()->fQueryCounter(query->mGLName, target);
|
||||
query->mTarget = LOCAL_GL_TIMESTAMP_EXT;
|
||||
query->QueueAvailablity();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -221,7 +224,8 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
|
||||
mContext->GL()->fGetQueryObjectuiv(query->mGLName,
|
||||
LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT,
|
||||
&avail);
|
||||
retval.set(JS::BooleanValue(bool(avail)));
|
||||
bool canBeAvailable = query->CanBeAvailable() || gfxPrefs::WebGLImmediateQueries();
|
||||
retval.set(JS::BooleanValue(bool(avail) && canBeAvailable));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -238,10 +242,13 @@ WebGLExtensionDisjointTimerQuery::IsSupported(const WebGLContext* webgl)
|
||||
gl::GLContext* gl = webgl->GL();
|
||||
return gl->IsSupported(gl::GLFeature::query_objects) &&
|
||||
gl->IsSupported(gl::GLFeature::get_query_object_i64v) &&
|
||||
gl->IsSupported(gl::GLFeature::query_counter); // provides GL_TIMESTAMP
|
||||
gl->IsSupported(gl::GLFeature::query_counter) && // provides GL_TIMESTAMP
|
||||
gl->IsSupported(gl::GLFeature::sync); // provides glGetInteger64v
|
||||
// 'sync' provides glGetInteger64v either by supporting ARB_sync, GL3+, or GLES3+.
|
||||
// Since there are no differences between support for glGetInteger64v and support for
|
||||
// 'sync', we just piggy-back off of 'sync'.
|
||||
}
|
||||
|
||||
|
||||
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDisjointTimerQuery, EXT_disjoint_timer_query)
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -624,9 +624,14 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum attachment, TexImageTarget texImag
|
||||
return;
|
||||
|
||||
if (tex) {
|
||||
bool isTexture2D = tex->Target() == LOCAL_GL_TEXTURE_2D;
|
||||
bool isTexTarget2D = texImageTarget == LOCAL_GL_TEXTURE_2D;
|
||||
if (isTexture2D != isTexTarget2D) {
|
||||
if (!tex->HasEverBeenBound()) {
|
||||
mContext->ErrorInvalidOperation("framebufferTexture2D: the texture"
|
||||
" is not the name of a texture.");
|
||||
return;
|
||||
}
|
||||
|
||||
const TexTarget destTexTarget = TexImageTargetToTexTarget(texImageTarget);
|
||||
if (tex->Target() != destTexTarget) {
|
||||
mContext->ErrorInvalidOperation("framebufferTexture2D: Mismatched"
|
||||
" texture and texture target.");
|
||||
return;
|
||||
@@ -1140,7 +1145,8 @@ WebGLFramebuffer::FinalizeAttachments() const
|
||||
bool
|
||||
WebGLFramebuffer::ValidateForRead(const char* funcName,
|
||||
const webgl::FormatUsageInfo** const out_format,
|
||||
uint32_t* const out_width, uint32_t* const out_height)
|
||||
uint32_t* const out_width, uint32_t* const out_height,
|
||||
GLenum* const out_mode)
|
||||
{
|
||||
if (!ValidateAndInitAttachments(funcName))
|
||||
return false;
|
||||
@@ -1158,6 +1164,7 @@ WebGLFramebuffer::ValidateForRead(const char* funcName,
|
||||
return false;
|
||||
}
|
||||
|
||||
*out_mode = mReadBufferMode;
|
||||
*out_format = attachPoint->Format();
|
||||
attachPoint->Size(out_width, out_height);
|
||||
return true;
|
||||
|
||||
@@ -253,6 +253,10 @@ public:
|
||||
return mDepthStencilAttachment;
|
||||
}
|
||||
|
||||
void SetReadBufferMode(GLenum readBufferMode) {
|
||||
mReadBufferMode = readBufferMode;
|
||||
}
|
||||
|
||||
protected:
|
||||
WebGLFBAttachPoint* GetAttachPoint(GLenum attachment); // Fallible
|
||||
|
||||
@@ -280,7 +284,8 @@ public:
|
||||
|
||||
bool ValidateForRead(const char* info,
|
||||
const webgl::FormatUsageInfo** const out_format,
|
||||
uint32_t* const out_width, uint32_t* const out_height);
|
||||
uint32_t* const out_width, uint32_t* const out_height,
|
||||
GLenum* const out_mode);
|
||||
|
||||
JS::Value GetAttachmentParameter(const char* funcName, JSContext* cx, GLenum target,
|
||||
GLenum attachment, GLenum pname,
|
||||
|
||||
+24
-19
@@ -342,7 +342,6 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
|
||||
|
||||
webgl::LinkedProgramInfo::LinkedProgramInfo(WebGLProgram* prog)
|
||||
: prog(prog)
|
||||
, fragDataMap(nullptr)
|
||||
{ }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -569,8 +568,9 @@ WebGLProgram::GetFragDataLocation(const nsAString& userName_wide) const
|
||||
const NS_LossyConvertUTF16toASCII userName(userName_wide);
|
||||
|
||||
nsCString mappedName;
|
||||
if (!LinkInfo()->FindFragData(userName, &mappedName))
|
||||
return -1;
|
||||
if (!FindActiveOutputMappedNameByUserName(userName, &mappedName)) {
|
||||
mappedName = userName;
|
||||
}
|
||||
|
||||
gl::GLContext* gl = mContext->GL();
|
||||
gl->MakeCurrent();
|
||||
@@ -885,7 +885,7 @@ WebGLProgram::UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockB
|
||||
gl->fUniformBlockBinding(mGLName, uniformBlockIndex, uniformBlockBinding);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
WebGLProgram::LinkProgram()
|
||||
{
|
||||
mContext->InvalidateBufferFetching(); // we do it early in this function
|
||||
@@ -897,18 +897,18 @@ WebGLProgram::LinkProgram()
|
||||
if (!mVertShader || !mVertShader->IsCompiled()) {
|
||||
mLinkLog.AssignLiteral("Must have a compiled vertex shader attached.");
|
||||
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mFragShader || !mFragShader->IsCompiled()) {
|
||||
mLinkLog.AssignLiteral("Must have an compiled fragment shader attached.");
|
||||
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mFragShader->CanLinkTo(mVertShader, &mLinkLog)) {
|
||||
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
gl::GLContext* gl = mContext->gl;
|
||||
@@ -925,14 +925,14 @@ WebGLProgram::LinkProgram()
|
||||
mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on"
|
||||
" Mesa drivers to avoid crashing.");
|
||||
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Bug 1203135: Mesa crashes internally if we exceed the reported maximum attribute count.
|
||||
if (mVertShader->NumAttributes() > mContext->MaxVertexAttribs()) {
|
||||
mLinkLog.AssignLiteral("Number of attributes exceeds Mesa's reported max attribute count.");
|
||||
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,8 +954,9 @@ WebGLProgram::LinkProgram()
|
||||
&mTempMappedVaryings);
|
||||
}
|
||||
|
||||
if (LinkAndUpdate())
|
||||
return true;
|
||||
LinkAndUpdate();
|
||||
if (IsLinked())
|
||||
return;
|
||||
|
||||
// Failed link.
|
||||
if (mContext->ShouldGenerateWarnings()) {
|
||||
@@ -970,8 +971,6 @@ WebGLProgram::LinkProgram()
|
||||
mLinkLog.BeginReading());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1013,7 +1012,7 @@ WebGLProgram::ValidateProgram() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
void
|
||||
WebGLProgram::LinkAndUpdate()
|
||||
{
|
||||
mMostRecentLinkInfo = nullptr;
|
||||
@@ -1039,15 +1038,21 @@ WebGLProgram::LinkAndUpdate()
|
||||
GLint ok = 0;
|
||||
gl->fGetProgramiv(mGLName, LOCAL_GL_LINK_STATUS, &ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
return;
|
||||
|
||||
mMostRecentLinkInfo = QueryProgramInfo(this, gl);
|
||||
MOZ_RELEASE_ASSERT(mMostRecentLinkInfo);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mMostRecentLinkInfo);
|
||||
if (!mMostRecentLinkInfo)
|
||||
mLinkLog.AssignLiteral("Failed to gather program info.");
|
||||
bool
|
||||
WebGLProgram::FindActiveOutputMappedNameByUserName(const nsACString& userName,
|
||||
nsCString* const out_mappedName) const
|
||||
{
|
||||
if (mFragShader->FindActiveOutputMappedNameByUserName(userName, out_mappedName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return mMostRecentLinkInfo;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -67,7 +67,6 @@ struct LinkedProgramInfo final
|
||||
std::map<nsCString, const WebGLActiveInfo*> attribMap;
|
||||
std::map<nsCString, const WebGLActiveInfo*> uniformMap;
|
||||
std::map<nsCString, const WebGLActiveInfo*> transformFeedbackVaryingsMap;
|
||||
std::map<nsCString, const nsCString>* fragDataMap;
|
||||
|
||||
std::vector<RefPtr<UniformBlockInfo>> uniformBlocks;
|
||||
|
||||
@@ -112,17 +111,6 @@ struct LinkedProgramInfo final
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FindFragData(const nsCString& baseUserName,
|
||||
nsCString* const out_baseMappedName) const
|
||||
{
|
||||
if (!fragDataMap) {
|
||||
*out_baseMappedName = baseUserName;
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Not implemented.");
|
||||
}
|
||||
|
||||
bool HasActiveAttrib(GLuint loc) const {
|
||||
auto itr = activeAttribLocs.find(loc);
|
||||
return itr != activeAttribLocs.end();
|
||||
@@ -168,12 +156,14 @@ public:
|
||||
dom::Nullable< nsTArray<GLuint> >& retval) const;
|
||||
void UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const;
|
||||
|
||||
bool LinkProgram();
|
||||
void LinkProgram();
|
||||
bool UseProgram() const;
|
||||
void ValidateProgram() const;
|
||||
|
||||
////////////////
|
||||
|
||||
bool FindActiveOutputMappedNameByUserName(const nsACString& userName,
|
||||
nsCString* const out_mappedName) const;
|
||||
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
|
||||
nsDependentCString* const out_userName) const;
|
||||
bool FindVaryingByMappedName(const nsACString& mappedName,
|
||||
@@ -205,7 +195,7 @@ public:
|
||||
private:
|
||||
~WebGLProgram();
|
||||
|
||||
bool LinkAndUpdate();
|
||||
void LinkAndUpdate();
|
||||
|
||||
public:
|
||||
const GLuint mGLName;
|
||||
|
||||
@@ -329,6 +329,22 @@ WebGLShader::BindAttribLocation(GLuint prog, const nsCString& userName,
|
||||
mContext->gl->fBindAttribLocation(prog, index, mappedNameStr->c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLShader::FindActiveOutputMappedNameByUserName(const nsACString& userName,
|
||||
nsCString* const out_mappedName) const
|
||||
{
|
||||
if (!mValidator)
|
||||
return false;
|
||||
|
||||
const std::string userNameStr(userName.BeginReading());
|
||||
const std::string* mappedNameStr;
|
||||
if (!mValidator->FindActiveOutputMappedNameByUserName(userNameStr, &mappedNameStr))
|
||||
return false;
|
||||
|
||||
*out_mappedName = mappedNameStr->c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLShader::FindAttribUserNameByMappedName(const nsACString& mappedName,
|
||||
nsDependentCString* const out_userName) const
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
size_t CalcNumSamplerUniforms() const;
|
||||
size_t NumAttributes() const;
|
||||
void BindAttribLocation(GLuint prog, const nsCString& userName, GLuint index) const;
|
||||
bool FindActiveOutputMappedNameByUserName(const nsACString& userName,
|
||||
nsCString* const out_mappedName) const;
|
||||
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
|
||||
nsDependentCString* const out_userName) const;
|
||||
bool FindVaryingByMappedName(const nsACString& mappedName,
|
||||
|
||||
@@ -401,6 +401,21 @@ ShaderValidator::FindAttribUserNameByMappedName(const std::string& mappedName,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ShaderValidator::FindActiveOutputMappedNameByUserName(const std::string& userName,
|
||||
const std::string** const out_mappedName) const
|
||||
{
|
||||
const std::vector<sh::OutputVariable>& varibles = *ShGetOutputVariables(mHandle);
|
||||
for (auto itr = varibles.begin(); itr != varibles.end(); ++itr) {
|
||||
if (itr->name == userName) {
|
||||
*out_mappedName = &(itr->mappedName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ShaderValidator::FindAttribMappedNameByUserName(const std::string& userName,
|
||||
const std::string** const out_mappedName) const
|
||||
@@ -464,14 +479,44 @@ ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t dotPos = mappedName.find(".");
|
||||
|
||||
const std::vector<sh::InterfaceBlock>& interfaces = *ShGetInterfaceBlocks(mHandle);
|
||||
for (const auto& interface : interfaces) {
|
||||
|
||||
std::string mappedFieldName;
|
||||
const bool hasInstanceName = !interface.instanceName.empty();
|
||||
|
||||
// If the InterfaceBlock has an instanceName, all variables defined
|
||||
// within the block are qualified with the block name, as opposed
|
||||
// to being placed in the global scope.
|
||||
if (hasInstanceName) {
|
||||
|
||||
// If mappedName has no block name prefix, skip
|
||||
if (std::string::npos == dotPos)
|
||||
continue;
|
||||
|
||||
// If mappedName has a block name prefix that doesn't match, skip
|
||||
const std::string mappedInterfaceBlockName = mappedName.substr(0, dotPos);
|
||||
if (interface.mappedName != mappedInterfaceBlockName)
|
||||
continue;
|
||||
|
||||
mappedFieldName = mappedName.substr(dotPos + 1);
|
||||
} else {
|
||||
mappedFieldName = mappedName;
|
||||
}
|
||||
|
||||
for (const auto& field : interface.fields) {
|
||||
const sh::ShaderVariable* found;
|
||||
|
||||
if (!field.findInfoByMappedName(mappedName, &found, out_userName))
|
||||
if (!field.findInfoByMappedName(mappedFieldName, &found, out_userName))
|
||||
continue;
|
||||
|
||||
if (hasInstanceName) {
|
||||
// Prepend the user name of the interface that matched
|
||||
*out_userName = interface.name + "." + *out_userName;
|
||||
}
|
||||
|
||||
*out_isArray = found->isArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ public:
|
||||
bool FindAttribUserNameByMappedName(const std::string& mappedName,
|
||||
const std::string** const out_userName) const;
|
||||
|
||||
bool FindActiveOutputMappedNameByUserName(const std::string& userName,
|
||||
const std::string** const out_mappedName) const;
|
||||
|
||||
bool FindAttribMappedNameByUserName(const std::string& userName,
|
||||
const std::string** const out_mappedName) const;
|
||||
|
||||
|
||||
@@ -1719,10 +1719,21 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal
|
||||
const webgl::FormatUsageInfo* srcUsage;
|
||||
uint32_t srcWidth;
|
||||
uint32_t srcHeight;
|
||||
if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight))
|
||||
GLenum srcMode;
|
||||
if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight,
|
||||
&srcMode))
|
||||
return;
|
||||
auto srcFormat = srcUsage->format;
|
||||
|
||||
// GLES 3.0.4 p145:
|
||||
// "Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
|
||||
// INVALID_OPERATION error if any of the following conditions is true: READ_BUFFER
|
||||
// is NONE"
|
||||
if (srcMode == LOCAL_GL_NONE) {
|
||||
mContext->ErrorInvalidOperation("%s: READ_BUFFER is NONE. ", funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Check that source and dest info are compatible
|
||||
|
||||
@@ -1869,10 +1880,21 @@ WebGLTexture::CopyTexSubImage(const char* funcName, TexImageTarget target, GLint
|
||||
const webgl::FormatUsageInfo* srcUsage;
|
||||
uint32_t srcWidth;
|
||||
uint32_t srcHeight;
|
||||
if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight))
|
||||
GLenum srcMode;
|
||||
if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight,
|
||||
&srcMode))
|
||||
return;
|
||||
auto srcFormat = srcUsage->format;
|
||||
|
||||
// GLES 3.0.4 p145:
|
||||
// "Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
|
||||
// INVALID_OPERATION error if any of the following conditions is true: READ_BUFFER
|
||||
// is NONE"
|
||||
if (srcMode == LOCAL_GL_NONE) {
|
||||
mContext->ErrorInvalidOperation("%s: READ_BUFFER is NONE. ", funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Check that source and dest info are compatible
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -23,6 +24,7 @@ WebGLTimerQuery::WebGLTimerQuery(WebGLContext* webgl, GLuint name)
|
||||
: WebGLContextBoundObject(webgl)
|
||||
, mGLName(name)
|
||||
, mTarget(LOCAL_GL_NONE)
|
||||
, mCanBeAvailable(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -53,6 +55,12 @@ WebGLTimerQuery::GetParentObject() const
|
||||
return mContext;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTimerQuery::QueueAvailablity()
|
||||
{
|
||||
RefPtr<WebGLTimerQuery> self = this;
|
||||
NS_DispatchToCurrentThread(NS_NewRunnableFunction([self] { self->mCanBeAvailable = true; }));
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTimerQuery)
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ public:
|
||||
void Delete();
|
||||
|
||||
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
|
||||
bool CanBeAvailable() const { return mCanBeAvailable; }
|
||||
void QueueAvailablity();
|
||||
GLenum Target() const { return mTarget; }
|
||||
|
||||
WebGLContext* GetParentObject() const;
|
||||
@@ -41,6 +43,7 @@ private:
|
||||
~WebGLTimerQuery();
|
||||
|
||||
GLenum mTarget;
|
||||
bool mCanBeAvailable;
|
||||
|
||||
friend class WebGLExtensionDisjointTimerQuery;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_color_buffer_half_float.html]
|
||||
fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_disjoint_timer_query.html]
|
||||
fail-if = (os == 'android') || (os == 'mac') || (os == 'win' && (os_version == '5.1' || os_version == '6.1'))
|
||||
fail-if = (os == 'android') || (os == 'mac') || (os == 'win')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_frag_depth.html]
|
||||
fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_sRGB.html]
|
||||
|
||||
@@ -340,7 +340,6 @@ CloneData(JSContext* aCx, CryptoBuffer& aDst, JS::Handle<JSObject*> aSrc)
|
||||
void
|
||||
WebCryptoTask::DispatchWithPromise(Promise* aResultPromise)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mResultPromise = aResultPromise;
|
||||
|
||||
// Fail if an error was set during the constructor
|
||||
@@ -357,13 +356,6 @@ WebCryptoTask::DispatchWithPromise(Promise* aResultPromise)
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure that NSS is initialized, since presumably CalculateResult
|
||||
// will use NSS functions
|
||||
if (!EnsureNSSInitializedChromeOrContent()) {
|
||||
mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
MAYBE_EARLY_FAIL(mEarlyRv)
|
||||
}
|
||||
|
||||
// Store calling thread and dispatch to thread pool.
|
||||
mOriginalThread = NS_GetCurrentThread();
|
||||
mEarlyRv = WebCryptoThreadPool::Dispatch(this);
|
||||
@@ -2316,16 +2308,10 @@ private:
|
||||
};
|
||||
|
||||
GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
|
||||
JSContext* aCx, const ObjectOrString& aAlgorithm, bool aExtractable,
|
||||
const Sequence<nsString>& aKeyUsages)
|
||||
nsIGlobalObject* aGlobal, JSContext* aCx, const ObjectOrString& aAlgorithm,
|
||||
bool aExtractable, const Sequence<nsString>& aKeyUsages)
|
||||
: mKeyPair(new CryptoKeyPair())
|
||||
{
|
||||
nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
if (!global) {
|
||||
mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
mArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!mArena) {
|
||||
mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
@@ -2333,8 +2319,8 @@ GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
|
||||
}
|
||||
|
||||
// Create an empty key pair and set easy attributes
|
||||
mKeyPair->mPrivateKey = new CryptoKey(global);
|
||||
mKeyPair->mPublicKey = new CryptoKey(global);
|
||||
mKeyPair->mPrivateKey = new CryptoKey(aGlobal);
|
||||
mKeyPair->mPublicKey = new CryptoKey(aGlobal);
|
||||
|
||||
// Extract algorithm name
|
||||
mEarlyRv = GetAlgorithmName(aCx, aAlgorithm, mAlgName);
|
||||
@@ -3420,7 +3406,8 @@ WebCryptoTask::CreateGenerateKeyTask(nsIGlobalObject* aGlobal,
|
||||
algName.EqualsASCII(WEBCRYPTO_ALG_ECDH) ||
|
||||
algName.EqualsASCII(WEBCRYPTO_ALG_ECDSA) ||
|
||||
algName.EqualsASCII(WEBCRYPTO_ALG_DH)) {
|
||||
return new GenerateAsymmetricKeyTask(aCx, aAlgorithm, aExtractable, aKeyUsages);
|
||||
return new GenerateAsymmetricKeyTask(aGlobal, aCx, aAlgorithm, aExtractable,
|
||||
aKeyUsages);
|
||||
} else {
|
||||
return new FailureTask(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ private:
|
||||
class GenerateAsymmetricKeyTask : public WebCryptoTask
|
||||
{
|
||||
public:
|
||||
GenerateAsymmetricKeyTask(JSContext* aCx,
|
||||
GenerateAsymmetricKeyTask(nsIGlobalObject* aGlobal, JSContext* aCx,
|
||||
const ObjectOrString& aAlgorithm, bool aExtractable,
|
||||
const Sequence<nsString>& aKeyUsages);
|
||||
protected:
|
||||
|
||||
@@ -65,6 +65,8 @@ WebCryptoThreadPool::DispatchInternal(nsIRunnable* aRunnable)
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (!mPool) {
|
||||
NS_ENSURE_TRUE(EnsureNSSInitializedChromeOrContent(), NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIThreadPool> pool(do_CreateInstance(NS_THREADPOOL_CONTRACTID));
|
||||
NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE);
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static const char* labelsEncodings[][3] = {
|
||||
static const nsUConvProp labelsEncodings[] = {
|
||||
#include "labelsencodings.properties.h"
|
||||
};
|
||||
|
||||
static const char* encodingsGroups[][3] = {
|
||||
static const nsUConvProp encodingsGroups[] = {
|
||||
#include "encodingsgroups.properties.h"
|
||||
};
|
||||
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static const char* localesFallbacks[][3] = {
|
||||
static const nsUConvProp localesFallbacks[] = {
|
||||
#include "localesfallbacks.properties.h"
|
||||
};
|
||||
|
||||
static const char* domainsFallbacks[][3] = {
|
||||
static const nsUConvProp domainsFallbacks[] = {
|
||||
#include "domainsfallbacks.properties.h"
|
||||
};
|
||||
|
||||
static const char* nonParticipatingDomains[][3] = {
|
||||
static const nsUConvProp nonParticipatingDomains[] = {
|
||||
#include "nonparticipatingdomains.properties.h"
|
||||
};
|
||||
|
||||
|
||||
@@ -13,28 +13,10 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
void
|
||||
TextEncoder::Init(const nsAString& aEncoding, ErrorResult& aRv)
|
||||
TextEncoder::Init()
|
||||
{
|
||||
nsAutoString label(aEncoding);
|
||||
EncodingUtils::TrimSpaceCharacters(label);
|
||||
|
||||
// Let encoding be the result of getting an encoding from label.
|
||||
// If encoding is failure, or is none of utf-8, utf-16, and utf-16be,
|
||||
// throw a RangeError (https://encoding.spec.whatwg.org/#dom-textencoder).
|
||||
if (!EncodingUtils::FindEncodingForLabel(label, mEncoding)) {
|
||||
aRv.ThrowRangeError<MSG_ENCODING_NOT_SUPPORTED>(label);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mEncoding.EqualsLiteral("UTF-8") &&
|
||||
!mEncoding.EqualsLiteral("UTF-16LE") &&
|
||||
!mEncoding.EqualsLiteral("UTF-16BE")) {
|
||||
aRv.ThrowRangeError<MSG_DOM_ENCODING_NOT_UTF>();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create an encoder object for mEncoding.
|
||||
mEncoder = EncodingUtils::EncoderForEncoding(mEncoding);
|
||||
// Create an encoder object for utf-8.
|
||||
mEncoder = EncodingUtils::EncoderForEncoding(NS_LITERAL_CSTRING("UTF-8"));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -92,8 +74,7 @@ TextEncoder::Encode(JSContext* aCx,
|
||||
void
|
||||
TextEncoder::GetEncoding(nsAString& aEncoding)
|
||||
{
|
||||
CopyASCIItoUTF16(mEncoding, aEncoding);
|
||||
nsContentUtils::ASCIIToLower(aEncoding);
|
||||
aEncoding.AssignLiteral("utf-8");
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -24,14 +24,10 @@ public:
|
||||
|
||||
static TextEncoder*
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aEncoding,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsAutoPtr<TextEncoder> txtEncoder(new TextEncoder());
|
||||
txtEncoder->Init(aEncoding, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
txtEncoder->Init();
|
||||
return txtEncoder.forget();
|
||||
}
|
||||
|
||||
@@ -50,16 +46,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Validates provided encoding and throws an exception if invalid encoding.
|
||||
* If no encoding is provided then mEncoding is default initialised to "utf-8".
|
||||
*
|
||||
* @param aEncoding Optional encoding (case insensitive) provided.
|
||||
* (valid values are "utf-8", "utf-16", "utf-16be")
|
||||
* Default value is "utf-8" if no encoding is provided.
|
||||
* @return aRv EncodingError exception else null.
|
||||
*/
|
||||
void Init(const nsAString& aEncoding, ErrorResult& aRv);
|
||||
void Init();
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -70,7 +57,7 @@ public:
|
||||
void GetEncoding(nsAString& aEncoding);
|
||||
|
||||
/**
|
||||
* Encodes incoming utf-16 code units/ DOM string to the requested encoding.
|
||||
* Encodes incoming utf-16 code units/ DOM string to utf-8.
|
||||
*
|
||||
* @param aCx Javascript context.
|
||||
* @param aObj the wrapper of the TextEncoder
|
||||
@@ -84,7 +71,6 @@ public:
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
private:
|
||||
nsCString mEncoding;
|
||||
nsCOMPtr<nsIUnicodeEncoder> mEncoder;
|
||||
};
|
||||
|
||||
|
||||
@@ -199,6 +199,7 @@ x-euc-jp=EUC-JP
|
||||
csiso2022jp=ISO-2022-JP
|
||||
iso-2022-jp=ISO-2022-JP
|
||||
csshiftjis=Shift_JIS
|
||||
ms932=Shift_JIS
|
||||
ms_kanji=Shift_JIS
|
||||
shift-jis=Shift_JIS
|
||||
shift_jis=Shift_JIS
|
||||
|
||||
@@ -359,7 +359,7 @@ function testDecoderGetEncoding()
|
||||
{encoding: "big5", labels: ["big5", "cn-big5", "csbig5", "x-x-big5", "big5-hkscs"]},
|
||||
{encoding: "euc-jp", labels: ["cseucpkdfmtjapanese", "euc-jp", "x-euc-jp"]},
|
||||
{encoding: "iso-2022-jp", labels: ["csiso2022jp", "iso-2022-jp"]},
|
||||
{encoding: "shift_jis", labels: ["csshiftjis", "ms_kanji", "shift-jis", "shift_jis", "sjis", "windows-31j", "x-sjis"]},
|
||||
{encoding: "shift_jis", labels: ["csshiftjis", "ms932", "ms_kanji", "shift-jis", "shift_jis", "sjis", "windows-31j", "x-sjis"]},
|
||||
{encoding: "euc-kr", labels: ["cseuckr", "csksc56011987", "euc-kr", "iso-ir-149", "korean", "ks_c_5601-1987", "ks_c_5601-1989", "ksc5601", "ksc_5601", "windows-949"]},
|
||||
{encoding: "utf-16le", labels: ["utf-16", "utf-16le"]},
|
||||
{encoding: "utf-16be", labels: ["utf-16be"]},
|
||||
|
||||
@@ -4,6 +4,15 @@
|
||||
*/
|
||||
|
||||
function runTextEncoderTests()
|
||||
{
|
||||
test(testEncoderEncode, "testEncoderEncode");
|
||||
test(testEncoderGetEncoding, "testEncoderGetEncoding");
|
||||
test(testInvalidSequence, "testInvalidSequence");
|
||||
test(testInputString, "testInputString");
|
||||
test(testStreamingOptions, "testStreamingOptions");
|
||||
}
|
||||
|
||||
function testEncoderEncode()
|
||||
{
|
||||
var data = "\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09"
|
||||
+ "\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14"
|
||||
@@ -46,19 +55,9 @@ function runTextEncoderTests()
|
||||
0xB9, 0x98, 0xE0, 0xB9, 0x99, 0xE0, 0xB9, 0x9A, 0xE0,
|
||||
0xB9, 0x9B];
|
||||
|
||||
test(testEncoderGetEncoding, "testEncoderGetEncoding");
|
||||
test(testInvalidSequence, "testInvalidSequence");
|
||||
test(testEncodeUTF16ToUTF16, "testEncodeUTF16ToUTF16");
|
||||
test(function() {
|
||||
testConstructorEncodingOption(data, expectedString)
|
||||
}, "testConstructorEncodingOption");
|
||||
test(function() {
|
||||
testEncodingValues(data, expectedString)
|
||||
}, "testEncodingValues");
|
||||
test(function() {
|
||||
testInputString(data, expectedString)
|
||||
}, "testInputString");
|
||||
test(testStreamingOptions, "testStreamingOptions");
|
||||
// valid encoding passed
|
||||
testSingleString({input: data, expected: expectedString,
|
||||
msg: "testing encoding with valid utf-8 encoding."});
|
||||
}
|
||||
|
||||
function testInvalidSequence()
|
||||
@@ -68,77 +67,18 @@ function testInvalidSequence()
|
||||
0xE0, 0xB9, 0x85];
|
||||
|
||||
//Test null input string
|
||||
testSingleString({encoding: "utf-8", input: data, expected: expectedString,
|
||||
testSingleString({input: data, expected: expectedString,
|
||||
msg: "encoder with replacement character test."});
|
||||
}
|
||||
|
||||
function testEncodeUTF16ToUTF16()
|
||||
{
|
||||
var data = "\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c"
|
||||
+ "\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56"
|
||||
+ "\u0e57\u0e58\u0e59\u0e5a\u0e5b";
|
||||
|
||||
var expected = [0x43, 0x0E, 0x44, 0x0E, 0x45, 0x0E, 0x46, 0x0E, 0x47, 0x0E,
|
||||
0x48, 0x0E, 0x49, 0x0E, 0x4A, 0x0E, 0x4B, 0x0E, 0x4C, 0x0E,
|
||||
0x4D, 0x0E, 0x4E, 0x0E, 0x4F, 0x0E, 0x50, 0x0E, 0x51, 0x0E,
|
||||
0x52, 0x0E, 0x53, 0x0E, 0x54, 0x0E, 0x55, 0x0E, 0x56, 0x0E,
|
||||
0x57, 0x0E, 0x58, 0x0E, 0x59, 0x0E, 0x5A, 0x0E, 0x5B, 0x0E];
|
||||
|
||||
testSingleString({encoding: "Utf-16", input: data, expected: expected,
|
||||
msg: "testing encoding from utf-16 to utf-16 zero."});
|
||||
}
|
||||
|
||||
function testConstructorEncodingOption(aData, aExpectedString)
|
||||
{
|
||||
function errorMessage(encoding) {
|
||||
return `The given encoding '${String(encoding).trim()}' is not supported.`;
|
||||
}
|
||||
|
||||
// valid encoding passed
|
||||
var encoding = "UTF-8";
|
||||
testSingleString({encoding: encoding, input: aData, expected: aExpectedString,
|
||||
msg: "testing encoding with valid utf-8 encoding."});
|
||||
|
||||
// passing spaces for encoding
|
||||
encoding = " ";
|
||||
testSingleString({encoding: encoding, input: aData, error: "RangeError",
|
||||
errorMessage: errorMessage(encoding),
|
||||
msg: "constructor encoding, spaces encoding test."});
|
||||
|
||||
// invalid encoding passed
|
||||
encoding = "asdfasdf";
|
||||
testSingleString({encoding: encoding, input: aData, error: "RangeError",
|
||||
errorMessage: errorMessage(encoding),
|
||||
msg: "constructor encoding, invalid encoding test."});
|
||||
|
||||
// null encoding passed
|
||||
encoding = null;
|
||||
testSingleString({encoding: encoding, input: aData, error: "RangeError",
|
||||
errorMessage: errorMessage(encoding),
|
||||
msg: "constructor encoding, \"null\" encoding test."});
|
||||
|
||||
// empty encoding passed
|
||||
encoding = "";
|
||||
testSingleString({encoding: encoding, input: aData, error: "RangeError",
|
||||
errorMessage: errorMessage(encoding),
|
||||
msg: "constructor encoding, empty encoding test."});
|
||||
}
|
||||
|
||||
function testEncodingValues(aData, aExpectedString)
|
||||
{
|
||||
var encoding = "ISO-8859-11";
|
||||
testSingleString({encoding: aData, input: encoding, error: "RangeError",
|
||||
msg: "encoder encoding values test."});
|
||||
}
|
||||
|
||||
function testInputString(aData, aExpectedString)
|
||||
function testInputString()
|
||||
{
|
||||
//Test null input string
|
||||
testSingleString({encoding: "utf-8", input: "", expected: [],
|
||||
testSingleString({input: "", expected: [],
|
||||
msg: "encoder null input string test."});
|
||||
|
||||
//Test spaces as input string
|
||||
testSingleString({encoding: "utf-8", input: " ", expected: [32, 32],
|
||||
testSingleString({input: " ", expected: [32, 32],
|
||||
msg: "spaces as input string."});
|
||||
}
|
||||
|
||||
@@ -147,7 +87,7 @@ function testSingleString(test)
|
||||
var outText;
|
||||
try {
|
||||
var stream = test.stream ? {stream: true} : null;
|
||||
outText = (new TextEncoder(test.encoding)).encode(test.input, stream);
|
||||
outText = (new TextEncoder()).encode(test.input, stream);
|
||||
} catch (e) {
|
||||
assert_equals(e.name, test.error, test.msg + " error thrown from the constructor.");
|
||||
if (test.errorMessage) {
|
||||
@@ -223,13 +163,9 @@ function testStreamingOptions()
|
||||
0xE0, 0xB9, 0x98, 0xE0, 0xB9, 0x99, 0xE0, 0xB9, 0x9A,
|
||||
0xE0, 0xB9, 0x9B]];
|
||||
|
||||
var expectedUTF16 = data.map(function(d) {
|
||||
return new Uint8Array(new Uint16Array(arrayFromString(d)).buffer);
|
||||
});
|
||||
|
||||
// STREAMING TEST ONE: test streaming three valid strings with stream option
|
||||
// set to true for all three.
|
||||
testArrayOfStrings({encoding: "utf-8", array: [
|
||||
testArrayOfStrings({array: [
|
||||
{input: data[0], stream: true, expected: expected[0]},
|
||||
{input: data[1], stream: true, expected: expected[1]},
|
||||
{input: data[2], stream: true, expected: expected[2]},
|
||||
@@ -238,10 +174,10 @@ function testStreamingOptions()
|
||||
// STREAMING TEST TWO: test streaming valid strings with stream option
|
||||
// streaming option: false from constructor, string 1 stream: true,
|
||||
// string 2 stream: false, string 3 stream: false
|
||||
testArrayOfStrings({encoding: "utf-16", array: [
|
||||
{input: data[0], stream: true, expected: expectedUTF16[0]},
|
||||
{input: data[1], expected: expectedUTF16[1]},
|
||||
{input: data[2], expected: expectedUTF16[2]},
|
||||
testArrayOfStrings({array: [
|
||||
{input: data[0], stream: true, expected: expected[0]},
|
||||
{input: data[1], expected: expected[1]},
|
||||
{input: data[2], expected: expected[2]},
|
||||
], msg: "streaming test two."});
|
||||
}
|
||||
|
||||
@@ -253,7 +189,7 @@ function testArrayOfStrings(test)
|
||||
{
|
||||
var encoder;
|
||||
try {
|
||||
encoder = new TextEncoder(test.encoding);
|
||||
encoder = new TextEncoder();
|
||||
} catch (e) {
|
||||
assert_equals(e.name, test.error, test.msg);
|
||||
return;
|
||||
@@ -278,16 +214,6 @@ function testArrayOfStrings(test)
|
||||
|
||||
function testEncoderGetEncoding()
|
||||
{
|
||||
var labelEncodings = [
|
||||
{encoding: "utf-8", labels: ["unicode-1-1-utf-8", "utf-8", "utf8"]},
|
||||
{encoding: "utf-16le", labels: ["utf-16", "utf-16"]},
|
||||
{encoding: "utf-16be", labels: ["utf-16be"]},
|
||||
];
|
||||
|
||||
for (var le of labelEncodings) {
|
||||
for (var label of le.labels) {
|
||||
var encoder = new TextEncoder(label);
|
||||
assert_equals(encoder.encoding, le.encoding, label + " label encoding test.");
|
||||
}
|
||||
}
|
||||
var encoder = new TextEncoder();
|
||||
assert_equals(encoder.encoding, "utf-8", "TextEncoder encoding test.");
|
||||
}
|
||||
|
||||
@@ -133,7 +133,17 @@ test(
|
||||
function () {
|
||||
["utf-8", "utf-16le", "utf-16be"].forEach(function (encoding) {
|
||||
var string = "\x00123ABCabc\x80\xFF\u0100\u1000\uFFFD\uD800\uDC00\uDBFF\uDFFF";
|
||||
var encoded = new TextEncoder(encoding).encode(string);
|
||||
var octets = {
|
||||
"utf-16le": [0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42,0x00,
|
||||
0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF,0x00,
|
||||
0x00,0x01,0x00,0x10,0xFD,0xFF,0x00,0xD8,0x00,0xDC,0xFF,0xDB,
|
||||
0xFF,0xDF],
|
||||
"utf-16be": [0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42,
|
||||
0x00,0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF,
|
||||
0x01,0x00,0x10,0x00,0xFF,0xFD,0xD8,0x00,0xDC,0x00,0xDB,0xFF,
|
||||
0xDF,0xFF]
|
||||
};
|
||||
var encoded = octets[encoding] || new TextEncoder(encoding).encode(string);
|
||||
|
||||
for (var len = 1; len <= 5; ++len) {
|
||||
var out = "", decoder = new TextDecoder(encoding);
|
||||
@@ -204,19 +214,12 @@ test(
|
||||
test(
|
||||
function () {
|
||||
|
||||
var utf_encodings = ["utf-8", "utf-16le", "utf-16be"];
|
||||
var encodings = ["utf-8", "ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "x-user-defined", "utf-16le", "utf-16be"];
|
||||
|
||||
var legacy_encodings = ["ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "x-user-defined"];
|
||||
|
||||
utf_encodings.forEach(function(encoding) {
|
||||
encodings.forEach(function(encoding) {
|
||||
assert_equals(new TextDecoder(encoding).encoding, encoding);
|
||||
assert_equals(new TextEncoder(encoding).encoding, encoding);
|
||||
});
|
||||
|
||||
legacy_encodings.forEach(function(encoding) {
|
||||
assert_equals(new TextDecoder(encoding).encoding, encoding);
|
||||
assert_throws({name: 'RangeError'}, function() { new TextEncoder(encoding); });
|
||||
assert_equals(new TextEncoder(encoding).encoding, "utf-8");
|
||||
});
|
||||
},
|
||||
"Non-UTF encodings supported only for decode, not encode"
|
||||
"Non-UTF-8 encodings supported only for decode, not encode"
|
||||
);
|
||||
|
||||
@@ -42,6 +42,28 @@ function encode_utf8(string) {
|
||||
return octets;
|
||||
}
|
||||
|
||||
function encode_utf16le(string) {
|
||||
var octets = new Uint8Array(string.length * 2);
|
||||
var di = 0;
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
var code = string.charCodeAt(i);
|
||||
octets[di++] = code & 0xFF;
|
||||
octets[di++] = code >> 8;
|
||||
}
|
||||
return octets;
|
||||
}
|
||||
|
||||
function encode_utf16be(string) {
|
||||
var octets = new Uint8Array(string.length * 2);
|
||||
var di = 0;
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
var code = string.charCodeAt(i);
|
||||
octets[di++] = code >> 8;
|
||||
octets[di++] = code & 0xFF;
|
||||
}
|
||||
return octets;
|
||||
}
|
||||
|
||||
function decode_utf8(octets) {
|
||||
var utf8 = String.fromCharCode.apply(null, octets);
|
||||
return decodeURIComponent(escape(utf8));
|
||||
@@ -94,13 +116,11 @@ function test_utf_roundtrip () {
|
||||
|
||||
var block, block_tag, i, j, encoded, decoded, exp_encoded, exp_decoded;
|
||||
|
||||
var TE_U16LE = new TextEncoder("UTF-16LE");
|
||||
var TD_U16LE = new TextDecoder("UTF-16LE");
|
||||
|
||||
var TE_U16BE = new TextEncoder("UTF-16BE");
|
||||
var TD_U16BE = new TextDecoder("UTF-16BE");
|
||||
|
||||
var TE_U8 = new TextEncoder("UTF-8");
|
||||
var TE_U8 = new TextEncoder();
|
||||
var TD_U8 = new TextDecoder("UTF-8");
|
||||
|
||||
for (i = MIN_CODEPOINT; i < MAX_CODEPOINT; i += BLOCK_SIZE) {
|
||||
@@ -108,11 +128,11 @@ function test_utf_roundtrip () {
|
||||
block = genblock(i, BLOCK_SIZE);
|
||||
|
||||
// test UTF-16LE, UTF-16BE, and UTF-8 encodings against themselves
|
||||
encoded = TE_U16LE.encode(block);
|
||||
encoded = encode_utf16le(block);
|
||||
decoded = TD_U16LE.decode(encoded);
|
||||
assert_string_equals(block, decoded, "UTF-16LE round trip " + block_tag);
|
||||
|
||||
encoded = TE_U16BE.encode(block);
|
||||
encoded = encode_utf16be(block);
|
||||
decoded = TD_U16BE.decode(encoded);
|
||||
assert_string_equals(block, decoded, "UTF-16BE round trip " + block_tag);
|
||||
|
||||
@@ -145,12 +165,12 @@ function test_utf_samples () {
|
||||
expected: [0x00, 0x7A, 0x00, 0xA2, 0x6C, 0x34, 0xD8, 0x34, 0xDD, 0x1E, 0xDB, 0xFF, 0xDF, 0xFD] }
|
||||
];
|
||||
|
||||
var encoded = new TextEncoder().encode(sample);
|
||||
assert_array_equals(encoded, cases[0].expected,
|
||||
"expected equal encodings");
|
||||
|
||||
cases.forEach(
|
||||
function(t) {
|
||||
var encoded = new TextEncoder(t.encoding).encode(sample);
|
||||
assert_array_equals(encoded, t.expected,
|
||||
"expected equal encodings - " + t.encoding);
|
||||
|
||||
var decoded = new TextDecoder(t.encoding)
|
||||
.decode(new Uint8Array(t.expected));
|
||||
assert_equals(decoded, sample,
|
||||
|
||||
@@ -34,6 +34,22 @@ DeviceMotionEvent::InitDeviceMotionEvent(
|
||||
const DeviceAccelerationInit& aAccelIncludingGravity,
|
||||
const DeviceRotationRateInit& aRotationRate,
|
||||
Nullable<double> aInterval)
|
||||
{
|
||||
InitDeviceMotionEvent(aType, aCanBubble, aCancelable, aAcceleration,
|
||||
aAccelIncludingGravity, aRotationRate, aInterval,
|
||||
Nullable<uint64_t>());
|
||||
}
|
||||
|
||||
void
|
||||
DeviceMotionEvent::InitDeviceMotionEvent(
|
||||
const nsAString& aType,
|
||||
bool aCanBubble,
|
||||
bool aCancelable,
|
||||
const DeviceAccelerationInit& aAcceleration,
|
||||
const DeviceAccelerationInit& aAccelIncludingGravity,
|
||||
const DeviceRotationRateInit& aRotationRate,
|
||||
Nullable<double> aInterval,
|
||||
Nullable<uint64_t> aTimeStamp)
|
||||
{
|
||||
Event::InitEvent(aType, aCanBubble, aCancelable);
|
||||
|
||||
@@ -50,6 +66,9 @@ DeviceMotionEvent::InitDeviceMotionEvent(
|
||||
aRotationRate.mBeta,
|
||||
aRotationRate.mGamma);
|
||||
mInterval = aInterval;
|
||||
if (!aTimeStamp.IsNull()) {
|
||||
mEvent->mTime = aTimeStamp.Value();
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DeviceMotionEvent>
|
||||
@@ -141,7 +160,7 @@ using namespace mozilla::dom;
|
||||
already_AddRefed<DeviceMotionEvent>
|
||||
NS_NewDOMDeviceMotionEvent(EventTarget* aOwner,
|
||||
nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent)
|
||||
WidgetEvent* aEvent)
|
||||
{
|
||||
RefPtr<DeviceMotionEvent> it =
|
||||
new DeviceMotionEvent(aOwner, aPresContext, aEvent);
|
||||
|
||||
@@ -130,6 +130,16 @@ public:
|
||||
const DeviceRotationRateInit& aRotationRate,
|
||||
Nullable<double> aInterval);
|
||||
|
||||
void InitDeviceMotionEvent(
|
||||
const nsAString& aType,
|
||||
bool aCanBubble,
|
||||
bool aCancelable,
|
||||
const DeviceAccelerationInit& aAcceleration,
|
||||
const DeviceAccelerationInit& aAccelerationIncludingGravity,
|
||||
const DeviceRotationRateInit& aRotationRate,
|
||||
Nullable<double> aInterval,
|
||||
Nullable<uint64_t> aTimeStamp);
|
||||
|
||||
static already_AddRefed<DeviceMotionEvent>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
|
||||
@@ -12,7 +12,17 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "AnimationEvent.h"
|
||||
#include "BeforeAfterKeyboardEvent.h"
|
||||
#include "BeforeUnloadEvent.h"
|
||||
#include "ClipboardEvent.h"
|
||||
#include "CommandEvent.h"
|
||||
#include "CompositionEvent.h"
|
||||
#include "DataContainerEvent.h"
|
||||
#include "DeviceMotionEvent.h"
|
||||
#include "DragEvent.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "KeyboardEvent.h"
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "mozilla/dom/CloseEvent.h"
|
||||
#include "mozilla/dom/CustomEvent.h"
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsDOMCID.h"
|
||||
#include "nsError.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@@ -1197,15 +1196,14 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||
|
||||
// Maybe add a marker to the docshell's timeline, but only
|
||||
// bother with all the logic if some docshell is recording.
|
||||
nsDocShell* docShell;
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
|
||||
bool needsEndEventMarker = false;
|
||||
|
||||
if (mIsMainThreadELM &&
|
||||
listener->mListenerType != Listener::eNativeListener) {
|
||||
nsCOMPtr<nsIDocShell> docShellComPtr = GetDocShellForTarget();
|
||||
if (docShellComPtr) {
|
||||
docShell = static_cast<nsDocShell*>(docShellComPtr.get());
|
||||
docShell = GetDocShellForTarget();
|
||||
if (docShell) {
|
||||
if (timelines && timelines->HasConsumer(docShell)) {
|
||||
needsEndEventMarker = true;
|
||||
nsAutoString typeStr;
|
||||
|
||||
@@ -23,7 +23,7 @@ class nsIMutableArray;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class EventTarget;
|
||||
};
|
||||
} // namespace dom
|
||||
|
||||
template<typename T>
|
||||
class Maybe;
|
||||
|
||||
@@ -740,10 +740,11 @@ IMEContentObserver::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
|
||||
mIsHandlingQueryContentEvent = true;
|
||||
ContentEventHandler handler(GetPresContext());
|
||||
nsresult rv = handler.HandleQueryContentEvent(aEvent);
|
||||
if (aEvent->mSucceeded) {
|
||||
// We need to guarantee that mRootContent should be always same value for
|
||||
// the observing editor.
|
||||
aEvent->mReply.mContentsRoot = mRootContent;
|
||||
|
||||
if (!IsInitializedWithPlugin() &&
|
||||
NS_WARN_IF(aEvent->mReply.mContentsRoot != mRootContent)) {
|
||||
// Focus has changed unexpectedly, so make the query fail.
|
||||
aEvent->mSucceeded = false;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -1263,7 +1264,8 @@ IMEContentObserver::UpdateSelectionCache()
|
||||
WidgetQueryContentEvent selection(true, eQuerySelectedText, mWidget);
|
||||
ContentEventHandler handler(GetPresContext());
|
||||
handler.OnQuerySelectedText(&selection);
|
||||
if (NS_WARN_IF(!selection.mSucceeded)) {
|
||||
if (NS_WARN_IF(!selection.mSucceeded) ||
|
||||
NS_WARN_IF(selection.mReply.mContentsRoot != mRootContent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1404,7 +1406,8 @@ IMEContentObserver::TryToFlushPendingNotifications()
|
||||
MOZ_LOG(sIMECOLog, LogLevel::Debug,
|
||||
("IMECO: 0x%p IMEContentObserver::TryToFlushPendingNotifications(), "
|
||||
"performing queued IMENotificationSender forcibly", this));
|
||||
mQueuedSender->Run();
|
||||
RefPtr<IMENotificationSender> queuedSender = mQueuedSender;
|
||||
queuedSender->Run();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -1549,12 +1552,18 @@ IMEContentObserver::IMENotificationSender::Run()
|
||||
|
||||
// If notifications caused some new change, we should notify them now.
|
||||
if (mIMEContentObserver->NeedsToNotifyIMEOfSomething()) {
|
||||
MOZ_LOG(sIMECOLog, LogLevel::Debug,
|
||||
("IMECO: 0x%p IMEContentObserver::IMENotificationSender::Run(), "
|
||||
"posting IMENotificationSender to current thread", this));
|
||||
mIMEContentObserver->mQueuedSender =
|
||||
new IMENotificationSender(mIMEContentObserver);
|
||||
NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender);
|
||||
if (mIMEContentObserver->GetState() == eState_StoppedObserving) {
|
||||
MOZ_LOG(sIMECOLog, LogLevel::Debug,
|
||||
("IMECO: 0x%p IMEContentObserver::IMENotificationSender::Run(), "
|
||||
"waiting IMENotificationSender to be reinitialized", this));
|
||||
} else {
|
||||
MOZ_LOG(sIMECOLog, LogLevel::Debug,
|
||||
("IMECO: 0x%p IMEContentObserver::IMENotificationSender::Run(), "
|
||||
"posting IMENotificationSender to current thread", this));
|
||||
mIMEContentObserver->mQueuedSender =
|
||||
new IMENotificationSender(mIMEContentObserver);
|
||||
NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ UIEvent::UIEvent(EventTarget* aOwner,
|
||||
case eScrollPortEventClass:
|
||||
{
|
||||
InternalScrollPortEvent* scrollEvent = mEvent->AsScrollPortEvent();
|
||||
mDetail = (int32_t)scrollEvent->orient;
|
||||
mDetail = static_cast<int32_t>(scrollEvent->mOrient);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user