com.gargoylesoftware.htmlunit.html.HtmlArea Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of htmlunit Show documentation
Show all versions of htmlunit Show documentation
A headless browser intended for use in testing web-based applications.
/*
* Copyright (c) 2002-2022 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 com.gargoylesoftware.htmlunit.html;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_DISPLAY_BLOCK;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
import com.gargoylesoftware.htmlunit.protocol.javascript.JavaScriptURLConnection;
import com.gargoylesoftware.htmlunit.util.geometry.Circle2D;
import com.gargoylesoftware.htmlunit.util.geometry.Polygon2D;
import com.gargoylesoftware.htmlunit.util.geometry.Rectangle2D;
import com.gargoylesoftware.htmlunit.util.geometry.Shape2D;
/**
* Wrapper for the HTML element "area".
*
* @author Mike Bowler
* @author David K. Taylor
* @author Christian Sell
* @author Marc Guillemot
* @author Ahmed Ashour
* @author Frank Danek
* @author Ronald Brill
*/
public class HtmlArea extends HtmlElement {
private static final Log LOG = LogFactory.getLog(HtmlArea.class);
/** The HTML tag represented by this element. */
public static final String TAG_NAME = "area";
private static final String SHAPE_RECT = "rect";
private static final String SHAPE_CIRCLE = "circle";
private static final String SHAPE_POLY = "poly";
/**
* Creates a new instance.
*
* @param qualifiedName the qualified name of the element type to instantiate
* @param page the page that contains this element
* @param attributes the initial attributes
*/
HtmlArea(final String qualifiedName, final SgmlPage page,
final Map attributes) {
super(qualifiedName, page, attributes);
}
/**
* {@inheritDoc}
*/
@Override
protected boolean doClickStateUpdate(final boolean shiftKey, final boolean ctrlKey) throws IOException {
final HtmlPage enclosingPage = (HtmlPage) getPage();
final WebClient webClient = enclosingPage.getWebClient();
final String href = getHrefAttribute().trim();
if (!href.isEmpty()) {
final HtmlPage page = (HtmlPage) getPage();
if (StringUtils.startsWithIgnoreCase(href, JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
page.executeJavaScript(
href, "javascript url", getStartLineNumber());
return false;
}
final URL url;
try {
url = enclosingPage.getFullyQualifiedUrl(getHrefAttribute());
}
catch (final MalformedURLException e) {
throw new IllegalStateException(
"Not a valid url: " + getHrefAttribute(), e);
}
final WebRequest request = new WebRequest(url, page.getCharset(), page.getUrl());
final WebWindow webWindow = enclosingPage.getEnclosingWindow();
final String target = enclosingPage.getResolvedTarget(getTargetAttribute());
webClient.getPage(webClient.openTargetWindow(webWindow, target, WebClient.TARGET_SELF), request);
}
return false;
}
/**
* Returns the value of the attribute {@code shape}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code shape} or an empty string if that attribute isn't defined
*/
public final String getShapeAttribute() {
return getAttributeDirect("shape");
}
/**
* Returns the value of the attribute {@code coords}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code coords} or an empty string if that attribute isn't defined
*/
public final String getCoordsAttribute() {
return getAttributeDirect("coords");
}
/**
* Returns the value of the attribute {@code href}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code href} or an empty string if that attribute isn't defined
*/
public final String getHrefAttribute() {
return getAttributeDirect("href");
}
/**
* Returns the value of the attribute {@code nohref}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code nohref} or an empty string if that attribute isn't defined
*/
public final String getNoHrefAttribute() {
return getAttributeDirect("nohref");
}
/**
* Returns the value of the attribute {@code alt}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code alt} or an empty string if that attribute isn't defined
*/
public final String getAltAttribute() {
return getAttributeDirect("alt");
}
/**
* Returns the value of the attribute {@code tabindex}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code tabindex} or an empty string if that attribute isn't defined
*/
public final String getTabIndexAttribute() {
return getAttributeDirect("tabindex");
}
/**
* Returns the value of the attribute {@code accesskey}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code accesskey} or an empty string if that attribute isn't defined
*/
public final String getAccessKeyAttribute() {
return getAttributeDirect("accesskey");
}
/**
* Returns the value of the attribute {@code onfocus}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code onfocus} or an empty string if that attribute isn't defined
*/
public final String getOnFocusAttribute() {
return getAttributeDirect("onfocus");
}
/**
* Returns the value of the attribute {@code onblur}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code onblur} or an empty string if that attribute isn't defined
*/
public final String getOnBlurAttribute() {
return getAttributeDirect("onblur");
}
/**
* Returns the value of the attribute {@code target}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code target} or an empty string if that attribute isn't defined
*/
public final String getTargetAttribute() {
return getAttributeDirect("target");
}
/**
* Indicates if this area contains the specified point.
* @param x the x coordinate of the point
* @param y the y coordinate of the point
* @return {@code true} if the point is contained in this area
*/
boolean containsPoint(final int x, final int y) {
final String shape = StringUtils.defaultIfEmpty(getShapeAttribute(), SHAPE_RECT).toLowerCase(Locale.ROOT);
if ("default".equals(shape) && getCoordsAttribute() != null) {
return true;
}
if (SHAPE_RECT.equals(shape) && getCoordsAttribute() != null) {
final Shape2D rectangle = parseRect();
return rectangle.contains(x, y);
}
if (SHAPE_CIRCLE.equals(shape) && getCoordsAttribute() != null) {
final Shape2D circle = parseCircle();
return circle.contains(x, y);
}
if (SHAPE_POLY.equals(shape) && getCoordsAttribute() != null) {
final Shape2D path = parsePoly();
return path.contains(x, y);
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public DisplayStyle getDefaultStyleDisplay() {
if (hasFeature(CSS_DISPLAY_BLOCK)) {
return DisplayStyle.NONE;
}
return DisplayStyle.INLINE;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isDisplayed() {
final DomNode parent = getParentNode();
if (parent instanceof HtmlMap && parent.isDisplayed()) {
return !isEmpty();
}
return false;
}
private Rectangle2D parseRect() {
// browsers seem to support comma and blank
final String[] coords = StringUtils.split(getCoordsAttribute(), ", ");
double leftX = 0;
double topY = 0;
double rightX = 0;
double bottomY = 0;
try {
if (coords.length > 0) {
leftX = Double.parseDouble(coords[0].trim());
}
if (coords.length > 1) {
topY = Double.parseDouble(coords[1].trim());
}
if (coords.length > 2) {
rightX = Double.parseDouble(coords[2].trim());
}
if (coords.length > 3) {
bottomY = Double.parseDouble(coords[3].trim());
}
}
catch (final NumberFormatException e) {
if (LOG.isWarnEnabled()) {
LOG.warn("Invalid rect coords '" + Arrays.toString(coords) + "'", e);
}
}
return new Rectangle2D(leftX, topY, rightX, bottomY);
}
private Circle2D parseCircle() {
// browsers seem to support comma and blank
final String[] coords = StringUtils.split(getCoordsAttribute(), ", ");
double centerX = 0;
double centerY = 0;
double radius = 0;
try {
if (coords.length > 0) {
centerX = Double.parseDouble(coords[0].trim());
}
if (coords.length > 1) {
centerY = Double.parseDouble(coords[1].trim());
}
if (coords.length > 2) {
radius = Double.parseDouble(coords[2].trim());
}
}
catch (final NumberFormatException e) {
LOG.warn("Invalid circle coords '" + Arrays.toString(coords) + "'", e);
}
return new Circle2D(centerX, centerY, radius);
}
private Shape2D parsePoly() {
// browsers seem to support comma and blank
final String[] coords = StringUtils.split(getCoordsAttribute(), ", ");
try {
if (coords.length > 1) {
final Polygon2D path = new Polygon2D(Double.parseDouble(coords[0]), Double.parseDouble(coords[1]));
for (int i = 2; i + 1 < coords.length; i += 2) {
path.lineTo(Double.parseDouble(coords[i]), Double.parseDouble(coords[i + 1]));
}
return path;
}
}
catch (final NumberFormatException e) {
if (LOG.isWarnEnabled()) {
LOG.warn("Invalid poly coords '" + Arrays.toString(coords) + "'", e);
}
}
return new Rectangle2D(0, 0, 0, 0);
}
/**
* {@inheritDoc}
*/
@Override
public boolean handles(final Event event) {
if (Event.TYPE_BLUR.equals(event.getType()) || Event.TYPE_FOCUS.equals(event.getType())) {
return true;
}
return super.handles(event);
}
private boolean isEmpty() {
final String shape = StringUtils.defaultIfEmpty(getShapeAttribute(), SHAPE_RECT).toLowerCase(Locale.ROOT);
if ("default".equals(shape) && getCoordsAttribute() != null) {
return false;
}
if (SHAPE_RECT.equals(shape) && getCoordsAttribute() != null) {
final Shape2D rectangle = parseRect();
return rectangle.isEmpty();
}
if (SHAPE_CIRCLE.equals(shape) && getCoordsAttribute() != null) {
final Shape2D circle = parseCircle();
return circle.isEmpty();
}
if (SHAPE_POLY.equals(shape) && getCoordsAttribute() != null) {
final Shape2D path = parsePoly();
return path.isEmpty();
}
return false;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy