From: Sam H. <sa...@re...> - 2004-07-14 01:39:46
|
Dear All, Think Ive got the prototype of a patch to add innerHTML to htmlunit but Im very new to the code so some hand holding/sanity check before I learn the coding standards and flesh out the unit tests would be very welcome. What I have in mind is jsSet_innerHTML in HTMLElement that calls a new HTMLParser.parse method. Adapt the DOMBuilder to not construct a HtmlPage but do that in the old parse method. Small addition of a flag to tell Necko if it should treat input as fragment or not. New/changed code pasted below. Worth finishing? Ideas for none obvious unit tests...? Also would a patch to switch to using httpclient authentication mechanism rather than htmlunits own be a good idea? Cheers Sam HTMLElement method: public final void jsSet_innerHTML(final String newHTML) { try { // remove existing children DomNode node = this.getDomNodeOrDie(); while (node.getFirstChild() != null) node.getFirstChild().remove(); HTMLParser.parse(node, newHTML); } catch (IOException ex) { ex.printStackTrace(); // TODO learn what the error handling rules are } } Rearrange HTMLParser a bit: /** * parse the HTML content from the given WebResponse into an object tree representation * * @param webResponse the response data * @param webWindow the web window into which the page is to be loaded * @return the page object which forms the root of the DOM tree, or <code>null</code> if the <HTML> * tag is missing * @throws java.io.IOException io error */ public static HtmlPage parse( final WebResponse webResponse, final WebWindow webWindow) throws IOException { HtmlPage page = new HtmlPage(webResponse.getUrl(), webResponse, webWindow); webWindow.setEnclosedPage(page); HtmlUnitDOMBuilder domBuilder = new HtmlUnitDOMBuilder(page, false); XMLInputSource in = new XMLInputSource( null, webResponse.getUrl().toString(), null, webResponse.getContentAsStream(), webResponse.getContentCharSet()); domBuilder.parse(in); return page; } public static void parse(DomNode node, String content) throws IOException { HtmlUnitDOMBuilder domBuilder = new HtmlUnitDOMBuilder(node, true); XMLInputSource in = new XMLInputSource( null, node.getPage().getWebResponse().getUrl().toString(), null, new ByteArrayInputStream(content.getBytes()), "utf-8"); domBuilder.parse(in); } static HTMLConfiguration x = new HTMLConfiguration(); /** * The parser and DOM builder. This class subclasses Xerces's AbstractSAXParser and implements * the ContentHandler interface. Thus all parser APIs are kept private. The ContentHandler methods * consume SAX events to build the page DOM */ private static class HtmlUnitDOMBuilder extends AbstractSAXParser implements ContentHandler /*, LexicalHandler */ { //private final WebResponse webResponse_; //private final WebWindow webWindow_; //private final ScriptFilter scriptFilter_; private final HtmlPage page_; private Locator locator_; private final Stack stack_ = new Stack(); private DomNode currentNode_; private StringBuffer characters_; /** * create a new builder for parsing the given response contents * @param webResponse the response data * @param webWindow the web window into which the page is to be loaded */ public HtmlUnitDOMBuilder(final DomNode node, boolean fragment) { super(new HTMLConfiguration()); //webResponse_ = webResponse; //webWindow_ = webWindow; currentNode_ = node; stack_.push(currentNode_); page_ = node.getPage(); ScriptFilter scriptFilter = new ScriptFilter((HTMLConfiguration) fConfiguration); // XXX OK that different to parser? reuse? page_.setScriptFilter(scriptFilter); scriptFilter.setHtmlPage(page_); try { XMLDocumentFilter[] filters = { scriptFilter }; setProperty( "http://cyberneko.org/html/properties/filters", filters); setFeature( "http://cyberneko.org/html/features/augmentations", true); setProperty( "http://cyberneko.org/html/properties/names/elems", "lower"); setFeature( "http://cyberneko.org/html/features/report-errors", true); if (fragment) { setFeature( "http://cyberneko.org/html/features/balance-tags/document-fragment", true); } } catch (SAXException e) { throw new ObjectInstantiationException( "unable to create HTML parser", e); } } /** * parse the input source. This is the only parse() method that should be called. * * @param inputSource an XMLInputSource * @throws java.io.IOException */ public void parse(XMLInputSource inputSource) throws IOException { setContentHandler(this); //setLexicalHandler(this); comments and CDATA super.parse(inputSource); } /** * @return the document locator */ public Locator getLocator() { return locator_; } /** * set the document locator * @param locator */ public void setDocumentLocator(Locator locator) { this.locator_ = locator; } /** SAX start document event */ public void startDocument() throws SAXException { } |