United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4636235 : HTMLEditorKit.create() cannot handle some element types.

Details
Type:
Bug
Submit Date:
2002-02-11
Status:
Resolved
Updated Date:
2004-10-13
Project Name:
JDK
Resolved Date:
2004-09-14
Component:
client-libs
OS:
generic,windows_98
Sub-Component:
javax.swing
CPU:
generic,x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.4.0
Fixed Versions:

Related Reports
Duplicate:

Sub Tasks

Description
HTMLEditorKit.create() cannot handle element types that do not set the name attribute using StyleConstants.NameAttribute. As a result, methods like JTextPane.insertComponent() do not work properly with an HTMLEditorKit.

The problem is that AbstractDocument and StyledEditorKit use AbstractDocument.ElementNameAttribute to represent the element name and HTMLDocument and HTMLEditorKit use StyleConstants.NameAttribute.

When HTMLEditorKit then calls getAttribute(StyleConstants.NameAttribute) and the name is not defined, the attribute resolves upwards to the parent until if finds something (ie. the wrong element type).

You can see this behavior with the attached test case. Compile and run ComponentTest.java. Hitting the button on top should insert components into the JTextPane. Instead, blank space is inserted. Hitting the button at the bottom brings up a tree showing the view structure. Notice that javax.swing.text.html.ParagraphViews are being created where the ComponentViews should be.

Additional note:
I suspect the fix to this will involve changes to HTMLEditorKit.create() so I am making a note of something else that should change there. This is not causing the bad behavior described in the bug report but may when the bug is fixed.

Lines 1153 and 1154 read:

} else if (nm.equals(AbstractDocument.ParagraphElementName)) {
    return new ParagraphView(elem);
}

I beleive this should create a new java.swing.text.ParagraphView instead.

                                    

Comments
SUGGESTED FIX



Name: slR10134			Date: 06/07/2002



