org.cobraparser.html.domimpl.HTMLStyleElementImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Cobra Show documentation
Show all versions of Cobra Show documentation
Cobra is the rendering engine designed for LoboBrowser
/*
GNU LESSER GENERAL PUBLIC LICENSE
Copyright (C) 2006 The Lobo Project
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Contact info: [email protected]
*/
/*
* Created on Nov 27, 2005
*/
package org.cobraparser.html.domimpl;
import org.cobraparser.html.style.CSSUtilities;
import org.cobraparser.ua.UserAgentContext;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.w3c.dom.css.CSSStyleSheet;
import org.w3c.dom.html.HTMLStyleElement;
import org.w3c.dom.stylesheets.LinkStyle;
import org.cobraparser.css.domimpl.JStyleSheetWrapper;
import cz.vutbr.web.css.StyleSheet;
public class HTMLStyleElementImpl extends HTMLElementImpl implements HTMLStyleElement, LinkStyle {
private JStyleSheetWrapper styleSheet;
public HTMLStyleElementImpl() {
super("STYLE", true);
}
public HTMLStyleElementImpl(final String name) {
super(name, true);
}
private boolean disabled;
public boolean getDisabled() {
return this.disabled;
}
public void setDisabled(final boolean disabled) {
this.disabled = disabled;
final CSSStyleSheet sheet = this.styleSheet;
if (sheet != null) {
sheet.setDisabled(disabled);
}
}
//TODO hide from JS
public void setDisabledImpl(final boolean disabled) {
this.disabled = disabled;
}
public String getMedia() {
return this.getAttribute("media");
}
public void setMedia(final String media) {
this.setAttribute("media", media);
}
public String getType() {
return this.getAttribute("type");
}
public void setType(final String type) {
this.setAttribute("type", type);
}
// TODO: This should probably not be a nop. We should probably be handling changes to inner text.
@Override
protected void appendInnerTextImpl(final StringBuffer buffer) {
// nop
}
@Override
public void setAttribute(final String name, final String value) throws DOMException {
super.setAttribute(name, value);
if (isAttachedToDocument()) {
final String nameLowerCase = name.toLowerCase();
if ("type".equals(nameLowerCase) || "media".equals(nameLowerCase) || "title".equals(nameLowerCase)) {
this.disabled = false;
this.processStyle();
}
}
}
private String getOnlyText() {
final NodeList nl = this.getChildNodes();
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < nl.getLength(); i++) {
final Node n = nl.item(i);
if (n.getNodeType() == Node.TEXT_NODE) {
final Text textNode = (Text) n;
sb.append(textNode.getTextContent());
}
}
return sb.toString();
}
private boolean isAllowedType() {
final String type = this.getType();
return ((type == null) || (type.trim().length() == 0) || (type.equalsIgnoreCase("text/css")));
}
// TODO: check if this method can be made private
protected void processStyle() {
if (isAttachedToDocument()) {
/* check if type == "text/css" or no, empty value is also allowed as well.
if it is something other than empty or "text/css" set the style sheet to null
we need not check for the media type here, jStyle parser should take care of this.
*/
if (isAllowedType()) {
final UserAgentContext uacontext = this.getUserAgentContext();
if (uacontext.isInternalCSSEnabled()) {
final HTMLDocumentImpl doc = (HTMLDocumentImpl) this.getOwnerDocument();
final JStyleSheetWrapper newStyleSheet = processStyleHelper();
newStyleSheet.setDisabled(this.disabled);
this.styleSheet = newStyleSheet;
doc.styleSheetManager.invalidateStyles();
}
} else {
this.detachStyleSheet();
}
}
}
private JStyleSheetWrapper processStyleHelper() {
final HTMLDocumentImpl doc = (HTMLDocumentImpl) this.getOwnerDocument();
// TODO a sanity check can be done for the media type while setting it to the style sheet
// as in is it a valid media type or not
try {
final String text = this.getOnlyText();
final String processedText = CSSUtilities.preProcessCss(text);
final String baseURI = doc.getBaseURI();
// TODO if the new StyleSheet contains any @import rules, then we should queue them for further processing. GH #137
final StyleSheet jSheet = CSSUtilities.jParseStyleSheet(this, baseURI, processedText, doc.getUserAgentContext());
return new JStyleSheetWrapper(jSheet, this.getMedia(), null, this.getType(), this.getTitle(), this, doc.styleSheetManager.bridge);
} catch (final Exception err) {
this.warn("Unable to parse style sheet", err);
}
return this.getEmptyStyleSheet();
}
private JStyleSheetWrapper getEmptyStyleSheet() {
final HTMLDocumentImpl doc = (HTMLDocumentImpl) this.getOwnerDocument();
return new JStyleSheetWrapper(CSSUtilities.getEmptyStyleSheet(), this.getMedia(), null, this.getType(), this.getTitle(), this,
doc.styleSheetManager.bridge);
}
private void detachStyleSheet() {
if (this.styleSheet != null) {
this.styleSheet.setOwnerNode(null);
this.styleSheet = null;
final HTMLDocumentImpl doc = (HTMLDocumentImpl) this.getOwnerDocument();
doc.styleSheetManager.invalidateStyles();
}
}
public CSSStyleSheet getSheet() {
return this.styleSheet;
}
@Override
protected void handleChildListChanged() {
this.processStyle();
}
@Override
protected void handleDocumentAttachmentChanged() {
if (isAttachedToDocument()) {
this.processStyle();
} else {
this.detachStyleSheet();
}
}
}