diff --git a/lib/htmlagilitypack/HtmlAgilityPack.XML b/lib/htmlagilitypack/HtmlAgilityPack.XML new file mode 100644 index 000000000..bc0d29ce1 --- /dev/null +++ b/lib/htmlagilitypack/HtmlAgilityPack.XML @@ -0,0 +1,2430 @@ + + + + HtmlAgilityPack + + + + + Represents an HTML navigator on an HTML document seen as a data store. + + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. + + The input stream. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. + + The input stream. + Indicates whether to look for byte order marks at the beginning of the stream. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. + + The input stream. + The character encoding to use. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. + + The input stream. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the stream. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. + + The input stream. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the stream. + The minimum buffer size. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a TextReader. + + The TextReader used to feed the HTML data into the document. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. + + The complete file path to be read. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. + + The complete file path to be read. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. + + The complete file path to be read. + The character encoding to use. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. + + The complete file path to be read. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. + + The complete file path to be read. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the file. + The minimum buffer size. + + + + Creates a new HtmlNavigator positioned at the same node as this HtmlNavigator. + + A new HtmlNavigator object positioned at the same node as the original HtmlNavigator. + + + + Gets the value of the HTML attribute with the specified LocalName and NamespaceURI. + + The local name of the HTML attribute. + The namespace URI of the attribute. Unsupported with the HtmlNavigator implementation. + The value of the specified HTML attribute. String.Empty or null if a matching attribute is not found or if the navigator is not positioned on an element node. + + + + Returns the value of the namespace node corresponding to the specified local name. + Always returns string.Empty for the HtmlNavigator implementation. + + The local name of the namespace node. + Always returns string.Empty for the HtmlNavigator implementation. + + + + Determines whether the current HtmlNavigator is at the same position as the specified HtmlNavigator. + + The HtmlNavigator that you want to compare against. + true if the two navigators have the same position, otherwise, false. + + + + Moves to the same position as the specified HtmlNavigator. + + The HtmlNavigator positioned on the node that you want to move to. + true if successful, otherwise false. If false, the position of the navigator is unchanged. + + + + Moves to the HTML attribute with matching LocalName and NamespaceURI. + + The local name of the HTML attribute. + The namespace URI of the attribute. Unsupported with the HtmlNavigator implementation. + true if the HTML attribute is found, otherwise, false. If false, the position of the navigator does not change. + + + + Moves to the first sibling of the current node. + + true if the navigator is successful moving to the first sibling node, false if there is no first sibling or if the navigator is currently positioned on an attribute node. + + + + Moves to the first HTML attribute. + + true if the navigator is successful moving to the first HTML attribute, otherwise, false. + + + + Moves to the first child of the current node. + + true if there is a first child node, otherwise false. + + + + Moves the XPathNavigator to the first namespace node of the current element. + Always returns false for the HtmlNavigator implementation. + + An XPathNamespaceScope value describing the namespace scope. + Always returns false for the HtmlNavigator implementation. + + + + Moves to the node that has an attribute of type ID whose value matches the specified string. + + A string representing the ID value of the node to which you want to move. This argument does not need to be atomized. + true if the move was successful, otherwise false. If false, the position of the navigator is unchanged. + + + + Moves the XPathNavigator to the namespace node with the specified local name. + Always returns false for the HtmlNavigator implementation. + + The local name of the namespace node. + Always returns false for the HtmlNavigator implementation. + + + + Moves to the next sibling of the current node. + + true if the navigator is successful moving to the next sibling node, false if there are no more siblings or if the navigator is currently positioned on an attribute node. If false, the position of the navigator is unchanged. + + + + Moves to the next HTML attribute. + + + + + + Moves the XPathNavigator to the next namespace node. + Always returns falsefor the HtmlNavigator implementation. + + An XPathNamespaceScope value describing the namespace scope. + Always returns false for the HtmlNavigator implementation. + + + + Moves to the parent of the current node. + + true if there is a parent node, otherwise false. + + + + Moves to the previous sibling of the current node. + + true if the navigator is successful moving to the previous sibling node, false if there is no previous sibling or if the navigator is currently positioned on an attribute node. + + + + Moves to the root node to which the current node belongs. + + + + + Gets the base URI for the current node. + Always returns string.Empty in the case of HtmlNavigator implementation. + + + + + Gets the current HTML document. + + + + + Gets the current HTML node. + + + + + Gets a value indicating whether the current node has child nodes. + + + + + Gets a value indicating whether the current node has child nodes. + + + + + Gets a value indicating whether the current node is an empty element. + + + + + Gets the name of the current HTML node without the namespace prefix. + + + + + Gets the qualified name of the current node. + + + + + Gets the namespace URI (as defined in the W3C Namespace Specification) of the current node. + Always returns string.Empty in the case of HtmlNavigator implementation. + + + + + Gets the associated with this implementation. + + + + + Gets the type of the current node. + + + + + Gets the prefix associated with the current node. + Always returns string.Empty in the case of HtmlNavigator implementation. + + + + + Gets the text value of the current node. + + + + + Gets the xml:lang scope for the current node. + Always returns string.Empty in the case of HtmlNavigator implementation. + + + + + Represents a complete HTML document. + + + + + Adds Debugging attributes to node. Default is false. + + + + + Defines if closing for non closed nodes must be done at the end or directly in the document. + Setting this to true can actually change how browsers render the page. Default is false. + + + + + Defines if non closed nodes will be checked at the end of parsing. Default is true. + + + + + Defines if a checksum must be computed for the document while parsing. Default is false. + + + + + Defines the default stream encoding to use. Default is System.Text.Encoding.Default. + + + + + Defines if source text must be extracted while parsing errors. + If the document has a lot of errors, or cascading errors, parsing performance can be dramatically affected if set to true. + Default is false. + + + + + Defines the maximum length of source text or parse errors. Default is 100. + + + + + Defines if LI, TR, TH, TD tags must be partially fixed when nesting errors are detected. Default is false. + + + + + Defines if output must conform to XML, instead of HTML. + + + + + Defines if attribute value output must be optimized (not bound with double quotes if it is possible). Default is false. + + + + + Defines if name must be output with it's original case. Useful for asp.net tags and attributes + + + + + Defines if name must be output in uppercase. Default is false. + + + + + Defines if declared encoding must be read from the document. + Declared encoding is determined using the meta http-equiv="content-type" content="text/html;charset=XXXXX" html node. + Default is true. + + + + + Defines the name of a node that will throw the StopperNodeException when found as an end node. Default is null. + + + + + Defines if the 'id' attribute must be specifically used. Default is true. + + + + + Defines if empty nodes must be written as closed during output. Default is false. + + + + + Creates an instance of an HTML document. + + + + + Creates a new XPathNavigator object for navigating this HTML document. + + An XPathNavigator object. The XPathNavigator is positioned on the root of the document. + + + + Gets a valid XML name. + + Any text. + A string that is a valid XML name. + + + + Applies HTML encoding to a specified string. + + The input string to encode. May not be null. + The encoded string. + + + + Determines if the specified character is considered as a whitespace character. + + The character to check. + true if if the specified character is considered as a whitespace character. + + + + Creates an HTML attribute with the specified name. + + The name of the attribute. May not be null. + The new HTML attribute. + + + + Creates an HTML attribute with the specified name. + + The name of the attribute. May not be null. + The value of the attribute. + The new HTML attribute. + + + + Creates an HTML comment node. + + The new HTML comment node. + + + + Creates an HTML comment node with the specified comment text. + + The comment text. May not be null. + The new HTML comment node. + + + + Creates an HTML element node with the specified name. + + The qualified name of the element. May not be null. + The new HTML node. + + + + Creates an HTML text node. + + The new HTML text node. + + + + Creates an HTML text node with the specified text. + + The text of the node. May not be null. + The new HTML text node. + + + + Detects the encoding of an HTML stream. + + The input stream. May not be null. + The detected encoding. + + + + Detects the encoding of an HTML file. + + Path for the file containing the HTML document to detect. May not be null. + The detected encoding. + + + + Detects the encoding of an HTML text provided on a TextReader. + + The TextReader used to feed the HTML. May not be null. + The detected encoding. + + + + Detects the encoding of an HTML document from a file first, and then loads the file. + + The complete file path to be read. + + + + Detects the encoding of an HTML document from a file first, and then loads the file. + + The complete file path to be read. May not be null. + true to detect encoding, false otherwise. + + + + Detects the encoding of an HTML text. + + The input html text. May not be null. + The detected encoding. + + + + Gets the HTML node with the specified 'id' attribute value. + + The attribute id to match. May not be null. + The HTML node with the matching id or null if not found. + + + + Loads an HTML document from a stream. + + The input stream. + + + + Loads an HTML document from a stream. + + The input stream. + Indicates whether to look for byte order marks at the beginning of the stream. + + + + Loads an HTML document from a stream. + + The input stream. + The character encoding to use. + + + + Loads an HTML document from a stream. + + The input stream. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the stream. + + + + Loads an HTML document from a stream. + + The input stream. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the stream. + The minimum buffer size. + + + + Loads an HTML document from a file. + + The complete file path to be read. May not be null. + + + + Loads an HTML document from a file. + + The complete file path to be read. May not be null. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Loads an HTML document from a file. + + The complete file path to be read. May not be null. + The character encoding to use. May not be null. + + + + Loads an HTML document from a file. + + The complete file path to be read. May not be null. + The character encoding to use. May not be null. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Loads an HTML document from a file. + + The complete file path to be read. May not be null. + The character encoding to use. May not be null. + Indicates whether to look for byte order marks at the beginning of the file. + The minimum buffer size. + + + + Loads the HTML document from the specified TextReader. + + The TextReader used to feed the HTML data into the document. May not be null. + + + + Loads the HTML document from the specified string. + + String containing the HTML document to load. May not be null. + + + + Saves the HTML document to the specified stream. + + The stream to which you want to save. + + + + Saves the HTML document to the specified stream. + + The stream to which you want to save. May not be null. + The character encoding to use. May not be null. + + + + Saves the mixed document to the specified file. + + The location of the file where you want to save the document. + + + + Saves the mixed document to the specified file. + + The location of the file where you want to save the document. May not be null. + The character encoding to use. May not be null. + + + + Saves the HTML document to the specified StreamWriter. + + The StreamWriter to which you want to save. + + + + Saves the HTML document to the specified TextWriter. + + The TextWriter to which you want to save. May not be null. + + + + Saves the HTML document to the specified XmlWriter. + + The XmlWriter to which you want to save. + + + + Gets the document CRC32 checksum if OptionComputeChecksum was set to true before parsing, 0 otherwise. + + + + + Gets the document's declared encoding. + Declared encoding is determined using the meta http-equiv="content-type" content="text/html;charset=XXXXX" html node. + + + + + Gets the root node of the document. + + + + + Gets the document's output encoding. + + + + + Gets a list of parse errors found in the document. + + + + + Gets the remaining text. + Will always be null if OptionStopperNodeName is null. + + + + + Gets the offset of Remainder in the original Html text. + If OptionStopperNodeName is null, this will return the length of the original Html text. + + + + + Gets the document's stream encoding. + + + + + A utility class to get HTML document from HTTP. + + + + + Occurs after an HTTP request has been executed. + + + + + Occurs before an HTML document is handled. + + + + + Occurs before an HTTP request is executed. + + + + + Gets the MIME content type for a given path extension. + + The input path extension. + The default content type to return if any error occurs. + The path extension's MIME content type. + + + + Gets the path extension for a given MIME content type. + + The input MIME content type. + The default path extension to return if any error occurs. + The MIME content type's path extension. + + + + Creates an instance of the given type from the specified Internet resource. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The requested type. + An newly created instance. + + + + Creates an instance of the given type from the specified Internet resource. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The URL that specifies the XSLT stylesheet to load. + An containing the namespace-qualified arguments used as input to the transform. + The requested type. + An newly created instance. + + + + Creates an instance of the given type from the specified Internet resource. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The URL that specifies the XSLT stylesheet to load. + An containing the namespace-qualified arguments used as input to the transform. + The requested type. + A file path where the temporary XML before transformation will be saved. Mostly used for debugging purposes. + An newly created instance. + + + + Gets an HTML document from an Internet resource and saves it to the specified file. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The location of the file where you want to save the document. + + + + Gets an HTML document from an Internet resource and saves it to the specified file. - Proxy aware + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The location of the file where you want to save the document. + + + + + + Gets an HTML document from an Internet resource and saves it to the specified file. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The location of the file where you want to save the document. + The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. + + + + Gets an HTML document from an Internet resource and saves it to the specified file. Understands Proxies + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The location of the file where you want to save the document. + + The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. + + + + + Gets the cache file path for a specified url. + + The url fo which to retrieve the cache path. May not be null. + The cache file path. + + + + Gets an HTML document from an Internet resource. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + A new HTML document. + + + + Gets an HTML document from an Internet resource. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + Host to use for Proxy + Port the Proxy is on + User Id for Authentication + Password for Authentication + A new HTML document. + + + + Loads an HTML document from an Internet resource. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. + A new HTML document. + + + + Loads an HTML document from an Internet resource. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. + Proxy to use with this request + Credentials to use when authenticating + A new HTML document. + + + + Loads an HTML document from an Internet resource and saves it to the specified XmlTextWriter. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The XmlTextWriter to which you want to save. + + + + Loads an HTML document from an Internet resource and saves it to the specified XmlTextWriter, after an XSLT transformation. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". + The URL that specifies the XSLT stylesheet to load. + An XsltArgumentList containing the namespace-qualified arguments used as input to the transform. + The XmlTextWriter to which you want to save. + + + + Loads an HTML document from an Internet resource and saves it to the specified XmlTextWriter, after an XSLT transformation. + + The requested URL, such as "http://Myserver/Mypath/Myfile.asp". May not be null. + The URL that specifies the XSLT stylesheet to load. + An XsltArgumentList containing the namespace-qualified arguments used as input to the transform. + The XmlTextWriter to which you want to save. + A file path where the temporary XML before transformation will be saved. Mostly used for debugging purposes. + + + + Gets or Sets a value indicating if document encoding must be automatically detected. + + + + + Gets or Sets a value indicating whether to get document only from the cache. + If this is set to true and document is not found in the cache, nothing will be loaded. + + + + + Gets or Sets the cache path. If null, no caching mechanism will be used. + + + + + Gets a value indicating if the last document was retrieved from the cache. + + + + + Gets the last request duration in milliseconds. + + + + + Gets the URI of the Internet resource that actually responded to the request. + + + + + Gets the last request status. + + + + + Gets or Sets the size of the buffer used for memory operations. + + + + + Gets or Sets a value indicating if cookies will be stored. + + + + + Gets or Sets a value indicating whether the caching mechanisms should be used or not. + + + + + Represents the method that will handle the PostResponse event. + + + + + Represents the method that will handle the PreHandleDocument event. + + + + + Represents the method that will handle the PreRequest event. + + + + + Represents the type of fragment in a mixed code document. + + + + + The fragment contains code. + + + + + The fragment contains text. + + + + + Represents a combined list and collection of HTML nodes. + + + + + Adds supplied item to collection + + + + + + Explicit clear + + + + + Retreives existence of supplied item + + + + + + + Copies collection to array + + + + + + + Get Explicit enumerator + + + + + + Explicit non-generic enumerator + + + + + + Retrieves the index for the supplied item, -1 if not found + + + + + + + Inserts given item into collection at supplied index + + + + + + + Explicit collection remove + + + + + + + Removes the attribute at the specified index. + + The index of the attribute to remove. + + + + Adds a new attribute to the collection with the given values + + + + + + + Inserts the specified attribute as the last attribute in the collection. + + The attribute to insert. May not be null. + The appended attribute. + + + + Creates and inserts a new attribute as the last attribute in the collection. + + The name of the attribute to insert. + The appended attribute. + + + + Creates and inserts a new attribute as the last attribute in the collection. + + The name of the attribute to insert. + The value of the attribute to insert. + The appended attribute. + + + + Checks for existance of attribute with given name + + + + + + + Inserts the specified attribute as the first node in the collection. + + The attribute to insert. May not be null. + The prepended attribute. + + + + Removes a given attribute from the list. + + The attribute to remove. May not be null. + + + + Removes an attribute from the list, using its name. If there are more than one attributes with this name, they will all be removed. + + The attribute's name. May not be null. + + + + Remove all attributes in the list. + + + + + Returns all attributes with specified name. Handles case insentivity + + Name of the attribute + + + + + Removes all attributes from the collection + + + + + Clears the attribute collection + + + + + Gets a given attribute from the list using its name. + + + + + Gets the number of elements actually contained in the list. + + + + + Gets readonly status of colelction + + + + + Gets the attribute at the specified index. + + + + + Flags that describe the behavior of an Element node. + + + + + The node is a CDATA node. + + + + + The node is empty. META or IMG are example of such nodes. + + + + + The node will automatically be closed during parsing. + + + + + The node can overlap. + + + + + Represents a combined list and collection of HTML nodes. + + + + + Initialize the HtmlNodeCollection with the base parent node + + The base node of the collection + + + + Add node to the collection + + + + + + Clears out the collection of HtmlNodes. Removes each nodes reference to parentnode, nextnode and prevnode + + + + + Gets existence of node in collection + + + + + + + Copy collection to array + + + + + + + Get Enumerator + + + + + + Get Explicit Enumerator + + + + + + Get index of node + + + + + + + Insert node at index + + + + + + + Remove node + + + + + + + Remove at index + + + + + + Get first instance of node in supplied collection + + + + + + + + Add node to the end of the collection + + + + + + Get first instance of node with name + + + + + + + Get index of node + + + + + + + Add node to the beginning of the collection + + + + + + Remove node at index + + + + + + + Replace node at index + + + + + + + Get all node descended from this collection + + + + + + Get all node descended from this collection + + + + + + Get all node descended from this collection with matching name + + + + + + Gets all first generation elements in collection + + + + + + Gets all first generation elements matching name + + + + + + + All first generation nodes in collection + + + + + + Gets a given node from the list. + + + + + Get node with tag name + + + + + + + Gets the number of elements actually contained in the list. + + + + + Is collection read only + + + + + Gets the node at the specified index. + + + + + A utility class to compute CRC32. + + + + + Compute a checksum for a given array of bytes. + + The array of bytes to compute the checksum for. + The computed checksum. + + + + Compute a checksum for a given string. + + The string to compute the checksum for. + The computed checksum. + + + + Represents an HTML node. + + + + + Gets the name of a comment node. It is actually defined as '#comment'. + + + + + Gets the name of the document node. It is actually defined as '#document'. + + + + + Gets the name of a text node. It is actually defined as '#text'. + + + + + Gets a collection of flags that define specific behaviors for specific element nodes. + The table contains a DictionaryEntry list with the lowercase tag name as the Key, and a combination of HtmlElementFlags as the Value. + + + + + Initialize HtmlNode. Builds a list of all tags that have special allowances + + + + + Initializes HtmlNode, providing type, owner and where it exists in a collection + + + + + + + + Creates a new XPathNavigator object for navigating this HTML node. + + An XPathNavigator object. The XPathNavigator is positioned on the node from which the method was called. It is not positioned on the root of the document. + + + + Determines if an element node can be kept overlapped. + + The name of the element node to check. May not be null. + true if the name is the name of an element node that can be kept overlapped, false otherwise. + + + + Creates an HTML node from a string representing literal HTML. + + The HTML text. + The newly created node instance. + + + + Determines if an element node is a CDATA element node. + + The name of the element node to check. May not be null. + true if the name is the name of a CDATA element node, false otherwise. + + + + Determines if an element node is closed. + + The name of the element node to check. May not be null. + true if the name is the name of a closed element node, false otherwise. + + + + Determines if an element node is defined as empty. + + The name of the element node to check. May not be null. + true if the name is the name of an empty element node, false otherwise. + + + + Determines if a text corresponds to the closing tag of an node that can be kept overlapped. + + The text to check. May not be null. + true or false. + + + + Returns a collection of all ancestor nodes of this element. + + + + + + Get Ancestors with matching name + + + + + + + Returns a collection of all ancestor nodes of this element. + + + + + + Gets all anscestor nodes and the current node + + + + + + + Adds the specified node to the end of the list of children of this node. + + The node to add. May not be null. + The node added. + + + + Adds the specified node to the end of the list of children of this node. + + The node list to add. May not be null. + + + + Gets all Attributes with name + + + + + + + Creates a duplicate of the node + + + + + + Creates a duplicate of the node and changes its name at the same time. + + The new name of the cloned node. May not be null. + The cloned node. + + + + Creates a duplicate of the node and changes its name at the same time. + + The new name of the cloned node. May not be null. + true to recursively clone the subtree under the specified node; false to clone only the node itself. + The cloned node. + + + + Creates a duplicate of the node. + + true to recursively clone the subtree under the specified node; false to clone only the node itself. + The cloned node. + + + + Creates a duplicate of the node and the subtree under it. + + The node to duplicate. May not be null. + + + + Creates a duplicate of the node. + + The node to duplicate. May not be null. + true to recursively clone the subtree under the specified node, false to clone only the node itself. + + + + Creates an XPathNavigator using the root of this document. + + + + + + Gets all Descendant nodes for this node and each of child nodes + + + + + + Returns a collection of all descendant nodes of this element, in document order + + + + + + Gets all Descendant nodes in enumerated list + + + + + + Get all descendant nodes with matching name + + + + + + + Returns a collection of all descendant nodes of this element, in document order + + + + + + Gets all descendant nodes including this node + + + + + + + Gets first generation child node matching name + + + + + + + Gets matching first generation child nodes matching name + + + + + + + Helper method to get the value of an attribute of this node. If the attribute is not found, the default value will be returned. + + The name of the attribute to get. May not be null. + The default value to return if not found. + The value of the attribute if found, the default value if not found. + + + + Helper method to get the value of an attribute of this node. If the attribute is not found, the default value will be returned. + + The name of the attribute to get. May not be null. + The default value to return if not found. + The value of the attribute if found, the default value if not found. + + + + Helper method to get the value of an attribute of this node. If the attribute is not found, the default value will be returned. + + The name of the attribute to get. May not be null. + The default value to return if not found. + The value of the attribute if found, the default value if not found. + + + + Inserts the specified node immediately after the specified reference node. + + The node to insert. May not be null. + The node that is the reference node. The newNode is placed after the refNode. + The node being inserted. + + + + Inserts the specified node immediately before the specified reference node. + + The node to insert. May not be null. + The node that is the reference node. The newChild is placed before this node. + The node being inserted. + + + + Adds the specified node to the beginning of the list of children of this node. + + The node to add. May not be null. + The node added. + + + + Adds the specified node list to the beginning of the list of children of this node. + + The node list to add. May not be null. + + + + Removes node from parent collection + + + + + Removes all the children and/or attributes of the current node. + + + + + Removes all the children of the current node. + + + + + Removes the specified child node. + + The node being removed. May not be null. + The node removed. + + + + Removes the specified child node. + + The node being removed. May not be null. + true to keep grand children of the node, false otherwise. + The node removed. + + + + Replaces the child node oldChild with newChild node. + + The new node to put in the child list. + The node being replaced in the list. + The node replaced. + + + + Selects a list of nodes matching the expression. + + The XPath expression. + An containing a collection of nodes matching the query, or null if no node matched the XPath expression. + + + + Selects the first XmlNode that matches the XPath expression. + + The XPath expression. May not be null. + The first that matches the XPath query or a null reference if no matching node was found. + + + + Helper method to set the value of an attribute of this node. If the attribute is not found, it will be created automatically. + + The name of the attribute to set. May not be null. + The value for the attribute. + The corresponding attribute instance. + + + + Saves all the children of the node to the specified TextWriter. + + The TextWriter to which you want to save. + + + + Saves all the children of the node to a string. + + The saved string. + + + + Saves the current node to the specified TextWriter. + + The TextWriter to which you want to save. + + + + Saves the current node to the specified XmlWriter. + + The XmlWriter to which you want to save. + + + + Saves the current node to a string. + + The saved string. + + + + Gets the collection of HTML attributes for this node. May not be null. + + + + + Gets all the children of the node. + + + + + Gets a value indicating if this node has been closed or not. + + + + + Gets the collection of HTML attributes for the closing tag. May not be null. + + + + + Gets the first child of the node. + + + + + Gets a value indicating whether the current node has any attributes. + + + + + Gets a value indicating whether this node has any child nodes. + + + + + Gets a value indicating whether the current node has any attributes on the closing tag. + + + + + Gets or sets the value of the 'id' HTML attribute. The document must have been parsed using the OptionUseIdAttribute set to true. + + + + + Gets or Sets the HTML between the start and end tags of the object. + + + + + Gets or Sets the text between the start and end tags of the object. + + + + + Gets the last child of the node. + + + + + Gets the line number of this node in the document. + + + + + Gets the column number of this node in the document. + + + + + Gets or sets this node's name. + + + + + Gets the HTML node immediately following this element. + + + + + Gets the type of this node. + + + + + The original unaltered name of the tag + + + + + Gets or Sets the object and its content in HTML. + + + + + Gets the to which this node belongs. + + + + + Gets the parent of this node (for nodes that can have parents). + + + + + Gets the node immediately preceding this node. + + + + + Gets the stream position of this node in the document, relative to the start of the document. + + + + + Gets a valid XPath string that points to this node + + + + + Represents an HTML attribute. + + + + + Compares the current instance with another attribute. Comparison is based on attributes' name. + + An attribute to compare with this instance. + A 32-bit signed integer that indicates the relative order of the names comparison. + + + + Creates a duplicate of this attribute. + + The cloned attribute. + + + + Removes this attribute from it's parents collection + + + + + Gets the line number of this attribute in the document. + + + + + Gets the column number of this attribute in the document. + + + + + Gets the qualified name of the attribute. + + + + + Name of attribute with original case + + + + + Gets the HTML document to which this attribute belongs. + + + + + Gets the HTML node to which this attribute belongs. + + + + + Specifies what type of quote the data should be wrapped in + + + + + Gets the stream position of this attribute in the document, relative to the start of the document. + + + + + Gets or sets the value of the attribute. + + + + + Gets a valid XPath string that points to this Attribute + + + + + An Enum representing different types of Quotes used for surrounding attribute values + + + + + A single quote mark ' + + + + + A double quote mark " + + + + + A utility class to replace special characters by entities and vice-versa. + Follows HTML 4.0 specification found at http://www.w3.org/TR/html4/sgml/entities.html + + + + + Replace known entities by characters. + + The source text. + The result text. + + + + Clone and entitize an HtmlNode. This will affect attribute values and nodes' text. It will also entitize all child nodes. + + The node to entitize. + An entitized cloned node. + + + + Replace characters above 127 by entities. + + The source text. + The result text. + + + + Replace characters above 127 by entities. + + The source text. + If set to false, the function will not use known entities name. Default is true. + The result text. + + + + Replace characters above 127 by entities. + + The source text. + If set to false, the function will not use known entities name. Default is true. + If set to true, the [quote], [ampersand], [lower than] and [greather than] characters will be entitized. + The result text + + + + A collection of entities indexed by name. + + + + + A collection of entities indexed by value. + + + + + Represents a fragment of text in a mixed code document. + + + + + Represents a base class for fragments in a mixed code document. + + + + + Gets the fragement text. + + + + + Gets the type of fragment. + + + + + Gets the line number of the fragment. + + + + + Gets the line position (column) of the fragment. + + + + + Gets the fragment position in the document's stream. + + + + + Gets the fragment text. + + + + + Represents an exception thrown by the HtmlWeb utility class. + + + + + Creates an instance of the HtmlWebException. + + The exception's message. + + + + Represents the type of parsing error. + + + + + A tag was not closed. + + + + + A tag was not opened. + + + + + There is a charset mismatch between stream and declared (META) encoding. + + + + + An end tag was not required. + + + + + An end tag is invalid at this position. + + + + + Represents an HTML comment. + + + + + Gets or Sets the comment text of the node. + + + + + Gets or Sets the HTML between the start and end tags of the object. In the case of a text node, it is equals to OuterHtml. + + + + + Gets or Sets the object and its content in HTML. + + + + + Represents a document with mixed code and text. ASP, ASPX, JSP, are good example of such documents. + + + + + Gets or sets the token representing code end. + + + + + Gets or sets the token representing code start. + + + + + Gets or sets the token representing code directive. + + + + + Gets or sets the token representing response write directive. + + + + + Creates a mixed code document instance. + + + + + Create a code fragment instances. + + The newly created code fragment instance. + + + + Create a text fragment instances. + + The newly created text fragment instance. + + + + Loads a mixed code document from a stream. + + The input stream. + + + + Loads a mixed code document from a stream. + + The input stream. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Loads a mixed code document from a stream. + + The input stream. + The character encoding to use. + + + + Loads a mixed code document from a stream. + + The input stream. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Loads a mixed code document from a stream. + + The input stream. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the file. + The minimum buffer size. + + + + Loads a mixed code document from a file. + + The complete file path to be read. + + + + Loads a mixed code document from a file. + + The complete file path to be read. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Loads a mixed code document from a file. + + The complete file path to be read. + The character encoding to use. + + + + Loads a mixed code document from a file. + + The complete file path to be read. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the file. + + + + Loads a mixed code document from a file. + + The complete file path to be read. + The character encoding to use. + Indicates whether to look for byte order marks at the beginning of the file. + The minimum buffer size. + + + + Loads the mixed code document from the specified TextReader. + + The TextReader used to feed the HTML data into the document. + + + + Loads a mixed document from a text + + The text to load. + + + + Saves the mixed document to the specified stream. + + The stream to which you want to save. + + + + Saves the mixed document to the specified stream. + + The stream to which you want to save. + The character encoding to use. + + + + Saves the mixed document to the specified file. + + The location of the file where you want to save the document. + + + + Saves the mixed document to the specified file. + + The location of the file where you want to save the document. + The character encoding to use. + + + + Saves the mixed document to the specified StreamWriter. + + The StreamWriter to which you want to save. + + + + Saves the mixed document to the specified TextWriter. + + The TextWriter to which you want to save. + + + + Gets the code represented by the mixed code document seen as a template. + + + + + Gets the list of code fragments in the document. + + + + + Gets the list of all fragments in the document. + + + + + Gets the encoding of the stream used to read the document. + + + + + Gets the list of text fragments in the document. + + + + + Represents a parsing error found during document parsing. + + + + + Gets the type of error. + + + + + Gets the line number of this error in the document. + + + + + Gets the column number of this error in the document. + + + + + Gets a description for the error. + + + + + Gets the the full text of the line containing the error. + + + + + Gets the absolute stream position of this error in the document, relative to the start of the document. + + + + + Represents a fragment of code in a mixed code document. + + + + + Gets the fragment code text. + + + + + Represents the type of a node. + + + + + The root of a document. + + + + + An HTML element. + + + + + An HTML comment. + + + + + A text node is always the child of an element or a document node. + + + + + Represents a list of mixed code fragments. + + + + + Gets an enumerator that can iterate through the fragment list. + + + + + Appends a fragment to the list of fragments. + + The fragment to append. May not be null. + + + + Gets an enumerator that can iterate through the fragment list. + + + + + Prepends a fragment to the list of fragments. + + The fragment to append. May not be null. + + + + Remove a fragment from the list of fragments. If this fragment was not in the list, an exception will be raised. + + The fragment to remove. May not be null. + + + + Remove all fragments from the list. + + + + + Remove a fragment from the list of fragments, using its index in the list. + + The index of the fragment to remove. + + + + Gets the Document + + + + + Gets the number of fragments contained in the list. + + + + + Gets a fragment from the list using its index. + + + + + Represents a fragment enumerator. + + + + + Advances the enumerator to the next element of the collection. + + true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. + + + + Sets the enumerator to its initial position, which is before the first element in the collection. + + + + + Gets the current element in the collection. + + + + + Gets the current element in the collection. + + + + + Represents an HTML text node. + + + + + Gets or Sets the HTML between the start and end tags of the object. In the case of a text node, it is equals to OuterHtml. + + + + + Gets or Sets the object and its content in HTML. + + + + + Gets or Sets the text of the node. + + + + diff --git a/lib/htmlagilitypack/HtmlAgilityPack.dll b/lib/htmlagilitypack/HtmlAgilityPack.dll new file mode 100644 index 000000000..a30005e94 Binary files /dev/null and b/lib/htmlagilitypack/HtmlAgilityPack.dll differ diff --git a/lib/htmlagilitypack/HtmlAgilityPack.pdb b/lib/htmlagilitypack/HtmlAgilityPack.pdb new file mode 100644 index 000000000..8a5f31a00 Binary files /dev/null and b/lib/htmlagilitypack/HtmlAgilityPack.pdb differ diff --git a/src/Orchard.Specs/Bindings/WebAppHosting.cs b/src/Orchard.Specs/Bindings/WebAppHosting.cs new file mode 100644 index 000000000..4e443c058 --- /dev/null +++ b/src/Orchard.Specs/Bindings/WebAppHosting.cs @@ -0,0 +1,70 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Web; +using System.Web.Hosting; +using Orchard.Specs.Hosting; +using Orchard.Specs.Util; +using TechTalk.SpecFlow; +using NUnit.Framework; + +namespace Orchard.Specs.Bindings { + [Binding] + public class WebAppHosting { + private WebHost _webHost; + private RequestDetails _details; + + [Given(@"I have a clean site")] + public void GivenIHaveACleanSite() { + _webHost = new WebHost(); + _webHost.Initialize("Orchard.Web", "/"); + } + + [Given(@"I have module ""(.*)""")] + public void GivenIHaveModule(string moduleName) { + _webHost.CopyExtension("Modules", moduleName); + } + + [Given(@"I have theme ""(.*)""")] + public void GivenIHaveTheme(string themeName) { + _webHost.CopyExtension("Themes", themeName); + } + + [Given(@"I have core ""(.*)""")] + public void GivenIHaveCore(string moduleName) { + _webHost.CopyExtension("Core", moduleName); + } + + [When(@"I go to ""(.*)""")] + public void WhenIGoTo(string urlPath) { + _details = _webHost.SendRequest(urlPath); + } + + [When(@"I follow ""(.*)""")] + public void WhenIFollow(string linkText) { + var doc = new HtmlAgilityPack.HtmlDocument(); + doc.Load(new StringReader(_details.ResponseText)); + var link = doc.DocumentNode.SelectNodes("//a").Single(elt => elt.InnerText == linkText); + + WhenIGoTo(link.Attributes["href"].Value); + } + + [Then(@"the status should be (.*) (.*)")] + public void ThenTheStatusShouldBe(int statusCode, string statusDescription) { + Assert.That(_details.StatusCode, Is.EqualTo(statusCode)); + Assert.That(_details.StatusDescription, Is.EqualTo(statusDescription)); + } + + [Then(@"I should see ""(.*)""")] + public void ThenIShouldSee(string text) { + Assert.That(_details.ResponseText, Is.StringContaining(text)); + } + + [Then(@"the title contains ""(.*)""")] + public void ThenTheTitleContainsText(string text) { + ScenarioContext.Current.Pending(); + } + } +} diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Content/Static.txt b/src/Orchard.Specs/Hosting/Orchard.Web/Content/Static.txt new file mode 100644 index 000000000..d2d010c8f --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Content/Static.txt @@ -0,0 +1 @@ +Hello world! \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Core/Web.config b/src/Orchard.Specs/Hosting/Orchard.Web/Core/Web.config new file mode 100644 index 000000000..8bfa88317 --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Core/Web.config @@ -0,0 +1,154 @@ + + + + + + + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Default.aspx b/src/Orchard.Specs/Hosting/Orchard.Web/Default.aspx new file mode 100644 index 000000000..87acc9c18 --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Default.aspx @@ -0,0 +1 @@ +<%@ Page AutoEventWireup="true" Inherits="Orchard.Specs.Hosting.Orchard.Web._Default, Orchard.Specs" %> \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Global.asax b/src/Orchard.Specs/Hosting/Orchard.Web/Global.asax new file mode 100644 index 000000000..99e31d82c --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Global.asax @@ -0,0 +1 @@ +<%@ Application Inherits="Orchard.Specs.Hosting.Orchard.Web.MvcApplication, Orchard.Specs" %> \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Global.asax.cs b/src/Orchard.Specs/Hosting/Orchard.Web/Global.asax.cs new file mode 100644 index 000000000..c823f0312 --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Global.asax.cs @@ -0,0 +1,45 @@ +using System; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; +using Autofac; +using Autofac.Integration.Web; +using Orchard.Environment; + +namespace Orchard.Specs.Hosting.Orchard.Web +{ + public class MvcApplication : HttpApplication + { + private static IOrchardHost _host; + + protected void Application_Start() + { + _host = OrchardStarter.CreateHost(MvcSingletons); + _host.Initialize(); + + var route = RouteTable.Routes.MapRoute("foo", "hello-world", new { controller = "Home", action = "Index" }); + route.RouteHandler = new HelloYetAgainHandler(); + + } + + protected void Application_BeginRequest() + { + _host.BeginRequest(); + } + + protected void Application_EndRequest() + { + _host.EndRequest(); + } + + protected void MvcSingletons(ContainerBuilder builder) + { + builder.RegisterInstance(ControllerBuilder.Current); + builder.RegisterInstance(RouteTable.Routes); + builder.RegisterInstance(ModelBinders.Binders); + builder.RegisterInstance(ModelMetadataProviders.Current); + builder.RegisterInstance(ViewEngines.Engines); + } + + } +} \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/HelloYetAgainHandler.cs b/src/Orchard.Specs/Hosting/Orchard.Web/HelloYetAgainHandler.cs new file mode 100644 index 000000000..0de8c71d0 --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/HelloYetAgainHandler.cs @@ -0,0 +1,21 @@ +using System; +using System.Web; +using System.Web.Routing; + +namespace Orchard.Specs.Hosting.Orchard.Web +{ + public class HelloYetAgainHandler : IRouteHandler, IHttpHandler + { + public IHttpHandler GetHttpHandler(RequestContext requestContext) + { + return this; + } + + public void ProcessRequest(HttpContext context) + { + context.Response.Write("Hello yet again"); + } + + public bool IsReusable { get { return false; } } + } +} \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Simple/Page.aspx b/src/Orchard.Specs/Hosting/Orchard.Web/Simple/Page.aspx new file mode 100644 index 000000000..43b3e5058 --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Simple/Page.aspx @@ -0,0 +1,5 @@ +<%@ Page %> + +

