📄 htmldocument.java
字号:
* Creates a document leaf element that directly represents * text (doesn't have any children). This is implemented * to return an element of type * <code>HTMLDocument.RunElement</code>. * * @param parent the parent element * @param a the attributes for the element * @param p0 the beginning of the range (must be at least 0) * @param p1 the end of the range (must be at least p0) * @return the new element */ protected Element createLeafElement(Element parent, AttributeSet a, int p0, int p1) { return new RunElement(parent, a, p0, p1); } /** * Creates a document branch element, that can contain other elements. * This is implemented to return an element of type * <code>HTMLDocument.BlockElement</code>. * * @param parent the parent element * @param a the attributes * @return the element */ protected Element createBranchElement(Element parent, AttributeSet a) { return new BlockElement(parent, a); } /** * Creates the root element to be used to represent the * default document structure. * * @return the element base */ protected AbstractElement createDefaultRoot() { // grabs a write-lock for this initialization and // abandon it during initialization so in normal // operation we can detect an illegitimate attempt // to mutate attributes. writeLock(); MutableAttributeSet a = new SimpleAttributeSet(); a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.HTML); BlockElement html = new BlockElement(null, a.copyAttributes()); a.removeAttributes(a); a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.BODY); BlockElement body = new BlockElement(html, a.copyAttributes()); a.removeAttributes(a); a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.P); getStyleSheet().addCSSAttributeFromHTML(a, CSS.Attribute.MARGIN_TOP, "0"); BlockElement paragraph = new BlockElement(body, a.copyAttributes()); a.removeAttributes(a); a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.CONTENT); RunElement brk = new RunElement(paragraph, a, 0, 1); Element[] buff = new Element[1]; buff[0] = brk; paragraph.replace(0, 0, buff); buff[0] = paragraph; body.replace(0, 0, buff); buff[0] = body; html.replace(0, 0, buff); writeUnlock(); return html; } /** * Sets the number of tokens to buffer before trying to update * the documents element structure. * * @param n the number of tokens to buffer */ public void setTokenThreshold(int n) { putProperty(TokenThreshold, new Integer(n)); } /** * Gets the number of tokens to buffer before trying to update * the documents element structure. The default value is * <code>Integer.MAX_VALUE</code>. * * @return the number of tokens to buffer */ public int getTokenThreshold() { Integer i = (Integer) getProperty(TokenThreshold); if (i != null) { return i.intValue(); } return Integer.MAX_VALUE; } /** * Determines how unknown tags are handled by the parser. * If set to true, unknown * tags are put in the model, otherwise they are dropped. * * @param preservesTags true if unknown tags should be * saved in the model, otherwise tags are dropped * @see javax.swing.text.html.HTML.Tag */ public void setPreservesUnknownTags(boolean preservesTags) { preservesUnknownTags = preservesTags; } /** * Returns the behavior the parser observes when encountering * unknown tags. * * @see javax.swing.text.html.HTML.Tag * @return true if unknown tags are to be preserved when parsing */ public boolean getPreservesUnknownTags() { return preservesUnknownTags; } /** * Processes <code>HyperlinkEvents</code> that * are generated by documents in an HTML frame. * The <code>HyperlinkEvent</code> type, as the parameter suggests, * is <code>HTMLFrameHyperlinkEvent</code>. * In addition to the typical information contained in a * <code>HyperlinkEvent</code>, * this event contains the element that corresponds to the frame in * which the click happened (the source element) and the * target name. The target name has 4 possible values: * <ul> * <li> _self * <li> _parent * <li> _top * <li> a named frame * </ul> * * If target is _self, the action is to change the value of the * <code>HTML.Attribute.SRC</code> attribute and fires a * <code>ChangedUpdate</code> event. *<p> * If the target is _parent, then it deletes the parent element, * which is a <FRAMESET> element, and inserts a new <FRAME> * element, and sets its <code>HTML.Attribute.SRC</code> attribute * to have a value equal to the destination URL and fire a * <code>RemovedUpdate</code> and <code>InsertUpdate</code>. *<p> * If the target is _top, this method does nothing. In the implementation * of the view for a frame, namely the <code>FrameView</code>, * the processing of _top is handled. Given that _top implies * replacing the entire document, it made sense to handle this outside * of the document that it will replace. *<p> * If the target is a named frame, then the element hierarchy is searched * for an element with a name equal to the target, its * <code>HTML.Attribute.SRC</code> attribute is updated and a * <code>ChangedUpdate</code> event is fired. * * @param e the event */ public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent e) { String frameName = e.getTarget(); Element element = e.getSourceElement(); String urlStr = e.getURL().toString(); if (frameName.equals("_self")) { /* The source and destination elements are the same. */ updateFrame(element, urlStr); } else if (frameName.equals("_parent")) { /* The destination is the parent of the frame. */ updateFrameSet(element.getParentElement(), urlStr); } else { /* locate a named frame */ Element targetElement = findFrame(frameName); if (targetElement != null) { updateFrame(targetElement, urlStr); } } } /** * Searches the element hierarchy for an FRAME element * that has its name attribute equal to the <code>frameName</code>. * * @param frameName * @return the element whose NAME attribute has a value of * <code>frameName</code>; returns <code>null</code> * if not found */ private Element findFrame(String frameName) { ElementIterator it = new ElementIterator(this); Element next = null; while ((next = it.next()) != null) { AttributeSet attr = next.getAttributes(); if (matchNameAttribute(attr, HTML.Tag.FRAME)) { String frameTarget = (String)attr.getAttribute(HTML.Attribute.NAME); if (frameTarget != null && frameTarget.equals(frameName)) { break; } } } return next; } /** * Returns true if <code>StyleConstants.NameAttribute</code> is * equal to the tag that is passed in as a parameter. * * @param attr the attributes to be matched * @param tag the value to be matched * @return true if there is a match, false otherwise * @see javax.swing.text.html.HTML.Attribute */ static boolean matchNameAttribute(AttributeSet attr, HTML.Tag tag) { Object o = attr.getAttribute(StyleConstants.NameAttribute); if (o instanceof HTML.Tag) { HTML.Tag name = (HTML.Tag) o; if (name == tag) { return true; } } return false; } /** * Replaces a frameset branch Element with a frame leaf element. * * @param element the frameset element to remove * @param url the value for the SRC attribute for the * new frame that will replace the frameset */ private void updateFrameSet(Element element, String url) { try { int startOffset = element.getStartOffset(); int endOffset = Math.min(getLength(), element.getEndOffset()); String html = "<frame"; if (url != null) { html += " src=\"" + url + "\""; } html += ">"; installParserIfNecessary(); setOuterHTML(element, html); } catch (BadLocationException e1) { // Should handle this better } catch (IOException ioe) { // Should handle this better } } /** * Updates the Frame elements <code>HTML.Attribute.SRC attribute</code> * and fires a <code>ChangedUpdate</code> event. * * @param element a FRAME element whose SRC attribute will be updated * @param url a string specifying the new value for the SRC attribute */ private void updateFrame(Element element, String url) { try { writeLock(); DefaultDocumentEvent changes = new DefaultDocumentEvent(element.getStartOffset(), 1, DocumentEvent.EventType.CHANGE); AttributeSet sCopy = element.getAttributes().copyAttributes(); MutableAttributeSet attr = (MutableAttributeSet) element.getAttributes(); changes.addEdit(new AttributeUndoableEdit(element, sCopy, false)); attr.removeAttribute(HTML.Attribute.SRC); attr.addAttribute(HTML.Attribute.SRC, url); changes.end(); fireChangedUpdate(changes); fireUndoableEditUpdate(new UndoableEditEvent(this, changes)); } finally { writeUnlock(); } } /** * Returns true if the document will be viewed in a frame. * @return true if document will be viewed in a frame, otherwise false */ boolean isFrameDocument() { return frameDocument; } /** * Sets a boolean state about whether the document will be * viewed in a frame. * @param frameDoc true if the document will be viewed in a frame, * otherwise false */ void setFrameDocumentState(boolean frameDoc) { this.frameDocument = frameDoc; } /** * Adds the specified map, this will remove a Map that has been * previously registered with the same name. * * @param map the <code>Map</code> to be registered */ void addMap(Map map) { String name = map.getName(); if (name != null) { Object maps = getProperty(MAP_PROPERTY); if (maps == null) { maps = new Hashtable(11); putProperty(MAP_PROPERTY, maps); } if (maps instanceof Hashtable) { ((Hashtable)maps).put("#" + name, map); } } } /** * Removes a previously registered map. * @param map the <code>Map</code> to be removed */ void removeMap(Map map) { String name = map.getName(); if (name != null) { Object maps = getProperty(MAP_PROPERTY); if (maps instanceof Hashtable) { ((Hashtable)maps).remove("#" + name); } } } /** * Returns the Map associated with the given name. * @param the name of the desired <code>Map</code> * @return the <code>Map</code> or <code>null</code> if it can't * be found, or if <code>name</code> is <code>null</code> */ Map getMap(String name) { if (name != null) { Object maps = getProperty(MAP_PROPERTY); if (maps != null && (maps instanceof Hashtable)) { return (Map)((Hashtable)maps).get(name); } } return null; } /** * Returns an <code>Enumeration</code> of the possible Maps. * @return the enumerated list of maps, or <code>null</code> * if the maps are not an instance of <code>Hashtable</code> */ Enumeration getMaps() { Object maps = getProperty(MAP_PROPERTY); if (maps instanceof Hashtable) { return ((Hashtable)maps).elements(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -