org.htmlunit.javascript.host.css.CSSStyleDeclaration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xlt Show documentation
Show all versions of xlt Show documentation
XLT (Xceptance LoadTest) is an extensive load and performance test tool developed and maintained by Xceptance.
/*
* Copyright (c) 2002-2023 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.htmlunit.javascript.host.css;
import static org.htmlunit.BrowserVersionFeatures.CSS_BACKGROUND_INITIAL;
import static org.htmlunit.BrowserVersionFeatures.CSS_BACKGROUND_RGBA;
import static org.htmlunit.BrowserVersionFeatures.CSS_LENGTH_INITIAL;
import static org.htmlunit.BrowserVersionFeatures.CSS_OUTLINE_WIDTH_UNIT_NOT_REQUIRED;
import static org.htmlunit.BrowserVersionFeatures.CSS_VERTICAL_ALIGN_SUPPORTS_AUTO;
import static org.htmlunit.BrowserVersionFeatures.CSS_ZINDEX_TYPE_INTEGER;
import static org.htmlunit.BrowserVersionFeatures.JS_STYLE_UNSUPPORTED_PROPERTY_GETTER;
import static org.htmlunit.BrowserVersionFeatures.JS_STYLE_WORD_SPACING_ACCEPTS_PERCENT;
import static org.htmlunit.BrowserVersionFeatures.JS_STYLE_WRONG_INDEX_RETURNS_UNDEFINED;
import static org.htmlunit.css.CssStyleSheet.ABSOLUTE;
import static org.htmlunit.css.CssStyleSheet.AUTO;
import static org.htmlunit.css.CssStyleSheet.FIXED;
import static org.htmlunit.css.CssStyleSheet.INHERIT;
import static org.htmlunit.css.CssStyleSheet.INITIAL;
import static org.htmlunit.css.CssStyleSheet.NONE;
import static org.htmlunit.css.CssStyleSheet.RELATIVE;
import static org.htmlunit.css.CssStyleSheet.REPEAT;
import static org.htmlunit.css.CssStyleSheet.STATIC;
import static org.htmlunit.css.StyleAttributes.Definition.ACCELERATOR;
import static org.htmlunit.css.StyleAttributes.Definition.BACKGROUND;
import static org.htmlunit.css.StyleAttributes.Definition.BACKGROUND_ATTACHMENT;
import static org.htmlunit.css.StyleAttributes.Definition.BACKGROUND_COLOR;
import static org.htmlunit.css.StyleAttributes.Definition.BACKGROUND_IMAGE;
import static org.htmlunit.css.StyleAttributes.Definition.BACKGROUND_POSITION;
import static org.htmlunit.css.StyleAttributes.Definition.BACKGROUND_REPEAT;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_BOTTOM;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_BOTTOM_COLOR;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_BOTTOM_STYLE;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_BOTTOM_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_LEFT;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_LEFT_COLOR;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_LEFT_STYLE;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_LEFT_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_RIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_RIGHT_COLOR;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_RIGHT_STYLE;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_RIGHT_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_TOP;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_TOP_COLOR;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_TOP_STYLE;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_TOP_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.BORDER_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.BOTTOM;
import static org.htmlunit.css.StyleAttributes.Definition.COLOR;
import static org.htmlunit.css.StyleAttributes.Definition.DISPLAY;
import static org.htmlunit.css.StyleAttributes.Definition.FLOAT;
import static org.htmlunit.css.StyleAttributes.Definition.FONT;
import static org.htmlunit.css.StyleAttributes.Definition.FONT_FAMILY;
import static org.htmlunit.css.StyleAttributes.Definition.FONT_SIZE;
import static org.htmlunit.css.StyleAttributes.Definition.HEIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.LEFT;
import static org.htmlunit.css.StyleAttributes.Definition.LETTER_SPACING;
import static org.htmlunit.css.StyleAttributes.Definition.LINE_HEIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.MARGIN;
import static org.htmlunit.css.StyleAttributes.Definition.MARGIN_BOTTOM;
import static org.htmlunit.css.StyleAttributes.Definition.MARGIN_LEFT;
import static org.htmlunit.css.StyleAttributes.Definition.MARGIN_RIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.MARGIN_TOP;
import static org.htmlunit.css.StyleAttributes.Definition.MAX_HEIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.MAX_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.MIN_HEIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.MIN_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.OPACITY;
import static org.htmlunit.css.StyleAttributes.Definition.ORPHANS;
import static org.htmlunit.css.StyleAttributes.Definition.OUTLINE;
import static org.htmlunit.css.StyleAttributes.Definition.OUTLINE_WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.PADDING;
import static org.htmlunit.css.StyleAttributes.Definition.PADDING_BOTTOM;
import static org.htmlunit.css.StyleAttributes.Definition.PADDING_LEFT;
import static org.htmlunit.css.StyleAttributes.Definition.PADDING_RIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.PADDING_TOP;
import static org.htmlunit.css.StyleAttributes.Definition.POSITION;
import static org.htmlunit.css.StyleAttributes.Definition.RIGHT;
import static org.htmlunit.css.StyleAttributes.Definition.RUBY_ALIGN;
import static org.htmlunit.css.StyleAttributes.Definition.SIZE;
import static org.htmlunit.css.StyleAttributes.Definition.TEXT_INDENT;
import static org.htmlunit.css.StyleAttributes.Definition.TOP;
import static org.htmlunit.css.StyleAttributes.Definition.VERTICAL_ALIGN;
import static org.htmlunit.css.StyleAttributes.Definition.WIDOWS;
import static org.htmlunit.css.StyleAttributes.Definition.WIDTH;
import static org.htmlunit.css.StyleAttributes.Definition.WORD_SPACING;
import static org.htmlunit.css.StyleAttributes.Definition.Z_INDEX_;
import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
import static org.htmlunit.javascript.configuration.SupportedBrowser.IE;
import static org.apache.commons.lang3.StringUtils.defaultIfEmpty;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.htmlunit.cssparser.dom.AbstractCSSRuleImpl;
import org.htmlunit.BrowserVersion;
import org.htmlunit.css.AbstractCssStyleDeclaration;
import org.htmlunit.css.ComputedCssStyleDeclaration;
import org.htmlunit.css.CssPixelValueConverter;
import org.htmlunit.css.ElementCssStyleDeclaration;
import org.htmlunit.css.StyleAttributes;
import org.htmlunit.css.StyleAttributes.Definition;
import org.htmlunit.css.StyleElement;
import org.htmlunit.css.WrappedCssStyleDeclaration;
import org.htmlunit.html.DomElement;
import org.htmlunit.html.impl.Color;
import org.htmlunit.javascript.HtmlUnitScriptable;
import org.htmlunit.javascript.configuration.JsxClass;
import org.htmlunit.javascript.configuration.JsxConstructor;
import org.htmlunit.javascript.configuration.JsxFunction;
import org.htmlunit.javascript.configuration.JsxGetter;
import org.htmlunit.javascript.configuration.JsxSetter;
import org.htmlunit.javascript.host.Element;
import org.htmlunit.corejs.javascript.Context;
import org.htmlunit.corejs.javascript.ScriptRuntime;
import org.htmlunit.corejs.javascript.Scriptable;
import org.htmlunit.corejs.javascript.ScriptableObject;
import org.htmlunit.corejs.javascript.Undefined;
/**
* A JavaScript object for {@code CSSStyleDeclaration}.
*
* @author Mike Bowler
* @author Christian Sell
* @author Daniel Gredler
* @author Chris Erskine
* @author Ahmed Ashour
* @author Rodney Gitzel
* @author Sudhan Moghe
* @author Ronald Brill
* @author Frank Danek
* @author Dennis Duysak
* @see MDN doc
*/
@JsxClass
public class CSSStyleDeclaration extends HtmlUnitScriptable {
private static final Pattern URL_PATTERN =
Pattern.compile("url\\(\\s*[\"']?(.*?)[\"']?\\s*\\)");
private static final Pattern POSITION_PATTERN =
Pattern.compile("(\\d+\\s*(%|px|cm|mm|in|pt|pc|em|ex))\\s*"
+ "(\\d+\\s*(%|px|cm|mm|in|pt|pc|em|ex)|top|bottom|center)");
private static final Pattern POSITION_PATTERN2 =
Pattern.compile("(left|right|center)\\s*(\\d+\\s*(%|px|cm|mm|in|pt|pc|em|ex)|top|bottom|center)");
private static final Pattern POSITION_PATTERN3 =
Pattern.compile("(top|bottom|center)\\s*(\\d+\\s*(%|px|cm|mm|in|pt|pc|em|ex)|left|right|center)");
private static final Set LENGTH_PROPERTIES_FFFF = new HashSet<>(Arrays.asList(
BORDER_TOP_WIDTH.getAttributeName(),
BORDER_LEFT_WIDTH.getAttributeName(),
BORDER_BOTTOM_WIDTH.getAttributeName(),
BORDER_RIGHT_WIDTH.getAttributeName(),
LETTER_SPACING.getAttributeName()));
private static final Set LENGTH_PROPERTIES_TTFF = new HashSet<>(Arrays.asList(
HEIGHT.getAttributeName(),
WIDTH.getAttributeName(),
TOP.getAttributeName(),
LEFT.getAttributeName(),
BOTTOM.getAttributeName(),
RIGHT.getAttributeName(),
MARGIN_TOP.getAttributeName(),
MARGIN_LEFT.getAttributeName(),
MARGIN_BOTTOM.getAttributeName(),
MARGIN_RIGHT.getAttributeName(),
MIN_HEIGHT.getAttributeName(),
MIN_WIDTH.getAttributeName()
));
private static final Set LENGTH_PROPERTIES_FTFF = new HashSet<>(Arrays.asList(
FONT_SIZE.getAttributeName(),
TEXT_INDENT.getAttributeName(),
PADDING_TOP.getAttributeName(),
PADDING_LEFT.getAttributeName(),
PADDING_BOTTOM.getAttributeName(),
PADDING_RIGHT.getAttributeName(),
MAX_HEIGHT.getAttributeName(),
MAX_WIDTH.getAttributeName()
));
private static final String[] THIN_MED_THICK = {"thin", "medium", "thick"};
private static final String[] ALIGN_KEYWORDS =
{"baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom",
"inherit", "initial", "revert", "unset"};
// private static final Log LOG = LogFactory.getLog(CSSStyleDeclaration.class);
private static final Map CSSColors_ = new HashMap<>();
/** The wrapped CSSStyleDeclaration */
private AbstractCssStyleDeclaration styleDeclaration_;
static {
CSSColors_.put("aqua", "rgb(0, 255, 255)");
CSSColors_.put("black", "rgb(0, 0, 0)");
CSSColors_.put("blue", "rgb(0, 0, 255)");
CSSColors_.put("fuchsia", "rgb(255, 0, 255)");
CSSColors_.put("gray", "rgb(128, 128, 128)");
CSSColors_.put("green", "rgb(0, 128, 0)");
CSSColors_.put("lime", "rgb(0, 255, 0)");
CSSColors_.put("maroon", "rgb(128, 0, 0)");
CSSColors_.put("navy", "rgb(0, 0, 128)");
CSSColors_.put("olive", "rgb(128, 128, 0)");
CSSColors_.put("purple", "rgb(128, 0, 128)");
CSSColors_.put("red", "rgb(255, 0, 0)");
CSSColors_.put("silver", "rgb(192, 192, 192)");
CSSColors_.put("teal", "rgb(0, 128, 128)");
CSSColors_.put("white", "rgb(255, 255, 255)");
CSSColors_.put("yellow", "rgb(255, 255, 0)");
}
/**
* Creates an instance.
*/
public CSSStyleDeclaration() {
}
/**
* JavaScript constructor.
*
* @param type the event type
* @param details the event details (optional)
*/
@JsxConstructor({CHROME, EDGE, FF, FF_ESR})
public void jsConstructor(final String type, final ScriptableObject details) {
throw ScriptRuntime.typeError("CSSStyleDeclaration ctor is not available");
}
/**
* Creates an instance and sets its parent scope to the one of the provided element.
* @param element the element to which this style is bound
* @param styleDeclaration the style declaration to be based on
*/
public CSSStyleDeclaration(final Element element, final AbstractCssStyleDeclaration styleDeclaration) {
setParentScope(element.getParentScope());
setPrototype(getPrototype(getClass()));
setDomNode(element.getDomNodeOrNull(), false);
styleDeclaration_ = styleDeclaration;
}
/**
* Creates an instance which wraps the specified style declaration.
* @param parentStyleSheet the parent {@link CSSStyleSheet} to use
* @param styleDeclaration the style declaration to wrap
*/
CSSStyleDeclaration(final CSSStyleSheet parentStyleSheet, final WrappedCssStyleDeclaration styleDeclaration) {
setParentScope(parentStyleSheet);
setPrototype(getPrototype(getClass()));
styleDeclaration_ = styleDeclaration;
}
protected AbstractCssStyleDeclaration getCssStyleDeclaration() {
return styleDeclaration_;
}
/**
* IE makes unknown style properties accessible.
* @param name the name of the requested property
* @return the object value, {@link #NOT_FOUND} if nothing is found
*/
@Override
protected Object getWithPreemption(final String name) {
if (getBrowserVersion().hasFeature(JS_STYLE_UNSUPPORTED_PROPERTY_GETTER)
&& (styleDeclaration_ instanceof ElementCssStyleDeclaration
|| styleDeclaration_ instanceof ComputedCssStyleDeclaration)) {
final StyleElement element = styleDeclaration_.getStyleElement(name);
if (element != null && element.getValue() != null) {
return element.getValue();
}
}
return NOT_FOUND;
}
/**
* Returns the element to which this style belongs.
* @return the element to which this style belongs
*/
protected Element getElement() {
if (styleDeclaration_ == null) {
return null;
}
return styleDeclaration_.getElementOrNull();
}
/**
* @return the dom element to which this style belongs
*/
protected DomElement getDomElement() {
if (styleDeclaration_ == null) {
return null;
}
return styleDeclaration_.getDomElementOrNull();
}
/**
* Returns the priority of the named style attribute, or an empty string if it is not found.
*
* @param name the name of the style attribute whose value is to be retrieved
* @return the named style attribute value, or an empty string if it is not found
*/
protected String getStylePriority(final String name) {
if (styleDeclaration_ == null) {
return null;
}
return styleDeclaration_.getStylePriority(name);
}
/**
* Determines the StyleElement for the given name.
* This ignores the case of the name.
*
* @param name the name of the requested StyleElement
* @return the StyleElement or null if not found
*/
private StyleElement getStyleElementCaseInSensitive(final String name) {
if (styleDeclaration_ == null) {
return null;
}
return styleDeclaration_.getStyleElementCaseInSensitive(name);
}
/**
* Sets the specified style attribute.
* @param name the attribute name (camel-cased)
* @param newValue the attribute value
*/
protected void setStyleAttribute(final String name, final String newValue) {
setStyleAttribute(name, newValue, "");
}
/**
* Sets the specified style attribute.
* @param name the attribute name (camel-cased)
* @param newValue the attribute value
* @param important important value
*/
protected void setStyleAttribute(final String name, String newValue, final String important) {
if (null == newValue || "null".equals(newValue)) {
newValue = "";
}
styleDeclaration_.setStyleAttribute(name, newValue, important);
}
/**
* Removes the specified style attribute, returning the value of the removed attribute.
* @param name the attribute name (delimiter-separated, not camel-cased)
*/
private String removeStyleAttribute(final String name) {
if (styleDeclaration_ == null) {
return null;
}
return styleDeclaration_.removeStyleAttribute(name);
}
/**
* Returns a sorted map containing style elements, keyed on style element name. We use a
* {@link LinkedHashMap} map so that results are deterministic and are thus testable.
*
* @return a sorted map containing style elements, keyed on style element name
*/
private Map getStyleMap() {
if (styleDeclaration_ == null) {
return Collections.emptyMap();
}
return styleDeclaration_.getStyleMap();
}
/**
* Gets the {@code accelerator} style attribute.
* @return the style attribute
*/
@JsxGetter(IE)
public String getAccelerator() {
return defaultIfEmpty(getStyleAttribute(ACCELERATOR), "false");
}
/**
* Sets the {@code accelerator} style attribute.
* @param accelerator the new attribute
*/
@JsxSetter(IE)
public void setAccelerator(final String accelerator) {
setStyleAttribute(ACCELERATOR.getAttributeName(), accelerator);
}
/**
* Gets the {@code backgroundAttachment} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBackgroundAttachment() {
String value = getStyleAttribute(BACKGROUND_ATTACHMENT, false);
if (StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(BACKGROUND);
if (StringUtils.isNotBlank(bg)) {
value = findAttachment(bg);
if (value == null) {
if (getBrowserVersion().hasFeature(CSS_BACKGROUND_INITIAL)
&& getClass() == CSSStyleDeclaration.class) {
return INITIAL;
}
return "scroll"; // default if shorthand is used
}
return value;
}
return "";
}
return value;
}
/**
* Sets the {@code backgroundAttachment} style attribute.
* @param backgroundAttachment the new attribute
*/
@JsxSetter
public void setBackgroundAttachment(final String backgroundAttachment) {
setStyleAttribute(BACKGROUND_ATTACHMENT.getAttributeName(), backgroundAttachment);
}
/**
* Gets the {@code backgroundColor} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBackgroundColor() {
String value = getStyleAttribute(BACKGROUND_COLOR, false);
if (StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(BACKGROUND, false);
if (StringUtils.isBlank(bg)) {
return "";
}
value = findColor(bg);
if (value == null) {
if (getBrowserVersion().hasFeature(CSS_BACKGROUND_INITIAL)) {
if (getClass() == CSSStyleDeclaration.class) {
return INITIAL;
}
return "rgba(0, 0, 0, 0)";
}
if (getBrowserVersion().hasFeature(CSS_BACKGROUND_RGBA)) {
return "rgba(0, 0, 0, 0)";
}
return "transparent"; // default if shorthand is used
}
return value;
}
if (StringUtils.isBlank(value)) {
return "";
}
return value;
}
/**
* Sets the {@code backgroundColor} style attribute.
* @param backgroundColor the new attribute
*/
@JsxSetter
public void setBackgroundColor(final String backgroundColor) {
setStyleAttribute(BACKGROUND_COLOR.getAttributeName(), backgroundColor);
}
/**
* Gets the {@code backgroundImage} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBackgroundImage() {
String value = getStyleAttribute(BACKGROUND_IMAGE, false);
if (StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(BACKGROUND, false);
if (StringUtils.isNotBlank(bg)) {
value = findImageUrl(bg);
final boolean isComputed = getClass() != CSSStyleDeclaration.class;
final boolean backgroundInitial = getBrowserVersion().hasFeature(CSS_BACKGROUND_INITIAL);
if (value == null) {
return backgroundInitial && !isComputed ? INITIAL : NONE;
}
if (isComputed) {
try {
value = value.substring(5, value.length() - 2);
return "url(\"" + getDomElement().getHtmlPageOrNull()
.getFullyQualifiedUrl(value) + "\")";
}
catch (final Exception e) {
// ignore
}
}
return value;
}
return "";
}
return value;
}
/**
* Sets the {@code backgroundImage} style attribute.
* @param backgroundImage the new attribute
*/
@JsxSetter
public void setBackgroundImage(final String backgroundImage) {
setStyleAttribute(BACKGROUND_IMAGE.getAttributeName(), backgroundImage);
}
/**
* Gets the {@code backgroundPosition} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBackgroundPosition() {
String value = getStyleAttribute(BACKGROUND_POSITION, false);
if (value == null) {
return null;
}
if (StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(BACKGROUND, false);
if (bg == null) {
return null;
}
if (StringUtils.isNotBlank(bg)) {
value = findPosition(bg);
final boolean isInitial = getBrowserVersion().hasFeature(CSS_BACKGROUND_INITIAL);
final boolean isComputed = getClass() != CSSStyleDeclaration.class;
if (value == null) {
if (isInitial) {
return isComputed ? "" : INITIAL;
}
return "0% 0%";
}
if (getBrowserVersion().hasFeature(CSS_ZINDEX_TYPE_INTEGER)) {
final String[] values = value.split(" ");
if ("center".equals(values[0])) {
values[0] = "";
}
if ("center".equals(values[1])) {
values[1] = "";
}
if (!isComputed || value.contains("top")) {
return (values[0] + ' ' + values[1]).trim();
}
}
if (isComputed) {
final String[] values = value.split(" ");
switch (values[0]) {
case "left":
values[0] = "0%";
break;
case "center":
values[0] = "50%";
break;
case "right":
values[0] = "100%";
break;
default:
}
switch (values[1]) {
case "top":
values[1] = "0%";
break;
case "center":
values[1] = "50%";
break;
case "bottom":
values[1] = "100%";
break;
default:
}
value = values[0] + ' ' + values[1];
}
return value;
}
return "";
}
return value;
}
/**
* Sets the {@code backgroundPosition} style attribute.
* @param backgroundPosition the new attribute
*/
@JsxSetter
public void setBackgroundPosition(final String backgroundPosition) {
setStyleAttribute(BACKGROUND_POSITION.getAttributeName(), backgroundPosition);
}
/**
* Gets the {@code backgroundRepeat} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBackgroundRepeat() {
String value = getStyleAttribute(BACKGROUND_REPEAT, false);
if (StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(BACKGROUND, false);
if (StringUtils.isNotBlank(bg)) {
value = findRepeat(bg);
if (value == null) {
if (getBrowserVersion().hasFeature(CSS_BACKGROUND_INITIAL)
&& getClass() == CSSStyleDeclaration.class) {
return INITIAL;
}
return REPEAT; // default if shorthand is used
}
return value;
}
return "";
}
return value;
}
/**
* Sets the {@code backgroundRepeat} style attribute.
* @param backgroundRepeat the new attribute
*/
@JsxSetter
public void setBackgroundRepeat(final String backgroundRepeat) {
setStyleAttribute(BACKGROUND_REPEAT.getAttributeName(), backgroundRepeat);
}
/**
* Gets the {@code borderBottomColor} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderBottomColor() {
String value = getStyleAttribute(BORDER_BOTTOM_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(BORDER_BOTTOM, false));
if (value == null) {
value = findColor(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderBottomColor} style attribute.
* @param borderBottomColor the new attribute
*/
@JsxSetter
public void setBorderBottomColor(final String borderBottomColor) {
setStyleAttribute(BORDER_BOTTOM_COLOR.getAttributeName(), borderBottomColor);
}
/**
* Gets the {@code borderBottomStyle} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderBottomStyle() {
String value = getStyleAttribute(BORDER_BOTTOM_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(BORDER_BOTTOM, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderBottomStyle} style attribute.
* @param borderBottomStyle the new attribute
*/
@JsxSetter
public void setBorderBottomStyle(final String borderBottomStyle) {
setStyleAttribute(BORDER_BOTTOM_STYLE.getAttributeName(), borderBottomStyle);
}
/**
* Gets the {@code borderBottomWidth} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderBottomWidth() {
return getBorderWidth(BORDER_BOTTOM_WIDTH, BORDER_BOTTOM);
}
/**
* Sets the {@code borderBottomWidth} style attribute.
* @param borderBottomWidth the new attribute
*/
@JsxSetter
public void setBorderBottomWidth(final Object borderBottomWidth) {
setStyleLengthAttribute(BORDER_BOTTOM_WIDTH.getAttributeName(), borderBottomWidth, "",
false, false, false, null);
}
/**
* Gets the {@code borderLeftColor} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderLeftColor() {
String value = getStyleAttribute(BORDER_LEFT_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(BORDER_LEFT, false));
if (value == null) {
value = findColor(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderLeftColor} style attribute.
* @param borderLeftColor the new attribute
*/
@JsxSetter
public void setBorderLeftColor(final String borderLeftColor) {
setStyleAttribute(BORDER_LEFT_COLOR.getAttributeName(), borderLeftColor);
}
/**
* Gets the {@code borderLeftStyle} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderLeftStyle() {
String value = getStyleAttribute(BORDER_LEFT_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(BORDER_LEFT, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderLeftStyle} style attribute.
* @param borderLeftStyle the new attribute
*/
@JsxSetter
public void setBorderLeftStyle(final String borderLeftStyle) {
setStyleAttribute(BORDER_LEFT_STYLE.getAttributeName(), borderLeftStyle);
}
/**
* Gets the {@code borderLeftWidth} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderLeftWidth() {
return getBorderWidth(BORDER_LEFT_WIDTH, BORDER_LEFT);
}
/**
* Gets the border width for the specified side
* @param borderSideWidth the border side width Definition
* @param borderSide the border side Definition
* @return the width, "" if not defined
*/
private String getBorderWidth(final Definition borderSideWidth, final Definition borderSide) {
String value = getStyleAttribute(borderSideWidth, false);
if (value.isEmpty()) {
value = findBorderWidth(getStyleAttribute(borderSide, false));
if (value == null) {
final String borderWidth = getStyleAttribute(BORDER_WIDTH, false);
if (!StringUtils.isEmpty(borderWidth)) {
final String[] values = StringUtils.split(borderWidth);
int index = values.length;
if (borderSideWidth.name().contains("TOP")) {
index = 0;
}
else if (borderSideWidth.name().contains("RIGHT")) {
index = 1;
}
else if (borderSideWidth.name().contains("BOTTOM")) {
index = 2;
}
else if (borderSideWidth.name().contains("LEFT")) {
index = 3;
}
if (index < values.length) {
value = values[index];
}
}
}
if (value == null) {
value = findBorderWidth(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderLeftWidth} style attribute.
* @param borderLeftWidth the new attribute
*/
@JsxSetter
public void setBorderLeftWidth(final Object borderLeftWidth) {
setStyleLengthAttribute(BORDER_LEFT_WIDTH.getAttributeName(), borderLeftWidth, "",
false, false, false, null);
}
/**
* Gets the {@code borderRightColor} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderRightColor() {
String value = getStyleAttribute(BORDER_RIGHT_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(BORDER_RIGHT, false));
if (value == null) {
value = findColor(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderRightColor} style attribute.
* @param borderRightColor the new attribute
*/
@JsxSetter
public void setBorderRightColor(final String borderRightColor) {
setStyleAttribute(BORDER_RIGHT_COLOR.getAttributeName(), borderRightColor);
}
/**
* Gets the {@code borderRightStyle} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderRightStyle() {
String value = getStyleAttribute(BORDER_RIGHT_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(BORDER_RIGHT, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderRightStyle} style attribute.
* @param borderRightStyle the new attribute
*/
@JsxSetter
public void setBorderRightStyle(final String borderRightStyle) {
setStyleAttribute(BORDER_RIGHT_STYLE.getAttributeName(), borderRightStyle);
}
/**
* Gets the {@code borderRightWidth} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderRightWidth() {
return getBorderWidth(BORDER_RIGHT_WIDTH, BORDER_RIGHT);
}
/**
* Sets the {@code borderRightWidth} style attribute.
* @param borderRightWidth the new attribute
*/
@JsxSetter
public void setBorderRightWidth(final Object borderRightWidth) {
setStyleLengthAttribute(BORDER_RIGHT_WIDTH.getAttributeName(), borderRightWidth, "",
false, false, false, null);
}
/**
* Gets the {@code borderTop} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderTop() {
return getStyleAttribute(BORDER_TOP);
}
/**
* Sets the {@code borderTop} style attribute.
* @param borderTop the new attribute
*/
@JsxSetter
public void setBorderTop(final String borderTop) {
setStyleAttribute(BORDER_TOP.getAttributeName(), borderTop);
}
/**
* Gets the {@code borderTopColor} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderTopColor() {
String value = getStyleAttribute(BORDER_TOP_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(BORDER_TOP, false));
if (value == null) {
value = findColor(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderTopColor} style attribute.
* @param borderTopColor the new attribute
*/
@JsxSetter
public void setBorderTopColor(final String borderTopColor) {
setStyleAttribute(BORDER_TOP_COLOR.getAttributeName(), borderTopColor);
}
/**
* Gets the {@code borderTopStyle} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderTopStyle() {
String value = getStyleAttribute(BORDER_TOP_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(BORDER_TOP, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Sets the {@code borderTopStyle} style attribute.
* @param borderTopStyle the new attribute
*/
@JsxSetter
public void setBorderTopStyle(final String borderTopStyle) {
setStyleAttribute(BORDER_TOP_STYLE.getAttributeName(), borderTopStyle);
}
/**
* Gets the {@code borderTopWidth} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBorderTopWidth() {
return getBorderWidth(BORDER_TOP_WIDTH, BORDER_TOP);
}
/**
* Sets the {@code borderTopWidth} style attribute.
* @param borderTopWidth the new attribute
*/
@JsxSetter
public void setBorderTopWidth(final Object borderTopWidth) {
setStyleLengthAttribute(BORDER_TOP_WIDTH.getAttributeName(), borderTopWidth, "",
false, false, false, null);
}
/**
* Gets the {@code bottom} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getBottom() {
return getStyleAttribute(BOTTOM);
}
/**
* Sets the {@code bottom} style attribute.
* @param bottom the new attribute
*/
@JsxSetter
public void setBottom(final Object bottom) {
setStyleLengthAttribute(BOTTOM.getAttributeName(), bottom, "", true, true, false, null);
}
/**
* Gets the {@code color} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getColor() {
return getStyleAttribute(COLOR);
}
/**
* Sets the {@code color} style attribute.
* @param color the new attribute
*/
@JsxSetter
public void setColor(final String color) {
setStyleAttribute(COLOR.getAttributeName(), color);
}
/**
* Gets the {@code cssFloat} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getCssFloat() {
return getStyleAttribute(FLOAT);
}
/**
* Sets the {@code cssFloat} style attribute.
* @param value the new attribute
*/
@JsxSetter
public void setCssFloat(final String value) {
setStyleAttribute(FLOAT.getAttributeName(), value);
}
/**
* Returns the actual text of the style.
* @return the actual text of the style
*/
@JsxGetter
public String getCssText() {
if (styleDeclaration_ == null) {
return null;
}
return styleDeclaration_.getCssText();
}
/**
* Sets the actual text of the style.
* @param value the new text
*/
@JsxSetter
public void setCssText(final String value) {
String fixedValue = value;
if (fixedValue == null || "null".equals(fixedValue)) {
fixedValue = "";
}
styleDeclaration_.setCssText(fixedValue);
}
/**
* Gets the {@code display} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getDisplay() {
return getStyleAttribute(DISPLAY);
}
/**
* Sets the {@code display} style attribute.
* @param display the new attribute
*/
@JsxSetter
public void setDisplay(final String display) {
setStyleAttribute(DISPLAY.getAttributeName(), display);
}
/**
* Gets the {@code fontSize} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getFontSize() {
return getStyleAttribute(FONT_SIZE);
}
/**
* Sets the {@code fontSize} style attribute.
* @param fontSize the new attribute
*/
@JsxSetter
public void setFontSize(final Object fontSize) {
setStyleLengthAttribute(FONT_SIZE.getAttributeName(), fontSize, "", false, true, false, null);
updateFont(getFont(), false);
}
/**
* Gets the {@code lineHeight} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getLineHeight() {
return getStyleAttribute(LINE_HEIGHT);
}
/**
* Sets the {@code lineHeight} style attribute.
* @param lineHeight the new attribute
*/
@JsxSetter
public void setLineHeight(final String lineHeight) {
setStyleAttribute(LINE_HEIGHT.getAttributeName(), lineHeight);
updateFont(getFont(), false);
}
/**
* Gets the {@code fontFamily} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getFontFamily() {
return getStyleAttribute(FONT_FAMILY);
}
/**
* Sets the {@code fontFamily} style attribute.
* @param fontFamily the new attribute
*/
@JsxSetter
public void setFontFamily(final String fontFamily) {
setStyleAttribute(FONT_FAMILY.getAttributeName(), fontFamily);
updateFont(getFont(), false);
}
private void updateFont(final String font, final boolean force) {
final BrowserVersion browserVersion = getBrowserVersion();
final String[] details = ComputedFont.getDetails(font, browserVersion);
if (details != null || force) {
final StringBuilder newFont = new StringBuilder();
newFont.append(getFontSize());
String lineHeight = getLineHeight();
final String defaultLineHeight = LINE_HEIGHT.getDefaultComputedValue(browserVersion);
if (lineHeight.isEmpty()) {
lineHeight = defaultLineHeight;
}
if (browserVersion.hasFeature(CSS_ZINDEX_TYPE_INTEGER) || !lineHeight.equals(defaultLineHeight)) {
newFont.append('/');
if (lineHeight.equals(defaultLineHeight)) {
newFont.append(LINE_HEIGHT.getDefaultComputedValue(browserVersion));
}
else {
newFont.append(lineHeight);
}
}
newFont.append(' ').append(getFontFamily());
setStyleAttribute(FONT.getAttributeName(), newFont.toString());
}
}
/**
* Gets the {@code font} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getFont() {
return getStyleAttribute(FONT);
}
/**
* Sets the {@code font} style attribute.
* @param font the new attribute
*/
@JsxSetter
public void setFont(final String font) {
final String[] details = ComputedFont.getDetails(font, getBrowserVersion());
if (details != null) {
setStyleAttribute(FONT_FAMILY.getAttributeName(), details[ComputedFont.FONT_FAMILY_INDEX]);
final String fontSize = details[ComputedFont.FONT_SIZE_INDEX];
if (details[ComputedFont.LINE_HEIGHT_INDEX] != null) {
setStyleAttribute(LINE_HEIGHT.getAttributeName(), details[ComputedFont.LINE_HEIGHT_INDEX]);
}
setStyleAttribute(FONT_SIZE.getAttributeName(), fontSize);
updateFont(font, true);
}
}
/**
* Gets the {@code height} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getHeight() {
return getStyleAttribute(HEIGHT);
}
/**
* Sets the {@code height} style attribute.
* @param height the new attribute
*/
@JsxSetter
public void setHeight(final Object height) {
setStyleLengthAttribute(HEIGHT.getAttributeName(), height, "", true, true, false, null);
}
/**
* Gets the {@code left} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getLeft() {
return getStyleAttribute(LEFT);
}
/**
* Sets the {@code left} style attribute.
* @param left the new attribute
*/
@JsxSetter
public void setLeft(final Object left) {
setStyleLengthAttribute(LEFT.getAttributeName(), left, "", true, true, false, null);
}
/**
* Returns the {@code length} property.
* @return the {@code length} property
*/
@JsxGetter
public int getLength() {
if (styleDeclaration_ == null) {
return 0;
}
return styleDeclaration_.getLength();
}
/**
* Returns the item in the given index.
* @param index the index
* @return the item in the given index
*/
@JsxFunction
public Object item(final int index) {
if (styleDeclaration_ == null) {
return null;
}
return styleDeclaration_.item(index);
}
/**
* Gets the {@code letterSpacing} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getLetterSpacing() {
return getStyleAttribute(LETTER_SPACING);
}
/**
* Sets the {@code letterSpacing} style attribute.
* @param letterSpacing the new attribute
*/
@JsxSetter
public void setLetterSpacing(final Object letterSpacing) {
setStyleLengthAttribute(LETTER_SPACING.getAttributeName(), letterSpacing, "",
false, false, false, null);
}
/**
* Gets the {@code margin} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMargin() {
return getStyleAttribute(MARGIN);
}
/**
* Sets the {@code margin} style attribute.
* @param margin the new attribute
*/
@JsxSetter
public void setMargin(final String margin) {
setStyleAttribute(MARGIN.getAttributeName(), margin);
}
/**
* Gets the {@code marginBottom} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMarginBottom() {
return getCssStyleDeclaration().getStyleAttribute(MARGIN_BOTTOM, MARGIN);
}
/**
* Sets the {@code marginBottom} style attribute.
* @param marginBottom the new attribute
*/
@JsxSetter
public void setMarginBottom(final Object marginBottom) {
setStyleLengthAttribute(MARGIN_BOTTOM.getAttributeName(), marginBottom, "", true, true, false, null);
}
/**
* Gets the {@code marginLeft} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMarginLeft() {
return getCssStyleDeclaration().getStyleAttribute(MARGIN_LEFT, MARGIN);
}
/**
* Sets the {@code marginLeft} style attribute.
* @param marginLeft the new attribute
*/
@JsxSetter
public void setMarginLeft(final Object marginLeft) {
setStyleLengthAttribute(MARGIN_LEFT.getAttributeName(), marginLeft, "", true, true, false, null);
}
/**
* Gets the {@code marginRight} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMarginRight() {
return getCssStyleDeclaration().getStyleAttribute(MARGIN_RIGHT, MARGIN);
}
/**
* Sets the {@code marginRight} style attribute.
* @param marginRight the new attribute
*/
@JsxSetter
public void setMarginRight(final Object marginRight) {
setStyleLengthAttribute(MARGIN_RIGHT.getAttributeName(), marginRight, "", true, true, false, null);
}
/**
* Gets the {@code marginTop} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMarginTop() {
return getCssStyleDeclaration().getStyleAttribute(MARGIN_TOP, MARGIN);
}
/**
* Sets the {@code marginTop} style attribute.
* @param marginTop the new attribute
*/
@JsxSetter
public void setMarginTop(final Object marginTop) {
setStyleLengthAttribute(MARGIN_TOP.getAttributeName(), marginTop, "", true, true, false, null);
}
/**
* Gets the {@code maxHeight} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMaxHeight() {
return getStyleAttribute(MAX_HEIGHT);
}
/**
* Sets the {@code maxHeight} style attribute.
* @param maxHeight the new attribute
*/
@JsxSetter
public void setMaxHeight(final Object maxHeight) {
setStyleLengthAttribute(MAX_HEIGHT.getAttributeName(), maxHeight, "", false, true, false, null);
}
/**
* Gets the {@code maxWidth} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMaxWidth() {
return getStyleAttribute(MAX_WIDTH);
}
/**
* Sets the {@code maxWidth} style attribute.
* @param maxWidth the new attribute
*/
@JsxSetter
public void setMaxWidth(final Object maxWidth) {
setStyleLengthAttribute(MAX_WIDTH.getAttributeName(), maxWidth, "", false, true, false, null);
}
/**
* Gets the {@code minHeight} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMinHeight() {
return getStyleAttribute(MIN_HEIGHT);
}
/**
* Sets the {@code minHeight} style attribute.
* @param minHeight the new attribute
*/
@JsxSetter
public void setMinHeight(final Object minHeight) {
setStyleLengthAttribute(MIN_HEIGHT.getAttributeName(), minHeight, "", true, true, false, null);
}
/**
* Gets the {@code minWidth} style attribute.
* @return the style attribute
*/
@JsxGetter
public String getMinWidth() {
return getStyleAttribute(MIN_WIDTH);
}
/**
* Sets the {@code minWidth} style attribute.
* @param minWidth the new attribute
*/
@JsxSetter
public void setMinWidth(final Object minWidth) {
setStyleLengthAttribute(MIN_WIDTH.getAttributeName(), minWidth, "", true, true, false, null);
}
/**
* {@inheritDoc}
*/
@Override
public Object get(final String name, final Scriptable start) {
if (this != start) {
return super.get(name, start);
}
Scriptable prototype = getPrototype();
while (prototype != null) {
Object value = prototype.get(name, start);
if (value != Scriptable.NOT_FOUND) {
return value;
}
final String camel = org.htmlunit.util.StringUtils.cssCamelize(name);
if (!name.equals(camel)) {
value = prototype.get(camel, start);
if (value != Scriptable.NOT_FOUND) {
return value;
}
}
prototype = prototype.getPrototype();
}
final Definition style = StyleAttributes.getDefinition(name, getBrowserVersion());
if (style != null) {
return getStyleAttribute(style);
}
return super.get(name, start);
}
@Override
public Object get(final int index, final Scriptable start) {
if (index < 0) {
return Undefined.instance;
}
final Map style = getStyleMap();
final int size = style.size();
if (index >= size) {
if (getBrowserVersion().hasFeature(JS_STYLE_WRONG_INDEX_RETURNS_UNDEFINED)) {
return Undefined.instance;
}
return "";
}
return style.keySet().toArray(new String[size])[index];
}
/**
* Get the value for the style attribute.
* @param definition the definition
* @return the value
*/
public final String getStyleAttribute(final Definition definition) {
return getStyleAttribute(definition, true);
}
/**
* Get the value for the style attribute.
* This impl ignores the default getDefaultValueIfEmpty flag, but there is a overload
* in {@link ComputedCSSStyleDeclaration}.
* @param definition the definition
* @param getDefaultValueIfEmpty whether to get the default value if empty or not
* @return the value
*/
public String getStyleAttribute(final Definition definition, final boolean getDefaultValueIfEmpty) {
if (styleDeclaration_ != null) {
return styleDeclaration_.getStyleAttribute(definition, getDefaultValueIfEmpty);
}
return "";
}
@Override
public void put(final String name, final Scriptable start, final Object value) {
if (this != start) {
super.put(name, start, value);
return;
}
final Scriptable prototype = getPrototype();
if (prototype != null && !"constructor".equals(name)) {
if (prototype.get(name, start) != Scriptable.NOT_FOUND) {
prototype.put(name, start, value);
return;
}
final String camel = org.htmlunit.util.StringUtils.cssCamelize(name);
if (!name.equals(camel) && prototype.get(camel, start) != Scriptable.NOT_FOUND) {
prototype.put(camel, start, value);
return;
}
}
if (getDomNodeOrNull() != null) { // check if prototype or not
final Definition style = StyleAttributes.getDefinition(name, getBrowserVersion());
if (style != null) {
final String stringValue = Context.toString(value);
setStyleAttribute(style.getAttributeName(), stringValue);
return;
}
}
super.put(name, start, value);
}
@Override
public boolean has(final String name, final Scriptable start) {
if (this != start) {
return super.has(name, start);
}
final Definition style = StyleAttributes.getDefinition(name, getBrowserVersion());
if (style != null) {
return true;
}
return super.has(name, start);
}
@Override
public Object[] getIds() {
final List