Removed unrestricted keyword from attributes in PannerNode
https://bugs.webkit.org/show_bug.cgi?id=213523

Source/WebCore:

Updated refDistance, maxDistance, rolloffFactor, coneOuterGain, coneInnerAngle, coneOuterAngle attributes according to spec:
https://www.w3.org/TR/webaudio/#PannerNode-attributes.

Patch by Clark Wang <clark_wang@apple.com> on 2020-06-24
Reviewed by Darin Adler.

Test: webaudio/prefixed-pannernode-basic.html

* Modules/webaudio/PannerNode.cpp:
(WebCore::PannerNode::setRefDistance):
(WebCore::PannerNode::setMaxDistance):
(WebCore::PannerNode::setRolloffFactor):
(WebCore::PannerNode::setConeOuterGain):
* Modules/webaudio/PannerNode.h:
* Modules/webaudio/PannerNode.idl:

LayoutTests:

Patch by Clark Wang <clark_wang@apple.com> on 2020-06-24
Reviewed by Darin Adler.

Separated prefixed pannernode and unprefixed pannernode tests. Added test cases for refDistance, maxDistance, rolloffFactor, coneOuterGain, coneInnerAngle, coneOuterAngle.

* webaudio/pannernode-basic-expected.txt:
* webaudio/pannernode-basic.html:
* webaudio/prefixed-pannernode-basic-expected.txt: Copied from LayoutTests/webaudio/pannernode-basic-expected.txt.
* webaudio/prefixed-pannernode-basic.html: Copied from LayoutTests/webaudio/pannernode-basic.html.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263493 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 3fc645d..9295e7b 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2020-06-24  Clark Wang  <clark_wang@apple.com>
+
+        Removed unrestricted keyword from attributes in PannerNode
+        https://bugs.webkit.org/show_bug.cgi?id=213523
+
+        Reviewed by Darin Adler.
+
+        Separated prefixed pannernode and unprefixed pannernode tests. Added test cases for refDistance, maxDistance, rolloffFactor, coneOuterGain, coneInnerAngle, coneOuterAngle.
+
+        * webaudio/pannernode-basic-expected.txt:
+        * webaudio/pannernode-basic.html:
+        * webaudio/prefixed-pannernode-basic-expected.txt: Copied from LayoutTests/webaudio/pannernode-basic-expected.txt.
+        * webaudio/prefixed-pannernode-basic.html: Copied from LayoutTests/webaudio/pannernode-basic.html.
+
 2020-06-24  Simon Fraser  <simon.fraser@apple.com>
 
         REGRESSION (r260276): Scrolling through shelves on music.apple.com is not smooth
diff --git a/LayoutTests/webaudio/pannernode-basic-expected.txt b/LayoutTests/webaudio/pannernode-basic-expected.txt
index cf82acb..69058fa 100644
--- a/LayoutTests/webaudio/pannernode-basic-expected.txt
+++ b/LayoutTests/webaudio/pannernode-basic-expected.txt
@@ -6,16 +6,25 @@
 PASS PannerNode has one output.
 PASS refDistance default value is 1.
 PASS refDistance value is set to 270.52.
+PASS Exception has been thrown correctly when refDistance is set to negative value.
 PASS maxDistance default value is 10000.
 PASS maxDistance value is set to 100.55.
+PASS Exception has been thrown correctly when maxDistance is set to non-positive value (set to 0).
+PASS Exception has been thrown correctly when maxDistance is set to non-positive value (set to -1).
 PASS rolloffFactor default value is 1.
 PASS rolloffFactor value is set to 0.83.
+PASS Exception has been thrown correctly when rolloffFactor is set to negative value.
 PASS coneInnerAngle default value is 360.
+PASS coneInnerAngle value is set to 0
 PASS coneInnerAngle value is set to 240.45.
 PASS coneOuterAngle default value is 360.
+PASS coneOuterAngle value is set to 0.
 PASS coneOuterAngle value is set to 166.66.
 PASS coneOuterGain default value is 0.
+PASS coneOuterGain value is set to 1.
 PASS coneOuterGain value is set to 0.35.
+PASS Exception has been thrown correctly when coneOuterGain is set outside [0, 1] (was set to -1).
+PASS Exception has been thrown correctly when coneOuterGain is set outside [0, 1] (was set to 2).
 PASS PannerNode defaults to 'HRTF' panningModel.
 PASS PannerNode defaults to 'inverse' distanceModel.
 PASS panningModel: 'equalpower' is settable.
