Bug 7296 - JavaScript error not thrown when trying to set a CSS property to an invalid value
: JavaScript error not thrown when trying to set a CSS property to an invalid v...
Status: RESOLVED FIXED
: WebKit
CSS
: 417.x
: Macintosh Mac OS X 10.4
: P2 Normal
Assigned To:
:
:
:
:
  Show dependency treegraph
 
Reported: 2006-02-16 00:56 PST by
Modified: 2007-04-11 14:23 PST (History)


Attachments
Full page code (2.29 KB, application/xhtml+xml)
2006-02-16 00:57 PST, Giovanni Intini
no flags Details
proposed fix (13.83 KB, patch)
2006-12-16 14:08 PST, Alexey Proskuryakov
no flags Review Patch | Details | Formatted Diff | Diff
disable exceptions (7.37 KB, patch)
2006-12-24 02:03 PST, Alexey Proskuryakov
ggaren: review-
Review Patch | Details | Formatted Diff | Diff
without a Dashboard quirk (6.65 KB, patch)
2006-12-24 14:36 PST, Alexey Proskuryakov
ggaren: review+
Review Patch | Details | Formatted Diff | Diff


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2006-02-16 00:56:36 PST
The following two lines (full code attached) are used to dinamically change the position of a div:

67: innerDiv.style.top = top + (event.clientY - dragStartTop) + 'px';
68: innerDiv.style.left = left + (event.clientX - dragStartLeft);

Using an XHTML doctype the first line is correct while the 2nd one isn't because it's missing the + 'px' part. 

Safari doesn't work (as it should), but the javascript console doesn't return any error.
------- Comment #1 From 2006-02-16 00:57:08 PST -------
Created an attachment (id=6533) [details]
Full page code
------- Comment #2 From 2006-02-16 08:51:30 PST -------
I think this is known - a comment in the code says this problem cannot be fixed right away because that would cause backwards compatibility problems.
------- Comment #3 From 2006-02-16 12:27:17 PST -------
I should point out that it only seems to occur when the document is in "standards" mode.  In quirks mode, the value is parsed even without the "px" and everything proceeds.  In standards mode, the value is not parsed with the "px" and therefore the line has zero effect.  I'm not clear on how changing this would be a compatibility problem - on the same code Firefox raises a JavaScript exception when setting the property.
------- Comment #4 From 2006-02-16 12:35:42 PST -------
I have now found this comment, it's in DOMCSSStyleDeclaration::put(). FWIW:
// We have to ignore exceptions here, because of the following unfortunate situation:
//   1) Older versions ignored exceptions here by accident, because the put function
//      that translated exceptions did not translate CSS exceptions.
//   2) Gecko does not raise an exception in this case, although WinIE does.
//   3) At least some Dashboard widgets are depending on this behavior.
// It would be nice to fix this some day, perhaps with some kind of "quirks mode",
// but it's likely that the Dashboard widgets are already using a strict mode DOCTYPE.
------- Comment #5 From 2006-02-16 12:42:45 PST -------
Thanks for the clarification.  Breaking Dashboard widgets is a pretty big no-no, so that would be reason enough not to "fix" this.  Is there any easy way to log a "warning" in the JS console without throwing an exception?  Having code that mysteriously doesn't work with no message as to why can be very frustrating.
------- Comment #6 From 2006-02-16 13:05:51 PST -------
Looks like this is done with Frame::addMessageToConsole(). I think it is a great idea!
------- Comment #7 From 2006-12-16 14:08:25 PST -------
Created an attachment (id=11888) [details]
proposed fix

Now we do have a quirks mode for Dashboard!

The attached test now raises an exception even earlier than expected, that is, when trying to set the cursor:

innerDiv.style.cursor = "-moz-grab";

WinIE treats this as "url('-moz-grab')" and thus doesn't raise an exception. OTOH, Firefox ignores unknown cursor names. I'm going to file a followup bug for this.
------- Comment #8 From 2006-12-16 14:11:39 PST -------
See also bug 9687
------- Comment #9 From 2006-12-16 14:17:44 PST -------
(In reply to comment #7)
> OTOH, Firefox ignores unknown cursor names. 

More precisely, it treats such declarations as invalid, but it doesn't raise exceptions for invalid CSS anyway.
------- Comment #10 From 2006-12-19 07:42:09 PST -------
(From update of attachment 11888 [details])
The mechanics of the change look good. But the bug report has conflicting information about Firefox's behavior.

Generally, fixes that cause us to raise more exceptions have been problematic in the past -- it's one of the easiest ways to stop sites from working.

+      if (Document* doc = static_cast<CSSStyleSheet*>(styleDecl.stylesheet())->doc())

No need to nil-check the document. A document can have a nil frame, but a stylesheet can't have a nil document.

+            styleDecl.removeProperty(prop, exception);
+            if (!exception) {
+              ExceptionCode ec = 0;
+              styleDecl.setProperty(prop, propValue, ec);
+              return;
+            }

I think it's confusing here to have one variable named exception and another named ec. The difference is that the second one is ignored, and so perhaps its name should reflect that.

+    // When replacing an existing property value, this moves the property to the end of the list.
+    // Firefox preserves the position, and MSIE moves the property to the beginning.

Should we have a test case or bug report for this?

I'm going to say review+ even though I think this is risky for compatibility.
------- Comment #11 From 2006-12-19 11:20:20 PST -------
Committed revision 18320. Filed bug 11878 for cursors.

(In reply to comment #10)

> +      if (Document* doc =
> static_cast<CSSStyleSheet*>(styleDecl.stylesheet())->doc())
> 
> No need to nil-check the document. A document can have a nil frame, but a
> stylesheet can't have a nil document.

Fixed.

> I think it's confusing here to have one variable named exception and another
> named ec. The difference is that the second one is ignored, and so perhaps its
> name should reflect that.

OK.

> +    // When replacing an existing property value, this moves the property to
> the end of the list.
> +    // Firefox preserves the position, and MSIE moves the property to the
> beginning.
> 
> Should we have a test case or bug report for this?

The modified fast/dom/css-set-property-exception.html test will at least catch changes in behavior. I don't think there's anything for us to fix, since the behavior is unspecified, and other browsers behave inconsistently.
------- Comment #12 From 2006-12-21 00:32:11 PST -------
Hyatt and I think this change was a bad idea.

1. Small gain. It doesn't improve performance or compatibility.

2. It's a ticking compatibilty timebomb. IE6 is pretty lenient with invalid CSS values. It doesn't throw when setting to null, for example. Throwing an exception completely destroys a site / widget / app.

3. Dashboard quirks should be a last resort. There's no way for an author to turn them off, and they create a confusing gap between widgets and real web technology.

4. The proof is in the pudding: this change broke our very own Web Inspector and JavaScript debugger!
------- Comment #13 From 2006-12-21 00:38:10 PST -------
For reference, bug 11888 covers the inspector/debugger breakage and includes a proposed patch which treats null as valid to allow its use in resetting a property to its initial value.  Of course, the patch is moot if this change gets reverted.
------- Comment #14 From 2006-12-21 01:26:13 PST -------
(In reply to comment #12)
> IE6 is pretty lenient with invalid CSS values. 
> It doesn't throw when setting to null, for example. 

  Interesting - in my tests, it does! See fast/dom/css-set-property-exception.html .

> 4. The proof is in the pudding: this change broke our very own Web Inspector
> and JavaScript debugger!

  Well, this sort of thing aways happens to code that was only tested in one browser. Thankfully, there isn't that much code that has only been tested with WebKit ;)

  One thing I want to point out is that this patch shouldn't be just reverted if it's decided that exceptions shouldn't be thrown. Besides enabling exceptions, it corrected the behavior is error case. 
------- Comment #15 From 2006-12-21 17:24:28 PST -------
>   Interesting - in my tests, it does! See
> fast/dom/css-set-property-exception.html .

I can see that IE throws in your test. But it doesn't throw for, e.g., div.style.width = null. And FF, whose code path we usually take on websites, never throws.

Can we just report the error in the console instead of throwing an exception? Generally, throwing an exception for bad CSS seems completely contrary to CSS, whose goal is gracefully to ignore unsupported syntax.

Also, I think this might be a bug:

+      if (Document* doc = static_cast<CSSStyleSheet*>(styleDecl.stylesheet())->doc())
+        if (Frame* frame = doc->frame())
+          if (frame->settings()->shouldUseDashboardBackwardCompatibilityMode()) {
+            styleDecl.removeProperty(prop, exception);
+            if (!exception) {
+              ExceptionCode ec = 0;
+              styleDecl.setProperty(prop, propValue, ec);
+              return;
+            }
+          }
+      styleDecl.setProperty(prop, propValue, exception);

If removeProperty throws an exception, this code will call setProperty, even though there's a branch that attempts to prevent that. I think the second call to setProperty needs to be in an 'else' clause.
------- Comment #16 From 2006-12-21 21:52:03 PST -------
(In reply to comment #15)
> I can see that IE throws in your test. But it doesn't throw for, e.g.,
> div.style.width = null. And FF, whose code path we usually take on websites,
> never throws.

  I've now added a special case for null, see bug 11919. Please note that previously, that didn't behave correctly in all cases anyway (because null was converted to "null"), and no one seemed to care :)

> Can we just report the error in the console instead of throwing an exception?
> Generally, throwing an exception for bad CSS seems completely contrary to CSS,
> whose goal is gracefully to ignore unsupported syntax.

  Of course we can! I just think it's humiliating not to be standards-compliant in an area where IE is compliant. Hiding mistakes in general may be good for compatibility in short term, but has a bunch of its own negative consequences.

  Your argument #2 (IE6 is pretty lenient with invalid CSS values) does make me rather nervous indeed, but maybe we should wait for a few compatibility problems before freaking out?

> Also, I think this might be a bug:

  Oops! I think "return" in Dashboard case should be moved down a bit.
------- Comment #17 From 2006-12-22 15:00:16 PST -------
>   I've now added a special case for null, see bug 11919.

Thanks!

>  Please note that previously, that didn't behave correctly in all cases anyway (because null was
> converted to "null"), and no one seemed to care :)

Sure, and that's great. My concern is limited to exceptions.

>   Of course we can! I just think it's humiliating not to be standards-compliant
> in an area where IE is compliant. Hiding mistakes in general may be good for
> compatibility in short term, but has a bunch of its own negative consequences.

I have mixed feelings about this. Standards help developers understand how a browser will behave. But this standard seems like more trouble than it's worth. CSS is meant to grow and change. If I develop CSS for a modern Safari, and it throws exceptions in an older Safari, I'm an unhappy developer.

>   Your argument #2 (IE6 is pretty lenient with invalid CSS values) does make me
> rather nervous indeed, but maybe we should wait for a few compatibility
> problems before freaking out?

OK, let's see how things turn out. Bug 11936 is our first.
------- Comment #18 From 2006-12-22 23:12:27 PST -------
(In reply to comment #17)

> But this standard seems like more trouble than it's worth.
> CSS is meant to grow and change.
<...>
> OK, let's see how things turn out. Bug 11936 is our first.

If we count bug 11878 (Mozilla cursors), it's already the second...

I guess I'm convinced now.
------- Comment #19 From 2006-12-23 00:48:30 PST -------
I wonder if we could honor the spirit of the spec by return false or an exception object from setProperty when parsing failed, without actually throwing an exception. The spec says that setProperty should have a void return value, so it would be a neat augmentation.
------- Comment #20 From 2006-12-24 02:03:14 PST -------
Created an attachment (id=11992) [details]
disable exceptions

This doesn't implement logging (tracked as bug 9687).
------- Comment #21 From 2006-12-24 13:54:30 PST -------
(From update of attachment 11992 [details])
I spoke with ap about this. He's going to remove the Dashboard quirk. We'd rather not have them unless we know they're needed.
------- Comment #22 From 2006-12-24 14:36:57 PST -------
Created an attachment (id=12010) [details]
without a Dashboard quirk

We're ending up with throwing less than before - in shipping Safari, setProperty was allowed to throw exceptions.
------- Comment #23 From 2006-12-27 13:51:07 PST -------
Does bug 11993 mean that we need the quirk afterall?
------- Comment #24 From 2006-12-27 22:34:50 PST -------
(From update of attachment 12010 [details])
I'm going to wait and let Geoff review this.
------- Comment #25 From 2006-12-28 09:52:43 PST -------
(In reply to comment #23)
> Does bug 11993 mean that we need the quirk afterall?

I don't think so! Alexey's basically saying we're going in the opposite direction -- we're going to throw exceptions even *less* than before, so bugs like that one will go away.
------- Comment #26 From 2006-12-28 09:58:43 PST -------
(From update of attachment 12010 [details])
ChangeLog is misleading since it mentions a Dashboard quirk and the patch has none.

In the case where the value is not parsable, the old code removes the property. But the new code does nothing. Is that change OK for Dashboard widgets? I'm not sure it is.
------- Comment #27 From 2006-12-28 10:09:13 PST -------
(In reply to comment #26)
> In the case where the value is not parsable, the old code removes the property.
> But the new code does nothing. Is that change OK for Dashboard widgets? I'm not
> sure it is.

I believe that's what Geoff is asking about in comment 23. I don't have an answer myself.
------- Comment #28 From 2006-12-28 15:29:15 PST -------
(From update of attachment 11888 [details])
Clearing darin's r+ on attachment 11888 [details] so this doesn't show up in the commit queue.
------- Comment #29 From 2007-01-03 20:51:59 PST -------
It would be great to see some progress with Alexey's patch.  The original change in r18320 has caused quite a serious regression at mapquest.com (bug 11936) which I will need to roll out in the near future unless it is addressed.

It looks like the sticking point on the latest patch is the whether the property should be removed or left untouched when the value is not parseable?  For compatibility, I would suggest it should be removed as we  did prior to r18320.
------- Comment #30 From 2007-01-03 21:07:37 PST -------
(From update of attachment 12010 [details])
I like the change to move this into the DOM!

I think Darin is right, though: We need to maintain the old behavior of unconditionally removing the property, then setting it only if it parses correctly.
------- Comment #31 From 2007-01-04 01:12:24 PST -------
(In reply to comment #30)
> I think Darin is right, though: We need to maintain the old behavior of
> unconditionally removing the property, then setting it only if it parses
> correctly.

Then the previous version of the patch is what you want, right?
------- Comment #32 From 2007-01-04 23:09:58 PST -------
(From update of attachment 12010 [details])
I'm going to approve this patch.

ap mentioned on IRC that neither IE nor Firefox deletes the property when it fails to parse, so I think this is a compatibilty improvement. Let's not add a Dashboard quirk until it proves necessary.

Please remember to do these things before landing:
- Remove mention of the quirk from the ChangeLog
- Change to ASSERT(!ec), to match our style guidelines
- Add a test the verifies that a syntax error does not remove the previous property (i don't think that was covered by the original patch)
------- Comment #33 From 2007-01-05 08:33:09 PST -------
Committed revision 18618.

(In reply to comment #32)
> - Remove mention of the quirk from the ChangeLog

  Done.

> - Change to ASSERT(!ec), to match our style guidelines

  Done.

> - Add a test the verifies that a syntax error does not remove the previous
> property (i don't think that was covered by the original patch)

  Actually, it is already covered - the test dumps complete cssText after assignment.
------- Comment #34 From 2007-04-11 14:23:11 PST -------
Some fallout:

<rdar://problem/5111539> -- an Apple internal website relying on WebKit's old behavior, using an unparseable style rule to clear a style.

<rdar://problem/5011784> -- a WebKit app using undefined to clear a style rule.