use of com.gargoylesoftware.htmlunit.javascript.host.dom.Document in project htmlunit by HtmlUnit.
the class HtmlElement method getDoTypeNode.
/**
* Returns the node to type into.
* @return the node
*/
private DomText getDoTypeNode() {
final HTMLElement scriptElement = getScriptableObject();
if (scriptElement.isIsContentEditable() || "on".equals(((Document) scriptElement.getOwnerDocument()).getDesignMode())) {
DomNodeList<DomNode> children = getChildNodes();
while (!children.isEmpty()) {
final DomNode lastChild = children.get(children.size() - 1);
if (lastChild instanceof DomText) {
return (DomText) lastChild;
}
children = lastChild.getChildNodes();
}
final DomText domText = new DomText(getPage(), "");
appendChild(domText);
return domText;
}
return null;
}
use of com.gargoylesoftware.htmlunit.javascript.host.dom.Document in project htmlunit by HtmlUnit.
the class XMLSerializer method serializeToString.
/**
* The subtree rooted by the specified element is serialized to a string.
* @param root the root of the subtree to be serialized (this may be any node, even a document)
* @return the serialized string
*/
@JsxFunction
public String serializeToString(Node root) {
if (root == null) {
return "";
}
if (root instanceof DocumentFragment) {
if (root.getOwnerDocument() instanceof HTMLDocument && getBrowserVersion().hasFeature(JS_XML_SERIALIZER_HTML_DOCUMENT_FRAGMENT_ALWAYS_EMPTY)) {
return "";
}
Node node = root.getFirstChild();
if (node == null) {
return "";
}
final StringBuilder builder = new StringBuilder();
while (node != null) {
builder.append(serializeToString(node));
node = node.getNextSibling();
}
return builder.toString();
}
if (root instanceof Document) {
root = ((Document) root).getDocumentElement();
}
if (root instanceof Element) {
final StringBuilder builder = new StringBuilder();
final DomNode node = root.getDomNodeOrDie();
final SgmlPage page = node.getPage();
final boolean isHtmlPage = page != null && page.isHtmlPage();
String forcedNamespace = null;
if (isHtmlPage) {
forcedNamespace = "http://www.w3.org/1999/xhtml";
}
toXml(1, node, builder, forcedNamespace);
return builder.toString();
}
if (root instanceof CDATASection && getBrowserVersion().hasFeature(JS_XML_SERIALIZER_ROOT_CDATA_AS_ESCAPED_TEXT)) {
final DomCDataSection domCData = (DomCDataSection) root.getDomNodeOrDie();
final String data = domCData.getData();
if (org.apache.commons.lang3.StringUtils.isNotBlank(data)) {
return StringUtils.escapeXmlChars(data);
}
}
return root.getDomNodeOrDie().asXml();
}
use of com.gargoylesoftware.htmlunit.javascript.host.dom.Document in project htmlunit by HtmlUnit.
the class ScriptElementSupport method executeScriptIfNeeded.
/**
* <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
*
* Executes this script node if necessary and/or possible.
* @param element the element
* @param ignoreAttachedToPage don't do the isAttachedToPage check
* @param ignorePageIsAncestor don't do the element.getPage().isAncestorOf(element) check
*/
public static void executeScriptIfNeeded(final DomElement element, final boolean ignoreAttachedToPage, final boolean ignorePageIsAncestor) {
if (!isExecutionNeeded(element, ignoreAttachedToPage, ignorePageIsAncestor)) {
return;
}
final ScriptElement scriptElement = (ScriptElement) element;
final String src = scriptElement.getSrcAttribute();
if (src.equals(SLASH_SLASH_COLON)) {
executeEvent(element, Event.TYPE_ERROR);
return;
}
final HtmlPage page = (HtmlPage) element.getPage();
if (src != ATTRIBUTE_NOT_DEFINED) {
if (!src.startsWith(JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
// <script src="[url]"></script>
if (LOG.isDebugEnabled()) {
LOG.debug("Loading external JavaScript: " + src);
}
try {
scriptElement.setExecuted(true);
Charset charset = EncodingSniffer.toCharset(scriptElement.getCharsetAttribute());
if (charset == null) {
charset = page.getCharset();
}
final JavaScriptLoadResult result;
final Window win = page.getEnclosingWindow().getScriptableObject();
final Document doc = win.getDocument();
try {
doc.setCurrentScript(element.getScriptableObject());
result = page.loadExternalJavaScriptFile(src, charset);
} finally {
doc.setCurrentScript(null);
}
if (result == JavaScriptLoadResult.SUCCESS) {
executeEvent(element, Event.TYPE_LOAD);
} else if (result == JavaScriptLoadResult.DOWNLOAD_ERROR) {
executeEvent(element, Event.TYPE_ERROR);
} else if (result == JavaScriptLoadResult.NO_CONTENT) {
final BrowserVersion browserVersion = page.getWebClient().getBrowserVersion();
if (browserVersion.hasFeature(JS_SCRIPT_HANDLE_204_AS_ERROR)) {
executeEvent(element, Event.TYPE_ERROR);
} else {
executeEvent(element, Event.TYPE_LOAD);
}
}
} catch (final FailingHttpStatusCodeException e) {
executeEvent(element, Event.TYPE_ERROR);
throw e;
}
}
} else if (element.getFirstChild() != null) {
// <script>[code]</script>
final Window win = page.getEnclosingWindow().getScriptableObject();
final Document doc = win.getDocument();
try {
doc.setCurrentScript(element.getScriptableObject());
executeInlineScriptIfNeeded(element);
} finally {
doc.setCurrentScript(null);
}
if (element.hasFeature(EVENT_ONLOAD_INTERNAL_JAVASCRIPT)) {
executeEvent(element, Event.TYPE_LOAD);
}
}
}
use of com.gargoylesoftware.htmlunit.javascript.host.dom.Document in project htmlunit by HtmlUnit.
the class EventTarget method fireEvent.
/**
* Fires the event on the node with capturing and bubbling phase.
* @param event the event
* @return the result
*/
public ScriptResult fireEvent(final Event event) {
final Window window = getWindow();
event.startFire();
final Event previousEvent = window.getCurrentEvent();
window.setCurrentEvent(event);
try {
// These can be null if we aren't tied to a DOM node
final DomNode ourNode = getDomNodeOrNull();
final DomNode ourParentNode = (ourNode != null) ? ourNode.getParentNode() : null;
// Determine the propagation path which is fixed here and not affected by
// DOM tree modification from intermediate listeners (tested in Chrome)
final List<EventTarget> propagationPath = new ArrayList<>();
// We're added to the propagation path first
propagationPath.add(this);
// and MessagePort, etc. will not have any parents)
for (DomNode parent = ourParentNode; parent != null; parent = parent.getParentNode()) {
propagationPath.add(parent.getScriptableObject());
}
// (see Note in https://www.w3.org/TR/DOM-Level-3-Events/#event-type-load)
if (!Event.TYPE_LOAD.equals(event.getType())) {
// Add Window if the the propagation path reached Document
if (propagationPath.get(propagationPath.size() - 1) instanceof Document) {
propagationPath.add(window);
}
}
// capturing phase
event.setEventPhase(Event.CAPTURING_PHASE);
for (int i = propagationPath.size() - 1; i >= 1; i--) {
final EventTarget jsNode = propagationPath.get(i);
final EventListenersContainer elc = jsNode.eventListenersContainer_;
if (elc != null) {
elc.executeCapturingListeners(event, new Object[] { event });
if (event.isPropagationStopped()) {
return new ScriptResult(null);
}
}
}
// at target phase
event.setEventPhase(Event.AT_TARGET);
if (!propagationPath.isEmpty()) {
// Note: This element is not always the same as event.getTarget():
// e.g. the 'load' event targets Document but "at target" is on Window.
final EventTarget jsNode = propagationPath.get(0);
final EventListenersContainer elc = jsNode.eventListenersContainer_;
if (elc != null) {
elc.executeAtTargetListeners(event, new Object[] { event });
if (event.isPropagationStopped()) {
return new ScriptResult(null);
}
}
}
// bubbling phase
if (event.isBubbles()) {
// This belongs here inside the block because events that don't bubble never set
// eventPhase = 3 (tested in Chrome)
event.setEventPhase(Event.BUBBLING_PHASE);
for (int i = 1, size = propagationPath.size(); i < size; i++) {
final EventTarget jsNode = propagationPath.get(i);
final EventListenersContainer elc = jsNode.eventListenersContainer_;
if (elc != null) {
elc.executeBubblingListeners(event, new Object[] { event });
if (event.isPropagationStopped()) {
return new ScriptResult(null);
}
}
}
}
HtmlLabel label = null;
if (event.processLabelAfterBubbling()) {
for (DomNode parent = ourParentNode; parent != null; parent = parent.getParentNode()) {
if (parent instanceof HtmlLabel) {
label = (HtmlLabel) parent;
break;
}
}
}
if (label != null) {
final HtmlElement element = label.getLabeledElement();
if (element != null && element != getDomNodeOrNull()) {
try {
element.click(event.isShiftKey(), event.isCtrlKey(), event.isAltKey(), false, true, true, true);
} catch (final IOException e) {
// ignore for now
}
}
}
} finally {
event.endFire();
// reset event
window.setCurrentEvent(previousEvent);
}
return new ScriptResult(null);
}
Aggregations