use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.
the class BaseFrameElement method loadSrc.
private void loadSrc() {
loadSrcWhenAddedToPage_ = false;
final String src = getSrcAttribute();
// recreate a window if the old one was closed
if (enclosedWindow_.isClosed()) {
init();
}
final AbstractJavaScriptEngine<?> jsEngine = getPage().getWebClient().getJavaScriptEngine();
// first evaluated and only loading, when any, should be postponed.
if (jsEngine == null || !jsEngine.isScriptRunning() || src.startsWith(JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
loadInnerPageIfPossible(src);
} else {
final Page pageInFrame = getEnclosedPage();
final PostponedAction action = new PostponedAction(getPage(), "BaseFrame.loadSrc") {
@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);
}
}
use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.
the class BaseFrameElement method loadInnerPage.
/**
* <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
*
* Called after the node for the {@code frame} or {@code iframe} has been added to the containing page.
* The node needs to be added first to allow JavaScript in the frame to see the frame in the parent.
* @throws FailingHttpStatusCodeException if the server returns a failing status code AND the property
* {@link com.gargoylesoftware.htmlunit.WebClientOptions#setThrowExceptionOnFailingStatusCode(boolean)} is
* set to true
*/
public void loadInnerPage() throws FailingHttpStatusCodeException {
String source = getSrcAttribute();
if (source.isEmpty()) {
source = UrlUtils.ABOUT_BLANK;
} else if (StringUtils.startsWithIgnoreCase(source, UrlUtils.ABOUT_SCHEME) && hasFeature(FRAME_LOCATION_ABOUT_BLANK_FOR_ABOUT_SCHEME)) {
source = UrlUtils.ABOUT_BLANK;
}
loadInnerPageIfPossible(source);
final Page enclosedPage = getEnclosedPage();
if (enclosedPage != null && enclosedPage.isHtmlPage()) {
final HtmlPage htmlPage = (HtmlPage) enclosedPage;
final AbstractJavaScriptEngine<?> jsEngine = htmlPage.getWebClient().getJavaScriptEngine();
if (jsEngine != null && jsEngine.isScriptRunning()) {
final PostponedAction action = new PostponedAction(getPage(), "BaseFrame.loadInnerPage") {
@Override
public void execute() throws Exception {
htmlPage.setReadyState(READY_STATE_COMPLETE);
}
};
jsEngine.addPostponedAction(action);
} else {
htmlPage.setReadyState(READY_STATE_COMPLETE);
}
}
}
use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.
the class BaseFrameElement method removeAttribute.
@Override
public final void removeAttribute(final String attributeName) {
super.removeAttribute(attributeName);
// TODO find a better implementation without all the code duplication
if (isAttachedToPage()) {
loadSrcWhenAddedToPage_ = false;
final String src = getSrcAttribute();
final AbstractJavaScriptEngine<?> jsEngine = getPage().getWebClient().getJavaScriptEngine();
// first evaluated and only loading, when any, should be postponed.
if (jsEngine == null || !jsEngine.isScriptRunning()) {
loadInnerPageIfPossible(src);
} else {
final Page pageInFrame = getEnclosedPage();
final PostponedAction action = new PostponedAction(getPage(), "BaseFrame.removeAttribute") {
@Override
public void execute() throws Exception {
loadInnerPage();
}
@Override
public boolean isStillAlive() {
// skip if page in frame has already been changed
return super.isStillAlive() && pageInFrame == getEnclosedPage();
}
};
jsEngine.addPostponedAction(action);
}
} else {
loadSrcWhenAddedToPage_ = true;
}
}
use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.
the class AudioContext method decodeAudioData.
/**
* The decodeAudioData() method of the BaseAudioContext Interface is used to asynchronously
* decode audio file data contained in an ArrayBuffer. In this case the ArrayBuffer is
* loaded from XMLHttpRequest and FileReader.
* The decoded AudioBuffer is resampled to the AudioContext's sampling rate,
* then passed to a callback or promise.
* @param buffer An ArrayBuffer containing the audio data to be decoded, usually grabbed
* from XMLHttpRequest, WindowOrWorkerGlobalScope.fetch() or FileReader
* @param success A callback function to be invoked when the decoding successfully finishes.
* The single argument to this callback is an AudioBuffer representing the decodedData
* (the decoded PCM audio data). Usually you'll want to put the decoded data into
* an AudioBufferSourceNode, from which it can be played and manipulated how you want.
* @param error An optional error callback, to be invoked if an error occurs
* when the audio data is being decoded.
* @return the promise or null
*/
@JsxFunction
public Object decodeAudioData(final NativeArrayBuffer buffer, final Function success, final Function error) {
final Window window = getWindow();
final HtmlPage owningPage = (HtmlPage) window.getDocument().getPage();
final JavaScriptEngine jsEngine = (JavaScriptEngine) window.getWebWindow().getWebClient().getJavaScriptEngine();
if (error != null) {
jsEngine.addPostponedAction(new PostponedAction(owningPage, "AudioContext.decodeAudioData") {
@Override
public void execute() throws Exception {
jsEngine.callFunction(owningPage, error, getParentScope(), AudioContext.this, new Object[] {});
}
});
return null;
}
final Scriptable scope = ScriptableObject.getTopLevelScope(this);
final LambdaConstructor ctor = (LambdaConstructor) getProperty(scope, "Promise");
final LambdaFunction reject = (LambdaFunction) getProperty(ctor, "reject");
return reject.call(Context.getCurrentContext(), this, ctor, new Object[] {});
}
use of com.gargoylesoftware.htmlunit.javascript.PostponedAction in project htmlunit by HtmlUnit.
the class HtmlScript method setAttributeNS.
/**
* If setting the <tt>src</tt> attribute, this method executes the new JavaScript if necessary
* (behavior varies by browser version). {@inheritDoc}
*/
@Override
protected void setAttributeNS(final String namespaceURI, final String qualifiedName, final String attributeValue, final boolean notifyAttributeChangeListeners, final boolean notifyMutationObservers) {
// special additional processing for the 'src'
if (namespaceURI != null || !SRC_ATTRIBUTE.equals(qualifiedName)) {
super.setAttributeNS(namespaceURI, qualifiedName, attributeValue, notifyAttributeChangeListeners, notifyMutationObservers);
return;
}
// namespaceURI is always null here - we can call getAttribute directly
final String oldValue = getAttribute(qualifiedName);
super.setAttributeNS(null, qualifiedName, attributeValue, notifyAttributeChangeListeners, notifyMutationObservers);
if (isAttachedToPage() && oldValue.isEmpty() && getFirstChild() == null) {
final PostponedAction action = new PostponedAction(getPage(), "HtmlScript.setAttributeNS") {
@Override
public void execute() {
ScriptElementSupport.executeScriptIfNeeded(HtmlScript.this, false, false);
}
};
final AbstractJavaScriptEngine<?> engine = getPage().getWebClient().getJavaScriptEngine();
engine.addPostponedAction(action);
}
}
Aggregations