2010-10-23 Nikolas Zimmermann <nzimmermann@rim.com>
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 24 Oct 2010 10:38:56 +0000 (10:38 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 24 Oct 2010 10:38:56 +0000 (10:38 +0000)
        Reviewed by Dirk Schulze.

        Convert SVGAngle to the new SVGPropertyTearOff concept, reimplement it properly
        https://bugs.webkit.org/show_bug.cgi?id=48179

        Rewrite SVGAngle to use the new SVGPropertyTearOff concept, and consume much less memory.
        Down from two floats, one string and an ushort to one float and one ushort. Synchronize value/valueInSpecifiedUnits/valueAsString on demand.

        Adding an extensive SVGAngle test, that required to implement 'StrictTypeChecking' for attribute setters (was only implemented in V8/JSC for function cals so far).

        Test: svg/dom/SVGAngle.html

        * GNUmakefile.am: Add SVGAnimatedAngle.h to build.
        * WebCore.gypi: Ditto.
        * WebCore.pro: Ditto.
        * WebCore.vcproj/WebCore.vcproj: Ditto.
        * WebCore.xcodeproj/project.pbxproj: Ditto.
        * bindings/scripts/CodeGenerator.pm: Split IsPrimitiveType in IsPrimitiveType and IsNumericType.
        * bindings/scripts/CodeGeneratorJS.pm: Implement 'StrictTypeChecking' for setters and recognize SVGAngle as new SVGPropertyTearOff type.
        * bindings/scripts/CodeGeneratorObjC.pm: Ditto.
        * bindings/scripts/CodeGeneratorV8.pm: Ditto.
        * svg/DeprecatedSVGAnimatedPropertyTraits.h: Remove SVGAngle handling.
        * svg/DeprecatedSVGAnimatedTemplate.h: Remove SVGAnimatedAngle handling.
        * svg/SVGAngle.cpp: Rewrite, to consume less memory and to operate more efficient.
        * svg/SVGAngle.h: Ditto.
        * svg/SVGAngle.idl: Add 'StrictTypeChecking' to the value/valueInSpecifiedUnits methods.
        * svg/SVGAnimatedAngle.h: Added.
        * svg/SVGAnimatedAngle.idl: Mark as [SVGAnimatedProperty].
        * svg/SVGMarkerElement.cpp:
        (WebCore::SVGMarkerElement::parseMappedAttribute): SVGAngle::setValueAsString() now takes an ExceptionCode parameter.
        * svg/SVGMarkerElement.h: s/ANIMATED_PROPERTY/ANIMATED_PROPERTY_NEW/ for the SVGAngle type.
        * svg/SVGNumber.idl: Remove exception setter exceptions, which aren't needed. As we're now generating exception handlers in the bindings, it would lead to compile errors.
        * svg/SVGPoint.idl: Ditto.
        * svg/SVGRect.idl: Ditto.
        * svg/SVGSVGElement.idl: Remove obsolete [SVGLiveProperty] flag.
2010-10-23  Nikolas Zimmermann  <nzimmermann@rim.com>

        Reviewed by Dirk Schulze.

        Convert SVGAngle to the new SVGPropertyTearOff concept, reimplement it properly
        https://bugs.webkit.org/show_bug.cgi?id=48179

        Add an extensive SVGAngle test, checking all getter/setters & methods, with valid and invalid arguments.
        The test exposes bugs in Opera & FireFox, we now pass them all.

        * svg/dom/SVGAngle-expected.txt: Added.
        * svg/dom/SVGAngle.html: Added.
        * svg/dom/script-tests/SVGAngle.js: Added.
        * svg/dom/svg-element-attribute-js-null-expected.txt:
        * svg/dom/svg-element-attribute-js-null.xhtml: Update incorrect test, setting valueAsString to null, should not result in "0deg" but "0".

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70410 268f45cc-cd09-0410-ab3c-d52691b4dbfc

29 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/dom/SVGAngle-expected.txt [new file with mode: 0644]
LayoutTests/svg/dom/SVGAngle.html [new file with mode: 0644]
LayoutTests/svg/dom/script-tests/SVGAngle.js [new file with mode: 0644]
LayoutTests/svg/dom/svg-element-attribute-js-null-expected.txt
LayoutTests/svg/dom/svg-element-attribute-js-null.xhtml
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/bindings/scripts/CodeGenerator.pm
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/bindings/scripts/CodeGeneratorObjC.pm
WebCore/bindings/scripts/CodeGeneratorV8.pm
WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h
WebCore/svg/DeprecatedSVGAnimatedTemplate.h
WebCore/svg/SVGAngle.cpp
WebCore/svg/SVGAngle.h
WebCore/svg/SVGAngle.idl
WebCore/svg/SVGAnimatedAngle.h [new file with mode: 0644]
WebCore/svg/SVGAnimatedAngle.idl
WebCore/svg/SVGMarkerElement.cpp
WebCore/svg/SVGMarkerElement.h
WebCore/svg/SVGNumber.idl
WebCore/svg/SVGPoint.idl
WebCore/svg/SVGRect.idl
WebCore/svg/SVGSVGElement.idl

index e9307e0..ab210f8 100644 (file)
@@ -1,3 +1,19 @@
+2010-10-23  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Convert SVGAngle to the new SVGPropertyTearOff concept, reimplement it properly
+        https://bugs.webkit.org/show_bug.cgi?id=48179
+
+        Add an extensive SVGAngle test, checking all getter/setters & methods, with valid and invalid arguments.
+        The test exposes bugs in Opera & FireFox, we now pass them all.
+
+        * svg/dom/SVGAngle-expected.txt: Added.
+        * svg/dom/SVGAngle.html: Added.
+        * svg/dom/script-tests/SVGAngle.js: Added.
+        * svg/dom/svg-element-attribute-js-null-expected.txt:
+        * svg/dom/svg-element-attribute-js-null.xhtml: Update incorrect test, setting valueAsString to null, should not result in "0deg" but "0".
+
 2010-10-23  Dimitri Glazkov  <dglazkov@chromium.org>
 
         [Chromium/DRT] Unbreak build by removing duplicate test expectations.
diff --git a/LayoutTests/svg/dom/SVGAngle-expected.txt b/LayoutTests/svg/dom/SVGAngle-expected.txt
new file mode 100644 (file)
index 0000000..217c2a2
--- /dev/null
@@ -0,0 +1,173 @@
+This test checks the SVGAngle API
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Check initial angle values
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+
+Check invalid arguments for 'convertToSpecifiedUnits'
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN) threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
+PASS angle.convertToSpecifiedUnits(-1) threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
+PASS angle.convertToSpecifiedUnits(5) threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Check valid arguments for 'convertToSpecifiedUnits', that should only modify the 'valueAsString'
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD) is undefined.
+PASS angle.valueAsString is "0rad"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD) is undefined.
+PASS angle.valueAsString is "0grad"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_GRAD
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG) is undefined.
+PASS angle.valueAsString is "0deg"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED) is undefined.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Check invalid arguments for 'newValueSpecifiedUnits'
+PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN, 50) threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
+PASS angle.newValueSpecifiedUnits(-1, 50) threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
+PASS angle.newValueSpecifiedUnits(5, 50) threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Check valid arguments for 'newValueSpecifiedUnits', that should only modify the 'valueAsString'
+PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, parseFloat(Math.PI.toFixed(5))) is undefined.
+PASS angle.valueAsString is "3.14159rad"
+PASS angle.value.toFixed(1) is "180.0"
+PASS angle.valueInSpecifiedUnits.toFixed(5) is Math.PI.toFixed(5)
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
+PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD, 400) is undefined.
+PASS angle.valueAsString is "400grad"
+PASS angle.value.toFixed(1) is "360.0"
+PASS angle.valueInSpecifiedUnits is 400
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_GRAD
+PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 360) is undefined.
+PASS angle.valueAsString is "360deg"
+PASS angle.value is 360
+PASS angle.valueInSpecifiedUnits is 360
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 180) is undefined.
+PASS angle.valueAsString is "180"
+PASS angle.value is 180
+PASS angle.valueInSpecifiedUnits is 180
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Reset to initial angle state
+PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 0) is undefined.
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Check setting invalid 'valueAsString' arguments
+PASS angle.valueAsString = '10px' threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS angle.valueAsString = '10x' threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS angle.valueAsString = '5graD' threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS angle.valueAsString = '5Rad' threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS angle.valueAsString = ',5 rad' threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Check setting invalid 'valueInSpecifiedUnits' arguments
+PASS angle.valueInSpecifiedUnits = 'test' threw exception TypeError: Type error.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS angle.valueInSpecifiedUnits = angle threw exception TypeError: Type error.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Check setting invalid 'value' arguments
+PASS angle.value = 'test' threw exception TypeError: Type error.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS angle.value = angle threw exception TypeError: Type error.
+PASS angle.valueAsString is "0"
+PASS angle.value is 0
+PASS angle.valueInSpecifiedUnits is 0
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+
+Reset to angle in degree units
+PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0) is undefined.
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+
+Check setting valid 'value' arguments, assure that 'valueInSpecifiedUnits' and 'valueAsString' are synchronized
+PASS angle.value = 50 is 50
+PASS angle.valueInSpecifiedUnits is 50
+PASS angle.valueAsString is "50deg"
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+
+Try modifiying the readonly 'unitType', needs to fail
+PASS angle.unitType = SVGAngle.SVG_ANGLETTYE_RAD is undefined.
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+
+Check setting valid 'valueInSpecifiedUnits' arguments, assure that 'value' and 'valueAsString' are synchronized
+PASS angle.valueInSpecifiedUnits = 100 is 100
+PASS angle.value is 100
+PASS angle.valueAsString is "100deg"
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+
+Check setting valid 'valueAsString' arguments, assure that 'value' and 'valueInSpecifiedUnits' are synchronized
+PASS angle.valueAsString = '200grad' is "200grad"
+PASS angle.valueInSpecifiedUnits is 200
+PASS angle.value.toFixed(1) is "180.0"
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_GRAD
+
+Now convert the GRAD value into a RAD value, and assure that all properties have been synchronized
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD) is undefined.
+PASS angle.value.toFixed(1) is "180.0"
+PASS angle.valueInSpecifiedUnits.toFixed(5) is "3.14159"
+PASS angle.valueAsString is "3.14159rad"
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
+
+Now try converting the RAD value into an unknown value, that should fail and throw
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN) threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
+PASS angle.value.toFixed(1) is "180.0"
+PASS angle.valueInSpecifiedUnits.toFixed(5) is "3.14159"
+PASS angle.valueAsString is "3.14159rad"
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
+
+Now convert the RAD value into a DEG value, and assure that all properties have been synchronized
+PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG) is undefined.
+PASS angle.value.toFixed(1) is "180.0"
+PASS angle.valueInSpecifiedUnits.toFixed(1) is "180.0"
+PASS angle.valueAsString is "180deg"
+PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/dom/SVGAngle.html b/LayoutTests/svg/dom/SVGAngle.html
new file mode 100644 (file)
index 0000000..9eb6288
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/SVGAngle.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/dom/script-tests/SVGAngle.js b/LayoutTests/svg/dom/script-tests/SVGAngle.js
new file mode 100644 (file)
index 0000000..c772946
--- /dev/null
@@ -0,0 +1,202 @@
+description("This test checks the SVGAngle API");
+
+var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+var angle = svgElement.createSVGAngle();
+
+debug("");
+debug("Check initial angle values");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+
+// Spec: Raised if unitType is SVG_ANGLETYPE_UNKNOWN or not a valid unit type constant (one of the other SVG_ANGLETYPE_* constants defined on this interface).
+debug("");
+debug("Check invalid arguments for 'convertToSpecifiedUnits'");
+shouldThrow("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN)");
+shouldThrow("angle.convertToSpecifiedUnits(-1)");
+shouldThrow("angle.convertToSpecifiedUnits(5)");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+debug("");
+debug("Check valid arguments for 'convertToSpecifiedUnits', that should only modify the 'valueAsString'");
+shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD)");
+shouldBeEqualToString("angle.valueAsString", "0rad");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
+
+shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD)");
+shouldBeEqualToString("angle.valueAsString", "0grad");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_GRAD");
+
+shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG)");
+shouldBeEqualToString("angle.valueAsString", "0deg");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+
+shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED)");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+// Spec: Raised if unitType is SVG_ANGLETYPE_UNKNOWN or not a valid unit type constant (one of the other SVG_ANGLETYPE_* constants defined on this interface).
+debug("");
+debug("Check invalid arguments for 'newValueSpecifiedUnits'");
+shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN, 50)");
+shouldThrow("angle.newValueSpecifiedUnits(-1, 50)");
+shouldThrow("angle.newValueSpecifiedUnits(5, 50)");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+debug("");
+debug("Check valid arguments for 'newValueSpecifiedUnits', that should only modify the 'valueAsString'");
+shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, parseFloat(Math.PI.toFixed(5)))");
+shouldBeEqualToString("angle.valueAsString", Math.PI.toFixed(5) + "rad");
+shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
+shouldBe("angle.valueInSpecifiedUnits.toFixed(5)", "Math.PI.toFixed(5)");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
+
+shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD, 400)");
+shouldBeEqualToString("angle.valueAsString", "400grad");
+shouldBeEqualToString("angle.value.toFixed(1)", "360.0");
+shouldBe("angle.valueInSpecifiedUnits", "400");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_GRAD");
+
+shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 360)");
+shouldBeEqualToString("angle.valueAsString", "360deg");
+shouldBe("angle.value", "360");
+shouldBe("angle.valueInSpecifiedUnits", "360");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+
+shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 180)");
+shouldBeEqualToString("angle.valueAsString", "180");
+shouldBe("angle.value", "180");
+shouldBe("angle.valueInSpecifiedUnits", "180");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+debug("");
+debug("Reset to initial angle state");
+shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 0)");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+// Spec: Raised if the assigned string cannot be parsed as a valid <angle>.
+debug("");
+debug("Check setting invalid 'valueAsString' arguments");
+shouldThrow("angle.valueAsString = '10px'");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+shouldThrow("angle.valueAsString = '10x'");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+shouldThrow("angle.valueAsString = '5graD'");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+shouldThrow("angle.valueAsString = '5Rad'");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+shouldThrow("angle.valueAsString = ',5 rad'");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+debug("");
+debug("Check setting invalid 'valueInSpecifiedUnits' arguments");
+shouldThrow("angle.valueInSpecifiedUnits = 'test'");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+shouldThrow("angle.valueInSpecifiedUnits = angle");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+debug("");
+debug("Check setting invalid 'value' arguments");
+shouldThrow("angle.value = 'test'");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+shouldThrow("angle.value = angle");
+shouldBeEqualToString("angle.valueAsString", "0");
+shouldBe("angle.value", "0");
+shouldBe("angle.valueInSpecifiedUnits", "0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+
+debug("");
+debug("Reset to angle in degree units");
+shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0)");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+
+debug("");
+debug("Check setting valid 'value' arguments, assure that 'valueInSpecifiedUnits' and 'valueAsString' are synchronized");
+shouldBe("angle.value = 50", "50");
+shouldBe("angle.valueInSpecifiedUnits", "50");
+shouldBeEqualToString("angle.valueAsString", "50deg");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+
+debug("");
+debug("Try modifiying the readonly 'unitType', needs to fail");
+shouldBeUndefined("angle.unitType = SVGAngle.SVG_ANGLETTYE_RAD");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+
+debug("");
+debug("Check setting valid 'valueInSpecifiedUnits' arguments, assure that 'value' and 'valueAsString' are synchronized");
+shouldBe("angle.valueInSpecifiedUnits = 100", "100");
+shouldBe("angle.value", "100");
+shouldBeEqualToString("angle.valueAsString", "100deg");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+
+debug("");
+debug("Check setting valid 'valueAsString' arguments, assure that 'value' and 'valueInSpecifiedUnits' are synchronized");
+shouldBeEqualToString("angle.valueAsString = '200grad'", "200grad");
+shouldBe("angle.valueInSpecifiedUnits", "200");
+shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_GRAD");
+
+debug("");
+debug("Now convert the GRAD value into a RAD value, and assure that all properties have been synchronized");
+shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD)");
+shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
+shouldBeEqualToString("angle.valueInSpecifiedUnits.toFixed(5)", Math.PI.toFixed(5));
+shouldBeEqualToString("angle.valueAsString", Math.PI.toFixed(5) + "rad");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
+
+debug("");
+debug("Now try converting the RAD value into an unknown value, that should fail and throw");
+shouldThrow("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN)");
+shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
+shouldBeEqualToString("angle.valueInSpecifiedUnits.toFixed(5)", Math.PI.toFixed(5));
+shouldBeEqualToString("angle.valueAsString", Math.PI.toFixed(5) + "rad");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
+
+debug("");
+debug("Now convert the RAD value into a DEG value, and assure that all properties have been synchronized");
+shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG)");
+shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
+shouldBeEqualToString("angle.valueInSpecifiedUnits.toFixed(1)", "180.0");
+shouldBeEqualToString("angle.valueAsString", "180deg");
+shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+
+successfullyParsed = true;
index 5bb0aba..f2d0b21 100644 (file)
@@ -3,7 +3,7 @@ This test setting various attributes of a SVG elements to JavaScript null.
 TEST SUCCEEDED: The value was the empty string. [tested SVGElement.id]
 TEST SUCCEEDED: The value was the empty string. [tested SVGElement.xmlbase]
 
