/******************************************************************************* * Copyright (c) 2011, 2013 Tasktop Technologies. * 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: * David Green - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.wikitext.internal.parser.html; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.mylyn.wikitext.parser.css.CssParser; import org.eclipse.mylyn.wikitext.parser.css.CssRule; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import org.jsoup.select.Selector; /** * Removes excessive inline styles from HTML, * * @author David Green */ public class RemoveExcessiveStylesProcessor extends DocumentProcessor { @Override public void process(Document document) { Element body = document.body(); CssParser cssParser = new CssParser(); for (Element element : Selector.select("[style], font, span", body)) { //$NON-NLS-1$ String style = element.attr("style"); //$NON-NLS-1$ String newStyle = ""; //$NON-NLS-1$ List<CssRule> rules = null; if (style != null && style.length() > 0) { rules = cssParser.parseBlockContent(style); Iterator<CssRule> ruleIt = rules.iterator(); while (ruleIt.hasNext()) { CssRule rule = ruleIt.next(); if ("color".equals(rule.name)) { //$NON-NLS-1$ if (!(rule.value.equalsIgnoreCase("black") || rule.value.equals("#010101"))) { //$NON-NLS-1$//$NON-NLS-2$ continue; } } else if ("font-weight".equals(rule.name)) { //$NON-NLS-1$ if (rule.value.equalsIgnoreCase("bold") || rule.value.equalsIgnoreCase("bolder")) { //$NON-NLS-1$ //$NON-NLS-2$ continue; } } else if ("font-style".equals(rule.name)) { //$NON-NLS-1$ if (rule.value.equalsIgnoreCase("bold") || rule.value.equalsIgnoreCase("italic")) { //$NON-NLS-1$ //$NON-NLS-2$ continue; } } else if ("text-decoration".equals(rule.name)) { //$NON-NLS-1$ if (rule.value.equalsIgnoreCase("underline") || rule.value.equalsIgnoreCase("line-through")) { //$NON-NLS-1$ //$NON-NLS-2$ continue; } } ruleIt.remove(); } } if ("font".equalsIgnoreCase(element.nodeName())) { //$NON-NLS-1$ String color = element.attr("color"); //$NON-NLS-1$ if (color != null && color.trim().length() > 0) { if (rules == null) { rules = new ArrayList<CssRule>(1); } rules.add(new CssRule("color", color.trim(), 0, 0, 0, 0)); //$NON-NLS-1$ } } if (rules != null) { for (CssRule rule : rules) { newStyle += rule.name + ": " + rule.value + ";"; //$NON-NLS-1$ //$NON-NLS-2$ } } if (newStyle.length() > 0) { if ("font".equalsIgnoreCase(element.nodeName())) { //$NON-NLS-1$ Element spanElement = document.createElement("span"); //$NON-NLS-1$ for (Node child : new ArrayList<Node>(element.childNodes())) { child.remove(); spanElement.appendChild(child); } element.before(spanElement); element.remove(); element = spanElement; } element.attr("style", newStyle); //$NON-NLS-1$ } else { element.removeAttr("style"); //$NON-NLS-1$ if (("span".equalsIgnoreCase(element.nodeName()) && (element.attr("class").trim().isEmpty())) //$NON-NLS-1$//$NON-NLS-2$ || "font".equalsIgnoreCase(element.nodeName())) { //$NON-NLS-1$ removeElementPreserveChildren(element); } } } } private void removeElementPreserveChildren(Element element) { final Element parent = element.parent(); for (Node child : new ArrayList<Node>(element.childNodes())) { child.remove(); element.before(child); } element.remove(); if (parent != null) { normalizeTextNodes(parent); } } }