htmlunit-2.7

all)) {
      return;
    }
    Element doc = page.getDocumentElement();
    boolean hasBody = false;
    for (Node child = doc.getFirstChild(); child != null; child = child.getNextSibling()) {
      if (((child instanceof HtmlBody)) || ((child instanceof HtmlFrameSet)))
      {
        hasBody = true;
        break;
      }
    }
    if ((!hasBody) && (!checkInsideFrameOnly))
    {
      HtmlBody body = new HtmlBody(null, "body", page, null, false);
      doc.appendChild(body);
    }
    if (ie) {
      for (FrameWindow frame : page.getFrames())
      {
        Page containedPage = frame.getEnclosedPage();
        if ((containedPage instanceof HtmlPage)) {
          addBodyToPageIfNecessary((HtmlPage)containedPage, false, false);
        }
      }
    }
  }
  
  static Throwable extractNestedException(Throwable e)
  {
    Throwable originalException = e;
    Throwable cause = ((XNIException)e).getException();
    while (cause != null)
    {
      originalException = cause;
      if ((cause instanceof XNIException)) {
        cause = ((XNIException)cause).getException();
      } else if ((cause instanceof InvocationTargetException)) {
        cause = cause.getCause();
      } else {
        cause = null;
      }
    }
    return originalException;
  }
  
  static IElementFactory getElementFactory(String namespaceURI, String qualifiedName)
  {
    if ((namespaceURI == null) || (namespaceURI.length() == 0) || (!qualifiedName.contains(":")) || (namespaceURI.equals("http://www.w3.org/1999/xhtml")))
    {
      String tagName = qualifiedName;
      int index = tagName.indexOf(":");
      if (index != -1) {
        tagName = tagName.substring(index + 1);
      } else {
        tagName = tagName.toLowerCase();
      }
      IElementFactory factory = (IElementFactory)ELEMENT_FACTORIES.get(tagName);
      if (factory != null) {
        return factory;
      }
    }
    return UnknownElementFactory.instance;
  }
  
  static final class HtmlUnitDOMBuilder
    extends AbstractSAXParser
    implements ContentHandler, LexicalHandler, HTMLTagBalancingListener
  {
    private final HtmlPage page_;
    private Locator locator_;
    private final Stack<DomNode> stack_ = new Stack();
    private DomNode currentNode_;
    private StringBuilder characters_;
    private boolean headParsed_ = false;
    private boolean parsingInnerHead_ = false;
    private HtmlElement head_;
    private HtmlElement body_;
    private Augmentations augmentations_;
    private HtmlForm formWaitingForLostChildren_;
    private static final String FEATURE_AUGMENTATIONS = "http://cyberneko.org/html/features/augmentations";
    private static final String FEATURE_PARSE_NOSCRIPT = "http://cyberneko.org/html/features/parse-noscript-content";
    
    public void pushInputString(String html)
    {
      page_.registerParsingStart();
      page_.registerInlineSnippetParsingStart();
      try
      {
        WebResponse webResponse = page_.getWebResponse();
        String charset = webResponse.getContentCharset();
        String url = webResponse.getRequestSettings().getUrl().toString();
        XMLInputSource in = new XMLInputSource(null, url, null, new StringReader(html), charset);
        ((HTMLConfiguration)fConfiguration).evaluateInputSource(in);
      }
      finally
      {
        page_.registerParsingEnd();
        page_.registerInlineSnippetParsingEnd();
      }
    }
    
    private HtmlUnitDOMBuilder(DomNode node, URL url)
    {
      super();
      page_ = ((HtmlPage)node.getPage());
      
      currentNode_ = node;
      for (Node ancestor : currentNode_.getAncestors(true)) {
        stack_.push((DomNode)ancestor);
      }
      HTMLParserListener listener = page_.getWebClient().getHTMLParserListener();
      boolean reportErrors;
      if (listener != null)
      {
        boolean reportErrors = true;
        fConfiguration.setErrorHandler(new HTMLErrorHandler(listener, url));
      }
      else
      {
        reportErrors = false;
      }
      try
      {
        setFeature("http://cyberneko.org/html/features/augmentations", true);
        setProperty("http://cyberneko.org/html/properties/names/elems", "default");
        setFeature("http://cyberneko.org/html/features/report-errors", reportErrors);
        setFeature("http://cyberneko.org/html/features/balance-tags/ignore-outside-content", HTMLParser.IgnoreOutsideContent_);
        
        setFeature("http://cyberneko.org/html/features/parse-noscript-content", !page_.getWebClient().isJavaScriptEnabled());
        
        setContentHandler(this);
        setLexicalHandler(this);
      }
      catch (SAXException e)
      {
        throw new ObjectInstantiationException("unable to create HTML parser", e);
      }
    }
    
    private static XMLParserConfiguration createConfiguration(WebClient webClient)
    {
      BrowserVersion browserVersion = webClient.getBrowserVersion();
      if (browserVersion.isIE()) {
        new HTMLConfiguration()
        {
          protected HTMLScanner createDocumentScanner()
          {
            return new HTMLScannerForIE(val$browserVersion);
          }
        };
      }
      return new HTMLConfiguration();
    }
    
    public Locator getLocator()
    {
      return locator_;
    }
    
    public void setDocumentLocator(Locator locator)
    {
      locator_ = locator;
    }
    
    public void startDocument()
      throws SAXException
    {}
    
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
      throws SAXException
    {
      handleCharacters();
      
      String tagLower = localName.toLowerCase();
      if ((page_.isParsingHtmlSnippet()) && ((tagLower.equals("html")) || (tagLower.equals("body")))) {
        return;
      }
      if ((parsingInnerHead_) && (page_.getWebClient().getBrowserVersion().hasFeature(BrowserVersionFeatures.IGNORE_CONTENTS_OF_INNER_HEAD))) {
        return;
      }
      if (tagLower.equals("head"))
      {
        if ((headParsed_) || (page_.isParsingHtmlSnippet()))
        {
          parsingInnerHead_ = true;
          return;
        }
        headParsed_ = true;
      }
      else if ((!headParsed_) && ((tagLower.equals("body")) || (tagLower.equals("frameset"))))
      {
        IElementFactory factory = HTMLParser.getElementFactory(namespaceURI, "head");
        HtmlElement newElement = factory.createElement(page_, "head", null);
        currentNode_.appendChild(newElement);
        headParsed_ = true;
      }
      HtmlBody oldBody = null;
      if ((qName.equals("body")) && ((page_.getBody() instanceof HtmlBody))) {
        oldBody = (HtmlBody)page_.getBody();
      }
      if ((!(page_ instanceof XHtmlPage)) && ("http://www.w3.org/1999/xhtml".equals(namespaceURI))) {
        namespaceURI = null;
      }
      IElementFactory factory = HTMLParser.getElementFactory(namespaceURI, qName);
      HtmlElement newElement = factory.createElementNS(page_, namespaceURI, qName, atts);
      newElement.setStartLocation(locator_.getLineNumber(), locator_.getColumnNumber());
      
      addNodeToRightParent(currentNode_, newElement);
      if (oldBody != null) {
        oldBody.quietlyRemoveAndMoveChildrenTo(newElement);
      }
      if (tagLower.equals("body")) {
        body_ = newElement;
      } else if (tagLower.equals("head")) {
        head_ = newElement;
      }
      currentNode_ = newElement;
      stack_.push(currentNode_);
    }
    
    private void addNodeToRightParent(DomNode currentNode, HtmlElement newElement)
    {
      String currentNodeName = currentNode.getNodeName();
      String newNodeName = newElement.getNodeName();
      if (("table".equals(currentNodeName)) && ("div".equals(newNodeName))) {
        currentNode.insertBefore(newElement);
      } else if (("title".equals(newNodeName)) && (head_ != null)) {
        head_.appendChild(newElement);
      } else {
        currentNode.appendChild(newElement);
      }
    }
    
    public void endElement(QName element, Augmentations augs)
      throws XNIException
    {
      augmentations_ = augs;
      super.endElement(element, augs);
    }
    
    public void endElement(String namespaceURI, String localName, String qName)
      throws SAXException
    {
      handleCharacters();
      
      String tagLower = localName.toLowerCase();
      if ((page_.isParsingHtmlSnippet()) && ((tagLower.equals("html")) || (tagLower.equals("body")))) {
        return;
      }
      if (parsingInnerHead_)
      {
        if (tagLower.equals("head")) {
          parsingInnerHead_ = false;
        }
        if ((tagLower.equals("head")) || (page_.getWebClient().getBrowserVersion().hasFeature(BrowserVersionFeatures.IGNORE_CONTENTS_OF_INNER_HEAD))) {
          return;
        }
      }
      DomNode previousNode = (DomNode)stack_.pop();
      previousNode.setEndLocation(locator_.getLineNumber(), locator_.getColumnNumber());
      if (((previousNode instanceof HtmlForm)) && (((HTMLEventInfo)augmentations_.getItem("http://cyberneko.org/html/features/augmentations")).isSynthesized())) {
        formWaitingForLostChildren_ = ((HtmlForm)previousNode);
      } else if ((formWaitingForLostChildren_ != null) && ((previousNode instanceof SubmittableElement))) {
        formWaitingForLostChildren_.addLostChild((HtmlElement)previousNode);
      }
      if (!stack_.isEmpty()) {
        currentNode_ = ((DomNode)stack_.peek());
      }
      boolean postponed = page_.isParsingInlineHtmlSnippet();
      previousNode.onAllChildrenAddedToPage(postponed);
    }
    
    public void characters(char[] ch, int start, int length)
      throws SAXException
    {
      if (((characters_ == null) || (characters_.length() == 0)) && (new String(ch, start, length).trim().length() == 0) && (page_.getWebClient().getBrowserVersion().isIE()))
      {
        DomNode node = currentNode_.getLastChild();
        if ((currentNode_ instanceof HTMLElement.ProxyDomNode))
        {
          HTMLElement.ProxyDomNode proxyNode = (HTMLElement.ProxyDomNode)currentNode_;
          node = proxyNode.getDomNode();
          if (!proxyNode.isAppend())
          {
            node = node.getPreviousSibling();
            if (node == null) {
              node = proxyNode.getDomNode().getParentNode();
            }
          }
        }
        if (removeEmptyCharacters(node)) {
          return;
        }
      }
      if (characters_ == null) {
        characters_ = new StringBuilder();
      }
      characters_.append(ch, start, length);
    }
    
    private boolean removeEmptyCharacters(DomNode node)
    {
      if (node != null)
      {
        if ((node instanceof HtmlInput)) {
          return false;
        }
        if (((node instanceof HtmlAnchor)) || ((node instanceof HtmlSpan)) || ((node instanceof HtmlFont)))
        {
          DomNode anchorChild = node.getFirstChild();
          if (anchorChild != null) {
            return false;
          }
        }
      }
      else if ((currentNode_ instanceof HtmlFont))
      {
        return false;
      }
      return true;
    }
    
    public void ignorableWhitespace(char[] ch, int start, int length)
      throws SAXException
    {
      if (characters_ == null) {
        characters_ = new StringBuilder();
      }
      characters_.append(ch, start, length);
    }
    
    private void handleCharacters()
    {
      if ((characters_ != null) && (characters_.length() > 0)) {
        if ((currentNode_ instanceof HtmlHtml))
        {
          characters_.setLength(0);
        }
        else
        {
          DomText text = new DomText(page_, characters_.toString());
          characters_.setLength(0);
          currentNode_.appendChild(text);
        }
      }
    }
    
    public void endDocument()
      throws SAXException
    {
      handleCharacters();
      DomNode currentPage = page_;
      currentPage.setEndLocation(locator_.getLineNumber(), locator_.getColumnNumber());
    }
    
    public void startPrefixMapping(String prefix, String uri)
      throws SAXException
    {}
    
    public void endPrefixMapping(String prefix)
      throws SAXException
    {}
    
    public void processingInstruction(String target, String data)
      throws SAXException
    {}
    
    public void skippedEntity(String name)
      throws SAXException
    {}
    
    public void comment(char[] ch, int start, int length)
    {
      handleCharacters();
      String data = String.valueOf(ch, start, length);
      if ((!data.startsWith("[CDATA")) || (!page_.getWebClient().getBrowserVersion().isIE()))
      {
        DomComment comment = new DomComment(page_, data);
        currentNode_.appendChild(comment);
      }
    }
    
    public void endCDATA() {}
    
    public void endDTD() {}
    
    public void endEntity(String name) {}
    
    public void startCDATA() {}
    
    public void startDTD(String name, String publicId, String systemId)
    {
      DomDocumentType type = new DomDocumentType(page_, name, publicId, systemId);
      page_.setDocumentType(type);
      page_.appendChild(type);
    }
    
    public void startEntity(String name) {}
    
    public void ignoredEndElement(QName element, Augmentations augs)
    {
      if ((formWaitingForLostChildren_ != null) && ("form".equals(localpart))) {
        formWaitingForLostChildren_ = null;
      }
    }
    
    public void ignoredStartElement(QName elem, XMLAttributes attrs, Augmentations augs)
    {
      if ((body_ != null) && ("body".equalsIgnoreCase(localpart)) && (attrs != null))
      {
        int length = attrs.getLength();
        for (int i = 0; i < length; i++)
        {
          String attrName = attrs.getLocalName(i).toLowerCase();
          if (body_.getAttributes().getNamedItem(attrName) == null)
          {
            body_.setAttribute(attrName, attrs.getValue(i));
            if ((attrName.startsWith("on")) && (body_.getScriptObject() != null))
            {
              HTMLBodyElement jsBody = (HTMLBodyElement)body_.getScriptObject();
              jsBody.createEventHandlerFromAttribute(attrName, attrs.getValue(i));
            }
          }
        }
      }
    }
    
    public void parse(XMLInputSource inputSource)
      throws XNIException, IOException
    {
      HtmlUnitDOMBuilder oldBuilder = page_.getBuilder();
      page_.setBuilder(this);
      try
      {
        super.parse(inputSource);
      }
      finally
      {
        page_.setBuilder(oldBuilder);
      }
    }
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.html.HTMLParser
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.html;

import java.util.Comparator;

class HtmlPage$1
  implements Comparator<HtmlElement>
{
  HtmlPage$1(HtmlPage paramHtmlPage) {}
  
  public int compare(HtmlElement element1, HtmlElement element2)
  {
    Short i1 = element1.getTabIndex();
    Short i2 = element2.getTabIndex();
    short index1;
    short index1;
    if (i1 != null) {
      index1 = i1.shortValue();
    } else {
      index1 = -1;
    }
    short index2;
    short index2;
    if (i2 != null) {
      index2 = i2.shortValue();
    } else {
      index2 = -1;
    }
    int result;
    int result;
    if ((index1 > 0) && (index2 > 0))
    {
      result = index1 - index2;
    }
    else
    {
      int result;
      if (index1 > 0)
      {
        result = -1;
      }
      else
      {
        int result;
        if (index2 > 0)
        {
          result = 1;
        }
        else
        {
          int result;
          if (index1 == index2) {
            result = 0;
          } else {
            result = index2 - index1;
          }
        }
      }
    }
    return result;
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.html.HtmlPage.1
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.html;

 enum HtmlPage$JavaScriptLoadResult
{
  NOOP,  SUCCESS,  DOWNLOAD_ERROR,  COMPILATION_ERROR;
  
  private HtmlPage$JavaScriptLoadResult() {}
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.html.HtmlPage.JavaScriptLoadResult
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.html;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.BrowserVersionFeatures;
import com.gargoylesoftware.htmlunit.Cache;
import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.IncorrectnessListener;
import com.gargoylesoftware.htmlunit.OnbeforeunloadHandler;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.RefreshHandler;
import com.gargoylesoftware.htmlunit.ScriptException;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.TopLevelWindow;
import com.gargoylesoftware.htmlunit.WebAssert;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequestSettings;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.impl.SelectableTextInput;
import com.gargoylesoftware.htmlunit.html.impl.SimpleRange;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.PostponedAction;
import com.gargoylesoftware.htmlunit.javascript.host.Event;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.Script;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.w3c.dom.ranges.Range;

public class HtmlPage
  extends SgmlPage
{
  private static final long serialVersionUID = 1779746292119944291L;
  private static final Log LOG = LogFactory.getLog(HtmlPage.class);
  private HTMLParser.HtmlUnitDOMBuilder builder_;
  private String originalCharset_;
  private Map<String, List<HtmlElement>> idMap_ = new HashMap();
  private Map<String, List<HtmlElement>> nameMap_ = new HashMap();
  private HtmlElement elementWithFocus_;
  private int parserCount_;
  private int snippetParserCount_;
  private int inlineSnippetParserCount_;
  private List<HtmlAttributeChangeListener> attributeListeners_;
  private final Object lock_ = new String();
  private List<Range> selectionRanges_ = new ArrayList(3);
  private final List<PostponedAction> afterLoadActions_ = new ArrayList();
  private boolean cleaning_;
  private HtmlBase base_;
  private URL baseUrl_;
  
  public HtmlPage(URL originatingUrl, WebResponse webResponse, WebWindow webWindow)
  {
    super(webResponse, webWindow);
  }
  
  public HtmlPage getPage()
  {
    return this;
  }
  
  public boolean hasCaseSensitiveTagNames()
  {
    return false;
  }
  
  public void initialize()
    throws IOException, FailingHttpStatusCodeException
  {
    WebWindow enclosingWindow = getEnclosingWindow();
    if (getWebResponse().getRequestSettings().getUrl() == WebClient.URL_ABOUT_BLANK)
    {
      if (((enclosingWindow instanceof FrameWindow)) && (getWebResponse().getRequestSettings().getUrl() == WebClient.URL_ABOUT_BLANK) && (!((FrameWindow)enclosingWindow).getFrameElement().isContentLoaded())) {
        return;
      }
      if ((enclosingWindow instanceof TopLevelWindow))
      {
        TopLevelWindow topWindow = (TopLevelWindow)enclosingWindow;
        WebWindow openerWindow = topWindow.getOpener();
        if ((openerWindow != null) && (openerWindow.getEnclosedPage() != null)) {
          baseUrl_ = openerWindow.getEnclosedPage().getWebResponse().getRequestSettings().getUrl();
        }
      }
    }
    loadFrames();
    setReadyState("complete");
    getDocumentElement().setReadyState("complete");
    if (!getWebClient().getBrowserVersion().isIE()) {
      executeEventHandlersIfNeeded("DOMContentLoaded");
    }
    executeDeferredScriptsIfNeeded();
    setReadyStateOnDeferredScriptsIfNeeded();
    executeEventHandlersIfNeeded("load");
    List<PostponedAction> actions = new ArrayList(afterLoadActions_);
    afterLoadActions_.clear();
    try
    {
      for (PostponedAction action : actions) {
        action.execute();
      }
    }
    catch (IOException e)
    {
      throw e;
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
    executeRefreshIfNeeded();
  }
  
  void addAfterLoadAction(PostponedAction action)
  {
    afterLoadActions_.add(action);
  }
  
  public void cleanUp()
  {
    if (cleaning_) {
      return;
    }
    cleaning_ = true;
    executeEventHandlersIfNeeded("unload");
    deregisterFramesIfNeeded();
    cleaning_ = false;
  }
  
  public HtmlElement getDocumentElement()
  {
    return (HtmlElement)super.getDocumentElement();
  }
  
  public HtmlElement getBody()
  {
    HtmlElement doc = getDocumentElement();
    if (doc != null) {
      for (DomNode node : doc.getChildren()) {
        if (((node instanceof HtmlBody)) || ((node instanceof HtmlFrameSet))) {
          return (HtmlElement)node;
        }
      }
    }
    return null;
  }
  
  public Document getOwnerDocument()
  {
    return null;
  }
  
  public org.w3c.dom.Node importNode(org.w3c.dom.Node importedNode, boolean deep)
  {
    throw new UnsupportedOperationException("HtmlPage.importNode is not yet implemented.");
  }
  
  public DomNodeList<HtmlElement> getElementsByTagName(String tagName)
  {
    return new XPathDomNodeList(this, "//*[local-name()='" + tagName + "']");
  }
  
  public DomNodeList<HtmlElement> getElementsByTagNameNS(String namespaceURI, String localName)
  {
    throw new UnsupportedOperationException("HtmlPage.getElementsByTagNameNS is not yet implemented.");
  }
  
  public HtmlElement getElementById(String elementId)
  {
    try
    {
      return getHtmlElementById(elementId);
    }
    catch (ElementNotFoundException e) {}
    return null;
  }
  
  public String getInputEncoding()
  {
    throw new UnsupportedOperationException("HtmlPage.getInputEncoding is not yet implemented.");
  }
  
  public String getXmlEncoding()
  {
    throw new UnsupportedOperationException("HtmlPage.getXmlEncoding is not yet implemented.");
  }
  
  public boolean getXmlStandalone()
  {
    throw new UnsupportedOperationException("HtmlPage.getXmlStandalone is not yet implemented.");
  }
  
  public void setXmlStandalone(boolean xmlStandalone)
    throws DOMException
  {
    throw new UnsupportedOperationException("HtmlPage.setXmlStandalone is not yet implemented.");
  }
  
  public String getXmlVersion()
  {
    throw new UnsupportedOperationException("HtmlPage.getXmlVersion is not yet implemented.");
  }
  
  public void setXmlVersion(String xmlVersion)
    throws DOMException
  {
    throw new UnsupportedOperationException("HtmlPage.setXmlVersion is not yet implemented.");
  }
  
  public boolean getStrictErrorChecking()
  {
    throw new UnsupportedOperationException("HtmlPage.getStrictErrorChecking is not yet implemented.");
  }
  
  public void setStrictErrorChecking(boolean strictErrorChecking)
  {
    throw new UnsupportedOperationException("HtmlPage.setStrictErrorChecking is not yet implemented.");
  }
  
  public String getDocumentURI()
  {
    throw new UnsupportedOperationException("HtmlPage.getDocumentURI is not yet implemented.");
  }
  
  public void setDocumentURI(String documentURI)
  {
    throw new UnsupportedOperationException("HtmlPage.setDocumentURI is not yet implemented.");
  }
  
  public org.w3c.dom.Node adoptNode(org.w3c.dom.Node source)
    throws DOMException
  {
    throw new UnsupportedOperationException("HtmlPage.adoptNode is not yet implemented.");
  }
  
  public DOMConfiguration getDomConfig()
  {
    throw new UnsupportedOperationException("HtmlPage.getDomConfig is not yet implemented.");
  }
  
  public org.w3c.dom.Node renameNode(org.w3c.dom.Node newNode, String namespaceURI, String qualifiedName)
    throws DOMException
  {
    throw new UnsupportedOperationException("HtmlPage.renameNode is not yet implemented.");
  }
  
  public String getPageEncoding()
  {
    if (originalCharset_ == null) {
      originalCharset_ = getWebResponse().getContentCharset();
    }
    return originalCharset_;
  }
  
  public HtmlElement createElement(String tagName)
  {
    if (tagName.indexOf(':') == -1) {
      tagName = tagName.toLowerCase();
    }
    return HTMLParser.getFactory(tagName).createElement(this, tagName, null);
  }
  
  public HtmlElement createElementNS(String namespaceURI, String qualifiedName)
  {
    return HTMLParser.getElementFactory(namespaceURI, qualifiedName).createElementNS(this, namespaceURI, qualifiedName, null);
  }
  
  public Attr createAttributeNS(String namespaceURI, String qualifiedName)
  {
    throw new UnsupportedOperationException("HtmlPage.createAttributeNS is not yet implemented.");
  }
  
  public Comment createComment(String data)
  {
    return new DomComment(this, data);
  }
  
  public Text createTextNode(String data)
  {
    return new DomText(this, data);
  }
  
  public CDATASection createCDATASection(String data)
  {
    return new DomCDataSection(this, data);
  }
  
  public DocumentFragment createDocumentFragment()
  {
    return new DomDocumentFragment(this);
  }
  
  public DOMImplementation getImplementation()
  {
    throw new UnsupportedOperationException("HtmlPage.getImplementation is not yet implemented.");
  }
  
  public EntityReference createEntityReference(String id)
  {
    throw new UnsupportedOperationException("HtmlPage.createEntityReference is not yet implemented.");
  }
  
  public ProcessingInstruction createProcessingInstruction(String namespaceURI, String qualifiedName)
  {
    throw new UnsupportedOperationException("HtmlPage.createProcessingInstruction is not yet implemented.");
  }
  
  public HtmlAnchor getAnchorByName(String name)
    throws ElementNotFoundException
  {
    return (HtmlAnchor)getDocumentElement().getOneHtmlElementByAttribute("a", "name", name);
  }
  
  public HtmlAnchor getAnchorByHref(String href)
    throws ElementNotFoundException
  {
    return (HtmlAnchor)getDocumentElement().getOneHtmlElementByAttribute("a", "href", href);
  }
  
  public List<HtmlAnchor> getAnchors()
  {
    return getDocumentElement().getHtmlElementsByTagName("a");
  }
  
  @Deprecated
  public HtmlAnchor getFirstAnchorByText(String text)
    throws ElementNotFoundException
  {
    return getAnchorByText(text);
  }
  
  public HtmlAnchor getAnchorByText(String text)
    throws ElementNotFoundException
  {
    WebAssert.notNull("text", text);
    for (HtmlAnchor anchor : getAnchors()) {
      if (text.equals(anchor.asText())) {
        return anchor;
      }
    }
    throw new ElementNotFoundException("a", "<text>", text);
  }
  
  public HtmlForm getFormByName(String name)
    throws ElementNotFoundException
  {
    List<HtmlForm> forms = getDocumentElement().getElementsByAttribute("form", "name", name);
    if (forms.size() == 0) {
      throw new ElementNotFoundException("form", "name", name);
    }
    return (HtmlForm)forms.get(0);
  }
  
  public List<HtmlForm> getForms()
  {
    return getDocumentElement().getHtmlElementsByTagName("form");
  }
  
  public URL getFullyQualifiedUrl(String relativeUrl)
    throws MalformedURLException
  {
    URL baseUrl;
    if (base_ == null)
    {
      URL baseUrl = getWebResponse().getRequestSettings().getUrl();
      WebWindow window = getEnclosingWindow();
      boolean frame = window != window.getTopWindow();
      if (frame)
      {
        boolean frameSrcIsNotSet = baseUrl == WebClient.URL_ABOUT_BLANK;
        boolean frameSrcIsJs = "javascript".equals(baseUrl.getProtocol());
        boolean jsFrameUseParentUrl = getWebClient().getBrowserVersion().hasFeature(BrowserVersionFeatures.JS_FRAME_RESOLVE_URL_WITH_PARENT_WINDOW);
        if ((frameSrcIsNotSet) || ((frameSrcIsJs) && (jsFrameUseParentUrl))) {
          baseUrl = ((HtmlPage)window.getTopWindow().getEnclosedPage()).getWebResponse().getRequestSettings().getUrl();
        }
      }
      else if (baseUrl_ != null)
      {
        baseUrl = baseUrl_;
      }
    }
    else
    {
      boolean insideHead = false;
      for (DomNode parent = base_.getParentNode(); parent != null; parent = parent.getParentNode()) {
        if ((parent instanceof HtmlHead))
        {
          insideHead = true;
          break;
        }
      }
      if (!insideHead) {
        notifyIncorrectness("Element 'base' must appear in <head>, it is ignored.");
      }
      String href = base_.getHrefAttribute();
      URL baseUrl;
      if ((!insideHead) || (StringUtils.isEmpty(href))) {
        baseUrl = getWebResponse().getRequestSettings().getUrl();
      } else {
        try
        {
          baseUrl = new URL(href);
        }
        catch (MalformedURLException e)
        {
          notifyIncorrectness("Invalid base url: \"" + href + "\", ignoring it");
          baseUrl = getWebResponse().getRequestSettings().getUrl();
        }
      }
    }
    if (getWebClient().getBrowserVersion().isFirefox())
    {
      boolean incorrectnessNotified = false;
      while ((relativeUrl.startsWith("http:")) && (!relativeUrl.startsWith("http://")))
      {
        if (!incorrectnessNotified)
        {
          notifyIncorrectness("Incorrect URL \"" + relativeUrl + "\" has been corrected");
          incorrectnessNotified = true;
        }
        relativeUrl = "http:/" + relativeUrl.substring(5);
      }
    }
    return WebClient.expandUrl(baseUrl, relativeUrl);
  }
  
  public String getResolvedTarget(String elementTarget)
  {
    String resolvedTarget;
    String resolvedTarget;
    if (base_ == null)
    {
      resolvedTarget = elementTarget;
    }
    else
    {
      String resolvedTarget;
      if ((elementTarget != null) && (elementTarget.length() > 0)) {
        resolvedTarget = elementTarget;
      } else {
        resolvedTarget = base_.getTargetAttribute();
      }
    }
    return resolvedTarget;
  }
  
  public List<String> getTabbableElementIds()
  {
    List<String> list = new ArrayList();
    for (HtmlElement element : getTabbableElements()) {
      list.add(element.getAttribute("id"));
    }
    return Collections.unmodifiableList(list);
  }
  
  public List<HtmlElement> getTabbableElements()
  {
    List<String> tags = Arrays.asList(new String[] { "a", "area", "button", "input", "object", "select", "textarea" });
    
    List<HtmlElement> tabbableElements = new ArrayList();
    for (HtmlElement element : getHtmlElementDescendants())
    {
      String tagName = element.getTagName();
      if (tags.contains(tagName))
      {
        boolean disabled = element.hasAttribute("disabled");
        if ((!disabled) && (element.getTabIndex() != HtmlElement.TAB_INDEX_OUT_OF_BOUNDS)) {
          tabbableElements.add(element);
        }
      }
    }
    Collections.sort(tabbableElements, createTabOrderComparator());
    return Collections.unmodifiableList(tabbableElements);
  }
  
  private Comparator<HtmlElement> createTabOrderComparator()
  {
    new Comparator()
    {
      public int compare(HtmlElement element1, HtmlElement element2)
      {
        Short i1 = element1.getTabIndex();
        Short i2 = element2.getTabIndex();
        short index1;
        short index1;
        if (i1 != null) {
          index1 = i1.shortValue();
        } else {
          index1 = -1;
        }
        short index2;
        short index2;
        if (i2 != null) {
          index2 = i2.shortValue();
        } else {
          index2 = -1;
        }
        int result;
        int result;
        if ((index1 > 0) && (index2 > 0))
        {
          result = index1 - index2;
        }
        else
        {
          int result;
          if (index1 > 0)
          {
            result = -1;
          }
          else
          {
            int result;
            if (index2 > 0)
            {
              result = 1;
            }
            else
            {
              int result;
              if (index1 == index2) {
                result = 0;
              } else {
                result = index2 - index1;
              }
            }
          }
        }
        return result;
      }
    };
  }
  
  public HtmlElement getElementByAccessKey(char accessKey)
  {
    List<HtmlElement> elements = getElementsByAccessKey(accessKey);
    if (elements.isEmpty()) {
      return null;
    }
    return (HtmlElement)elements.get(0);
  }
  
  public List<HtmlElement> getElementsByAccessKey(char accessKey)
  {
    List<HtmlElement> elements = new ArrayList();
    
    String searchString = ("" + accessKey).toLowerCase();
    List<String> acceptableTagNames = Arrays.asList(new String[] { "a", "area", "button", "input", "label", "legend", "textarea" });
    for (HtmlElement element : getHtmlElementDescendants()) {
      if (acceptableTagNames.contains(element.getTagName()))
      {
        String accessKeyAttribute = element.getAttribute("accesskey");
        if (searchString.equalsIgnoreCase(accessKeyAttribute)) {
          elements.add(element);
        }
      }
    }
    return elements;
  }
  
  public ScriptResult executeJavaScript(String sourceCode)
  {
    return executeJavaScriptIfPossible(sourceCode, "injected script", 1);
  }
  
  public ScriptResult executeJavaScriptIfPossible(String sourceCode, String sourceName, int startLine)
  {
    if (!getWebClient().isJavaScriptEnabled()) {
      return new ScriptResult(null, this);
    }
    if (sourceCode.toLowerCase().startsWith("javascript:")) {
      sourceCode = sourceCode.substring("javascript:".length());
    }
    Object result = getWebClient().getJavaScriptEngine().execute(this, sourceCode, sourceName, startLine);
    return new ScriptResult(result, getWebClient().getCurrentWindow().getEnclosedPage());
  }
  
  public ScriptResult executeJavaScriptFunctionIfPossible(Function function, Scriptable thisObject, Object[] args, DomNode htmlElementScope)
  {
    if (!getWebClient().isJavaScriptEnabled()) {
      return new ScriptResult(null, this);
    }
    JavaScriptEngine engine = getWebClient().getJavaScriptEngine();
    Object result = engine.callFunction(this, function, thisObject, args, htmlElementScope);
    
    return new ScriptResult(result, getWebClient().getCurrentWindow().getEnclosedPage());
  }
  
  static enum JavaScriptLoadResult
  {
    NOOP,  SUCCESS,  DOWNLOAD_ERROR,  COMPILATION_ERROR;
    
    private JavaScriptLoadResult() {}
  }
  
  JavaScriptLoadResult loadExternalJavaScriptFile(String srcAttribute, String charset)
    throws FailingHttpStatusCodeException
  {
    WebClient client = getWebClient();
    if ((StringUtils.isBlank(srcAttribute)) || (!client.isJavaScriptEnabled())) {
      return JavaScriptLoadResult.NOOP;
    }
    URL scriptURL;
    try
    {
      scriptURL = getFullyQualifiedUrl(srcAttribute);
      if (scriptURL.getProtocol().equals("javascript"))
      {
        if (LOG.isInfoEnabled()) {
          LOG.info("Ignoring script src [" + srcAttribute + "]");
        }
        return JavaScriptLoadResult.NOOP;
      }
    }
    catch (MalformedURLException e)
    {
      if (LOG.isErrorEnabled()) {
        LOG.error("Unable to build URL for script src tag [" + srcAttribute + "]");
      }
      if (client.isThrowExceptionOnScriptError()) {
        throw new ScriptException(this, e);
      }
      return JavaScriptLoadResult.NOOP;
    }
    Script script;
    try
    {
      script = loadJavaScriptFromUrl(scriptURL, charset);
    }
    catch (IOException e)
    {
      if (LOG.isErrorEnabled()) {
        LOG.error("Error loading JavaScript from [" + scriptURL + "].", e);
      }
      return JavaScriptLoadResult.DOWNLOAD_ERROR;
    }
    if (script == null) {
      return JavaScriptLoadResult.COMPILATION_ERROR;
    }
    client.getJavaScriptEngine().execute(this, script);
    return JavaScriptLoadResult.SUCCESS;
  }
  
  private Script loadJavaScriptFromUrl(URL url, String charset)
    throws IOException, FailingHttpStatusCodeException
  {
    String scriptEncoding = charset;
    String pageEncoding = getPageEncoding();
    WebRequestSettings referringRequest = getWebResponse().getRequestSettings();
    
    WebClient client = getWebClient();
    Cache cache = client.getCache();
    
    WebRequestSettings request = new WebRequestSettings(url);
    request.setAdditionalHeaders(new HashMap(referringRequest.getAdditionalHeaders()));
    request.setAdditionalHeader("Referer", referringRequest.getUrl().toString());
    
    Object cachedScript = cache.getCachedObject(request);
    if ((cachedScript instanceof Script)) {
      return (Script)cachedScript;
    }
    WebResponse response = client.loadWebResponse(request);
    client.printContentIfNecessary(response);
    client.throwFailingHttpStatusCodeExceptionIfNecessary(response);
    
    int statusCode = response.getStatusCode();
    boolean successful = (statusCode >= 200) && (statusCode < 300);
    boolean noContent = statusCode == 204;
    if ((!successful) || (noContent)) {
      throw new IOException("Unable to download JavaScript from '" + url + "' (status " + statusCode + ").");
    }
    String contentType = response.getContentType();
    if ((!contentType.equalsIgnoreCase("application/javascript")) && (!contentType.equalsIgnoreCase("application/ecmascript"))) {
      if ((contentType.equals("text/javascript")) || (contentType.equals("text/ecmascript"))) {
        getWebClient().getIncorrectnessListener().notify("Obsolete content type encountered: '" + contentType + "'.", this);
      } else {
        getWebClient().getIncorrectnessListener().notify("Expected content type of 'application/javascript' or 'application/ecmascript' for remotely loaded JavaScript element at '" + url + "', " + "but got '" + contentType + "'.", this);
      }
    }
    if (StringUtils.isEmpty(scriptEncoding))
    {
      String contentCharset = response.getContentCharset();
      if (!contentCharset.equals("ISO-8859-1")) {
        scriptEncoding = contentCharset;
      } else if (!pageEncoding.equals("ISO-8859-1")) {
        scriptEncoding = pageEncoding;
      } else {
        scriptEncoding = "ISO-8859-1";
      }
    }
    String scriptCode = response.getContentAsString(scriptEncoding);
    JavaScriptEngine javaScriptEngine = client.getJavaScriptEngine();
    Script script = javaScriptEngine.compile(this, scriptCode, url.toExternalForm(), 1);
    if (script != null) {
      cache.cacheIfPossible(request, response, script);
    }
    return script;
  }
  
  public String getTitleText()
  {
    HtmlTitle titleElement = getTitleElement();
    if (titleElement != null) {
      return titleElement.asText();
    }
    return "";
  }
  
  public void setTitleText(String message)
  {
    HtmlTitle titleElement = getTitleElement();
    if (titleElement == null)
    {
      if (LOG.isDebugEnabled()) {
        LOG.debug("No title element, creating one");
      }
      HtmlHead head 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2017. Infinite Loop Ltd