Ejemplo n.º 1
0
        /// <summary>
        /// Persist the container's controls list matches the tag's attributes' state
        /// </summary>
        public void PersistControls()
        {
            var doc = Parse();

            foreach (XNode node in doc.XDocument.RootElement.AllDescendentElements)
            {
                if (!(node is XElement))
                {
                    continue;
                }

                var element = node as XElement;

                if (element.Name.HasPrefix || XDocumentHelper.IsRunAtServer(element))
                {
                    string id = XDocumentHelper.GetAttributeValueCI(element.Attributes, "id");

                    bool       checkDefaults;
                    IComponent comp = host.GetComponent(id);
                    if (comp == null)
                    {
                        // the tag does not have a matching component in the
                        // container so create one
                        comp = ProcessControl(element);

                        if (comp == null)
                        {
                            continue;
                        }

                        // assuming that we have an id already from the initial controls parse
                        host.Container.Add(comp, id);

                        // no need to check for defaults as we have a new component
                        checkDefaults = false;
                    }
                    else
                    {
                        // check if the tag's attributes and the component's attributes match
                        checkDefaults = true;
                    }

                    ProcessControlProperties(element, comp, checkDefaults);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the control tag's XElement instance.
        /// </summary>
        /// <returns>
        /// The control tag.
        /// </returns>
        /// <param name='container'>
        /// The Xelement that contains the control's XElement instance
        /// </param>
        /// <param name='id'>
        /// Identifier of the control.
        /// </param>
        XElement GetControlTag(XElement container, string id)
        {
            XElement controlTag = null;

            foreach (XNode node in container.Nodes)
            {
                if (controlTag != null)
                {
                    break;
                }
                if (node is XElement)
                {
                    XElement el     = node as XElement;
                    string   currId = XDocumentHelper.GetAttributeValueCI(el.Attributes, "id");
                    if (XDocumentHelper.IsRunAtServer(el) && (string.Compare(currId, id, true) == 0))
                    {
                        controlTag = el;
                        break;
                    }
                    controlTag = GetControlTag(el, id);
                }
            }
            return(controlTag);
        }
Ejemplo n.º 3
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;
        }
Ejemplo n.º 4
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);
            }
        }