- From: John Daggett <jdaggett@mozilla.com>
- Date: Thu, 13 Sep 2012 00:46:31 -0700 (PDT)
- To: www-style list <www-style@w3.org>
I mentioned it briefly on the call yesterday but I wanted to bring up the issue of CSSFontFaceRule. This was originally defined in CSS2 OM spec as: interface CSSFontFaceRule : CSSRule { attribute CSSStyleDeclaration style; } The CSSStyleDeclaration interface [1] is the general getter/setter interface used for style rules: interface CSSStyleDeclaration { attribute DOMString cssText; DOMString getPropertyValue(in DOMString propertyName); CSSValue getPropertyCSSValue(in DOMString propertyName); DOMString removeProperty(in DOMString propertyName) DOMString getPropertyPriority(in DOMString propertyName); void setProperty(in DOMString propertyName, in DOMString value, in DOMString priority) readonly attribute unsigned long length; DOMString item(in unsigned long index); readonly attribute CSSRule parentRule; }; But CSS2 also defined the "extended" version of this, the CSS2Properties interface [2], that includes direct accessors for all style properties: interface CSS2Properties { attribute DOMString azimuth; attribute DOMString background; attribute DOMString backgroundAttachment; attribute DOMString backgroundColor; attribute DOMString backgroundImage; attribute DOMString backgroundPosition; attribute DOMString backgroundRepeat; attribute DOMString border; attribute DOMString borderCollapse; attribute DOMString borderColor; ... [ all style properties in CSS ] ... }; Implementations have typically combined the two, such that given a style rule, either style.fontFamily or style.getPropertyValue("font-family") will return the setting for 'font-family', if defined in the rule. In the context of @font-face rules, there's some crossover between the set of descriptors defined for @font-face rules and for style rules (e.g. "font-family", "font-weight", "font-style", etc.) but several of descriptors are unique to @font-face rules (e.g. "unicode-range", "src"). This makes use the CSSStyleDeclaration interface for @font-face rules very odd. There are also some subtle differences, the "font-family" descriptor for @font-face rules only takes a *single* name, not the list of multiple names allowed for the "font-family" property in style rules. I put together some tests that show some of the problems with using the CSSStyleDeclaration/CSS2Properties as a way to access descriptions in @font-face rules. http://people.mozilla.org/~jdaggett/tests/fontfacedom.html Details of the differences are included at the end of this post. I think it might make sense to define a new, simpler interface for accessing descriptors in @-rules and simply define CSSFontFactRule as an interface containing descriptors that implements that interface. [NoInterfaceObject] interface DescriptorAccess { DOMString GetDescriptorValue(DOMString descName); void SetDescriptorValue(DOMString descName, DOMString value); readonly attribute unsigned long length; DOMString item(unsigned long index); }; interface CSSFontFaceRule : CSSRule { // descriptors attribute DOMString fontFamily; attribute DOMString src; attribute DOMString fontWeight; attribute DOMString fontStyle; attribute DOMString fontStretch; attribute DOMString fontVariant; attribute DOMString fontFeatureSettings; attribute DOMString unicodeRange; // load state - whether the font is loaded or not readonly attribute boolean loaded; }; interface CSSFontFaceRule implements DescriptorAccess; If there's concern about the existing rule.style.xxx accessors, implementations could alias those to the properties above. Other rules, such as the @counter-style rule, could follow this model, rather than using CSSStyleDeclaration as a global property bucket. Thoughts? Regards, John Daggett Mozilla Japan [1] http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration [2] http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties OM access of @font-face rule details ================================================ While all the browsers that implement @font-face rules allow access to @font-face rules via this interface, the differences are striking and there are several very interesting bugs in current implementations. Tests: http://people.mozilla.org/~jdaggett/tests/fontfacedom.html Example 1: If 'rule' is a CSSFontFaceRule object, what should the code below do? rule.style.font = "bold italic 12px test57"; Both Webkit and IE9 parse this as a shorthand and set the relevant descriptors (e.g. "font-weight", "font-style") but also set "line-height" and "font-size" and it makes a mess of rule.style.cssText. Opera is smarter, the line above has no effect on the descriptor values. Firefox throws an error on all attempts to access rule.style.xxx in @font-face rules (I think Boris mentioned that the CSS2Properties isn't used with these, I haven't dug into the code just yet). Example 2: What should the code below do? rule.style.fontFamily = "test1, test2"; Here the problem is that only a single name is allowed for the "font-family" descriptor of @font-face rules. Here again, Webkit and IE accept it but Opera rejects it. Example 3: What should the call below return? var src = rule.style.getPropertyValue("src"); All implementations return the value of the "src" descriptor for the @font-face rule. Example 4: What should the value of the two variables below be? var ur1 = rule.style.src; var ur2 = rule.style.getPropertyValue("src"); In Webkit and Opera, both return the value of the "src" descriptor of the @font-face rule. Firefox returns 'undefined' for ur1 and the descriptor value for the second. IE9 returns 'undefined' for the first, a null string for the second. Example 5: Should the three values below be equal or not? var ur = el.style.unicodeRange; var unk = el.style.unknownProperty; For unknown properties, the result in both cases should be "undefined", since "unicode-range" is not a property associated with style rules. However, to make access to "unicode-range" available within @font-face rules, the Webkit implementation addds "unicodeRange" to the CSS2Properties struct which means that all elements expose access to this. IE9 and Firefox return "undefined" for both of these. Opera returns a null string for the first and "undefined" for the second.
Received on Thursday, 13 September 2012 07:47:03 UTC