Closed Bug 167224 Opened 22 years ago Closed 20 years ago

Cleanup marquee

Categories

(Core :: Layout, defect, P2)

x86
All
defect

Tracking

()

RESOLVED FIXED
mozilla1.7alpha

People

(Reporter: doronr, Assigned: doronr)

References

Details

(Keywords: topembed-, Whiteboard: [dev notes] whitebox)

Attachments

(2 files, 12 obsolete files)

14.48 KB, patch
neil
: review+
bryner
: superreview+
Details | Diff | Splinter Review
14.37 KB, patch
Details | Diff | Splinter Review
Will fix:

- use % for height
- correct behaviour of alternate scrolling
- allow marquee's direction to be changed anytime
- make marquee a block in html.css
Attached patch fixes most of the issues atm (obsolete) — Splinter Review
Attached patch really working partial patch (obsolete) — Splinter Review
Attachment #98242 - Attachment is obsolete: true
much better patch
Attachment #98244 - Attachment is obsolete: true
Attached patch no evil tabs! (obsolete) — Splinter Review
Attachment #98373 - Attachment is obsolete: true
QA Contact: petersen → amar
better patch
Attachment #98374 - Attachment is obsolete: true
Priority: -- → P2
Marking as nsbeta1+/topembed+ per EDT triage.
Attached patch patch for trunk/1.2 branch (obsolete) — Splinter Review
this applies correctly on 1.2 and trunk
Attachment #98523 - Attachment is obsolete: true
Status: NEW → ASSIGNED
Attachment #105209 - Attachment is obsolete: true
Attachment #106286 - Flags: review?(ian)
Comment on attachment 106286 [details] [diff] [review]
fix 2 minor "bugs" *cough*IE compat*cough*

fix the three things I mentioned on IRC and add some breathing space around the
?: operators and come back to me. :-)
Attachment #106286 - Flags: review?(ian) → review-
Whiteboard: [dev notes]
Whiteboard: [dev notes] → [dev notes] whitebox
1.4alpha I guess
Target Milestone: --- → mozilla1.4alpha
Target Milestone: mozilla1.4alpha → Future
Blocks: 203856
Discussed in topembed bug triage.  Minusing.
Keywords: topembed+topembed-
targetting 1.5alpha
Target Milestone: Future → mozilla1.5alpha
Blocks: 208683
1.6a
Target Milestone: mozilla1.5alpha → mozilla1.6alpha
Blocks: 192671
Doron,

can you repair the things Ian requested and check if the patch still works in
current trunk version?

pi
Since opera now supports marquee, we have to have better support than they do :)

I lost all the stuff at netscape, so will redo the patch (parts of it are in the
tree) and get new reviews.
Target Milestone: mozilla1.6alpha → mozilla1.6beta
oh, and safari now too!
OS: Windows 2000 → All
Attached patch updated patch (obsolete) — Splinter Review
Attachment #106286 - Attachment is obsolete: true
Attachment #134567 - Attachment is obsolete: true
Attachment #135185 - Flags: review?(ian)
Comment on attachment 135185 [details] [diff] [review]
add some spacing to make it more readable

don't have time to review this in the near future, sorry
Attachment #135185 - Flags: review?(ian) → review?
Attachment #135185 - Flags: review? → review?(timeless)
Comment on attachment 135185 [details] [diff] [review]
add some spacing to make it more readable

>       <property name="direction">
>         <getter>
>           if (this.hasAttribute("direction"))
>-            return this.getAttribute("direction");
>+            return this.getAttribute("direction").toLowerCase();
no. getters are generally called more often, and as you'll see later, you want
to have the case 'correct' internally.
>           return "left"; //default value is "left"
>         </getter>
>+        <setter>
>+          // since we changed the direction, set startNewDirection to 1
>+          this.startNewDirection = 1;
>+          this.setAttribute("direction", val);
toLowerCase here.
>+        </setter>        
>       </property>
> 
>       <property name="behavior">
>         <getter>
>           if (this.hasAttribute("behavior"))
>-            return this.getAttribute("behavior");
>+            return this.getAttribute("behavior").toLowerCase();
same comment, not here.
>           return "scroll"; //default value is "scroll"
>         </getter>
>+        <setter>
>+          this.setAttribute("behavior", val);
same comment, convert here.
>+        </setter>        
>       </property>
> 
>       <field name="dirsign">1</field>

>@@ -115,18 +128,22 @@
>           <![CDATA[
>           if (this.hasAttribute("width"))
>             return this.getAttribute("width");
>-          else if (this.parentNode.offsetWidth > 0)
>-            return this.parentNode.offsetWidth;
>-          else if (this.parentNode.parentNode.offsetWidth > 0)
>-            return this.parentNode.parentNode.offsetWidth;
>-          else
else after return
>+          else if (this.offsetParent){
>+            var myElem = this;  
>+            while (myElem && (myElem.offsetWidth <= 0))
>+              myElem = this.offsetparent;
>+
>+            if(myElem.offsetWidth > 0)  
>+              return myElem.offsetWidth;
>+            else return 1;  
else after and even before return
>+          } else
>             return 1;
and after again.

if (this.hasAttribute("width"))
  return this.getAttribute("width");
if (!this.offsetParent)
  return 1;
var myElem = this;  
while (myElem && (myElem.offsetWidth <= 0))
  myElem = this.offsetparent;

return myElem.offsetWidth || 1;
/* as you can easily see from this loop and return, there's a problem if myElem
becomes false. i couldn't even see that in your original code. what do you want
to do? return myElem && myElem.offsetWidth || 1; is one possibility. changing
the loop control is another, there are others still.... */

>+            if ((this.direction == "up") || (this.direction == "down")){
note that you don't check for "UP" here. fixing the setter avoids this problem.
>+
>+              if (this.hasAttribute('height')){
>+                height = this.getAttribute('height');
>+                if (height == "") //empty attribute, default to 200px
>+                  height = "200px";             
^ trailing whitespace.
>+              }  
>+              else 
>+                height = "200px";
What if the height is 0?
If height = 0 is meaningless (and should be treated as empty) then you can use:
height = this.hasAttribute('height') && this.getAttribute('height') || "200px";
as a replacement for the enter height section.

>+
>+              // support % heights
>+              if (height.indexOf("%") > 0){
>+                height = parseInt('0' + height, 10);
what happens if parseInt returns NaN?
>+                height = (height/100) * this.outerDiv.offsetHeight;           
then this is NaN
>+              }
>+         
>+              this.outerDiv.style.height = height;
and this
>+
>+              this.innerDiv.style.padding = height + " 0";
and this is "NaN 0"

>             switch (this.direction)
again, you wanted direction lowercased at the setter
>             {
>               case "up":
>                 this.dirsign = 1;
>-                this.startAt = 0;
>-                this.stopAt  = this.innerDiv.offsetHeight -
>-                               parseInt(this.outerDiv.style.height);
>+                this.startAt = (this.behavior == 'alternate') ? this.originalHeight : 0;
this.startAt = (this.behavior == 'alternate') && this.originalHeight;
>+                this.stopAt  = this.innerDiv.offsetHeight - parseInt(this.outerDiv.style.height) 
>+                               - ((this.behavior == 'alternate') ? this.originalHeight : 0);
- ((this.behavior == 'alternate') && this.originalHeight);
>               break;

...

>+                this.startAt = this.innerDiv.offsetHeight - parseInt(this.outerDiv.style.height)
>+                               - ((this.behavior == 'alternate') ? this.originalHeight : 0);
>+                this.stopAt  = (this.behavior == 'alternate') ? this.originalHeight : 0;
same idea

>+              case "left":  
>+                this.dirsign = 1;                                              
>+                this.startAt = (this.behavior != 'alternate') ? (this.innerDiv.offsetLeft - this.outerDiv.offsetWidth) : this.innerDiv.offsetWidth;
>+                this.stopAt  = this.outerDiv.offsetWidth 
>+                               + ((this.behavior != 'alternate') ? (this.innerDiv.offsetWidth + this.startAt) : 0);
and here

>+                this.stopAt  = (this.behavior != 'alternate') ? this.innerDiv.offsetLeft - this.outerDiv.offsetWidth:this.innerDiv.offsetWidth;
>+                this.startAt = this.outerDiv.offsetWidth 
>+                               + ((this.behavior!='alternate') ? (this.innerDiv.offsetWidth+ this.stopAt) : 0);   
and here
Attachment #135185 - Flags: review?(timeless) → review-
Comment on attachment 135185 [details] [diff] [review]
add some spacing to make it more readable

>>-            return this.getAttribute("direction");
>>+            return this.getAttribute("direction").toLowerCase();
>no. getters are generally called more often, and as you'll see later, you want
>to have the case 'correct' internally.
I can't really comment on this without knowing what IE does - if you have
<MARQUEE DIRECTION="RIGHT"> what does IE return as the property? (If it's right,
then doron is right, if it's RIGHT, then IMHO you're both wrong.)

>+            while (myElem && (myElem.offsetWidth <= 0))
>+              myElem = this.offsetparent;
Infinite loop alert.

>+            if(myElem.offsetWidth > 0)  
>+              return myElem.offsetWidth;
>+            else return 1;  
trailing whitespace and you should use ?: here.

>+              if (this.hasAttribute('height')){
>+                height = this.getAttribute('height');
>+                if (height == "") //empty attribute, default to 200px
>+                  height = "200px";             
>+              }  
>+              else 
>+                height = "200px";
height = this.getAttribute("height") || "200px";

>What if the height is 0?
>If height = 0 is meaningless (and should be treated as empty) then you can use:
>height = this.hasAttribute('height') && this.getAttribute('height') || "200px";
>as a replacement for the enter height section.
Actually, "0" will evaluate as true for the purposes of ||.

>>+
>>+              // support % heights
>>+              if (height.indexOf("%") > 0){
>>+                height = parseInt('0' + height, 10);
>what happens if parseInt returns NaN?
Rather neatly, the ,10 fixes that :-)

>>+                this.startAt = (this.behavior == 'alternate') ?
>>this.originalHeight : 0;
>this.startAt = (this.behavior == 'alternate') && this.originalHeight;
This is tricky JS at the best of times, assuming that startAt will only be used
as an integer so that false will convert to zero.
Comment on attachment 135185 [details] [diff] [review]
add some spacing to make it more readable

neil notes that
>+            while (myElem && (myElem.offsetWidth <= 0))
>+              myElem = this.offsetparent;
this loop is infinite (oops), since nothing advances myElem
>+                height = parseInt('0' + height, 10);
and that in my haste, i missed the ,10 -sorry-. so there isn't a nan concern.
on IE, marquee returns the lowercased direction, even if its set to RIGHT in the
HTML.

Nitpickers! :)
that doesn't answer the question.

if you set "RIGHT", does it behave like "right" or "random-unrecognized-string"?
all marquee attributes are case insensative, and always return the lowercased
version when queried via DOM.
Attachment #135185 - Attachment is obsolete: true
Attachment #135400 - Flags: review?(neil.parkwaycc.co.uk)
Comment on attachment 135400 [details] [diff] [review]
Fixes the nitpicks and the performance issue

but not the infinite loop this => myElem ?
Attachment #135400 - Flags: review?(neil.parkwaycc.co.uk) → review-
Attached patch fix the loop issue (obsolete) — Splinter Review
Attachment #135400 - Attachment is obsolete: true
Attachment #135423 - Flags: review?(neil.parkwaycc.co.uk)
Comment on attachment 135423 [details] [diff] [review]
fix the loop issue

Were you aware that this patch regresses the behaviour that setAttribute may be
used to modify the marquee?

Do you have a testcase to demonstrate the effect of your changes?

Here are the usual nits:
>+          // since we changed the scrolldelay, restart the marquee
>+          this.stop();
>+          this.start();          
start() already calls stop(), also lost the trailing whitespace.

>+          // since we changed the direction, set startNewDirection to 1
Um... why isn't this a true/false?

>+              // "", 0 and empty height should default to 200px
>+              height = (this.hasAttribute('height') && this.getAttribute('height')) ? this.getAttribute('height') : "200px";
This doesn't work for "0", because it's a string.
height = (this.getAttribute("height") != "0" && this.getAttribute("height")) ||
"200px";

>+              if (height.indexOf("%") > 0){
if (/%/.test(height) {

>+              // swap direction    
>+              this.directionField = 
>+               (this.directionField == "left") ? "right" : (this.directionField == "down") ? "up" : (this.directionField == "up") ? "down" : "left";
const swap = {left: "right", down: "up", up: "down", right: "left"};
this.directionField = swap[this.directionField];
-> 1.7a
Target Milestone: mozilla1.6beta → mozilla1.7alpha
Attached patch fix nitpicks (obsolete) — Splinter Review
Patch fixes nitpicks as well as makes the marquee transition nicely when a new
direction is set (no marquee position resetting).

Behavior changing doesn't work well still.
Attachment #135423 - Attachment is obsolete: true
Any plan to support marquue in CSS3 Style?
http://www.w3.org/TR/2002/WD-css3-box-20021024/#marquee
The pages can then be written using strict mode with visual marquee effects.
The 2nd working draft of the module is planned in April 2004, though.
Attachment #137721 - Flags: review?(neil.parkwaycc.co.uk)
Comment on attachment 137721 [details] [diff] [review]
fix nitpicks

>+          this.start();          
No trailing spaces, please. (You do this quite a lot :-( )

>+          // pass in aSkipSettingNewPosition as true
>+          this.start(true);          
Isn't start() a public method? In which case we shouldn't be passing it our own
parameters.

>+            while (myElem.offsetParent && (myElem.offsetWidth <= 0))
>+              myElem = myElem.offsetParent;
>+
>+            if (myElem.offsetWidth > 0)
myElem might be null at this point. However, if it is not null, then its
offsetWidth will be greater than zero.

>+          // Website can define a background color via the bgcolor attribute
>+          if (this.hasAttribute("bgcolor"))
>+            this.outerDiv.style.backgroundColor = this.getAttribute("bgcolor");
This one isn't dynamic then?

The marquee didn't like me deleting the direction or behavior attributes.
Isn't setting the direction/behaviour supposed to update the attribute?
I would liked to have had more test cases.
Attachment #137721 - Flags: review?(neil.parkwaycc.co.uk) → review-
testcase tool with new xbl embedded:
http://www.nexgenmedia.net/marquee/marqueetest.html

Made a non-public method _doMove that start() now calls.  Fixed the whitespaces
as well.

>+            while (myElem.offsetParent && (myElem.offsetWidth <= 0))
>+              myElem = myElem.offsetParent;
>+
>+            if (myElem.offsetWidth > 0)
myElem might be null at this point. However, if it is not null, then its
offsetWidth will be greater than zero.

In theory myElm will always be non-null, but maide it check just in case.

And bgcolor is a different bug, its not new code but code that moved.
Setting behavior/direction to "" is now fixed, it should do nothing.
Comment on attachment 141156 [details] [diff] [review]
Fixes neil's issues, also fixes some table width in marquee problems

>+          rv = this.defaultScrollDelay; //default value is 85 ms
var rv, please.

>+            // in case direction is swamped between horizontal/vertical, use
Typo: swapped

>+          if (!this.startNewDirection){
> 
Why did you leave that blank line in?

>       <method name="init">
>         <body>
>         <![CDATA[
>-          var height;
> 
Take out this blank line too.

>+        if (oldValue != newValue && newValue){
>+          if (attrName == "direction"){
>+            this.startNewDirection = true;
>+            this.directionField = newValue;
>+            this._doMove(true);
>+          } else if (attrName == "behavior"){
Spaces between )s and {s please.
Attachment #141156 - Flags: review+
who does xbl sr's these days?
Attachment #141156 - Flags: superreview?(bryner)
If you have a good r=, the sr need not be an XBl/JS whiz.

Should this patch go into 1.7b?

/be
It fixes serveral IE incompatabilities and cleans up the code, so it would be
great for 1.7b.  And shouldn't regress anything.
Get an sr, go for patch approval, fast.

/be
Flags: blocking1.7b+
Comment on attachment 141156 [details] [diff] [review]
Fixes neil's issues, also fixes some table width in marquee problems

>+      <handler event="DOMAttrModified" phase="target">

Unfortunately there is a performance penalty for using mutation events (we
don't bother firing the events at all if there are no mutation listeners).  I
can't really see another way to do what you're doing here though.  So see if
you can think of a different way to do this, but if not, don't worry about it. 
sr=me.
Attachment #141156 - Flags: superreview?(bryner) → superreview+
Since 1.7 is a long lived branch now - nominating.
Flags: blocking1.7?
Attachment #141156 - Flags: approval1.7?
Attachment #141156 - Flags: approval1.7? → approval1.7+
Checking in layout/html/document/src/xbl-marquee/resources/content/xbl-marquee.xml;
/cvsroot/mozilla/layout/html/document/src/xbl-marquee/resources/content/xbl-marquee.xml,v
 <--  xbl-marquee.xml
new revision: 1.8; previous revision: 1.7
done
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Attachment #135423 - Flags: review?(neil.parkwaycc.co.uk)
*** Bug 237314 has been marked as a duplicate of this bug. ***
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: