Пример #1
0
        /// <summary>
        /// Removes a control tag from the source code editor
        /// </summary>
        /// <param name='id'>
        /// Identifier of the control.
        /// </param>
        public void RemoveControlTag(string id)
        {
            if (id == null)
            {
                throw new ArgumentNullException("Cannot find component by an empty string");
            }

            IComponent comp = host.GetComponent(id);

            if (comp == null)
            {
                throw new InvalidOperationException("Component with that name doesn't exists: " + id);
            }

            XDocument doc = document.Parse().XDocument;
            XElement  tag = GetControlTag(doc.RootElement, id);

            if (tag == null)
            {
                throw new InvalidOperationException("The the tag for the component was not found. ID: " + id);
            }

            DomRegion region;

            if (tag.IsSelfClosing)
            {
                region = tag.Region;
            }
            else if (tag.IsClosed)
            {
                region = new DomRegion(tag.Region.Begin, tag.ClosingTag.Region.End);
            }
            else
            {
                throw new InvalidOperationException("The tag has no closing tag. It cannot be removed");
            }

            document.RemoveText(region);
        }
Пример #2
0
        /// <summary>
        /// Checks the document for control tags, creates components and adds the to the IContainer.
        /// Adds an id attributes to tags that are server controls but doesn't have an id attribute.
        /// </summary>
        void ParseControls()
        {
            // no need to serialize the document, if we add just an id attribute to a control
            suppressSerialization = true;

            // if an id tag was added the document changes
            // so we parse the document each time it does
            do
            {
                // get a fresh new AspNetParsedDocument
                var doc = Parse();

                // go through all the nodes of the document
                foreach (XNode node in doc.XDocument.RootElement.AllDescendentElements)
                {
                    // if a node is not a XElement, no need to check if it's a control
                    if (!(node is XElement))
                    {
                        continue;
                    }

                    var element = node as XElement;

                    // the controls have a tag prefix or runat="server" attribute
                    if (element.Name.HasPrefix || XDocumentHelper.IsRunAtServer(element))
                    {
                        string id = XDocumentHelper.GetAttributeValueCI(element.Attributes, "id");

                        // check the DesignContainer if a component for that node already exists
                        if (host.GetComponent(id) == null)
                        {
                            // create a component of type depending of the element
                            IComponent comp = ProcessControl(element);

                            if (comp == null)
                            {
                                continue;
                            }

                            // add id to the component, for later recognition if it has no ID attribute
                            if (String.IsNullOrEmpty(id))
                            {
                                var nameServ = host.GetService(typeof(INameCreationService)) as INameCreationService;
                                if (nameServ == null)
                                {
                                    throw new Exception("Could not obtain INameCreationService from the DesignerHost.");
                                }

                                // insert the attribute to the element
                                host.AspNetSerializer.SetAttribtue(element, "id", nameServ.CreateName(host.Container, comp.GetType()));
                                updateEditorContent.WaitOne();                                  // wait until the changes have been applied to the document
                                break;
                            }

                            // we have a control component, add it to the container
                            this.host.Container.Add(comp, id);
                            // and parse its attributes for component properties
                            ProcessControlProperties(element, comp);
                        }
                    }
                }
            } while (txtDocDirty);

            suppressSerialization = false;
        }
Пример #3
0
        /// <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);
            }
        }