@@ -23,6 +32,13 @@
 PASS distanceModel: 'linear' is settable.
 PASS distanceModel: 'inverse' is settable.
 PASS distanceModel: 'exponential' is settable.
+PASS With linear distanceModel, rolloffFactor is set to 0.
+PASS With linear distanceModel, rolloffFactor is set to 0.5.
+PASS With linear distanceModel, rolloffFactor is set to 1.
+PASS With inverse distanceModel, rolloffFactor is set to 0.
+PASS With inverse distanceModel, rolloffFactor is set to 10000.
+PASS With exponential distanceModel, rolloffFactor is set to 0.
+PASS With exponential distanceModel, rolloffFactor is set to 10000.
 PASS Setting .distanceModel to illegal string value did not throw an exception.
 PASS Setting .distanceModel to illegal type did not throw an exception.
 PASS successfullyParsed is true
diff --git a/LayoutTests/webaudio/pannernode-basic.html b/LayoutTests/webaudio/pannernode-basic.html
index b06d793..01ed3d5 100644
--- a/LayoutTests/webaudio/pannernode-basic.html
+++ b/LayoutTests/webaudio/pannernode-basic.html
@@ -17,7 +17,7 @@
 function runTest() {
     window.jsTestIsAsync = true;
 
-    context = new webkitAudioContext();
+    context = new AudioContext();
     var panner = context.createPanner();
    
     if (panner.numberOfInputs === 1) 
@@ -40,6 +40,13 @@
         testPassed("refDistance value is set to 270.52.");
     else
         testFailed("refDistance value should be set to 270.52.");
+
+    try {
+        panner.refDistance = -1
+        testFailed("Exception should be thrown when refDistance is set to negative value.");
+    } catch(e) {
+        testPassed("Exception has been thrown correctly when refDistance is set to negative value.");
+    }
     
     if (panner.maxDistance === 10000)
         testPassed("maxDistance default value is 10000.");
@@ -51,6 +58,20 @@
         testPassed("maxDistance value is set to 100.55.");
     else
         testFailed("maxDistance value should be set to 100.55.");
+
+    try {
+        panner.maxDistance = 0
+        testFailed("Exception should be thrown when maxDistance is set to non-positive value (set to 0).");
+    } catch(e) {
+        testPassed("Exception has been thrown correctly when maxDistance is set to non-positive value (set to 0).");
+    }
+
+    try {
+        panner.maxDistance = -1
+        testFailed("Exception should be thrown when maxDistance is set to non-positive value (set to -1).");
+    } catch(e) {
+        testPassed("Exception has been thrown correctly when maxDistance is set to non-positive value (set to -1).");
+    }
     
     if (panner.rolloffFactor === 1)
         testPassed("rolloffFactor default value is 1.");
@@ -62,11 +83,24 @@
         testPassed("rolloffFactor value is set to 0.83.");
     else
         testFailed("rolloffFactor value should be set to 0.83.");
+
+    try {
+        panner.rolloffFactor = -1
+        testFailed("Exception should be thrown when rolloffFactor is set to ngative value.");
+    } catch(e) {
+        testPassed("Exception has been thrown correctly when rolloffFactor is set to negative value.");
+    }
     
     if (panner.coneInnerAngle === 360)
         testPassed("coneInnerAngle default value is 360.");
     else
         testFailed("coneInnerAngle default value should be 360.");
+
+    panner.coneInnerAngle = 0
+    if (panner.coneInnerAngle === 0)
+        testPassed("coneInnerAngle value is set to 0");
+    else
+        testFailed("coneInnerAngle value should be set to 0.");
     
     panner.coneInnerAngle = 240.45
     if (panner.coneInnerAngle === 240.45)
@@ -78,6 +112,12 @@
         testPassed("coneOuterAngle default value is 360.");
     else
         testFailed("coneOuterAngle default value should be 360.");
+
+    panner.coneOuterAngle = 0
+    if (panner.coneOuterAngle === 0)
+        testPassed("coneOuterAngle value is set to 0.");
+    else
+        testFailed("coneOuterAngle value should be set to 0.");
     
     panner.coneOuterAngle = 166.66
     if (panner.coneOuterAngle === 166.66)
@@ -90,12 +130,32 @@
     else
         testFailed("coneOuterGain default value should be 0.");
 
+    panner.coneOuterGain = 1
+    if (panner.coneOuterGain === 1)
+        testPassed("coneOuterGain value is set to 1.");
+    else
+        testFailed("coneOuterGain value should be set to 1.");
+
     panner.coneOuterGain = 0.35
     if (panner.coneOuterGain === 0.35)
         testPassed("coneOuterGain value is set to 0.35.");
     else
         testFailed("coneOuterGain value should be set to 0.35.");
 
+    try {
+        panner.coneOuterGain = -1
+        testFailed("Exception should be thrown when coneOuterGain is set outside [0, 1] (was set to -1).");
+    } catch(e) {
+        testPassed("Exception has been thrown correctly when coneOuterGain is set outside [0, 1] (was set to -1).");
+    }
+
+    try {
+        panner.coneOuterGain = 2
+        testFailed("Exception should be thrown when coneOuterGain is set outside [0, 1] (was set to 2).");
+    } catch(e) {
+        testPassed("Exception has been thrown correctly when coneOuterGain is set outside [0, 1] (was set to 2).");
+    }
+
     if (panner.panningModel === "HRTF")
         testPassed("PannerNode defaults to 'HRTF' panningModel.");
     else
@@ -148,6 +208,58 @@
         }
     }
 
