From: <rb...@us...> - 2013-12-12 18:52:09
|
Revision: 8836 http://sourceforge.net/p/htmlunit/code/8836 Author: rbri Date: 2013-12-12 18:52:03 +0000 (Thu, 12 Dec 2013) Log Message: ----------- first huge implementation step forward to support IE11 [Frank Danek] this introduces a completely separate implementation of the MSXMLActiveXObject (IE11 supports this AND a build in one) Modified Paths: -------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObject.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Attr.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Document.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/DocumentType.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Event.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/KeyboardEvent.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessageEvent.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MouseEvent.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Navigator.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Node.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Selection.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Text.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/UIEvent.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfigurationTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObjectTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/ObjectsTest.java Added Paths: ----------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentFragment.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentType.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMElement.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMImplementation.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNamedNodeMap.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNode.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNodeList.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMParseError.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMProcessingInstruction.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMSelection.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMText.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLHTTPRequest.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLSerializer.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLProcessor.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLTemplate.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/package.html trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/AbstractJavaScriptConfiguration.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/activex/javascript/ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/ Index: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml 2013-12-12 18:41:07 UTC (rev 8835) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml 2013-12-12 18:52:03 UTC (rev 8836) Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml ___________________________________________________________________ Added: bugtraq:label ## -0,0 +1 ## +SF issue number (optional): \ No newline at end of property Added: bugtraq:url ## -0,0 +1 ## +http://sourceforge.net/support/tracker.php?aid=%BUGID% \ No newline at end of property Added: bugtraq:message ## -0,0 +1 ## +Issue %BUGID% \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import java.util.Locale; + +import net.sourceforge.htmlunit.corejs.javascript.Scriptable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.ScriptException; +import com.gargoylesoftware.htmlunit.WebWindow; + +/** + * ActiveXObjectFactory for the MSXML ActiveX library. + * + * @version $Revision$ + * @author Frank Danek + */ +public class MSXMLActiveXObjectFactory { + + private static final Log LOG = LogFactory.getLog(MSXMLActiveXObjectFactory.class); + + private MSXMLJavaScriptEnvironment environment_; + + /** + * Initializes the factory. + * + * @param browserVersion the browser version to use + * @throws Exception if something goes wrong + */ + public void init(final BrowserVersion browserVersion) throws Exception { + environment_ = new MSXMLJavaScriptEnvironment(browserVersion); + } + + /** + * Checks if the given ActiveX name is supported by this factory. + * + * @param activeXName the ActiveX name to check + * @return true if the given name is supported + */ + public boolean supports(final String activeXName) { + return isXMLDOMDocument(activeXName) + || isXMLHTTPRequest(activeXName) + || isXSLTemplate(activeXName); + } + + /** + * Indicates whether the ActiveX name is one flavor of XMLDOMDocument. + * @param name the ActiveX name + * @return <code>true</code> if this is an XMLDOMDocument + */ + static boolean isXMLDOMDocument(String name) { + if (name == null) { + return false; + } + name = name.toLowerCase(Locale.ENGLISH); + return "microsoft.xmldom".equals(name) + || name.startsWith("msxml2.domdocument") + || name.startsWith("msxml2.freethreadeddomdocument"); + } + + /** + * Indicates whether the ActiveX name is one flavor of XMLHTTPRequest. + * @param name the ActiveX name + * @return <code>true</code> if this is an XMLHTTPRequest + */ + static boolean isXMLHTTPRequest(String name) { + if (name == null) { + return false; + } + name = name.toLowerCase(Locale.ENGLISH); + return "microsoft.xmlhttp".equals(name) + || name.startsWith("msxml2.xmlhttp"); + } + + /** + * Indicates if the ActiveX name is one flavor of XSLTemplate. + * @param name the ActiveX name + * @return <code>true</code> if this is an XSLTemplate + */ + static boolean isXSLTemplate(String name) { + if (name == null) { + return false; + } + name = name.toLowerCase(Locale.ENGLISH); + return name.startsWith("msxml2.xsltemplate"); + } + + /** + * Creates an instance of the ActiveX object for the given name. + * + * @param activeXName the ActiveX name to create an object for + * @param enclosingWindow the enclosing window + * @return the created ActiveX object + */ + public Scriptable create(final String activeXName, final WebWindow enclosingWindow) { + if (isXMLDOMDocument(activeXName)) { + return createXMLDOMDocument(enclosingWindow); + } + + if (isXMLHTTPRequest(activeXName)) { + return createXMLHTTPRequest(enclosingWindow); + } + + if (isXSLTemplate(activeXName)) { + return createXSLTemplate(enclosingWindow); + } + return null; + } + + private XMLDOMDocument createXMLDOMDocument(final WebWindow enclosingWindow) { + final XMLDOMDocument document = new XMLDOMDocument(enclosingWindow); + initObject(document); + + try { + document.setParentScope((Scriptable) enclosingWindow.getScriptObject()); + } + catch (final Exception e) { + LOG.error("Exception while initializing JavaScript for the page", e); + throw new ScriptException(null, e); // BUG: null is not useful. + } + return document; + } + + private Scriptable createXMLHTTPRequest(final WebWindow enclosingWindow) { + final XMLHTTPRequest request = new XMLHTTPRequest(); + initObject(request); + return request; + } + + private Scriptable createXSLTemplate(final WebWindow enclosingWindow) { + final XSLTemplate template = new XSLTemplate(); + initObject(template); + return template; + } + + private void initObject(final MSXMLScriptable scriptable) { + try { + scriptable.setPrototype(environment_.getPrototype(scriptable.getClass())); + scriptable.setEnvironment(environment_); + } + catch (final Exception e) { + LOG.error("Exception while initializing JavaScript for the page", e); + throw new ScriptException(null, e); // BUG: null is not useful. + } + } +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import java.util.Map; +import java.util.WeakHashMap; + +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.javascript.configuration.AbstractJavaScriptConfiguration; + +/** + * A container for all the JavaScript configuration information. + * + * @version $Revision$ + * @author <a href="mailto:mb...@Ga...">Mike Bowler</a> + * @author Chris Erskine + * @author Ahmed Ashour + * @author Ronald Brill + * @author Frank Danek + */ +public final class MSXMLConfiguration extends AbstractJavaScriptConfiguration { + + @SuppressWarnings("unchecked") + static final Class<MSXMLScriptable>[] CLASSES_ = new Class[] { + XMLDOMAttribute.class, XMLDOMCDATASection.class, XMLDOMCharacterData.class, XMLDOMComment.class, + XMLDOMDocument.class, XMLDOMDocumentFragment.class, XMLDOMDocumentType.class, XMLDOMElement.class, + XMLDOMImplementation.class, XMLDOMNamedNodeMap.class, XMLDOMNode.class, XMLDOMNodeList.class, + XMLDOMParseError.class, XMLDOMProcessingInstruction.class, XMLDOMSelection.class, XMLDOMText.class, + XMLHTTPRequest.class, XSLProcessor.class, XSLTemplate.class + }; + + /** Cache of browser versions and their corresponding JavaScript configurations. */ + private static final Map<BrowserVersion, MSXMLConfiguration> CONFIGURATION_MAP_ = + new WeakHashMap<BrowserVersion, MSXMLConfiguration>(); + + /** + * Constructor is only called from {@link #getInstance(BrowserVersion)} which is synchronized. + * @param browser the browser version to use + */ + private MSXMLConfiguration(final BrowserVersion browser) { + super(browser); + } + + /** + * Returns the instance that represents the configuration for the specified {@link BrowserVersion}. + * This method is synchronized to allow multi-threaded access to the JavaScript configuration. + * @param browserVersion the {@link BrowserVersion} + * @return the instance for the specified {@link BrowserVersion} + */ + public static synchronized MSXMLConfiguration getInstance(final BrowserVersion browserVersion) { + if (browserVersion == null) { + throw new IllegalStateException("BrowserVersion must be defined"); + } + MSXMLConfiguration configuration = CONFIGURATION_MAP_.get(browserVersion); + + if (configuration == null) { + configuration = new MSXMLConfiguration(browserVersion); + CONFIGURATION_MAP_.put(browserVersion, configuration); + } + return configuration; + } + + @Override + protected Class<MSXMLScriptable>[] getClasses() { + return CLASSES_; + } +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import net.sourceforge.htmlunit.corejs.javascript.Context; +import net.sourceforge.htmlunit.corejs.javascript.FunctionObject; +import net.sourceforge.htmlunit.corejs.javascript.Scriptable; +import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; + +import org.apache.commons.lang3.StringUtils; + +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.javascript.ScriptableWithFallbackGetter; +import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable; +import com.gargoylesoftware.htmlunit.javascript.configuration.ClassConfiguration; + +/** + * JavaScript environment for the MSXML ActiveX library. + * + * @version $Revision$ + * @author Frank Danek + */ +public class MSXMLJavaScriptEnvironment { + + private final MSXMLConfiguration config_; + + private Map<Class<? extends MSXMLScriptable>, Scriptable> prototypes_; + + /** + * Creates an instance for the given {@link BrowserVersion}. + * + * @param browserVersion the browser version to use + * @throws Exception if something goes wrong + */ + @SuppressWarnings("unchecked") + public MSXMLJavaScriptEnvironment(final BrowserVersion browserVersion) throws Exception { + config_ = MSXMLConfiguration.getInstance(browserVersion); + + final Map<String, ScriptableObject> prototypesPerJSName = new HashMap<String, ScriptableObject>(); + final Map<Class<? extends MSXMLScriptable>, Scriptable> prototypes = + new HashMap<Class<? extends MSXMLScriptable>, Scriptable>(); + + // put custom object to be called as very last prototype to call the fallback getter (if any) + final Scriptable fallbackCaller = new FallbackCaller(); + + for (final ClassConfiguration config : config_.getAll()) { + final ScriptableObject prototype = configureClass(config); + if (config.isJsObject()) { + prototypes.put((Class<? extends MSXMLScriptable>) config.getHostClass(), prototype); + } + prototypesPerJSName.put(config.getHostClass().getSimpleName(), prototype); + } + + // once all prototypes have been build, it's possible to configure the chains +// final Scriptable objectPrototype = ScriptableObject.getObjectPrototype(window); + for (final Map.Entry<String, ScriptableObject> entry : prototypesPerJSName.entrySet()) { + final String name = entry.getKey(); + final ClassConfiguration config = config_.getClassConfiguration(name); + Scriptable prototype = entry.getValue(); + if (prototype.getPrototype() != null) { + prototype = prototype.getPrototype(); // "double prototype" hack for FF + } + if (!StringUtils.isEmpty(config.getExtendedClassName())) { + final Scriptable parentPrototype = prototypesPerJSName.get(config.getExtendedClassName()); + prototype.setPrototype(parentPrototype); + } + else { +// prototype.setPrototype(objectPrototype); + prototype.setPrototype(fallbackCaller); + } + } + + prototypes_ = prototypes; + } + + /** + * Configures the specified class for access via JavaScript. + * @param config the configuration settings for the class to be configured + * @param window the scope within which to configure the class + * @throws InstantiationException if the new class cannot be instantiated + * @throws IllegalAccessException if we don't have access to create the new instance + * @return the created prototype + */ + private ScriptableObject configureClass(final ClassConfiguration config/*, final Scriptable window*/) + throws InstantiationException, IllegalAccessException { + + final Class<?> jsHostClass = config.getHostClass(); + final ScriptableObject prototype = (ScriptableObject) jsHostClass.newInstance(); +// prototype.setParentScope(window); + + configureConstantsPropertiesAndFunctions(config, prototype); + + return prototype; + } + + /** + * Configures constants, properties and functions on the object. + * @param config the configuration for the object + * @param scriptable the object to configure + */ + private void configureConstantsPropertiesAndFunctions(final ClassConfiguration config, + final ScriptableObject scriptable) { + + // the constants + configureConstants(config, scriptable); + + // the properties + for (final Entry<String, ClassConfiguration.PropertyInfo> propertyEntry : config.propertyEntries()) { + final String propertyName = propertyEntry.getKey(); + final Method readMethod = propertyEntry.getValue().getReadMethod(); + final Method writeMethod = propertyEntry.getValue().getWriteMethod(); + scriptable.defineProperty(propertyName, null, readMethod, writeMethod, ScriptableObject.EMPTY); + } + + final int attributes = ScriptableObject.DONTENUM; + // the functions + for (final Entry<String, Method> functionInfo : config.functionEntries()) { + final String functionName = functionInfo.getKey(); + final Method method = functionInfo.getValue(); + final FunctionObject functionObject = new FunctionObject(functionName, method, scriptable); + scriptable.defineProperty(functionName, functionObject, attributes); + } + } + + private void configureConstants(final ClassConfiguration config, + final ScriptableObject scriptable) { + final Class<?> linkedClass = config.getHostClass(); + for (final String constant : config.constants()) { + try { + final Object value = linkedClass.getField(constant).get(null); + scriptable.defineProperty(constant, value, ScriptableObject.EMPTY); + } + catch (final Exception e) { + throw Context.reportRuntimeError("Cannot get field '" + constant + "' for type: " + + config.getHostClass().getName()); + } + } + } + + /** + * Gets the class of the JavaScript object for the node class. + * @param c the node class <code>DomNode</code> or some subclass. + * @return <code>null</code> if none found + */ + @SuppressWarnings("unchecked") + public Class<? extends MSXMLScriptable> getJavaScriptClass(final Class<?> c) { + return (Class<? extends MSXMLScriptable>) config_.getDomJavaScriptMapping().get(c); + } + + /** + * Returns the prototype object corresponding to the specified HtmlUnit class inside the window scope. + * @param jsClass the class whose prototype is to be returned + * @return the prototype object corresponding to the specified class inside the specified scope + */ + public Scriptable getPrototype(final Class<? extends SimpleScriptable> jsClass) { + return prototypes_.get(jsClass); + } + + private static class FallbackCaller extends ScriptableObject { + private static final long serialVersionUID = 1402030469837200894L; + + @Override + public Object get(final String name, final Scriptable start) { + if (start instanceof ScriptableWithFallbackGetter) { + return ((ScriptableWithFallbackGetter) start).getWithFallback(name); + } + return NOT_FOUND; + } + + @Override + public String getClassName() { + return "htmlUnitHelper-fallbackCaller"; + } + } +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import net.sourceforge.htmlunit.corejs.javascript.Context; +import net.sourceforge.htmlunit.corejs.javascript.Scriptable; + +import com.gargoylesoftware.htmlunit.html.DomNode; +import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable; + +/** + * Base class for MSXML's (ActiveX) JavaScript host objects in HtmlUnit. + * + * @version $Revision$ + * @author Frank Danek + */ +public class MSXMLScriptable extends SimpleScriptable { + + private static final Log LOG = LogFactory.getLog(MSXMLScriptable.class); + + private MSXMLJavaScriptEnvironment environment_; + + /** + * {@inheritDoc} + */ + @Override + public void setParentScope(final Scriptable m) { + super.setParentScope(m); + + if (m instanceof MSXMLScriptable) { + setEnvironment(((MSXMLScriptable) m).getEnvironment()); + } + } + + /** + * Builds a new the JavaScript object that corresponds to the specified object. + * @param domNode the DOM node for which a JS object should be created + * @return the JavaScript object + */ + public SimpleScriptable makeScriptableFor(final DomNode domNode) { + // Get the JS class name for the specified DOM node. + // Walk up the inheritance chain if necessary. + Class<? extends MSXMLScriptable> javaScriptClass = null; + for (Class<?> c = domNode.getClass(); javaScriptClass == null && c != null; c = c.getSuperclass()) { + javaScriptClass = getEnvironment().getJavaScriptClass(c); + } + + final MSXMLScriptable scriptable; + if (javaScriptClass == null) { + // We don't have a specific subclass for this element so create something generic. + scriptable = new XMLDOMElement(); + if (LOG.isDebugEnabled()) { + LOG.debug("No MSXML JavaScript class found for element <" + domNode.getNodeName() + + ">. Using XMLDOMElement"); + } + } + else { + try { + scriptable = javaScriptClass.newInstance(); + } + catch (final Exception e) { + throw Context.throwAsScriptRuntimeEx(e); + } + } + initParentScope(domNode, scriptable); + + scriptable.setPrototype(getPrototype(javaScriptClass)); + scriptable.setDomNode(domNode); + scriptable.setEnvironment(getEnvironment()); + + return scriptable; + } + + /** + * Gets the prototype object for the given host class. + * @param javaScriptClass the host class + * @return the prototype + */ + @SuppressWarnings("unchecked") + protected Scriptable getPrototype(final Class<? extends SimpleScriptable> javaScriptClass) { + final Scriptable prototype = getEnvironment().getPrototype(javaScriptClass); + if (prototype == null && javaScriptClass != SimpleScriptable.class) { + return getPrototype((Class<? extends SimpleScriptable>) javaScriptClass.getSuperclass()); + } + return prototype; + } + + /** + * {@inheritDoc} + */ + @Override + public String getClassName() { + return "Object"; + } + + /** + * @return the environment_ + */ + public MSXMLJavaScriptEnvironment getEnvironment() { + return environment_; + } + + /** + * @param environment the environment_ to set + */ + public void setEnvironment(final MSXMLJavaScriptEnvironment environment) { + environment_ = environment; + } +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.IE; +import net.sourceforge.htmlunit.corejs.javascript.Context; + +import com.gargoylesoftware.htmlunit.html.DomAttr; +import com.gargoylesoftware.htmlunit.html.DomElement; +import com.gargoylesoftware.htmlunit.html.DomText; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter; +import com.gargoylesoftware.htmlunit.javascript.configuration.WebBrowser; +import com.gargoylesoftware.htmlunit.javascript.host.Node; +import com.gargoylesoftware.htmlunit.util.StringUtils; + +/** + * A JavaScript object for MSXML's (ActiveX) XMLDOMAttribute.<br> + * Represents an attribute of the IXMLDOMElement. Valid and default values for the attribute are defined in a + * document type definition (DTD) or schema. + * @see <a href="http://msdn.microsoft.com/en-us/library/ms762738.aspx">MSDN documentation</a> + * + * @version $Revision$ + * @author Sudhan Moghe + * @author Frank Danek + */ +@JsxClass(domClass = DomAttr.class, browsers = @WebBrowser(IE)) +public class XMLDOMAttribute extends XMLDOMNode { + + private XMLDOMText textNode_; + + /** + * Creates an instance. JavaScript objects must have a default constructor. + */ + public XMLDOMAttribute() { } + + /** + * Returns a node list containing the child nodes. + * @return a node list containing the child nodes + */ + @Override + public XMLDOMNodeList getChildNodes() { + initTextNode(); + + return super.getChildNodes(); + } + + /** + * Returns the first child of the attribute. + * @return the first child of the attribute + */ + @Override + public XMLDOMNode getFirstChild() { + return getLastChild(); + } + + /** + * Returns the last child attribute. + * @return the last child attribute + */ + @Override + public XMLDOMNode getLastChild() { + initTextNode(); + + return textNode_; + } + + private void initTextNode() { + if (textNode_ == null) { + final String value = getValue(); + if (!org.apache.commons.lang3.StringUtils.isEmpty(value)) { + final DomText text = new DomText(getDomNodeOrDie().getPage(), value); + getDomNodeOrDie().appendChild(text); + textNode_ = (XMLDOMText) text.getScriptObject(); + } + } + } + + /** + * Returns the attribute name. + * @return the attribute name + */ + @JsxGetter + public String getName() { + return getDomNodeOrDie().getName(); + } + + /** + * Returns the text associated with the attribute. + * @return the text associated with the attribute + */ + @Override + public String getNodeValue() { + return getValue(); + } + + /** + * Sets the text associated with the attribute. + * @param value the new text associated with the attribute + */ + @Override + public void setNodeValue(final String value) { + setValue(value); + } + + /** + * Returns the parent node. + * @return <code>null</code> + */ + @Override + public Node getParentNode() { + return null; + } + + /** + * Indicates whether the attribute is explicitly specified or derived from a default value in + * the document type definition (DTD) or schema. + * @return <code>true</code> if this attribute has been explicitly specified + */ + @JsxGetter + public boolean getSpecified() { + return getDomNodeOrDie().getSpecified(); + } + + /** + * Returns a string representing the value of the attribute with entities expanded. + * @return the value of this attribute + */ + @Override + public Object getText() { + return getValue(); + } + + /** + * Sets the text content of the attribute. + * @param value the text content of the attribute + */ + @Override + public void setText(final Object value) { + setValue(value == null ? null : Context.toString(value)); + } + + /** + * Returns the attribute value. + * @return the attribute value + */ + @JsxGetter + public String getValue() { + return getDomNodeOrDie().getValue(); + } + + /** + * Sets the attribute value. + * @param value the new attribute value + */ + @JsxSetter + public void setValue(final String value) { + getDomNodeOrDie().setValue(value); + + resetTextNode(); + } + + private void resetTextNode() { + if (textNode_ != null) { + getDomNodeOrDie().removeChild(textNode_.getDomNodeOrNull()); + textNode_ = null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getXml() { + final StringBuilder sb = new StringBuilder(getName()); + sb.append('=').append('"'); + sb.append(StringUtils.escapeXmlAttributeValue(getValue())); + sb.append('"'); + return sb.toString(); + } + + /** + * Detaches this attribute from the parent HTML element after caching the attribute value. + */ + public void detachFromParent() { + final DomAttr domNode = getDomNodeOrDie(); + final DomElement parent = (DomElement) domNode.getParentNode(); + if (parent != null) { + domNode.setValue(parent.getAttribute(getName())); + } + domNode.remove(); + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public DomAttr getDomNodeOrDie() throws IllegalStateException { + return super.getDomNodeOrDie(); + } +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.IE; + +import com.gargoylesoftware.htmlunit.html.DomCDataSection; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; +import com.gargoylesoftware.htmlunit.javascript.configuration.WebBrowser; + +/** + * A JavaScript object for MSXML's (ActiveX) XMLDOMCDATASection.<br> + * Used to quote or escape blocks of text to keep that text from being interpreted as markup language. + * @see <a href="http://msdn.microsoft.com/en-us/library/ms762780.aspx">MSDN documentation</a> + * + * @version $Revision$ + * @author Ahmed Ashour + * @author Frank Danek + */ +@JsxClass(domClass = DomCDataSection.class, browsers = @WebBrowser(IE)) +public final class XMLDOMCDATASection extends XMLDOMText { + + /** + * Creates an instance. JavaScript objects must have a default constructor. + */ + public XMLDOMCDATASection() { + } + +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.IE; +import net.sourceforge.htmlunit.corejs.javascript.Context; + +import com.gargoylesoftware.htmlunit.html.DomCharacterData; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter; +import com.gargoylesoftware.htmlunit.javascript.configuration.WebBrowser; + +/** + * A JavaScript object for MSXML's (ActiveX) XMLDOMCharacterData.<br> + * Provides text manipulation methods that are used by several objects. + * @see <a href="http://msdn.microsoft.com/en-us/library/ms767515.aspx">MSDN documentation</a> + * + * @version $Revision$ + * @author David K. Taylor + * @author Chris Erskine + * @author Frank Danek + */ +@JsxClass(domClass = DomCharacterData.class, browsers = @WebBrowser(IE)) +public class XMLDOMCharacterData extends XMLDOMNode { + + /** + * Creates an instance. JavaScript objects must have a default constructor. + */ + public XMLDOMCharacterData() { + } + + /** + * Returns the node data depending on the node type. + * @return the node data depending on the node type + */ + @JsxGetter + public Object getData() { + final DomCharacterData domCharacterData = getDomNodeOrDie(); + return domCharacterData.getData(); + } + + /** + * Sets the node data depending on the node type. + * @param newData the node data depending on the node type + */ + @JsxSetter + public void setData(final String newData) { + if (newData == null || "null".equals(newData)) { + throw Context.reportRuntimeError("Type mismatch."); + } + + final DomCharacterData domCharacterData = getDomNodeOrDie(); + domCharacterData.setData(newData); + } + + /** + * Returns the length, in characters, of the data. + * @return the length of the data + */ + @JsxGetter + public int getLength() { + final DomCharacterData domCharacterData = getDomNodeOrDie(); + return domCharacterData.getLength(); + } + + /** + * Sets the text contained in the node. + * @param newText the text contained in the node + */ + @Override + public void setText(final Object newText) { + setData(newText == null ? null : Context.toString(newText)); + } + + /** + * {@inheritDoc} + */ + @Override + public Object getXml() { + Object xml = super.getXml(); + if (xml instanceof String) { + final String xmlString = (String) xml; + if (xmlString.indexOf('\n') >= 0) { + xml = xmlString.replaceAll("([^\r])\n", "$1\r\n"); + } + } + return xml; + } + + /** + * Appends the supplied string to the existing string data. + * @param data the data that is to be appended to the existing string + */ + @JsxFunction + public void appendData(final String data) { + if (data == null || "null".equals(data)) { + throw Context.reportRuntimeError("Type mismatch."); + } + + final DomCharacterData domCharacterData = getDomNodeOrDie(); + domCharacterData.appendData(data); + } + + /** + * Deletes specified data. + * @param offset the offset, in characters, at which to start deleting string data + * @param count the number of characters to delete + */ + @JsxFunction + public void deleteData(final int offset, final int count) { + if (offset < 0) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + if (count < 0) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + if (count == 0) { + return; + } + + final DomCharacterData domCharacterData = (DomCharacterData) getDomNodeOrDie(); + if (offset > domCharacterData.getLength()) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + + domCharacterData.deleteData(offset, count); + } + + /** + * Inserts a string at the specified offset. + * @param offset the offset, in characters, at which to insert the supplied string data + * @param data the data that is to be inserted into the existing string + */ + @JsxFunction + public void insertData(final int offset, final String data) { + if (data.isEmpty()) { + return; + } + if (offset < 0) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + if (data == null || "null".equals(data)) { + throw Context.reportRuntimeError("Type mismatch."); + } + + final DomCharacterData domCharacterData = getDomNodeOrDie(); + if (offset > domCharacterData.getLength()) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + + domCharacterData.insertData(offset, data); + } + + /** + * Replaces the specified number of characters with the supplied string. + * @param offset the offset, in characters, at which to start replacing string data + * @param count the number of characters to replace + * @param data the new data that replaces the old string data + */ + @JsxFunction + public void replaceData(final int offset, final int count, final String data) { + if (offset < 0) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + if (count < 0) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + if (data == null || "null".equals(data)) { + throw Context.reportRuntimeError("Type mismatch."); + } + + final DomCharacterData domCharacterData = getDomNodeOrDie(); + if (offset > domCharacterData.getLength()) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + + domCharacterData.replaceData(offset, count, data); + } + + /** + * Retrieves a substring of the full string from the specified range. + * @param offset the offset, in characters, from the beginning of the string. An offset of zero indicates + * copying from the start of the data + * @param count the number of characters to retrieve from the specified offset + * @return the substring + */ + @JsxFunction + public String substringData(final int offset, final int count) { + if (offset < 0) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + if (count < 0) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + + final DomCharacterData domCharacterData = getDomNodeOrDie(); + if (offset > domCharacterData.getLength()) { + throw Context.reportRuntimeError("The offset must be 0 or a positive number that is not greater than the " + + "number of characters in the data."); + } + + return domCharacterData.substringData(offset, count); + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public DomCharacterData getDomNodeOrDie() { + return (DomCharacterData) super.getDomNodeOrDie(); + } +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.IE; + +import com.gargoylesoftware.htmlunit.html.DomComment; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; +import com.gargoylesoftware.htmlunit.javascript.configuration.WebBrowser; + +/** + * A JavaScript object for MSXML's (ActiveX) XMLDOMComment.<br> + * Represents the content of an XML comment. + * @see <a href="http://msdn.microsoft.com/en-us/library/ms765529.aspx">MSDN documentation</a> + * + * @version $Revision$ + * @author Mirko Friedenhagen + * @author Ahmed Ashour + * @author Frank Danek + */ +@JsxClass(domClass = DomComment.class, browsers = @WebBrowser(IE)) +public final class XMLDOMComment extends XMLDOMCharacterData { + + /** + * Creates an instance. JavaScript objects must have a default constructor. + */ + public XMLDOMComment() { + } + + /** + * Returns the text contained in the node. + * @return the text contained in the node + */ + @Override + public String getText() { + return (String) getData(); + } +} Property changes on: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java (rev 0) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java 2013-12-12 18:52:03 UTC (rev 8836) @@ -0,0 +1,710 @@ +/* + * Copyright (c) 2002-2013 Gargoyle Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gargoylesoftware.htmlunit.activex.javascript.msxml; + +import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.IE; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.htmlunit.corejs.javascript.Context; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Node; + +import com.gargoylesoftware.htmlunit.ElementNotFoundException; +import com.gargoylesoftware.htmlunit.SgmlPage; +import com.gargoylesoftware.htmlunit.StringWebResponse; +import com.gargoylesoftware.htmlunit.WebRequest; +import com.gargoylesoftware.htmlunit.WebResponse; +import com.gargoylesoftware.htmlunit.WebWindow; +import com.gargoylesoftware.htmlunit.html.DomAttr; +import com.gargoylesoftware.htmlunit.html.DomCDataSection; +import com.gargoylesoftware.htmlunit.html.DomComment; +import com.gargoylesoftware.htmlunit.html.DomDocumentFragment; +import com.gargoylesoftware.htmlunit.html.DomElement; +import com.gargoylesoftware.htmlunit.html.DomNode; +import com.gargoylesoftware.htmlunit.html.DomProcessingInstruction; +import com.gargoylesoftware.htmlunit.html.DomText; +import com.gargoylesoftware.htmlunit.html.HTMLParser; +import com.gargoylesoftware.htmlunit.html.HtmlElement; +import com.gargoylesoftware.htmlunit.html.HtmlPage; +import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter; +import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter; +import com.gargoylesoftware.htmlunit.javascript.configuration.WebBrowser; +import com.gargoylesoftware.htmlunit.xml.XmlPage; + +/** + * A JavaScript object for MSXML's (ActiveX) XMLDOMDocument.<br> + * Represents the top level of the XML source. Includes members for retrieving and creating all other XML objects. + * @see <a href="http://msdn.microsoft.com/en-us/library/ms756987.aspx">MSDN documentation</a> + * + * @version $Revision$ + * @author Ahmed Ashour + * @author Marc Guillemot + * @author Sudhan Moghe + * @author Ronald Brill + * @author Chuck Dumont + * @author Frank Danek + */ +@JsxClass(browsers = @WebBrowser(IE)) +public class XMLDOMDocument extends XMLDOMNode { + + private static final Log LOG = LogFactory.getLog(XMLDOMDocument.class); + + private boolean async_ = true; + private XMLDOMImplementation implementation_; + private boolean preserveWhiteSpace_; + private boolean preserveWhiteSpaceDuringLoad_ = true; + private XMLDOMParseError parseError_; + private Map<String, String> properties_ = new HashMap<String, String>(); + private String url_ = ""; + + /** + * Creates a new instance. JavaScript objects must have a default constructor. + */ + public XMLDOMDocument() { + this(null); + } + + /** + * Creates a new instance, with associated {@link XmlPage}. + * @param enclosingWindow the window + */ + public XMLDOMDocument(final WebWindow enclosingWindow) { + if (enclosingWindow != null) { + try { + final XmlPage page = new XmlPage((WebResponse) null, enclosingWindow, true, false); + setDomNode(page); + } + catch (final IOException e) { + throw Context.reportRuntimeError("IOException: " + e); + } + } + } + + /** + * Returns if asynchronous download is permitted. + * @return if asynchronous download is permitted + */ + @JsxGetter + public boolean getAsync() { + return async_; + } + + /** + * Sets if asynchronous download is permitted. + * @param async if asynchronous download is permitted + */ + @JsxSetter + public void setAsync(final boolean async) { + async_ = async; + } + + /** + * Returns the document type node that specifies the DTD for this document. + * @return the document type node that specifies the DTD for this document + */ + @JsxGetter + public XMLDOMDocumentType getDoctype() { + final Object documentType = getPage().getDoctype(); + if (documentType == null) { + return null; + } + return (XMLDOMDocumentType) getScriptableFor(documentType); + } + + /** + * Returns the root element of the document. + * @return the root element of the document + */ + @JsxGetter + public XMLDOMElement getDocumentElement() { + final Object documentElement = getPage().getDocumentElement(); + if (documentElement == null) { + // for instance with an XML document with parsing error + return null; + } + return (XMLDOMElement) getScriptableFor(documentElement); + } + + /** + * Sets the root element of the document. + * @param element the root element of the document + */ + @JsxSetter + public void setDocumentElement(final XMLDOMElement element) { + if (element == null) { + throw Context.reportRuntimeError("Type mismatch."); + } + + final XMLDOMElement documentElement = getDocumentElement(); + if (documentElement != null) { + documentElement.getDomNodeOrDie().remove(); + } + + appendChild(element); + } + + /** + * Returns the implementation object for the document. + * @return the implementation object for the doc... [truncated message content] |