Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions org/w3c/css/atrules/css/AtRuleFontFeatureValues.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Author: Yves Lafon <ylafon@w3.org>
//
// (c) COPYRIGHT W3C, 2026
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.css.atrules.css;

import org.w3c.css.parser.AtRule;
import org.w3c.css.properties.css3.fontpalettevalues.CssFontFamily;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.InvalidParamException;
import org.w3c.css.values.CssExpression;
import org.w3c.css.values.CssValue;

/**
* @see CssFontFamily
*/
public class AtRuleFontFeatureValues extends AtRule {
CssValue target = null;

/**
* Create a new AtRuleFontFeatureValues
*/
public AtRuleFontFeatureValues() {
}

public AtRuleFontFeatureValues(CssValue target) {
this.target = target;
}

public void setTarget(ApplContext ac, CssExpression expression)
throws InvalidParamException {
// as it has the same syntax as @font-palette-values.font-family, let's reuse that


CssFontFamily fontFamily = null;
try {
fontFamily = new CssFontFamily(ac, expression);
} catch (InvalidParamException iex) {
throw new InvalidParamException("value",
expression.toStringFromStart(),
keyword(), ac);
}
this.target = fontFamily.value;
}

/**
* Returns the at rule keyword
*/
public String keyword() {
return "font-feature-values";
}

/**
* The second must be exactly the same of this one
*/
public boolean canApply(AtRule atRule) {
return (atRule instanceof AtRuleFontFeatureValues);
}

/**
* Return true if other is an instance of AtRUleFontFeatureValues
*/
public boolean equals(Object other) {
return (other instanceof AtRuleFontFeatureValues);
}

/**
* The second must only match this one
*/
public boolean canMatch(AtRule atRule) {
return (atRule instanceof AtRuleFontFeatureValues);
}

/**
* Returns a string representation of the object.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('@').append(keyword());
if (target != null) {
sb.append(' ').append(target.getType());
}
return sb.toString();
}

public boolean isEmpty() {
return false;
}

public boolean isPropertyLookupStrict() {
return true;
}
}
71 changes: 71 additions & 0 deletions org/w3c/css/atrules/css/AtRuleFontPaletteValues.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Author: Yves Lafon <ylafon@w3.org>
//
// (c) COPYRIGHT W3C, 2026
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.css.atrules.css;

import org.w3c.css.parser.AtRule;

public class AtRuleFontPaletteValues extends AtRule {
String name = null;

/**
* Create a new AtRuleFontPaletteValues
*/
public AtRuleFontPaletteValues() {
}

public AtRuleFontPaletteValues(String name) {
this.name = name;
}

/**
* Returns the at rule keyword
*/
public String keyword() {
return "font-palette-values";
}

/**
* The second must be exactly the same of this one
*/
public boolean canApply(AtRule atRule) {
return (atRule instanceof AtRuleFontPaletteValues);
}

/**
* Return true if other is an instance of AtRUleFontPaletteValues
*/
public boolean equals(Object other) {
return (other instanceof AtRuleFontPaletteValues);
}

/**
* The second must only match this one
*/
public boolean canMatch(AtRule atRule) {
return (atRule instanceof AtRuleFontPaletteValues);
}

/**
* Returns a string representation of the object.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('@').append(keyword());
if (name !=null ) {
sb.append(' ').append(name);
}
return sb.toString();
}

public void setName(String name) {
this.name = name;
}


public boolean isEmpty() {
return false;
}
}
38 changes: 32 additions & 6 deletions org/w3c/css/parser/CssPropertyFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,18 @@
*/
public class CssPropertyFactory implements Cloneable {

// TODO move to a Property set
private static final String[] NONSTANDARD_PROPERTIES = //
{ };
{};

private static boolean isNonstandardProperty(String property) {
private static boolean isNonstandardProperty(AtRule atrule, String property) {
if (property.charAt(0) == '-' || property.charAt(0) == '_') {
return true;
}
String prefix = atrule.lookupPrefix();
String prefixedProperty = ((prefix == null) || prefix.isEmpty()) ? property : "@" + prefix + '.' + property;
for (String s : NONSTANDARD_PROPERTIES) {
if (s.equals(property)) {
if (s.equals(prefixedProperty)) {
return true;
}
}
Expand Down Expand Up @@ -176,10 +179,11 @@ public synchronized CssProperty createProperty(ApplContext ac, AtRule atRule, St
String classname = null;
AtRuleMedia atRuleMedia;
String media = null;
boolean isCatchall = false;

// if the property name indicates a vendor extension, exit without checking
// if we need to raise only a warning.
if (ac.getTreatVendorExtensionsAsWarnings() && isVendorExtension(property)) {
if (ac.getTreatVendorExtensionsAsWarnings() && isVendorExtension(atRule, property)) {
throw new WarningParamException("vendor-extension", property);
}

Expand All @@ -198,6 +202,11 @@ public synchronized CssProperty createProperty(ApplContext ac, AtRule atRule, St
}
classname = setClassName(atRule, media, ac, property);

// special case for catchall in some rules
if (classname == null && atRule.isPropertyLookupStrict()) {
classname = getCatchallClass(atRule, media, ac, property);
isCatchall = (classname != null);
}
// the property does not exist in this profile
// this is an error... or a warning if it exists in another profile
if (classname == null) {
Expand Down Expand Up @@ -279,6 +288,13 @@ public synchronized CssProperty createProperty(ApplContext ac, AtRule atRule, St
CssProperty p = (CssProperty) constructor.newInstance(parameters);
p.value = cssIdent;
return p;
} else if (isCatchall) {
// create an instance of your property class
Class[] parametersType = {ac.getClass(), String.class, expression.getClass(), boolean.class};
Constructor constructor = Class.forName(classname).getConstructor(parametersType);
Object[] parameters = {ac, property, expression, Boolean.TRUE};
// invoke the constructor
return (CssProperty) constructor.newInstance(parameters);
} else {
// create an instance of your property class
Class[] parametersType = {ac.getClass(), expression.getClass(), boolean.class};
Expand All @@ -296,6 +312,13 @@ public synchronized CssProperty createProperty(ApplContext ac, AtRule atRule, St
}
}

private String getCatchallClass(AtRule atRule, String media, ApplContext ac, String property) {
// special case for catchall for some specific classes
java.lang.StringBuilder sb = new StringBuilder();
sb.append('@').append(atRule.keyword()).append('.').append("*catchall*");
return PropertiesLoader.getProfile(ac.getPropertyKey()).getProperty(sb.toString());
}

private String setClassName(AtRule atRule, String media, ApplContext ac, String property) {
String className;
String prefix = atRule.lookupPrefix();
Expand Down Expand Up @@ -357,7 +380,10 @@ private String findClosestPropertyName(AtRule atRule, ApplContext ac, String pro
return null;
}

private boolean isVendorExtension(String property) {
return property.length() > 0 && isNonstandardProperty(property);
private boolean isVendorExtension(AtRule atrule, String property) {
if (property == null || property.length() == 0) {
return false;
}
return isNonstandardProperty(atrule, property);
}
}
Loading
Loading