mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1160342 - Implement marquee using mutation observers, r=smaug
This commit is contained in:
parent
ac975a3e11
commit
842cd6d33f
@ -168,4 +168,5 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s
|
||||
[test_bug1022869.html]
|
||||
[test_bug1112040.html]
|
||||
[test_bug1160342_marquee.html]
|
||||
[test_bug1171215.html]
|
||||
|
228
dom/tests/mochitest/bugs/test_bug1160342_marquee.html
Normal file
228
dom/tests/mochitest/bugs/test_bug1160342_marquee.html
Normal file
@ -0,0 +1,228 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1160342
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 411103</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1160342">Mozilla Bug 1160342</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<marquee id="a">marquee</marquee>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var x=document.getElementById('a');
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
setTimeout(function() {
|
||||
is(x.behavior, "scroll", "Wrong behavior value");
|
||||
x.setAttribute('behavior', 'alternate');
|
||||
is(x.behavior, "alternate", "Wrong behavior value");
|
||||
x.setAttribute('behavior', 'invalid');
|
||||
todo_is(x.behavior, "scroll", "Wrong behavior value");;
|
||||
x.setAttribute('behavior', 'Scroll');
|
||||
is(x.behavior, "scroll", "Wrong behavior value");
|
||||
x.setAttribute('behavior', 'Slide');
|
||||
is(x.behavior, "slide", "Wrong behavior value");
|
||||
x.removeAttribute('behavior');
|
||||
is(x.behavior, "scroll", "Wrong behavior value");
|
||||
|
||||
x.behavior = 'alternate';
|
||||
is(x.behavior, "alternate", "Wrong behavior value");
|
||||
try {
|
||||
x.behavior = 'invalid';
|
||||
todo_is(false, true, "marquee.behavior = 'invalid' should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
is(x.behavior, "alternate", "Wrong behavior value");
|
||||
x.behavior = 'Slide';
|
||||
is(x.behavior, "slide", "Wrong behavior value");
|
||||
try {
|
||||
x.behavior = 'invalid';
|
||||
todo_is(false, true, "marquee.behavior = 'invalid' should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
is(x.behavior, "slide", "Wrong behavior value");
|
||||
|
||||
is(x.loop, -1, "Wrong loop value");
|
||||
x.setAttribute('loop', '1');
|
||||
is(x.loop, 1, "Wrong loop value");
|
||||
x.setAttribute('loop', 'invalid');
|
||||
todo_is(x.loop, -1, "Wrong loop value");
|
||||
x.setAttribute('loop', '1000');
|
||||
is(x.loop, 1000, "Wrong loop value");
|
||||
x.setAttribute('loop', '-1');
|
||||
is(x.loop, -1, "Wrong loop value");
|
||||
x.setAttribute('loop', '1000');
|
||||
is(x.loop, 1000, "Wrong loop value");
|
||||
x.removeAttribute('loop');
|
||||
is(x.loop, -1, "Wrong loop value");
|
||||
|
||||
x.loop = 1;
|
||||
is(x.loop, 1, "Wrong loop value");
|
||||
try {
|
||||
x.loop = -2;
|
||||
todo_is(false, true, "marquee.loop = -2 should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
todo_is(x.loop, 1, "Wrong loop value");
|
||||
try {
|
||||
x.loop = 'invalid';
|
||||
todo_is(false, true, ".loop = 'invalid' should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
todo_is(x.loop, 1, "Wrong loop value");
|
||||
try {
|
||||
x.loop = null;
|
||||
todo_is(false, true, "marquee.loop = null should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
todo_is(x.loop, 1, "Wrong loop value");
|
||||
x.loop = -1;
|
||||
is(x.loop, -1, "Wrong loop value");
|
||||
x.loop = '100';
|
||||
is(x.loop, 100, "Wrong loop value");
|
||||
|
||||
is(x.scrollAmount, 6, "Wrong scrollAmount value");
|
||||
x.setAttribute('scrollAmount', '1');
|
||||
is(x.scrollAmount, 1, "Wrong scrollAmount value");
|
||||
x.setAttribute('scrollAmount', 'invalid');
|
||||
todo_is(x.scrollAmount, 6, "Wrong scrollAmount value");
|
||||
x.setAttribute('scrollAmount', '1000');
|
||||
is(x.scrollAmount, 1000, "Wrong scrollAmount value");
|
||||
x.setAttribute('scrollAmount', '-1');
|
||||
is(x.scrollAmount, 1000, "Wrong scrollAmount value");
|
||||
x.setAttribute('scrollAmount', '999');
|
||||
is(x.scrollAmount, 999, "Wrong scrollAmount value");
|
||||
x.removeAttribute('scrollAmount');
|
||||
is(x.scrollAmount, 6, "Wrong scrollAmount value");
|
||||
|
||||
x.scrollAmount = 1;
|
||||
is(x.scrollAmount, 1, "Wrong scrollAmount value");
|
||||
try {
|
||||
x.scrollAmount = -2;
|
||||
todo_is(false, true, "marquee.scrollAmount = -2 should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
is(x.scrollAmount, 1, "Wrong scrollAmount value");
|
||||
x.scrollAmount = 'invalid';
|
||||
todo_is(x.scrollAmount, 0, "Wrong scrollAmount value");
|
||||
x.scrollAmount = 1;
|
||||
x.scrollAmount = null;
|
||||
todo_is(x.scrollAmount, 0, "Wrong scrollAmount value");
|
||||
x.scrollAmount = '2';
|
||||
is(x.scrollAmount, 2, "Wrong scrollAmount value");
|
||||
|
||||
|
||||
is(x.scrollDelay, 85, "Wrong scrollDelay value");
|
||||
x.setAttribute('scrollDelay', '1');
|
||||
is(x.scrollDelay, 1, "Wrong scrollDelay value");
|
||||
x.setAttribute('scrollDelay', 'invalid');
|
||||
todo_is(x.scrollDelay, 85, "Wrong scrollDelay value");
|
||||
x.setAttribute('scrollDelay', '70');
|
||||
is(x.scrollDelay, 70, "Wrong scrollDelay value");
|
||||
x.setAttribute('scrollDelay', '59');
|
||||
is(x.scrollDelay, 59, "Wrong scrollDelay value");
|
||||
x.setAttribute('scrollDelay', '1000');
|
||||
is(x.scrollDelay, 1000, "Wrong scrollDelay value");
|
||||
x.setAttribute('scrollDelay', '-1');
|
||||
is(x.scrollDelay, 1000, "Wrong scrollDelay value");
|
||||
x.removeAttribute('scrollDelay');
|
||||
is(x.scrollDelay, 85, "Wrong scrollDelay value");
|
||||
|
||||
x.scrollDelay = 100;
|
||||
is(x.scrollDelay, 100, "Wrong scrollDelay value");
|
||||
try {
|
||||
x.scrollDelay = -2;
|
||||
todo_is(false, true, "marquee.scrollDelay = -2 should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
is(x.scrollDelay, 100, "Wrong scrollDelay value");
|
||||
try {
|
||||
x.scrollDelay = 'invalid';
|
||||
todo_is(false, true, "marquee.scrollDelay = 'invalid' should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
is(x.scrollDelay, 100, "Wrong scrollDelay value");
|
||||
try {
|
||||
x.scrollDelay = null;
|
||||
todo_is(false, true, "marquee.scrollDelay = null should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
is(x.scrollDelay, 100, "Wrong scrollDelay value");
|
||||
try {
|
||||
x.scrollDelay = -1;
|
||||
todo_is(false, true, "marquee.scrollDelay = -1 should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
is(x.scrollDelay, 100, "Wrong scrollDelay value");
|
||||
x.scrollDelay = '50';
|
||||
is(x.scrollDelay, 50, "Wrong scrollDelay value");
|
||||
|
||||
is(x.trueSpeed, false, "Wrong trueSpeed value");
|
||||
x.setAttribute('trueSpeed', '1');
|
||||
is(x.trueSpeed, true, "Wrong trueSpeed value");
|
||||
x.setAttribute('trueSpeed', 'false');
|
||||
is(x.trueSpeed, true, "Wrong trueSpeed value");
|
||||
x.removeAttribute('trueSpeed');
|
||||
is(x.trueSpeed, false, "Wrong trueSpeed value");
|
||||
|
||||
x.trueSpeed = 1;
|
||||
is(x.trueSpeed, true, "Wrong trueSpeed value");
|
||||
x.trueSpeed = -2;
|
||||
is(x.trueSpeed, true, "Wrong trueSpeed value");
|
||||
x.trueSpeed = null;
|
||||
is(x.trueSpeed, false, "Wrong trueSpeed value");
|
||||
x.trueSpeed = '100';
|
||||
is(x.trueSpeed, true, "Wrong trueSpeed value");
|
||||
|
||||
todo_is(x.direction, "left", "Wrong direction value");
|
||||
x.setAttribute('direction', 'right');
|
||||
is(x.direction, "right", "Wrong direction value");
|
||||
x.setAttribute('direction', 'invalid');
|
||||
todo_is(x.direction, "left", "Wrong direction value");
|
||||
x.setAttribute('direction', 'RIGHT');
|
||||
todo_is(x.direction, "right", "Wrong direction value");
|
||||
x.removeAttribute('direction');
|
||||
todo_is(x.direction, "left", "Wrong direction value");
|
||||
|
||||
x.direction = 'right';
|
||||
is(x.direction, "right", "Wrong direction value");
|
||||
try {
|
||||
x.direction = 1;
|
||||
todo_is(false, true, "marquee.direction = 1 should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
todo_is(x.direction, "right", "Wrong direction value");
|
||||
try {
|
||||
x.direction = null;
|
||||
todo_is(false, true, "marquee.direction = null should throw");
|
||||
} catch(e) {
|
||||
ok(true, "Exception was raised");
|
||||
}
|
||||
todo_is(x.direction, "right", "Wrong direction value");
|
||||
SimpleTest.finish();
|
||||
}, 0);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
10
layout/reftests/marquee/1160342-1.html
Normal file
10
layout/reftests/marquee/1160342-1.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1160342 - Implement marquee using mutation observers</title>
|
||||
</head>
|
||||
<body onload="document.getElementById('a').setAttribute('behavior', 'alternate')">
|
||||
<marquee id="a" scrollamount=0 direction=right>
|
||||
This text should be visible
|
||||
</marquee>
|
||||
</body>
|
||||
</html>
|
10
layout/reftests/marquee/1160342-2.html
Normal file
10
layout/reftests/marquee/1160342-2.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1160342 - Implement marquee using mutation observers</title>
|
||||
</head>
|
||||
<body onload="document.getElementById('a').setAttribute('direction', 'right')">
|
||||
<marquee id="a" behavior=alternate scrollamount=0>
|
||||
This text should be visible
|
||||
</marquee>
|
||||
</body>
|
||||
</html>
|
10
layout/reftests/marquee/1160342-ref.html
Normal file
10
layout/reftests/marquee/1160342-ref.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1160342 - Implement marquee using mutation observers</title>
|
||||
</head>
|
||||
<body>
|
||||
<marquee id="a" behavior=alternate scrollamount=0 direction=right>
|
||||
This text should be visible
|
||||
</marquee>
|
||||
</body>
|
||||
</html>
|
@ -7,3 +7,5 @@ fuzzy-if(Android&&AndroidVersion>=15,8,220) == 413027-4.html 413027-4-ref.html
|
||||
fuzzy-if(Android&&AndroidVersion>=15,8,30) == 425247-1.html 425247-1-ref.html
|
||||
fuzzy-if(Android&&AndroidVersion>=15,8,30) == 425247-2.html 425247-2-ref.html
|
||||
random == 429849-1.html 429849-1-ref.html # bug 432288
|
||||
== 1160342-1.html 1160342-ref.html
|
||||
== 1160342-2.html 1160342-ref.html
|
||||
|
@ -20,6 +20,7 @@
|
||||
<property name="scrollAmount" exposeToUntrustedContent="true">
|
||||
<getter>
|
||||
<![CDATA[
|
||||
this._mutationActor(this._mutationObserver.takeRecords());
|
||||
var val = parseInt(this.getAttribute("scrollamount"));
|
||||
|
||||
if (val <= 0 || isNaN(val))
|
||||
@ -36,6 +37,7 @@
|
||||
<property name="scrollDelay" exposeToUntrustedContent="true">
|
||||
<getter>
|
||||
<![CDATA[
|
||||
this._mutationActor(this._mutationObserver.takeRecords());
|
||||
var val = parseInt(this.getAttribute("scrolldelay"));
|
||||
|
||||
if (val <= 0 || isNaN(val))
|
||||
@ -79,6 +81,7 @@
|
||||
|
||||
<property name="behavior" exposeToUntrustedContent="true">
|
||||
<getter>
|
||||
this._mutationActor(this._mutationObserver.takeRecords());
|
||||
return this._behavior;
|
||||
</getter>
|
||||
<setter>
|
||||
@ -90,6 +93,7 @@
|
||||
<property name="loop" exposeToUntrustedContent="true">
|
||||
<getter>
|
||||
<![CDATA[
|
||||
this._mutationActor(this._mutationObserver.takeRecords());
|
||||
var val = parseInt(this.getAttribute('loop'));
|
||||
|
||||
if (val < -1 || isNaN(val))
|
||||
@ -156,6 +160,7 @@
|
||||
<parameter name="aValue"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
aValue = parseInt(aValue);
|
||||
if (aValue <= 0 || isNaN(aValue) || aValue == null)
|
||||
return false;
|
||||
|
||||
@ -177,6 +182,7 @@
|
||||
<parameter name="aValue"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
aValue = parseInt(aValue);
|
||||
if (aValue < 0 || isNaN(aValue) || aValue == null)
|
||||
return false;
|
||||
|
||||
@ -488,6 +494,88 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_mutationActor">
|
||||
<parameter name="aMutations"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
while (aMutations.length > 0) {
|
||||
var mutation = aMutations.shift();
|
||||
var attrName = mutation.attributeName.toLowerCase();
|
||||
var oldValue = mutation.oldValue;
|
||||
var target = mutation.target;
|
||||
var newValue = target.getAttribute(attrName);
|
||||
|
||||
if (oldValue != newValue) {
|
||||
switch (attrName) {
|
||||
case "loop":
|
||||
if (!target._set_loop(newValue)) {
|
||||
if (!newValue) {
|
||||
target._loop = -1;
|
||||
if (target.runId == 0)
|
||||
target.start();
|
||||
}
|
||||
}
|
||||
if (target.rundId == 0)
|
||||
target.start();
|
||||
break;
|
||||
case "scrollamount":
|
||||
if (!newValue)
|
||||
target._scrollAmount = 6;
|
||||
else
|
||||
target._set_scrollAmount(newValue);
|
||||
break;
|
||||
case "scrolldelay":
|
||||
if (!newValue)
|
||||
target._scrollDelay = 85;
|
||||
else
|
||||
target._set_scrollDelay(newValue);
|
||||
target.stop();
|
||||
target.start();
|
||||
break;
|
||||
case "truespeed":
|
||||
//needed to update target._scrollDelay
|
||||
var myThis = target;
|
||||
var lambda = function() {myThis._set_scrollDelay(myThis.getAttribute('scrolldelay'));}
|
||||
window.setTimeout(lambda, 0);
|
||||
break;
|
||||
case "behavior":
|
||||
if (!newValue)
|
||||
target._behavior = "scroll";
|
||||
else
|
||||
target._set_behavior(newValue);
|
||||
target.startNewDirection = true;
|
||||
if ((oldValue == "slide" && target.newPosition == target.stopAt) ||
|
||||
newValue == "alternate" || newValue == "slide") {
|
||||
target.stop();
|
||||
target._doMove(true);
|
||||
}
|
||||
break;
|
||||
case "direction":
|
||||
if (!newValue)
|
||||
target._direction = "left";
|
||||
else
|
||||
target._set_direction(newValue);
|
||||
break;
|
||||
case "width":
|
||||
case "height":
|
||||
target.startNewDirection = true;
|
||||
break;
|
||||
case "onstart":
|
||||
target._setEventListener("start", newValue);
|
||||
break;
|
||||
case "onfinish":
|
||||
target._setEventListener("finish", newValue);
|
||||
break;
|
||||
case "onbounce":
|
||||
target._setEventListener("bounce", newValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
// Set up state.
|
||||
@ -518,6 +606,9 @@
|
||||
this._setEventListener("bounce", this.getAttribute("onbounce"));
|
||||
this.startNewDirection = true;
|
||||
|
||||
this._mutationObserver = new MutationObserver(this._mutationActor);
|
||||
this._mutationObserver.observe(this, { attributes: true, attributeOldValue: true });
|
||||
|
||||
// init needs to be run after the page has loaded in order to calculate
|
||||
// the correct height/width
|
||||
if (document.readyState == "complete")
|
||||
@ -528,99 +619,6 @@
|
||||
</constructor>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="DOMAttrModified" phase="target">
|
||||
<![CDATA[
|
||||
var attrName = event.attrName.toLowerCase();
|
||||
var oldValue = event.prevValue.toLowerCase();
|
||||
var newValue = event.newValue.toLowerCase();
|
||||
var attributeRemoval = false;
|
||||
if (event.attrChange == event.REMOVAL) {
|
||||
newValue = null;
|
||||
attributeRemoval = true;
|
||||
};
|
||||
|
||||
if (oldValue != newValue) {
|
||||
switch (attrName) {
|
||||
case "loop":
|
||||
if (!this._set_loop(newValue)) {
|
||||
if (attributeRemoval) {
|
||||
this._loop = -1;
|
||||
if (this.runId == 0)
|
||||
this.start();
|
||||
}
|
||||
else
|
||||
throw new Error("Invalid argument for Marquee::loop");
|
||||
}
|
||||
if (this.rundId == 0)
|
||||
this.start();
|
||||
break;
|
||||
case "scrollamount":
|
||||
if (!this._set_scrollAmount(newValue)) {
|
||||
if (attributeRemoval)
|
||||
this._scrollAmount = 6;
|
||||
else
|
||||
throw new Error("Invalid argument for Marquee::scrollAmount");
|
||||
}
|
||||
break;
|
||||
case "scrolldelay":
|
||||
if (!this._set_scrollDelay(newValue)) {
|
||||
if (attributeRemoval)
|
||||
this._scrollDelay = 85;
|
||||
else
|
||||
throw new Error("Invalid argument for Marquee::scrollDelay");
|
||||
}
|
||||
this.stop();
|
||||
this.start();
|
||||
break;
|
||||
case "truespeed":
|
||||
//needed to update this._scrollDelay
|
||||
var myThis = this;
|
||||
var lambda = function() {myThis._set_scrollDelay(myThis.getAttribute('scrolldelay'));}
|
||||
window.setTimeout(lambda, 0);
|
||||
break;
|
||||
case "behavior":
|
||||
if (!this._set_behavior(newValue)) {
|
||||
if (attributeRemoval)
|
||||
this._behavior = "scroll";
|
||||
else
|
||||
throw new Error("Invalid argument for Marquee::behavior");
|
||||
}
|
||||
|
||||
this.startNewDirection = true;
|
||||
if ((oldValue == "slide" && this.newPosition == this.stopAt) ||
|
||||
newValue == "alternate" || newValue == "slide") {
|
||||
this.stop();
|
||||
this._doMove(true);
|
||||
}
|
||||
break;
|
||||
case "direction":
|
||||
if (!this._set_direction(newValue)) {
|
||||
if (attributeRemoval)
|
||||
this._direction = "left";
|
||||
else
|
||||
throw new Error("Invalid argument for Marquee::direction");
|
||||
}
|
||||
break;
|
||||
case "width":
|
||||
case "height":
|
||||
this.startNewDirection = true;
|
||||
break;
|
||||
case "onstart":
|
||||
this._setEventListener("start", newValue);
|
||||
break;
|
||||
case "onfinish":
|
||||
this._setEventListener("finish", newValue);
|
||||
break;
|
||||
case "onbounce":
|
||||
this._setEventListener("bounce", newValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
</handlers>
|
||||
|
||||
</binding>
|
||||
|
||||
<binding id="marquee-horizontal" bindToUntrustedContent="true"
|
||||
|
Loading…
Reference in New Issue
Block a user