Closed Bug 188321 Opened 22 years ago Closed 6 years ago

Create a quick way to access unknown/custom CSS properties without using C++ to define them

Categories

(Core :: DOM: CSS Object Model, enhancement, P5)

enhancement

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: bkn3, Assigned: bkn3)

References

Details

User-Agent:       Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv:1.2a) Gecko/20020910
Build Identifier: Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv:1.2a) Gecko/20020910

Right now creating a new custom CSS property is a bit tedious, involving C++. 
Further, even if someone creates a custom property, it might not be appropriate
for merging into the central Mozilla tree, requiring the person to maintain
their own patch of the CSS system, which is a pain in the butt.  Further, we can
only expect the list of custom CSS properties to grow with time
(-moz-border-radius anyone?) as people heap on their favorite visual need
(gradient backgrounds! blinking borders!), which is a maintenance problem.

Some might argue that we don't need to be able to add custom CSS values, since
you can simply define custom DOM attributes, which is possible now.  However,
this is kinda nasty when you are trying to seperate things that are
semantic/content oriented (which is natural to XUL and XML), and things which
are visual layout oriented (which is natural for CSS).  So imagine that I have
an XBL widget bound to the tag <foobox>, and want to control some special
formatting on this widget using a new custom CSS tag "-moz-drop-shadow: true". 
Without custom CSS properties I would have to do <foobox drop-shadow="true">,
which mixes presentation with content, which is a Bad Thing (tm), and isn't that
the whole reason behind splitting XUL and CSS in the first place?

So, here's a quick possible solution to this problem:

I noticed that the CSSParser currently simply throws away an unknown CSS
Property and CSS Value if it is encountered.  However, imagine if we define a
new CSS struct, named UnknownCSSProperties, that is a hashmap.  When the
CSSParser encounters an unknown CSS Property, it simply throws it into this
struct.  Instead of trying to parse the custom CSS Value itself into one of the
known CSSValues (such as seeing that its a color, url, etc.), it would simply be
saved as a string.  Both the CSSProperty and the CSSValue would simply be
strings saved in the hashmap, such as:

-my-custom-property --> 300px
-foobar-property --> some_random_value

Now, we need to define a way to access these unknown values from the DOM, which
I don't have a good idea yet; its made harder by the fact that we don't have a
DOM name for these custom properties.  Perhaps these can be autogenerated by
mangling the CSS property name (such as removing all dashes and capitalizing or
something: -my-custom-property gets the DOM name myCustomProperty).  Does the
CSS 3 spec have anything to say about handling unknown CSS properties? 

However this is done, when the CSS Value is accessed through the DOM, all you
get is a string, so if the value were "300px" you would simply get a string with
the value "300px" (you have to parse it yourself in your javascript and figure
out what it means, removing the "px" and so forth).


Reproducible: Always

Steps to Reproduce:
1.
2.
3.
One fancy addition to this scheme would be to have the CSSParser actually see if
it can recognize the CSSValue given, and parse it into an URL, boolean, etc.
CSSValue; if it is unknown then it would be saved as a string.  This adds
complexity though and isn't really needed.
I asked Brad to report this, for discussion, so confirming and assigning back to
him.  The question is mainly for XBL widgets, which could use custom style
attributes.  This is (at least technically) not appropriate in the markup,
because it is a presentational attribute, for example:

an XBL widget to resize an image might desire a CSS attribute
xblresizer-maintain-aspect

Sounds like supporting this would be Very Hard (TM), and I don't know whether it
would be possible without hurting performance.
Assignee: jst → bkn3
Status: UNCONFIRMED → NEW
Ever confirmed: true
Whiteboard: [DUPEME]
Whiteboard: DUPEME

*** This bug has been marked as a duplicate of 35618 ***
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → DUPLICATE
This bug is not a duplicate of 35618, which concerns CSSUnknownRules; a
CSSUnknownRule is a rule that isn't a selector, a media import, etc. It would be
something like

&aWierdSymbol {}

This bug is about being able to have CSSDeclarations inside of a CSS Rule that
involve custom CSS properties: 

#myElement { -moz-custom-prop: 300px; }

This bug should be reopened.
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
> Both the CSSProperty and the CSSValue would simply be strings saved in the
> hashmap

Do these values and properties get cascaded?  If so, how?

Are they inherit or reset properties?  How do we tell?

> Now, we need to define a way to access these unknown values from the DOM

This part is simple, actually; use getPropertyValue instead of accessing it as a
property off the CSSDeclaration...

> Does the CSS 3 spec have anything to say about handling unknown CSS
> properties? 

Yes, it carefully describes how they get ignored, last I checked.
If we postulate that this is an extension of CSS solely for XBL, it might be
possible to apply the following rules:

1. properties using this mechanism must begin with xbl- (e.g.
xbl-imgresizer-maintain-aspect)

2. They always inherit.

3. They cascade using normal cascade rules.  The default value is ""
3b. If you ask for any property beginning "xbl-" and it is not anywhere in the
CSS cascade/inherit scheme, you get "".
Whiteboard: DUPEME
Are we postulating that?
I suppose that Brad should answer that, 'cause he reported the RFE, but I'm
arguing that this should be limited strictly to XBL styling:

"new/custom" style properties are useless unless something actually presents
them, and XBL is the only presenter I can imagine at the moment that would not
be able to define propertes in C++.

We shouldn't extend CSS unless there's a good reason, but I think that XBL
styling is a good reason.  There is currently no mechanism for an author to
provide presentational attributes to XBL, and CSS is the "right" layer.  And
"xbl-" properties would not seriously pollute the CSS namespace.
I agree that the usecase for this RFE is around XBL, so these custom CSS
properties should be preceded by "-xbl".  getPropertyValue is probably the best
way to access these values through the DOM.  You're right that the CSS spec says
to ignore unknown declarations; however, since we have extended CSS as a generic
way to style XML, it does make sense to genericize CSS a bit more so that we can
have custom CSS visual properties for our custom tags (through XBL).  Just for
simplicities sake these should all be reset properties rather than inherit ones;
that's probably the safest thing to assume.

What portions of the code need to be changed to handle these changes?  It seems
relatively minimal to me.
nsCSSParser, nsStyleStructList, nsStyleStruct, nsCSSDeclaration, nsRuleNode,
nsComputedDOMStyle.

Those should be all, I think...  The general docs on adding a new style property
explain the process..

I'd like to hear Ian and David's opinions on this, however.
p { -foo-bar: baz { quux }; }

I'm against doing this as described. If we want to do this we should do it in a
way that the extension requests a specific syntax, cascade, etc. Hyatt once
described such a system.
Ian, can you describe what Hyatt's system was?
Keywords: qawanted
*** Bug 293821 has been marked as a duplicate of this bug. ***
So I think the information that a caller needs to provide for a custom CSS property to get implemented correctly through existing APIs would be:
 * the name of the property (String)
 * whether the property is inherited (Boolean)
 * an initial value for the property (V_Spec)
 * a parse function (Input -> V_Spec or None)
 * a compute function (V_Spec * DOM Element -> V_Comp)
 * a function to serialize the specified value type (V_Spec -> String)
 * a function to serialize the computed value type (V_Comp -> String)
where V_Spec and V_Comp are arbitrary types, and Input is a type representing a way of accessing CSS token streams.

That's a pretty complex API, especially since CSS tokenization is not frozen.

V_Comp could in theory be String (thus removing the need for the second serialization function), although it might be nice to allow it not to be if there were an API for implementors to get to it.

In theory, we could simplify by merging the parse and compute functions, which would require the single function meet a bunch of constraints:
 * the function return the initial value when given a specific (perhaps empty) input
 * the function return a special value to indicate parse failure (at which point it would be called again with a different value, perhaps the magic one for initial)
 * it could return the computed value in string form (see above)

We could also simplify the API (although drastically reduce the chances that a property would be implemented correctly per spec -- essentially to zero) by giving the input in string form instead of as a token stream.  This would make the API easier to freeze, though.

With all these simplifications, we could be down to:
 * name of property (String)
 * inherited or not (Boolean)
 * parse + compute function (String * DOM Element -> String)

This probably is doable using an API in JS since we could arrange things so that the functions are only called in response to CSSOM API calls in JS.


However, propagating all the values of unknown properties through the system would be a good bit of work.
QA Contact: ian → general
QA Contact: general → style-system
Re-add qawanted if you need specific QA help here.
Keywords: qawanted
Priority: -- → P5
I'm going to call this WORKSFORME.  We have CSS Custom Properties, designed to work with Web Components, and at some point we'll have typed versions from the Properties & Values spec in bug 1273706.  XBL is going away so I don't think we need any mechanism specific to that.
Status: REOPENED → RESOLVED
Closed: 22 years ago6 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.