1 21 24 package org.lobobrowser.html.domimpl; 25 26 import org.lobobrowser.html.*; 27 import org.lobobrowser.html.io.*; 28 import org.lobobrowser.html.js.*; 29 import org.lobobrowser.html.parser.HtmlParser; 30 import org.lobobrowser.html.style.*; 31 import org.lobobrowser.util.*; 32 import org.lobobrowser.util.io.EmptyReader; 33 import org.w3c.dom.*; 34 import org.w3c.dom.css.CSSStyleSheet; 35 import org.w3c.dom.html2.*; 36 import org.xml.sax.ErrorHandler ; 37 import org.xml.sax.SAXException ; 38 import org.mozilla.javascript.Function; 39 40 import java.io.*; 41 import java.net.MalformedURLException ; 42 import java.net.URL ; 43 import java.util.*; 44 import java.util.logging.*; 45 import java.security.*; 46 47 public class HTMLDocumentImpl extends NodeImpl implements HTMLDocument { 48 private static final Logger logger = Logger.getLogger(HTMLDocumentImpl.class.getName()); 49 private final ElementFactory factory; 50 private final HtmlRendererContext rcontext; 51 private final UserAgentContext ucontext; 52 private final Window window; 53 private final Map elementsById = new WeakValueHashMap(); 54 private String documentURI; 55 private java.net.URL documentURL; 56 57 private WritableLineReader reader; 58 59 public HTMLDocumentImpl(HtmlRendererContext rcontext) { 60 this(rcontext.getUserAgentContext(), rcontext, null, null); 61 } 62 63 public HTMLDocumentImpl(UserAgentContext ucontext) { 64 this(ucontext, null, null, null); 65 } 66 67 public HTMLDocumentImpl(final UserAgentContext ucontext, final HtmlRendererContext rcontext, WritableLineReader reader, String documentURI) { 68 this.factory = ElementFactory.getInstance(); 69 this.rcontext = rcontext; 70 this.ucontext = ucontext; 71 this.reader = reader; 72 this.documentURI = documentURI; 73 try { 74 java.net.URL docURL = new java.net.URL (documentURI); 75 SecurityManager sm = System.getSecurityManager(); 76 if(sm != null) { 77 sm.checkPermission(new java.net.SocketPermission (docURL.getHost(), "connect")); 82 } 83 this.documentURL = docURL; 84 this.domain = docURL.getHost(); 85 } catch(java.net.MalformedURLException mfu) { 86 logger.warning("HTMLDocumentImpl(): Document URI [" + documentURI + "] is malformed."); 87 } 88 this.document = this; 89 Window window; 91 if(rcontext != null) { 92 window = Window.getWindow(rcontext); 93 } 94 else { 95 window = new Window(null, ucontext); 97 } 98 this.window = window; 100 window.setDocument(this); 101 this.setUserData(Executor.SCOPE_KEY, window.getWindowScope(), null); 103 } 104 105 String getDocumentHost() { 106 URL docUrl = this.documentURL; 107 return docUrl == null ? null : docUrl.getHost(); 108 } 109 110 public URL getDocumentURL() { 111 return this.documentURL; 113 } 114 115 118 void setElementById(String id, Element element) { 119 synchronized(this) { 120 this.elementsById.put(id, element); 121 } 122 } 123 124 void removeElementById(String id) { 125 synchronized(this) { 126 this.elementsById.remove(id); 127 } 128 } 129 130 private volatile String baseURI; 131 132 135 public String getBaseURI() { 136 String buri = this.baseURI; 137 return buri == null ? this.documentURI : buri; 138 } 139 140 public void setBaseURI(String value) { 141 this.baseURI = value; 142 } 143 144 private String defaultTarget; 145 146 public String getDefaultTarget() { 147 return this.defaultTarget; 148 } 149 150 public void setDefaultTarget(String value) { 151 this.defaultTarget = value; 152 } 153 154 public String getTextContent() throws DOMException { 155 return null; 156 } 157 158 public void setTextContent(String textContent) throws DOMException { 159 } 161 162 private String title; 163 164 public String getTitle() { 165 return this.title; 166 } 167 168 public void setTitle(String title) { 169 this.title = title; 170 } 171 172 private String referrer; 173 174 public String getReferrer() { 175 return this.referrer; 176 } 177 178 public void setReferrer(String value) { 179 this.referrer = value; 180 } 181 182 private String domain; 183 184 public String getDomain() { 185 return this.domain; 186 } 187 188 public void setDomain(String domain) { 189 String oldDomain = this.domain; 190 if(oldDomain != null && Domains.isValidCookieDomain(domain, oldDomain)) { 191 this.domain = domain; 192 } 193 else { 194 throw new SecurityException ("Cannot set domain to '" + domain + "' when current domain is '" + oldDomain + "'"); 195 } 196 } 197 198 public HTMLElement getBody() { 199 synchronized(this) { 200 return this.body; 201 } 202 } 203 204 private HTMLCollection images; 205 private HTMLCollection applets; 206 private HTMLCollection links; 207 private HTMLCollection forms; 208 private HTMLCollection anchors; 209 private HTMLCollection frames; 210 211 public HTMLCollection getImages() { 212 synchronized(this) { 213 if(this.images == null) { 214 this.images = new FilteredHTMLCollectionImpl(this, this.elementsById, new ImageFilter(), this.treeLock); 215 } 216 return this.images; 217 } 218 } 219 220 public HTMLCollection getApplets() { 221 synchronized(this) { 222 if(this.applets == null) { 223 this.applets = new FilteredHTMLCollectionImpl(this, this.elementsById, new AppletFilter(), this.treeLock); 225 } 226 return this.applets; 227 } 228 } 229 230 public HTMLCollection getLinks() { 231 synchronized(this) { 232 if(this.links == null) { 233 this.links = new FilteredHTMLCollectionImpl(this, this.elementsById, new LinkFilter(), this.treeLock); 234 } 235 return this.links; 236 } 237 } 238 239 public HTMLCollection getForms() { 240 synchronized(this) { 241 if(this.forms == null) { 242 this.forms = new FilteredHTMLCollectionImpl(this, this.elementsById, new FormFilter(), this.treeLock); 243 } 244 return this.forms; 245 } 246 } 247 248 public HTMLCollection getFrames() { 249 synchronized(this) { 250 if(this.frames == null) { 251 this.frames = new FilteredHTMLCollectionImpl(this, this.elementsById, new FrameFilter(), this.treeLock); 252 } 253 return this.frames; 254 } 255 } 256 257 public HTMLCollection getAnchors() { 258 synchronized(this) { 259 if(this.anchors == null) { 260 this.anchors = new FilteredHTMLCollectionImpl(this, this.elementsById, new AnchorFilter(), this.treeLock); 261 } 262 return this.anchors; 263 } 264 } 265 266 public String getCookie() { 267 SecurityManager sm = System.getSecurityManager(); 268 if(sm != null) { 269 return (String ) AccessController.doPrivileged(new PrivilegedAction() { 270 public Object run() { 277 return ucontext.getCookie(documentURL); 278 } 279 }); 280 } 281 else { 282 return this.ucontext.getCookie(this.documentURL); 283 } 284 } 285 286 public void setCookie(final String cookie) throws DOMException { 287 SecurityManager sm = System.getSecurityManager(); 288 if(sm != null) { 289 AccessController.doPrivileged(new PrivilegedAction() { 290 public Object run() { 297 ucontext.setCookie(documentURL, cookie); 298 return null; 299 } 300 }); 301 } 302 else { 303 this.ucontext.setCookie(this.documentURL, cookie); 304 } 305 } 306 307 public void open() { 308 synchronized(this.treeLock) { 309 if(this.reader != null) { 310 if(this.reader instanceof LocalWritableLineReader) { 311 try { 312 this.reader.close(); 313 } catch(IOException ioe) { 314 } 316 this.reader = null; 317 } 318 else { 319 return; 322 } 323 } 324 this.removeAllChildrenImpl(); 325 this.reader = new LocalWritableLineReader(new EmptyReader()); 326 } 327 } 328 329 336 public void load() throws IOException,SAXException ,UnsupportedEncodingException { 337 this.load(true); 338 } 339 340 public void load(boolean closeReader) throws IOException,SAXException ,UnsupportedEncodingException { 341 WritableLineReader reader; 342 synchronized(this.treeLock) { 343 this.removeAllChildrenImpl(); 344 this.setTitle(null); 345 this.setBaseURI(null); 346 this.setDefaultTarget(null); 347 this.styleSheets.clear(); 348 this.styleSheetAggregator = null; 349 reader = this.reader; 350 } 351 if(reader != null) { 352 try { 353 ErrorHandler errorHandler = new LocalErrorHandler(); 354 String systemId = this.documentURI; 355 String publicId = systemId; 356 HtmlParser parser = new HtmlParser(this.ucontext, this, errorHandler, publicId, systemId); 357 parser.parse(reader); 358 } finally { 359 if(closeReader) { 360 try { 361 reader.close(); 362 } catch(Exception err) { 363 logger.log(Level.WARNING,"load(): Unable to close stream", err); 364 } 365 synchronized(this.treeLock) { 366 this.reader = null; 367 } 368 } 369 } 370 } 371 } 372 373 public void close() { 374 synchronized(this.treeLock) { 375 if(this.reader instanceof LocalWritableLineReader) { 376 try { 377 this.reader.close(); 378 } catch(java.io.IOException ioe) { 379 } 381 this.reader = null; 382 } 383 else { 384 } 386 } 388 } 389 390 public void write(String text) { 391 synchronized(this.treeLock) { 392 if(this.reader != null) { 393 try { 394 this.reader.write(text); 396 } catch(IOException ioe) { 397 } 399 } 400 } 401 } 402 403 public void writeln(String text) { 404 synchronized(this.treeLock) { 405 if(this.reader != null) { 406 try { 407 this.reader.write(text + "\r\n"); 409 } catch(IOException ioe) { 410 } 412 } 413 } 414 } 415 416 private void openBufferChanged(String text) { 417 ErrorHandler errorHandler = new LocalErrorHandler(); 420 String systemId = this.documentURI; 421 String publicId = systemId; 422 HtmlParser parser = new HtmlParser(this.ucontext, this, errorHandler, publicId, systemId); 423 StringReader strReader = new StringReader(text); 424 try { 425 parser.parse(strReader); 427 } catch(Exception err) { 428 this.warn("Unable to parse written HTML text. BaseURI=[" + this.getBaseURI() + "].", err); 429 } 430 } 431 432 436 public NodeList getElementsByName(String elementName) { 437 return this.getNodeList(new ElementNameFilter(elementName)); 438 } 439 440 private DocumentType doctype; 441 442 public DocumentType getDoctype() { 443 return this.doctype; 444 } 445 446 public void setDoctype(DocumentType doctype) { 447 this.doctype = doctype; 448 } 449 450 public Element getDocumentElement() { 451 synchronized(this.treeLock) { 452 ArrayList nl = this.nodeList; 453 if(nl != null) { 454 Iterator i = nl.iterator(); 455 while(i.hasNext()) { 456 Object node = i.next(); 457 if(node instanceof Element) { 458 return (Element) node; 459 } 460 } 461 } 462 return null; 463 } 464 } 465 466 public Element createElement(String tagName) 467 throws DOMException { 468 return this.factory.createElement(this, tagName); 469 } 470 471 474 public DocumentFragment createDocumentFragment() { 475 DocumentFragmentImpl node = new DocumentFragmentImpl(); 479 node.setOwnerDocument(this); 480 return node; 481 } 482 483 public Text createTextNode(String data) { 484 TextImpl node = new TextImpl(data); 485 node.setOwnerDocument(this); 486 return node; 487 } 488 489 public Comment createComment(String data) { 490 CommentImpl node = new CommentImpl(data); 491 node.setOwnerDocument(this); 492 return node; 493 } 494 495 public CDATASection createCDATASection(String data) 496 throws DOMException { 497 CDataSectionImpl node = new CDataSectionImpl(data); 498 node.setOwnerDocument(this); 499 return node; 500 } 501 502 public ProcessingInstruction createProcessingInstruction( 503 String target, String data) throws DOMException { 504 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "HTML document"); 505 } 506 507 public Attr createAttribute(String name) throws DOMException { 508 return new AttrImpl(name); 509 } 510 511 public EntityReference createEntityReference(String name) 512 throws DOMException { 513 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "HTML document"); 514 } 515 516 521 public NodeList getElementsByTagName(String tagname) { 522 if("*".equals(tagname)) { 523 return this.getNodeList(new ElementFilter()); 524 } 525 else { 526 return this.getNodeList(new TagNameFilter(tagname)); 527 } 528 } 529 530 public Node importNode(Node importedNode, boolean deep) 531 throws DOMException { 532 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implemented"); 533 } 534 535 public Element createElementNS(String namespaceURI, 536 String qualifiedName) throws DOMException { 537 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "HTML document"); 538 } 539 540 public Attr createAttributeNS(String namespaceURI, 541 String qualifiedName) throws DOMException { 542 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "HTML document"); 543 } 544 545 public NodeList getElementsByTagNameNS(String namespaceURI, 546 String localName) { 547 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "HTML document"); 548 } 549 550 public Element getElementById(String elementId) { 551 Element element; 552 synchronized(this) { 553 element = (Element) this.elementsById.get(elementId); 554 } 555 return element; 556 } 557 558 private final Map elementsByName = new HashMap(0); 559 560 public Element namedItem(String name) { 561 Element element; 562 synchronized(this) { 563 element = (Element) this.elementsByName.get(name); 564 } 565 return element; 566 } 567 568 void setNamedItem(String name, Element element) { 569 synchronized(this) { 570 this.elementsByName.put(name, element); 571 } 572 } 573 574 void removeNamedItem(String name) { 575 synchronized(this) { 576 this.elementsByName.remove(name); 577 } 578 } 579 580 private String inputEncoding; 581 582 public String getInputEncoding() { 583 return this.inputEncoding; 584 } 585 586 private String xmlEncoding; 587 588 public String getXmlEncoding() { 589 return this.xmlEncoding; 590 } 591 592 private boolean xmlStandalone; 593 594 public boolean getXmlStandalone() { 595 return this.xmlStandalone; 596 } 597 598 public void setXmlStandalone(boolean xmlStandalone) throws DOMException { 599 this.xmlStandalone = xmlStandalone; 600 } 601 602 private String xmlVersion = null; 603 604 public String getXmlVersion() { 605 return this.xmlVersion; 606 } 607 608 public void setXmlVersion(String xmlVersion) throws DOMException { 609 this.xmlVersion = xmlVersion; 610 } 611 612 private boolean strictErrorChecking = true; 613 614 public boolean getStrictErrorChecking() { 615 return this.strictErrorChecking; 616 } 617 618 public void setStrictErrorChecking(boolean strictErrorChecking) { 619 this.strictErrorChecking = strictErrorChecking; 620 } 621 622 public String getDocumentURI() { 623 return this.documentURI; 624 } 625 626 public void setDocumentURI(String documentURI) { 627 this.documentURI = documentURI; 629 } 630 631 public Node adoptNode(Node source) throws DOMException { 632 if(source instanceof NodeImpl) { 633 NodeImpl node = (NodeImpl) source; 634 node.setOwnerDocument(this, true); 635 return node; 636 } 637 else { 638 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Invalid Node implementation"); 639 } 640 } 641 642 private DOMConfiguration domConfig; 643 644 public DOMConfiguration getDomConfig() { 645 synchronized(this) { 646 if(this.domConfig == null) { 647 this.domConfig = new DOMConfigurationImpl(); 648 } 649 return this.domConfig; 650 } 651 } 652 653 public void normalizeDocument() { 654 synchronized(this.treeLock) { 656 this.visitImpl(new NodeVisitor() { 657 public void visit(Node node) { 658 node.normalize(); 659 } 660 }); 661 } 662 } 663 664 public Node renameNode(Node n, String namespaceURI, 665 String qualifiedName) throws DOMException { 666 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "No renaming"); 667 } 668 669 private DOMImplementation domImplementation; 670 671 674 public DOMImplementation getImplementation() { 675 synchronized(this) { 676 if(this.domImplementation == null) { 677 this.domImplementation = new DOMImplementationImpl(this.ucontext); 678 } 679 return this.domImplementation; 680 } 681 } 682 683 686 public String getLocalName() { 687 return null; 689 } 690 691 694 public String getNodeName() { 695 return "#document"; 696 } 697 698 701 public short getNodeType() { 702 return Node.DOCUMENT_NODE; 703 } 704 705 708 public String getNodeValue() throws DOMException { 709 return null; 711 } 712 713 716 public void setNodeValue(String nodeValue) throws DOMException { 717 throw new DOMException(DOMException.INVALID_MODIFICATION_ERR, "Cannot set node value of document"); 718 } 719 720 public final HtmlRendererContext getHtmlRendererContext() { 721 return this.rcontext; 722 } 723 724 public UserAgentContext getUserAgentContext() { 725 return this.ucontext; 726 } 727 728 public final URL getFullURL(String uri) { 729 try { 730 String baseURI = this.getBaseURI(); 731 URL documentURL = baseURI == null ? null : new URL (baseURI); 732 return Urls.createURL(documentURL, uri); 733 } catch(MalformedURLException mfu) { 734 try { 736 return new URL (uri); 737 } catch(MalformedURLException mfu2) { 738 logger.log(Level.WARNING,"Unable to create URL for URI=[" + uri + "], with base=[" + this.getBaseURI() + "].", mfu); 739 return null; 740 } 741 } 742 } 743 744 public final Location getLocation() { 745 return this.window.getLocation(); 746 } 747 748 public void setLocation(String location) { 749 this.getLocation().setHref(location); 750 } 751 752 public String getURL() { 753 return this.documentURI; 754 } 755 756 private HTMLElement body; 757 758 public void setBody(HTMLElement body) { 759 synchronized(this) { 760 this.body = body; 761 } 762 } 763 764 private final Collection styleSheets = new LinkedList(); 765 766 final void addStyleSheet(CSSStyleSheet ss) { 767 synchronized(this.treeLock) { 768 this.styleSheets.add(ss); 769 this.styleSheetAggregator = null; 770 this.forgetRenderState(); 773 ArrayList nl = this.nodeList; 775 if(nl != null) { 776 Iterator i = nl.iterator(); 777 while(i.hasNext()) { 778 Object node = i.next(); 779 if(node instanceof HTMLElementImpl) { 780 ((HTMLElementImpl) node).forgetStyle(true); 781 } 782 } 783 } 784 } 785 this.allInvalidated(); 786 } 787 788 private StyleSheetAggregator styleSheetAggregator = null; 789 790 final StyleSheetAggregator getStyleSheetAggregator() { 791 synchronized(this.treeLock) { 792 StyleSheetAggregator ssa = this.styleSheetAggregator; 793 if(ssa == null) { 794 ssa = new StyleSheetAggregator(this); 795 try { 796 ssa.addStyleSheets(this.styleSheets); 797 } catch(MalformedURLException mfu) { 798 logger.log(Level.WARNING,"getStyleSheetAggregator()", mfu); 799 } 800 this.styleSheetAggregator = ssa; 801 } 802 return ssa; 803 } 804 } 805 806 private final ArrayList documentNotificationListeners = new ArrayList(1); 807 808 public void addDocumentNotificationListener(DocumentNotificationListener listener) { 809 ArrayList listenersList = this.documentNotificationListeners; 810 synchronized(listenersList) { 811 listenersList.add(listener); 812 } 813 } 814 815 public void removeDocumentNotificationListener(DocumentNotificationListener listener) { 816 ArrayList listenersList = this.documentNotificationListeners; 817 synchronized(listenersList) { 818 listenersList.remove(listener); 819 } 820 } 821 822 public void sizeInvalidated(NodeImpl node) { 823 ArrayList listenersList = this.documentNotificationListeners; 824 int size; 825 synchronized(listenersList) { 826 size = listenersList.size(); 827 } 828 for(int i = 0; i < size; i++) { 833 try { 834 DocumentNotificationListener dnl = (DocumentNotificationListener) listenersList.get(i); 835 dnl.sizeInvalidated(node); 836 } catch(IndexOutOfBoundsException iob) { 837 } 839 } 840 } 841 842 849 public void lookInvalidated(NodeImpl node) { 850 ArrayList listenersList = this.documentNotificationListeners; 851 int size; 852 synchronized(listenersList) { 853 size = listenersList.size(); 854 } 855 for(int i = 0; i < size; i++) { 860 try { 861 DocumentNotificationListener dnl = (DocumentNotificationListener) listenersList.get(i); 862 dnl.lookInvalidated(node); 863 } catch(IndexOutOfBoundsException iob) { 864 } 866 } 867 868 } 869 870 875 public void positionInParentInvalidated(NodeImpl node) { 876 ArrayList listenersList = this.documentNotificationListeners; 877 int size; 878 synchronized(listenersList) { 879 size = listenersList.size(); 880 } 881 for(int i = 0; i < size; i++) { 886 try { 887 DocumentNotificationListener dnl = (DocumentNotificationListener) listenersList.get(i); 888 dnl.positionInvalidated(node); 889 } catch(IndexOutOfBoundsException iob) { 890 } 892 } 893 } 894 895 901 public void invalidated(NodeImpl node) { 902 ArrayList listenersList = this.documentNotificationListeners; 903 int size; 904 synchronized(listenersList) { 905 size = listenersList.size(); 906 } 907 for(int i = 0; i < size; i++) { 912 try { 913 DocumentNotificationListener dnl = (DocumentNotificationListener) listenersList.get(i); 914 dnl.invalidated(node); 915 } catch(IndexOutOfBoundsException iob) { 916 } 918 } 919 } 920 921 public void nodeLoaded(NodeImpl node) { 922 ArrayList listenersList = this.documentNotificationListeners; 923 int size; 924 synchronized(listenersList) { 925 size = listenersList.size(); 926 } 927 for(int i = 0; i < size; i++) { 932 try { 933 DocumentNotificationListener dnl = (DocumentNotificationListener) listenersList.get(i); 934 dnl.nodeLoaded(node); 935 } catch(IndexOutOfBoundsException iob) { 936 } 938 } 939 } 940 941 public void externalScriptLoading(NodeImpl node) { 942 ArrayList listenersList = this.documentNotificationListeners; 943 int size; 944 synchronized(listenersList) { 945 size = listenersList.size(); 946 } 947 for(int i = 0; i < size; i++) { 952 try { 953 DocumentNotificationListener dnl = (DocumentNotificationListener) listenersList.get(i); 954 dnl.externalScriptLoading(node); 955 } catch(IndexOutOfBoundsException iob) { 956 } 958 } 959 } 960 961 public void allInvalidated() { 962 ArrayList listenersList = this.documentNotificationListeners; 963 int size; 964 synchronized(listenersList) { 965 size = listenersList.size(); 966 } 967 for(int i = 0; i < size; i++) { 972 try { 973 DocumentNotificationListener dnl = (DocumentNotificationListener) listenersList.get(i); 974 dnl.allInvalidated(); 975 } catch(IndexOutOfBoundsException iob) { 976 } 978 } 979 } 980 981 protected RenderState createRenderState(RenderState prevRenderState) { 982 return new StyleSheetRenderState(null, null); 983 } 984 985 private final Map imageInfos = new HashMap(4); 986 private final ImageEvent BLANK_IMAGE_EVENT = new ImageEvent(this, null); 987 988 994 void loadImage(String relativeUri, ImageListener imageListener) { 995 HtmlRendererContext rcontext = this.getHtmlRendererContext(); 996 if(rcontext == null) { 997 imageListener.imageLoaded(BLANK_IMAGE_EVENT); 999 return; 1000 } 1001 final URL url = this.getFullURL(relativeUri); 1002 if(url == null) { 1003 imageListener.imageLoaded(BLANK_IMAGE_EVENT); 1004 return; 1005 } 1006 final String urlText = url.toExternalForm(); 1007 final Map map = this.imageInfos; 1008 ImageEvent event = null; 1009 synchronized(map) { 1010 ImageInfo info = (ImageInfo) map.get(urlText); 1011 if(info != null) { 1012 if(info.loaded) { 1013 event = info.imageEvent; 1016 } 1017 else { 1018 info.addListener(imageListener); 1019 } 1020 } 1021 else { 1022 UserAgentContext uac = rcontext.getUserAgentContext(); 1023 final HttpRequest httpRequest = uac.createHttpRequest(); 1024 final ImageInfo newInfo = new ImageInfo(); 1025 map.put(urlText, newInfo); 1026 newInfo.addListener(imageListener); 1027 httpRequest.addReadyStateChangeListener(new ReadyStateChangeListener() { 1028 public void readyStateChanged() { 1029 if(httpRequest.getReadyState() == HttpRequest.STATE_COMPLETE) { 1030 ImageEvent newEvent = new ImageEvent(HTMLDocumentImpl.this, httpRequest.getResponseImage()); 1031 ImageListener[] listeners; 1032 synchronized(map) { 1033 newInfo.imageEvent = newEvent; 1034 newInfo.loaded = true; 1035 listeners = newInfo.getListeners(); 1036 map.remove(urlText); 1040 } 1041 int llength = listeners.length; 1042 for(int i = 0; i < llength; i++) { 1043 listeners[i].imageLoaded(newEvent); 1045 } 1046 } 1047 } 1048 }); 1049 SecurityManager sm = System.getSecurityManager(); 1050 if(sm == null) { 1051 httpRequest.open("GET", url, true); 1052 } 1053 else { 1054 AccessController.doPrivileged(new PrivilegedAction() { 1055 public Object run() { 1056 httpRequest.open("GET", url, true); 1059 return null; 1060 } 1061 }); 1062 } 1063 } 1064 } 1065 if(event != null) { 1066 imageListener.imageLoaded(event); 1068 } 1069 } 1070 1071 private Function onloadHandler; 1072 1073 public Function getOnloadHandler() { 1074 return onloadHandler; 1075 } 1076 1077 public void setOnloadHandler(Function onloadHandler) { 1078 this.onloadHandler = onloadHandler; 1079 } 1080 1081 public Object setUserData(String key, Object data, UserDataHandler handler) { 1082 Function onloadHandler = this.onloadHandler; 1083 if(onloadHandler != null) { 1084 if(org.lobobrowser.html.parser.HtmlParser.MODIFYING_KEY.equals(key) && data == Boolean.FALSE) { 1085 Executor.executeFunction(this, onloadHandler, null); 1087 } 1088 } 1089 return super.setUserData(key, data, handler); 1090 } 1091 1092 protected Node createSimilarNode() { 1093 return new HTMLDocumentImpl(this.ucontext, this.rcontext, this.reader, this.documentURI); 1094 } 1095 1096 private static class ImageInfo { 1097 public ImageEvent imageEvent; 1099 public boolean loaded; 1100 private ArrayList listeners = new ArrayList(1); 1101 1102 void addListener(ImageListener listener) { 1103 this.listeners.add(listener); 1104 } 1105 1106 ImageListener[] getListeners() { 1107 return (ImageListener[]) this.listeners.toArray(ImageListener.EMPTY_ARRAY); 1108 } 1109 } 1110 1111 private class ImageFilter implements NodeFilter { 1112 public boolean accept(Node node) { 1113 return "IMG".equalsIgnoreCase(node.getNodeName()); 1114 } 1115 } 1116 1117 private class AppletFilter implements NodeFilter { 1118 public boolean accept(Node node) { 1119 return "APPLET".equalsIgnoreCase(node.getNodeName()); 1121 } 1122 } 1123 1124 private class LinkFilter implements NodeFilter { 1125 public boolean accept(Node node) { 1126 String nodeName = node.getNodeName(); 1127 return "LINK".equalsIgnoreCase(nodeName); 1128 } 1129 } 1130 1131 private class AnchorFilter implements NodeFilter { 1132 public boolean accept(Node node) { 1133 String nodeName = node.getNodeName(); 1134 return "A".equalsIgnoreCase(nodeName) || "ANCHOR".equalsIgnoreCase(nodeName); 1135 } 1136 } 1137 1138 private class FormFilter implements NodeFilter { 1139 public boolean accept(Node node) { 1140 String nodeName = node.getNodeName(); 1141 return "FORM".equalsIgnoreCase(nodeName); 1142 } 1143 } 1144 1145 private class FrameFilter implements NodeFilter { 1146 public boolean accept(Node node) { 1147 return node instanceof org.w3c.dom.html2.HTMLFrameElement || 1148 node instanceof org.w3c.dom.html2.HTMLIFrameElement; 1149 } 1150 } 1151 1152 1158 private class ElementNameFilter implements NodeFilter { 1159 private final String name; 1160 1161 public ElementNameFilter(String name) { 1162 this.name = name; 1163 } 1164 1165 public boolean accept(Node node) { 1166 return (node instanceof Element) && 1168 this.name.equals(((Element) node).getAttribute("name")); 1169 } 1170 } 1171 1172 private class ElementFilter implements NodeFilter { 1173 public ElementFilter() { 1174 } 1175 1176 public boolean accept(Node node) { 1177 return node instanceof Element; 1178 } 1179 } 1180 1181 private class TagNameFilter implements NodeFilter { 1182 private final String name; 1183 1184 public TagNameFilter(String name) { 1185 this.name = name; 1186 } 1187 1188 public boolean accept(Node node) { 1189 if(!(node instanceof Element)) { 1190 return false; 1191 } 1192 String n = this.name; 1193 return n.equalsIgnoreCase(((Element) node).getTagName()); 1194 } 1195 } 1196 1197 1202 private class LocalWritableLineReader extends WritableLineReader { 1203 1206 public LocalWritableLineReader(LineNumberReader reader) { 1207 super(reader); 1208 } 1209 1210 1213 public LocalWritableLineReader(Reader reader) { 1214 super(reader); 1215 } 1216 1217 public void write(String text) throws IOException { 1218 super.write(text); 1219 if("".equals(text)) { 1220 openBufferChanged(text); 1221 } 1222 } 1223 } 1224} 1225 | Popular Tags |