use of com.gargoylesoftware.htmlunit.javascript.host.Element in project htmlunit by HtmlUnit.
the class WebWindowImpl method getComputedStyle.
/**
* {@inheritDoc}
*/
@Override
public CSS2Properties getComputedStyle(final DomElement element, final String pseudoElement) {
String normalizedPseudo = pseudoElement;
if (normalizedPseudo != null) {
if (normalizedPseudo.startsWith("::")) {
normalizedPseudo = normalizedPseudo.substring(1);
} else if (getWebClient().getBrowserVersion().hasFeature(JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON) && normalizedPseudo.length() > 0 && normalizedPseudo.charAt(0) != ':') {
normalizedPseudo = ":" + normalizedPseudo;
}
}
final SgmlPage sgmlPage = element.getPage();
if (sgmlPage instanceof HtmlPage) {
final CSS2Properties styleFromCache = ((HtmlPage) sgmlPage).getStyleFromCache(element, normalizedPseudo);
if (styleFromCache != null) {
return styleFromCache;
}
}
final Element e = element.getScriptableObject();
final CSS2Properties style = new CSS2Properties(e);
final Object ownerDocument = e.getOwnerDocument();
if (ownerDocument instanceof HTMLDocument) {
final StyleSheetList sheets = ((HTMLDocument) ownerDocument).getStyleSheets();
final boolean trace = LOG.isTraceEnabled();
for (int i = 0; i < sheets.getLength(); i++) {
final CSSStyleSheet sheet = (CSSStyleSheet) sheets.item(i);
if (sheet.isActive() && sheet.isEnabled()) {
if (trace) {
LOG.trace("modifyIfNecessary: " + sheet + ", " + style + ", " + e);
}
sheet.modifyIfNecessary(style, element, normalizedPseudo);
}
}
((HtmlPage) element.getPage()).putStyleIntoCache(element, normalizedPseudo, style);
}
return style;
}
use of com.gargoylesoftware.htmlunit.javascript.host.Element in project htmlunit by HtmlUnit.
the class ComputedCSSStyleDeclaration method getTop.
/**
* {@inheritDoc}
*/
@Override
public String getTop() {
final Element elem = getElement();
if (!elem.getDomNodeOrDie().isAttachedToPage() && getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return "";
}
final String superTop = super.getTop();
if (!superTop.endsWith("%")) {
return defaultIfEmpty(superTop, TOP);
}
return pixelString(elem, new CssValue(0, 0) {
@Override
public String get(final ComputedCSSStyleDeclaration style) {
if (style.getElement() == elem) {
return style.getStyleAttribute(TOP, true);
}
return style.getStyleAttribute(HEIGHT, true);
}
});
}
use of com.gargoylesoftware.htmlunit.javascript.host.Element in project htmlunit by HtmlUnit.
the class ComputedCSSStyleDeclaration method getEmptyHeight.
/**
* Returns the element's calculated height taking relevant CSS into account, but <b>not</b> the element's child
* elements.
*
* @return the element's calculated height taking relevant CSS into account, but <b>not</b> the element's child
* elements
*/
private int getEmptyHeight() {
if (height2_ != null) {
return height2_.intValue();
}
final DomNode node = getElement().getDomNodeOrDie();
if (!node.mayBeDisplayed()) {
height2_ = Integer.valueOf(0);
return 0;
}
final String display = getDisplay();
if (NONE.equals(display)) {
height2_ = Integer.valueOf(0);
return 0;
}
final Element elem = getElement();
final int windowHeight = elem.getWindow().getWebWindow().getInnerHeight();
if (elem instanceof HTMLBodyElement) {
height2_ = windowHeight;
return windowHeight;
}
final boolean isInline = "inline".equals(display) && !(node instanceof HtmlInlineFrame);
// height is ignored for inline elements
final boolean explicitHeightSpecified = !isInline && !super.getHeight().isEmpty();
int defaultHeight;
if ((elem.getClass() == HTMLElement.class || elem instanceof HTMLDivElement || elem instanceof HTMLUnknownElement || elem instanceof HTMLDataElement || elem instanceof HTMLTimeElement || elem instanceof HTMLOutputElement || elem instanceof HTMLSlotElement || elem instanceof HTMLLegendElement) && StringUtils.isBlank(node.getTextContent())) {
defaultHeight = 0;
} else if (elem.getFirstChild() == null) {
if (node instanceof HtmlRadioButtonInput || node instanceof HtmlCheckBoxInput) {
final BrowserVersion browser = getBrowserVersion();
if (browser.hasFeature(JS_CLIENTHEIGHT_RADIO_CHECKBOX_10)) {
defaultHeight = 10;
} else {
defaultHeight = 13;
}
} else if (node instanceof HtmlButton) {
defaultHeight = 20;
} else if (node instanceof HtmlInput && !(node instanceof HtmlHiddenInput)) {
final BrowserVersion browser = getBrowserVersion();
if (browser.hasFeature(JS_CLIENTHEIGHT_INPUT_17)) {
defaultHeight = 17;
} else if (browser.hasFeature(JS_CLIENTHEIGHT_INPUT_18)) {
defaultHeight = 18;
} else {
defaultHeight = 20;
}
} else if (node instanceof HtmlSelect) {
defaultHeight = 20;
} else if (node instanceof HtmlTextArea) {
defaultHeight = 49;
} else if (node instanceof HtmlInlineFrame) {
defaultHeight = 154;
} else {
defaultHeight = 0;
}
} else {
final String fontSize = getFontSize();
defaultHeight = getBrowserVersion().getFontHeight(fontSize);
if (node instanceof HtmlDivision || node instanceof HtmlSpan) {
String width = getStyleAttribute(WIDTH, false);
// maybe we are enclosed something that forces a width
Element parent = getElement().getParentElement();
while (width.isEmpty() && parent != null) {
width = getWindow().getComputedStyle(parent, null).getStyleAttribute(WIDTH, false);
parent = parent.getParentElement();
}
final int pixelWidth = pixelValue(width);
final String content = node.getVisibleText();
if (pixelWidth > 0 && !width.isEmpty() && StringUtils.isNotBlank(content)) {
final String[] lines = StringUtils.split(content, '\n');
int lineCount = 0;
final int fontSizeInt = Integer.parseInt(fontSize.substring(0, fontSize.length() - 2));
final FontRenderContext fontRenderCtx = new FontRenderContext(null, false, true);
for (final String line : lines) {
if (StringUtils.isBlank(line)) {
lineCount++;
} else {
// width is specified, we have to to some line breaking
final AttributedString attributedString = new AttributedString(line);
attributedString.addAttribute(TextAttribute.SIZE, fontSizeInt / 1.1);
final LineBreakMeasurer lineBreakMeasurer = new LineBreakMeasurer(attributedString.getIterator(), fontRenderCtx);
lineBreakMeasurer.nextLayout(pixelWidth);
lineCount++;
while (lineBreakMeasurer.getPosition() < line.length() && lineCount < 1000) {
lineBreakMeasurer.nextLayout(pixelWidth);
lineCount++;
}
}
}
defaultHeight *= lineCount;
} else {
if (node instanceof HtmlSpan && StringUtils.isEmpty(content)) {
defaultHeight = 0;
} else {
defaultHeight *= StringUtils.countMatches(content, '\n') + 1;
}
}
}
}
final int defaultWindowHeight = elem instanceof HTMLCanvasElement ? 150 : windowHeight;
int height = pixelValue(elem, new CssValue(defaultHeight, defaultWindowHeight) {
@Override
public String get(final ComputedCSSStyleDeclaration style) {
final Element element = style.getElement();
if (element instanceof HTMLBodyElement) {
return String.valueOf(element.getWindow().getWebWindow().getInnerHeight());
}
// height is ignored for inline elements
if (isInline) {
return "";
}
return style.getStyleAttribute(HEIGHT, true);
}
});
if (height == 0 && !explicitHeightSpecified) {
height = defaultHeight;
}
height2_ = Integer.valueOf(height);
return height;
}
use of com.gargoylesoftware.htmlunit.javascript.host.Element in project htmlunit by HtmlUnit.
the class ComputedCSSStyleDeclaration method getMarginX.
private String getMarginX(final String superMarginX, final Definition definition) {
if (!superMarginX.endsWith("%")) {
return pixelString(defaultIfEmpty(superMarginX, "0px", null));
}
final Element elem = getElement();
if (!elem.getDomNodeOrDie().isAttachedToPage() && getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return "";
}
final int windowWidth = elem.getWindow().getWebWindow().getInnerWidth();
return pixelString(elem, new CssValue(0, windowWidth) {
@Override
public String get(final ComputedCSSStyleDeclaration style) {
if (style.getElement() == elem) {
return style.getStyleAttribute(definition, true);
}
return style.getStyleAttribute(WIDTH, true);
}
});
}
use of com.gargoylesoftware.htmlunit.javascript.host.Element in project htmlunit by HtmlUnit.
the class CSSStyleDeclaration method pixelValue.
private static int pixelValue(final Element element, final CssValue value, final boolean percentMode) {
final String s = value.get(element);
if (s.endsWith("%") || (s.isEmpty() && element instanceof HTMLHtmlElement)) {
final float i = NumberUtils.toFloat(TO_FLOAT_PATTERN.matcher(s).replaceAll("$1"), 100);
final Element parent = element.getParentElement();
final int absoluteValue = (parent == null) ? value.getWindowDefaultValue() : pixelValue(parent, value, true);
return Math.round((i / 100f) * absoluteValue);
}
if (AUTO.equals(s)) {
return value.getDefaultValue();
}
if (s.isEmpty()) {
if (element instanceof HTMLCanvasElement) {
return value.getWindowDefaultValue();
}
// we can provide some kind of base value for percent calculation
if (percentMode) {
final Element parent = element.getParentElement();
if (parent == null || parent instanceof HTMLHtmlElement) {
return value.getWindowDefaultValue();
}
return pixelValue(parent, value, true);
}
return 0;
}
return pixelValue(s);
}
Aggregations