Exemple #1
0
        /// <summary>
        /// Inserts an attribute to an XElement in the source code editor.
        /// </summary>
        /// <param name='el'>
        /// the tag's XElement instance
        /// </param>
        /// <param name='key'>
        /// Key.
        /// </param>
        /// <param name='value'>
        /// Value.
        /// </param>
        public void InsertAttribute(XElement el, string key, string value)
        {
            int line   = el.Region.EndLine;
            int column = 1;
            // a preceding space or nothing
            string preambula = String.Empty;
            // a space or nothing after the last quote
            string ending = String.Empty;

            if (el.IsSelfClosing)
            {
                column = el.Region.EndColumn - 2;                 // "/>"
                // a space before the /> of the tag
                ending = " ";
            }
            else
            {
                column = el.Region.EndColumn - 1;                // ">"
                // no need for a space in the end of an openning tag
            }

            // check if a space is needed infront of the attribute
            // or the method should write at the first column of a new line
            if (column > 1)
            {
                string whatsBeforeUs = document.GetTextFromEditor(line, column - 1, line, column);
                if (!String.IsNullOrWhiteSpace(whatsBeforeUs))
                {
                    preambula = " ";
                }
            }

            // finally, insert the result
            document.InsertText(
                new TextLocation(line, column),
                String.Format("{0}{1}=\"{2}\"{3}", preambula, key, value, ending)
                );
        }
        /// <summary>
        /// Serializes a XNode to a HTML tag. This is a recursive method.
        /// </summary>
        /// <param name='node'>
        /// Node.
        /// </param>
        /// <param name='sb'>
        /// A string builder instance.
        /// </param>
        void SerializeNode(XNode node, StringBuilder sb)
        {
            prevTagLocation = node.Region.End;

            var element = node as XElement;

            if (element == null)
            {
                return;
            }

            string id = XDocumentHelper.GetAttributeValueCI(element.Attributes, "id");

            // Controls are runat="server" and have unique id in the Container
            if (element.Name.HasPrefix || XDocumentHelper.IsRunAtServer(element))
            {
                IComponent component = host.GetComponent(id);

                // HTML controls, doesn't need special rendering
                var control = component as Control;

                // genarete placeholder
                if (control != null)
                {
                    StringWriter   strWriter = new StringWriter();
                    HtmlTextWriter writer    = new HtmlTextWriter(strWriter);
                    control.RenderControl(writer);
                    writer.Close();
                    strWriter.Flush();
                    sb.Append(strWriter.ToString());
                    strWriter.Close();
                    if (!element.IsSelfClosing)
                    {
                        prevTagLocation = element.ClosingTag.Region.End;
                    }
                    return;
                }
            }

            // strip script tags
            if (element.Name.Name.ToLower() == "script")
            {
                return;
            }

            // the node is a html element
            sb.AppendFormat("<{0}", element.Name.FullName);

            // print the attributes
            foreach (MonoDevelop.Xml.StateEngine.XAttribute attr in element.Attributes)
            {
                string name = attr.Name.Name.ToLower();
                // strip runat and on* event attributes
                if ((name != "runat") && (name.Substring(0, 2).ToLower() != "on"))
                {
                    sb.AppendFormat(" {0}=\"{1}\"", attr.Name.FullName, attr.Value);
                }
            }

            if (element.IsSelfClosing)
            {
                sb.Append(" />");
            }
            else
            {
                sb.Append(">");

                // we are currentyl on the head tag
                // add designer content - js and css
                if (element.Name.Name.ToLower() == "head")
                {
                    sb.Append(designerContext);
                }

                if (element.Name.Name.ToLower() == "body")
                {
                    GetDesignerInitParams(sb);
                }

                // serializing the childnodes if any
                foreach (MonoDevelop.Xml.StateEngine.XNode nd in element.Nodes)
                {
                    // get the text before the openning tag of the child element
                    sb.Append(document.GetTextFromEditor(prevTagLocation, nd.Region.Begin));
                    // and the element itself
                    SerializeNode(nd, sb);
                }

                // printing the text after the closing tag of the child elements
                int lastChildEndLine   = element.Region.EndLine;
                int lastChildEndColumn = element.Region.EndColumn;

                // if the element have 1+ children
                if (element.LastChild != null)
                {
                    var lastChild = element.LastChild as MonoDevelop.Xml.StateEngine.XElement;
                    // the last child is an XML tag
                    if (lastChild != null)
                    {
                        // the tag is selfclosing
                        if (lastChild.IsSelfClosing)
                        {
                            lastChildEndLine   = lastChild.Region.EndLine;
                            lastChildEndColumn = lastChild.Region.EndColumn;
                            // the tag is not selfclosing and has a closing tag
                        }
                        else if (lastChild.ClosingTag != null)
                        {
                            lastChildEndLine   = lastChild.ClosingTag.Region.EndLine;
                            lastChildEndColumn = lastChild.ClosingTag.Region.EndColumn;
                        }
                        else
                        {
                            // TODO: the element is not closed. Warn the user
                        }
                        // the last child is not a XML element. Probably AspNet tag. TODO: find the end location of that tag
                    }
                    else
                    {
                        lastChildEndLine = element.LastChild.Region.EndLine;
                        lastChildEndLine = element.LastChild.Region.EndLine;
                    }
                }

                if (element.ClosingTag != null)
                {
                    sb.Append(document.GetTextFromEditor(new TextLocation(lastChildEndLine, lastChildEndColumn), element.ClosingTag.Region.Begin));
                    prevTagLocation = element.ClosingTag.Region.End;
                }
                else
                {
                    // TODO: the element is not closed. Warn the user
                }

                sb.AppendFormat("</{0}>", element.Name.FullName);
            }
        }