------- HTMLEditorKit.java -------
*** /tmp/sccs.iJaGCs	^T???? M-	????  7 14:30:05 2002
--- HTMLEditorKit.java	^T???? M-	????  7 14:20:11 2002
***************
*** 1032,1050 ****
  	 * @return the view
  	 */
          public View create(Element elem) {
! 	    Object o = 
elem.getAttributes().getAttribute(StyleConstants.NameAttribute);
! 	    if (o instanceof HTML.Tag) {
! 		HTML.Tag kind = (HTML.Tag) o;
! 		if (kind == HTML.Tag.CONTENT) {
! 		    return new InlineView(elem);
! 		} else if (kind == HTML.Tag.IMPLIED) {
! 		    String ws = (String) elem.getAttributes().getAttribute(
! 			CSS.Attribute.WHITE_SPACE);
! 		    if ((ws != null) && ws.equals("pre")) {
! 			return new LineView(elem);
! 		    }
! 		    return new javax.swing.text.html.ParagraphView(elem);
! 		} else if ((kind == HTML.Tag.P) ||
  			   (kind == HTML.Tag.H1) ||
  			   (kind == HTML.Tag.H2) ||
  			   (kind == HTML.Tag.H3) ||
--- 1032,1052 ----
  	 * @return the view
  	 */
          public View create(Element elem) {
! 	    Object elemName = 
elem.getAttributes().getAttribute(AbstractDocument.ElementNameAttribute);
! 	    if (elemName == null) {
! 	        Object o = 
elem.getAttributes().getAttribute(StyleConstants.NameAttribute);
! 	        if (o instanceof HTML.Tag) {
! 		    HTML.Tag kind = (HTML.Tag) o;
! 		    if (kind == HTML.Tag.CONTENT) {
! 		        return new InlineView(elem);
! 		    } else if (kind == HTML.Tag.IMPLIED) {
! 		        String ws = (String) elem.getAttributes().getAttribute(
! 			    CSS.Attribute.WHITE_SPACE);
! 		        if ((ws != null) && ws.equals("pre")) {
! 			    return new LineView(elem);
! 		        }
! 		        return new javax.swing.text.html.ParagraphView(elem);
! 		    } else if ((kind == HTML.Tag.P) ||
  			   (kind == HTML.Tag.H1) ||
  			   (kind == HTML.Tag.H2) ||
  			   (kind == HTML.Tag.H3) ||
***************
*** 1052,1069 ****
  			   (kind == HTML.Tag.H5) ||
  			   (kind == HTML.Tag.H6) ||
  			   (kind == HTML.Tag.DT)) {
! 		    // paragraph
! 		    return new javax.swing.text.html.ParagraphView(elem);
! 		} else if ((kind == HTML.Tag.MENU) || 
  			   (kind == HTML.Tag.DIR) ||
  			   (kind == HTML.Tag.UL)   || 
  			   (kind == HTML.Tag.OL)) {
! 		    return new ListView(elem);
! 		} else if (kind == HTML.Tag.BODY) {
! 		    return new BodyBlockView(elem);
! 		} else if (kind == HTML.Tag.HTML) {
! 		    return new BlockView(elem, View.Y_AXIS);
! 		} else if ((kind == HTML.Tag.LI) || 
  			   (kind == HTML.Tag.CENTER) ||
  			   (kind == HTML.Tag.DL) ||
  			   (kind == HTML.Tag.DD) || 
--- 1054,1071 ----
  			   (kind == HTML.Tag.H5) ||
  			   (kind == HTML.Tag.H6) ||
  			   (kind == HTML.Tag.DT)) {
! 		        // paragraph
! 		        return new javax.swing.text.html.ParagraphView(elem);
! 		    } else if ((kind == HTML.Tag.MENU) || 
  			   (kind == HTML.Tag.DIR) ||
  			   (kind == HTML.Tag.UL)   || 
  			   (kind == HTML.Tag.OL)) {
! 		        return new ListView(elem);
! 		    } else if (kind == HTML.Tag.BODY) {
! 		        return new BodyBlockView(elem);
! 		    } else if (kind == HTML.Tag.HTML) {
! 		        return new BlockView(elem, View.Y_AXIS);
! 		    } else if ((kind == HTML.Tag.LI) || 
  			   (kind == HTML.Tag.CENTER) ||
  			   (kind == HTML.Tag.DL) ||
  			   (kind == HTML.Tag.DD) || 
***************
*** 1071,1138 ****
  			   (kind == HTML.Tag.BLOCKQUOTE) || 
  			   (kind == HTML.Tag.PRE) ||
                             (kind == HTML.Tag.FORM)) {
! 		    // vertical box
! 		    return new BlockView(elem, View.Y_AXIS);
! 		} else if (kind == HTML.Tag.NOFRAMES) {
! 		    return new NoFramesView(elem, View.Y_AXIS);
! 		} else if (kind==HTML.Tag.IMG) {
! 		    return new ImageView(elem);
! 		} else if (kind == HTML.Tag.ISINDEX) {
! 		    return new IsindexView(elem);
! 		} else if (kind == HTML.Tag.HR) {
! 		    return new HRuleView(elem);
! 		} else if (kind == HTML.Tag.BR) {
! 		    return new BRView(elem);
! 		} else if (kind == HTML.Tag.TABLE) {
! 		    return new javax.swing.text.html.TableView(elem);
! 		} else if ((kind == HTML.Tag.INPUT) ||
  			   (kind == HTML.Tag.SELECT) ||
  			   (kind == HTML.Tag.TEXTAREA)) {
! 		    return new FormView(elem);
! 		} else if (kind == HTML.Tag.OBJECT) {
! 		    return new ObjectView(elem);
! 		} else if (kind == HTML.Tag.FRAMESET) {
!                      if (elem.getAttributes().isDefined(HTML.Attribute.ROWS)) 
{
!                          return new FrameSetView(elem, View.Y_AXIS);
!                      } else if 
(elem.getAttributes().isDefined(HTML.Attribute.COLS)) {
!                          return new FrameSetView(elem, View.X_AXIS);
!                      }
!                      throw new RuntimeException("Can't build a"  + kind + ", " 
+ elem + ":" +
                                       "no ROWS or COLS defined.");
!                 } else if (kind == HTML.Tag.FRAME) {
!  		    return new FrameView(elem);
!                 } else if (kind instanceof HTML.UnknownTag) {
! 		    return new HiddenTagView(elem);
! 		} else if (kind == HTML.Tag.COMMENT) {
! 		    return new CommentView(elem);
! 		} else if (kind == HTML.Tag.HEAD) {
! 		    // Make the head never visible, and never load its
! 		    // children. For Cursor positioning,
! 		    // getNextVisualPositionFrom is overriden to always return
! 		    // the end offset of the element.
! 		    return new BlockView(elem, View.X_AXIS) {
! 			public float getPreferredSpan(int axis) {
! 			    return 0;
! 			}
! 			public float getMinimumSpan(int axis) {
! 			    return 0;
! 			}
! 			public float getMaximumSpan(int axis) {
! 			    return 0;
! 			}
! 			protected void loadChildren(ViewFactory f) {
! 			}
!                         public Shape modelToView(int pos, Shape a,
                                 Position.Bias b) throws BadLocationException {
!                             return a;
!                         }
! 			public int getNextVisualPositionFrom(int pos,
  				     Position.Bias b, Shape a, 
  				     int direction, Position.Bias[] biasRet) {
! 			    return getElement().getEndOffset();
! 			}
! 		    };
! 		} else if ((kind == HTML.Tag.TITLE) ||
  			   (kind == HTML.Tag.META) ||
  			   (kind == HTML.Tag.LINK) ||
  			   (kind == HTML.Tag.STYLE) ||
--- 1073,1140 ----
  			   (kind == HTML.Tag.BLOCKQUOTE) || 
  			   (kind == HTML.Tag.PRE) ||
                             (kind == HTML.Tag.FORM)) {
! 		        // vertical box
! 		        return new BlockView(elem, View.Y_AXIS);
! 		    } else if (kind == HTML.Tag.NOFRAMES) {
! 		        return new NoFramesView(elem, View.Y_AXIS);
! 		    } else if (kind==HTML.Tag.IMG) {
! 		        return new ImageView(elem);
! 		    } else if (kind == HTML.Tag.ISINDEX) {
! 		        return new IsindexView(elem);
! 		    } else if (kind == HTML.Tag.HR) {
! 		        return new HRuleView(elem);
! 		    } else if (kind == HTML.Tag.BR) {
! 		        return new BRView(elem);
! 		    } else if (kind == HTML.Tag.TABLE) {
! 		        return new javax.swing.text.html.TableView(elem);
! 		    } else if ((kind == HTML.Tag.INPUT) ||
  			   (kind == HTML.Tag.SELECT) ||
  			   (kind == HTML.Tag.TEXTAREA)) {
! 		        return new FormView(elem);
! 		    } else if (kind == HTML.Tag.OBJECT) {
! 		        return new ObjectView(elem);
! 		    } else if (kind == HTML.Tag.FRAMESET) {
!                          if 
(elem.getAttributes().isDefined(HTML.Attribute.ROWS)) {
!                              return new FrameSetView(elem, View.Y_AXIS);
!                          } else if 
(elem.getAttributes().isDefined(HTML.Attribute.COLS)) {
!                              return new FrameSetView(elem, View.X_AXIS);
!                          }
!                          throw new RuntimeException("Can't build a"  + kind + 
", " + elem + ":" +
                                       "no ROWS or COLS defined.");
!                     } else if (kind == HTML.Tag.FRAME) {
!  		        return new FrameView(elem);
!                     } else if (kind instanceof HTML.UnknownTag) {
! 		        return new HiddenTagView(elem);
! 		    } else if (kind == HTML.Tag.COMMENT) {
! 		        return new CommentView(elem);
! 		    } else if (kind == HTML.Tag.HEAD) {
! 		        // Make the head never visible, and never load its
! 		        // children. For Cursor positioning,
! 		        // getNextVisualPositionFrom is overriden to always 
return
! 		        // the end offset of the element.
! 		        return new BlockView(elem, View.X_AXIS) {
! 			    public float getPreferredSpan(int axis) {
! 			        return 0;
! 			    }
! 			    public float getMinimumSpan(int axis) {
! 			        return 0;
! 			    }
! 			    public float getMaximumSpan(int axis) {
! 			        return 0;
! 			    }
! 			    protected void loadChildren(ViewFactory f) {
! 			    }
!                             public Shape modelToView(int pos, Shape a,
                                 Position.Bias b) throws BadLocationException {
!                                 return a;
!                             }
! 			    public int getNextVisualPositionFrom(int pos,
  				     Position.Bias b, Shape a, 
  				     int direction, Position.Bias[] biasRet) {
! 			        return getElement().getEndOffset();
! 			    }
! 		        };
! 		    } else if ((kind == HTML.Tag.TITLE) ||
  			   (kind == HTML.Tag.META) ||
  			   (kind == HTML.Tag.LINK) ||
  			   (kind == HTML.Tag.STYLE) ||
***************
*** 1141,1152 ****
  			   (kind == HTML.Tag.MAP) ||
  			   (kind == HTML.Tag.PARAM) ||
  			   (kind == HTML.Tag.APPLET)) {
! 		    return new HiddenTagView(elem);
! 		}
  	    }
  	    // If we get here, it's either an element we don't know about
  	    // or something from StyledDocument that doesn't have a mapping to 
HTML.
! 	    String nm = elem.getName();
  	    if (nm != null) {
  		if (nm.equals(AbstractDocument.ContentElementName)) {
  		    return new LabelView(elem);
--- 1143,1159 ----
  			   (kind == HTML.Tag.MAP) ||
  			   (kind == HTML.Tag.PARAM) ||
  			   (kind == HTML.Tag.APPLET)) {
! 		        return new HiddenTagView(elem);
! 		    }
! 	        }
  	    }
  	    // If we get here, it's either an element we don't know about
  	    // or something from StyledDocument that doesn't have a mapping to 
HTML.
! 	    String nm;
! 	    if(elemName != null)
! 		nm = (String)elemName;
! 	    else
! 		 nm = elem.getName();
  	    if (nm != null) {
  		if (nm.equals(AbstractDocument.ContentElementName)) {
  		    return new LabelView(elem);


======================================================================
                                     
2004-09-14
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mustang

FIXED IN:
mustang

INTEGRATED IN:
mustang


                                     
2004-09-14
EVALUATION



Name: slR10134			Date: 06/07/2002



(###@###.###)

The reason of the bug is the following: The problem is that AbstractDocument and 
StyledEditorKit use
AbstractDocument.ElementNameAttribute to represent the element name and
HTMLDocument and HTMLEditorKit use StyleConstants.NameAttribute.
When HTMLEditorKit then calls getAttribute(StyleConstants.NameAttribute) and
the name is not defined, the attribute resolves upwards to the parent until if
finds something (ie. the wrong element type).
The idea of suggested fix is to try to get AbstractDocument.ElementNameAttribute
first and if it is null then to get StyleConstants.NameAttribute.
Since elements named with AbstractDocument.ElementNameAttribute
are only leaf elements fix shouldn't cause situation
when ElementNameAttribute is not defined and attribute resolves upwards to the 
parent until it
finds something.

======================================================================

Name: dsR10138			Date: 03/24/2004



The previous evaluation by ###@###.### is thorough and
correct.

###@###.### 2004-03-24




======================================================================
                                     
2004-09-14



Hardware and Software, Engineered to Work Together