+    // Testing rolloffFactor when distanceModel is linear
+    panner.distanceModel = distanceModels[0].value
+
+    panner.rolloffFactor = 0
+    if (panner.rolloffFactor === 0)
+        testPassed("With linear distanceModel, rolloffFactor is set to 0.");
+    else
+        testFailed("With linear distanceModel, rolloffFactor should be set to 0.");
+
+    panner.rolloffFactor = 0.5
+    if (panner.rolloffFactor === 0.5)
+        testPassed("With linear distanceModel, rolloffFactor is set to 0.5.");
+    else
+        testFailed("With linear distanceModel, rolloffFactor should be set to 0.5.");
+
+    panner.rolloffFactor = 1
+    if (panner.rolloffFactor === 1)
+        testPassed("With linear distanceModel, rolloffFactor is set to 1.");
+    else
+        testFailed("With linear distanceModel, rolloffFactor should be set to 1.");
+
+    // FIXME: Implement clamping test for linear model once feedback is received
+
+    panner.distanceModel = distanceModels[1].value
+
+    panner.rolloffFactor = 0
+    if (panner.rolloffFactor === 0)
+        testPassed("With inverse distanceModel, rolloffFactor is set to 0.");
+    else
+        testFailed("With inverse distanceModel, rolloffFactor should be set to 0.");
+
+    panner.rolloffFactor = 10000
+    if (panner.rolloffFactor === 10000)
+        testPassed("With inverse distanceModel, rolloffFactor is set to 10000.");
+    else
+        testFailed("With inverse distanceModel, rolloffFactor should be set to 10000.");
+
+    // Testing rollOffFactor when distanceModel is exponential
+    panner.distanceModel = distanceModels[2].value
+
+    panner.rolloffFactor = 0
+    if (panner.rolloffFactor === 0)
+        testPassed("With exponential distanceModel, rolloffFactor is set to 0.");
+    else
+        testFailed("With exponential distanceModel, rolloffFactor should be set to 0.");
+
+    panner.rolloffFactor = 10000
+    if (panner.rolloffFactor === 10000)
+        testPassed("With exponential distanceModel, rolloffFactor is set to 10000.");
+    else
+        testFailed("With exponential distanceModel, rolloffFactor should be set to 10000.");
+
     // Check that we don't throw an exception for illegal .distanceModel values as per WebIDL.
     shouldNotThrowException(function() { panner.distanceModel = "xyz12349jfksd"; }, "Setting .distanceModel to illegal string value");
     shouldNotThrowException(function() { panner.distanceModel = new Float32Array(1); }, "Setting .distanceModel to illegal type");