-TEST SUCCEEDED: The value was the string '0deg'. [tested SVGAngle.valueAsString]
+TEST SUCCEEDED: The value was the string '0'. [tested SVGAngle.valueAsString]
 
 TEST SUCCEEDED: The value was the string '0'. [tested SVGLength.valueAsString]
 
index 02c3702..e24255a 100644 (file)
@@ -60,7 +60,7 @@
                     type: 'SVGAngle',
                     elementToUse: svg.createSVGAngle(),
                     attributes: [
-                        {name: 'valueAsString', expectedNull: '0deg'}
+                        {name: 'valueAsString', expectedNull: '0'}
                     ]
                 },
                 {
index 2c4d065..f69c7e9 100644 (file)
@@ -1,3 +1,41 @@
+2010-10-23  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Convert SVGAngle to the new SVGPropertyTearOff concept, reimplement it properly
+        https://bugs.webkit.org/show_bug.cgi?id=48179
+
+        Rewrite SVGAngle to use the new SVGPropertyTearOff concept, and consume much less memory.
+        Down from two floats, one string and an ushort to one float and one ushort. Synchronize value/valueInSpecifiedUnits/valueAsString on demand.
+
+        Adding an extensive SVGAngle test, that required to implement 'StrictTypeChecking' for attribute setters (was only implemented in V8/JSC for function cals so far).
+
+        Test: svg/dom/SVGAngle.html
+
+        * GNUmakefile.am: Add SVGAnimatedAngle.h to build.
+        * WebCore.gypi: Ditto.
+        * WebCore.pro: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * bindings/scripts/CodeGenerator.pm: Split IsPrimitiveType in IsPrimitiveType and IsNumericType.
+        * bindings/scripts/CodeGeneratorJS.pm: Implement 'StrictTypeChecking' for setters and recognize SVGAngle as new SVGPropertyTearOff type.
+        * bindings/scripts/CodeGeneratorObjC.pm: Ditto.
+        * bindings/scripts/CodeGeneratorV8.pm: Ditto.
+        * svg/DeprecatedSVGAnimatedPropertyTraits.h: Remove SVGAngle handling.
+        * svg/DeprecatedSVGAnimatedTemplate.h: Remove SVGAnimatedAngle handling.
+        * svg/SVGAngle.cpp: Rewrite, to consume less memory and to operate more efficient.
+        * svg/SVGAngle.h: Ditto.
+        * svg/SVGAngle.idl: Add 'StrictTypeChecking' to the value/valueInSpecifiedUnits methods.
+        * svg/SVGAnimatedAngle.h: Added.
+        * svg/SVGAnimatedAngle.idl: Mark as [SVGAnimatedProperty].
+        * svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::parseMappedAttribute): SVGAngle::setValueAsString() now takes an ExceptionCode parameter.
+        * svg/SVGMarkerElement.h: s/ANIMATED_PROPERTY/ANIMATED_PROPERTY_NEW/ for the SVGAngle type.
+        * svg/SVGNumber.idl: Remove exception setter exceptions, which aren't needed. As we're now generating exception handlers in the bindings, it would lead to compile errors.
+        * svg/SVGPoint.idl: Ditto.
+        * svg/SVGRect.idl: Ditto.
+        * svg/SVGSVGElement.idl: Remove obsolete [SVGLiveProperty] flag.
+
 2010-10-23  Daniel Bates  <dbates@rim.com>
 
         Reviewed by Adam Barth.
index c9689f7..3c8783f 100644 (file)
@@ -3028,6 +3028,7 @@ webcore_sources += \
        WebCore/svg/SVGAngle.h \
        WebCore/svg/SVGAnimateColorElement.cpp \
        WebCore/svg/SVGAnimateColorElement.h \
+       WebCore/svg/SVGAnimatedAngle.h \
        WebCore/svg/SVGAnimatedLength.h \
        WebCore/svg/SVGAnimatedLengthList.h \
        WebCore/svg/SVGAnimatedPathData.cpp \
index ddde4fd..cd65668 100644 (file)
             'svg/SVGAnimateMotionElement.h',
             'svg/SVGAnimateTransformElement.cpp',
             'svg/SVGAnimateTransformElement.h',
+            'svg/SVGAnimatedAngle.h',
             'svg/SVGAnimatedLength.h',
             'svg/SVGAnimatedLengthList.h',
             'svg/SVGAnimatedPathData.cpp',
index bf31b67..551bd9b 100644 (file)
@@ -2358,6 +2358,7 @@ HEADERS += \
     svg/SVGAltGlyphElement.h \
     svg/SVGAngle.h \
     svg/SVGAnimateColorElement.h \
+    svg/SVGAnimatedAngle.h \
     svg/SVGAnimatedLength.h \
     svg/SVGAnimatedLengthList.h \
     svg/SVGAnimatedPathData.h \
index 629baed..c700074 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\svg\SVGAnimatedAngle.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\svg\SVGAnimatedLength.h"\r
                                >\r
                        </File>\r
index 8f09b8b..4c1e01d 100644 (file)
                08735FB910E91232006D6FAD /* SVGMarkerLayoutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 08735FB710E91232006D6FAD /* SVGMarkerLayoutInfo.h */; };
                08744BAA0EDB7D86004C9E63 /* WMLOnEventElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08744BA90EDB7D86004C9E63 /* WMLOnEventElement.cpp */; };
                08744BAE0EDB7D92004C9E63 /* WMLOnEventElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08744BAD0EDB7D92004C9E63 /* WMLOnEventElement.h */; };
+               087B84961272CEC800A14417 /* SVGAnimatedAngle.h in Headers */ = {isa = PBXBuildFile; fileRef = 087B84951272CEC700A14417 /* SVGAnimatedAngle.h */; settings = {ATTRIBUTES = (Private, ); }; };
                087D97BF10FB8D7700C00874 /* JSSVGPODListCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 087D97BE10FB8D7700C00874 /* JSSVGPODListCustom.h */; };
                087FFA0F0EFF3ED3009DBD88 /* WMLInsertedLegendElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 087FFA0D0EFF3ED3009DBD88 /* WMLInsertedLegendElement.cpp */; };
                087FFA100EFF3ED3009DBD88 /* WMLInsertedLegendElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 087FFA0E0EFF3ED3009DBD88 /* WMLInsertedLegendElement.h */; };
                08735FB710E91232006D6FAD /* SVGMarkerLayoutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGMarkerLayoutInfo.h; sourceTree = "<group>"; };
                08744BA90EDB7D86004C9E63 /* WMLOnEventElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLOnEventElement.cpp; sourceTree = "<group>"; };
                08744BAD0EDB7D92004C9E63 /* WMLOnEventElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLOnEventElement.h; sourceTree = "<group>"; };
+               087B84951272CEC700A14417 /* SVGAnimatedAngle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedAngle.h; sourceTree = "<group>"; };
                087D97BE10FB8D7700C00874 /* JSSVGPODListCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSVGPODListCustom.h; sourceTree = "<group>"; };
                087FFA0D0EFF3ED3009DBD88 /* WMLInsertedLegendElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLInsertedLegendElement.cpp; sourceTree = "<group>"; };
                087FFA0E0EFF3ED3009DBD88 /* WMLInsertedLegendElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLInsertedLegendElement.h; sourceTree = "<group>"; };
                                B22277E30D00BF1F0071B782 /* SVGAnimateColorElement.cpp */,
                                B22277E40D00BF1F0071B782 /* SVGAnimateColorElement.h */,
                                B22277E50D00BF1F0071B782 /* SVGAnimateColorElement.idl */,
+                               087B84951272CEC700A14417 /* SVGAnimatedAngle.h */,
                                B22277E60D00BF1F0071B782 /* SVGAnimatedAngle.idl */,
                                B22277E70D00BF1F0071B782 /* SVGAnimatedBoolean.idl */,
                                B22277E80D00BF1F0071B782 /* SVGAnimatedEnumeration.idl */,
                                089021A9126EF5DE0092D5EA /* SVGAnimatedLength.h in Headers */,
                                089021AD126EF5E90092D5EA /* SVGAnimatedLengthList.h in Headers */,
                                8AB4BC77126FDB7100DEB727 /* IgnoreDestructiveWriteCountIncrementer.h in Headers */,
