summaryrefslogtreecommitdiff
path: root/gnu/javax/swing/text/html
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/javax/swing/text/html')
-rw-r--r--gnu/javax/swing/text/html/css/BorderWidth.java (renamed from gnu/javax/swing/text/html/parser/HTML_401Swing.java)65
-rw-r--r--gnu/javax/swing/text/html/css/CSSColor.java29
-rw-r--r--gnu/javax/swing/text/html/css/CSSParser.java23
-rw-r--r--gnu/javax/swing/text/html/css/CSSParserCallback.java2
-rw-r--r--gnu/javax/swing/text/html/css/CSSScanner.java1
-rw-r--r--gnu/javax/swing/text/html/css/Length.java64
-rw-r--r--gnu/javax/swing/text/html/css/Selector.java233
-rw-r--r--gnu/javax/swing/text/html/parser/GnuParserDelegator.java3
-rw-r--r--gnu/javax/swing/text/html/parser/support/Parser.java21
9 files changed, 372 insertions, 69 deletions
diff --git a/gnu/javax/swing/text/html/parser/HTML_401Swing.java b/gnu/javax/swing/text/html/css/BorderWidth.java
index 9c934f647..b717020e3 100644
--- a/gnu/javax/swing/text/html/parser/HTML_401Swing.java
+++ b/gnu/javax/swing/text/html/css/BorderWidth.java
@@ -1,4 +1,4 @@
-/* HTML_401Swing.java -- The HTML 4.01 DTD, adapted for HTML rendering in Swing
+/* BorderWidth.java -- A CSS metric for border widths
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,56 +36,31 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-package gnu.javax.swing.text.html.parser;
-
-import javax.swing.text.html.parser.DTD;
+package gnu.javax.swing.text.html.css;
/**
- * This class is necessary because the current implementation of the GNU
- * Classpath Swing requires always enclose the text into paragraphs.
- *
- * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ * A special CSS metric for border widths. It basically understands everything
+ * as Length, and in addition to that provides a mapping for the border-width's
+ * thin, medium and think values.
*/
-public class HTML_401Swing extends HTML_401F
+public class BorderWidth
+ extends Length
{
+
/**
- * The singleton instance;
- */
- final static HTML_401Swing singleton = new HTML_401Swing();
-
- /**
- * Either takes the document (by name) from DTD table, or
- * creates a new instance and registers it in the tabe.
- * The document is registerd under name "-//W3C//DTD HTML 4.01 Frameset//EN".
- * @return The new or existing DTD for parsing HTML 4.01 Frameset.
- */
- public static DTD getInstance()
- {
- return singleton;
- }
-
- /**
- * Get elements that are allowed in the document body, at the zero level.
- * This list disallows the text at this level (the implied P tag will be
- * generated). It also disallows A, B, I, U, CITE and other similar
- * elements that have the plain text inside. They will also be placed
- * inside the generated implied P tags.
+ * Creates a new BorderWidth instance.
+ *
+ * @param val the CSS value to be interpreted
*/
- protected String[] getBodyElements()
+ public BorderWidth(String val)
{
- return new String[] {
- APPLET, BASEFONT,
- BR, BUTTON,
- IFRAME, IMG,
- INPUT, LABEL, MAP, OBJECT,
- SCRIPT, SELECT,
- TEXTAREA,
- BLOCKQUOTE, CENTER, DEL, DIR,
- DIV, DL, FIELDSET, FORM, H1,
- H2, H3, H4, H5, H6,
- HR, INS, ISINDEX, MENU, NOFRAMES,
- NOSCRIPT, OL, P, PRE, TABLE,
- UL
- };
+ super(val);
+ if (val.equals("thin"))
+ floatValue = 1.F;
+ else if (val.equals("medium"))
+ floatValue = 2.F;
+ else if (val.equals("thick"))
+ floatValue = 3.F;
}
+
}
diff --git a/gnu/javax/swing/text/html/css/CSSColor.java b/gnu/javax/swing/text/html/css/CSSColor.java
index 381bcd5ed..57230f12a 100644
--- a/gnu/javax/swing/text/html/css/CSSColor.java
+++ b/gnu/javax/swing/text/html/css/CSSColor.java
@@ -40,6 +40,8 @@ package gnu.javax.swing.text.html.css;
import java.awt.Color;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
/**
* Converts CSS color values into AWT Color values.
@@ -131,4 +133,31 @@ public class CSSColor
{
return value;
}
+
+ /**
+ * Returns <code>true</code> if the specified value is a valid color value,
+ * <code>false</code> otherwise.
+ *
+ * @param val the value to check
+ *
+ * @return <code>true</code> if the specified value is a valid color value,
+ * <code>false</code> otherwise
+ */
+ public static boolean isValidColor(String val)
+ {
+ boolean ret = false;
+ if (val.charAt(0) == '#')
+ ret = true;
+ else
+ {
+ Set colors = COLOR_MAP.keySet();
+ for (Iterator i = colors.iterator(); i.hasNext() && ret == false;)
+ {
+ String color = (String) i.next();
+ if (color.equalsIgnoreCase(val))
+ ret = true;
+ }
+ }
+ return ret;
+ }
}
diff --git a/gnu/javax/swing/text/html/css/CSSParser.java b/gnu/javax/swing/text/html/css/CSSParser.java
index 190c93eb4..0d68457a3 100644
--- a/gnu/javax/swing/text/html/css/CSSParser.java
+++ b/gnu/javax/swing/text/html/css/CSSParser.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package gnu.javax.swing.text.html.css;
import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -156,7 +158,7 @@ public class CSSParser
{
StringBuilder selector = new StringBuilder();
parseSelector(selector);
- callback.startStatement(selector.toString());
+ callback.startStatement(new Selector(selector.toString()));
// Read any number of whitespace.
int token;
do
@@ -296,7 +298,9 @@ public class CSSParser
throws IOException
{
// FIXME: Handle block and ATKEYWORD.
- return parseAny(s);
+ boolean success = parseAny(s);
+ while (parseAny(s));
+ return success;
}
/**
@@ -439,13 +443,22 @@ public class CSSParser
{
try
{
- String name = "/javax/swing/text/html/default.css";
- InputStream in = CSSScanner.class.getResourceAsStream(name);
+ InputStream in;
+ if (args.length > 0)
+ {
+ File file = new File(args[0]);
+ in = new FileInputStream(file);
+ }
+ else
+ {
+ String name = "/javax/swing/text/html/default.css";
+ in = CSSScanner.class.getResourceAsStream(name);
+ }
BufferedInputStream bin = new BufferedInputStream(in);
InputStreamReader r = new InputStreamReader(bin);
CSSParserCallback cb = new CSSParserCallback()
{
- public void startStatement(String selector)
+ public void startStatement(Selector selector)
{
System.out.println("startStatement: " + selector);
}
diff --git a/gnu/javax/swing/text/html/css/CSSParserCallback.java b/gnu/javax/swing/text/html/css/CSSParserCallback.java
index 60dc5488a..b62baddfc 100644
--- a/gnu/javax/swing/text/html/css/CSSParserCallback.java
+++ b/gnu/javax/swing/text/html/css/CSSParserCallback.java
@@ -62,7 +62,7 @@ public interface CSSParserCallback
*
* @param selector the selector of the statement.
*/
- void startStatement(String selector);
+ void startStatement(Selector selector);
/**
* Signals the end of a statement.
diff --git a/gnu/javax/swing/text/html/css/CSSScanner.java b/gnu/javax/swing/text/html/css/CSSScanner.java
index a402b9522..9cc6209a5 100644
--- a/gnu/javax/swing/text/html/css/CSSScanner.java
+++ b/gnu/javax/swing/text/html/css/CSSScanner.java
@@ -509,6 +509,7 @@ class CSSScanner
{
parseBuffer[tokenEnd] = (char) ch;
tokenEnd++;
+ ch = read();
}
// Push back last read character since it doesn't belong to the IDENT.
diff --git a/gnu/javax/swing/text/html/css/Length.java b/gnu/javax/swing/text/html/css/Length.java
index 7091fbae7..339e2a2e0 100644
--- a/gnu/javax/swing/text/html/css/Length.java
+++ b/gnu/javax/swing/text/html/css/Length.java
@@ -54,7 +54,12 @@ public class Length
/**
* The converted value.
*/
- private float floatValue;
+ protected float floatValue;
+
+ /**
+ * Indicates when the value is a percentage value.
+ */
+ private boolean isPercentage;
/**
* Creates a new length converter instance.
@@ -65,16 +70,31 @@ public class Length
{
value = val;
int i = value.indexOf("px");
- floatValue = 0.0F;
- if (i != -1)
+ int percent = value.indexOf("%");
+ try
{
- String sub = value.substring(0, i);
- floatValue = Float.parseFloat(sub);
+ floatValue = 0.0F;
+ if (i != -1)
+ {
+ String sub = value.substring(0, i);
+ floatValue = Float.parseFloat(sub);
+ }
+ else if (percent != -1)
+ {
+ isPercentage = true;
+ String sub = value.substring(0, percent);
+ floatValue = Float.parseFloat(sub) / 100;
+ }
+ else
+ {
+ // TODO: Implement other length options.
+ floatValue = Float.parseFloat(value);
+ }
}
- else
+ catch (NumberFormatException ex)
{
- // TODO: Implement other length options.
- floatValue = Float.parseFloat(value);
+ // Don't let such small problems interrupt CSS parsing.
+ System.err.println("couldn't parse: " + val);
}
}
@@ -87,4 +107,32 @@ public class Length
{
return floatValue;
}
+
+ /**
+ * Returns the absolute span for the case when this length value is
+ * a relative value.
+ *
+ * @param available the target span
+ *
+ * @return the absolute span
+ */
+ public float getValue(float available)
+ {
+ float span = floatValue;
+ if (isPercentage)
+ span *= available;
+ return span;
+ }
+
+ /**
+ * Returns <code>true</code> when the length value is a percentage
+ * value, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> when the length value is a percentage
+ * value, <code>false</code> otherwise
+ */
+ public boolean isPercentage()
+ {
+ return isPercentage;
+ }
}
diff --git a/gnu/javax/swing/text/html/css/Selector.java b/gnu/javax/swing/text/html/css/Selector.java
new file mode 100644
index 000000000..75f2d46c6
--- /dev/null
+++ b/gnu/javax/swing/text/html/css/Selector.java
@@ -0,0 +1,233 @@
+/* Selector.java -- A CSS selector
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.swing.text.html.css;
+
+import java.util.StringTokenizer;
+
+/**
+ * A CSS selector. This provides methods to interpret a selector and
+ * query matches with an actual HTML element tree.
+ */
+public class Selector
+{
+
+ /**
+ * The actual selector. The selector tokens are stored backwards, that
+ * is the last token first. This makes matching easier.
+ */
+ private String[] selector;
+
+ private String[] elements;
+ private String[] ids;
+ private String[] classes;
+
+ /**
+ * The specificity of the selector.
+ */
+ private int specificity;
+
+ /**
+ * An implicit selector has true here. This is the case for CSS rules that
+ * are attached to HTML elements directly via style="<CSS rule>".
+ */
+ private boolean implicit;
+
+ /**
+ * Creates a new Selector instance for the specified selector string.
+ *
+ * @param sel the selector
+ */
+ public Selector(String sel)
+ {
+ StringTokenizer selectorTokens = new StringTokenizer(sel, " ");
+ selector = new String[selectorTokens.countTokens()];
+ for (int i = selector.length - 1; selectorTokens.hasMoreTokens(); i--)
+ {
+ selector[i] = selectorTokens.nextToken();
+ }
+ calculateSpecificity();
+ }
+
+ /**
+ * Determines if this selector matches the element path specified in the
+ * arguments. The arguments hold the element names as well as class
+ * and id attibutes of the HTML element to be queried. The first item
+ * in the array is the deepest element and the last on the highest up (for
+ * instance, the html tag).
+ *
+ * @param tags
+ * @param classes
+ * @param ids
+ *
+ * @return <code>true</code> when this selector matches the element path,
+ * <code>false</code> otherwise
+ */
+ public boolean matches(String[] tags, String[] pathClasses, String[] pathIds)
+ {
+ // TODO: This implements class, id and descendent matching. These are
+ // the most commonly used selector matchers in CSS together with HTML.
+ // However, the CSS spec defines a couple of more sophisticated matches
+ // which should be implemented.
+ // http://www.w3.org/TR/CSS21/selector.html
+
+ // All parts of the selector must match at some point.
+ boolean match = false;
+ int numTags = tags.length;
+ int numSel = selector.length;
+ if (numSel <= numTags)
+ {
+ match = true;
+ int tagIndex = 0;
+ for (int j = 0; j < numSel && match; j++)
+ {
+ boolean tagMatch = false;
+ for (; tagIndex < numTags && tagMatch == false; tagIndex++)
+ {
+ String tag = elements[j];
+ String clazz = classes[j];
+ String id = ids[j];
+ tagMatch = tag.equals("") || tag.equals("*")
+ || tag.equals(tags[tagIndex]);
+ tagMatch = tagMatch && (clazz.equals("*")
+ || clazz.equals(pathClasses[tagIndex]));
+ tagMatch = tagMatch && (id.equals("*")
+ || id.equals(pathIds[tagIndex]));
+ // For the last element in the selector we must not look
+ // further.
+ if (j == 0)
+ break;
+ }
+ // If we don't come out here with a matching tag, then we're
+ // not matching at all.
+ match = tagMatch;
+ }
+ }
+ return match;
+ }
+
+ /**
+ * Returns the specificity of the selector. This is calculated according
+ * to:
+ * http://www.w3.org/TR/CSS21/cascade.html#specificity
+ *
+ * @return the specificity of the selector
+ */
+ public int getSpecificity()
+ {
+ return specificity;
+ }
+
+ /**
+ * Returns a string representation of the selector. This tries to reconstruct
+ * the original selector as closely as possible.
+ *
+ * @return a string representation of the selector
+ */
+ public String toString()
+ {
+ StringBuilder b = new StringBuilder();
+ for (int i = selector.length - 1; i >= 0; i--)
+ {
+ b.append(selector[i]);
+ if (i > 0)
+ b.append(' ');
+ }
+ return b.toString();
+ }
+
+ /**
+ * Calculates the specificity of the selector. This is calculated according
+ * to:
+ * http://www.w3.org/TR/CSS21/cascade.html#specificity
+ */
+ private void calculateSpecificity()
+ {
+ int a = implicit ? 1 : 0;
+ int b = 0;
+ int c = 0;
+ int d = 0;
+ int numSel = selector.length;
+ elements = new String[numSel];
+ ids = new String[numSel];
+ classes = new String[numSel];
+ for (int i = 0; i < numSel; i++)
+ {
+ String sel = selector[i];
+ int clazzIndex = sel.indexOf('.');
+ int idIndex = sel.indexOf('#');
+ String clazz;
+ if (clazzIndex == -1)
+ {
+ clazz = "*";
+ clazzIndex = sel.length();
+ }
+ else
+ {
+ c++;
+ clazz = sel.substring(clazzIndex + 1,
+ idIndex > 0 ? Math.min(idIndex, sel.length())
+ : sel.length());
+ }
+ String id;
+ if (idIndex == -1)
+ {
+ id = "*";
+ idIndex = sel.length();
+ }
+ else
+ {
+ b++;
+ id = sel.substring(idIndex + 1,
+ clazzIndex > 0 ? Math.min(idIndex, sel.length())
+ : sel.length());
+ }
+ String tag = sel.substring(0,
+ Math.min(Math.min(clazzIndex, idIndex),
+ sel.length()));
+ if (! tag.equals("") && ! tag.equals("*"))
+ d++;
+
+ elements[i] = tag;
+ ids[i] = id;
+ classes[i] = clazz;
+ }
+ // An order of 20 should be enough for everybody.
+ specificity = a * 20 ^ 3 + b * 20 ^ 2 + c * 20 + d;
+ }
+}
diff --git a/gnu/javax/swing/text/html/parser/GnuParserDelegator.java b/gnu/javax/swing/text/html/parser/GnuParserDelegator.java
index 841db667e..273461a72 100644
--- a/gnu/javax/swing/text/html/parser/GnuParserDelegator.java
+++ b/gnu/javax/swing/text/html/parser/GnuParserDelegator.java
@@ -43,6 +43,7 @@ import java.io.Reader;
import java.io.Serializable;
import javax.swing.text.BadLocationException;
+import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.parser.DTD;
@@ -92,7 +93,7 @@ public class GnuParserDelegator extends ParserDelegator implements Serializable
protected final void handleStartTag(TagElement tag)
{
- htmlAttributeSet attributes = gnu.getAttributes();
+ SimpleAttributeSet attributes = gnu.getAttributes();
if (tag.fictional())
attributes.addAttribute(ParserCallback.IMPLIED, Boolean.TRUE);
diff --git a/gnu/javax/swing/text/html/parser/support/Parser.java b/gnu/javax/swing/text/html/parser/support/Parser.java
index 92f9b27c5..f1f25fad0 100644
--- a/gnu/javax/swing/text/html/parser/support/Parser.java
+++ b/gnu/javax/swing/text/html/parser/support/Parser.java
@@ -56,6 +56,7 @@ import java.util.TreeSet;
import java.util.Vector;
import javax.swing.text.ChangedCharSetException;
+import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.parser.AttributeList;
import javax.swing.text.html.parser.DTD;
@@ -250,9 +251,9 @@ public class Parser
* Get the attributes of the current tag.
* @return The attribute set, representing the attributes of the current tag.
*/
- public htmlAttributeSet getAttributes()
+ public SimpleAttributeSet getAttributes()
{
- return attributes;
+ return new SimpleAttributeSet(attributes);
}
/**
@@ -661,12 +662,16 @@ public class Parser
if (text != null && text.length > 0)
{
TagElement pcdata = new TagElement(dtd.getElement("#pcdata"));
- attributes = htmlAttributeSet.EMPTY_HTML_ATTRIBUTE_SET;
- _handleEmptyTag(pcdata);
+ if ((text.length > 1 && text[0] != ' ')
+ || validator.tagIsValidForContext(pcdata) == Boolean.TRUE)
+ {
+ attributes = htmlAttributeSet.EMPTY_HTML_ATTRIBUTE_SET;
+ _handleEmptyTag(pcdata);
- handleText(text);
- if (titleOpen)
- title.append(text);
+ handleText(text);
+ if (titleOpen)
+ title.append(text);
+ }
}
}
@@ -1418,8 +1423,6 @@ public class Parser
hTag = new Token(start, next);
- attributes.setResolveParent(defaulter.getDefaultParameters(name.getImage()));
-
if (!end)
{
// The tag body contains errors. If additionally the tag