use of com.gargoylesoftware.css.dom.CSSStyleSheetImpl in project htmlunit by HtmlUnit.
the class CSSStyleSheet method loadStylesheet.
/**
* Loads the stylesheet at the specified link or href.
* @param element the parent DOM element
* @param link the stylesheet's link (may be {@code null} if a <tt>url</tt> is specified)
* @param url the stylesheet's url (may be {@code null} if a <tt>link</tt> is specified)
* @return the loaded stylesheet
*/
public static CSSStyleSheet loadStylesheet(final HTMLElement element, final HtmlLink link, final String url) {
final HtmlPage page = (HtmlPage) element.getDomNodeOrDie().getPage();
String uri = page.getUrl().toExternalForm();
try {
// Retrieve the associated content and respect client settings regarding failing HTTP status codes.
final WebRequest request;
final WebResponse response;
final WebClient client = page.getWebClient();
if (link == null) {
// Use href.
final BrowserVersion browser = client.getBrowserVersion();
request = new WebRequest(new URL(url), browser.getCssAcceptHeader(), browser.getAcceptEncodingHeader());
request.setRefererlHeader(page.getUrl());
// our cache is a bit strange;
// loadWebResponse check the cache for the web response
// AND also fixes the request url for the following cache lookups
response = client.loadWebResponse(request);
} else {
// Use link.
request = link.getWebRequest();
if (element.getBrowserVersion().hasFeature(HTMLLINK_CHECK_TYPE_FOR_STYLESHEET)) {
final String type = link.getTypeAttribute();
if (StringUtils.isNotBlank(type) && !MimeType.TEXT_CSS.equals(type)) {
return new CSSStyleSheet(element, "", uri);
}
}
// our cache is a bit strange;
// loadWebResponse check the cache for the web response
// AND also fixes the request url for the following cache lookups
response = link.getWebResponse(true, request);
}
// now we can look into the cache with the fixed request for
// a cached script
final Cache cache = client.getCache();
final Object fromCache = cache.getCachedObject(request);
if (fromCache instanceof CSSStyleSheetImpl) {
uri = request.getUrl().toExternalForm();
return new CSSStyleSheet(element, element.getWindow(), (CSSStyleSheetImpl) fromCache, uri);
}
uri = response.getWebRequest().getUrl().toExternalForm();
client.printContentIfNecessary(response);
client.throwFailingHttpStatusCodeExceptionIfNecessary(response);
// CSS content must have downloaded OK; go ahead and build the corresponding stylesheet.
final CSSStyleSheet sheet;
final String contentType = response.getContentType();
if (StringUtils.isEmpty(contentType) || MimeType.TEXT_CSS.equals(contentType)) {
final InputStream in = response.getContentAsStreamWithBomIfApplicable();
if (in == null) {
if (LOG.isWarnEnabled()) {
LOG.warn("Loading stylesheet for url '" + uri + "' returns empty responseData");
}
return new CSSStyleSheet(element, "", uri);
}
try {
Charset cssEncoding = Charset.forName("windows-1252");
final Charset contentCharset = EncodingSniffer.sniffEncodingFromHttpHeaders(response.getResponseHeaders());
if (contentCharset == null && request.getCharset() != null) {
cssEncoding = request.getCharset();
} else if (contentCharset != null) {
cssEncoding = contentCharset;
}
if (in instanceof BOMInputStream) {
final BOMInputStream bomIn = (BOMInputStream) in;
// we have to call this before hasBOM(ByteOrderMark)
if (bomIn.hasBOM()) {
if (bomIn.hasBOM(ByteOrderMark.UTF_8)) {
cssEncoding = UTF_8;
} else if (bomIn.hasBOM(ByteOrderMark.UTF_16BE)) {
cssEncoding = UTF_16BE;
} else if (bomIn.hasBOM(ByteOrderMark.UTF_16LE)) {
cssEncoding = UTF_16LE;
}
}
}
try (InputSource source = new InputSource(new InputStreamReader(in, cssEncoding))) {
source.setURI(uri);
sheet = new CSSStyleSheet(element, source, uri);
}
} finally {
in.close();
}
} else {
sheet = new CSSStyleSheet(element, "", uri);
}
// cache the style sheet
if (!cache.cacheIfPossible(request, response, sheet.getWrappedSheet())) {
response.cleanUp();
}
return sheet;
} catch (final FailingHttpStatusCodeException e) {
// Got a 404 response or something like that; behave nicely.
if (LOG.isErrorEnabled()) {
LOG.error("Exception loading " + uri, e);
}
return new CSSStyleSheet(element, "", uri);
} catch (final IOException e) {
// Got a basic IO error; behave nicely.
if (LOG.isErrorEnabled()) {
LOG.error("IOException loading " + uri, e);
}
return new CSSStyleSheet(element, "", uri);
} catch (final RuntimeException e) {
// Got something unexpected; we can throw an exception in this case.
if (LOG.isErrorEnabled()) {
LOG.error("RuntimeException loading " + uri, e);
}
throw Context.reportRuntimeError("Exception: " + e);
} catch (final Exception e) {
// Got something unexpected; we can throw an exception in this case.
if (LOG.isErrorEnabled()) {
LOG.error("Exception loading " + uri, e);
}
throw Context.reportRuntimeError("Exception: " + e);
}
}
use of com.gargoylesoftware.css.dom.CSSStyleSheetImpl in project LoboEvolution by LoboEvolution.
the class BackgroundImageSetter method changeValue.
/**
* {@inheritDoc}
*/
@Override
public void changeValue(AbstractCSSProperties properties, String newValue, CSSStyleDeclarationImpl declaration, boolean important) {
String baseHref = null;
String finalValue;
if (declaration != null) {
final AbstractCSSRuleImpl rule = declaration.getParentRule();
if (rule != null) {
final CSSStyleSheetImpl sheet = rule.getParentStyleSheet();
final CSSStyleSheetImpl ssheet = sheet;
baseHref = ssheet.getHref();
}
}
if (baseHref == null) {
baseHref = properties.getContext().getDocumentBaseURI();
}
final String start = "url(";
if (newValue == null || !newValue.toLowerCase().startsWith(start)) {
finalValue = newValue;
} else {
final int startIdx = start.length();
final int closingIdx = newValue.lastIndexOf(')');
if (closingIdx == -1) {
finalValue = newValue;
} else {
final String quotedUri = newValue.substring(startIdx, closingIdx);
final String tentativeUri = HtmlValues.unquoteAndUnescape(quotedUri);
if (baseHref == null) {
finalValue = newValue;
} else {
try {
final URL styleUrl = Urls.createURL(null, baseHref);
if (tentativeUri.contains("data:image")) {
finalValue = tentativeUri;
} else {
finalValue = "url(" + HtmlValues.quoteAndEscape(Urls.createURL(styleUrl, tentativeUri).toExternalForm()) + ")";
}
} catch (final Exception mfu) {
logger.log(Level.WARNING, "Unable to create URL for URI=[" + tentativeUri + "], with base=[" + baseHref + "].", mfu);
finalValue = newValue;
}
}
}
}
properties.setPropertyValueLCAlt(BACKGROUND_IMAGE, finalValue, important);
}
use of com.gargoylesoftware.css.dom.CSSStyleSheetImpl in project htmlunit by HtmlUnit.
the class HTMLStyleElement method getSheet.
/**
* Gets the associated sheet.
* @see <a href="http://www.xulplanet.com/references/objref/HTMLStyleElement.html">Mozilla doc</a>
* @return the sheet
*/
@JsxGetter
public CSSStyleSheet getSheet() {
if (sheet_ != null) {
return sheet_;
}
final HtmlStyle style = (HtmlStyle) getDomNodeOrDie();
final String css = style.getTextContent();
final Window window = getWindow();
final Cache cache = window.getWebWindow().getWebClient().getCache();
final CSSStyleSheetImpl cached = cache.getCachedStyleSheet(css);
final String uri = getDomNodeOrDie().getPage().getWebResponse().getWebRequest().getUrl().toExternalForm();
if (cached != null) {
sheet_ = new CSSStyleSheet(this, window, cached, uri);
} else {
sheet_ = new CSSStyleSheet(this, css, uri);
cache.cache(css, sheet_.getWrappedSheet());
}
return sheet_;
}
use of com.gargoylesoftware.css.dom.CSSStyleSheetImpl in project htmlunit by HtmlUnit.
the class CSSStyleSheet method parseCSS.
/**
* Parses the CSS at the specified input source. If anything at all goes wrong, this method
* returns an empty stylesheet.
*
* @param source the source from which to retrieve the CSS to be parsed
* @param client the client
* @return the stylesheet parsed from the specified input source
*/
private static CSSStyleSheetImpl parseCSS(final InputSource source, final WebClient client) {
CSSStyleSheetImpl ss;
try {
final CSSErrorHandler errorHandler = client.getCssErrorHandler();
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
parser.setErrorHandler(errorHandler);
ss = parser.parseStyleSheet(source, null);
} catch (final Throwable t) {
if (LOG.isErrorEnabled()) {
LOG.error("Error parsing CSS from '" + toString(source) + "': " + t.getMessage(), t);
}
ss = new CSSStyleSheetImpl();
}
return ss;
}
use of com.gargoylesoftware.css.dom.CSSStyleSheetImpl in project htmlunit by HtmlUnit.
the class CSSStyleSheet method getRuleIndex.
private CSSStyleSheetImpl.CSSStyleSheetRuleIndex getRuleIndex() {
final CSSStyleSheetImpl styleSheet = getWrappedSheet();
CSSStyleSheetImpl.CSSStyleSheetRuleIndex index = styleSheet.getRuleIndex();
if (index == null) {
index = new CSSStyleSheetImpl.CSSStyleSheetRuleIndex();
final CSSRuleListImpl ruleList = styleSheet.getCssRules();
index(index, ruleList, new HashSet<>());
styleSheet.setRuleIndex(index);
}
return index;
}
Aggregations