+                               087B84961272CEC800A14417 /* SVGAnimatedAngle.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index cbf0cbd..f10908b 100644 (file)
@@ -5,6 +5,7 @@
 # Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
 # Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
 # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
+# Copyright (C) Research In Motion Limited 2010. All rights reserved.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -42,20 +43,22 @@ my $codeGenerator = 0;
 
 my $verbose = 0;
 
-my %primitiveTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1,
-                         "unsigned int" => 1, "unsigned short" => 1,
-                         "unsigned long" => 1, "unsigned long long" => 1,
-                         "float" => 1, "double" => 1,
-                         "boolean" => 1, "void" => 1,
-                         "Date" => 1);
+my %numericTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1,
+                       "unsigned int" => 1, "unsigned short" => 1,
+                       "unsigned long" => 1, "unsigned long long" => 1,
+                       "float" => 1, "double" => 1);
+
+my %primitiveTypeHash = ( "boolean" => 1, "void" => 1, "Date" => 1);
 
 my %podTypeHash = ("SVGNumber" => 1, "SVGTransform" => 1);
-my %podTypesWithWritablePropertiesHash = ("SVGAngle" => 1, "SVGMatrix" => 1, "SVGPoint" => 1, "SVGPreserveAspectRatio" => 1, "SVGRect" => 1);
+my %podTypesWithWritablePropertiesHash = ("SVGMatrix" => 1, "SVGPoint" => 1, "SVGPreserveAspectRatio" => 1, "SVGRect" => 1);
 my %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1);
 
 my %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1, "SVGPaintType" => 1);
 
-my %svgNewStyleAnimatedTypeHash = ("SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1);
+my %svgTypeNeedingTearOffHash = ("SVGLength" => 1, "SVGAngle" => 1);
+
+my %svgNewStyleAnimatedTypeHash = ("SVGAnimatedAngle" => 1, "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1);
 
 my %svgAnimatedTypeHash = ("SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1,
                            "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1,
@@ -283,6 +286,8 @@ sub ParseInterface
 }
 
 # Helpers for all CodeGenerator***.pm modules
+
+# FIXME: This method will go away once all SVG animated properties are converted to the new scheme.
 sub IsPodType
 {
     my $object = shift;
@@ -302,12 +307,22 @@ sub IsPodTypeWithWriteableProperties
     return 0;
 }
 
+sub IsNumericType
+{
+    my $object = shift;
+    my $type = shift;
+
+    return 1 if $numericTypeHash{$type};
+    return 0;
+}
+
 sub IsPrimitiveType
 {
     my $object = shift;
     my $type = shift;
 
     return 1 if $primitiveTypeHash{$type};
+    return 1 if $numericTypeHash{$type};
     return 0;
 }
 
@@ -325,7 +340,17 @@ sub IsNonPointerType
     my $object = shift;
     my $type = shift;
 
-    return 1 if $nonPointerTypeHash{$type} or $primitiveTypeHash{$type};
+    return 1 if $nonPointerTypeHash{$type} or $primitiveTypeHash{$type} or $numericTypeHash{$type};
+    return 0;
+}
+
+
+sub IsSVGTypeNeedingTearOff
+{
+    my $object = shift;
+    my $type = shift;
+
+    return 1 if $svgTypeNeedingTearOffHash{$type};
     return 0;
 }
 
index 0b56f13..9370e15 100644 (file)
@@ -324,15 +324,18 @@ sub AddClassForwardIfNeeded
     }
 }
 
+# FIXME: This method will go away once all SVG animated properties are converted to the new scheme.
 sub IsSVGTypeNeedingContextParameter
 {
+    # FIXME: This function will be removed, as soon the PODType concept is gone, and all SVG datatypes use the new style JS bindings.
+
     my $implClassName = shift;
 
     return 0 unless $implClassName =~ /SVG/;
     return 0 if $implClassName =~ /Element/;
     return 0 if $codeGenerator->IsSVGNewStyleAnimatedType($implClassName);
 
-    my @noContextNeeded = ("SVGLength", "SVGLengthList", "SVGPaint", "SVGColor", "SVGDocument", "SVGZoomEvent");
+    my @noContextNeeded = ("SVGAngle", "SVGLength", "SVGLengthList", "SVGPaint", "SVGColor", "SVGDocument", "SVGZoomEvent");
     foreach (@noContextNeeded) {
         return 0 if $implClassName eq $_;
     }
@@ -1802,21 +1805,53 @@ sub GenerateImplementation
                         } else {
                             push(@implContent, "    $className* castedThis = static_cast<$className*>(thisObject);\n");
                             push(@implContent, "    $implType* imp = static_cast<$implType*>(castedThis->impl());\n");
+                            push(@implContent, "    ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions};
+
+                            # For setters with "StrictTypeChecking", if an input parameter's type does not match the signature,
+                            # a TypeError is thrown instead of casting to null.
+                            if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) {
+                                my $argType = $attribute->signature->type;
+                                if ($codeGenerator->IsStringType($argType)) {
+                                    push(@implContent, "    if (!value.isUndefinedOrNull() && !value.isString() && !value.isObject()) {\n");
+                                    push(@implContent, "        throwVMTypeError(exec);\n");
+                                    push(@implContent, "        return;\n");
+                                    push(@implContent, "    };\n");
+                                } elsif ($codeGenerator->IsNumericType($argType)) {
+                                    push(@implContent, "    if (!value.isUndefinedOrNull() && !value.isNumber()) {\n");
+                                    push(@implContent, "        throwVMTypeError(exec);\n");
+                                    push(@implContent, "        return;\n");
+                                    push(@implContent, "    };\n");
+                                } elsif (!IsNativeType($argType)) {
+                                    push(@implContent, "    if (!value.isUndefinedOrNull() && !value.inherits(&JS${argType}::s_info)) {\n");
+                                    push(@implContent, "        throwVMTypeError(exec);\n");
+                                    push(@implContent, "        return;\n");
+                                    push(@implContent, "    };\n");
+                                }
+                            }
+
+                            my $nativeValue = JSValueToNative($attribute->signature, "value");
                             if ($svgPropertyOrPodType) {
                                 push(@implContent, "    $svgPropertyOrPodType podImp(*imp);\n") if $podType;
                                 push(@implContent, "    $svgPropertyOrPodType& podImp = imp->propertyReference();\n") if !$podType;
                                 if ($svgPropertyOrPodType eq "float") { # Special case for JSSVGNumber
-                                    push(@implContent, "    podImp = " . JSValueToNative($attribute->signature, "value") . ";\n");
+                                    push(@implContent, "    podImp = $nativeValue;\n");
                                 } else {
-                                    push(@implContent, "    podImp.set$implSetterFunctionName(" . JSValueToNative($attribute->signature, "value") . ");\n");
+                                    push(@implContent, "    podImp.set$implSetterFunctionName($nativeValue");
+                                    push(@implContent, ", ec") if @{$attribute->setterExceptions};
+                                    push(@implContent, ");\n");
+                                    push(@implContent, "    setDOMException(exec, ec);\n") if @{$attribute->setterExceptions};
                                 }
                                 push(@implContent, "    imp->commitChange(podImp, castedThis);\n") if $podType;
-                                push(@implContent, "    imp->commitChange();\n") if $svgPropertyType;
+                                if ($svgPropertyType) {
+                                    if (@{$attribute->setterExceptions}) {
+                                        push(@implContent, "    if (!ec)\n"); 
+                                        push(@implContent, "        imp->commitChange();\n");
+                                    } else {
+                                        push(@implContent, "    imp->commitChange();\n");
+                                    }
+                                }
                             } else {
-                                my $nativeValue = JSValueToNative($attribute->signature, "value");
                                 my $setterExpressionPrefix = $codeGenerator->SetterExpressionPrefix(\%implIncludes, $interfaceName, $attribute);
-
-                                push(@implContent, "    ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions};
                                 push(@implContent, "    imp->$setterExpressionPrefix$nativeValue");
                                 push(@implContent, ", ec") if @{$attribute->setterExceptions};
                                 push(@implContent, ");\n");
@@ -2008,8 +2043,9 @@ sub GenerateImplementation
                         }
 
                         my $name = $parameter->name;
+                        my $argType = $codeGenerator->StripModule($parameter->type);
 
-                        if ($parameter->type eq "XPathNSResolver") {
+                        if ($argType eq "XPathNSResolver") {
                             push(@implContent, "    RefPtr<XPathNSResolver> customResolver;\n");
                             push(@implContent, "    XPathNSResolver* resolver = toXPathNSResolver(exec->argument($argsIndex));\n");
                             push(@implContent, "    if (!resolver) {\n");
@@ -2019,10 +2055,10 @@ sub GenerateImplementation
                             push(@implContent, "        resolver = customResolver.get();\n");
                             push(@implContent, "    }\n");
                         } elsif ($parameter->extendedAttributes->{"Callback"}) {
-                            my $callbackClassName = GetCallbackClassName($parameter->type);
+                            my $callbackClassName = GetCallbackClassName($argType);
                             $implIncludes{"$callbackClassName.h"} = 1;
                             if ($parameter->extendedAttributes->{"Optional"}) {
-                                push(@implContent, "    RefPtr<" . $parameter->type. "> $name;\n");
+                                push(@implContent, "    RefPtr<$argType> $name;\n");
                                 push(@implContent, "    if (exec->argumentCount() > $argsIndex && !exec->argument($argsIndex).isNull() && !exec->argument($argsIndex).isUndefined()) {\n");
                                 push(@implContent, "        if (!exec->argument($argsIndex).isObject()) {\n");
                                 push(@implContent, "            setDOMException(exec, TYPE_MISMATCH_ERR);\n");
@@ -2035,21 +2071,23 @@ sub GenerateImplementation
                                 push(@implContent, "        setDOMException(exec, TYPE_MISMATCH_ERR);\n");
                                 push(@implContent, "        return JSValue::encode(jsUndefined());\n");
                                 push(@implContent, "    }\n");
-                                push(@implContent, "    RefPtr<" . $parameter->type . "> $name = ${callbackClassName}::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n");
+                                push(@implContent, "    RefPtr<$argType> $name = ${callbackClassName}::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n");
                             }
                         } else {
                             # For functions with "StrictTypeChecking", if an input parameter's type does not match the signature,
                             # a TypeError is thrown instead of casting to null.
                             if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
                                 my $argValue = "exec->argument($argsIndex)";
-                                my $argType = $codeGenerator->StripModule($parameter->type);
-                                if (!IsNativeType($argType)) {
-                                    push(@implContent, "    if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.inherits(&JS${argType}::s_info))\n");
-                                    push(@implContent, "        return throwVMTypeError(exec);\n");
-                                } elsif ($codeGenerator->IsStringType($argType)) {
+                                if ($codeGenerator->IsStringType($argType)) {
                                     push(@implContent, "    if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.isString() && !${argValue}.isObject())\n");
                                     push(@implContent, "        return throwVMTypeError(exec);\n");
-                                }
+                                } elsif ($codeGenerator->IsNumericType($argType)) {
+                                    push(@implContent, "    if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.isNumber())\n");
+                                    push(@implContent, "        return throwVMTypeError(exec);\n");
+                                } elsif (!IsNativeType($argType)) {
+                                    push(@implContent, "    if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.inherits(&JS${argType}::s_info))\n");
+                                    push(@implContent, "        return throwVMTypeError(exec);\n");
+                                } 
                             }
 
                             push(@implContent, "    " . GetNativeTypeFromSignature($parameter) . " $name = " . JSValueToNative($parameter, "exec->argument($argsIndex)") . ";\n");
@@ -2067,12 +2105,21 @@ sub GenerateImplementation
                             # Check if the type conversion succeeded.
                             push(@implContent, "    if (exec->hadException())\n");
                             push(@implContent, "        return JSValue::encode(jsUndefined());\n");
+
+                            if ($codeGenerator->IsSVGTypeNeedingTearOff($argType) and not $implClassName =~ /List$/) {
+                                push(@implContent, "    if (!$name) {\n");
+                                push(@implContent, "        setDOMException(exec, TYPE_MISMATCH_ERR);\n");
+                                push(@implContent, "        return JSValue::encode(jsUndefined());\n");
+                                push(@implContent, "    }\n");
+                            }
                         }
 
                         $functionString .= ", " if $paramIndex;
 
-                        if ($parameter->type eq "NodeFilter") {
+                        if ($argType eq "NodeFilter") {
                             $functionString .= "$name.get()";
+                        } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($argType) and not $implClassName =~ /List$/) {
+                            $functionString .= "$name->propertyReference()";
                         } else {
                             $functionString .= $name;
                         }
@@ -2371,7 +2418,16 @@ sub GenerateImplementationFunctionCall()
         push(@implContent, $indent . "$functionString;\n");
         push(@implContent, $indent . "setDOMException(exec, ec);\n") if @{$function->raisesExceptions};
         push(@implContent, $indent . "imp->commitChange(podImp, castedThis);\n") if $podType;
-        push(@implContent, $indent . "imp->commitChange();\n") if $svgPropertyType;
+
+        if ($svgPropertyType) {
+            if (@{$function->raisesExceptions}) {
+                push(@implContent, $indent . "if (!ec)\n"); 
+                push(@implContent, $indent . "    imp->commitChange();\n");
+            } else {
+                push(@implContent, $indent . "imp->commitChange();\n");
+            }
+        }
+
         push(@implContent, $indent . "return JSValue::encode(jsUndefined());\n");
     } else {
         push(@implContent, "\n" . $indent . "JSC::JSValue result = " . NativeToJSValue($function->signature, 1, $implClassName, "", $functionString, "castedThis") . ";\n");
@@ -2413,7 +2469,7 @@ my %nativeType = (
     "NodeFilter" => "RefPtr<NodeFilter>",
     "SerializedScriptValue" => "RefPtr<SerializedScriptValue>",
     "IDBKey" => "RefPtr<IDBKey>",
-    "SVGAngle" => "SVGAngle",
+    "SVGAngle" => "SVGPropertyTearOff<SVGAngle>*",
     "SVGLength" => "SVGPropertyTearOff<SVGLength>*",
     "SVGMatrix" => "AffineTransform",
     "SVGNumber" => "float",
@@ -2567,12 +2623,6 @@ sub NativeToJSValue
         }
     } 
 
-    my $svgLivePropertyType = $signature->extendedAttributes->{"SVGLiveProperty"};
-    if ($svgLivePropertyType) {
-        $implIncludes{"JS$type.h"} = 1;
-        return "toJS(exec, $globalObject, SVGPropertyTearOff<$type>::create($value).get())";
-    }
-
     if ($type eq "CSSStyleDeclaration") {
         $implIncludes{"CSSMutableStyleDeclaration.h"} = 1;
     }
@@ -2612,13 +2662,15 @@ sub NativeToJSValue
         return "toJSNewlyCreated(exec, $globalObject, WTF::getPtr($value))";
     }
 
-    # Convert from abstract SVGProperty to real type, so the right toJS() method can be invoked.
     if ($codeGenerator->IsSVGNewStyleAnimatedType($implClassName)) {
+        # Convert from abstract SVGProperty to real type, so the right toJS() method can be invoked.
         if ($implClassName =~ /List$/) {
             $value = "static_cast<SVGListPropertyTearOff<$type>*>($value)";
         } else {
             $value = "static_cast<SVGPropertyTearOff<$type>*>($value)";
         }
+    } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($type) and not $implClassName =~ /List$/) {
+        $value = "SVGPropertyTearOff<$type>::create($value)";
     }
 
     return "toJS(exec, $globalObject, WTF::getPtr($value))";
index 0732627..af3fb78 100644 (file)
@@ -6,6 +6,7 @@
 # Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
 # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
 # Copyright (C) 2010 Google Inc.
+# Copyright (C) Research In Motion Limited 2010. All rights reserved.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -1369,8 +1370,16 @@ sub GenerateImplementation
                 if ($svgPropertyType) {
                     $getterContentHead = "$getterExpressionPrefix";
                     push(@implContent, "    $svgPropertyTypeWithNamespace& podImpl = IMPL->propertyReference();\n");
-                    push(@implContent, "    podImpl.$coreSetterName($arg);\n");
-                    push(@implContent, "    IMPL->commitChange();\n");
+                    my $ec = $hasSetterException ? ", ec" : "";
+                    push(@implContent, "    $exceptionInit\n") if $hasSetterException;
+                    push(@implContent, "    podImpl.$coreSetterName($arg$ec);\n");
+                    if ($hasSetterException) {
+                        push(@implContent, "    if (!ec)\n");
+                        push(@implContent, "        IMPL->commitChange();\n");
+                        push(@implContent, "    $exceptionRaiseOnError\n");
+                    } else {
+                        push(@implContent, "        IMPL->commitChange();\n");
+                    }
                 } elsif ($svgListPropertyType) {
                     $getterContentHead = "$getterExpressionPrefix";
                     push(@implContent, "    IMPL->$coreSetterName($arg);\n");
@@ -1503,6 +1512,35 @@ sub GenerateImplementation
 
             push(@parameterNames, "ec") if $raisesExceptions and !($svgMatrixRotateFromVector || $svgMatrixInverse);
             push(@parameterNames, "0 /* FIXME */") if $svgLengthConvertToSpecifiedUnits; 
+
+            # Handle arguments that are 'SVGProperty' based (SVGAngle/SVGLength). We need to convert from SVGPropertyTearOff<Type>* to Type,
+            # to be able to call the desired WebCore function. If the conversion fails, we can't extract Type and need to raise an exception.
+            my $currentParameter = -1;
+            foreach my $param (@{$function->parameters}) {
+                $currentParameter++;
+
+                my $paramName = $param->name;
+                my $idlType = $codeGenerator->StripModule($param->type);
+                next if not $codeGenerator->IsSVGTypeNeedingTearOff($idlType) or $implClassName =~ /List$/;
+
+                my $implGetter = GetObjCTypeGetter($paramName, $idlType);
+                my $idlTypeWithNamespace = ($idlType eq "float") ? "$idlType" : "WebCore::$idlType";
+
+                push(@functionContent, "    WebCore::SVGPropertyTearOff<$idlTypeWithNamespace>* ${paramName}Core = $implGetter;\n");
+                push(@functionContent, "    if (!${paramName}Core) {\n");
+                push(@functionContent, "        WebCore::ExceptionCode ec = WebCore::TYPE_MISMATCH_ERR;\n");
+                push(@functionContent, "        $exceptionRaiseOnError\n");
+                if ($returnType eq "void") { 
+                    push(@functionContent, "        return;\n");
+                } else {
+                    push(@functionContent, "        return nil;\n");
+                }
+                push(@functionContent, "    }\n");
+
+                # Replace the paramter core() getter, by the cached variable.
+                splice(@parameterNames, $currentParameter, 1, "${paramName}Core->propertyReference()");
+            }
+
             my $content = $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterNames) . ")"; 
 
             if ($svgPropertyType) {
@@ -1554,9 +1592,8 @@ sub GenerateImplementation
                 $content = "foo";
             } else {
                 if (ConversionNeeded($function->signature->type)) {
-                    my $svgLiveProperty = $function->signature->extendedAttributes->{"SVGLiveProperty"};
-                    if ($svgLiveProperty) {
-                        $content = "kit(WebCore::SVGPropertyTearOff<WebCore::" . $function->signature->type . ">::create($content).get())";
+                    if ($codeGenerator->IsSVGTypeNeedingTearOff($function->signature->type) and not $implClassName =~ /List$/) {
+                        $content = "kit(WTF::getPtr(WebCore::SVGPropertyTearOff<WebCore::" . $function->signature->type . ">::create($content)))";
                     } elsif ($codeGenerator->IsPodType($function->signature->type)) {
                         $content = "kit($content)";
                     } else {
index 751e350..d45058b 100644 (file)
@@ -6,6 +6,7 @@
 # Copyright (C) 2006 Apple Computer, Inc.
 # Copyright (C) 2007, 2008, 2009 Google Inc.
 # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
+# Copyright (C) Research In Motion Limited 2010. All rights reserved.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -87,6 +88,7 @@ sub finish
 }
 
 # Workaround for V8 bindings difference where RGBColor is not a POD type.
+# FIXME: This method will go away once all SVG animated properties are converted to the new scheme.
 sub IsPodType
 {
     my $type = shift;
@@ -936,6 +938,28 @@ sub GenerateNormalAttrSetter
     push(@implContentDecls, "static void ${attrName}AttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n");
     push(@implContentDecls, "    INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
 
+    # For functions with "StrictTypeChecking", if an input parameter's type does not match the signature,
+    # a TypeError is thrown instead of casting to null.
+    if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) {
+        my $argType = GetTypeFromSignature($attribute->signature);
+        if ($codeGenerator->IsStringType($argType)) {
+            push(@implContentDecls, "    if (!isUndefinedOrNull(value) && !value->IsString() && !value->IsObject()) {\n");
+            push(@implContentDecls, "        V8Proxy::throwTypeError();\n");
+            push(@implContentDecls, "        return;\n");
+            push(@implContentDecls, "    }\n");
+        } elsif ($codeGenerator->IsNumericType($argType)) {
+            push(@implContentDecls, "    if (!isUndefinedOrNull(value) && !value->IsNumber()) {\n");
+            push(@implContentDecls, "        V8Proxy::throwTypeError();\n");
+            push(@implContentDecls, "        return;\n");
+            push(@implContentDecls, "    }\n");
+        } elsif (IsWrapperType($argType)) {
+            push(@implContentDecls, "    if (!isUndefinedOrNull(value) && !V8${argType}::HasInstance(value)) {\n");
+            push(@implContentDecls, "        V8Proxy::throwTypeError();\n");
+            push(@implContentDecls, "        return;\n");
+            push(@implContentDecls, "    }\n");
+        }
+    }
+
     my $isPodType = IsPodType($implClassName);
     my $svgPropertyType = $dataNode->extendedAttributes->{"SVGProperty"};
     my $svgListPropertyType = $dataNode->extendedAttributes->{"SVGListProperty"};
@@ -1050,7 +1074,12 @@ END
     if ($isPodType) {
         push(@implContentDecls, "    wrapper->commitChange(*imp, V8Proxy::svgContext(wrapper));\n");
     } elsif ($svgPropertyType) {
-        push(@implContentDecls, "    wrapper->commitChange();\n");
+        if ($useExceptions) {
+            push(@implContentDecls, "    if (!ec)\n");
+            push(@implContentDecls, "        wrapper->commitChange();\n");
+        } else {
+            push(@implContentDecls, "    wrapper->commitChange();\n");
+        }
     } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
         $implIncludes{"SVGElement.h"} = 1;
 
@@ -1377,13 +1406,18 @@ END
             if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
                 my $argValue = "args[$paramIndex]";
                 my $argType = GetTypeFromSignature($parameter);
-                if (IsWrapperType($argType)) {
-                    push(@implContentDecls, "    if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue)) {\n");
+                if ($codeGenerator->IsStringType($argType)) {
+                    push(@implContentDecls, "    if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !${argValue}->IsString() && !${argValue}->IsObject()) {\n");
                     push(@implContentDecls, "        V8Proxy::throwTypeError();\n");
                     push(@implContentDecls, "        return notHandledByInterceptor();\n");
                     push(@implContentDecls, "    }\n");
-                } elsif ($codeGenerator->IsStringType($argType)) {
-                    push(@implContentDecls, "    if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !${argValue}->IsString() && !${argValue}->IsObject()) {\n");
+                } elsif ($codeGenerator->IsNumericType($argType)) {
+                    push(@implContentDecls, "    if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !${argValue}->IsNumber()) {\n");
+                    push(@implContentDecls, "        V8Proxy::throwTypeError();\n");
+                    push(@implContentDecls, "        return notHandledByInterceptor();\n");
+                    push(@implContentDecls, "    }\n");
+                } elsif (IsWrapperType($argType)) {
+                    push(@implContentDecls, "    if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue)) {\n");
                     push(@implContentDecls, "        V8Proxy::throwTypeError();\n");
                     push(@implContentDecls, "        return notHandledByInterceptor();\n");
                     push(@implContentDecls, "    }\n");
@@ -2711,6 +2745,12 @@ sub GenerateFunctionCallString()
 
         if ($parameter->type eq "NodeFilter" || $parameter->type eq "XPathNSResolver") {
             $functionString .= "$paramName.get()";
+        } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($parameter->type) and not $implClassName =~ /List$/) {
+            $functionString .= "$paramName->propertyReference()";
+            $result .= $indent . "if (!$paramName) {\n";
+            $result .= $indent . "    V8Proxy::setDOMException(WebCore::TYPE_MISMATCH_ERR);\n";
+            $result .= $indent . "    return v8::Handle<v8::Value>();\n";
+            $result .= $indent . "}\n";
         } else {
             $functionString .= $paramName;
         }
@@ -2775,12 +2815,11 @@ sub GenerateFunctionCallString()
         $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n";
         $return = "wrapper";
     }
-    
-    my $svgLivePropertyType = $function->signature->extendedAttributes->{"SVGLiveProperty"};
-    if ($svgLivePropertyType) {
+
+    if ($codeGenerator->IsSVGTypeNeedingTearOff($returnType) and not $implClassName =~ /List$/) {
         $implIncludes{"V8$returnType.h"} = 1;
         $implIncludes{"SVGPropertyTearOff.h"} = 1;
-        return $indent . "return toV8(SVGPropertyTearOff<$returnType>::create($return).get());\n";
+        return $indent . "return toV8(WTF::getPtr(SVGPropertyTearOff<$returnType>::create($return)));\n";
     }
 
     my $generatedSVGContextRetrieval = 0;
@@ -2902,7 +2941,7 @@ sub GetNativeType
     return "FloatPoint" if $type eq "SVGPoint";
     return "AffineTransform" if $type eq "SVGMatrix";
     return "SVGTransform" if $type eq "SVGTransform";
-    return "SVGAngle" if $type eq "SVGAngle";
+    return "RefPtr<SVGPropertyTearOff<SVGAngle> >" if $type eq "SVGAngle";
     return "RefPtr<SVGPropertyTearOff<SVGLength> >" if $type eq "SVGLength";
     return "SVGListPropertyTearOff<SVGLengthList>*" if $type eq "SVGLengthList";
     return "float" if $type eq "SVGNumber";
@@ -2956,7 +2995,6 @@ sub BasicTypeCanFailConversion
     my $signature = shift;
     my $type = GetTypeFromSignature($signature);
 
-    return 1 if $type eq "SVGAngle";
     return 1 if $type eq "SVGMatrix";
     return 1 if $type eq "SVGPoint";
     return 1 if $type eq "SVGPreserveAspectRatio";
@@ -3280,6 +3318,7 @@ sub ReturnNativeToJSValue
     return "return toV8($value)";
 }
 
+# FIXME: This method will go away once all SVG animated properties are converted to the new scheme.
 sub GenerateSVGStaticPodTypeWrapper {
     my $type = shift;
     my $value = shift;
@@ -3334,18 +3373,25 @@ sub WriteData
     }
 }
 
+# FIXME: This method will go away once all SVG animated properties are converted to the new scheme.
 sub IsSVGTypeNeedingContextParameter
 {
     my $implClassName = shift;
 
     return 0 if $codeGenerator->IsSVGNewStyleAnimatedType($implClassName);
     if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
-        return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/ or $implClassName =~ /SVGLength/ or $implClassName =~/SVGLengthList/;
+        return 1 unless $implClassName =~ /SVGAngle/
+                     or $implClassName =~ /SVGPaint/
+                     or $implClassName =~ /SVGColor/
+                     or $implClassName =~ /SVGDocument/
+                     or $implClassName =~ /SVGLength/
+                     or $implClassName =~ /SVGLengthList/;
     }
 
     return 0;
 }
 
+# FIXME: This method will go away once all SVG animated properties are converted to the new scheme.
 sub GenerateSVGContextAssignment
 {
     my $srcType = shift;
@@ -3358,6 +3404,7 @@ sub GenerateSVGContextAssignment
     return $result;
 }
 
+# FIXME: This method will go away once all SVG animated properties are converted to the new scheme.
 sub GenerateSVGContextRetrieval
 {
     my $srcType = shift;
index 7d8d017..63a90cf 100644 (file)
@@ -24,7 +24,6 @@
 #if ENABLE(SVG)
 #include "FloatRect.h"
 #include "PlatformString.h"
-#include "SVGAngle.h"
 #include "SVGNumberList.h"
 #include "SVGPreserveAspectRatio.h"
 #include "SVGTransformList.h"
@@ -34,18 +33,6 @@ namespace WebCore {
 template<typename Type>
 struct DeprecatedSVGAnimatedPropertyTraits : public Noncopyable { };
 
-// SVGAnimatedAngle
-template<>
-struct DeprecatedSVGAnimatedPropertyTraits<SVGAngle> : public Noncopyable {
-    typedef const SVGAngle& PassType;
-    typedef SVGAngle ReturnType;
-    typedef SVGAngle StoredType;
-
-    static ReturnType null() { return SVGAngle(); }
-    static ReturnType toReturnType(const StoredType& type) { return type; }
-    static String toString(PassType type) { return type.valueAsString(); }
-};
-
 // SVGAnimatedBoolean
 template<>
 struct DeprecatedSVGAnimatedPropertyTraits<bool> : public Noncopyable {
index 4f33999..351ff5a 100644 (file)
@@ -28,7 +28,6 @@
 
 namespace WebCore {
    
-    class SVGAngle;
     class SVGElement;
     class SVGNumberList;
     class SVGPreserveAspectRatio;
@@ -155,7 +154,6 @@ namespace WebCore {
     }
 
     // Common type definitions, to ease IDL generation.
-    typedef DeprecatedSVGAnimatedTemplate<SVGAngle> SVGAnimatedAngle;
     typedef DeprecatedSVGAnimatedTemplate<bool> SVGAnimatedBoolean;
     typedef DeprecatedSVGAnimatedTemplate<int> SVGAnimatedEnumeration;
     typedef DeprecatedSVGAnimatedTemplate<long> SVGAnimatedInteger;
index 6702904..6475064 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  */
 
 #include "config.h"
-#include "SVGAngle.h"
 
 #if ENABLE(SVG)
+#include "SVGAngle.h"
 
+#include "SVGParserUtilities.h"
+#include <wtf/text/StringConcatenate.h>
 #include <wtf/MathExtras.h>
 
 namespace WebCore {
 
 SVGAngle::SVGAngle()
-    : m_unitType(SVG_ANGLETYPE_UNKNOWN)
-    , m_value(0)
+    : m_unitType(SVG_ANGLETYPE_UNSPECIFIED)
     , m_valueInSpecifiedUnits(0)
 {
 }
 
+float SVGAngle::value() const
+{
+    switch (m_unitType) {
+    case SVG_ANGLETYPE_GRAD:
+        return grad2deg(m_valueInSpecifiedUnits);
+    case SVG_ANGLETYPE_RAD:
+        return rad2deg(m_valueInSpecifiedUnits);
+    case SVG_ANGLETYPE_UNSPECIFIED:
+    case SVG_ANGLETYPE_UNKNOWN:
+    case SVG_ANGLETYPE_DEG:
+        return m_valueInSpecifiedUnits;
+    }
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
 void SVGAngle::setValue(float value)
 {
-    m_value = value;
+    switch (m_unitType) {
+    case SVG_ANGLETYPE_GRAD:
+        m_valueInSpecifiedUnits = deg2grad(value);
+        break;
+    case SVG_ANGLETYPE_RAD:
+        m_valueInSpecifiedUnits = deg2rad(value);
+        break;
+    case SVG_ANGLETYPE_UNSPECIFIED:
+    case SVG_ANGLETYPE_UNKNOWN:
+    case SVG_ANGLETYPE_DEG:
+        m_valueInSpecifiedUnits = value;
+        break;
+    }
+}
+
+inline SVGAngle::SVGAngleType stringToAngleType(const UChar*& ptr, const UChar* end)
+{
+    // If there's no unit given, the angle type is unspecified.
+    if (ptr == end)
+        return SVGAngle::SVG_ANGLETYPE_UNSPECIFIED;
+
+    const UChar firstChar = *ptr;
+    
+    // If the unit contains only one character, the angle type is unknown.
+    ++ptr;
+    if (ptr == end)
+        return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
+
+    const UChar secondChar = *ptr;
+    // If the unit contains only two characters, the angle type is unknown.
+    ++ptr;
+    if (ptr == end)
+        return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
+
+    const UChar thirdChar = *ptr;
+    if (firstChar == 'd' && secondChar == 'e' && thirdChar == 'g')
+        return SVGAngle::SVG_ANGLETYPE_DEG;
+    if (firstChar == 'r' && secondChar == 'a' && thirdChar == 'd')
+        return SVGAngle::SVG_ANGLETYPE_RAD;
+
+    // If the unit contains three characters, but is not deg or rad, then it's unknown.
+    ++ptr;
+    if (ptr == end)
+        return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
+
+    const UChar fourthChar = *ptr;
+
+    if (firstChar == 'g' && secondChar == 'r' && thirdChar == 'a' && fourthChar == 'd')
+        return SVGAngle::SVG_ANGLETYPE_GRAD;
+
+    return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
 }
 
-// calc m_value
-void SVGAngle::calculate()
+String SVGAngle::valueAsString() const
 {
-    if (m_unitType == SVG_ANGLETYPE_GRAD)
-        m_value = grad2deg(m_valueInSpecifiedUnits);
-    else if (m_unitType == SVG_ANGLETYPE_RAD)
-        m_value = rad2deg(m_valueInSpecifiedUnits);
-    else if (m_unitType == SVG_ANGLETYPE_UNSPECIFIED || m_unitType == SVG_ANGLETYPE_DEG)
-        m_value = m_valueInSpecifiedUnits;
+    switch (m_unitType) {
+    case SVG_ANGLETYPE_DEG:
+        return makeString(String::number(m_valueInSpecifiedUnits), "deg");
+    case SVG_ANGLETYPE_RAD:
+        return makeString(String::number(m_valueInSpecifiedUnits), "rad");
+    case SVG_ANGLETYPE_GRAD:
+        return makeString(String::number(m_valueInSpecifiedUnits), "grad");
+    case SVG_ANGLETYPE_UNSPECIFIED:
+    case SVG_ANGLETYPE_UNKNOWN:
+        return makeString(String::number(m_valueInSpecifiedUnits));
+    }
+
+    ASSERT_NOT_REACHED();
+    return String();
 }
 
-void SVGAngle::setValueInSpecifiedUnits(float valueInSpecifiedUnits)
+void SVGAngle::setValueAsString(const String& value, ExceptionCode& ec)
 {
+    if (value.isEmpty()) {
+        m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
+        return;
+    }
+
+    float valueInSpecifiedUnits = 0;
+    const UChar* ptr = value.characters();
+    const UChar* end = ptr + value.length();
+
+    if (!parseNumber(ptr, end, valueInSpecifiedUnits, false)) {
+        ec = SYNTAX_ERR;
+        return;
+    }
+
+    SVGAngleType unitType = stringToAngleType(ptr, end);
+    if (unitType == SVG_ANGLETYPE_UNKNOWN) {
+        ec = SYNTAX_ERR;
+        return;
+    }
+
+    m_unitType = unitType;
     m_valueInSpecifiedUnits = valueInSpecifiedUnits;
-    calculate();
 }
 
-void SVGAngle::setValueAsString(const String& s)
+void SVGAngle::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionCode& ec)
 {
-    m_valueAsString = s;
-
-    bool bOK;
-    m_valueInSpecifiedUnits = m_valueAsString.toFloat(&bOK);
-    m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
-
-    if (!bOK) {
-        if (m_valueAsString.endsWith("deg"))
-            m_unitType = SVG_ANGLETYPE_DEG;
-        else if (m_valueAsString.endsWith("grad"))
-            m_unitType = SVG_ANGLETYPE_GRAD;
-        else if (m_valueAsString.endsWith("rad"))
-            m_unitType = SVG_ANGLETYPE_RAD;
+    if (unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) {
+        ec = NOT_SUPPORTED_ERR;
+        return;
     }
-    
-    calculate();
+
+    if (unitType != m_unitType)
+        m_unitType = static_cast<SVGAngleType>(unitType);
+
+    m_valueInSpecifiedUnits = valueInSpecifiedUnits;
 }
 
-String SVGAngle::valueAsString() const
+void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionCode& ec)
 {
-    m_valueAsString = String::number(m_valueInSpecifiedUnits);
+    if (unitType == SVG_ANGLETYPE_UNKNOWN || m_unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) {
+        ec = NOT_SUPPORTED_ERR;
+        return;
+    }
+
+    if (unitType == m_unitType)
+        return;
 
     switch (m_unitType) {
+    case SVG_ANGLETYPE_RAD:
+        switch (unitType) {
+        case SVG_ANGLETYPE_GRAD:
+            m_valueInSpecifiedUnits = rad2grad(m_valueInSpecifiedUnits);
+            break;
+        case SVG_ANGLETYPE_UNSPECIFIED:
+        case SVG_ANGLETYPE_DEG:
+            m_valueInSpecifiedUnits = rad2deg(m_valueInSpecifiedUnits);
+            break;
+        case SVG_ANGLETYPE_RAD:
+        case SVG_ANGLETYPE_UNKNOWN:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+        break;
+    case SVG_ANGLETYPE_GRAD:
+        switch (unitType) {
+        case SVG_ANGLETYPE_RAD:
+            m_valueInSpecifiedUnits = grad2rad(m_valueInSpecifiedUnits);
+            break;
         case SVG_ANGLETYPE_UNSPECIFIED:
         case SVG_ANGLETYPE_DEG:
-            m_valueAsString += "deg";
+            m_valueInSpecifiedUnits = grad2deg(m_valueInSpecifiedUnits);
+            break;
+        case SVG_ANGLETYPE_GRAD:
+        case SVG_ANGLETYPE_UNKNOWN:
+            ASSERT_NOT_REACHED();
             break;
+        }
+        break;
+    case SVG_ANGLETYPE_UNSPECIFIED:
+        // Spec: For angles, a unitless value is treated the same as if degrees were specified.
+    case SVG_ANGLETYPE_DEG:
+        switch (unitType) {
         case SVG_ANGLETYPE_RAD:
-            m_valueAsString += "rad";
+            m_valueInSpecifiedUnits = deg2rad(m_valueInSpecifiedUnits);
             break;
         case SVG_ANGLETYPE_GRAD:
-            m_valueAsString += "grad";
+            m_valueInSpecifiedUnits = deg2grad(m_valueInSpecifiedUnits);
             break;
+        case SVG_ANGLETYPE_UNSPECIFIED:
+            break;
+        case SVG_ANGLETYPE_DEG:
         case SVG_ANGLETYPE_UNKNOWN:
+            ASSERT_NOT_REACHED();
             break;
+        }
+        break;
+    case SVG_ANGLETYPE_UNKNOWN:
+        ASSERT_NOT_REACHED();
+        break;
     }
-    
-    return m_valueAsString;
-}
-
-void SVGAngle::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits)
-{
-    m_unitType = (SVGAngleType)unitType;
-    m_valueInSpecifiedUnits = valueInSpecifiedUnits;
-    calculate();
-}
-
-void SVGAngle::convertToSpecifiedUnits(unsigned short unitType)
-{
-    if (m_unitType == unitType)
-        return;
 
-    if (m_unitType == SVG_ANGLETYPE_DEG && unitType == SVG_ANGLETYPE_RAD)
-        m_valueInSpecifiedUnits = deg2rad(m_valueInSpecifiedUnits);
-    else if (m_unitType == SVG_ANGLETYPE_GRAD && unitType == SVG_ANGLETYPE_RAD)
-        m_valueInSpecifiedUnits = grad2rad(m_valueInSpecifiedUnits);
-    else if (m_unitType == SVG_ANGLETYPE_DEG && unitType == SVG_ANGLETYPE_GRAD)
-        m_valueInSpecifiedUnits = deg2grad(m_valueInSpecifiedUnits);
-    else if (m_unitType == SVG_ANGLETYPE_RAD && unitType == SVG_ANGLETYPE_GRAD)
-        m_valueInSpecifiedUnits = rad2grad(m_valueInSpecifiedUnits);
-    else if (m_unitType == SVG_ANGLETYPE_RAD && unitType == SVG_ANGLETYPE_DEG)
-        m_valueInSpecifiedUnits = rad2deg(m_valueInSpecifiedUnits);
-    else if (m_unitType == SVG_ANGLETYPE_GRAD && unitType == SVG_ANGLETYPE_DEG)
-        m_valueInSpecifiedUnits = grad2deg(m_valueInSpecifiedUnits);
-
-    m_unitType = (SVGAngleType)unitType;
+    m_unitType = static_cast<SVGAngleType>(unitType);
 }
 
 }
index de5c3ce..4afaa4b 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #define SVGAngle_h
 
 #if ENABLE(SVG)
-#include "PlatformString.h"
+#include "ExceptionCode.h"
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
-    class SVGAngle {
-    public:
-        SVGAngle();
+class SVGAngle {
+public:
+    SVGAngle();
 
-        enum SVGAngleType {
-            SVG_ANGLETYPE_UNKNOWN           = 0,
-            SVG_ANGLETYPE_UNSPECIFIED       = 1,
-            SVG_ANGLETYPE_DEG               = 2,
-            SVG_ANGLETYPE_RAD               = 3,
-            SVG_ANGLETYPE_GRAD              = 4
-        };
-
-        SVGAngleType unitType() const { return m_unitType; }
+    enum SVGAngleType {
+        SVG_ANGLETYPE_UNKNOWN = 0,
+        SVG_ANGLETYPE_UNSPECIFIED = 1,
+        SVG_ANGLETYPE_DEG = 2,
+        SVG_ANGLETYPE_RAD = 3,
+        SVG_ANGLETYPE_GRAD = 4
+    };
 
-        void setValue(float);
-        float value() const { return m_value; }
+    SVGAngleType unitType() const { return m_unitType; }
 
-        void setValueInSpecifiedUnits(float valueInSpecifiedUnits);
-        float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; }
+    void setValue(float);
+    float value() const;
 
-        void setValueAsString(const String&);
-        String valueAsString() const;
+    void setValueInSpecifiedUnits(float valueInSpecifiedUnits) { m_valueInSpecifiedUnits = valueInSpecifiedUnits; }
+    float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; }
 
-        void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits);
-        void convertToSpecifiedUnits(unsigned short unitType);
+    void setValueAsString(const String&, ExceptionCode&);
+    String valueAsString() const;
 
-    private:
-        SVGAngleType m_unitType;
-        float m_value;
-        float m_valueInSpecifiedUnits;
-        mutable String m_valueAsString;
+    void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionCode&);
+    void convertToSpecifiedUnits(unsigned short unitType, ExceptionCode&);
 
-        void calculate();
-    };
+private:
+    SVGAngleType m_unitType;
+    float m_valueInSpecifiedUnits;
+};
 
 } // namespace WebCore
 
index cb5148c..69959ad 100644 (file)
 
 module svg {
 
-    interface [Conditional=SVG, PODType=SVGAngle] SVGAngle { 
+    interface [Conditional=SVG, SVGProperty=SVGAngle] SVGAngle { 
         // Angle Unit Types
-        const unsigned short SVG_ANGLETYPE_UNKNOWN     = 0;
+        const unsigned short SVG_ANGLETYPE_UNKNOWN = 0;
         const unsigned short SVG_ANGLETYPE_UNSPECIFIED = 1;
-        const unsigned short SVG_ANGLETYPE_DEG         = 2;
-        const unsigned short SVG_ANGLETYPE_RAD         = 3;
-        const unsigned short SVG_ANGLETYPE_GRAD        = 4;
-        
+        const unsigned short SVG_ANGLETYPE_DEG = 2;
+        const unsigned short SVG_ANGLETYPE_RAD = 3;
+        const unsigned short SVG_ANGLETYPE_GRAD = 4;
+
         readonly attribute unsigned short unitType;
-                 attribute float          value;
-                 attribute float          valueInSpecifiedUnits;
-                 attribute [ConvertNullToNullString] DOMString      valueAsString;
-        
-        void newValueSpecifiedUnits(in unsigned short unitType, 
-                                    in float valueInSpecifiedUnits);
-        void convertToSpecifiedUnits(in unsigned short unitType);
+        attribute [StrictTypeChecking] float value;
+        attribute [StrictTypeChecking] float valueInSpecifiedUnits;
+
+        attribute [ConvertNullToNullString] DOMString valueAsString
+            setter raises(DOMException);
+
+        void newValueSpecifiedUnits(in unsigned short unitType, in float valueInSpecifiedUnits)
+            raises(DOMException);
+
+        void convertToSpecifiedUnits(in unsigned short unitType)
+            raises(DOMException);
     };
 
 }
diff --git a/WebCore/svg/SVGAnimatedAngle.h b/WebCore/svg/SVGAnimatedAngle.h
new file mode 100644 (file)
index 0000000..bda7a36
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SVGAnimatedAngle_h
+#define SVGAnimatedAngle_h
+
+#if ENABLE(SVG)
+#include "SVGAngle.h"
+#include "SVGAnimatedPropertyTearOff.h"
+
+namespace WebCore {
+
+typedef SVGAnimatedPropertyTearOff<SVGAngle> SVGAnimatedAngle;
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif
index 76d4b71..48159fd 100644 (file)
@@ -25,7 +25,7 @@
 
 module svg {
 
-    interface [Conditional=SVG] SVGAnimatedAngle {
+    interface [Conditional=SVG, SVGAnimatedProperty] SVGAnimatedAngle {
         readonly attribute SVGAngle baseVal;
         readonly attribute SVGAngle animVal;
     };
index 4ff420d..6ec0500 100644 (file)
@@ -81,7 +81,8 @@ void SVGMarkerElement::parseMappedAttribute(Attribute* attr)
         if (attr->value() == "auto")
             setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO);
         else {
-            angle.setValueAsString(attr->value());
+            ExceptionCode ec = 0;
+            angle.setValueAsString(attr->value(), ec);
             setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE);
         }
 
index 8b21ff5..bc70524 100644 (file)
@@ -82,7 +82,7 @@ private:
     DECLARE_ANIMATED_PROPERTY_NEW(SVGMarkerElement, SVGNames::markerHeightAttr, SVGLength, MarkerHeight, markerHeight)
     DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::markerUnitsAttr, int, MarkerUnits, markerUnits)
     DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGMarkerElement, SVGNames::orientAttr, SVGOrientTypeAttrIdentifier, int, OrientType, orientType)
-    DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGMarkerElement, SVGNames::orientAttr, SVGOrientAngleAttrIdentifier, SVGAngle, OrientAngle, orientAngle)
+    DECLARE_ANIMATED_PROPERTY_NEW_MULTIPLE_WRAPPERS(SVGMarkerElement, SVGNames::orientAttr, SVGOrientAngleAttrIdentifier, SVGAngle, OrientAngle, orientAngle)
 
     // SVGExternalResourcesRequired
     DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired)
index f57ff40..32e9620 100644 (file)
@@ -23,8 +23,7 @@
 module svg {
 
     interface [Conditional=SVG, PODType=float] SVGNumber {
-                 attribute float value
-                     setter raises(DOMException);
+        attribute float value;
     };
 
 }
index e93baf1..46ca671 100644 (file)
 module svg {
 
     interface [Conditional=SVG, PODType=FloatPoint] SVGPoint {
-                 attribute float x
-                     setter raises(DOMException);
-                 attribute float y
-                     setter raises(DOMException);
+        attribute float x;
+        attribute float y;
 
         SVGPoint matrixTransform(in SVGMatrix matrix);
     };
index 2f8799c..a4ece66 100644 (file)
 module svg {
 
     interface [Conditional=SVG, PODType=FloatRect] SVGRect {
-                 attribute float x
-                     setter raises(DOMException);
-                 attribute float y
-                     setter raises(DOMException);
-                 attribute float width
-                     setter raises(DOMException);
-                 attribute float height
-                     setter raises(DOMException);
+        attribute float x;
+        attribute float y;
+        attribute float width;
+        attribute float height;
     };
 
 }
index fc920bf..bcf9236 100644 (file)
@@ -73,7 +73,7 @@ module svg {
         void deselectAll();
 
         SVGNumber createSVGNumber();
-        [SVGLiveProperty] SVGLength createSVGLength();
+        SVGLength createSVGLength();
         SVGAngle createSVGAngle();
         SVGPoint createSVGPoint();
         SVGMatrix createSVGMatrix();