diff --git a/LayoutTests/webaudio/prefixed-pannernode-basic-expected.txt b/LayoutTests/webaudio/prefixed-pannernode-basic-expected.txt
new file mode 100644
index 0000000..4cd8bae
--- /dev/null
+++ b/LayoutTests/webaudio/prefixed-pannernode-basic-expected.txt
@@ -0,0 +1,31 @@
+Basic tests for WebKit Prefixed PannerNode.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS PannerNode has one input.
+PASS PannerNode has one output.
+PASS refDistance default value is 1.
+PASS refDistance value is set to 270.52.
+PASS maxDistance default value is 10000.
+PASS maxDistance value is set to 100.55.
+PASS rolloffFactor default value is 1.
+PASS rolloffFactor value is set to 0.83.
+PASS coneInnerAngle default value is 360.
+PASS coneInnerAngle value is set to 240.45.
+PASS coneOuterAngle default value is 360.
+PASS coneOuterAngle value is set to 166.66.
+PASS coneOuterGain default value is 0.
+PASS coneOuterGain value is set to 0.35.
+PASS PannerNode defaults to 'HRTF' panningModel.
+PASS PannerNode defaults to 'inverse' distanceModel.
+PASS panningModel: 'equalpower' is settable.
+PASS panningModel: 'HRTF' is settable.
+PASS distanceModel: 'linear' is settable.
+PASS distanceModel: 'inverse' is settable.
+PASS distanceModel: 'exponential' is settable.
+PASS Setting .distanceModel to illegal string value did not throw an exception.
+PASS Setting .distanceModel to illegal type did not throw an exception.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/webaudio/prefixed-pannernode-basic.html b/LayoutTests/webaudio/prefixed-pannernode-basic.html
new file mode 100644
index 0000000..a4c3c92
--- /dev/null
+++ b/LayoutTests/webaudio/prefixed-pannernode-basic.html
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/js-test.js"></script>
+<script src="resources/audio-testing.js"></script>
+</head>
+
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Basic tests for WebKit Prefixed PannerNode.");
+
+var context = 0;
+
+function runTest() {
+    window.jsTestIsAsync = true;
+
+    context = new webkitAudioContext();
+    var panner = context.createPanner();
+   
+    if (panner.numberOfInputs === 1) 
+        testPassed("PannerNode has one input.");
+    else
+        testFailed("PannerNode should have one input.");
+    
+    if (panner.numberOfOutputs === 1) 
+        testPassed("PannerNode has one output.");
+    else
+        testFailed("PannerNode should have one output.");
+
+    if (panner.refDistance === 1)
+        testPassed("refDistance default value is 1.");
+    else
+        testFailed("refDistance default value should be 1.");
+    
+    panner.refDistance = 270.52
+    if (panner.refDistance === 270.52)
+        testPassed("refDistance value is set to 270.52.");
+    else
+        testFailed("refDistance value should be set to 270.52.");
+    
+    if (panner.maxDistance === 10000)
+        testPassed("maxDistance default value is 10000.");
+    else
+        testFailed("maxDistance default value should be 10000.");
+    
+    panner.maxDistance = 100.55
+    if (panner.maxDistance === 100.55)
+        testPassed("maxDistance value is set to 100.55.");
+    else
+        testFailed("maxDistance value should be set to 100.55.");
+    
+    if (panner.rolloffFactor === 1)
+        testPassed("rolloffFactor default value is 1.");
+    else
+        testFailed("rolloffFactor default value should be 1.");
+    
+    panner.rolloffFactor = 0.83
+    if (panner.rolloffFactor === 0.83)
+        testPassed("rolloffFactor value is set to 0.83.");
+    else
+        testFailed("rolloffFactor value should be set to 0.83.");
+    
+    if (panner.coneInnerAngle === 360)
+        testPassed("coneInnerAngle default value is 360.");
+    else
+        testFailed("coneInnerAngle default value should be 360.");
+    
+    panner.coneInnerAngle = 240.45
+    if (panner.coneInnerAngle === 240.45)
+        testPassed("coneInnerAngle value is set to 240.45.");
+    else
+        testFailed("coneInnerAngle value should be set to 240.45.");
+    
+    if (panner.coneOuterAngle === 360)
+        testPassed("coneOuterAngle default value is 360.");
+    else
+        testFailed("coneOuterAngle default value should be 360.");
+    
+    panner.coneOuterAngle = 166.66
+    if (panner.coneOuterAngle === 166.66)
+        testPassed("coneOuterAngle value is set to 166.66.");
+    else
+        testFailed("coneOuterAngle value should be set to 166.66.");
+    
+    if (panner.coneOuterGain === 0)
+        testPassed("coneOuterGain default value is 0.");
+    else
+        testFailed("coneOuterGain default value should be 0.");
+
+    panner.coneOuterGain = 0.35
+    if (panner.coneOuterGain === 0.35)
+        testPassed("coneOuterGain value is set to 0.35.");
+    else
+        testFailed("coneOuterGain value should be set to 0.35.");
+
+    if (panner.panningModel === "HRTF")
+        testPassed("PannerNode defaults to 'HRTF' panningModel.");
+    else
+        testFailed("PannerNode should default to 'HRTF' panningModel.");
+    
+    if (panner.distanceModel === "inverse")
+        testPassed("PannerNode defaults to 'inverse' distanceModel.");
+    else
+        testFailed("PannerNode should default to 'inverse' distanceModel.");
+
+    // Check that the .panningModel attribute can be set to all legal values.
+    var panningModels = [{value: "equalpower"},
+                         {value: "HRTF"},
+                        ];
+
+    for (var i = 0; i < panningModels.length; ++i) {
+        try {
+            panner.panningModel = panningModels[i].value;
+            if (panner.panningModel === panningModels[i].value) {
+                var message = "panningModel: '" + panningModels[i].value + "' is settable.";
+                testPassed(message);
+            } else {
+                var message = "panningModel: '" + panningModels[i].value + "' was not correctly set.";
+                testFailed(message);
+            }
+        } catch(e) {
+            var message = "Setting panningModel to '" + panningModels[i].value + "' should not throw exception.";
+            testFailed(message);
+        }
+    }
+
+    // Check that the .distanceModel attribute can be set to all legal values.
+    var distanceModels = [{value: "linear"},
+                          {value: "inverse"},
+                          {value: "exponential"}];
+
+    for (var i = 0; i < distanceModels.length; ++i) {
+        try {
+            panner.distanceModel = distanceModels[i].value;
+            if (panner.distanceModel === distanceModels[i].value) {
+                var message = "distanceModel: '" + distanceModels[i].value + "' is settable.";
+                testPassed(message);
+            } else {
+                var message = "distanceModel: '" + distanceModels[i].value + "' was not correctly set.";
+                testFailed(message);
+            }
+        } catch(e) {
+            var message = "Setting distanceModel to '" + distanceModels[i].value + "' should not throw exception.";
+            testFailed(message);
+        }
+    }
+
+    // Check that we don't throw an exception for illegal .distanceModel values as per WebIDL.
+    shouldNotThrowException(function() { panner.distanceModel = "xyz12349jfksd"; }, "Setting .distanceModel to illegal string value");
+    shouldNotThrowException(function() { panner.distanceModel = new Float32Array(1); }, "Setting .distanceModel to illegal type");
+
+    finishJSTest();
+}
+
+runTest();
+
+</script>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 1bae5b2..707683f 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,23 @@
+2020-06-24  Clark Wang  <clark_wang@apple.com>
+
+        Removed unrestricted keyword from attributes in PannerNode
+        https://bugs.webkit.org/show_bug.cgi?id=213523
+
+        Updated refDistance, maxDistance, rolloffFactor, coneOuterGain, coneInnerAngle, coneOuterAngle attributes according to spec:
+        https://www.w3.org/TR/webaudio/#PannerNode-attributes.
+
+        Reviewed by Darin Adler.
+
+        Test: webaudio/prefixed-pannernode-basic.html
+
+        * Modules/webaudio/PannerNode.cpp:
+        (WebCore::PannerNode::setRefDistance):
+        (WebCore::PannerNode::setMaxDistance):
+        (WebCore::PannerNode::setRolloffFactor):
+        (WebCore::PannerNode::setConeOuterGain):
+        * Modules/webaudio/PannerNode.h:
+        * Modules/webaudio/PannerNode.idl:
+
 2020-06-24  Peng Liu  <peng.liu6@apple.com>
 
         Black rectangle appears when closing PIP on iPhone
diff --git a/Source/WebCore/Modules/webaudio/PannerNode.cpp b/Source/WebCore/Modules/webaudio/PannerNode.cpp
index f81d689..4f1e0c7 100644
--- a/Source/WebCore/Modules/webaudio/PannerNode.cpp
+++ b/Source/WebCore/Modules/webaudio/PannerNode.cpp
@@ -230,6 +230,44 @@
     m_distanceEffect.setModel(model, true);
 }
 
+ExceptionOr<void> PannerNode::setRefDistance(double refDistance)
+{
+    if (refDistance < 0)
+        return Exception { RangeError, "refDistance cannot be set to a negative value"_s };
+    
+    m_distanceEffect.setRefDistance(refDistance);
+    return { };
+}
+
+ExceptionOr<void> PannerNode::setMaxDistance(double maxDistance)
+{
+    if (maxDistance <= 0)
+        return Exception { RangeError, "maxDistance cannot be set to a non-positive value"_s };
+    
+    m_distanceEffect.setMaxDistance(maxDistance);
+    return { };
+}
+
+ExceptionOr<void> PannerNode::setRolloffFactor(double rolloffFactor)
+{
+    // FIXME: Implement clamping of linear model once feedback is received
+    
+    if (rolloffFactor < 0)
+        return Exception { RangeError, "rolloffFactor cannot be set to a negative value"_s };
+    
+    m_distanceEffect.setRolloffFactor(rolloffFactor);
+    return { };
+}
+
+ExceptionOr<void> PannerNode::setConeOuterGain(double gain)
+{
+    if (gain < 0 || gain > 1)
+        return Exception { InvalidStateError, "coneOuterGain must be in [0, 1]"_s };
+    
+    m_coneEffect.setOuterGain(gain);
+    return { };
+}
+
 void PannerNode::getAzimuthElevation(double* outAzimuth, double* outElevation)
 {
     // FIXME: we should cache azimuth and elevation (if possible), so we only re-calculate if a change has been made.
diff --git a/Source/WebCore/Modules/webaudio/PannerNode.h b/Source/WebCore/Modules/webaudio/PannerNode.h
index f2514cb..76fb293 100644
--- a/Source/WebCore/Modules/webaudio/PannerNode.h
+++ b/Source/WebCore/Modules/webaudio/PannerNode.h
@@ -101,14 +101,14 @@
     DistanceModelType distanceModel() const;
     void setDistanceModel(DistanceModelType);
 
-    double refDistance() { return m_distanceEffect.refDistance(); }
-    void setRefDistance(double refDistance) { m_distanceEffect.setRefDistance(refDistance); }
+    double refDistance() const { return m_distanceEffect.refDistance(); }
+    ExceptionOr<void> setRefDistance(double);
 
-    double maxDistance() { return m_distanceEffect.maxDistance(); }
-    void setMaxDistance(double maxDistance) { m_distanceEffect.setMaxDistance(maxDistance); }
+    double maxDistance() const { return m_distanceEffect.maxDistance(); }
+    ExceptionOr<void> setMaxDistance(double);
 
-    double rolloffFactor() { return m_distanceEffect.rolloffFactor(); }
-    void setRolloffFactor(double rolloffFactor) { m_distanceEffect.setRolloffFactor(rolloffFactor); }
+    double rolloffFactor() const { return m_distanceEffect.rolloffFactor(); }
+    ExceptionOr<void> setRolloffFactor(double);
 
     // Sound cones - angles in degrees
     double coneInnerAngle() const { return m_coneEffect.innerAngle(); }
@@ -118,7 +118,7 @@
     void setConeOuterAngle(double angle) { m_coneEffect.setOuterAngle(angle); }
 
     double coneOuterGain() const { return m_coneEffect.outerGain(); }
-    void setConeOuterGain(double angle) { m_coneEffect.setOuterGain(angle); }
+    ExceptionOr<void> setConeOuterGain(double);
 
     void getAzimuthElevation(double* outAzimuth, double* outElevation);
     float dopplerRate() final;
diff --git a/Source/WebCore/Modules/webaudio/PannerNode.idl b/Source/WebCore/Modules/webaudio/PannerNode.idl
index 2cd1a3f..6ea27f3 100644
--- a/Source/WebCore/Modules/webaudio/PannerNode.idl
+++ b/Source/WebCore/Modules/webaudio/PannerNode.idl
@@ -37,14 +37,14 @@
     // Default distance model is inverse
     attribute DistanceModelType distanceModel;
 
-    attribute unrestricted double refDistance;
-    attribute unrestricted double maxDistance;
-    attribute unrestricted double rolloffFactor;
+    attribute double refDistance;
+    attribute double maxDistance;
+    attribute double rolloffFactor;
 
     // Directional sound cone
-    attribute unrestricted double coneInnerAngle;
-    attribute unrestricted double coneOuterAngle;
-    attribute unrestricted double coneOuterGain;
+    attribute double coneInnerAngle;
+    attribute double coneOuterAngle;
+    attribute double coneOuterGain;
     
     // Position of audio source in 3D Cartesian system
     readonly attribute AudioParam positionX;