Hello again

+

RawUrl: <%=Page.Request.RawUrl%>

+

Moving along to next page

diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Static.txt b/src/Orchard.Specs/Hosting/Orchard.Web/Static.txt new file mode 100644 index 000000000..d2d010c8f --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Static.txt @@ -0,0 +1 @@ +Hello world! \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Themes/Web.config b/src/Orchard.Specs/Hosting/Orchard.Web/Themes/Web.config new file mode 100644 index 000000000..1bf8c875d --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Themes/Web.config @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Web.config b/src/Orchard.Specs/Hosting/Orchard.Web/Web.config new file mode 100644 index 000000000..b9ed3c6de --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Web.config @@ -0,0 +1,212 @@ + + + + + + + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/_Default.aspx.cs b/src/Orchard.Specs/Hosting/Orchard.Web/_Default.aspx.cs new file mode 100644 index 000000000..d3535b075 --- /dev/null +++ b/src/Orchard.Specs/Hosting/Orchard.Web/_Default.aspx.cs @@ -0,0 +1,20 @@ +using System; +using System.Web; +using System.Web.Mvc; +using System.Web.UI; + +namespace Orchard.Specs.Hosting.Orchard.Web { + public class _Default : Page { + public void Page_Load(object sender, EventArgs e) { + // Change the current path so that the Routing handler can correctly interpret + // the request, then restore the original path so that the OutputCache module + // can correctly process the response (if caching is enabled). + + var originalPath = Request.Path; + HttpContext.Current.RewritePath(Request.ApplicationPath, false); + IHttpHandler httpHandler = new MvcHttpHandler(); + httpHandler.ProcessRequest(HttpContext.Current); + HttpContext.Current.RewritePath(originalPath, false); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/RequestDetails.cs b/src/Orchard.Specs/Hosting/RequestDetails.cs new file mode 100644 index 000000000..5a1a8419a --- /dev/null +++ b/src/Orchard.Specs/Hosting/RequestDetails.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Orchard.Specs.Hosting +{ + [Serializable] + public class RequestDetails + { + public string Page { get; set; } + public string Query { get; set; } + + public int StatusCode { get; set; } + public string StatusDescription { get; set; } + public string ResponseText { get; set; } + } +} diff --git a/src/Orchard.Specs/Hosting/RequestExtensions.cs b/src/Orchard.Specs/Hosting/RequestExtensions.cs new file mode 100644 index 000000000..a5927608d --- /dev/null +++ b/src/Orchard.Specs/Hosting/RequestExtensions.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Web; +using System.Web.Hosting; +using Orchard.Specs.Util; + +namespace Orchard.Specs.Hosting +{ + public static class RequestExtensions + { + public static RequestDetails SendRequest(this WebHost webHost, string urlPath) + { + var physicalPath = new PathUtil(webHost.PhysicalDirectory); + + var details = new RequestDetails + { + Page = physicalPath + .Combine(urlPath.TrimStart('/', '\\')) + .GetRelativePath(physicalPath) + .ToString() + }; + + webHost.Execute(() => + { + var output = new StringWriter(); + var worker = new Worker(details, output); + HttpRuntime.ProcessRequest(worker); + details.ResponseText = output.ToString(); + }); + + return details; + } + + class Worker : SimpleWorkerRequest + { + private RequestDetails _details; + private TextWriter _output; + + public Worker(RequestDetails details, TextWriter output) + : base(details.Page, details.Query, output) + { + _details = details; + _output = output; + } + + public override void SendStatus(int statusCode, string statusDescription) + { + _details.StatusCode = statusCode; + _details.StatusDescription = statusDescription; + + base.SendStatus(statusCode, statusDescription); + } + + public override void SendResponseFromFile(string filename, long offset, long length) + { + _output.Write(File.ReadAllText(filename)); + } + } + } +} diff --git a/src/Orchard.Specs/Hosting/SerializableDelegate.cs b/src/Orchard.Specs/Hosting/SerializableDelegate.cs new file mode 100644 index 000000000..082acfd76 --- /dev/null +++ b/src/Orchard.Specs/Hosting/SerializableDelegate.cs @@ -0,0 +1,99 @@ +using System; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Orchard.Specs.Hosting { + /// + /// Makes delegates serializable where possible + /// Adapted from http://www.codeproject.com/KB/cs/AnonymousSerialization.aspx + /// + [Serializable] + public class SerializableDelegate : ISerializable where TDelegate : class + { + public TDelegate Delegate { get; private set; } + + public SerializableDelegate(TDelegate @delegate) + { + Delegate = @delegate; + } + + internal SerializableDelegate(SerializationInfo info, StreamingContext context) + { + var delegateType = (Type) info.GetValue("delegateType", typeof (Type)); + + if (info.GetBoolean("isSerializable")) + //If it's a "simple" delegate we just read it straight off + Delegate = (TDelegate) info.GetValue("delegate", delegateType); + else { + //otherwise, we need to read its anonymous class + var methodInfo = (MethodInfo) info.GetValue("method", typeof (MethodInfo)); + var anonymousClassWrapper = (AnonymousClassWrapper) info.GetValue("class", typeof (AnonymousClassWrapper)); + Delegate = (TDelegate)(object)System.Delegate.CreateDelegate(delegateType, anonymousClassWrapper.TargetInstance, methodInfo); + } + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("delegateType", Delegate.GetType()); + var untypedDelegate = (Delegate) (object) Delegate; + //If it's an "simple" delegate we can serialize it directly + if ((untypedDelegate.Target == null || untypedDelegate.Method.DeclaringType.GetCustomAttributes(typeof(SerializableAttribute), false).Length > 0) && Delegate != null) + { + info.AddValue("isSerializable", true); + info.AddValue("delegate", Delegate); + } + else { + //otherwise, serialize anonymous class + info.AddValue("isSerializable", false); + info.AddValue("method", untypedDelegate.Method); + info.AddValue("class", new AnonymousClassWrapper(untypedDelegate.Method.DeclaringType, untypedDelegate.Target)); + } + } + + [Serializable] + private class AnonymousClassWrapper : ISerializable + { + public object TargetInstance { get; private set; } + private readonly Type targetType; + + internal AnonymousClassWrapper(Type targetType, object targetInstance) + { + this.targetType = targetType; + TargetInstance = targetInstance; + } + + internal AnonymousClassWrapper(SerializationInfo info, StreamingContext context) + { + var classType = (Type) info.GetValue("classType", typeof (Type)); + TargetInstance = Activator.CreateInstance(classType); + + foreach (FieldInfo field in classType.GetFields()) { + if (typeof (Delegate).IsAssignableFrom(field.FieldType)) + //If the field is a delegate + field.SetValue(TargetInstance, ((SerializableDelegate)info.GetValue(field.Name, typeof(SerializableDelegate))).Delegate); + else if (!field.FieldType.IsSerializable) + //If the field is an anonymous class + field.SetValue(TargetInstance, ((AnonymousClassWrapper) info.GetValue(field.Name, typeof (AnonymousClassWrapper))).TargetInstance); + else + //otherwise + field.SetValue(TargetInstance, info.GetValue(field.Name, field.FieldType)); + } + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("classType", targetType); + + foreach (FieldInfo field in targetType.GetFields()) { + //See corresponding comments above + if (typeof (Delegate).IsAssignableFrom(field.FieldType)) + info.AddValue(field.Name, new SerializableDelegate((TDelegate)field.GetValue(TargetInstance))); + else if (!field.FieldType.IsSerializable) + info.AddValue(field.Name, new AnonymousClassWrapper(field.FieldType, field.GetValue(TargetInstance))); + else + info.AddValue(field.Name, field.GetValue(TargetInstance)); + } + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/WebHost.cs b/src/Orchard.Specs/Hosting/WebHost.cs new file mode 100644 index 000000000..7fe63f478 --- /dev/null +++ b/src/Orchard.Specs/Hosting/WebHost.cs @@ -0,0 +1,69 @@ +using System; +using System.IO; +using System.Reflection; +using System.Web.Hosting; +using Orchard.Specs.Util; + +namespace Orchard.Specs.Hosting +{ + public class WebHost + { + private WebHostAgent _webHostAgent; + private PathUtil _tempSite; + private PathUtil _orchardWebPath; + + public void Initialize(string templateName, string virtualDirectory) + { + _tempSite = PathUtil.GetTempFolder(); + _orchardWebPath = PathUtil.BaseDirectory.Parent.Parent.Parent.Combine("Orchard.Web"); + + var baseDir = PathUtil.BaseDirectory; + + PathUtil.BaseDirectory + .Combine("Hosting") + .Combine(templateName) + .CopyAll(SearchOption.AllDirectories, _tempSite); + + _orchardWebPath.Combine("bin").CopyAll("*.dll", _tempSite.Combine("bin")); + _orchardWebPath.Combine("bin").CopyAll("*.pdb", _tempSite.Combine("bin")); + baseDir.CopyAll("*.dll", _tempSite.Combine("bin")); + baseDir.CopyAll("*.pdb", _tempSite.Combine("bin")); + + PhysicalDirectory = _tempSite.ToString(); + VirtualDirectory = virtualDirectory; + + _webHostAgent = (WebHostAgent)ApplicationHost.CreateApplicationHost(typeof(WebHostAgent), VirtualDirectory, PhysicalDirectory); + } + + public void CopyExtension(string extensionFolder, string extensionName) { + var sourceModule = _orchardWebPath.Combine(extensionFolder).Combine(extensionName); + var targetModule = _tempSite.Combine(extensionFolder).Combine(extensionName); + sourceModule.CopyAll("*.txt", targetModule); + if (sourceModule.Combine("Views").DirectoryExists) + sourceModule.Combine("Views").CopyAll(SearchOption.AllDirectories, targetModule.Combine("Views")); + + } + + public string PhysicalDirectory { get; private set; } + public string VirtualDirectory { get; private set; } + + public void Execute(Action action) + { + var shuttleSend = new SerializableDelegate(action); + var shuttleRecv = _webHostAgent.Execute(shuttleSend); + CopyFields(shuttleRecv.Delegate.Target, shuttleSend.Delegate.Target); + } + + private static void CopyFields(T from, T to) where T : class + { + if (from == null || to == null) + return; + foreach (FieldInfo fieldInfo in from.GetType().GetFields()) + { + var value = fieldInfo.GetValue(from); + fieldInfo.SetValue(to, value); + } + } + + } +} \ No newline at end of file diff --git a/src/Orchard.Specs/Hosting/WebHostAgent.cs b/src/Orchard.Specs/Hosting/WebHostAgent.cs new file mode 100644 index 000000000..e7cb96889 --- /dev/null +++ b/src/Orchard.Specs/Hosting/WebHostAgent.cs @@ -0,0 +1,12 @@ +using System; + +namespace Orchard.Specs.Hosting { + public class WebHostAgent : MarshalByRefObject + { + public SerializableDelegate Execute(SerializableDelegate shuttle) + { + shuttle.Delegate(); + return shuttle; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Specs/Orchard.Specs.csproj b/src/Orchard.Specs/Orchard.Specs.csproj index 27f249774..84680215b 100644 --- a/src/Orchard.Specs/Orchard.Specs.csproj +++ b/src/Orchard.Specs/Orchard.Specs.csproj @@ -31,14 +31,43 @@ 4 + + False + ..\..\lib\autofac\Autofac.dll + + + False + ..\..\lib\autofac\Autofac.Integration.Web.dll + + + False + ..\..\lib\autofac\Autofac.Integration.Web.Mvc.dll + + + False + ..\..\lib\htmlagilitypack\HtmlAgilityPack.dll + + + False ..\..\lib\nunit\nunit.framework.dll + 3.5 + + + False + ..\..\lib\aspnetmvc\System.Web.Mvc.dll + True + + + 3.5 + True + 3.5 @@ -53,20 +82,89 @@ + + + + + WebHosting.feature + True + True + + + + + + + + True + True + Setup.feature + True True UsingSpecFlow.feature + + ASPXCodeBehind + + + + Always + + + Always + + + Always + + + SpecFlowSingleFileGenerator + WebHosting.feature.cs + + + SpecFlowSingleFileGenerator + Setup.feature.cs + SpecFlowSingleFileGenerator UsingSpecFlow.feature.cs + + + {8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4} + Orchard.Setup + + + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} + Orchard.Framework + + + + + + + + Always + + + Always + + + Always + + + Always + + + Always + +