/** * Loads the content of the contained frames. This is done after the page is completely loaded, to allow script * contained in the frames to reference elements from the page located after the closing </frame> tag. * @throws FailingHttpStatusCodeException if the server returns a failing status code AND the property * {@link WebClient#setThrowExceptionOnFailingStatusCode(boolean)} is set to {@code true} */ void loadFrames() throws FailingHttpStatusCodeException { for (final FrameWindow w : getFrames()) { final BaseFrameElement frame = w.getFrameElement(); // test if the frame should really be loaded: // if a script has already changed its content, it should be skipped // use == and not equals(...) to identify initial content (versus URL set to "about:blank") if (frame.getEnclosedWindow() != null && WebClient.URL_ABOUT_BLANK == frame.getEnclosedPage().getUrl() && !frame.isContentLoaded()) { frame.loadInnerPage(); } } }
@Override public void execute() throws Exception { if (!src.isEmpty() && getSrcAttribute().equals(src)) { loadInnerPage(); } }
/** * Returns the value of the attribute {@code name}. Refer to the * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a> * documentation for details on the use of this attribute. * * @return the value of the attribute {@code name} or an empty string if that attribute isn't defined */ public final String getNameAttribute() { return getAttributeDirect("name"); }
private void loadSrc() { loadSrcWhenAddedToPage_ = false; final String src = getSrcAttribute(); final AbstractJavaScriptEngine<?> jsEngine = getPage().getWebClient().getJavaScriptEngine(); // When src is set from a script, loading is postponed until script finishes // in fact this implementation is probably wrong: JavaScript URL should be // first evaluated and only loading, when any, should be postponed. if (!jsEngine.isScriptRunning() || src.startsWith(JavaScriptURLConnection.JAVASCRIPT_PREFIX)) { loadInnerPageIfPossible(src); } else { final Page pageInFrame = getEnclosedPage(); final PostponedAction action = new PostponedAction(getPage()) { @Override public void execute() throws Exception { if (!src.isEmpty() && getSrcAttribute().equals(src)) { loadInnerPage(); } } @Override public boolean isStillAlive() { // skip if page in frame has already been changed return super.isStillAlive() && pageInFrame == getEnclosedPage(); } }; jsEngine.addPostponedAction(action); } }
if (frame.getEnclosedPage() .getWebResponse() .getWebRequest() .getUrl() == WebClient.URL_ABOUT_BLANK) { String src = frame.getSrcAttribute(); if (src != null && !src.isEmpty()) { final URL url; try { url = ((HtmlPage) frame.getEnclosedPage()).getFullyQualifiedUrl(src); } catch (final MalformedURLException e) { String message = "Invalid src attribute of " + frame.getTagName() + ": url=[" + src + "]. Ignored."; final IncorrectnessListener incorrectnessListener = webClient.getIncorrectnessListener(); if (isAlreadyLoadedByAncestor(url, ((HtmlPage) frame.getEnclosedPage()))) { String message = "Recursive src attribute of " + frame.getTagName() + ": url=[" + src + "]. Ignored."; final IncorrectnessListener incorrectnessListener = webClient.getIncorrectnessListener(); incorrectnessListener.notify(message, this); log.info("Frame already loaded: " + frame.toString()); return; log.info("Frame loaded: " + frame.toString()); log.error("Error when getting content for " + frame.getTagName() + " with src=" + url, e);
/** * Returns a list containing all the frames (from frame and iframe tags) in this page. * @return a list of {@link FrameWindow} */ public List<FrameWindow> getFrames() { final List<FrameWindow> list = new ArrayList<>(frameElements_.size()); for (final BaseFrameElement frameElement : frameElements_) { list.add(frameElement.getEnclosedWindow()); } return list; }
/** * @throws FailingHttpStatusCodeException if the server returns a failing status code AND the property * {@link WebClient#setThrowExceptionOnFailingStatusCode(boolean)} is set to true */ private void loadInnerPageIfPossible(final String src) throws FailingHttpStatusCodeException { setContentLoaded(); if (!src.isEmpty()) { final URL url; try { url = ((HtmlPage) getPage()).getFullyQualifiedUrl(src); } catch (final MalformedURLException e) { notifyIncorrectness("Invalid src attribute of " + getTagName() + ": url=[" + src + "]. Ignored."); return; } if (isAlreadyLoadedByAncestor(url)) { notifyIncorrectness("Recursive src attribute of " + getTagName() + ": url=[" + src + "]. Ignored."); return; } try { final WebRequest request = new WebRequest(url); request.setCharset(getPage().getCharset()); request.setAdditionalHeader(HttpHeader.REFERER, getPage().getUrl().toExternalForm()); getPage().getEnclosingWindow().getWebClient().getPage(enclosedWindow_, request); } catch (final IOException e) { LOG.error("IOException when getting content for " + getTagName() + ": url=[" + url + "]", e); } } }
@Override protected Object getWithPreemption(final String name) { final List<DomNode> elements = getElements(); for (final Object next : elements) { final BaseFrameElement frameElt = (BaseFrameElement) next; final WebWindow window = frameElt.getEnclosedWindow(); if (name.equals(window.getName())) { if (LOG.isDebugEnabled()) { LOG.debug("Property \"" + name + "\" evaluated (by name) to " + window); } return getScriptableForElement(window); } if (getBrowserVersion().hasFeature(JS_WINDOW_FRAMES_ACCESSIBLE_BY_ID) && frameElt.getId().equals(name)) { if (LOG.isDebugEnabled()) { LOG.debug("Property \"" + name + "\" evaluated (by id) to " + window); } return getScriptableForElement(window); } } return NOT_FOUND; }
if (Event.TYPE_LOAD.equals(eventType) && frame.getParentNode() instanceof DomDocumentFragment) { return true; if (frame.hasEventHandlers("on" + eventType)) { if (LOG.isDebugEnabled()) { LOG.debug("Executing on" + eventType + " handler for " + frame); final ScriptResult result = frame.fireEvent(event); if (!isOnbeforeunloadAccepted((HtmlPage) frame.getPage(), event, result)) { return false;
@Override public boolean isStillAlive() { // skip if page in frame has already been changed return super.isStillAlive() && pageInFrame == getEnclosedPage(); } };
/** * Creates an instance of BaseFrame. * * @param qualifiedName the qualified name of the element type to instantiate * @param page the HtmlPage that contains this element * @param attributes the initial attributes */ protected BaseFrameElement(final String qualifiedName, final SgmlPage page, final Map<String, DomAttr> attributes) { super(qualifiedName, page, attributes); init(); if (null != page && page.isHtmlPage() && ((HtmlPage) page).isParsingHtmlSnippet()) { // if created by the HTMLParser the src attribute is not set via setAttribute() or some other method but is // part of the given attributes already. final String src = getSrcAttribute(); if (src != ATTRIBUTE_NOT_DEFINED && !WebClient.ABOUT_BLANK.equals(src)) { loadSrcWhenAddedToPage_ = true; } } }
/** * Returns the value of URL loaded in the frame. * @return the value of this attribute */ @JsxGetter public String getSrc() { return getFrame().getSrcAttribute(); }
/** * Returns the HTML page in which the <frame> or <iframe> tag is contained * for this frame window. * This is a facility method for <code>(HtmlPage) (getParentWindow().getEnclosedPage())</code>. * @return the page in the parent window */ public HtmlPage getEnclosingPage() { return (HtmlPage) frame_.getPage(); }
/** * Sets the specified element as the document's active element. * @see HTMLElement#setActive() * @param element the new active element for this document */ public void setActiveElement(final HTMLElement element) { // TODO update page focus element also activeElement_ = element; if (element != null) { // if this is part of an iFrame, make the iFrame tag the // active element of his doc final WebWindow window = element.getDomNodeOrDie().getPage().getEnclosingWindow(); if (window instanceof FrameWindow) { final BaseFrameElement frame = ((FrameWindow) window).getFrameElement(); if (frame instanceof HtmlInlineFrame) { final Window winWithFrame = frame.getPage().getEnclosingWindow().getScriptableObject(); ((HTMLDocument) winWithFrame.getDocument()).setActiveElement( (HTMLElement) frame.getScriptableObject()); } } } }
/** * Return the given frame in the current conversation. * * @param frameNameOrId Frame name or ID. * @return The frame found or null. */ private WebWindow getFrame(String frameNameOrId) { // First try ID for (FrameWindow frame : getCurrentPage().getFrames()) { if (frameNameOrId.equals(frame.getFrameElement().getId())) { return frame; } } // Now try with Name for (FrameWindow frame : getCurrentPage().getFrames()) { if (frameNameOrId.equals(frame.getName())) { return frame; } } // Nothing was found. return null; }
/** * {@inheritDoc} * A FrameWindow shares it's name with it's containing frame. */ @Override public String getName() { return frame_.getNameAttribute(); }
private void init() { FrameWindow enclosedWindow = null; try { final HtmlPage htmlPage = getHtmlPageOrNull(); if (null != htmlPage) { // if loaded as part of XHR.responseXML, don't load content enclosedWindow = new FrameWindow(this); // put about:blank in the window to allow JS to run on this frame before the // real content is loaded final WebClient webClient = htmlPage.getWebClient(); final HtmlPage temporaryPage = webClient.getPage(enclosedWindow, new WebRequest(WebClient.URL_ABOUT_BLANK)); temporaryPage.setReadyState(READY_STATE_LOADING); } } catch (final FailingHttpStatusCodeException | IOException e) { // should never occur } enclosedWindow_ = enclosedWindow; }
private void loadSrc() { loadSrcWhenAddedToPage_ = false; final String src = getSrcAttribute(); final AbstractJavaScriptEngine<?> jsEngine = getPage().getWebClient().getJavaScriptEngine(); // When src is set from a script, loading is postponed until script finishes // in fact this implementation is probably wrong: JavaScript URL should be // first evaluated and only loading, when any, should be postponed. if (!jsEngine.isScriptRunning() || src.startsWith(JavaScriptURLConnection.JAVASCRIPT_PREFIX)) { loadInnerPageIfPossible(src); } else { final Page pageInFrame = getEnclosedPage(); final PostponedAction action = new PostponedAction(getPage()) { @Override public void execute() throws Exception { if (!src.isEmpty() && getSrcAttribute().equals(src)) { loadInnerPage(); } } @Override public boolean isStillAlive() { // skip if page in frame has already been changed return super.isStillAlive() && pageInFrame == getEnclosedPage(); } }; jsEngine.addPostponedAction(action); } }
/** * Returns a list containing all the frames (from frame and iframe tags) in this page. * @return a list of {@link FrameWindow} */ public List<FrameWindow> getFrames() { final List<FrameWindow> list = new ArrayList<>(frameElements_.size()); for (final BaseFrameElement frameElement : frameElements_) { list.add(frameElement.getEnclosedWindow()); } return list; }
setContentLoaded(); if (!src.isEmpty()) { final URL url; try { url = ((HtmlPage) getPage()).getFullyQualifiedUrl(src); notifyIncorrectness("Invalid src attribute of " + getTagName() + ": url=[" + src + "]. Ignored."); return; if (isAlreadyLoadedByAncestor(url)) { notifyIncorrectness("Recursive src attribute of " + getTagName() + ": url=[" + src + "]. Ignored."); return; request.setCharset(getPage().getCharset()); request.setAdditionalHeader(HttpHeader.REFERER, getPage().getUrl().toExternalForm()); getPage().getEnclosingWindow().getWebClient().getPage(enclosedWindow_, request); LOG.error("IOException when getting content for " + getTagName() + ": url=[" + url + "]", e);