mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 11:57:32 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
a7a525c65e
49 changed files with 1519 additions and 539 deletions
|
|
@ -39,14 +39,14 @@ add_task(function* () {
|
|||
|
||||
// Calculate offsets to click in the middle of the first box quad.
|
||||
let rect = prop.editor.valueSpan.getBoundingClientRect();
|
||||
let firstQuad = prop.editor.valueSpan.getBoxQuads()[0];
|
||||
let firstQuadBounds = prop.editor.valueSpan.getBoxQuads()[0].getBounds();
|
||||
// For a multiline value, the first quad left edge is not aligned with the
|
||||
// bounding rect left edge. The offsets expected by focusEditableField are
|
||||
// relative to the bouding rectangle, so we need to translate the x-offset.
|
||||
let x = firstQuad.bounds.left - rect.left + firstQuad.bounds.width / 2;
|
||||
let x = firstQuadBounds.left - rect.left + firstQuadBounds.width / 2;
|
||||
// The first quad top edge is aligned with the bounding top edge, no
|
||||
// translation needed here.
|
||||
let y = firstQuad.bounds.height / 2;
|
||||
let y = firstQuadBounds.height / 2;
|
||||
|
||||
info("Focusing the css property editable value");
|
||||
let editor = yield focusEditableField(view, prop.editor.valueSpan, x, y);
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ AutocompletePopup.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
let {top, height} = quads[0].bounds;
|
||||
let {top, height} = quads[0].getBounds();
|
||||
let containerHeight = this._tooltip.panel.getBoundingClientRect().height;
|
||||
if (top < 0) {
|
||||
// Element is above container.
|
||||
|
|
|
|||
|
|
@ -85,9 +85,9 @@ function* runTests(doc) {
|
|||
ok(arrow, "Tooltip has an arrow");
|
||||
|
||||
// Get the geometry of the anchor, the tooltip panel & arrow.
|
||||
let arrowBounds = arrow.getBoxQuads({relativeTo: doc})[0].bounds;
|
||||
let panelBounds = tooltip.panel.getBoxQuads({relativeTo: doc})[0].bounds;
|
||||
let anchorBounds = el.getBoxQuads({relativeTo: doc})[0].bounds;
|
||||
let arrowBounds = arrow.getBoxQuads({relativeTo: doc})[0].getBounds();
|
||||
let panelBounds = tooltip.panel.getBoxQuads({relativeTo: doc})[0].getBounds();
|
||||
let anchorBounds = el.getBoxQuads({relativeTo: doc})[0].getBounds();
|
||||
|
||||
let intersects = arrowBounds.left <= anchorBounds.right &&
|
||||
arrowBounds.right >= anchorBounds.left;
|
||||
|
|
|
|||
|
|
@ -78,9 +78,9 @@ function* runTests(doc) {
|
|||
ok(arrow, "Tooltip has an arrow");
|
||||
|
||||
// Get the geometry of the anchor, the tooltip panel & arrow.
|
||||
let arrowBounds = arrow.getBoxQuads({relativeTo: doc})[0].bounds;
|
||||
let panelBounds = tooltip.panel.getBoxQuads({relativeTo: doc})[0].bounds;
|
||||
let anchorBounds = el.getBoxQuads({relativeTo: doc})[0].bounds;
|
||||
let arrowBounds = arrow.getBoxQuads({relativeTo: doc})[0].getBounds();
|
||||
let panelBounds = tooltip.panel.getBoxQuads({relativeTo: doc})[0].getBounds();
|
||||
let anchorBounds = el.getBoxQuads({relativeTo: doc})[0].getBounds();
|
||||
|
||||
let intersects = arrowBounds.left <= anchorBounds.right &&
|
||||
arrowBounds.right >= anchorBounds.left;
|
||||
|
|
|
|||
|
|
@ -114,5 +114,5 @@ let runAutocompletionTest = Task.async(function* (editor) {
|
|||
*/
|
||||
function getPopupOffset({popup, input}) {
|
||||
let popupQuads = popup._panel.getBoxQuads({relativeTo: input});
|
||||
return popupQuads[0].bounds.left;
|
||||
return popupQuads[0].getBounds().left;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,9 +176,9 @@ const getRelativeRect = function (node, relativeTo) {
|
|||
// Width and Height can be taken from the rect.
|
||||
let {width, height} = node.getBoundingClientRect();
|
||||
|
||||
let quads = node.getBoxQuads({relativeTo});
|
||||
let top = quads[0].bounds.top;
|
||||
let left = quads[0].bounds.left;
|
||||
let quadBounds = node.getBoxQuads({relativeTo})[0].getBounds();
|
||||
let top = quadBounds.top;
|
||||
let left = quadBounds.left;
|
||||
|
||||
// Compute right and bottom coordinates using the rest of the data.
|
||||
let right = left + width;
|
||||
|
|
|
|||
|
|
@ -3071,7 +3071,10 @@ function nodeHasSize(node) {
|
|||
}
|
||||
|
||||
let quads = node.getBoxQuads();
|
||||
return quads.length && quads.some(quad => quad.bounds.width && quad.bounds.height);
|
||||
return quads.some(quad => {
|
||||
let bounds = quad.getBounds();
|
||||
return bounds.width && bounds.height;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -175,6 +175,11 @@ exports.getFrameOffsets = getFrameOffsets;
|
|||
/**
|
||||
* Get box quads adjusted for iframes and zoom level.
|
||||
*
|
||||
* Warning: this function returns things that look like DOMQuad objects but
|
||||
* aren't (they resemble an old version of the spec). Unlike the return value
|
||||
* of node.getBoxQuads, they have a .bounds property and not a .getBounds()
|
||||
* method.
|
||||
*
|
||||
* @param {DOMWindow} boundaryWindow
|
||||
* The window where to stop to iterate. If `null` is given, the top
|
||||
* window is used.
|
||||
|
|
@ -206,6 +211,7 @@ function getAdjustedQuads(boundaryWindow, node, region) {
|
|||
|
||||
let adjustedQuads = [];
|
||||
for (let quad of quads) {
|
||||
let bounds = quad.getBounds();
|
||||
adjustedQuads.push({
|
||||
p1: {
|
||||
w: quad.p1.w * scale,
|
||||
|
|
@ -232,14 +238,14 @@ function getAdjustedQuads(boundaryWindow, node, region) {
|
|||
z: quad.p4.z * scale
|
||||
},
|
||||
bounds: {
|
||||
bottom: quad.bounds.bottom * scale + yOffset,
|
||||
height: quad.bounds.height * scale,
|
||||
left: quad.bounds.left * scale + xOffset,
|
||||
right: quad.bounds.right * scale + xOffset,
|
||||
top: quad.bounds.top * scale + yOffset,
|
||||
width: quad.bounds.width * scale,
|
||||
x: quad.bounds.x * scale + xOffset,
|
||||
y: quad.bounds.y * scale + yOffset
|
||||
bottom: bounds.bottom * scale + yOffset,
|
||||
height: bounds.height * scale,
|
||||
left: bounds.left * scale + xOffset,
|
||||
right: bounds.right * scale + xOffset,
|
||||
top: bounds.top * scale + yOffset,
|
||||
width: bounds.width * scale,
|
||||
x: bounds.x * scale + xOffset,
|
||||
y: bounds.y * scale + yOffset
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,15 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "js/Equality.h" // JS::SameValueZero
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
template <typename T>
|
||||
static void
|
||||
SetDataInMatrix(DOMMatrixReadOnly* aMatrix, const T* aData, int aLength, ErrorResult& aRv);
|
||||
|
||||
static const double radPerDegree = 2.0 * M_PI / 360.0;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrixReadOnly, mParent)
|
||||
|
|
@ -27,6 +33,210 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrixReadOnly, mParent)
|
|||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrixReadOnly, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrixReadOnly, Release)
|
||||
|
||||
JSObject*
|
||||
DOMMatrixReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return DOMMatrixReadOnlyBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d
|
||||
static bool
|
||||
ValidateAndFixupMatrix2DInit(DOMMatrix2DInit& aMatrixInit, ErrorResult& aRv)
|
||||
{
|
||||
#define ValidateAliases(field, alias, fieldName, aliasName) \
|
||||
if ((field).WasPassed() && (alias).WasPassed() && \
|
||||
!JS::SameValueZero((field).Value(), (alias).Value())) { \
|
||||
aRv.ThrowTypeError<MSG_MATRIX_INIT_CONFLICTING_VALUE>((fieldName), \
|
||||
(aliasName)); \
|
||||
return false; \
|
||||
}
|
||||
#define SetFromAliasOrDefault(field, alias, defaultValue) \
|
||||
if (!(field).WasPassed()) { \
|
||||
if ((alias).WasPassed()) { \
|
||||
(field).Construct((alias).Value()); \
|
||||
} else { \
|
||||
(field).Construct(defaultValue); \
|
||||
} \
|
||||
}
|
||||
#define ValidateAndSet(field, alias, fieldName, aliasName, defaultValue) \
|
||||
ValidateAliases((field), (alias), NS_LITERAL_STRING(fieldName), \
|
||||
NS_LITERAL_STRING(aliasName)); \
|
||||
SetFromAliasOrDefault((field), (alias), (defaultValue));
|
||||
|
||||
ValidateAndSet(aMatrixInit.mM11, aMatrixInit.mA, "m11", "a", 1);
|
||||
ValidateAndSet(aMatrixInit.mM12, aMatrixInit.mB, "m12", "b", 0);
|
||||
ValidateAndSet(aMatrixInit.mM21, aMatrixInit.mC, "m21", "c", 0);
|
||||
ValidateAndSet(aMatrixInit.mM22, aMatrixInit.mD, "m22", "d", 1);
|
||||
ValidateAndSet(aMatrixInit.mM41, aMatrixInit.mE, "m41", "e", 0);
|
||||
ValidateAndSet(aMatrixInit.mM42, aMatrixInit.mF, "m42", "f", 0);
|
||||
|
||||
return true;
|
||||
|
||||
#undef ValidateAliases
|
||||
#undef SetFromAliasOrDefault
|
||||
#undef ValidateAndSet
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup
|
||||
static bool
|
||||
ValidateAndFixupMatrixInit(DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
|
||||
{
|
||||
#define Check3DField(field, fieldName, defaultValue) \
|
||||
if ((field) != (defaultValue)) { \
|
||||
if (!aMatrixInit.mIs2D.WasPassed()) { \
|
||||
aMatrixInit.mIs2D.Construct(false); \
|
||||
return true; \
|
||||
} \
|
||||
if (aMatrixInit.mIs2D.Value()) { \
|
||||
aRv.ThrowTypeError<MSG_MATRIX_INIT_EXCEEDS_2D>( \
|
||||
NS_LITERAL_STRING(fieldName)); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
if (!ValidateAndFixupMatrix2DInit(aMatrixInit, aRv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Check3DField(aMatrixInit.mM13, "m13", 0);
|
||||
Check3DField(aMatrixInit.mM14, "m14", 0);
|
||||
Check3DField(aMatrixInit.mM23, "m23", 0);
|
||||
Check3DField(aMatrixInit.mM24, "m24", 0);
|
||||
Check3DField(aMatrixInit.mM31, "m31", 0);
|
||||
Check3DField(aMatrixInit.mM32, "m32", 0);
|
||||
Check3DField(aMatrixInit.mM34, "m34", 0);
|
||||
Check3DField(aMatrixInit.mM43, "m43", 0);
|
||||
Check3DField(aMatrixInit.mM33, "m33", 1);
|
||||
Check3DField(aMatrixInit.mM44, "m44", 1);
|
||||
|
||||
if (!aMatrixInit.mIs2D.WasPassed()) {
|
||||
aMatrixInit.mIs2D.Construct(true);
|
||||
}
|
||||
return true;
|
||||
|
||||
#undef Check3DField
|
||||
}
|
||||
|
||||
void
|
||||
DOMMatrixReadOnly::SetDataFromMatrixInit(DOMMatrixInit& aMatrixInit)
|
||||
{
|
||||
const bool is2D = aMatrixInit.mIs2D.Value();
|
||||
MOZ_ASSERT(is2D == Is2D());
|
||||
if (is2D) {
|
||||
mMatrix2D->_11 = aMatrixInit.mM11.Value();
|
||||
mMatrix2D->_12 = aMatrixInit.mM12.Value();
|
||||
mMatrix2D->_21 = aMatrixInit.mM21.Value();
|
||||
mMatrix2D->_22 = aMatrixInit.mM22.Value();
|
||||
mMatrix2D->_31 = aMatrixInit.mM41.Value();
|
||||
mMatrix2D->_32 = aMatrixInit.mM42.Value();
|
||||
} else {
|
||||
mMatrix3D->_11 = aMatrixInit.mM11.Value();
|
||||
mMatrix3D->_12 = aMatrixInit.mM12.Value();
|
||||
mMatrix3D->_13 = aMatrixInit.mM13;
|
||||
mMatrix3D->_14 = aMatrixInit.mM14;
|
||||
mMatrix3D->_21 = aMatrixInit.mM21.Value();
|
||||
mMatrix3D->_22 = aMatrixInit.mM22.Value();
|
||||
mMatrix3D->_23 = aMatrixInit.mM23;
|
||||
mMatrix3D->_24 = aMatrixInit.mM24;
|
||||
mMatrix3D->_31 = aMatrixInit.mM31;
|
||||
mMatrix3D->_32 = aMatrixInit.mM32;
|
||||
mMatrix3D->_33 = aMatrixInit.mM33;
|
||||
mMatrix3D->_34 = aMatrixInit.mM34;
|
||||
mMatrix3D->_41 = aMatrixInit.mM41.Value();
|
||||
mMatrix3D->_42 = aMatrixInit.mM42.Value();
|
||||
mMatrix3D->_43 = aMatrixInit.mM43;
|
||||
mMatrix3D->_44 = aMatrixInit.mM44;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrixReadOnly>
|
||||
DOMMatrixReadOnly::FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
|
||||
{
|
||||
DOMMatrixInit matrixInit(aMatrixInit);
|
||||
if (!ValidateAndFixupMatrixInit(matrixInit, aRv)) {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
RefPtr<DOMMatrixReadOnly> rval =
|
||||
new DOMMatrixReadOnly(aGlobal.GetAsSupports(), matrixInit.mIs2D.Value());
|
||||
rval->SetDataFromMatrixInit(matrixInit);
|
||||
return rval.forget();
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<DOMMatrixReadOnly>
|
||||
DOMMatrixReadOnly::FromFloat32Array(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv)
|
||||
{
|
||||
aArray32.ComputeLengthAndData();
|
||||
|
||||
const int length = aArray32.Length();
|
||||
const bool is2D = length == 6;
|
||||
RefPtr<DOMMatrixReadOnly> obj =
|
||||
new DOMMatrixReadOnly(aGlobal.GetAsSupports(), is2D);
|
||||
SetDataInMatrix(obj, aArray32.Data(), length, aRv);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrixReadOnly>
|
||||
DOMMatrixReadOnly::FromFloat64Array(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv)
|
||||
{
|
||||
aArray64.ComputeLengthAndData();
|
||||
|
||||
const int length = aArray64.Length();
|
||||
const bool is2D = length == 6;
|
||||
RefPtr<DOMMatrixReadOnly> obj =
|
||||
new DOMMatrixReadOnly(aGlobal.GetAsSupports(), is2D);
|
||||
SetDataInMatrix(obj, aArray64.Data(), length, aRv);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrixReadOnly>
|
||||
DOMMatrixReadOnly::Constructor(
|
||||
const GlobalObject& aGlobal,
|
||||
const Optional<StringOrUnrestrictedDoubleSequence>& aArg,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<DOMMatrixReadOnly> rval = new DOMMatrixReadOnly(aGlobal.GetAsSupports());
|
||||
if (!aArg.WasPassed()) {
|
||||
return rval.forget();
|
||||
}
|
||||
|
||||
const auto& arg = aArg.Value();
|
||||
if (arg.IsString()) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!win) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
|
||||
return nullptr;
|
||||
}
|
||||
rval->SetMatrixValue(arg.GetAsString(), aRv);
|
||||
} else {
|
||||
const auto& sequence = arg.GetAsUnrestrictedDoubleSequence();
|
||||
SetDataInMatrix(rval, sequence.Elements(), sequence.Length(), aRv);
|
||||
}
|
||||
|
||||
return rval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrixReadOnly>
|
||||
DOMMatrixReadOnly::ReadStructuredClone(nsISupports* aParent, JSStructuredCloneReader* aReader)
|
||||
{
|
||||
uint8_t is2D;
|
||||
|
||||
if (!JS_ReadBytes(aReader, &is2D, 1)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DOMMatrixReadOnly> rval = new DOMMatrixReadOnly(aParent, is2D);
|
||||
|
||||
if (!ReadStructuredCloneElements(aReader, rval)) {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
return rval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrixReadOnly::Translate(double aTx,
|
||||
double aTy,
|
||||
|
|
@ -127,10 +337,10 @@ DOMMatrixReadOnly::SkewY(double aSy) const
|
|||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrixReadOnly::Multiply(const DOMMatrix& other) const
|
||||
DOMMatrixReadOnly::Multiply(const DOMMatrixInit& other, ErrorResult& aRv) const
|
||||
{
|
||||
RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
|
||||
retval->MultiplySelf(other);
|
||||
retval->MultiplySelf(other, aRv);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
|
@ -307,6 +517,117 @@ DOMMatrixReadOnly::Stringify(nsAString& aResult)
|
|||
aResult = matrixStr;
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#structured-serialization
|
||||
bool
|
||||
DOMMatrixReadOnly::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
|
||||
{
|
||||
#define WriteFloatPair(f1, f2) \
|
||||
JS_WriteUint32Pair(aWriter, BitwiseCast<uint32_t>(f1), \
|
||||
BitwiseCast<uint32_t>(f2))
|
||||
|
||||
const uint8_t is2D = Is2D();
|
||||
|
||||
if (!JS_WriteBytes(aWriter, &is2D, 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is2D == 1) {
|
||||
return WriteFloatPair(mMatrix2D->_11, mMatrix2D->_12) &&
|
||||
WriteFloatPair(mMatrix2D->_21, mMatrix2D->_22) &&
|
||||
WriteFloatPair(mMatrix2D->_31, mMatrix2D->_32);
|
||||
}
|
||||
|
||||
return WriteFloatPair(mMatrix3D->_11, mMatrix3D->_12) &&
|
||||
WriteFloatPair(mMatrix3D->_13, mMatrix3D->_14) &&
|
||||
WriteFloatPair(mMatrix3D->_21, mMatrix3D->_22) &&
|
||||
WriteFloatPair(mMatrix3D->_23, mMatrix3D->_24) &&
|
||||
WriteFloatPair(mMatrix3D->_31, mMatrix3D->_32) &&
|
||||
WriteFloatPair(mMatrix3D->_33, mMatrix3D->_34) &&
|
||||
WriteFloatPair(mMatrix3D->_41, mMatrix3D->_42) &&
|
||||
WriteFloatPair(mMatrix3D->_43, mMatrix3D->_44);
|
||||
#undef WriteFloatPair
|
||||
}
|
||||
|
||||
bool
|
||||
DOMMatrixReadOnly::ReadStructuredCloneElements(JSStructuredCloneReader* aReader, DOMMatrixReadOnly* matrix)
|
||||
{
|
||||
uint32_t high;
|
||||
uint32_t low;
|
||||
|
||||
#define ReadFloatPair(f1, f2) \
|
||||
if (!JS_ReadUint32Pair(aReader, &high, &low)) { \
|
||||
return false; \
|
||||
} \
|
||||
(*(f1) = BitwiseCast<float>(high)); \
|
||||
(*(f2) = BitwiseCast<float>(low));
|
||||
|
||||
if (matrix->Is2D() == 1) {
|
||||
ReadFloatPair(&(matrix->mMatrix2D->_11), &(matrix->mMatrix2D->_12));
|
||||
ReadFloatPair(&(matrix->mMatrix2D->_21), &(matrix->mMatrix2D->_22));
|
||||
ReadFloatPair(&(matrix->mMatrix2D->_31), &(matrix->mMatrix2D->_32));
|
||||
} else {
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_11), &(matrix->mMatrix3D->_12));
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_13), &(matrix->mMatrix3D->_14));
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_21), &(matrix->mMatrix3D->_22));
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_23), &(matrix->mMatrix3D->_24));
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_31), &(matrix->mMatrix3D->_32));
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_33), &(matrix->mMatrix3D->_34));
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_41), &(matrix->mMatrix3D->_42));
|
||||
ReadFloatPair(&(matrix->mMatrix3D->_43), &(matrix->mMatrix3D->_44));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
#undef ReadFloatPair
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::FromMatrix(nsISupports* aParent, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
|
||||
{
|
||||
DOMMatrixInit matrixInit(aMatrixInit);
|
||||
if (!ValidateAndFixupMatrixInit(matrixInit, aRv)) {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
RefPtr<DOMMatrix> matrix = new DOMMatrix(aParent, matrixInit.mIs2D.Value());
|
||||
matrix->SetDataFromMatrixInit(matrixInit);
|
||||
return matrix.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<DOMMatrix> matrix =
|
||||
FromMatrix(aGlobal.GetAsSupports(), aMatrixInit, aRv);
|
||||
return matrix.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::FromFloat32Array(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv)
|
||||
{
|
||||
aArray32.ComputeLengthAndData();
|
||||
|
||||
const int length = aArray32.Length();
|
||||
const bool is2D = length == 6;
|
||||
RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports(), is2D);
|
||||
SetDataInMatrix(obj, aArray32.Data(), length, aRv);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::FromFloat64Array(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv)
|
||||
{
|
||||
aArray64.ComputeLengthAndData();
|
||||
|
||||
const int length = aArray64.Length();
|
||||
const bool is2D = length == 6;
|
||||
RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports(), is2D);
|
||||
SetDataInMatrix(obj, aArray64.Data(), length, aRv);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
|
|
@ -317,6 +638,11 @@ DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
|||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::Constructor(const GlobalObject& aGlobal, const nsAString& aTransformList, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!win) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
|
||||
|
||||
obj = obj->SetMatrixValue(aTransformList, aRv);
|
||||
|
|
@ -330,7 +656,9 @@ DOMMatrix::Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOt
|
|||
return obj.forget();
|
||||
}
|
||||
|
||||
template <typename T> void SetDataInMatrix(DOMMatrix* aMatrix, const T* aData, int aLength, ErrorResult& aRv)
|
||||
template <typename T>
|
||||
static void
|
||||
SetDataInMatrix(DOMMatrixReadOnly* aMatrix, const T* aData, int aLength, ErrorResult& aRv)
|
||||
{
|
||||
if (aLength == 16) {
|
||||
aMatrix->SetM11(aData[0]);
|
||||
|
|
@ -357,28 +685,22 @@ template <typename T> void SetDataInMatrix(DOMMatrix* aMatrix, const T* aData, i
|
|||
aMatrix->SetE(aData[4]);
|
||||
aMatrix->SetF(aData[5]);
|
||||
} else {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
nsAutoString lengthStr;
|
||||
lengthStr.AppendInt(aLength);
|
||||
aRv.ThrowTypeError<MSG_MATRIX_INIT_LENGTH_WRONG>(lengthStr);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
|
||||
aArray32.ComputeLengthAndData();
|
||||
SetDataInMatrix(obj, aArray32.Data(), aArray32.Length(), aRv);
|
||||
|
||||
return obj.forget();
|
||||
return FromFloat32Array(aGlobal, aArray32, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::Constructor(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
|
||||
aArray64.ComputeLengthAndData();
|
||||
SetDataInMatrix(obj, aArray64.Data(), aArray64.Length(), aRv);
|
||||
|
||||
return obj.forget();
|
||||
return FromFloat64Array(aGlobal, aArray64, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMatrix>
|
||||
|
|
@ -390,7 +712,26 @@ DOMMatrix::Constructor(const GlobalObject& aGlobal, const Sequence<double>& aNum
|
|||
return obj.forget();
|
||||
}
|
||||
|
||||
void DOMMatrix::Ensure3DMatrix()
|
||||
already_AddRefed<DOMMatrix>
|
||||
DOMMatrix::ReadStructuredClone(nsISupports* aParent, JSStructuredCloneReader* aReader)
|
||||
{
|
||||
uint8_t is2D;
|
||||
|
||||
if (!JS_ReadBytes(aReader, &is2D, 1)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DOMMatrix> rval = new DOMMatrix(aParent, is2D);
|
||||
|
||||
if (!ReadStructuredCloneElements(aReader, rval)) {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
return rval.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DOMMatrixReadOnly::Ensure3DMatrix()
|
||||
{
|
||||
if (!mMatrix3D) {
|
||||
mMatrix3D = new gfx::Matrix4x4(gfx::Matrix4x4::From2D(*mMatrix2D));
|
||||
|
|
@ -399,42 +740,44 @@ void DOMMatrix::Ensure3DMatrix()
|
|||
}
|
||||
|
||||
DOMMatrix*
|
||||
DOMMatrix::MultiplySelf(const DOMMatrix& aOther)
|
||||
DOMMatrix::MultiplySelf(const DOMMatrixInit& aOtherInit, ErrorResult& aRv)
|
||||
{
|
||||
if (aOther.Identity()) {
|
||||
RefPtr<DOMMatrix> other = FromMatrix(mParent, aOtherInit, aRv);
|
||||
if (other->Identity()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (aOther.Is2D()) {
|
||||
if (other->Is2D()) {
|
||||
if (mMatrix3D) {
|
||||
*mMatrix3D = gfx::Matrix4x4::From2D(*aOther.mMatrix2D) * *mMatrix3D;
|
||||
*mMatrix3D = gfx::Matrix4x4::From2D(*other->mMatrix2D) * *mMatrix3D;
|
||||
} else {
|
||||
*mMatrix2D = *aOther.mMatrix2D * *mMatrix2D;
|
||||
*mMatrix2D = *other->mMatrix2D * *mMatrix2D;
|
||||
}
|
||||
} else {
|
||||
Ensure3DMatrix();
|
||||
*mMatrix3D = *aOther.mMatrix3D * *mMatrix3D;
|
||||
*mMatrix3D = *other->mMatrix3D * *mMatrix3D;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
DOMMatrix*
|
||||
DOMMatrix::PreMultiplySelf(const DOMMatrix& aOther)
|
||||
DOMMatrix::PreMultiplySelf(const DOMMatrixInit& aOtherInit, ErrorResult& aRv)
|
||||
{
|
||||
if (aOther.Identity()) {
|
||||
RefPtr<DOMMatrix> other = FromMatrix(mParent, aOtherInit, aRv);
|
||||
if (other->Identity()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (aOther.Is2D()) {
|
||||
if (other->Is2D()) {
|
||||
if (mMatrix3D) {
|
||||
*mMatrix3D = *mMatrix3D * gfx::Matrix4x4::From2D(*aOther.mMatrix2D);
|
||||
*mMatrix3D = *mMatrix3D * gfx::Matrix4x4::From2D(*other->mMatrix2D);
|
||||
} else {
|
||||
*mMatrix2D = *mMatrix2D * *aOther.mMatrix2D;
|
||||
*mMatrix2D = *mMatrix2D * *other->mMatrix2D;
|
||||
}
|
||||
} else {
|
||||
Ensure3DMatrix();
|
||||
*mMatrix3D = *mMatrix3D * *aOther.mMatrix3D;
|
||||
*mMatrix3D = *mMatrix3D * *other->mMatrix3D;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
@ -617,8 +960,8 @@ DOMMatrix::InvertSelf()
|
|||
return this;
|
||||
}
|
||||
|
||||
DOMMatrix*
|
||||
DOMMatrix::SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv)
|
||||
DOMMatrixReadOnly*
|
||||
DOMMatrixReadOnly::SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv)
|
||||
{
|
||||
SVGTransformListParser parser(aTransformList);
|
||||
if (!parser.Parse()) {
|
||||
|
|
@ -644,6 +987,13 @@ DOMMatrix::SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv)
|
|||
return this;
|
||||
}
|
||||
|
||||
DOMMatrix*
|
||||
DOMMatrix::SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv)
|
||||
{
|
||||
DOMMatrixReadOnly::SetMatrixValue(aTransformList, aRv);
|
||||
return this;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
DOMMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef MOZILLA_DOM_DOMMATRIX_H_
|
||||
#define MOZILLA_DOM_DOMMATRIX_H_
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
|
@ -22,7 +23,9 @@ namespace dom {
|
|||
class GlobalObject;
|
||||
class DOMMatrix;
|
||||
class DOMPoint;
|
||||
class StringOrUnrestrictedDoubleSequence;
|
||||
struct DOMPointInit;
|
||||
struct DOMMatrixInit;
|
||||
|
||||
class DOMMatrixReadOnly : public nsWrapperCache
|
||||
{
|
||||
|
|
@ -42,9 +45,36 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
DOMMatrixReadOnly(nsISupports* aParent, const gfx::Matrix4x4& aMatrix)
|
||||
: mParent(aParent)
|
||||
{
|
||||
mMatrix3D = new gfx::Matrix4x4(aMatrix);
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrixReadOnly)
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
static already_AddRefed<DOMMatrixReadOnly>
|
||||
FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrixReadOnly>
|
||||
FromFloat32Array(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrixReadOnly>
|
||||
FromFloat64Array(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrixReadOnly>
|
||||
Constructor(const GlobalObject& aGlobal, const Optional<StringOrUnrestrictedDoubleSequence>& aArg, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrixReadOnly>
|
||||
ReadStructuredClone(nsISupports* aParent, JSStructuredCloneReader* aReader);
|
||||
|
||||
static bool
|
||||
ReadStructuredCloneElements(JSStructuredCloneReader* aReader, DOMMatrixReadOnly* matrix);
|
||||
|
||||
#define GetMatrixMember(entry2D, entry3D, default) \
|
||||
{ \
|
||||
if (mMatrix3D) { \
|
||||
|
|
@ -88,88 +118,7 @@ public:
|
|||
#undef GetMatrixMember
|
||||
#undef Get3DMatrixMember
|
||||
|
||||
already_AddRefed<DOMMatrix> Translate(double aTx,
|
||||
double aTy,
|
||||
double aTz = 0) const;
|
||||
already_AddRefed<DOMMatrix> Scale(double aScale,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0) const;
|
||||
already_AddRefed<DOMMatrix> Scale3d(double aScale,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0,
|
||||
double aOriginZ = 0) const;
|
||||
already_AddRefed<DOMMatrix> ScaleNonUniform(double aScaleX,
|
||||
double aScaleY = 1.0,
|
||||
double aScaleZ = 1.0,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0,
|
||||
double aOriginZ = 0) const;
|
||||
already_AddRefed<DOMMatrix> Rotate(double aAngle,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0) const;
|
||||
already_AddRefed<DOMMatrix> RotateFromVector(double aX,
|
||||
double aY) const;
|
||||
already_AddRefed<DOMMatrix> RotateAxisAngle(double aX,
|
||||
double aY,
|
||||
double aZ,
|
||||
double aAngle) const;
|
||||
already_AddRefed<DOMMatrix> SkewX(double aSx) const;
|
||||
already_AddRefed<DOMMatrix> SkewY(double aSy) const;
|
||||
already_AddRefed<DOMMatrix> Multiply(const DOMMatrix& aOther) const;
|
||||
already_AddRefed<DOMMatrix> FlipX() const;
|
||||
already_AddRefed<DOMMatrix> FlipY() const;
|
||||
already_AddRefed<DOMMatrix> Inverse() const;
|
||||
|
||||
bool Is2D() const;
|
||||
bool Identity() const;
|
||||
already_AddRefed<DOMPoint> TransformPoint(const DOMPointInit& aPoint) const;
|
||||
void ToFloat32Array(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aResult,
|
||||
ErrorResult& aRv) const;
|
||||
void ToFloat64Array(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aResult,
|
||||
ErrorResult& aRv) const;
|
||||
void Stringify(nsAString& aResult);
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsAutoPtr<gfx::Matrix> mMatrix2D;
|
||||
nsAutoPtr<gfx::Matrix4x4> mMatrix3D;
|
||||
|
||||
virtual ~DOMMatrixReadOnly() {}
|
||||
|
||||
private:
|
||||
DOMMatrixReadOnly() = delete;
|
||||
DOMMatrixReadOnly(const DOMMatrixReadOnly&) = delete;
|
||||
DOMMatrixReadOnly& operator=(const DOMMatrixReadOnly&) = delete;
|
||||
};
|
||||
|
||||
class DOMMatrix : public DOMMatrixReadOnly
|
||||
{
|
||||
public:
|
||||
explicit DOMMatrix(nsISupports* aParent)
|
||||
: DOMMatrixReadOnly(aParent)
|
||||
{}
|
||||
|
||||
DOMMatrix(nsISupports* aParent, const DOMMatrixReadOnly& other)
|
||||
: DOMMatrixReadOnly(aParent, other)
|
||||
{}
|
||||
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const nsAString& aTransformList, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOther, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const Sequence<double>& aNumberSequence, ErrorResult& aRv);
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
// Defined here so we can construct DOMMatrixReadOnly objects.
|
||||
#define Set2DMatrixMember(entry2D, entry3D) \
|
||||
{ \
|
||||
if (mMatrix3D) { \
|
||||
|
|
@ -214,8 +163,128 @@ public:
|
|||
#undef Set2DMatrixMember
|
||||
#undef Set3DMatrixMember
|
||||
|
||||
DOMMatrix* MultiplySelf(const DOMMatrix& aOther);
|
||||
DOMMatrix* PreMultiplySelf(const DOMMatrix& aOther);
|
||||
already_AddRefed<DOMMatrix> Translate(double aTx,
|
||||
double aTy,
|
||||
double aTz = 0) const;
|
||||
already_AddRefed<DOMMatrix> Scale(double aScale,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0) const;
|
||||
already_AddRefed<DOMMatrix> Scale3d(double aScale,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0,
|
||||
double aOriginZ = 0) const;
|
||||
already_AddRefed<DOMMatrix> ScaleNonUniform(double aScaleX,
|
||||
double aScaleY = 1.0,
|
||||
double aScaleZ = 1.0,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0,
|
||||
double aOriginZ = 0) const;
|
||||
already_AddRefed<DOMMatrix> Rotate(double aAngle,
|
||||
double aOriginX = 0,
|
||||
double aOriginY = 0) const;
|
||||
already_AddRefed<DOMMatrix> RotateFromVector(double aX,
|
||||
double aY) const;
|
||||
already_AddRefed<DOMMatrix> RotateAxisAngle(double aX,
|
||||
double aY,
|
||||
double aZ,
|
||||
double aAngle) const;
|
||||
already_AddRefed<DOMMatrix> SkewX(double aSx) const;
|
||||
already_AddRefed<DOMMatrix> SkewY(double aSy) const;
|
||||
already_AddRefed<DOMMatrix> Multiply(const DOMMatrixInit& aOther,
|
||||
ErrorResult& aRv) const;
|
||||
already_AddRefed<DOMMatrix> FlipX() const;
|
||||
already_AddRefed<DOMMatrix> FlipY() const;
|
||||
already_AddRefed<DOMMatrix> Inverse() const;
|
||||
|
||||
bool Is2D() const;
|
||||
bool Identity() const;
|
||||
already_AddRefed<DOMPoint> TransformPoint(const DOMPointInit& aPoint) const;
|
||||
void ToFloat32Array(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aResult,
|
||||
ErrorResult& aRv) const;
|
||||
void ToFloat64Array(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aResult,
|
||||
ErrorResult& aRv) const;
|
||||
void Stringify(nsAString& aResult);
|
||||
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsAutoPtr<gfx::Matrix> mMatrix2D;
|
||||
nsAutoPtr<gfx::Matrix4x4> mMatrix3D;
|
||||
|
||||
virtual ~DOMMatrixReadOnly() {}
|
||||
|
||||
/**
|
||||
* Sets data from a fully validated and fixed-up matrix init,
|
||||
* where all of its members are properly defined.
|
||||
* The init dictionary's dimension must match the matrix one.
|
||||
*/
|
||||
void SetDataFromMatrixInit(DOMMatrixInit& aMatrixInit);
|
||||
|
||||
DOMMatrixReadOnly* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
|
||||
void Ensure3DMatrix();
|
||||
|
||||
DOMMatrixReadOnly(nsISupports* aParent, bool is2D) : mParent(aParent) {
|
||||
if (is2D) {
|
||||
mMatrix2D = new gfx::Matrix();
|
||||
} else {
|
||||
mMatrix3D = new gfx::Matrix4x4();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
DOMMatrixReadOnly() = delete;
|
||||
DOMMatrixReadOnly(const DOMMatrixReadOnly&) = delete;
|
||||
DOMMatrixReadOnly& operator=(const DOMMatrixReadOnly&) = delete;
|
||||
};
|
||||
|
||||
class DOMMatrix : public DOMMatrixReadOnly
|
||||
{
|
||||
public:
|
||||
explicit DOMMatrix(nsISupports* aParent)
|
||||
: DOMMatrixReadOnly(aParent)
|
||||
{}
|
||||
|
||||
DOMMatrix(nsISupports* aParent, const DOMMatrixReadOnly& other)
|
||||
: DOMMatrixReadOnly(aParent, other)
|
||||
{}
|
||||
|
||||
DOMMatrix(nsISupports* aParent, const gfx::Matrix4x4& aMatrix)
|
||||
: DOMMatrixReadOnly(aParent, aMatrix)
|
||||
{}
|
||||
|
||||
static already_AddRefed<DOMMatrix>
|
||||
FromMatrix(nsISupports* aParent, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrix>
|
||||
FromFloat32Array(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrix>
|
||||
FromFloat64Array(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const nsAString& aTransformList, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOther, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv);
|
||||
static already_AddRefed<DOMMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, const Sequence<double>& aNumberSequence, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<DOMMatrix>
|
||||
ReadStructuredClone(nsISupports* aParent, JSStructuredCloneReader* aReader);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
DOMMatrix* MultiplySelf(const DOMMatrixInit& aOther, ErrorResult& aRv);
|
||||
DOMMatrix* PreMultiplySelf(const DOMMatrixInit& aOther, ErrorResult& aRv);
|
||||
DOMMatrix* TranslateSelf(double aTx,
|
||||
double aTy,
|
||||
double aTz = 0);
|
||||
|
|
@ -245,10 +314,12 @@ public:
|
|||
DOMMatrix* SkewYSelf(double aSy);
|
||||
DOMMatrix* InvertSelf();
|
||||
DOMMatrix* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
|
||||
protected:
|
||||
void Ensure3DMatrix();
|
||||
|
||||
virtual ~DOMMatrix() {}
|
||||
|
||||
private:
|
||||
DOMMatrix(nsISupports* aParent, bool is2D)
|
||||
: DOMMatrixReadOnly(aParent, is2D) {}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
|||
|
|
@ -16,9 +16,68 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMPointReadOnly, mParent)
|
|||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPointReadOnly, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPointReadOnly, Release)
|
||||
|
||||
already_AddRefed<DOMPointReadOnly>
|
||||
DOMPointReadOnly::FromPoint(const GlobalObject& aGlobal, const DOMPointInit& aParams)
|
||||
{
|
||||
RefPtr<DOMPointReadOnly> obj =
|
||||
new DOMPointReadOnly(aGlobal.GetAsSupports(), aParams.mX, aParams.mY,
|
||||
aParams.mZ, aParams.mW);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMPointReadOnly>
|
||||
DOMPointReadOnly::Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
||||
double aZ, double aW, ErrorResult& aRV)
|
||||
{
|
||||
RefPtr<DOMPointReadOnly> obj =
|
||||
new DOMPointReadOnly(aGlobal.GetAsSupports(), aX, aY, aZ, aW);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
DOMPointReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return DOMPointReadOnlyBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#structured-serialization
|
||||
bool
|
||||
DOMPointReadOnly::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
|
||||
{
|
||||
#define WriteDouble(d) \
|
||||
JS_WriteUint32Pair(aWriter, (BitwiseCast<uint64_t>(d) >> 32) & 0xffffffff, \
|
||||
BitwiseCast<uint64_t>(d) & 0xffffffff)
|
||||
|
||||
return WriteDouble(mX) && WriteDouble(mY) && WriteDouble(mZ) &&
|
||||
WriteDouble(mW);
|
||||
|
||||
#undef WriteDouble
|
||||
}
|
||||
|
||||
bool
|
||||
DOMPointReadOnly::ReadStructuredClone(JSStructuredCloneReader* aReader)
|
||||
{
|
||||
uint32_t high;
|
||||
uint32_t low;
|
||||
|
||||
#define ReadDouble(d) \
|
||||
if (!JS_ReadUint32Pair(aReader, &high, &low)) { \
|
||||
return false; \
|
||||
} \
|
||||
(*(d) = BitwiseCast<double>(static_cast<uint64_t>(high) << 32 | low))
|
||||
|
||||
ReadDouble(&mX);
|
||||
ReadDouble(&mY);
|
||||
ReadDouble(&mZ);
|
||||
ReadDouble(&mW);
|
||||
|
||||
return true;
|
||||
|
||||
#undef ReadDouble
|
||||
}
|
||||
|
||||
already_AddRefed<DOMPoint>
|
||||
DOMPoint::Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
|
||||
ErrorResult& aRV)
|
||||
DOMPoint::FromPoint(const GlobalObject& aGlobal, const DOMPointInit& aParams)
|
||||
{
|
||||
RefPtr<DOMPoint> obj =
|
||||
new DOMPoint(aGlobal.GetAsSupports(), aParams.mX, aParams.mY,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef MOZILLA_DOMPOINT_H_
|
||||
#define MOZILLA_DOMPOINT_H_
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
|
@ -23,8 +24,8 @@ struct DOMPointInit;
|
|||
class DOMPointReadOnly : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
DOMPointReadOnly(nsISupports* aParent, double aX, double aY,
|
||||
double aZ, double aW)
|
||||
explicit DOMPointReadOnly(nsISupports* aParent, double aX = 0.0,
|
||||
double aY = 0.0, double aZ = 0.0, double aW = 1.0)
|
||||
: mParent(aParent)
|
||||
, mX(aX)
|
||||
, mY(aY)
|
||||
|
|
@ -33,6 +34,12 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
static already_AddRefed<DOMPointReadOnly>
|
||||
FromPoint(const GlobalObject& aGlobal, const DOMPointInit& aParams);
|
||||
static already_AddRefed<DOMPointReadOnly>
|
||||
Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
||||
double aZ, double aW, ErrorResult& aRV);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPointReadOnly)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPointReadOnly)
|
||||
|
||||
|
|
@ -41,6 +48,13 @@ public:
|
|||
double Z() const { return mZ; }
|
||||
double W() const { return mW; }
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
|
||||
|
||||
bool ReadStructuredClone(JSStructuredCloneReader* aReader);
|
||||
|
||||
protected:
|
||||
virtual ~DOMPointReadOnly() {}
|
||||
|
||||
|
|
@ -57,13 +71,11 @@ public:
|
|||
{}
|
||||
|
||||
static already_AddRefed<DOMPoint>
|
||||
Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
|
||||
ErrorResult& aRV);
|
||||
FromPoint(const GlobalObject& aGlobal, const DOMPointInit& aParams);
|
||||
static already_AddRefed<DOMPoint>
|
||||
Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
||||
double aZ, double aW, ErrorResult& aRV);
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void SetX(double aX) { mX = aX; }
|
||||
|
|
|
|||
|
|
@ -43,6 +43,32 @@ DOMQuad::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|||
return DOMQuadBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMQuad>
|
||||
DOMQuad::FromRect(const GlobalObject& aGlobal, const DOMRectInit& aInit)
|
||||
{
|
||||
nsISupports* parent = aGlobal.GetAsSupports();
|
||||
RefPtr<DOMQuad> obj = new DOMQuad(parent);
|
||||
obj->mPoints[0] = new DOMPoint(parent, aInit.mX, aInit.mY, 0, 1);
|
||||
obj->mPoints[1] =
|
||||
new DOMPoint(parent, aInit.mX + aInit.mWidth, aInit.mY, 0, 1);
|
||||
obj->mPoints[2] = new DOMPoint(parent, aInit.mX + aInit.mWidth,
|
||||
aInit.mY + aInit.mHeight, 0, 1);
|
||||
obj->mPoints[3] =
|
||||
new DOMPoint(parent, aInit.mX, aInit.mY + aInit.mHeight, 0, 1);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMQuad>
|
||||
DOMQuad::FromQuad(const GlobalObject& aGlobal, const DOMQuadInit& aInit)
|
||||
{
|
||||
RefPtr<DOMQuad> obj = new DOMQuad(aGlobal.GetAsSupports());
|
||||
obj->mPoints[0] = DOMPoint::FromPoint(aGlobal, aInit.mP1);
|
||||
obj->mPoints[1] = DOMPoint::FromPoint(aGlobal, aInit.mP2);
|
||||
obj->mPoints[2] = DOMPoint::FromPoint(aGlobal, aInit.mP3);
|
||||
obj->mPoints[3] = DOMPoint::FromPoint(aGlobal, aInit.mP4);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMQuad>
|
||||
DOMQuad::Constructor(const GlobalObject& aGlobal,
|
||||
const DOMPointInit& aP1,
|
||||
|
|
@ -52,10 +78,10 @@ DOMQuad::Constructor(const GlobalObject& aGlobal,
|
|||
ErrorResult& aRV)
|
||||
{
|
||||
RefPtr<DOMQuad> obj = new DOMQuad(aGlobal.GetAsSupports());
|
||||
obj->mPoints[0] = DOMPoint::Constructor(aGlobal, aP1, aRV);
|
||||
obj->mPoints[1] = DOMPoint::Constructor(aGlobal, aP2, aRV);
|
||||
obj->mPoints[2] = DOMPoint::Constructor(aGlobal, aP3, aRV);
|
||||
obj->mPoints[3] = DOMPoint::Constructor(aGlobal, aP4, aRV);
|
||||
obj->mPoints[0] = DOMPoint::FromPoint(aGlobal, aP1);
|
||||
obj->mPoints[1] = DOMPoint::FromPoint(aGlobal, aP2);
|
||||
obj->mPoints[2] = DOMPoint::FromPoint(aGlobal, aP3);
|
||||
obj->mPoints[3] = DOMPoint::FromPoint(aGlobal, aP4);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
|
|
@ -73,87 +99,86 @@ DOMQuad::Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect,
|
|||
return obj.forget();
|
||||
}
|
||||
|
||||
class DOMQuad::QuadBounds final : public DOMRectReadOnly
|
||||
void
|
||||
DOMQuad::GetHorizontalMinMax(double* aX1, double* aX2) const
|
||||
{
|
||||
public:
|
||||
explicit QuadBounds(DOMQuad* aQuad)
|
||||
: DOMRectReadOnly(aQuad->GetParentObject())
|
||||
, mQuad(aQuad)
|
||||
{}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(QuadBounds, DOMRectReadOnly)
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
virtual double X() const override
|
||||
{
|
||||
double x1, x2;
|
||||
GetHorizontalMinMax(&x1, &x2);
|
||||
return x1;
|
||||
double x1, x2;
|
||||
x1 = x2 = Point(0)->X();
|
||||
for (uint32_t i = 1; i < 4; ++i) {
|
||||
double x = Point(i)->X();
|
||||
x1 = std::min(x1, x);
|
||||
x2 = std::max(x2, x);
|
||||
}
|
||||
virtual double Y() const override
|
||||
{
|
||||
double y1, y2;
|
||||
GetVerticalMinMax(&y1, &y2);
|
||||
return y1;
|
||||
*aX1 = x1;
|
||||
*aX2 = x2;
|
||||
}
|
||||
|
||||
void
|
||||
DOMQuad::GetVerticalMinMax(double* aY1, double* aY2) const
|
||||
{
|
||||
double y1, y2;
|
||||
y1 = y2 = Point(0)->Y();
|
||||
for (uint32_t i = 1; i < 4; ++i) {
|
||||
double y = Point(i)->Y();
|
||||
y1 = std::min(y1, y);
|
||||
y2 = std::max(y2, y);
|
||||
}
|
||||
virtual double Width() const override
|
||||
{
|
||||
double x1, x2;
|
||||
GetHorizontalMinMax(&x1, &x2);
|
||||
return x2 - x1;
|
||||
}
|
||||
virtual double Height() const override
|
||||
{
|
||||
double y1, y2;
|
||||
GetVerticalMinMax(&y1, &y2);
|
||||
return y2 - y1;
|
||||
}
|
||||
|
||||
void GetHorizontalMinMax(double* aX1, double* aX2) const
|
||||
{
|
||||
double x1, x2;
|
||||
x1 = x2 = mQuad->Point(0)->X();
|
||||
for (uint32_t i = 1; i < 4; ++i) {
|
||||
double x = mQuad->Point(i)->X();
|
||||
x1 = std::min(x1, x);
|
||||
x2 = std::max(x2, x);
|
||||
}
|
||||
*aX1 = x1;
|
||||
*aX2 = x2;
|
||||
}
|
||||
|
||||
void GetVerticalMinMax(double* aY1, double* aY2) const
|
||||
{
|
||||
double y1, y2;
|
||||
y1 = y2 = mQuad->Point(0)->Y();
|
||||
for (uint32_t i = 1; i < 4; ++i) {
|
||||
double y = mQuad->Point(i)->Y();
|
||||
y1 = std::min(y1, y);
|
||||
y2 = std::max(y2, y);
|
||||
}
|
||||
*aY1 = y1;
|
||||
*aY2 = y2;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~QuadBounds() {}
|
||||
|
||||
RefPtr<DOMQuad> mQuad;
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly, mQuad)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMQuad::QuadBounds)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMRectReadOnly)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly)
|
||||
NS_IMPL_RELEASE_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly)
|
||||
*aY1 = y1;
|
||||
*aY2 = y2;
|
||||
}
|
||||
|
||||
DOMRectReadOnly*
|
||||
DOMQuad::Bounds() const
|
||||
DOMQuad::Bounds()
|
||||
{
|
||||
if (!mBounds) {
|
||||
mBounds = new QuadBounds(const_cast<DOMQuad*>(this));
|
||||
mBounds = GetBounds();
|
||||
}
|
||||
return mBounds;
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRectReadOnly>
|
||||
DOMQuad::GetBounds() const
|
||||
{
|
||||
double x1, x2;
|
||||
double y1, y2;
|
||||
|
||||
GetHorizontalMinMax(&x1, &x2);
|
||||
GetVerticalMinMax(&y1, &y2);
|
||||
|
||||
RefPtr<DOMRectReadOnly> rval = new DOMRectReadOnly(GetParentObject(),
|
||||
x1, y1, x2 - x1, y2 - y1);
|
||||
return rval.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DOMQuad::ToJSON(DOMQuadJSON& aInit)
|
||||
{
|
||||
aInit.mP1.Construct(RefPtr<DOMPoint>(P1()).forget());
|
||||
aInit.mP2.Construct(RefPtr<DOMPoint>(P2()).forget());
|
||||
aInit.mP3.Construct(RefPtr<DOMPoint>(P3()).forget());
|
||||
aInit.mP4.Construct(RefPtr<DOMPoint>(P4()).forget());
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#structured-serialization
|
||||
bool
|
||||
DOMQuad::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
|
||||
{
|
||||
for (const auto& point : mPoints) {
|
||||
if (!point->WriteStructuredClone(aWriter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMQuad::ReadStructuredClone(JSStructuredCloneReader* aReader)
|
||||
{
|
||||
for (auto& point : mPoints) {
|
||||
point = new DOMPoint(mParent);
|
||||
if (!point->ReadStructuredClone(aReader)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef MOZILLA_DOMQUAD_H_
|
||||
#define MOZILLA_DOMQUAD_H_
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
|
@ -20,7 +21,10 @@ namespace dom {
|
|||
|
||||
class DOMRectReadOnly;
|
||||
class DOMPoint;
|
||||
struct DOMQuadJSON;
|
||||
struct DOMPointInit;
|
||||
struct DOMQuadInit;
|
||||
struct DOMRectInit;
|
||||
|
||||
class DOMQuad final : public nsWrapperCache
|
||||
{
|
||||
|
|
@ -36,6 +40,12 @@ public:
|
|||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
static already_AddRefed<DOMQuad>
|
||||
FromRect(const GlobalObject& aGlobal, const DOMRectInit& aInit);
|
||||
|
||||
static already_AddRefed<DOMQuad>
|
||||
FromQuad(const GlobalObject& aGlobal, const DOMQuadInit& aInit);
|
||||
|
||||
static already_AddRefed<DOMQuad>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const DOMPointInit& aP1,
|
||||
|
|
@ -47,20 +57,28 @@ public:
|
|||
Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect,
|
||||
ErrorResult& aRV);
|
||||
|
||||
DOMRectReadOnly* Bounds() const;
|
||||
DOMRectReadOnly* Bounds();
|
||||
already_AddRefed<DOMRectReadOnly> GetBounds() const;
|
||||
DOMPoint* P1() const { return mPoints[0]; }
|
||||
DOMPoint* P2() const { return mPoints[1]; }
|
||||
DOMPoint* P3() const { return mPoints[2]; }
|
||||
DOMPoint* P4() const { return mPoints[3]; }
|
||||
|
||||
DOMPoint* Point(uint32_t aIndex) { return mPoints[aIndex]; }
|
||||
DOMPoint* Point(uint32_t aIndex) const { return mPoints[aIndex]; }
|
||||
|
||||
void ToJSON(DOMQuadJSON& aInit);
|
||||
|
||||
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
|
||||
|
||||
bool ReadStructuredClone(JSStructuredCloneReader* aReader);
|
||||
|
||||
protected:
|
||||
class QuadBounds;
|
||||
void GetHorizontalMinMax(double* aX1, double* aX2) const;
|
||||
void GetVerticalMinMax(double* aY1, double* aY2) const;
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
RefPtr<DOMPoint> mPoints[4];
|
||||
mutable RefPtr<QuadBounds> mBounds; // allocated lazily
|
||||
RefPtr<DOMRectReadOnly> mBounds;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
|||
|
|
@ -27,6 +27,59 @@ DOMRectReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|||
return DOMRectReadOnlyBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRectReadOnly>
|
||||
DOMRectReadOnly::FromRect(const GlobalObject& aGlobal, const DOMRectInit& aInit)
|
||||
{
|
||||
RefPtr<DOMRectReadOnly> obj = new DOMRectReadOnly(
|
||||
aGlobal.GetAsSupports(), aInit.mX, aInit.mY, aInit.mWidth, aInit.mHeight);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRectReadOnly>
|
||||
DOMRectReadOnly::Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
||||
double aWidth, double aHeight, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<DOMRectReadOnly> obj =
|
||||
new DOMRectReadOnly(aGlobal.GetAsSupports(), aX, aY, aWidth, aHeight);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#structured-serialization
|
||||
bool
|
||||
DOMRectReadOnly::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
|
||||
{
|
||||
#define WriteDouble(d) \
|
||||
JS_WriteUint32Pair(aWriter, (BitwiseCast<uint64_t>(d) >> 32) & 0xffffffff, \
|
||||
BitwiseCast<uint64_t>(d) & 0xffffffff)
|
||||
|
||||
return WriteDouble(mX) && WriteDouble(mY) && WriteDouble(mWidth) &&
|
||||
WriteDouble(mHeight);
|
||||
|
||||
#undef WriteDouble
|
||||
}
|
||||
|
||||
bool
|
||||
DOMRectReadOnly::ReadStructuredClone(JSStructuredCloneReader* aReader)
|
||||
{
|
||||
uint32_t high;
|
||||
uint32_t low;
|
||||
|
||||
#define ReadDouble(d) \
|
||||
if (!JS_ReadUint32Pair(aReader, &high, &low)) { \
|
||||
return false; \
|
||||
} \
|
||||
(*(d) = BitwiseCast<double>(static_cast<uint64_t>(high) << 32 | low))
|
||||
|
||||
ReadDouble(&mX);
|
||||
ReadDouble(&mY);
|
||||
ReadDouble(&mWidth);
|
||||
ReadDouble(&mHeight);
|
||||
|
||||
return true;
|
||||
|
||||
#undef ReadDouble
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(DOMRect, DOMRectReadOnly, nsIDOMClientRect)
|
||||
|
|
@ -54,16 +107,16 @@ DOMRect::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|||
}
|
||||
|
||||
already_AddRefed<DOMRect>
|
||||
DOMRect::Constructor(const GlobalObject& aGlobal, ErrorResult& aRV)
|
||||
DOMRect::FromRect(const GlobalObject& aGlobal, const DOMRectInit& aInit)
|
||||
{
|
||||
RefPtr<DOMRect> obj =
|
||||
new DOMRect(aGlobal.GetAsSupports(), 0.0, 0.0, 0.0, 0.0);
|
||||
RefPtr<DOMRect> obj = new DOMRect(aGlobal.GetAsSupports(), aInit.mX, aInit.mY,
|
||||
aInit.mWidth, aInit.mHeight);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRect>
|
||||
DOMRect::Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
||||
double aWidth, double aHeight, ErrorResult& aRV)
|
||||
double aWidth, double aHeight, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<DOMRect> obj =
|
||||
new DOMRect(aGlobal.GetAsSupports(), aX, aY, aWidth, aHeight);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef MOZILLA_DOMRECT_H_
|
||||
#define MOZILLA_DOMRECT_H_
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "nsIDOMClientRect.h"
|
||||
#include "nsIDOMClientRectList.h"
|
||||
#include "nsTArray.h"
|
||||
|
|
@ -22,6 +23,8 @@ struct nsRect;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct DOMRectInit;
|
||||
|
||||
class DOMRectReadOnly : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
|
|
@ -32,8 +35,13 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectReadOnly)
|
||||
|
||||
explicit DOMRectReadOnly(nsISupports* aParent)
|
||||
explicit DOMRectReadOnly(nsISupports* aParent, double aX = 0, double aY = 0,
|
||||
double aWidth = 0, double aHeight = 0)
|
||||
: mParent(aParent)
|
||||
, mX(aX)
|
||||
, mY(aY)
|
||||
, mWidth(aWidth)
|
||||
, mHeight(aHeight)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -44,10 +52,29 @@ public:
|
|||
}
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
virtual double X() const = 0;
|
||||
virtual double Y() const = 0;
|
||||
virtual double Width() const = 0;
|
||||
virtual double Height() const = 0;
|
||||
static already_AddRefed<DOMRectReadOnly>
|
||||
FromRect(const GlobalObject& aGlobal, const DOMRectInit& aInit);
|
||||
|
||||
static already_AddRefed<DOMRectReadOnly>
|
||||
Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
||||
double aWidth, double aHeight, ErrorResult& aRv);
|
||||
|
||||
double X() const
|
||||
{
|
||||
return mX;
|
||||
}
|
||||
double Y() const
|
||||
{
|
||||
return mY;
|
||||
}
|
||||
double Width() const
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
double Height() const
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
double Left() const
|
||||
{
|
||||
|
|
@ -70,8 +97,13 @@ public:
|
|||
return std::max(y, y + h);
|
||||
}
|
||||
|
||||
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
|
||||
|
||||
bool ReadStructuredClone(JSStructuredCloneReader* aReader);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
double mX, mY, mWidth, mHeight;
|
||||
};
|
||||
|
||||
class DOMRect final : public DOMRectReadOnly
|
||||
|
|
@ -80,22 +112,19 @@ class DOMRect final : public DOMRectReadOnly
|
|||
public:
|
||||
explicit DOMRect(nsISupports* aParent, double aX = 0, double aY = 0,
|
||||
double aWidth = 0, double aHeight = 0)
|
||||
: DOMRectReadOnly(aParent)
|
||||
, mX(aX)
|
||||
, mY(aY)
|
||||
, mWidth(aWidth)
|
||||
, mHeight(aHeight)
|
||||
: DOMRectReadOnly(aParent, aX, aY, aWidth, aHeight)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMCLIENTRECT
|
||||
|
||||
static already_AddRefed<DOMRect>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRV);
|
||||
FromRect(const GlobalObject& aGlobal, const DOMRectInit& aInit);
|
||||
|
||||
static already_AddRefed<DOMRect>
|
||||
Constructor(const GlobalObject& aGlobal, double aX, double aY,
|
||||
double aWidth, double aHeight, ErrorResult& aRV);
|
||||
double aWidth, double aHeight, ErrorResult& aRv);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
|
|
@ -104,23 +133,6 @@ public:
|
|||
}
|
||||
void SetLayoutRect(const nsRect& aLayoutRect);
|
||||
|
||||
virtual double X() const override
|
||||
{
|
||||
return mX;
|
||||
}
|
||||
virtual double Y() const override
|
||||
{
|
||||
return mY;
|
||||
}
|
||||
virtual double Width() const override
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
virtual double Height() const override
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
void SetX(double aX)
|
||||
{
|
||||
mX = aX;
|
||||
|
|
@ -138,11 +150,8 @@ public:
|
|||
mHeight = aHeight;
|
||||
}
|
||||
|
||||
protected:
|
||||
double mX, mY, mWidth, mHeight;
|
||||
|
||||
private:
|
||||
~DOMRect() {};
|
||||
~DOMRect() {}
|
||||
};
|
||||
|
||||
class DOMRectList final : public nsIDOMClientRectList,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,14 @@
|
|||
#include "mozilla/dom/CryptoKey.h"
|
||||
#include "mozilla/dom/Directory.h"
|
||||
#include "mozilla/dom/DirectoryBinding.h"
|
||||
#include "mozilla/dom/DOMMatrix.h"
|
||||
#include "mozilla/dom/DOMMatrixBinding.h"
|
||||
#include "mozilla/dom/DOMPoint.h"
|
||||
#include "mozilla/dom/DOMPointBinding.h"
|
||||
#include "mozilla/dom/DOMQuad.h"
|
||||
#include "mozilla/dom/DOMQuadBinding.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
#include "mozilla/dom/DOMRectBinding.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileList.h"
|
||||
#include "mozilla/dom/FileListBinding.h"
|
||||
|
|
@ -355,7 +363,11 @@ StructuredCloneHolder::ReadFullySerializableObjects(JSContext* aCx,
|
|||
return ReadStructuredCloneImageData(aCx, aReader);
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_WEBCRYPTO_KEY || aTag == SCTAG_DOM_URLSEARCHPARAMS) {
|
||||
if (aTag == SCTAG_DOM_WEBCRYPTO_KEY || aTag == SCTAG_DOM_URLSEARCHPARAMS ||
|
||||
aTag == SCTAG_DOM_DOMPOINT || aTag == SCTAG_DOM_DOMPOINT_READONLY ||
|
||||
aTag == SCTAG_DOM_DOMRECT || aTag == SCTAG_DOM_DOMRECT_READONLY ||
|
||||
aTag == SCTAG_DOM_DOMQUAD || aTag == SCTAG_DOM_DOMMATRIX ||
|
||||
aTag == SCTAG_DOM_DOMMATRIX_READONLY) {
|
||||
nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
if (!global) {
|
||||
return nullptr;
|
||||
|
|
@ -378,6 +390,57 @@ StructuredCloneHolder::ReadFullySerializableObjects(JSContext* aCx,
|
|||
} else {
|
||||
result = usp->WrapObject(aCx, nullptr);
|
||||
}
|
||||
} else if (aTag == SCTAG_DOM_DOMPOINT) {
|
||||
RefPtr<DOMPoint> domPoint = new DOMPoint(global);
|
||||
if (!domPoint->ReadStructuredClone(aReader)) {
|
||||
result = nullptr;
|
||||
} else {
|
||||
result = domPoint->WrapObject(aCx, nullptr);
|
||||
}
|
||||
} else if (aTag == SCTAG_DOM_DOMPOINT_READONLY) {
|
||||
RefPtr<DOMPointReadOnly> domPoint = new DOMPointReadOnly(global);
|
||||
if (!domPoint->ReadStructuredClone(aReader)) {
|
||||
result = nullptr;
|
||||
} else {
|
||||
result = domPoint->WrapObject(aCx, nullptr);
|
||||
}
|
||||
} else if (aTag == SCTAG_DOM_DOMRECT) {
|
||||
RefPtr<DOMRect> domRect = new DOMRect(global);
|
||||
if (!domRect->ReadStructuredClone(aReader)) {
|
||||
result = nullptr;
|
||||
} else {
|
||||
result = domRect->WrapObject(aCx, nullptr);
|
||||
}
|
||||
} else if (aTag == SCTAG_DOM_DOMRECT_READONLY) {
|
||||
RefPtr<DOMRectReadOnly> domRect = new DOMRectReadOnly(global);
|
||||
if (!domRect->ReadStructuredClone(aReader)) {
|
||||
result = nullptr;
|
||||
} else {
|
||||
result = domRect->WrapObject(aCx, nullptr);
|
||||
}
|
||||
} else if (aTag == SCTAG_DOM_DOMQUAD) {
|
||||
RefPtr<DOMQuad> domQuad = new DOMQuad(global);
|
||||
if (!domQuad->ReadStructuredClone(aReader)) {
|
||||
result = nullptr;
|
||||
} else {
|
||||
result = domQuad->WrapObject(aCx, nullptr);
|
||||
}
|
||||
} else if (aTag == SCTAG_DOM_DOMMATRIX) {
|
||||
RefPtr<DOMMatrix> domMatrix =
|
||||
DOMMatrix::ReadStructuredClone(global, aReader);
|
||||
if (!domMatrix) {
|
||||
result = nullptr;
|
||||
} else {
|
||||
result = domMatrix->WrapObject(aCx, nullptr);
|
||||
}
|
||||
} else if (aTag == SCTAG_DOM_DOMMATRIX_READONLY) {
|
||||
RefPtr<DOMMatrixReadOnly> domMatrix =
|
||||
DOMMatrixReadOnly::ReadStructuredClone(global, aReader);
|
||||
if (!domMatrix) {
|
||||
result = nullptr;
|
||||
} else {
|
||||
result = domMatrix->WrapObject(aCx, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
@ -483,6 +546,75 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
|||
}
|
||||
#endif
|
||||
|
||||
// Handle DOMPoint cloning
|
||||
// Should be done before DOMPointeReadOnly check
|
||||
// because every DOMPoint is also a DOMPointReadOnly
|
||||
{
|
||||
DOMPoint* domPoint = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(DOMPoint, &obj, domPoint))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DOMPOINT, 0) &&
|
||||
domPoint->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle DOMPointReadOnly cloning
|
||||
{
|
||||
DOMPointReadOnly* domPoint = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(DOMPointReadOnly, &obj, domPoint))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DOMPOINT_READONLY, 0) &&
|
||||
domPoint->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle DOMRect cloning
|
||||
// Should be done before DOMRecteReadOnly check
|
||||
// because every DOMRect is also a DOMRectReadOnly
|
||||
{
|
||||
DOMRect* domRect = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(DOMRect, &obj, domRect))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DOMRECT, 0) &&
|
||||
domRect->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle DOMRectReadOnly cloning
|
||||
{
|
||||
DOMRectReadOnly* domRect = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(DOMRectReadOnly, &obj, domRect))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DOMRECT_READONLY, 0) &&
|
||||
domRect->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle DOMQuad cloning
|
||||
{
|
||||
DOMQuad* domQuad = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(DOMQuad, &obj, domQuad))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DOMQUAD, 0) &&
|
||||
domQuad->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle DOMMatrix cloning
|
||||
// Should be done before DOMMatrixeReadOnly check
|
||||
// because every DOMMatrix is also a DOMMatrixReadOnly
|
||||
{
|
||||
DOMMatrix* domMatrix = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(DOMMatrix, &obj, domMatrix))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DOMMATRIX, 0) &&
|
||||
domMatrix->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle DOMMatrixReadOnly cloning
|
||||
{
|
||||
DOMMatrixReadOnly* domMatrix = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(DOMMatrixReadOnly, &obj, domMatrix))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DOMMATRIX_READONLY, 0) &&
|
||||
domMatrix->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_IsMainThread() && xpc::IsReflector(obj)) {
|
||||
nsCOMPtr<nsISupports> base = xpc::UnwrapReflectorToISupports(obj);
|
||||
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(base);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,15 @@ enum StructuredCloneTags {
|
|||
|
||||
// New IDB tags go here!
|
||||
|
||||
// Tags for Geometry interfaces.
|
||||
SCTAG_DOM_DOMPOINT,
|
||||
SCTAG_DOM_DOMPOINT_READONLY,
|
||||
SCTAG_DOM_DOMQUAD,
|
||||
SCTAG_DOM_DOMRECT,
|
||||
SCTAG_DOM_DOMRECT_READONLY,
|
||||
SCTAG_DOM_DOMMATRIX,
|
||||
SCTAG_DOM_DOMMATRIX_READONLY,
|
||||
|
||||
// These tags are used for both main thread and workers.
|
||||
SCTAG_DOM_IMAGEDATA,
|
||||
SCTAG_DOM_MAP_MESSAGEPORT,
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ static const double sRadPerDegree = 2.0 * M_PI / 360.0;
|
|||
bool
|
||||
WebKitCSSMatrix::FeatureEnabled(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
return Preferences::GetBool("layout.css.DOMMatrix.enabled", false) &&
|
||||
Preferences::GetBool("layout.css.prefixes.webkit", false);
|
||||
return Preferences::GetBool("layout.css.prefixes.webkit", false);
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
|
|
@ -115,10 +114,10 @@ WebKitCSSMatrix::SetMatrixValue(const nsAString& aTransformList,
|
|||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Multiply(const WebKitCSSMatrix& other) const
|
||||
WebKitCSSMatrix::Multiply(const DOMMatrixInit& aOtherInit, ErrorResult& aRv) const
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->MultiplySelf(other);
|
||||
retval->MultiplySelf(aOtherInit, aRv);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ public:
|
|||
WebKitCSSMatrix* SetMatrixValue(const nsAString& aTransformList,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix> Multiply(const WebKitCSSMatrix& aOther) const;
|
||||
already_AddRefed<WebKitCSSMatrix> Multiply(const DOMMatrixInit& aOtherInit,
|
||||
ErrorResult& aRv) const;
|
||||
already_AddRefed<WebKitCSSMatrix> Inverse(ErrorResult& aRv) const;
|
||||
already_AddRefed<WebKitCSSMatrix> Translate(double aTx,
|
||||
double aTy,
|
||||
|
|
|
|||
|
|
@ -47,3 +47,4 @@ DEPRECATED_OPERATION(PrefixedFullscreenAPI)
|
|||
DEPRECATED_OPERATION(LenientSetter)
|
||||
DEPRECATED_OPERATION(FileLastModifiedDate)
|
||||
DEPRECATED_OPERATION(ImageBitmapRenderingContext_TransferImageBitmap)
|
||||
DEPRECATED_OPERATION(DOMQuadBoundsAttr)
|
||||
|
|
|
|||
|
|
@ -253,12 +253,10 @@ DOMInterfaces = {
|
|||
|
||||
'DOMMatrixReadOnly': {
|
||||
'headerFile': 'mozilla/dom/DOMMatrix.h',
|
||||
'concrete': False,
|
||||
},
|
||||
|
||||
'DOMPointReadOnly': {
|
||||
'headerFile': 'mozilla/dom/DOMPoint.h',
|
||||
'concrete': False,
|
||||
},
|
||||
|
||||
'DOMRectList': {
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ MSG_DEF(MSG_TIME_VALUE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "{0} is outside the suppo
|
|||
MSG_DEF(MSG_ONLY_IF_CACHED_WITHOUT_SAME_ORIGIN, 1, JSEXN_TYPEERR, "Request mode '{0}' was used, but request cache mode 'only-if-cached' can only be used with request mode 'same-origin'.")
|
||||
MSG_DEF(MSG_THRESHOLD_RANGE_ERROR, 0, JSEXN_RANGEERR, "Threshold values must all be in the range [0, 1].")
|
||||
MSG_DEF(MSG_CACHE_OPEN_FAILED, 0, JSEXN_TYPEERR, "CacheStorage.open() failed to access the storage system.")
|
||||
MSG_DEF(MSG_MATRIX_INIT_CONFLICTING_VALUE, 2, JSEXN_TYPEERR, "Matrix init unexpectedly got different values for '{0}' and '{1}'.")
|
||||
MSG_DEF(MSG_MATRIX_INIT_EXCEEDS_2D, 1, JSEXN_TYPEERR, "Matrix init has an unexpected 3D element '{0}' which cannot coexist with 'is2D: true'.")
|
||||
MSG_DEF(MSG_MATRIX_INIT_LENGTH_WRONG, 1, JSEXN_TYPEERR, "Matrix init sequence must have a length of 6 or 16 (actual value: {0})")
|
||||
MSG_DEF(MSG_NO_NEGATIVE_ATTR, 1, JSEXN_TYPEERR, "Given attribute {0} cannot be negative.")
|
||||
MSG_DEF(MSG_PMO_NO_SEPARATE_ENDMARK, 0, JSEXN_TYPEERR, "Cannot provide separate endMark argument if PerformanceMeasureOptions argument is given.")
|
||||
MSG_DEF(MSG_PMO_MISSING_STARTENDMARK, 0, JSEXN_TYPEERR, "PerformanceMeasureOptions must have start and/or end member.")
|
||||
|
|
|
|||
|
|
@ -320,3 +320,4 @@ LargeAllocationNonE10S=A Large-Allocation header was ignored due to the document
|
|||
PushStateFloodingPrevented=Call to pushState or replaceState ignored due to excessive calls within a short timeframe.
|
||||
# LOCALIZATION NOTE: Do not translate "Reload"
|
||||
ReloadFloodingPrevented=Call to Reload ignored due to excessive calls within a short timeframe.
|
||||
DOMQuadBoundsAttrWarning=DOMQuad.bounds is deprecated in favor of DOMQuad.getBounds()
|
||||
|
|
|
|||
|
|
@ -4,14 +4,19 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dev.w3.org/fxtf/geometry/
|
||||
* https://drafts.fxtf.org/geometry/
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="layout.css.DOMMatrix.enabled"]
|
||||
[Constructor(optional (DOMString or sequence<unrestricted double>) init),
|
||||
Exposed=(Window,Worker)]
|
||||
interface DOMMatrixReadOnly {
|
||||
[NewObject, Throws] static DOMMatrixReadOnly fromMatrix(optional DOMMatrixInit other);
|
||||
[NewObject, Throws] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32);
|
||||
[NewObject, Throws] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64);
|
||||
|
||||
// These attributes are simple aliases for certain elements of the 4x4 matrix
|
||||
readonly attribute unrestricted double a;
|
||||
readonly attribute unrestricted double b;
|
||||
|
|
@ -65,7 +70,7 @@ interface DOMMatrixReadOnly {
|
|||
unrestricted double angle);
|
||||
DOMMatrix skewX(unrestricted double sx);
|
||||
DOMMatrix skewY(unrestricted double sy);
|
||||
DOMMatrix multiply(DOMMatrix other);
|
||||
[NewObject, Throws] DOMMatrix multiply(optional DOMMatrixInit other);
|
||||
DOMMatrix flipX();
|
||||
DOMMatrix flipY();
|
||||
DOMMatrix inverse();
|
||||
|
|
@ -76,17 +81,21 @@ interface DOMMatrixReadOnly {
|
|||
DOMPoint transformPoint(optional DOMPointInit point);
|
||||
[Throws] Float32Array toFloat32Array();
|
||||
[Throws] Float64Array toFloat64Array();
|
||||
stringifier;
|
||||
[Exposed=Window] stringifier;
|
||||
};
|
||||
|
||||
[Pref="layout.css.DOMMatrix.enabled",
|
||||
Constructor,
|
||||
[Constructor,
|
||||
Constructor(DOMString transformList),
|
||||
Constructor(DOMMatrixReadOnly other),
|
||||
Constructor(Float32Array array32),
|
||||
Constructor(Float64Array array64),
|
||||
Constructor(sequence<unrestricted double> numberSequence)]
|
||||
Constructor(sequence<unrestricted double> numberSequence),
|
||||
Exposed=(Window,Worker)]
|
||||
interface DOMMatrix : DOMMatrixReadOnly {
|
||||
[NewObject, Throws] static DOMMatrix fromMatrix(optional DOMMatrixInit other);
|
||||
[NewObject, Throws] static DOMMatrix fromFloat32Array(Float32Array array32);
|
||||
[NewObject, Throws] static DOMMatrix fromFloat64Array(Float64Array array64);
|
||||
|
||||
// These attributes are simple aliases for certain elements of the 4x4 matrix
|
||||
inherit attribute unrestricted double a;
|
||||
inherit attribute unrestricted double b;
|
||||
|
|
@ -113,8 +122,8 @@ interface DOMMatrix : DOMMatrixReadOnly {
|
|||
inherit attribute unrestricted double m44;
|
||||
|
||||
// Mutable transform methods
|
||||
DOMMatrix multiplySelf(DOMMatrix other);
|
||||
DOMMatrix preMultiplySelf(DOMMatrix other);
|
||||
[Throws] DOMMatrix multiplySelf(optional DOMMatrixInit other);
|
||||
[Throws] DOMMatrix preMultiplySelf(optional DOMMatrixInit other);
|
||||
DOMMatrix translateSelf(unrestricted double tx,
|
||||
unrestricted double ty,
|
||||
optional unrestricted double tz = 0);
|
||||
|
|
@ -143,6 +152,34 @@ interface DOMMatrix : DOMMatrixReadOnly {
|
|||
DOMMatrix skewXSelf(unrestricted double sx);
|
||||
DOMMatrix skewYSelf(unrestricted double sy);
|
||||
DOMMatrix invertSelf();
|
||||
[Throws] DOMMatrix setMatrixValue(DOMString transformList);
|
||||
[Exposed=Window, Throws] DOMMatrix setMatrixValue(DOMString transformList);
|
||||
};
|
||||
|
||||
dictionary DOMMatrix2DInit {
|
||||
unrestricted double a;
|
||||
unrestricted double b;
|
||||
unrestricted double c;
|
||||
unrestricted double d;
|
||||
unrestricted double e;
|
||||
unrestricted double f;
|
||||
unrestricted double m11;
|
||||
unrestricted double m12;
|
||||
unrestricted double m21;
|
||||
unrestricted double m22;
|
||||
unrestricted double m41;
|
||||
unrestricted double m42;
|
||||
};
|
||||
|
||||
dictionary DOMMatrixInit : DOMMatrix2DInit {
|
||||
unrestricted double m13 = 0;
|
||||
unrestricted double m14 = 0;
|
||||
unrestricted double m23 = 0;
|
||||
unrestricted double m24 = 0;
|
||||
unrestricted double m31 = 0;
|
||||
unrestricted double m32 = 0;
|
||||
unrestricted double m33 = 1;
|
||||
unrestricted double m34 = 0;
|
||||
unrestricted double m43 = 0;
|
||||
unrestricted double m44 = 1;
|
||||
boolean is2D;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,25 +4,30 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dev.w3.org/fxtf/geometry/
|
||||
* https://drafts.fxtf.org/geometry/
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="layout.css.DOMPoint.enabled"]
|
||||
[Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
|
||||
optional unrestricted double z = 0, optional unrestricted double w = 1),
|
||||
Exposed=(Window,Worker)]
|
||||
interface DOMPointReadOnly {
|
||||
[NewObject] static DOMPointReadOnly fromPoint(optional DOMPointInit other);
|
||||
|
||||
readonly attribute unrestricted double x;
|
||||
readonly attribute unrestricted double y;
|
||||
readonly attribute unrestricted double z;
|
||||
readonly attribute unrestricted double w;
|
||||
};
|
||||
|
||||
[Pref="layout.css.DOMPoint.enabled",
|
||||
Constructor(optional DOMPointInit point),
|
||||
Constructor(unrestricted double x, unrestricted double y,
|
||||
optional unrestricted double z = 0, optional unrestricted double w = 1)]
|
||||
[Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
|
||||
optional unrestricted double z = 0, optional unrestricted double w = 1),
|
||||
Exposed=(Window,Worker)]
|
||||
interface DOMPoint : DOMPointReadOnly {
|
||||
[NewObject] static DOMPoint fromPoint(optional DOMPointInit other);
|
||||
|
||||
inherit attribute unrestricted double x;
|
||||
inherit attribute unrestricted double y;
|
||||
inherit attribute unrestricted double z;
|
||||
|
|
@ -34,4 +39,4 @@ dictionary DOMPointInit {
|
|||
unrestricted double y = 0;
|
||||
unrestricted double z = 0;
|
||||
unrestricted double w = 1;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,20 +4,41 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dev.w3.org/fxtf/geometry/
|
||||
* https://drafts.fxtf.org/geometry/
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="layout.css.DOMQuad.enabled",
|
||||
Constructor(optional DOMPointInit p1, optional DOMPointInit p2,
|
||||
[Constructor(optional DOMPointInit p1, optional DOMPointInit p2,
|
||||
optional DOMPointInit p3, optional DOMPointInit p4),
|
||||
Constructor(DOMRectReadOnly rect)]
|
||||
Constructor(DOMRectReadOnly rect),
|
||||
Exposed=(Window,Worker)]
|
||||
interface DOMQuad {
|
||||
[NewObject] static DOMQuad fromRect(optional DOMRectInit other);
|
||||
[NewObject] static DOMQuad fromQuad(optional DOMQuadInit other);
|
||||
|
||||
[SameObject] readonly attribute DOMPoint p1;
|
||||
[SameObject] readonly attribute DOMPoint p2;
|
||||
[SameObject] readonly attribute DOMPoint p3;
|
||||
[SameObject] readonly attribute DOMPoint p4;
|
||||
[SameObject] readonly attribute DOMRectReadOnly bounds;
|
||||
};
|
||||
[NewObject] DOMRectReadOnly getBounds();
|
||||
|
||||
[SameObject, Deprecated=DOMQuadBoundsAttr] readonly attribute DOMRectReadOnly bounds;
|
||||
|
||||
DOMQuadJSON toJSON();
|
||||
};
|
||||
|
||||
dictionary DOMQuadJSON {
|
||||
DOMPoint p1;
|
||||
DOMPoint p2;
|
||||
DOMPoint p3;
|
||||
DOMPoint p4;
|
||||
};
|
||||
|
||||
dictionary DOMQuadInit {
|
||||
DOMPointInit p1 = null;
|
||||
DOMPointInit p2 = null;
|
||||
DOMPointInit p3 = null;
|
||||
DOMPointInit p4 = null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,23 +4,30 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dev.w3.org/fxtf/geometry/
|
||||
* https://drafts.fxtf.org/geometry/
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Constructor,
|
||||
Constructor(unrestricted double x, unrestricted double y,
|
||||
unrestricted double width, unrestricted double height)]
|
||||
[Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
|
||||
optional unrestricted double width = 0, optional unrestricted double height = 0),
|
||||
Exposed=(Window,Worker)]
|
||||
interface DOMRect : DOMRectReadOnly {
|
||||
[NewObject] static DOMRect fromRect(optional DOMRectInit other);
|
||||
|
||||
inherit attribute unrestricted double x;
|
||||
inherit attribute unrestricted double y;
|
||||
inherit attribute unrestricted double width;
|
||||
inherit attribute unrestricted double height;
|
||||
};
|
||||
|
||||
[Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
|
||||
optional unrestricted double width = 0, optional unrestricted double height = 0),
|
||||
Exposed=(Window,Worker)]
|
||||
interface DOMRectReadOnly {
|
||||
[NewObject] static DOMRectReadOnly fromRect(optional DOMRectInit other);
|
||||
|
||||
readonly attribute unrestricted double x;
|
||||
readonly attribute unrestricted double y;
|
||||
readonly attribute unrestricted double width;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ interface WebKitCSSMatrix : DOMMatrix {
|
|||
WebKitCSSMatrix setMatrixValue(DOMString transformList);
|
||||
|
||||
// Immutable transform methods
|
||||
WebKitCSSMatrix multiply(WebKitCSSMatrix other);
|
||||
[Throws]
|
||||
WebKitCSSMatrix multiply(optional DOMMatrixInit other);
|
||||
[Throws]
|
||||
WebKitCSSMatrix inverse();
|
||||
WebKitCSSMatrix translate(optional unrestricted double tx = 0,
|
||||
|
|
|
|||
68
js/public/Equality.h
Normal file
68
js/public/Equality.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Equality operations. */
|
||||
|
||||
#ifndef js_Equality_h
|
||||
#define js_Equality_h
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
|
||||
#include "jstypes.h" // JS_PUBLIC_API
|
||||
|
||||
#include "js/RootingAPI.h" // JS::Handle
|
||||
#include "js/Value.h" // JS::Value
|
||||
|
||||
struct JSContext;
|
||||
|
||||
namespace JS {
|
||||
|
||||
/**
|
||||
* Store |v1 === v2| to |*equal| -- strict equality, which performs no
|
||||
* conversions on |v1| or |v2| before comparing.
|
||||
*
|
||||
* This operation can fail only if an internal error occurs (e.g. OOM while
|
||||
* linearizing a string value).
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
StrictlyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
|
||||
|
||||
/**
|
||||
* Store |v1 == v2| to |*equal| -- loose equality, which may perform
|
||||
* user-modifiable conversions on |v1| or |v2|.
|
||||
*
|
||||
* This operation can fail if a user-modifiable conversion fails *or* if an
|
||||
* internal error occurs. (e.g. OOM while linearizing a string value).
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
LooselyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
|
||||
|
||||
/**
|
||||
* Stores |SameValue(v1, v2)| to |*equal| -- using the SameValue operation
|
||||
* defined in ECMAScript, initially exposed to script as |Object.is|. SameValue
|
||||
* behaves identically to strict equality, except that it equates two NaN values
|
||||
* and does not equate differently-signed zeroes. It performs no conversions on
|
||||
* |v1| or |v2| before comparing.
|
||||
*
|
||||
* This operation can fail only if an internal error occurs (e.g. OOM while
|
||||
* linearizing a string value).
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
SameValue(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* same);
|
||||
|
||||
/**
|
||||
* Implements |SameValueZero(v1, v2)| for Number values |v1| and |v2|.
|
||||
* SameValueZero equates NaNs, equal nonzero values, and zeroes without respect
|
||||
* to their signs.
|
||||
*/
|
||||
static inline bool
|
||||
SameValueZero(double v1, double v2)
|
||||
{
|
||||
return mozilla::EqualOrBothNaN(v1, v2);
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif /* js_Equality_h */
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
#include "ds/OrderedHashTable.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "js/Utility.h"
|
||||
#include "vm/EqualityOperations.h" // js::SameValue
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Interpreter.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "jit/InlinableNatives.h"
|
||||
#include "js/UniquePtr.h"
|
||||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/EqualityOperations.h" // js::SameValue
|
||||
#include "vm/StringBuffer.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "jit/mips64/Simulator-mips64.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EqualityOperations.h" // js::StrictlyEqual
|
||||
#include "vm/Interpreter.h"
|
||||
#include "vm/TraceLogging.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
#include <limits>
|
||||
#include <math.h>
|
||||
|
||||
#include "js/Equality.h" // JS::LooselyEqual
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -15,15 +17,15 @@ struct LooseEqualityFixture : public JSAPITest
|
|||
|
||||
bool leq(JS::HandleValue x, JS::HandleValue y) {
|
||||
bool equal;
|
||||
CHECK(JS_LooselyEqual(cx, x, y, &equal) && equal);
|
||||
CHECK(JS_LooselyEqual(cx, y, x, &equal) && equal);
|
||||
CHECK(JS::LooselyEqual(cx, x, y, &equal) && equal);
|
||||
CHECK(JS::LooselyEqual(cx, y, x, &equal) && equal);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nleq(JS::HandleValue x, JS::HandleValue y) {
|
||||
bool equal;
|
||||
CHECK(JS_LooselyEqual(cx, x, y, &equal) && !equal);
|
||||
CHECK(JS_LooselyEqual(cx, y, x, &equal) && !equal);
|
||||
CHECK(JS::LooselyEqual(cx, x, y, &equal) && !equal);
|
||||
CHECK(JS::LooselyEqual(cx, y, x, &equal) && !equal);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "js/Equality.h" // JS::SameValue
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
BEGIN_TEST(testSameValue)
|
||||
|
|
@ -11,7 +12,7 @@ BEGIN_TEST(testSameValue)
|
|||
|
||||
/*
|
||||
* NB: passing a double that fits in an integer jsval is API misuse. As a
|
||||
* matter of defense in depth, however, JS_SameValue should return the
|
||||
* matter of defense in depth, however, JS::SameValue should return the
|
||||
* correct result comparing a positive-zero double to a negative-zero
|
||||
* double, and this is believed to be the only way to make such a
|
||||
* comparison possible.
|
||||
|
|
@ -19,7 +20,7 @@ BEGIN_TEST(testSameValue)
|
|||
JS::RootedValue v1(cx, JS::DoubleValue(0.0));
|
||||
JS::RootedValue v2(cx, JS::DoubleValue(-0.0));
|
||||
bool same;
|
||||
CHECK(JS_SameValue(cx, v1, v2, &same));
|
||||
CHECK(JS::SameValue(cx, v1, v2, &same));
|
||||
CHECK(!same);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "jscntxt.h"
|
||||
#include "jsgc.h"
|
||||
|
||||
#include "js/Equality.h" // JS::SameValue
|
||||
#include "js/Vector.h"
|
||||
|
||||
/* Note: Aborts on OOM. */
|
||||
|
|
@ -201,9 +202,9 @@ class JSAPITest
|
|||
const char* filename, int lineno) {
|
||||
bool same;
|
||||
JS::RootedValue actual(cx, actualArg), expected(cx, expectedArg);
|
||||
return (JS_SameValue(cx, actual, expected, &same) && same) ||
|
||||
fail(JSAPITestString("CHECK_SAME failed: expected JS_SameValue(cx, ") +
|
||||
actualExpr + ", " + expectedExpr + "), got !JS_SameValue(cx, " +
|
||||
return (JS::SameValue(cx, actual, expected, &same) && same) ||
|
||||
fail(JSAPITestString("CHECK_SAME failed: expected JS::SameValue(cx, ") +
|
||||
actualExpr + ", " + expectedExpr + "), got !JS::SameValue(cx, " +
|
||||
jsvalToSource(actual) + ", " + jsvalToSource(expected) + ")", filename, lineno);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -391,36 +391,6 @@ JS_TypeOfValue(JSContext* cx, HandleValue value)
|
|||
return TypeOfValue(value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_StrictlyEqual(JSContext* cx, HandleValue value1, HandleValue value2, bool* equal)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, value1, value2);
|
||||
MOZ_ASSERT(equal);
|
||||
return StrictlyEqual(cx, value1, value2, equal);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_LooselyEqual(JSContext* cx, HandleValue value1, HandleValue value2, bool* equal)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, value1, value2);
|
||||
MOZ_ASSERT(equal);
|
||||
return LooselyEqual(cx, value1, value2, equal);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SameValue(JSContext* cx, HandleValue value1, HandleValue value2, bool* same)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, value1, value2);
|
||||
MOZ_ASSERT(same);
|
||||
return SameValue(cx, value1, value2, same);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_IsBuiltinEvalFunction(JSFunction* fun)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -959,15 +959,6 @@ InformalValueTypeName(const JS::Value& v);
|
|||
|
||||
} /* namespace JS */
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_StrictlyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_LooselyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_SameValue(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* same);
|
||||
|
||||
/** True iff fun is the global eval function. */
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsBuiltinEvalFunction(JSFunction* fun);
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ EXPORTS.js += [
|
|||
'../public/Conversions.h',
|
||||
'../public/Date.h',
|
||||
'../public/Debug.h',
|
||||
'../public/Equality.h',
|
||||
'../public/GCAnnotations.h',
|
||||
'../public/GCAPI.h',
|
||||
'../public/GCHashTable.h',
|
||||
|
|
@ -293,6 +294,7 @@ main_deunified_sources = [
|
|||
'vm/Debugger.cpp',
|
||||
'vm/DebuggerMemory.cpp',
|
||||
'vm/EnvironmentObject.cpp',
|
||||
'vm/EqualityOperations.cpp',
|
||||
'vm/ErrorObject.cpp',
|
||||
'vm/ForOfIterator.cpp',
|
||||
'vm/GeneratorObject.cpp',
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "vm/EqualityOperations.h" // js::SameValue
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
#include "vm/NativeObject-inl.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
#include "jit/JitcodeMap.h"
|
||||
#include "jit/OptimizationTracking.h"
|
||||
#include "js/Debug.h"
|
||||
#include "js/Equality.h" // JS::SameValue
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/Initialization.h"
|
||||
#include "js/StructuredClone.h"
|
||||
|
|
@ -2286,7 +2287,7 @@ AssertEq(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
bool same;
|
||||
if (!JS_SameValue(cx, args[0], args[1], &same))
|
||||
if (!JS::SameValue(cx, args[0], args[1], &same))
|
||||
return false;
|
||||
if (!same) {
|
||||
JSAutoByteString bytes0, bytes1;
|
||||
|
|
|
|||
215
js/src/vm/EqualityOperations.cpp
Normal file
215
js/src/vm/EqualityOperations.cpp
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "vm/EqualityOperations.h" // js::LooselyEqual, js::StrictlyEqual, js::SameValue
|
||||
|
||||
#include "mozilla/Assertions.h" // MOZ_ASSERT, MOZ_ASSERT_IF
|
||||
|
||||
#include "jsapi.h" // js::AssertHeapIsIdle, CHECK_REQUEST
|
||||
#include "jsnum.h" // js::StringToNumber
|
||||
#include "jsobj.h" // js::ToPrimitive
|
||||
#include "jsstr.h" // js::EqualStrings
|
||||
#include "jstypes.h" // JS_PUBLIC_API
|
||||
|
||||
#include "js/Equality.h" // JS::LooselyEqual, JS::StrictlyEqual, JS::SameValue
|
||||
#include "js/RootingAPI.h" // JS::Rooted, JS::Handle
|
||||
#include "js/Value.h" // JS::Int32Value, JS::SameType, JS::Value
|
||||
|
||||
#include "jsboolinlines.h" // js::EmulatesUndefined
|
||||
#include "jscntxtinlines.h" // js::assertSameCompartment
|
||||
|
||||
static inline bool
|
||||
EqualGivenSameType(JSContext* cx, JS::HandleValue lval, JS::HandleValue rval, bool* equal)
|
||||
{
|
||||
MOZ_ASSERT(SameType(lval, rval));
|
||||
|
||||
if (lval.isString())
|
||||
return EqualStrings(cx, lval.toString(), rval.toString(), equal);
|
||||
if (lval.isDouble()) {
|
||||
*equal = (lval.toDouble() == rval.toDouble());
|
||||
return true;
|
||||
}
|
||||
if (lval.isGCThing()) { // objects or symbols
|
||||
*equal = (lval.toGCThing() == rval.toGCThing());
|
||||
return true;
|
||||
}
|
||||
*equal = lval.get().payloadAsRawUint32() == rval.get().payloadAsRawUint32();
|
||||
MOZ_ASSERT_IF(lval.isUndefined() || lval.isNull(), *equal);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
LooselyEqualBooleanAndOther(JSContext* cx, JS::HandleValue lval, JS::HandleValue rval, bool* result)
|
||||
{
|
||||
MOZ_ASSERT(!rval.isBoolean());
|
||||
JS::RootedValue lvalue(cx, JS::Int32Value(lval.toBoolean() ? 1 : 0));
|
||||
|
||||
// The tail-call would end up in Step 3.
|
||||
if (rval.isNumber()) {
|
||||
*result = (lvalue.toNumber() == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
// The tail-call would end up in Step 6.
|
||||
if (rval.isString()) {
|
||||
double num;
|
||||
if (!StringToNumber(cx, rval.toString(), &num))
|
||||
return false;
|
||||
*result = (lvalue.toNumber() == num);
|
||||
return true;
|
||||
}
|
||||
|
||||
return js::LooselyEqual(cx, lvalue, rval, result);
|
||||
}
|
||||
|
||||
// ES6 draft rev32 7.2.12 Abstract Equality Comparison
|
||||
bool
|
||||
js::LooselyEqual(JSContext* cx, JS::HandleValue lval, JS::HandleValue rval, bool* result)
|
||||
{
|
||||
// Step 3.
|
||||
if (SameType(lval, rval))
|
||||
return EqualGivenSameType(cx, lval, rval, result);
|
||||
|
||||
// Handle int32 x double.
|
||||
if (lval.isNumber() && rval.isNumber()) {
|
||||
*result = (lval.toNumber() == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 4. This a bit more complex, because of the undefined emulating object.
|
||||
if (lval.isNullOrUndefined()) {
|
||||
// We can return early here, because null | undefined is only equal to the same set.
|
||||
*result = rval.isNullOrUndefined() ||
|
||||
(rval.isObject() && EmulatesUndefined(&rval.toObject()));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (rval.isNullOrUndefined()) {
|
||||
MOZ_ASSERT(!lval.isNullOrUndefined());
|
||||
*result = lval.isObject() && EmulatesUndefined(&lval.toObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (lval.isNumber() && rval.isString()) {
|
||||
double num;
|
||||
if (!StringToNumber(cx, rval.toString(), &num))
|
||||
return false;
|
||||
*result = (lval.toNumber() == num);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 7.
|
||||
if (lval.isString() && rval.isNumber()) {
|
||||
double num;
|
||||
if (!StringToNumber(cx, lval.toString(), &num))
|
||||
return false;
|
||||
*result = (num == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 8.
|
||||
if (lval.isBoolean())
|
||||
return LooselyEqualBooleanAndOther(cx, lval, rval, result);
|
||||
|
||||
// Step 9.
|
||||
if (rval.isBoolean())
|
||||
return LooselyEqualBooleanAndOther(cx, rval, lval, result);
|
||||
|
||||
// Step 10.
|
||||
if ((lval.isString() || lval.isNumber() || lval.isSymbol()) && rval.isObject()) {
|
||||
JS::RootedValue rvalue(cx, rval);
|
||||
if (!ToPrimitive(cx, &rvalue))
|
||||
return false;
|
||||
return js::LooselyEqual(cx, lval, rvalue, result);
|
||||
}
|
||||
|
||||
// Step 11.
|
||||
if (lval.isObject() && (rval.isString() || rval.isNumber() || rval.isSymbol())) {
|
||||
JS::RootedValue lvalue(cx, lval);
|
||||
if (!ToPrimitive(cx, &lvalue))
|
||||
return false;
|
||||
return js::LooselyEqual(cx, lvalue, rval, result);
|
||||
}
|
||||
|
||||
// Step 12.
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::LooselyEqual(JSContext* cx, Handle<Value> value1, Handle<Value> value2, bool* equal)
|
||||
{
|
||||
js::AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
js::assertSameCompartment(cx, value1, value2);
|
||||
MOZ_ASSERT(equal);
|
||||
return js::LooselyEqual(cx, value1, value2, equal);
|
||||
}
|
||||
|
||||
bool
|
||||
js::StrictlyEqual(JSContext* cx, JS::HandleValue lval, JS::HandleValue rval, bool* equal)
|
||||
{
|
||||
if (SameType(lval, rval))
|
||||
return EqualGivenSameType(cx, lval, rval, equal);
|
||||
|
||||
if (lval.isNumber() && rval.isNumber()) {
|
||||
*equal = (lval.toNumber() == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
*equal = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::StrictlyEqual(JSContext* cx, Handle<Value> value1, Handle<Value> value2, bool* equal)
|
||||
{
|
||||
js::AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
js::assertSameCompartment(cx, value1, value2);
|
||||
MOZ_ASSERT(equal);
|
||||
return js::StrictlyEqual(cx, value1, value2, equal);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsNegativeZero(const JS::Value& v)
|
||||
{
|
||||
return v.isDouble() && mozilla::IsNegativeZero(v.toDouble());
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsNaN(const JS::Value& v)
|
||||
{
|
||||
return v.isDouble() && mozilla::IsNaN(v.toDouble());
|
||||
}
|
||||
|
||||
bool
|
||||
js::SameValue(JSContext* cx, JS::HandleValue v1, JS::HandleValue v2, bool* same)
|
||||
{
|
||||
if (IsNegativeZero(v1)) {
|
||||
*same = IsNegativeZero(v2);
|
||||
return true;
|
||||
}
|
||||
if (IsNegativeZero(v2)) {
|
||||
*same = false;
|
||||
return true;
|
||||
}
|
||||
if (IsNaN(v1) && IsNaN(v2)) {
|
||||
*same = true;
|
||||
return true;
|
||||
}
|
||||
return js::StrictlyEqual(cx, v1, v2, same);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::SameValue(JSContext* cx, Handle<Value> value1, Handle<Value> value2, bool* same)
|
||||
{
|
||||
js::AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
js::assertSameCompartment(cx, value1, value2);
|
||||
MOZ_ASSERT(same);
|
||||
return js::SameValue(cx, value1, value2, same);
|
||||
}
|
||||
44
js/src/vm/EqualityOperations.h
Normal file
44
js/src/vm/EqualityOperations.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* The equality comparisons of js/Equality.h, but with extra efficiency for
|
||||
* SpiderMonkey-internal callers.
|
||||
*
|
||||
* These functions, assuming they're passed C++-valid arguments, are identical
|
||||
* to the same-named JS::-namespaced functions -- just with hidden linkage (so
|
||||
* they're more efficient to call), and without various external-caller-focused
|
||||
* JSAPI-usage assertions performed that SpiderMonkey users never come close to
|
||||
* failing.
|
||||
*/
|
||||
|
||||
#ifndef vm_EqualityOperations_h
|
||||
#define vm_EqualityOperations_h
|
||||
|
||||
#include "js/RootingAPI.h" // JS::Handle
|
||||
#include "js/Value.h" // JS::Value
|
||||
|
||||
struct JSContext;
|
||||
|
||||
namespace js {
|
||||
|
||||
/** Computes |lval === rval|. */
|
||||
extern bool
|
||||
StrictlyEqual(JSContext* cx, JS::HandleValue lval, JS::HandleValue rval, bool* equal);
|
||||
|
||||
/** Computes |lval == rval|. */
|
||||
extern bool
|
||||
LooselyEqual(JSContext* cx, JS::HandleValue lval, JS::HandleValue rval, bool* result);
|
||||
|
||||
/**
|
||||
* Computes |SameValue(v1, v2)| -- strict equality except that NaNs are
|
||||
* considered equal and opposite-signed zeroes are considered unequal.
|
||||
*/
|
||||
extern bool
|
||||
SameValue(JSContext* cx, JS::HandleValue v1, JS::HandleValue v2, bool* same);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // vm_EqualityOperations_h
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/AsyncIteration.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EqualityOperations.h" // js::StrictlyEqual
|
||||
#include "vm/GeneratorObject.h"
|
||||
#include "vm/Opcodes.h"
|
||||
#include "vm/Scope.h"
|
||||
|
|
@ -786,170 +787,6 @@ js::HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
|
|||
return JS::InstanceofOperator(cx, obj, local, bp);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
EqualGivenSameType(JSContext* cx, HandleValue lval, HandleValue rval, bool* equal)
|
||||
{
|
||||
MOZ_ASSERT(SameType(lval, rval));
|
||||
|
||||
if (lval.isString())
|
||||
return EqualStrings(cx, lval.toString(), rval.toString(), equal);
|
||||
if (lval.isDouble()) {
|
||||
*equal = (lval.toDouble() == rval.toDouble());
|
||||
return true;
|
||||
}
|
||||
if (lval.isGCThing()) { // objects or symbols
|
||||
*equal = (lval.toGCThing() == rval.toGCThing());
|
||||
return true;
|
||||
}
|
||||
*equal = lval.get().payloadAsRawUint32() == rval.get().payloadAsRawUint32();
|
||||
MOZ_ASSERT_IF(lval.isUndefined() || lval.isNull(), *equal);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
LooselyEqualBooleanAndOther(JSContext* cx, HandleValue lval, HandleValue rval, bool* result)
|
||||
{
|
||||
MOZ_ASSERT(!rval.isBoolean());
|
||||
RootedValue lvalue(cx, Int32Value(lval.toBoolean() ? 1 : 0));
|
||||
|
||||
// The tail-call would end up in Step 3.
|
||||
if (rval.isNumber()) {
|
||||
*result = (lvalue.toNumber() == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
// The tail-call would end up in Step 6.
|
||||
if (rval.isString()) {
|
||||
double num;
|
||||
if (!StringToNumber(cx, rval.toString(), &num))
|
||||
return false;
|
||||
*result = (lvalue.toNumber() == num);
|
||||
return true;
|
||||
}
|
||||
|
||||
return LooselyEqual(cx, lvalue, rval, result);
|
||||
}
|
||||
|
||||
// ES6 draft rev32 7.2.12 Abstract Equality Comparison
|
||||
bool
|
||||
js::LooselyEqual(JSContext* cx, HandleValue lval, HandleValue rval, bool* result)
|
||||
{
|
||||
// Step 3.
|
||||
if (SameType(lval, rval))
|
||||
return EqualGivenSameType(cx, lval, rval, result);
|
||||
|
||||
// Handle int32 x double.
|
||||
if (lval.isNumber() && rval.isNumber()) {
|
||||
*result = (lval.toNumber() == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 4. This a bit more complex, because of the undefined emulating object.
|
||||
if (lval.isNullOrUndefined()) {
|
||||
// We can return early here, because null | undefined is only equal to the same set.
|
||||
*result = rval.isNullOrUndefined() ||
|
||||
(rval.isObject() && EmulatesUndefined(&rval.toObject()));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (rval.isNullOrUndefined()) {
|
||||
MOZ_ASSERT(!lval.isNullOrUndefined());
|
||||
*result = lval.isObject() && EmulatesUndefined(&lval.toObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (lval.isNumber() && rval.isString()) {
|
||||
double num;
|
||||
if (!StringToNumber(cx, rval.toString(), &num))
|
||||
return false;
|
||||
*result = (lval.toNumber() == num);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 7.
|
||||
if (lval.isString() && rval.isNumber()) {
|
||||
double num;
|
||||
if (!StringToNumber(cx, lval.toString(), &num))
|
||||
return false;
|
||||
*result = (num == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 8.
|
||||
if (lval.isBoolean())
|
||||
return LooselyEqualBooleanAndOther(cx, lval, rval, result);
|
||||
|
||||
// Step 9.
|
||||
if (rval.isBoolean())
|
||||
return LooselyEqualBooleanAndOther(cx, rval, lval, result);
|
||||
|
||||
// Step 10.
|
||||
if ((lval.isString() || lval.isNumber() || lval.isSymbol()) && rval.isObject()) {
|
||||
RootedValue rvalue(cx, rval);
|
||||
if (!ToPrimitive(cx, &rvalue))
|
||||
return false;
|
||||
return LooselyEqual(cx, lval, rvalue, result);
|
||||
}
|
||||
|
||||
// Step 11.
|
||||
if (lval.isObject() && (rval.isString() || rval.isNumber() || rval.isSymbol())) {
|
||||
RootedValue lvalue(cx, lval);
|
||||
if (!ToPrimitive(cx, &lvalue))
|
||||
return false;
|
||||
return LooselyEqual(cx, lvalue, rval, result);
|
||||
}
|
||||
|
||||
// Step 12.
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::StrictlyEqual(JSContext* cx, HandleValue lval, HandleValue rval, bool* equal)
|
||||
{
|
||||
if (SameType(lval, rval))
|
||||
return EqualGivenSameType(cx, lval, rval, equal);
|
||||
|
||||
if (lval.isNumber() && rval.isNumber()) {
|
||||
*equal = (lval.toNumber() == rval.toNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
*equal = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsNegativeZero(const Value& v)
|
||||
{
|
||||
return v.isDouble() && mozilla::IsNegativeZero(v.toDouble());
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsNaN(const Value& v)
|
||||
{
|
||||
return v.isDouble() && mozilla::IsNaN(v.toDouble());
|
||||
}
|
||||
|
||||
bool
|
||||
js::SameValue(JSContext* cx, HandleValue v1, HandleValue v2, bool* same)
|
||||
{
|
||||
if (IsNegativeZero(v1)) {
|
||||
*same = IsNegativeZero(v2);
|
||||
return true;
|
||||
}
|
||||
if (IsNegativeZero(v2)) {
|
||||
*same = false;
|
||||
return true;
|
||||
}
|
||||
if (IsNaN(v1) && IsNaN(v2)) {
|
||||
*same = true;
|
||||
return true;
|
||||
}
|
||||
return StrictlyEqual(cx, v1, v2, same);
|
||||
}
|
||||
|
||||
JSType
|
||||
js::TypeOfObject(JSObject* obj)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -305,16 +305,6 @@ class InvokeState final : public RunState
|
|||
extern bool
|
||||
RunScript(JSContext* cx, RunState& state);
|
||||
|
||||
extern bool
|
||||
StrictlyEqual(JSContext* cx, HandleValue lval, HandleValue rval, bool* equal);
|
||||
|
||||
extern bool
|
||||
LooselyEqual(JSContext* cx, HandleValue lval, HandleValue rval, bool* equal);
|
||||
|
||||
/* === except that NaN is the same as NaN and -0 is not the same as +0. */
|
||||
extern bool
|
||||
SameValue(JSContext* cx, HandleValue v1, HandleValue v2, bool* same);
|
||||
|
||||
extern JSType
|
||||
TypeOfObject(JSObject* obj);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "gc/Marking.h"
|
||||
#include "js/Value.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EqualityOperations.h" // js::SameValue
|
||||
#include "vm/TypedArrayCommon.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
|
|
|||
|
|
@ -137,6 +137,22 @@ struct CSSParserInputState {
|
|||
bool mHavePushBack;
|
||||
};
|
||||
|
||||
struct ReduceNumberCalcOps : public mozilla::css::BasicFloatCalcOps,
|
||||
public mozilla::css::CSSValueInputCalcOps
|
||||
{
|
||||
result_type ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
// FIXME: Restore this assertion once ParseColor no longer uses this class.
|
||||
//MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
|
||||
return aValue.GetFloatValue();
|
||||
}
|
||||
|
||||
float ComputeNumber(const nsCSSValue& aValue)
|
||||
{
|
||||
return mozilla::css::ComputeCalc(aValue, *this);
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(css::eAuthorSheetFeatures == 0 &&
|
||||
css::eUserSheetFeatures == 1 &&
|
||||
css::eAgentSheetFeatures == 2,
|
||||
|
|
@ -659,6 +675,11 @@ protected:
|
|||
bool SkipAtRule(bool aInsideBlock);
|
||||
bool SkipDeclaration(bool aCheckForBraces);
|
||||
|
||||
// Returns true when the target token type is found, and false for the
|
||||
// end of declaration, start of !important flag, end of declaration
|
||||
// block, or EOF.
|
||||
bool LookForTokenType(nsCSSTokenType aType);
|
||||
|
||||
void PushGroup(css::GroupRule* aRule);
|
||||
void PopGroup();
|
||||
|
||||
|
|
@ -896,6 +917,7 @@ protected:
|
|||
};
|
||||
|
||||
bool IsFunctionTokenValidForImageLayerImage(const nsCSSToken& aToken) const;
|
||||
bool IsCalcFunctionToken(const nsCSSToken& aToken) const;
|
||||
bool ParseImageLayersItem(ImageLayersShorthandParseState& aState,
|
||||
const nsCSSPropertyID aTable[]);
|
||||
|
||||
|
|
@ -1178,14 +1200,6 @@ protected:
|
|||
|
||||
CSSParseResult ParseColor(nsCSSValue& aValue);
|
||||
|
||||
static bool
|
||||
IsCSSTokenCalcFunction(const nsCSSToken& aToken)
|
||||
{
|
||||
return aToken.mType == eCSSToken_Function &&
|
||||
(aToken.mIdent.LowerCaseEqualsLiteral("calc") ||
|
||||
aToken.mIdent.LowerCaseEqualsLiteral("-moz-calc"));
|
||||
}
|
||||
|
||||
template<typename ComponentType>
|
||||
bool ParseRGBColor(ComponentType& aR,
|
||||
ComponentType& aG,
|
||||
|
|
@ -5404,6 +5418,32 @@ CSSParserImpl::SkipDeclaration(bool aCheckForBraces)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::LookForTokenType(nsCSSTokenType aType) {
|
||||
bool rv = false;
|
||||
CSSParserInputState stateBeforeValue;
|
||||
SaveInputState(stateBeforeValue);
|
||||
|
||||
const char16_t stopChars[] = { ';', '!', '}', 0 };
|
||||
nsDependentString stopSymbolChars(stopChars);
|
||||
while (GetToken(true)) {
|
||||
if (mToken.mType == aType) {
|
||||
rv = true;
|
||||
break;
|
||||
}
|
||||
// Stop looking if we're at the end of the declaration, encountered an
|
||||
// !important flag, or at the end of the declaration block.
|
||||
if (mToken.mType == eCSSToken_Symbol &&
|
||||
stopSymbolChars.FindChar(mToken.mSymbol) != -1) {
|
||||
rv = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RestoreSavedInputState(stateBeforeValue);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
CSSParserImpl::SkipRuleSet(bool aInsideBraces)
|
||||
{
|
||||
|
|
@ -6996,7 +7036,15 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
|||
if (GetToken(true)) {
|
||||
UngetToken();
|
||||
}
|
||||
if (mToken.mType == eCSSToken_Number || mToken.mType == eCSSToken_Function) { // <number>
|
||||
|
||||
bool isNumber = mToken.mType == eCSSToken_Number;
|
||||
|
||||
// Check first if we have percentage values inside the function.
|
||||
if (mToken.mType == eCSSToken_Function) {
|
||||
isNumber = !LookForTokenType(eCSSToken_Percentage);
|
||||
}
|
||||
|
||||
if (isNumber) { // <number>
|
||||
uint8_t r, g, b, a;
|
||||
|
||||
if (ParseRGBColor(r, g, b, a)) {
|
||||
|
|
@ -7095,21 +7143,6 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
|||
return CSSParseResult::NotFound;
|
||||
}
|
||||
|
||||
struct ReduceNumberCalcOps : public mozilla::css::BasicFloatCalcOps,
|
||||
public mozilla::css::CSSValueInputCalcOps
|
||||
{
|
||||
result_type ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
|
||||
return aValue.GetFloatValue();
|
||||
}
|
||||
|
||||
float ComputeNumber(const nsCSSValue& aValue)
|
||||
{
|
||||
return mozilla::css::ComputeCalc(aValue, *this);
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseColorComponent(uint8_t& aComponent, Maybe<char> aSeparator)
|
||||
{
|
||||
|
|
@ -7119,18 +7152,16 @@ CSSParserImpl::ParseColorComponent(uint8_t& aComponent, Maybe<char> aSeparator)
|
|||
}
|
||||
|
||||
float value;
|
||||
|
||||
if (mToken.mType == eCSSToken_Number)
|
||||
if (mToken.mType == eCSSToken_Number) {
|
||||
value = mToken.mNumber;
|
||||
else if (IsCSSTokenCalcFunction(mToken)) {
|
||||
} else if (IsCalcFunctionToken(mToken)) {
|
||||
nsCSSValue aValue;
|
||||
if (!ParseCalc(aValue, VARIANT_LPN | VARIANT_CALC)) {
|
||||
return false;
|
||||
}
|
||||
ReduceNumberCalcOps ops;
|
||||
value = mozilla::css::ComputeCalc(aValue, ops);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
REPORT_UNEXPECTED_TOKEN(PEExpectedNumber);
|
||||
UngetToken();
|
||||
return false;
|
||||
|
|
@ -7157,18 +7188,16 @@ CSSParserImpl::ParseColorComponent(float& aComponent, Maybe<char> aSeparator)
|
|||
}
|
||||
|
||||
float value;
|
||||
|
||||
if (mToken.mType == eCSSToken_Percentage)
|
||||
if (mToken.mType == eCSSToken_Percentage) {
|
||||
value = mToken.mNumber;
|
||||
else if (IsCSSTokenCalcFunction(mToken)) {
|
||||
} else if (IsCalcFunctionToken(mToken)) {
|
||||
nsCSSValue aValue;
|
||||
if (!ParseCalc(aValue, VARIANT_LPN | VARIANT_CALC)) {
|
||||
return false;
|
||||
}
|
||||
ReduceNumberCalcOps ops;
|
||||
value = mozilla::css::ComputeCalc(aValue, ops);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
REPORT_UNEXPECTED_TOKEN(PEExpectedPercent);
|
||||
UngetToken();
|
||||
return false;
|
||||
|
|
@ -7199,17 +7228,6 @@ CSSParserImpl::ParseHue(float& aAngle)
|
|||
aAngle = mToken.mNumber;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsCSSTokenCalcFunction(mToken)) {
|
||||
nsCSSValue aValue;
|
||||
if (!ParseCalc(aValue, VARIANT_LPN | VARIANT_CALC)) {
|
||||
return false;
|
||||
}
|
||||
ReduceNumberCalcOps ops;
|
||||
aAngle = mozilla::css::ComputeCalc(aValue, ops);
|
||||
return true;
|
||||
}
|
||||
|
||||
UngetToken();
|
||||
|
||||
// <angle>
|
||||
|
|
@ -8227,7 +8245,7 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
|
|||
}
|
||||
}
|
||||
if ((aVariantMask & VARIANT_CALC) &&
|
||||
IsCSSTokenCalcFunction(*tk)) {
|
||||
IsCalcFunctionToken(*tk)) {
|
||||
// calc() currently allows only lengths and percents and number inside it.
|
||||
// And note that in current implementation, number cannot be mixed with
|
||||
// length and percent.
|
||||
|
|
@ -12476,6 +12494,14 @@ CSSParserImpl::IsFunctionTokenValidForImageLayerImage(
|
|||
funcName.LowerCaseEqualsLiteral("-webkit-repeating-radial-gradient")));
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::IsCalcFunctionToken(const nsCSSToken& aToken) const
|
||||
{
|
||||
return aToken.mType == eCSSToken_Function &&
|
||||
(aToken.mIdent.LowerCaseEqualsLiteral("calc") ||
|
||||
aToken.mIdent.LowerCaseEqualsLiteral("-moz-calc"));
|
||||
}
|
||||
|
||||
// Parse one item of the background shorthand property.
|
||||
bool
|
||||
CSSParserImpl::ParseImageLayersItem(
|
||||
|
|
@ -13988,7 +14014,7 @@ CSSParserImpl::ParseCalcTerm(nsCSSValue& aValue, uint32_t& aVariantMask)
|
|||
// Either an additive expression in parentheses...
|
||||
if (mToken.IsSymbol('(') ||
|
||||
// Treat nested calc() as plain parenthesis.
|
||||
IsCSSTokenCalcFunction(mToken)) {
|
||||
IsCalcFunctionToken(mToken)) {
|
||||
if (!ParseCalcAdditiveExpression(aValue, aVariantMask) ||
|
||||
!ExpectSymbol(')', true)) {
|
||||
SkipUntil(')');
|
||||
|
|
|
|||
|
|
@ -396,6 +396,20 @@ NumbersAreIdentical(T aValue1, T aValue2)
|
|||
return BitwiseCast<Bits>(aValue1) == BitwiseCast<Bits>(aValue2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if |aValue| and |aValue2| are equal (ignoring sign if both are
|
||||
* zero) or both NaN.
|
||||
*/
|
||||
template <typename T>
|
||||
static inline bool
|
||||
EqualOrBothNaN(T aValue1, T aValue2)
|
||||
{
|
||||
if (IsNaN(aValue1)) {
|
||||
return IsNaN(aValue2);
|
||||
}
|
||||
return aValue1 == aValue2;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
|
|
|
|||
|
|
@ -2506,15 +2506,6 @@ pref("layout.css.scroll-snap.prediction-sensitivity", "0.750");
|
|||
// Is support for basic shapes in clip-path enabled?
|
||||
pref("layout.css.clip-path-shapes.enabled", true);
|
||||
|
||||
// Is support for DOMPoint enabled?
|
||||
pref("layout.css.DOMPoint.enabled", true);
|
||||
|
||||
// Is support for DOMQuad enabled?
|
||||
pref("layout.css.DOMQuad.enabled", true);
|
||||
|
||||
// Is support for DOMMatrix enabled?
|
||||
pref("layout.css.DOMMatrix.enabled", true);
|
||||
|
||||
// Is support for GeometryUtils.getBoxQuads enabled?
|
||||
pref("layout.css.getBoxQuads.enabled", true);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue