org.htmlunit.css.AbstractCssStyleDeclaration 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.
The newest version!
/*
* Copyright (c) 2002-2024 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.css;
import static org.apache.commons.lang3.StringUtils.defaultIfEmpty;
import static org.htmlunit.BrowserVersionFeatures.CSS_BACKGROUND_INITIAL;
import static org.htmlunit.BrowserVersionFeatures.CSS_BACKGROUND_RGBA;
import static org.htmlunit.BrowserVersionFeatures.CSS_ZINDEX_TYPE_INTEGER;
import static org.htmlunit.css.CssStyleSheet.FIXED;
import static org.htmlunit.css.CssStyleSheet.INITIAL;
import static org.htmlunit.css.CssStyleSheet.NONE;
import static org.htmlunit.css.CssStyleSheet.REPEAT;
import static org.htmlunit.css.CssStyleSheet.SCROLL;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.htmlunit.BrowserVersion;
import org.htmlunit.BrowserVersionFeatures;
import org.htmlunit.css.StyleAttributes.Definition;
import org.htmlunit.cssparser.dom.AbstractCSSRuleImpl;
import org.htmlunit.html.DomElement;
import org.htmlunit.html.impl.Color;
import org.htmlunit.util.StringUtils;
/**
* A css StyleDeclaration.
*
* @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
* @author cd alexndr
*/
public abstract class AbstractCssStyleDeclaration implements Serializable {
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)");
/**
* 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
*/
public abstract String getStylePriority(String name);
/**
* Returns the actual text of the style.
* @return the actual text of the style
*/
public abstract String getCssText();
/**
* Get the value for the style attribute.
* @param name the name
* @return the value
*/
public abstract String getStyleAttribute(String name);
/**
* 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 abstract String getStyleAttribute(Definition definition, boolean getDefaultValueIfEmpty);
/**
* Indicates if the browser this is associated with has the feature.
* @param property the property name
* @return {@code false} if this browser doesn't have this feature
*/
public abstract boolean hasFeature(BrowserVersionFeatures property);
/**
* @return the {@link BrowserVersion}
*/
public abstract BrowserVersion getBrowserVersion();
/**
* Returns the value of one of the two named style attributes. If both attributes exist,
* the value of the attribute that was declared last is returned. If only one of the
* attributes exists, its value is returned. If neither attribute exists, an empty string
* is returned.
*
* The second named attribute may be shorthand for a the actual desired property.
* The following formats are possible:
*
* top right bottom left
: All values are explicit.
* top right bottom
: Left is implicitly the same as right.
* top right
: Left is implicitly the same as right, bottom is implicitly the same as top.
* top
: Left, bottom and right are implicitly the same as top.
*
*
* @param definition1 the name of the first style attribute
* @param definition2 the name of the second style attribute
* @return the value of one of the two named style attributes
*/
public String getStyleAttribute(final Definition definition1, final Definition definition2) {
final String value;
final StyleElement element1 = getStyleElement(definition1.getAttributeName());
final StyleElement element2 = getStyleElement(definition2.getAttributeName());
if (element2 == null) {
if (element1 == null) {
return "";
}
return element1.getValue();
}
if (element1 != null) {
if (element1.compareTo(element2) > 0) {
return element1.getValue();
}
}
value = element2.getValue();
final String[] values = StringUtils.splitAtJavaWhitespace(value);
if (definition1.name().contains("TOP")) {
if (values.length > 0) {
return values[0];
}
return "";
}
else if (definition1.name().contains("RIGHT")) {
if (values.length > 1) {
return values[1];
}
else if (values.length > 0) {
return values[0];
}
return "";
}
else if (definition1.name().contains("BOTTOM")) {
if (values.length > 2) {
return values[2];
}
else if (values.length > 0) {
return values[0];
}
return "";
}
else if (definition1.name().contains("LEFT")) {
if (values.length > 3) {
return values[3];
}
else if (values.length > 1) {
return values[1];
}
else if (values.length > 0) {
return values[0];
}
else {
return "";
}
}
else {
throw new IllegalStateException("Unsupported definition: " + definition1);
}
}
/**
* Sets the actual text of the style.
* @param value the new text
*/
public abstract void setCssText(String value);
/**
* Sets the specified style attribute.
* @param name the attribute name (camel-cased)
* @param newValue the attribute value
* @param important important value
*/
public abstract void setStyleAttribute(String name, String newValue, String important);
/**
* Removes the specified style attribute, returning the value of the removed attribute.
* @param name the attribute name (delimiter-separated, not camel-cased)
* @return the removed value
*/
public abstract String removeStyleAttribute(String name);
/**
* Returns the {@code length} property.
* @return the {@code length} property
*/
public abstract int getLength();
/**
* Returns the item in the given index.
* @param index the index
* @return the item in the given index
*/
public abstract Object item(int index);
/**
* Returns the CSSRule that is the parent of this style block or null
if this CSSStyleDeclaration is
* not attached to a CSSRule.
* @return the CSSRule that is the parent of this style block or null
if this CSSStyleDeclaration is
* not attached to a CSSRule
*/
public abstract AbstractCSSRuleImpl getParentRule();
/**
* Determines the StyleElement for the given name.
*
* @param name the name of the requested StyleElement
* @return the StyleElement or null if not found
*/
public abstract StyleElement getStyleElement(String 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
*/
public abstract StyleElement getStyleElementCaseInSensitive(String 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
*/
public abstract Map getStyleMap();
/**
* @return true if this is a computed style declaration
*/
public boolean isComputed() {
return false;
}
protected String getStyleAttribute(final Definition name, final String value) {
final String[] values = StringUtils.splitAtJavaWhitespace(value);
if (name.name().contains("TOP")) {
if (values.length > 0) {
return values[0];
}
return "";
}
else if (name.name().contains("RIGHT")) {
if (values.length > 1) {
return values[1];
}
else if (values.length > 0) {
return values[0];
}
return "";
}
else if (name.name().contains("BOTTOM")) {
if (values.length > 2) {
return values[2];
}
else if (values.length > 0) {
return values[0];
}
return "";
}
else if (name.name().contains("LEFT")) {
if (values.length > 3) {
return values[3];
}
else if (values.length > 1) {
return values[1];
}
else if (values.length > 0) {
return values[0];
}
else {
return "";
}
}
else {
throw new IllegalStateException("Unsupported definition: " + name);
}
}
/**
* Gets the {@code accelerator} style attribute.
* @return the style attribute
*/
public String getAccelerator() {
return defaultIfEmpty(getStyleAttribute(Definition.ACCELERATOR, true), "false");
}
/**
* Gets the {@code backgroundAttachment} style attribute.
* @return the style attribute
*/
public String getBackgroundAttachment() {
String value = getStyleAttribute(Definition.BACKGROUND_ATTACHMENT, false);
if (org.apache.commons.lang3.StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(Definition.BACKGROUND, true);
if (org.apache.commons.lang3.StringUtils.isNotBlank(bg)) {
value = findAttachment(bg);
if (value == null) {
if (hasFeature(CSS_BACKGROUND_INITIAL) && !isComputed()) {
return INITIAL;
}
return SCROLL; // default if shorthand is used
}
return value;
}
return "";
}
return value;
}
/**
* Gets the {@code backgroundColor} style attribute.
* @return the style attribute
*/
public String getBackgroundColor() {
String value = getStyleAttribute(Definition.BACKGROUND_COLOR, false);
if (org.apache.commons.lang3.StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(Definition.BACKGROUND, false);
if (org.apache.commons.lang3.StringUtils.isBlank(bg)) {
return "";
}
value = findColor(bg);
if (value == null) {
if (hasFeature(CSS_BACKGROUND_INITIAL)) {
if (!isComputed()) {
return INITIAL;
}
return "rgba(0, 0, 0, 0)";
}
if (hasFeature(CSS_BACKGROUND_RGBA)) {
return "rgba(0, 0, 0, 0)";
}
return "transparent"; // default if shorthand is used
}
return value;
}
if (org.apache.commons.lang3.StringUtils.isBlank(value)) {
return "";
}
return value;
}
/**
* Gets the {@code backgroundImage} style attribute.
* @return the style attribute
*/
public String getBackgroundImage() {
String value = getStyleAttribute(Definition.BACKGROUND_IMAGE, false);
if (org.apache.commons.lang3.StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(Definition.BACKGROUND, false);
if (org.apache.commons.lang3.StringUtils.isNotBlank(bg)) {
value = findImageUrl(bg);
final boolean backgroundInitial = hasFeature(CSS_BACKGROUND_INITIAL);
if (value == null) {
return backgroundInitial && !isComputed() ? INITIAL : NONE;
}
if (isComputed()) {
try {
value = value.substring(5, value.length() - 2);
final DomElement domElement = ((ComputedCssStyleDeclaration) this).getDomElement();
return "url(\"" + domElement.getHtmlPageOrNull()
.getFullyQualifiedUrl(value) + "\")";
}
catch (final Exception e) {
// ignore
}
}
return value;
}
return "";
}
return value;
}
/**
* Gets the {@code backgroundPosition} style attribute.
* @return the style attribute
*/
public String getBackgroundPosition() {
String value = getStyleAttribute(Definition.BACKGROUND_POSITION, false);
if (value == null) {
return null;
}
if (org.apache.commons.lang3.StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(Definition.BACKGROUND, false);
if (bg == null) {
return null;
}
if (org.apache.commons.lang3.StringUtils.isNotBlank(bg)) {
value = findPosition(bg);
final boolean isInitial = hasFeature(CSS_BACKGROUND_INITIAL);
if (value == null) {
if (isInitial) {
return isComputed() ? "" : INITIAL;
}
return "0% 0%";
}
if (hasFeature(CSS_ZINDEX_TYPE_INTEGER)) {
final String[] values = org.htmlunit.util.StringUtils.splitAtBlank(value);
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 = org.htmlunit.util.StringUtils.splitAtBlank(value);
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;
}
/**
* Gets the {@code backgroundRepeat} style attribute.
* @return the style attribute
*/
public String getBackgroundRepeat() {
String value = getStyleAttribute(Definition.BACKGROUND_REPEAT, false);
if (org.apache.commons.lang3.StringUtils.isBlank(value)) {
final String bg = getStyleAttribute(Definition.BACKGROUND, false);
if (org.apache.commons.lang3.StringUtils.isNotBlank(bg)) {
value = findRepeat(bg);
if (value == null) {
if (hasFeature(CSS_BACKGROUND_INITIAL) && !isComputed()) {
return INITIAL;
}
return REPEAT; // default if shorthand is used
}
return value;
}
return "";
}
return value;
}
/**
* Gets the {@code borderBottomColor} style attribute.
* @return the style attribute
*/
public String getBorderBottomColor() {
String value = getStyleAttribute(Definition.BORDER_BOTTOM_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(Definition.BORDER_BOTTOM, false));
if (value == null) {
value = findColor(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderBottomStyle} style attribute.
* @return the style attribute
*/
public String getBorderBottomStyle() {
String value = getStyleAttribute(Definition.BORDER_BOTTOM_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER_BOTTOM, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderBottomWidth} style attribute.
* @return the style attribute
*/
public String getBorderBottomWidth() {
return getBorderWidth(Definition.BORDER_BOTTOM_WIDTH, Definition.BORDER_BOTTOM);
}
/**
* Gets the {@code borderLeftColor} style attribute.
* @return the style attribute
*/
public String getBorderLeftColor() {
String value = getStyleAttribute(Definition.BORDER_LEFT_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(Definition.BORDER_LEFT, false));
if (value == null) {
value = findColor(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderLeftStyle} style attribute.
* @return the style attribute
*/
public String getBorderLeftStyle() {
String value = getStyleAttribute(Definition.BORDER_LEFT_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER_LEFT, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderLeftWidth} style attribute.
* @return the style attribute
*/
public String getBorderLeftWidth() {
return getBorderWidth(Definition.BORDER_LEFT_WIDTH, Definition.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(Definition.BORDER_WIDTH, false);
if (!org.apache.commons.lang3.StringUtils.isEmpty(borderWidth)) {
final String[] values = org.htmlunit.util.StringUtils.splitAtJavaWhitespace(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(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderRightColor} style attribute.
* @return the style attribute
*/
public String getBorderRightColor() {
String value = getStyleAttribute(Definition.BORDER_RIGHT_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(Definition.BORDER_RIGHT, false));
if (value == null) {
value = findColor(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderRightStyle} style attribute.
* @return the style attribute
*/
public String getBorderRightStyle() {
String value = getStyleAttribute(Definition.BORDER_RIGHT_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER_RIGHT, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderRightWidth} style attribute.
* @return the style attribute
*/
public String getBorderRightWidth() {
return getBorderWidth(Definition.BORDER_RIGHT_WIDTH, Definition.BORDER_RIGHT);
}
/**
* Gets the {@code borderTop} style attribute.
* @return the style attribute
*/
public String getBorderTop() {
return getStyleAttribute(Definition.BORDER_TOP, true);
}
/**
* Gets the {@code borderTopColor} style attribute.
* @return the style attribute
*/
public String getBorderTopColor() {
String value = getStyleAttribute(Definition.BORDER_TOP_COLOR, false);
if (value.isEmpty()) {
value = findColor(getStyleAttribute(Definition.BORDER_TOP, false));
if (value == null) {
value = findColor(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderTopStyle} style attribute.
* @return the style attribute
*/
public String getBorderTopStyle() {
String value = getStyleAttribute(Definition.BORDER_TOP_STYLE, false);
if (value.isEmpty()) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER_TOP, false));
if (value == null) {
value = findBorderStyle(getStyleAttribute(Definition.BORDER, false));
}
if (value == null) {
value = "";
}
}
return value;
}
/**
* Gets the {@code borderTopWidth} style attribute.
* @return the style attribute
*/
public String getBorderTopWidth() {
return getBorderWidth(Definition.BORDER_TOP_WIDTH, Definition.BORDER_TOP);
}
/**
* Gets the {@code bottom} style attribute.
* @return the style attribute
*/
public String getBottom() {
return getStyleAttribute(Definition.BOTTOM, true);
}
/**
* Gets the {@code color} style attribute.
* @return the style attribute
*/
public String getColor() {
return getStyleAttribute(Definition.COLOR, true);
}
/**
* Gets the {@code cssFloat} style attribute.
* @return the style attribute
*/
public String getCssFloat() {
return getStyleAttribute(Definition.FLOAT, true);
}
/**
* Gets the {@code display} style attribute.
* @return the style attribute
*/
public String getDisplay() {
return getStyleAttribute(Definition.DISPLAY, true);
}
/**
* Gets the {@code font} style attribute.
* @return the style attribute
*/
public String getFont() {
return getStyleAttribute(Definition.FONT, true);
}
/**
* Gets the {@code fontFamily} style attribute.
* @return the style attribute
*/
public String getFontFamily() {
return getStyleAttribute(Definition.FONT_FAMILY, true);
}
/**
* Gets the {@code fontSize} style attribute.
* @return the style attribute
*/
public String getFontSize() {
return getStyleAttribute(Definition.FONT_SIZE, true);
}
/**
* Gets the {@code height} style attribute.
* @return the style attribute
*/
public String getHeight() {
return getStyleAttribute(Definition.HEIGHT, true);
}
/**
* @return the style attribute {@code left}
*/
public String getLeft() {
return getStyleAttribute(Definition.LEFT, true);
}
/**
* @return the style attribute {@code letterSpacing}
*/
public String getLetterSpacing() {
return getStyleAttribute(Definition.LETTER_SPACING, true);
}
/**
* @return the style attribute {@code lineHeight}
*/
public String getLineHeight() {
return getStyleAttribute(Definition.LINE_HEIGHT, true);
}
/**
* @return the style attribute {@code margin}
*/
public String getMargin() {
return getStyleAttribute(Definition.MARGIN, true);
}
/**
* Gets the {@code marginBottom} style attribute.
* @return the style attribute
*/
public String getMarginBottom() {
return getStyleAttribute(Definition.MARGIN_BOTTOM, Definition.MARGIN);
}
/**
* Gets the {@code marginLeft} style attribute.
* @return the style attribute
*/
public String getMarginLeft() {
return getStyleAttribute(Definition.MARGIN_LEFT, Definition.MARGIN);
}
/**
* Gets the {@code marginRight} style attribute.
* @return the style attribute
*/
public String getMarginRight() {
return getStyleAttribute(Definition.MARGIN_RIGHT, Definition.MARGIN);
}
/**
* Gets the {@code marginTop} style attribute.
* @return the style attribute
*/
public String getMarginTop() {
return getStyleAttribute(Definition.MARGIN_TOP, Definition.MARGIN);
}
/**
* @return the style attribute {@code maxHeight}
*/
public String getMaxHeight() {
return getStyleAttribute(Definition.MAX_HEIGHT, true);
}
/**
* @return the style attribute {@code maxWidth}
*/
public String getMaxWidth() {
return getStyleAttribute(Definition.MAX_WIDTH, true);
}
/**
* @return the style attribute {@code minHeight}
*/
public String getMinHeight() {
return getStyleAttribute(Definition.MIN_HEIGHT, true);
}
/**
* @return the style attribute {@code minWidth}
*/
public String getMinWidth() {
return getStyleAttribute(Definition.MIN_WIDTH, true);
}
/**
* @return the style attribute {@code msImeAlign}
*/
public String getMsImeAlign() {
return getStyleAttribute(Definition.MS_IME_ALIGN, true);
}
/**
* Gets the {@code opacity} style attribute.
* @return the style attribute
*/
public String getOpacity() {
final String opacity = getStyleAttribute(Definition.OPACITY, false);
if (opacity == null || opacity.isEmpty()) {
return "";
}
final String trimedOpacity = opacity.trim();
try {
final double value = Double.parseDouble(trimedOpacity);
if (value % 1 == 0) {
return Integer.toString((int) value);
}
return Double.toString(value);
}
catch (final NumberFormatException e) {
// ignore wrong value
}
return "";
}
/**
* @return the style attribute {@code orphans}
*/
public String getOrphans() {
return getStyleAttribute(Definition.ORPHANS, true);
}
/**
* @return the style attribute {@code outline}
*/
public String getOutline() {
return getStyleAttribute(Definition.OUTLINE, true);
}
/**
* @return the style attribute {@code outlineWidth}
*/
public String getOutlineWidth() {
return getStyleAttribute(Definition.OUTLINE_WIDTH, true);
}
/**
* @return the style attribute {@code padding}
*/
public String getPadding() {
return getStyleAttribute(Definition.PADDING, true);
}
/**
* @return the style attribute {@code paddingBottom}
*/
public String getPaddingBottom() {
return getStyleAttribute(Definition.PADDING_BOTTOM, Definition.PADDING);
}
/**
* @return the style attribute {@code paddingLeft}
*/
public String getPaddingLeft() {
return getStyleAttribute(Definition.PADDING_LEFT, Definition.PADDING);
}
/**
* @return the style attribute {@code paddingRight}
*/
public String getPaddingRight() {
return getStyleAttribute(Definition.PADDING_RIGHT, Definition.PADDING);
}
/**
* @return the style attribute {@code paddingTop}
*/
public String getPaddingTop() {
return getStyleAttribute(Definition.PADDING_TOP, Definition.PADDING);
}
/**
* @return the style attribute {@code position}
*/
public String getPosition() {
return getStyleAttribute(Definition.POSITION, true);
}
/**
* @return the style attribute {@code right}
*/
public String getRight() {
return getStyleAttribute(Definition.RIGHT, true);
}
/**
* @return the style attribute {@code rubyAlign}
*/
public String getRubyAlign() {
return getStyleAttribute(Definition.RUBY_ALIGN, true);
}
/**
* @return the style attribute {@code size}
*/
public String getSize() {
return getStyleAttribute(Definition.SIZE, true);
}
/**
* @return the style attribute {@code textIndent}
*/
public String getTextIndent() {
return getStyleAttribute(Definition.TEXT_INDENT, true);
}
/**
* @return the style attribute {@code top}
*/
public String getTop() {
return getStyleAttribute(Definition.TOP, true);
}
/**
* @return the style attribute {@code verticalAlign}
*/
public String getVerticalAlign() {
return getStyleAttribute(Definition.VERTICAL_ALIGN, true);
}
/**
* @return the style attribute {@code widows}
*/
public String getWidows() {
return getStyleAttribute(Definition.WIDOWS, true);
}
/**
* @return the style attribute {@code width}
*/
public String getWidth() {
return getStyleAttribute(Definition.WIDTH, true);
}
/**
* @return the style attribute {@code wordSpacing}
*/
public String getWordSpacing() {
return getStyleAttribute(Definition.WORD_SPACING, true);
}
/**
* Gets the {@code zIndex} style attribute.
* @return the style attribute
*/
public Object getZIndex() {
final String value = getStyleAttribute(Definition.Z_INDEX_, true);
if (hasFeature(CSS_ZINDEX_TYPE_INTEGER)) {
try {
return Integer.valueOf(value);
}
catch (final NumberFormatException e) {
return "";
}
}
// zIndex is string
try {
Integer.parseInt(value);
return value;
}
catch (final NumberFormatException e) {
return "";
}
}
/**
* Searches for any attachment notation in the specified text.
* @param text the string to search in
* @return the string of the attachment if found, null otherwise
*/
private static String findAttachment(final String text) {
if (text.contains(SCROLL)) {
return SCROLL;
}
if (text.contains(FIXED)) {
return FIXED;
}
return null;
}
/**
* Searches for any color notation in the specified text.
* @param text the string to search in
* @return the string of the color if found, null otherwise
*/
private static String findColor(final String text) {
Color tmpColor = org.htmlunit.util.StringUtils.findColorRGB(text);
if (tmpColor != null) {
return org.htmlunit.util.StringUtils.formatColor(tmpColor);
}
final String[] tokens = org.htmlunit.util.StringUtils.splitAtBlank(text);
for (final String token : tokens) {
if (CssColors.isColorKeyword(token)) {
return token;
}
tmpColor = org.htmlunit.util.StringUtils.asColorHexadecimal(token);
if (tmpColor != null) {
return org.htmlunit.util.StringUtils.formatColor(tmpColor);
}
}
return null;
}
/**
* Searches for any URL notation in the specified text.
* @param text the string to search in
* @return the string of the URL if found, null otherwise
*/
private static String findImageUrl(final String text) {
final Matcher m = URL_PATTERN.matcher(text);
if (m.find()) {
return "url(\"" + m.group(1) + "\")";
}
return null;
}
/**
* Searches for any position notation in the specified text.
* @param text the string to search in
* @return the string of the position if found, null otherwise
*/
private static String findPosition(final String text) {
Matcher m = POSITION_PATTERN.matcher(text);
if (m.find()) {
return m.group(1) + " " + m.group(3);
}
m = POSITION_PATTERN2.matcher(text);
if (m.find()) {
return m.group(1) + " " + m.group(2);
}
m = POSITION_PATTERN3.matcher(text);
if (m.find()) {
return m.group(2) + " " + m.group(1);
}
return null;
}
/**
* Searches for any repeat notation in the specified text.
* @param text the string to search in
* @return the string of the repeat if found, null otherwise
*/
private static String findRepeat(final String text) {
if (text.contains("repeat-x")) {
return "repeat-x";
}
if (text.contains("repeat-y")) {
return "repeat-y";
}
if (text.contains("no-repeat")) {
return "no-repeat";
}
if (text.contains(REPEAT)) {
return REPEAT;
}
return null;
}
/**
* Searches for a border style in the specified text.
* @param text the string to search in
* @return the border style if found, null otherwise
*/
private static String findBorderStyle(final String text) {
for (final String token : org.htmlunit.util.StringUtils.splitAtBlank(text)) {
if (isBorderStyle(token)) {
return token;
}
}
return null;
}
/**
* Returns if the specified token is a border style.
* @param token the token to check
* @return whether the token is a border style or not
*/
private static boolean isBorderStyle(final String token) {
return NONE.equalsIgnoreCase(token) || "hidden".equalsIgnoreCase(token)
|| "dotted".equalsIgnoreCase(token) || "dashed".equalsIgnoreCase(token)
|| "solid".equalsIgnoreCase(token) || "double".equalsIgnoreCase(token)
|| "groove".equalsIgnoreCase(token) || "ridge".equalsIgnoreCase(token)
|| "inset".equalsIgnoreCase(token) || "outset".equalsIgnoreCase(token);
}
/**
* Searches for a border width in the specified text.
* @param text the string to search in
* @return the border width if found, null otherwise
*/
private static String findBorderWidth(final String text) {
for (final String token : org.htmlunit.util.StringUtils.splitAtBlank(text)) {
if (isBorderWidth(token)) {
return token;
}
}
return null;
}
/**
* Returns if the specified token is a border width.
* @param token the token to check
* @return whether the token is a border width or not
*/
private static boolean isBorderWidth(final String token) {
return "thin".equalsIgnoreCase(token) || "medium".equalsIgnoreCase(token)
|| "thick".equalsIgnoreCase(token) || isLength(token);
}
/**
* Returns if the specified token is a length.
* @param token the token to check
* @return whether the token is a length or not
*/
static boolean isLength(String token) {
if (token.endsWith("em") || token.endsWith("ex") || token.endsWith("px") || token.endsWith("in")
|| token.endsWith("cm") || token.endsWith("mm") || token.endsWith("pt") || token.endsWith("pc")
|| token.endsWith("%")) {
if (token.endsWith("%")) {
token = token.substring(0, token.length() - 1);
}
else {
token = token.substring(0, token.length() - 2);
}
try {
Double.parseDouble(token);
return true;
}
catch (final NumberFormatException e) {
// Ignore.
}
}
return false;
}
}