blob: 34ef4324823f715c138e3b6b078157795b14e9c6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.pagedesigner.css2;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.dtresourceprovider.DTSkinManager;
import org.eclipse.jst.pagedesigner.dtresourceprovider.IDTSkin;
import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetAdapter;
import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetListAdapter;
import org.eclipse.wst.html.core.internal.provisional.HTML40Namespace;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.stylesheets.StyleSheet;
import org.w3c.dom.stylesheets.StyleSheetList;
/**
* @author mengbo
* @version 1.5
*/
public final class CSSTempUtil {
/**
* the default implementation of (IStyleSheetListAdapter)
* docnotifier.getAdapterFor(IStyleSheetListAdapter.class) will only get
* those style tags under certain tags like "html", "head", etc.
*
* But datawindow is generating style tag and is not putting them into
* "head". So we can't handle them using the default SSE mechanism.
*
* We have another problem: currently the converted element is also using
* the original document, not generating another document, and these
* elements is not really adding into the document, so they can't be reached
* from the document.
*
* @param element
* @return the list
* see org.eclipse.wst.html.core.htmlcss.HTMLDocumentAdapter#addStyleSheet(org.w3c.dom.Element)
*/
public static List getStyleSheets(Element element) {
List styleSheets = new ArrayList();
INodeNotifier docnotifier = (INodeNotifier) element.getOwnerDocument();
IStyleSheetListAdapter adapter = (IStyleSheetListAdapter) docnotifier
.getAdapterFor(IStyleSheetListAdapter.class);
StyleSheetList ssl = (adapter == null ? null : adapter.getStyleSheets());
if (ssl != null) {
for (int i = 0, numStyles = ssl.getLength(); i < numStyles; i++) {
// loop for styles (<style> and <link>)
org.w3c.dom.stylesheets.StyleSheet ss = ssl.item(i);
styleSheets.add(ss);
}
}
// now is our work-around part for support datawindow.
Node parent = element.getParentNode();
Element rootEle = element;
while (parent != null && parent instanceof Element) {
rootEle = (Element) parent;
parent = parent.getParentNode();
}
addStyleSheet(rootEle, styleSheets);
//add stylesheets from any active IDTSkin instances
if (element instanceof IDOMNode) {
List<IDTSkin> dtSkins =
DTSkinManager.getInstance((IDOMNode)element).getCurrentSkins();
for (IDTSkin dtSkin: dtSkins) {
if (dtSkin != null) {
styleSheets.addAll(dtSkin.getStyleSheets());
}
}
}
return styleSheets;
}
/**
*/
private static void addStyleSheet(Element node, List result) {
IDOMElement element = (IDOMElement) node;
String tagName = element.getTagName();
if (tagName == null) {
return;
}
boolean isContainer = false;
if (element.isCommentTag()) {
Node parent = element.getParentNode();
if (parent == element.getOwnerDocument()) {
// This condition is too severe, actually do not work for JSF
// template.
// But above (! globalTag() && isContainer()) cover JSF template
// + tpl template
isContainer = true;
} else if (parent.getNodeType() == Node.ELEMENT_NODE) {
tagName = ((Element) parent).getTagName();
if (tagName != null
&& tagName
.equalsIgnoreCase(HTML40Namespace.ElementName.HEAD)) {
isContainer = true;
}
}
} else {
INodeNotifier notifier = element;
// (lium) Increase performance: since this method is called tooooo
// many times,
// and getAdapterFor() is slow, so add a check on the tagName to
// filter
// those stylesheet stuff first.
if (IHTMLConstants.TAG_LINK.equalsIgnoreCase(tagName)
|| IHTMLConstants.TAG_STYLE.equalsIgnoreCase(tagName)) {
INodeAdapter adapter = notifier
.getAdapterFor(IStyleSheetAdapter.class);
if (adapter instanceof IStyleSheetAdapter) {
// XXX: see bug 171740. This is a (hopefully) temporary
// workaround that avoids having the call to getSheet throw an NPE
IStyleSheetAdapter sheetAdapter = (IStyleSheetAdapter) adapter;
if (sheetAdapter.getElement() != null
&& "text/css".equals(sheetAdapter.getElement().getAttribute(HTML40Namespace.ATTR_NAME_TYPE))) //$NON-NLS-1$
{
StyleSheet sheet = ((IStyleSheetAdapter) adapter)
.getSheet();
if (sheet != null)
{
result.add(sheet);
}
}
}
}
isContainer = true;
}
if (isContainer) {
for (Node child = element.getFirstChild(); child != null; child = child
.getNextSibling()) {
if (child.getNodeType() != Node.ELEMENT_NODE)
continue;
addStyleSheet((Element) child, result);
}
}
}
private CSSTempUtil()
{
// util class, no instantiation
}
}