/// <summary> /// /// </summary> /// <param name="src">image source / url</param> /// <param name="alt">alternate text for image</param> public void InsertImage(string src, string alt) { try { using (new UndoUnit(Document, "Insert Image")) { // obtain a reference to the body node HtmlDomNode bodyNode = (HtmlDomNode)Document.body; HtmlImageElement img = (HtmlImageElement)Document.createElement("IMG"); img.src = src; img.alt = alt; // table processing all complete so insert into the DOM HtmlSelection selection = Document.selection; HtmlTextRange textRange = SelectionHelper.GetTextRange(Document); if (textRange != null) { textRange.pasteHTML(((HtmlElement)img).outerHTML);//"<img src=\"" + src + "\" alt=\"" + alt + "\">"); } else { HtmlControlRange controlRange = SelectionHelper.GetAllControls(Document); if (controlRange != null) { // overwrite any controls the user has selected try { // clear the selection and insert the table // only valid if multiple selection is enabled for (int idx = 1; idx < controlRange.length; idx++) { controlRange.remove(idx); } controlRange.item(0).outerHTML = ((HtmlElement)img).outerHTML; // this should work with initial count set to zero // controlRange.add((HtmlControlElement)table); } catch (Exception ex) { throw new HtmlEditorException("Cannot Delete all previously Controls selected.", "InsertImage", ex); } } else { // insert the table at the end of the HTML HtmlDomNode imgNode = (HtmlDomNode)img; bodyNode.appendChild(imgNode); } } } } catch (Exception ex) { throw new HtmlEditorException("Unable to insert image.", "InsertImage", ex); } }
private static string getNode(mshtml.IHTMLElement node) { string nodeExpr = node.tagName; if (nodeExpr == null) // Eg. node = #text { return(null); } if (node.id != "" && node.id != null) { nodeExpr += "[@id='" + node.id + "']"; // We don't really need to go back up to //HTML, since IDs are supposed // to be unique, so they are a good starting point. return("/" + nodeExpr); } // Find rank of node among its type in the parent int rank = 1; mshtml.IHTMLDOMNode nodeDom = node as mshtml.IHTMLDOMNode; mshtml.IHTMLDOMNode psDom = nodeDom.previousSibling; mshtml.IHTMLElement ps = psDom as mshtml.IHTMLElement; while (ps != null) { if (ps.tagName == node.tagName) { rank++; } psDom = psDom.previousSibling; ps = psDom as mshtml.IHTMLElement; } if (rank > 1) { nodeExpr += "[" + rank + "]"; } else { // First node of its kind at this level. Are there any others? mshtml.IHTMLDOMNode nsDom = nodeDom.nextSibling; mshtml.IHTMLElement ns = nsDom as mshtml.IHTMLElement; while (ns != null) { if (ns.tagName == node.tagName) { // Yes, mark it as being the first one nodeExpr += "[1]"; break; } nsDom = nsDom.nextSibling; ns = nsDom as mshtml.IHTMLElement; } } return(nodeExpr); }
public void ColumnMoveRight() { // see if a table selected or insertion point inside a table HtmlTable table = null; HtmlTableRow row = null; HtmlTableCell cell = null; GetTableElement(out table, out row, out cell); if (table != null && row != null && cell != null) { int index = cell.cellIndex; if (index >= row.cells.length - 1) { return; } try { using (new SelectionPreserver(GetMarkupRange())) { using (new UndoUnit(Document, "Table column move right")) { for (int i = 0; i < table.rows.length; i++) { HtmlTableRow r = table.rows.item(i); HtmlDomNode c1 = r.cells.item(index); HtmlDomNode c2 = r.cells.item(index + 1); c1.swapNode(c2); } } } } catch (Exception ex) { throw new HtmlEditorException("Unable to insert a new Row", "TableinsertRow", ex); } } else { throw new HtmlEditorException("Row not currently selected within the table", "TableInsertRow"); } }
static HObject ToHNode(mshtml.IHTMLDOMNode node) { if (node == null) { return(null); } //dynamic x = element; //Console.WriteLine(MetaTech.Library.ReflectionExtension.ReflectionHelper._P<object>(element.DomElement, "textContent")); //var span = element.DomElement as mshtml.IHTMLDOMNode; switch (node.nodeType) { case 3: return(new HText(node.nodeValue)); case 1: { var element = node as mshtml.IHTMLElement; var childs = node.childNodes as System.Collections.IEnumerable; return(new HElement(element.tagName, ToHAttribute("id", element.id), ToHAttribute("class", element.className), ToHAttribute("src", element.getAttribute("src")), //ToHAttribute("style", element.getAttribute("style")), childs != null ? childs.OfType <mshtml.IHTMLDOMNode>().Select(child => ToHNode(child)) : null )); } default: return(null); } ////Console.WriteLine(x.textContent); ////mshtml.HTMLTextAreaElement //return new HElement(element.TagName, // ToHAttribute("id", element.Id), // ToHAttribute("name", element.Name), // ToHAttribute("class", element.GetAttribute("class")), // ToHAttribute("style", element.Style), // element.Children.OfType<HtmlElement>().Select(e => ToHElement(e)), // ToHAttribute("type", element.DomElement._f(_=>_.GetType().FullName)) //); }
public string DataFromHtmlElement(HtmlElement e) { mshtml.IHTMLDOMNode node = e.DomElement as mshtml.IHTMLDOMNode; node = node.firstChild; string s = ""; while (node != null) { if (node.nodeType == 3) { s += node.nodeValue as string; node = node.nextSibling; } else { node = node.nextSibling; } } return(s); }
/// <summary> /// called when double shift-key press is detected /// </summary> /// <param name="currentElement"></param> private void analyzeElement(HtmlElement currentElement) { string tag = "", type = ""; elementNameTextBox.Text = ""; selectedElementListView.Items.Clear(); List <DAL.RecognitionProperty> props = new List <DAL.RecognitionProperty>(); WatiN.Core.Native.InternetExplorer.IEElement element = new WatiN.Core.Native.InternetExplorer.IEElement(currentElement.DomElement); mshtml.IHTMLDOMNode nd = (mshtml.IHTMLDOMNode)element.AsHtmlElement; mshtml.IHTMLAttributeCollection attribs = (mshtml.IHTMLAttributeCollection)nd.attributes; if ((currentElement.TagName != null) && (currentElement.TagName.Length > 0)) { props.Add(new DAL.RecognitionProperty("Tag", currentElement.TagName, 20)); ListViewItem item = selectedElementListView.Items.Add("Tag"); item.SubItems.Add(currentElement.TagName); item.SubItems.Add("20").Tag = 20; tag = currentElement.TagName; } if ((currentElement.OuterText != null) && (currentElement.OuterText.Length > 0)) { props.Add(new DAL.RecognitionProperty("OuterText", currentElement.OuterText, 20)); ListViewItem item = selectedElementListView.Items.Add("OuterText"); item.SubItems.Add(currentElement.OuterText); item.SubItems.Add("20").Tag = 20; } // add containing frame property if (currentElement.Document.Window.WindowFrameElement != null) { props.Add(new DAL.RecognitionProperty("FrameContainer", currentElement.Document.Window.WindowFrameElement.Name, 20)); ListViewItem xitem = selectedElementListView.Items.Add("FrameContainer"); xitem.SubItems.Add(currentElement.Document.Window.WindowFrameElement.Name); xitem.SubItems.Add("20").Tag = 20; } if ((currentElement.InnerText != null) && (currentElement.InnerText.Length > 0)) { props.Add(new DAL.RecognitionProperty("InnerText", currentElement.InnerText, 20)); ListViewItem item = selectedElementListView.Items.Add("InnerText"); item.SubItems.Add(currentElement.InnerText); item.SubItems.Add("20").Tag = 20; } foreach (mshtml.IHTMLDOMAttribute2 att in attribs) { if (((mshtml.IHTMLDOMAttribute)att).specified) { props.Add(new DAL.RecognitionProperty(att.name, att.value, 10)); ListViewItem item = selectedElementListView.Items.Add(att.name); item.SubItems.Add(att.value); if (string.Compare(att.name, "name", true) == 0) { item.SubItems.Add("50").Tag = 50; } else if (string.Compare(att.name, "id", true) == 0) { item.SubItems.Add("100").Tag = 100; } else if (string.Compare(att.name, "href", true) == 0) { item.SubItems.Add("45").Tag = 45; } else { item.SubItems.Add("10").Tag = 10; } if (string.Compare(att.name, "type", true) == 0) { type = att.value; } } } /** * if element has no id/name * 1. determined position in parent children by counting the depth of nextSibling loop * 2. push count to stack * 3. then check if parent have id attribute: if true then push id to stack else if parent=null stop else repeat 1-3 * 4. serialize stack content and create a fake attribute: indirectPath => [stack contents] with the format * <id:<id>|<name:<name>> <children indexes seperated by space> */ if ((currentElement.Name == "") && (currentElement.Id == null)) { //int position = -1; StringBuilder stack = new StringBuilder(); var elm = currentElement; do { if (elm.Parent != null) { for (var i = 0; i < elm.Parent.Children.Count; i++) { if (elm.Parent.Children[i].Equals(elm)) { stack.Insert(0, i.ToString() + " "); break; } } elm = elm.Parent; } else { break; } } while ((elm != null) && (elm.Id == null) && (elm.Name == "")); if ((elm != null) && (elm.Id != null)) { stack.Insert(0, "id:" + elm.Id + " "); } else if ((elm != null) && (elm.Name != "")) { stack.Insert(0, "name:" + elm.Name + " "); } //MessageBox.Show(stack.ToString().TrimEnd(' ')); if (stack[0] > '9') { props.Add(new DAL.RecognitionProperty("indirectPath", stack.ToString().TrimEnd(' '), 80)); ListViewItem item = selectedElementListView.Items.Add("indirectPath"); item.SubItems.Add(stack.ToString().TrimEnd(' ')); item.SubItems.Add("80").Tag = 80; } } if (string.Compare(tag, "input", true) == 0) { this.currentElementType = type == "" ? DAL.ElementType.TEXT : DAL.StringToElementType(type); } else if (string.Compare(tag, "textarea", true) == 0) { this.currentElementType = DAL.ElementType.AREA; } else if (string.Compare(tag, "select", true) == 0) { this.currentElementType = DAL.ElementType.SELECT; } else { this.currentElementType = DAL.ElementType.NONE; } }
// function to insert a basic table // will honour the existing table if passed in private void ProcessTable(HtmlTable table, HtmlTableProperty tableProperties) { try { using (new UndoUnit(Document, "Table add/modify")) { // obtain a reference to the body node and indicate table present HtmlDomNode bodyNode = (HtmlDomNode)Document.body; bool tableCreated = false; MsHtmlWrap.MarkupRange targetMarkupRange = null; // ensure a table node has been defined to work with if (table == null) { // create the table and indicate it was created table = (HtmlTable)Document.createElement("TABLE"); tableCreated = true; //markup range for selecting first cell after table creation targetMarkupRange = GetMarkupRange(); } // define the table border, width, cell padding and spacing table.border = tableProperties.BorderSize; if (tableProperties.TableWidth > 0) { table.width = (tableProperties.TableWidthMeasurement == MeasurementOption.Pixel) ? string.Format("{0}", tableProperties.TableWidth) : string.Format("{0}%", tableProperties.TableWidth); } else { table.width = string.Empty; } if (tableProperties.TableAlignment != HorizontalAlignOption.Default) { table.align = tableProperties.TableAlignment.ToString().ToLower(); } else { table.align = string.Empty; } table.cellPadding = tableProperties.CellPadding.ToString(); table.cellSpacing = tableProperties.CellSpacing.ToString(); // define the given table caption and alignment string caption = tableProperties.CaptionText; HtmlTableCaption tableCaption = table.caption; if (caption != null && caption != string.Empty) { // ensure table caption correctly defined if (tableCaption == null) { tableCaption = table.createCaption(); } ((HtmlElement)tableCaption).innerText = caption; if (tableProperties.CaptionAlignment != HorizontalAlignOption.Default) { tableCaption.align = tableProperties.CaptionAlignment.ToString().ToLower(); } if (tableProperties.CaptionLocation != VerticalAlignOption.Default) { tableCaption.vAlign = tableProperties.CaptionLocation.ToString().ToLower(); } } else { // if no caption specified remove the existing one if (tableCaption != null) { // prior to deleting the caption the contents must be cleared ((HtmlElement)tableCaption).innerText = null; table.deleteCaption(); } } // determine the number of rows one has to insert int numberRows, numberCols; if (tableCreated) { numberRows = Math.Max((int)tableProperties.TableRows, 1); } else { numberRows = Math.Max((int)tableProperties.TableRows, 1) - (int)table.rows.length; } // layout the table structure in terms of rows and columns table.cols = (int)tableProperties.TableColumns; if (tableCreated) { // this section is an optimization based on creating a new table // the section below works but not as efficiently numberCols = Math.Max((int)tableProperties.TableColumns, 1); // insert the appropriate number of rows HtmlTableRow tableRow; for (int idxRow = 0; idxRow < numberRows; idxRow++) { tableRow = table.insertRow(-1) as HtmlTableRow; // add the new columns to the end of each row for (int idxCol = 0; idxCol < numberCols; idxCol++) { tableRow.insertCell(-1); } } } else { // if the number of rows is increasing insert the decrepency if (numberRows > 0) { // insert the appropriate number of rows for (int idxRow = 0; idxRow < numberRows; idxRow++) { table.insertRow(-1); } } else { // remove the extra rows from the table for (int idxRow = numberRows; idxRow < 0; idxRow++) { table.deleteRow(table.rows.length - 1); } } // have the rows constructed // now ensure the columns are correctly defined for each row HtmlElementCollection rows = table.rows; foreach (HtmlTableRow tableRow in rows) { numberCols = Math.Max((int)tableProperties.TableColumns, 1) - (int)tableRow.cells.length; if (numberCols > 0) { // add the new column to the end of each row for (int idxCol = 0; idxCol < numberCols; idxCol++) { tableRow.insertCell(-1); } } else { // reduce the number of cells in the given row // remove the extra rows from the table for (int idxCol = numberCols; idxCol < 0; idxCol++) { tableRow.deleteCell(tableRow.cells.length - 1); } } } } // if the table was created then it requires insertion into the DOM // otherwise property changes are sufficient if (tableCreated) { // table processing all complete so insert into the DOM HtmlDomNode tableNode = (HtmlDomNode)table; HtmlElement tableElement = (HtmlElement)table; HtmlSelection selection = Document.selection; HtmlTextRange textRange = SelectionHelper.GetTextRange(Document); // final insert dependant on what user has selected if (textRange != null) { // text range selected so overwrite with a table try { string selectedText = textRange.text; if (selectedText != null) { // place selected text into first cell HtmlTableRow tableRow = table.rows.item(0, null) as HtmlTableRow; (tableRow.cells.item(0, null) as HtmlElement).innerText = selectedText; } textRange.pasteHTML(tableElement.outerHTML); } catch (Exception ex) { throw new HtmlEditorException("Invalid Text selection for the Insertion of a Table.", "ProcessTable", ex); } } else { HtmlControlRange controlRange = SelectionHelper.GetAllControls(Document); if (controlRange != null) { // overwrite any controls the user has selected try { // clear the selection and insert the table // only valid if multiple selection is enabled for (int idx = 1; idx < controlRange.length; idx++) { controlRange.remove(idx); } controlRange.item(0).outerHTML = tableElement.outerHTML; // this should work with initial count set to zero // controlRange.add((HtmlControlElement)table); } catch (Exception ex) { throw new HtmlEditorException("Cannot Delete all previously Controls selected.", "ProcessTable", ex); } } else { // insert the table at the end of the HTML bodyNode.appendChild(tableNode); } } } else { // table has been correctly defined as being the first selected item // need to remove other selected items HtmlControlRange controlRange = SelectionHelper.GetAllControls(Document); if (controlRange != null) { // clear the controls selected other than than the first table // only valid if multiple selection is enabled for (int idx = 1; idx < controlRange.length; idx++) { controlRange.remove(idx); } } } //if table created, then focus the first cell if (tableCreated) { try { HtmlElement cell = targetMarkupRange.GetFirstElement(e => e is HtmlTableCell, true); if (cell != null) { SelectCell(cell as HtmlTableCell); } } catch (Exception e) { Log.Write(e); } } } } catch (Exception ex) { // throw an exception indicating table structure change error throw new HtmlEditorException("Unable to modify Html Table properties.", "ProcessTable", ex); } } //ProcessTable