mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 865998: Implement WebIDL union return values r=bz
This commit is contained in:
parent
cc5560c810
commit
7837d54bf0
@ -186,8 +186,6 @@ MOCHITEST_BROWSER_FILES += \
|
||||
test-bug-595934-svg.xhtml \
|
||||
test-bug-595934-workers.html \
|
||||
test-bug-595934-workers.js \
|
||||
test-bug-595934-canvas.html \
|
||||
test-bug-595934-canvas.js \
|
||||
test-bug-595934-css-parser.html \
|
||||
test-bug-595934-css-parser.css \
|
||||
test-bug-595934-canvas-css.html \
|
||||
|
@ -46,31 +46,26 @@ const TESTS = [
|
||||
matchString: "fooBarSVG",
|
||||
},
|
||||
{ // #6
|
||||
file: "test-bug-595934-canvas.html",
|
||||
category: "Canvas",
|
||||
matchString: "strokeStyle",
|
||||
},
|
||||
{ // #7
|
||||
file: "test-bug-595934-css-parser.html",
|
||||
category: "CSS Parser",
|
||||
matchString: "foobarCssParser",
|
||||
},
|
||||
{ // #8
|
||||
{ // #7
|
||||
file: "test-bug-595934-malformedxml-external.html",
|
||||
category: "malformed-xml",
|
||||
matchString: "</html>",
|
||||
},
|
||||
{ // #9
|
||||
{ // #8
|
||||
file: "test-bug-595934-empty-getelementbyid.html",
|
||||
category: "DOM",
|
||||
matchString: "getElementById",
|
||||
},
|
||||
{ // #10
|
||||
{ // #9
|
||||
file: "test-bug-595934-canvas-css.html",
|
||||
category: "CSS Parser",
|
||||
matchString: "foobarCanvasCssParser",
|
||||
},
|
||||
{ // #11
|
||||
{ // #10
|
||||
file: "test-bug-595934-image.html",
|
||||
category: "Image",
|
||||
matchString: "corrupt",
|
||||
|
@ -1,15 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Web Console test for bug 595934 - category: Canvas</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript"
|
||||
src="test-bug-595934-canvas.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Web Console test for bug 595934 - category "Canvas".</p>
|
||||
<p><canvas width="200" height="200">Canvas support is required!</canvas></p>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
var canvas = document.querySelector("canvas");
|
||||
var context = canvas.getContext("2d");
|
||||
context.strokeStyle = document;
|
||||
}, false);
|
||||
|
@ -13,9 +13,6 @@
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
|
||||
{0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -23,7 +20,6 @@ class CanvasGradient : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENTAZURE_PRIVATE_IID)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CanvasGradient)
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include "nsISupports.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
|
||||
{0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
@ -27,7 +25,6 @@ class CanvasPattern MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERNAZURE_PRIVATE_IID)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CanvasPattern)
|
||||
|
||||
|
@ -92,10 +92,11 @@
|
||||
#include "nsJSUtils.h"
|
||||
#include "XPCQuickStubs.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
|
||||
#include "mozilla/dom/HTMLImageElement.h"
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
|
||||
#include "mozilla/dom/TextMetrics.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
#undef free // apparently defined by some windows header, clashing with a free()
|
||||
@ -400,8 +401,6 @@ CanvasGradient::AddColorStop(float offset, const nsAString& colorstr, ErrorResul
|
||||
mRawStops.AppendElement(newStop);
|
||||
}
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(CanvasGradient, NS_CANVASGRADIENTAZURE_PRIVATE_IID)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CanvasGradient)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CanvasGradient)
|
||||
|
||||
@ -409,12 +408,9 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(CanvasGradient, mContext)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CanvasGradient)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(mozilla::dom::CanvasGradient)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(CanvasPattern, NS_CANVASPATTERNAZURE_PRIVATE_IID)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CanvasPattern)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CanvasPattern)
|
||||
|
||||
@ -422,7 +418,6 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(CanvasPattern, mContext)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CanvasPattern)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(mozilla::dom::CanvasPattern)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
@ -648,17 +643,6 @@ CanvasRenderingContext2D::Reset()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
WarnAboutUnexpectedStyle(HTMLCanvasElement* canvasElement)
|
||||
{
|
||||
nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::warningFlag,
|
||||
"Canvas",
|
||||
canvasElement ? canvasElement->OwnerDoc() : nullptr,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"UnexpectedCanvasVariantStyle");
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::SetStyleFromString(const nsAString& str,
|
||||
Style whichStyle)
|
||||
@ -673,27 +657,18 @@ CanvasRenderingContext2D::SetStyleFromString(const nsAString& str,
|
||||
CurrentState().SetColorStyle(whichStyle, color);
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
CanvasRenderingContext2D::GetStyleAsStringOrInterface(nsAString& aStr,
|
||||
CanvasMultiGetterType& aType,
|
||||
Style aWhichStyle)
|
||||
void
|
||||
CanvasRenderingContext2D::GetStyleAsUnion(StringOrCanvasGradientOrCanvasPatternReturnValue& aValue,
|
||||
Style aWhichStyle)
|
||||
{
|
||||
const ContextState &state = CurrentState();
|
||||
nsISupports* supports;
|
||||
if (state.patternStyles[aWhichStyle]) {
|
||||
aStr.SetIsVoid(true);
|
||||
supports = state.patternStyles[aWhichStyle];
|
||||
aType = CMG_STYLE_PATTERN;
|
||||
aValue.SetAsCanvasPattern() = state.patternStyles[aWhichStyle];
|
||||
} else if (state.gradientStyles[aWhichStyle]) {
|
||||
aStr.SetIsVoid(true);
|
||||
supports = state.gradientStyles[aWhichStyle];
|
||||
aType = CMG_STYLE_GRADIENT;
|
||||
aValue.SetAsCanvasGradient() = state.gradientStyles[aWhichStyle];
|
||||
} else {
|
||||
StyleColorToString(state.colorStyles[aWhichStyle], aStr);
|
||||
supports = nullptr;
|
||||
aType = CMG_STYLE_STRING;
|
||||
StyleColorToString(state.colorStyles[aWhichStyle], aValue.SetAsString());
|
||||
}
|
||||
return supports;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -1349,92 +1324,25 @@ CanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx,
|
||||
//
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::SetStyleFromJSValue(JSContext* cx,
|
||||
JS::Handle<JS::Value> value,
|
||||
Style whichStyle)
|
||||
CanvasRenderingContext2D::SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& value,
|
||||
Style whichStyle)
|
||||
{
|
||||
if (value.isString()) {
|
||||
nsDependentJSString strokeStyle;
|
||||
if (strokeStyle.init(cx, value.toString())) {
|
||||
SetStyleFromString(strokeStyle, whichStyle);
|
||||
}
|
||||
if (value.IsString()) {
|
||||
SetStyleFromString(value.GetAsString(), whichStyle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.isObject()) {
|
||||
nsCOMPtr<nsISupports> holder;
|
||||
|
||||
CanvasGradient* gradient;
|
||||
JS::Rooted<JS::Value> rootedVal(cx, value);
|
||||
nsresult rv = xpc_qsUnwrapArg<CanvasGradient>(cx, value, &gradient,
|
||||
static_cast<nsISupports**>(getter_AddRefs(holder)),
|
||||
rootedVal.address());
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetStyleFromGradient(gradient, whichStyle);
|
||||
return;
|
||||
}
|
||||
|
||||
CanvasPattern* pattern;
|
||||
rv = xpc_qsUnwrapArg<CanvasPattern>(cx, value, &pattern,
|
||||
static_cast<nsISupports**>(getter_AddRefs(holder)),
|
||||
rootedVal.address());
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetStyleFromPattern(pattern, whichStyle);
|
||||
return;
|
||||
}
|
||||
if (value.IsCanvasGradient()) {
|
||||
SetStyleFromGradient(value.GetAsCanvasGradient(), whichStyle);
|
||||
return;
|
||||
}
|
||||
|
||||
WarnAboutUnexpectedStyle(mCanvasElement);
|
||||
}
|
||||
|
||||
static JS::Value
|
||||
WrapStyle(JSContext* cx, JSObject* objArg,
|
||||
CanvasRenderingContext2D::CanvasMultiGetterType type,
|
||||
nsAString& str, nsISupports* supports, ErrorResult& error)
|
||||
{
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
bool ok;
|
||||
switch (type) {
|
||||
case CanvasRenderingContext2D::CMG_STYLE_STRING:
|
||||
{
|
||||
ok = xpc::StringToJsval(cx, str, v.address());
|
||||
break;
|
||||
}
|
||||
case CanvasRenderingContext2D::CMG_STYLE_PATTERN:
|
||||
case CanvasRenderingContext2D::CMG_STYLE_GRADIENT:
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, objArg);
|
||||
ok = dom::WrapObject(cx, obj, supports, &v);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("unexpected CanvasMultiGetterType");
|
||||
if (value.IsCanvasPattern()) {
|
||||
SetStyleFromPattern(value.GetAsCanvasPattern(), whichStyle);
|
||||
return;
|
||||
}
|
||||
if (!ok) {
|
||||
error.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
JS::Value
|
||||
CanvasRenderingContext2D::GetStrokeStyle(JSContext* cx,
|
||||
ErrorResult& error)
|
||||
{
|
||||
nsString str;
|
||||
CanvasMultiGetterType t;
|
||||
nsISupports* supports = GetStyleAsStringOrInterface(str, t, STYLE_STROKE);
|
||||
return WrapStyle(cx, GetWrapper(), t, str, supports, error);
|
||||
}
|
||||
|
||||
JS::Value
|
||||
CanvasRenderingContext2D::GetFillStyle(JSContext* cx,
|
||||
ErrorResult& error)
|
||||
{
|
||||
nsString str;
|
||||
CanvasMultiGetterType t;
|
||||
nsISupports* supports = GetStyleAsStringOrInterface(str, t, STYLE_FILL);
|
||||
return WrapStyle(cx, GetWrapper(), t, str, supports, error);
|
||||
MOZ_ASSUME_UNREACHABLE("Invalid union value");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "gfxFont.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozilla/dom/CanvasGradient.h"
|
||||
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
|
||||
#include "mozilla/dom/CanvasPattern.h"
|
||||
@ -31,6 +30,9 @@ class SourceSurface;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
|
||||
class StringOrCanvasGradientOrCanvasPattern;
|
||||
class StringOrCanvasGradientOrCanvasPatternReturnValue;
|
||||
class TextMetrics;
|
||||
|
||||
extern const mozilla::gfx::Float SIGMA_MAX;
|
||||
@ -47,7 +49,7 @@ class CanvasRenderingContext2D :
|
||||
public nsICanvasRenderingContextInternal,
|
||||
public nsWrapperCache
|
||||
{
|
||||
typedef mozilla::dom::HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
|
||||
typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
|
||||
HTMLImageOrCanvasOrVideoElement;
|
||||
|
||||
public:
|
||||
@ -91,18 +93,25 @@ public:
|
||||
void GetGlobalCompositeOperation(nsAString& op, mozilla::ErrorResult& error);
|
||||
void SetGlobalCompositeOperation(const nsAString& op,
|
||||
mozilla::ErrorResult& error);
|
||||
JS::Value GetStrokeStyle(JSContext* cx, mozilla::ErrorResult& error);
|
||||
|
||||
void SetStrokeStyle(JSContext* cx, JS::Handle<JS::Value> value)
|
||||
void GetStrokeStyle(StringOrCanvasGradientOrCanvasPatternReturnValue& value)
|
||||
{
|
||||
SetStyleFromJSValue(cx, value, STYLE_STROKE);
|
||||
GetStyleAsUnion(value, STYLE_STROKE);
|
||||
}
|
||||
|
||||
JS::Value GetFillStyle(JSContext* cx, mozilla::ErrorResult& error);
|
||||
|
||||
void SetFillStyle(JSContext* cx, JS::Handle<JS::Value> value)
|
||||
void SetStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& value)
|
||||
{
|
||||
SetStyleFromJSValue(cx, value, STYLE_FILL);
|
||||
SetStyleFromUnion(value, STYLE_STROKE);
|
||||
}
|
||||
|
||||
void GetFillStyle(StringOrCanvasGradientOrCanvasPatternReturnValue& value)
|
||||
{
|
||||
GetStyleAsUnion(value, STYLE_FILL);
|
||||
}
|
||||
|
||||
void SetFillStyle(const StringOrCanvasGradientOrCanvasPattern& value)
|
||||
{
|
||||
SetStyleFromUnion(value, STYLE_FILL);
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasGradient>
|
||||
@ -162,10 +171,10 @@ public:
|
||||
bool IsPointInPath(double x, double y, const CanvasWindingRule& winding);
|
||||
bool IsPointInStroke(double x, double y);
|
||||
void FillText(const nsAString& text, double x, double y,
|
||||
const mozilla::dom::Optional<double>& maxWidth,
|
||||
const Optional<double>& maxWidth,
|
||||
mozilla::ErrorResult& error);
|
||||
void StrokeText(const nsAString& text, double x, double y,
|
||||
const mozilla::dom::Optional<double>& maxWidth,
|
||||
const Optional<double>& maxWidth,
|
||||
mozilla::ErrorResult& error);
|
||||
TextMetrics*
|
||||
MeasureText(const nsAString& rawText, mozilla::ErrorResult& error);
|
||||
@ -190,18 +199,18 @@ public:
|
||||
DrawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, 6, error);
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::dom::ImageData>
|
||||
already_AddRefed<ImageData>
|
||||
CreateImageData(JSContext* cx, double sw, double sh,
|
||||
mozilla::ErrorResult& error);
|
||||
already_AddRefed<mozilla::dom::ImageData>
|
||||
CreateImageData(JSContext* cx, mozilla::dom::ImageData& imagedata,
|
||||
already_AddRefed<ImageData>
|
||||
CreateImageData(JSContext* cx, ImageData& imagedata,
|
||||
mozilla::ErrorResult& error);
|
||||
already_AddRefed<mozilla::dom::ImageData>
|
||||
already_AddRefed<ImageData>
|
||||
GetImageData(JSContext* cx, double sx, double sy, double sw, double sh,
|
||||
mozilla::ErrorResult& error);
|
||||
void PutImageData(mozilla::dom::ImageData& imageData,
|
||||
void PutImageData(ImageData& imageData,
|
||||
double dx, double dy, mozilla::ErrorResult& error);
|
||||
void PutImageData(mozilla::dom::ImageData& imageData,
|
||||
void PutImageData(ImageData& imageData,
|
||||
double dx, double dy, double dirtyX, double dirtyY,
|
||||
double dirtyWidth, double dirtyHeight,
|
||||
mozilla::ErrorResult& error);
|
||||
@ -271,7 +280,7 @@ public:
|
||||
void LineTo(double x, double y)
|
||||
{
|
||||
EnsureWritablePath();
|
||||
|
||||
|
||||
LineTo(mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
|
||||
}
|
||||
|
||||
@ -474,21 +483,22 @@ protected:
|
||||
static mozilla::gfx::DrawTarget* sErrorTarget;
|
||||
|
||||
// Some helpers. Doesn't modify a color on failure.
|
||||
void SetStyleFromJSValue(JSContext* cx, JS::Handle<JS::Value> value,
|
||||
Style whichStyle);
|
||||
void SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& value,
|
||||
Style whichStyle);
|
||||
void SetStyleFromString(const nsAString& str, Style whichStyle);
|
||||
|
||||
void SetStyleFromGradient(CanvasGradient *gradient, Style whichStyle)
|
||||
void SetStyleFromGradient(CanvasGradient& gradient, Style whichStyle)
|
||||
{
|
||||
CurrentState().SetGradientStyle(whichStyle, gradient);
|
||||
CurrentState().SetGradientStyle(whichStyle, &gradient);
|
||||
}
|
||||
|
||||
void SetStyleFromPattern(CanvasPattern *pattern, Style whichStyle)
|
||||
void SetStyleFromPattern(CanvasPattern& pattern, Style whichStyle)
|
||||
{
|
||||
CurrentState().SetPatternStyle(whichStyle, pattern);
|
||||
CurrentState().SetPatternStyle(whichStyle, &pattern);
|
||||
}
|
||||
|
||||
nsISupports* GetStyleAsStringOrInterface(nsAString& aStr, CanvasMultiGetterType& aType, Style aWhichStyle);
|
||||
void GetStyleAsUnion(StringOrCanvasGradientOrCanvasPatternReturnValue& aValue,
|
||||
Style aWhichStyle);
|
||||
|
||||
// Returns whether a color was successfully parsed.
|
||||
bool ParseColor(const nsAString& aString, nscolor* aColor);
|
||||
@ -716,7 +726,7 @@ protected:
|
||||
nsresult DrawOrMeasureText(const nsAString& text,
|
||||
float x,
|
||||
float y,
|
||||
const mozilla::dom::Optional<double>& maxWidth,
|
||||
const Optional<double>& maxWidth,
|
||||
TextDrawOperation op,
|
||||
float* aWidth);
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/dom/CanvasRenderingContext2D.h"
|
||||
#include "mozilla/dom/HTMLCanvasElementBinding.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -159,8 +159,7 @@ DOMInterfaces = {
|
||||
|
||||
'CanvasRenderingContext2D': {
|
||||
'implicitJSContext': [
|
||||
'createImageData', 'getImageData', 'strokeStyle',
|
||||
'fillStyle', 'mozDash'
|
||||
'createImageData', 'getImageData', 'mozDash'
|
||||
],
|
||||
'resultNotAddRefed': [ 'canvas', 'measureText' ],
|
||||
'binaryNames': {
|
||||
|
@ -9,6 +9,7 @@ import os
|
||||
import re
|
||||
import string
|
||||
import math
|
||||
import itertools
|
||||
|
||||
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType
|
||||
from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
|
||||
@ -735,6 +736,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
|
||||
implheaders = set(["UnionTypes.h"])
|
||||
declarations = set()
|
||||
unionStructs = dict()
|
||||
unionReturnValues = dict()
|
||||
|
||||
def addInfoForType(t, descriptor=None, dictionary=None):
|
||||
"""
|
||||
@ -751,6 +753,10 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
|
||||
config)
|
||||
# FIXME: Unions are broken in workers. See bug 809899.
|
||||
unionStructs[name] = CGUnionStruct(t, providers[0])
|
||||
# Unions cannot contain JSObject*.
|
||||
if not any(member.isObject() or member.isSpiderMonkeyInterface() for member in t.flatMemberTypes):
|
||||
unionReturnValues[name] = CGUnionReturnValueStruct(t, providers[0])
|
||||
|
||||
for f in t.flatMemberTypes:
|
||||
f = f.unroll()
|
||||
if f.isInterface():
|
||||
@ -772,7 +778,8 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
|
||||
callForEachType(descriptors, dictionaries, callbacks, addInfoForType)
|
||||
|
||||
return (headers, implheaders, declarations,
|
||||
CGList(SortedDictValues(unionStructs), "\n"))
|
||||
CGList(itertools.chain(SortedDictValues(unionStructs),
|
||||
SortedDictValues(unionReturnValues)), "\n"))
|
||||
|
||||
def UnionConversions(descriptors, dictionaries, callbacks, config):
|
||||
"""
|
||||
@ -2069,7 +2076,7 @@ def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturn
|
||||
if len(failureReturnValue) > 0:
|
||||
failureReturn += " " + failureReturnValue
|
||||
failureReturn += ";"
|
||||
|
||||
|
||||
defineUnforgeables = ("if (!DefineUnforgeableAttributes(aCx, " + obj + ", %s)) {\n"
|
||||
" " + failureReturn + "\n"
|
||||
"}")
|
||||
@ -2488,6 +2495,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
lenientFloatCode=None,
|
||||
allowTreatNonCallableAsNull=False,
|
||||
isCallbackReturnValue=False,
|
||||
isInUnionReturnValue=False,
|
||||
sourceDescription="value"):
|
||||
"""
|
||||
Get a template for converting a JS value to a native object based on the
|
||||
@ -3036,13 +3044,16 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
isCallbackReturnValue)
|
||||
|
||||
# Sequences and non-worker callbacks have to hold a strong ref to the
|
||||
# thing being passed down. Also, callback return values always end up
|
||||
# thing being passed down. Union return values must hold a strong ref
|
||||
# because they may be returning an addrefed pointer.
|
||||
# Also, callback return values always end up
|
||||
# addrefing anyway, so there is no point trying to avoid it here and it
|
||||
# makes other things simpler since we can assume the return value is a
|
||||
# strong ref.
|
||||
forceOwningType = ((descriptor.interface.isCallback() and
|
||||
not descriptor.workers) or
|
||||
isMember or
|
||||
isInUnionReturnValue or
|
||||
isCallbackReturnValue)
|
||||
|
||||
typeName = descriptor.nativeType
|
||||
@ -3259,6 +3270,8 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
|
||||
if isOptional:
|
||||
declType = "Optional<nsAString>"
|
||||
elif isInUnionReturnValue:
|
||||
declType = "nsString"
|
||||
else:
|
||||
declType = "NonNull<nsAString>"
|
||||
|
||||
@ -4100,15 +4113,7 @@ if (!returnArray) {
|
||||
# NB: setValue(..., True) calls JS_WrapValue(), so is fallible
|
||||
return (setValue(toValue % result, wrapType), False)
|
||||
|
||||
if type.isUnion():
|
||||
if type.nullable():
|
||||
prefix = "%s->"
|
||||
else:
|
||||
prefix = "%s."
|
||||
return (wrapAndSetPtr((prefix % result) +
|
||||
"ToJSVal(cx, ${obj}, ${jsvalHandle})"), False)
|
||||
|
||||
if not (type.isPrimitive() or type.isDictionary() or type.isDate()):
|
||||
if not (type.isUnion() or type.isPrimitive() or type.isDictionary() or type.isDate()):
|
||||
raise TypeError("Need to learn to wrap %s" % type)
|
||||
|
||||
if type.nullable():
|
||||
@ -4119,6 +4124,10 @@ if (!returnArray) {
|
||||
CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
|
||||
"}\n" + recTemplate, recInfal)
|
||||
|
||||
if type.isUnion():
|
||||
return (wrapAndSetPtr("%s.ToJSVal(cx, ${obj}, ${jsvalHandle})" % result),
|
||||
False)
|
||||
|
||||
if type.isDictionary():
|
||||
return (wrapAndSetPtr("%s.ToObject(cx, ${obj}, ${jsvalHandle})" % result),
|
||||
False)
|
||||
@ -4322,7 +4331,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
|
||||
resultArgs = None
|
||||
return result, True, None, resultArgs
|
||||
if returnType.isUnion():
|
||||
raise TypeError("Need to sort out ownership model for union retvals");
|
||||
result = CGGeneric(returnType.unroll().name + "ReturnValue")
|
||||
if returnType.nullable():
|
||||
result = CGTemplatedType("Nullable", result)
|
||||
return result, True, None, None
|
||||
if returnType.isDate():
|
||||
result = CGGeneric("Date")
|
||||
if returnType.nullable():
|
||||
@ -4430,7 +4442,7 @@ class CGCallGenerator(CGThing):
|
||||
|
||||
if isFallible:
|
||||
self.cgRoot.prepend(CGGeneric("ErrorResult rv;"))
|
||||
self.cgRoot.append(CGGeneric("rv.WouldReportJSException();"));
|
||||
self.cgRoot.append(CGGeneric("rv.WouldReportJSException();"))
|
||||
self.cgRoot.append(CGGeneric("if (rv.Failed()) {"))
|
||||
self.cgRoot.append(CGIndenter(errorReport))
|
||||
self.cgRoot.append(CGGeneric("}"))
|
||||
@ -5839,7 +5851,7 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
|
||||
typeName = CGTemplatedType("Nullable", typeName, isReference=True)
|
||||
return typeName
|
||||
|
||||
def getUnionTypeTemplateVars(unionType, type, descriptorProvider):
|
||||
def getUnionTypeTemplateVars(unionType, type, descriptorProvider, isReturnValue=False):
|
||||
# For dictionaries and sequences we need to pass None as the failureCode
|
||||
# for getJSToNativeConversionInfo.
|
||||
# Also, for dictionaries we would need to handle conversion of
|
||||
@ -5864,7 +5876,7 @@ return true;"""
|
||||
}""" % name) + tryNextCode
|
||||
conversionInfo = getJSToNativeConversionInfo(
|
||||
type, descriptorProvider, failureCode=tryNextCode,
|
||||
isDefinitelyObject=True,
|
||||
isDefinitelyObject=True, isInUnionReturnValue=isReturnValue,
|
||||
sourceDescription="member of %s" % unionType)
|
||||
|
||||
# This is ugly, but UnionMember needs to call a constructor with no
|
||||
@ -5958,7 +5970,7 @@ class CGUnionStruct(CGThing):
|
||||
}"""
|
||||
methods.extend(mapTemplate(methodTemplate, templateVars))
|
||||
# Now have to be careful: we do not want the SetAsObject() method!
|
||||
setterTemplate = """ ${structType}& SetAs${name}()
|
||||
setterTemplate = """ ${structType}& SetAs${name}()
|
||||
{
|
||||
mType = e${name};
|
||||
return mValue.m${name}.SetValue();
|
||||
@ -6020,7 +6032,7 @@ ${destructors}
|
||||
if self.type.hasNullableType:
|
||||
conversionsToJS.append(" case eNull:\n"
|
||||
" {\n"
|
||||
" rval.set(JS::NullValue());\n"
|
||||
" rval.setNull();\n"
|
||||
" return true;\n"
|
||||
" }")
|
||||
conversionsToJS.extend(
|
||||
@ -6062,7 +6074,161 @@ ${doConversionsToJS}
|
||||
"jsvalHandle": "rval",
|
||||
"obj": "scopeObj",
|
||||
"result": val,
|
||||
"objectCanBeNonNull": True
|
||||
})
|
||||
return CGIndenter(CGList([CGGeneric("case e%(name)s:" % templateVars),
|
||||
CGWrapper(CGIndenter(CGGeneric(wrapCode)),
|
||||
pre="{\n",
|
||||
post="\n}")],
|
||||
"\n"),
|
||||
4).define()
|
||||
|
||||
class CGUnionReturnValueStruct(CGThing):
|
||||
def __init__(self, type, descriptorProvider):
|
||||
CGThing.__init__(self)
|
||||
self.type = type.unroll()
|
||||
self.descriptorProvider = descriptorProvider
|
||||
self.templateVars = map(
|
||||
lambda t: getUnionTypeTemplateVars(self.type, t,
|
||||
self.descriptorProvider,
|
||||
isReturnValue=True),
|
||||
self.type.flatMemberTypes)
|
||||
|
||||
def declare(self):
|
||||
templateVars = self.templateVars
|
||||
|
||||
enumValues = []
|
||||
methods = []
|
||||
if self.type.hasNullableType:
|
||||
enumValues.append("eNull")
|
||||
methods.append(""" bool IsNull() const
|
||||
{
|
||||
return mType == eNull;
|
||||
}
|
||||
|
||||
bool SetNull()
|
||||
{
|
||||
mType = eNull;
|
||||
return true;
|
||||
}""")
|
||||
|
||||
enumValues.extend(mapTemplate("e${name}", templateVars))
|
||||
methodTemplate = " ${structType}& SetAs${name}();"
|
||||
methods.extend(mapTemplate(methodTemplate, templateVars))
|
||||
values = mapTemplate("UnionMember<${structType} > m${name};", templateVars)
|
||||
return string.Template("""
|
||||
class ${structName}ReturnValue {
|
||||
public:
|
||||
${structName}ReturnValue() : mType(eUninitialized)
|
||||
{
|
||||
}
|
||||
~${structName}ReturnValue();
|
||||
|
||||
${methods}
|
||||
|
||||
bool ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj,
|
||||
JS::MutableHandle<JS::Value> rval) const;
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
eUninitialized,
|
||||
${enumValues}
|
||||
};
|
||||
union Value {
|
||||
${values}
|
||||
};
|
||||
|
||||
Type mType;
|
||||
Value mValue;
|
||||
};
|
||||
|
||||
""").substitute(
|
||||
{
|
||||
"structName": self.type.__str__(),
|
||||
"methods": "\n\n".join(methods),
|
||||
"enumValues": ",\n ".join(enumValues),
|
||||
"values": "\n ".join(values)
|
||||
})
|
||||
|
||||
def define(self):
|
||||
templateVars = self.templateVars
|
||||
conversionsToJS = []
|
||||
if self.type.hasNullableType:
|
||||
conversionsToJS.append(" case eNull:\n"
|
||||
" {\n"
|
||||
" rval.setNull();\n"
|
||||
" return true;\n"
|
||||
" }")
|
||||
conversionsToJS.extend(
|
||||
map(self.getConversionToJS,
|
||||
zip(templateVars, self.type.flatMemberTypes)))
|
||||
|
||||
toJSVal = string.Template("""
|
||||
|
||||
bool
|
||||
${structName}ReturnValue::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
|
||||
{
|
||||
switch (mType) {
|
||||
${doConversionsToJS}
|
||||
|
||||
case eUninitialized:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
""").substitute({
|
||||
"structName": str(self.type),
|
||||
"doConversionsToJS": "\n\n".join(conversionsToJS)
|
||||
})
|
||||
templateVars = self.templateVars
|
||||
|
||||
methods = []
|
||||
methodTemplate = """${structType}&
|
||||
%sReturnValue::SetAs${name}()
|
||||
{
|
||||
mType = e${name};
|
||||
return mValue.m${name}.SetValue();
|
||||
}""" % str(self.type)
|
||||
methods.extend(mapTemplate(methodTemplate, templateVars))
|
||||
|
||||
callDestructors = []
|
||||
if self.type.hasNullableType:
|
||||
callDestructors.append(" case eNull:\n"
|
||||
" break;")
|
||||
callDestructors.extend(mapTemplate(" case e${name}:\n"
|
||||
" mValue.m${name}.Destroy();\n"
|
||||
" mType = eUninitialized;\n"
|
||||
" break;", templateVars))
|
||||
destructor = string.Template("""
|
||||
${structName}ReturnValue::~${structName}ReturnValue()
|
||||
{
|
||||
switch (mType) {
|
||||
${callDestructors}
|
||||
case eUninitialized:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
""").substitute(
|
||||
{
|
||||
"structName": self.type.__str__(),
|
||||
"callDestructors": "\n".join(callDestructors),
|
||||
})
|
||||
|
||||
return destructor + "\n\n".join(methods) + toJSVal
|
||||
|
||||
def getConversionToJS(self, arg):
|
||||
(templateVars, type) = arg
|
||||
assert not type.nullable() # flatMemberTypes never has nullable types
|
||||
val = "mValue.m%(name)s.Value()" % templateVars
|
||||
wrapCode = wrapForType(
|
||||
type, self.descriptorProvider,
|
||||
{
|
||||
"jsvalRef": "rval",
|
||||
"jsvalHandle": "rval",
|
||||
"obj": "scopeObj",
|
||||
"result": val,
|
||||
})
|
||||
return CGIndenter(CGList([CGGeneric("case e%(name)s:" % templateVars),
|
||||
CGWrapper(CGIndenter(CGGeneric(wrapCode)),
|
||||
|
@ -2504,7 +2504,7 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
raise WebIDLError("An attribute cannot be of a sequence type",
|
||||
[self.location])
|
||||
if self.type.isUnion():
|
||||
for f in self.type.flatMemberTypes:
|
||||
for f in self.type.unroll().flatMemberTypes:
|
||||
if f.isDictionary():
|
||||
raise WebIDLError("An attribute cannot be of a union "
|
||||
"type if one of its member types (or "
|
||||
|
@ -507,6 +507,16 @@ public:
|
||||
//void PassUnionWithCallback(JSContext*, const TestCallbackOrLong&);
|
||||
void PassUnionWithObject(JSContext*, const ObjectOrLong&);
|
||||
|
||||
void ReceiveUnion(const CanvasPatternOrCanvasGradientReturnValue&);
|
||||
void ReceiveUnionContainingNull(const CanvasPatternOrNullOrCanvasGradientReturnValue&);
|
||||
void ReceiveNullableUnion(const Nullable<CanvasPatternOrCanvasGradientReturnValue>&);
|
||||
void GetWritableUnion(const CanvasPatternOrCanvasGradientReturnValue&);
|
||||
void SetWritableUnion(const CanvasPatternOrCanvasGradient&);
|
||||
void GetWritableUnionContainingNull(const CanvasPatternOrNullOrCanvasGradientReturnValue&);
|
||||
void SetWritableUnionContainingNull(const CanvasPatternOrNullOrCanvasGradient&);
|
||||
void GetWritableNullableUnion(const Nullable<CanvasPatternOrCanvasGradientReturnValue>&);
|
||||
void SetWritableNullableUnion(const Nullable<CanvasPatternOrCanvasGradient>&);
|
||||
|
||||
// Date types
|
||||
void PassDate(Date);
|
||||
void PassNullableDate(const Nullable<Date>&);
|
||||
|
@ -452,6 +452,14 @@ interface TestInterface {
|
||||
void passUnionWithObject((object or long) arg);
|
||||
//void passUnionWithDict((Dict or long) arg);
|
||||
|
||||
(CanvasPattern or CanvasGradient) receiveUnion();
|
||||
(CanvasPattern? or CanvasGradient) receiveUnionContainingNull();
|
||||
(CanvasPattern or CanvasGradient)? receiveNullableUnion();
|
||||
|
||||
attribute (CanvasPattern or CanvasGradient) writableUnion;
|
||||
attribute (CanvasPattern? or CanvasGradient) writableUnionContainingNull;
|
||||
attribute (CanvasPattern or CanvasGradient)? writableNullableUnion;
|
||||
|
||||
// Date types
|
||||
void passDate(Date arg);
|
||||
void passNullableDate(Date? arg);
|
||||
|
@ -348,6 +348,14 @@ interface TestExampleInterface {
|
||||
void passUnionWithObject((object or long) arg);
|
||||
//void passUnionWithDict((Dict or long) arg);
|
||||
|
||||
//(CanvasPattern or CanvasGradient) receiveUnion();
|
||||
//(CanvasPattern? or CanvasGradient) receiveUnionContainingNull();
|
||||
//(CanvasPattern or CanvasGradient)? receiveNullableUnion();
|
||||
|
||||
//attribute (CanvasPattern or CanvasGradient) writableUnion;
|
||||
//attribute (CanvasPattern? or CanvasGradient) writableUnionContainingNull;
|
||||
//attribute (CanvasPattern or CanvasGradient)? writableNullableUnion;
|
||||
|
||||
// Date types
|
||||
void passDate(Date arg);
|
||||
void passNullableDate(Date? arg);
|
||||
|
@ -372,6 +372,14 @@ interface TestJSImplInterface {
|
||||
void passUnionWithObject((object or long) arg);
|
||||
//void passUnionWithDict((Dict or long) arg);
|
||||
|
||||
//(CanvasPattern or CanvasGradient) receiveUnion();
|
||||
//(CanvasPattern? or CanvasGradient) receiveUnionContainingNull();
|
||||
//(CanvasPattern or CanvasGradient)? receiveNullableUnion();
|
||||
|
||||
//attribute (CanvasPattern or CanvasGradient) writableUnion;
|
||||
//attribute (CanvasPattern? or CanvasGradient) writableUnionContainingNull;
|
||||
//attribute (CanvasPattern or CanvasGradient)? writableNullableUnion;
|
||||
|
||||
// Date types
|
||||
void passDate(Date arg);
|
||||
void passNullableDate(Date? arg);
|
||||
|
@ -17,4 +17,5 @@ LIBXUL_LIBRARY = 1
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += -I$(topsrcdir)/dom/base
|
||||
INCLUDES += -I$(topsrcdir)/content/base/src
|
||||
|
||||
|
@ -46,10 +46,8 @@ interface CanvasRenderingContext2D {
|
||||
attribute DOMString globalCompositeOperation; // (default source-over)
|
||||
|
||||
// colors and styles (see also the CanvasDrawingStyles interface)
|
||||
[GetterThrows]
|
||||
attribute any strokeStyle; // (default black)
|
||||
[GetterThrows]
|
||||
attribute any fillStyle; // (default black)
|
||||
attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default black)
|
||||
attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
|
||||
[Creator]
|
||||
CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
|
||||
[Creator, Throws]
|
||||
|
Loading…
Reference in New Issue
Block a user