summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-12-01 23:20:28 +0000
committerRoman Kennke <roman@kennke.org>2006-12-01 23:20:28 +0000
commit5b46b46ff3fdcc16a7420b55fb57b804fb1eb3e3 (patch)
tree9f58c640a500e2ca3d5b32bf156de925184fb253
parentbe31fc91967c4a8d6e62a36b303498563dabc67a (diff)
downloadclasspath-5b46b46ff3fdcc16a7420b55fb57b804fb1eb3e3.tar.gz
2006-12-01 Roman Kennke <kennke@aicas.com>
* javax/swing/text/html/HTML.java (Attribute.DYNAMIC_CLASS): New field. (Attribute.PSEUDO_CLASS): New field. * javax/swing/text/html/HTMLDocument.java (HTMLReader.CharacterAction.start): Initialize anchor with link pseudo attribute. (updateSpecialClass): New helper method. Updates the dynamic or pseudo class for anchor tags. * javax/swing/text/html/HTMLEditorKit.java (LinkController.lastAnchorElement): New field. For tracking enter/exit of anchors. (LinkController.activateLink): Set pseudo class to 'visited'. (LinkController.mouseMoved): Added support for tracking the 'hover' dynamic class. * javax/swing/text/html/InlineView.java (changedUpdate): Fetch new properties. * javax/swing/text/html/StyleSheet.java (attributeSetToMap): New helper method. (getRule): Also append dynamic and pseudo class to key. (resolveStyle): Resolve style based generally on all attributes. * javax/swing/text/html/TableView.java (RowView.layoutMajorAxis): Make sure the grid is valid. (updateGrid): Made package private. * gnu/javax/swing/text/html/css/Selector.java (calculateSpecificity): Added support for dynamic and pseudo classes. (matches): Changed to operate on general attributes. Added support for dynamic and pseudo classes.
-rw-r--r--ChangeLog30
-rw-r--r--gnu/javax/swing/text/html/css/Selector.java17
-rw-r--r--javax/swing/text/html/HTML.java10
-rw-r--r--javax/swing/text/html/HTMLDocument.java49
-rw-r--r--javax/swing/text/html/HTMLEditorKit.java44
-rw-r--r--javax/swing/text/html/InlineView.java2
-rw-r--r--javax/swing/text/html/StyleSheet.java73
-rw-r--r--javax/swing/text/html/TableView.java5
8 files changed, 201 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e1e969da..43ef94e5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2006-12-01 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/text/html/HTML.java
+ (Attribute.DYNAMIC_CLASS): New field.
+ (Attribute.PSEUDO_CLASS): New field.
+ * javax/swing/text/html/HTMLDocument.java
+ (HTMLReader.CharacterAction.start): Initialize anchor with link
+ pseudo attribute.
+ (updateSpecialClass): New helper method. Updates the dynamic
+ or pseudo class for anchor tags.
+ * javax/swing/text/html/HTMLEditorKit.java
+ (LinkController.lastAnchorElement): New field. For tracking
+ enter/exit of anchors.
+ (LinkController.activateLink): Set pseudo class to 'visited'.
+ (LinkController.mouseMoved): Added support for tracking
+ the 'hover' dynamic class.
+ * javax/swing/text/html/InlineView.java
+ (changedUpdate): Fetch new properties.
+ * javax/swing/text/html/StyleSheet.java
+ (attributeSetToMap): New helper method.
+ (getRule): Also append dynamic and pseudo class to key.
+ (resolveStyle): Resolve style based generally on all attributes.
+ * javax/swing/text/html/TableView.java
+ (RowView.layoutMajorAxis): Make sure the grid is valid.
+ (updateGrid): Made package private.
+ * gnu/javax/swing/text/html/css/Selector.java
+ (calculateSpecificity): Added support for dynamic and pseudo classes.
+ (matches): Changed to operate on general attributes.
+ Added support for dynamic and pseudo classes.
+
2006-12-01 Mario Torre <neugens@limasoftware.net>
* java/text/DecimalFormat.java (formatInternal): move the formatting of
diff --git a/gnu/javax/swing/text/html/css/Selector.java b/gnu/javax/swing/text/html/css/Selector.java
index b8128233b..210df3a7b 100644
--- a/gnu/javax/swing/text/html/css/Selector.java
+++ b/gnu/javax/swing/text/html/css/Selector.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.javax.swing.text.html.css;
+import java.util.Map;
import java.util.StringTokenizer;
/**
@@ -98,7 +99,7 @@ public class Selector
* @return <code>true</code> when this selector matches the element path,
* <code>false</code> otherwise
*/
- public boolean matches(String[] tags, String[] pathClasses, String[] pathIds)
+ public boolean matches(String[] tags, Map[] attributes)
{
// TODO: This implements class, id and descendent matching. These are
// the most commonly used selector matchers in CSS together with HTML.
@@ -119,15 +120,22 @@ public class Selector
boolean tagMatch = false;
for (; tagIndex < numTags && tagMatch == false; tagIndex++)
{
+ Object pathClass = attributes[tagIndex].get("class");
+ // Try pseudo class too.
+ Object pseudoClass = attributes[tagIndex].get("_pseudo");
+ Object dynClass = attributes[tagIndex].get("_dynamic");
+ Object pathId = attributes[tagIndex].get("id");
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]));
+ || clazz.equals(dynClass)
+ || clazz.equals(pseudoClass)
+ || clazz.equals(pathClass));
tagMatch = tagMatch && (id.equals("*")
- || id.equals(pathIds[tagIndex]));
+ || id.equals(pathId));
// For the last element in the selector we must not look
// further.
if (j == 0)
@@ -190,6 +198,9 @@ public class Selector
{
String sel = selector[i];
int clazzIndex = sel.indexOf('.');
+ // Try pseudo class too.
+ if (clazzIndex == -1)
+ clazzIndex = sel.indexOf(':');
int idIndex = sel.indexOf('#');
String clazz;
if (clazzIndex == -1)
diff --git a/javax/swing/text/html/HTML.java b/javax/swing/text/html/HTML.java
index 2c908f6fc..29e6335a0 100644
--- a/javax/swing/text/html/HTML.java
+++ b/javax/swing/text/html/HTML.java
@@ -465,6 +465,16 @@ public class HTML
public static final Attribute WIDTH = new Attribute("width");
/**
+ * This is used to reflect the pseudo class for the a tag.
+ */
+ static final Attribute PSEUDO_CLASS = new Attribute("_pseudo");
+
+ /**
+ * This is used to reflect the dynamic class for the a tag.
+ */
+ static final Attribute DYNAMIC_CLASS = new Attribute("_dynamic");
+
+ /**
* The attribute name.
*/
private final String name;
diff --git a/javax/swing/text/html/HTMLDocument.java b/javax/swing/text/html/HTMLDocument.java
index c4f4222ec..8ef4c0e87 100644
--- a/javax/swing/text/html/HTMLDocument.java
+++ b/javax/swing/text/html/HTMLDocument.java
@@ -791,6 +791,10 @@ public class HTMLDocument extends DefaultStyledDocument
// Put the old attribute set on the stack.
pushCharacterStyle();
+ // Initialize with link pseudo class.
+ if (t == HTML.Tag.A)
+ a.addAttribute(HTML.Attribute.PSEUDO_CLASS, "link");
+
// Just add the attributes in <code>a</code>.
charAttr.addAttribute(t, a.copyAttributes());
}
@@ -2117,4 +2121,49 @@ public void setOuterHTML(Element elem, String htmlText)
{
return baseTarget;
}
+
+ /**
+ * Updates the A tag's pseudo class value in response to a hyperlink
+ * action.
+ *
+ * @param el the corresponding element
+ * @param value the new value
+ */
+ void updateSpecialClass(Element el, HTML.Attribute cl, String value)
+ {
+ try
+ {
+ writeLock();
+ DefaultDocumentEvent ev =
+ new DefaultDocumentEvent(el.getStartOffset(), 1,
+ DocumentEvent.EventType.CHANGE);
+ AttributeSet elAtts = el.getAttributes();
+ AttributeSet anchorAtts = (AttributeSet) elAtts.getAttribute(HTML.Tag.A);
+ if (anchorAtts != null)
+ {
+ AttributeSet copy = elAtts.copyAttributes();
+ StyleSheet ss = getStyleSheet();
+ if (value != null)
+ {
+ anchorAtts = ss.addAttribute(anchorAtts, cl, value);
+ }
+ else
+ {
+ anchorAtts = ss.removeAttribute(anchorAtts, cl);
+ }
+ MutableAttributeSet matts = (MutableAttributeSet) elAtts;
+ ev.addEdit(new AttributeUndoableEdit(el, copy, false));
+ matts.removeAttribute(HTML.Tag.A);
+ matts.addAttribute(HTML.Tag.A, anchorAtts);
+ ev.end();
+ fireChangedUpdate(ev);
+ fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
+ }
+ }
+ finally
+ {
+ writeUnlock();
+ }
+ }
+
}
diff --git a/javax/swing/text/html/HTMLEditorKit.java b/javax/swing/text/html/HTMLEditorKit.java
index 78b5df99f..3b122bb36 100644
--- a/javax/swing/text/html/HTMLEditorKit.java
+++ b/javax/swing/text/html/HTMLEditorKit.java
@@ -98,7 +98,12 @@ public class HTMLEditorKit
extends MouseAdapter
implements MouseMotionListener, Serializable
{
-
+
+ /**
+ * The element of the last anchor tag.
+ */
+ private Element lastAnchorElement;
+
/**
* Constructor
*/
@@ -162,10 +167,41 @@ public class HTMLEditorKit
AttributeSet aAtts = (AttributeSet)
el.getAttributes().getAttribute(HTML.Tag.A);
if (aAtts != null)
- newCursor = kit.getLinkCursor();
+ {
+ if (el != lastAnchorElement)
+ {
+ if (lastAnchorElement != null)
+ htmlDoc.updateSpecialClass(lastAnchorElement,
+ HTML.Attribute.DYNAMIC_CLASS,
+ null);
+ lastAnchorElement = el;
+ htmlDoc.updateSpecialClass(el,
+ HTML.Attribute.DYNAMIC_CLASS,
+ "hover");
+ }
+ newCursor = kit.getLinkCursor();
+ }
+ else
+ {
+ if (lastAnchorElement != null)
+ htmlDoc.updateSpecialClass(lastAnchorElement,
+ HTML.Attribute.DYNAMIC_CLASS,
+ null);
+ lastAnchorElement = null;
+ }
+ }
+ else
+ {
+ if (lastAnchorElement != null)
+ htmlDoc.updateSpecialClass(lastAnchorElement,
+ HTML.Attribute.DYNAMIC_CLASS,
+ null);
+ lastAnchorElement = null;
}
if (editor.getCursor() != newCursor)
- editor.setCursor(newCursor);
+ {
+ editor.setCursor(newCursor);
+ }
}
}
}
@@ -198,6 +234,8 @@ public class HTMLEditorKit
if (anchorAtts != null)
{
href = (String) anchorAtts.getAttribute(HTML.Attribute.HREF);
+ htmlDoc.updateSpecialClass(el, HTML.Attribute.PSEUDO_CLASS,
+ "visited");
}
else
{
diff --git a/javax/swing/text/html/InlineView.java b/javax/swing/text/html/InlineView.java
index 6b134ae39..cea0782b1 100644
--- a/javax/swing/text/html/InlineView.java
+++ b/javax/swing/text/html/InlineView.java
@@ -139,6 +139,7 @@ public class InlineView
StyleSheet ss = getStyleSheet();
attributes = ss.getViewAttributes(this);
preferenceChanged(null, true, true);
+ setPropertiesFromAttributes();
}
/**
@@ -303,4 +304,5 @@ public class InlineView
}
return span;
}
+
}
diff --git a/javax/swing/text/html/StyleSheet.java b/javax/swing/text/html/StyleSheet.java
index eadd325f2..acc14e73e 100644
--- a/javax/swing/text/html/StyleSheet.java
+++ b/javax/swing/text/html/StyleSheet.java
@@ -68,6 +68,7 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import javax.swing.border.Border;
import javax.swing.event.ChangeListener;
@@ -302,11 +303,21 @@ public class StyleSheet extends StyleContext
selector.append('#');
selector.append(atts.getAttribute(HTML.Attribute.ID));
}
- else if (atts.isDefined(HTML.Attribute.CLASS))
+ if (atts.isDefined(HTML.Attribute.CLASS))
{
selector.append('.');
selector.append(atts.getAttribute(HTML.Attribute.CLASS));
}
+ if (atts.isDefined(HTML.Attribute.DYNAMIC_CLASS))
+ {
+ selector.append(':');
+ selector.append(atts.getAttribute(HTML.Attribute.DYNAMIC_CLASS));
+ }
+ if (atts.isDefined(HTML.Attribute.PSEUDO_CLASS))
+ {
+ selector.append(':');
+ selector.append(atts.getAttribute(HTML.Attribute.PSEUDO_CLASS));
+ }
selector.append(' ');
}
selector.append(t.toString());
@@ -328,11 +339,21 @@ public class StyleSheet extends StyleContext
selector.append('#');
selector.append(atts.getAttribute(HTML.Attribute.ID));
}
- else if (atts.isDefined(HTML.Attribute.CLASS))
+ if (atts.isDefined(HTML.Attribute.CLASS))
{
selector.append('.');
selector.append(atts.getAttribute(HTML.Attribute.CLASS));
}
+ if (atts.isDefined(HTML.Attribute.DYNAMIC_CLASS))
+ {
+ selector.append(':');
+ selector.append(atts.getAttribute(HTML.Attribute.DYNAMIC_CLASS));
+ }
+ if (atts.isDefined(HTML.Attribute.PSEUDO_CLASS))
+ {
+ selector.append(':');
+ selector.append(atts.getAttribute(HTML.Attribute.PSEUDO_CLASS));
+ }
}
return getResolvedStyle(selector.toString(), path, t);
}
@@ -359,7 +380,7 @@ public class StyleSheet extends StyleContext
/**
* Resolves a style. This creates arrays that hold the tag names,
* class and id attributes and delegates the work to
- * {@link #resolveStyle(String, String[], String[], String[])}.
+ * {@link #resolveStyle(String, String[], Map[])}.
*
* @param selector the selector
* @param path the Element path
@@ -371,8 +392,7 @@ public class StyleSheet extends StyleContext
{
int count = path.size();
String[] tags = new String[count];
- String[] ids = new String[count];
- String[] classes = new String[count];
+ Map[] attributes = new Map[count];
for (int i = 0; i < count; i++)
{
Element el = (Element) path.get(i);
@@ -393,24 +413,16 @@ public class StyleSheet extends StyleContext
tags[i] = t.toString();
else
tags[i] = null;
- if (atts.isDefined(HTML.Attribute.CLASS))
- classes[i] = atts.getAttribute(HTML.Attribute.CLASS).toString();
- else
- classes[i] = null;
- if (atts.isDefined(HTML.Attribute.ID))
- ids[i] = atts.getAttribute(HTML.Attribute.ID).toString();
- else
- ids[i] = null;
+ attributes[i] = attributeSetToMap(atts);
}
else
{
tags[i] = null;
- classes[i] = null;
- ids[i] = null;
+ attributes[i] = null;
}
}
tags[0] = tag.toString();
- return resolveStyle(selector, tags, ids, classes);
+ return resolveStyle(selector, tags, attributes);
}
/**
@@ -418,13 +430,11 @@ public class StyleSheet extends StyleContext
*
* @param selector the selector
* @param tags the tags
- * @param ids the corresponding ID attributes
- * @param classes the corresponding CLASS attributes
+ * @param attributes the attributes of the tags
*
* @return the resolved style
*/
- private Style resolveStyle(String selector, String[] tags, String[] ids,
- String[] classes)
+ private Style resolveStyle(String selector, String[] tags, Map[] attributes)
{
// FIXME: This style resolver is not correct. But it works good enough for
// the default.css.
@@ -433,7 +443,7 @@ public class StyleSheet extends StyleContext
for (Iterator i = css.iterator(); i.hasNext();)
{
CSSStyle style = (CSSStyle) i.next();
- if (style.selector.matches(tags, classes, ids))
+ if (style.selector.matches(tags, attributes))
styles.add(style);
}
@@ -446,7 +456,7 @@ public class StyleSheet extends StyleContext
for (int j = ss.css.size() - 1; j >= 0; j--)
{
CSSStyle style = (CSSStyle) ss.css.get(j);
- if (style.selector.matches(tags, classes, ids))
+ if (style.selector.matches(tags, attributes))
styles.add(style);
}
}
@@ -1395,4 +1405,23 @@ public class StyleSheet extends StyleContext
}
}
+ /**
+ * Converts an AttributeSet to a Map. This is used for CSS resolving.
+ *
+ * @param atts the attributes to convert
+ *
+ * @return the converted map
+ */
+ private Map attributeSetToMap(AttributeSet atts)
+ {
+ HashMap map = new HashMap();
+ Enumeration keys = atts.getAttributeNames();
+ while (keys.hasMoreElements())
+ {
+ Object key = keys.nextElement();
+ Object value = atts.getAttribute(key);
+ map.put(key.toString(), value.toString());
+ }
+ return map;
+ }
}
diff --git a/javax/swing/text/html/TableView.java b/javax/swing/text/html/TableView.java
index c142462bc..90b3ecc4f 100644
--- a/javax/swing/text/html/TableView.java
+++ b/javax/swing/text/html/TableView.java
@@ -140,6 +140,7 @@ class TableView
protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
int spans[])
{
+ updateGrid();
int numCols = offsets.length;
int realColumn = 0;
for (int i = 0; i < numCols; i++)
@@ -664,8 +665,10 @@ class TableView
/**
* Updates the arrays that contain the row and column data in response
* to a change to the table structure.
+ *
+ * Package private to avoid accessor methods.
*/
- private void updateGrid()
+ void updateGrid()
{
if (! gridValid)
{