public virtual void ClassChanged() { if (currentXmlLayoutInstance.defaultAttributeValues.ContainsKey(this.tagType)) { var defaultAttributesMerged = new AttributeDictionary(); if (this.currentXmlLayoutInstance.defaultAttributeValues[this.tagType].ContainsKey("all")) { defaultAttributesMerged = this.currentXmlLayoutInstance.defaultAttributeValues[this.tagType]["all"]; } if (currentXmlElement.classes != null && currentXmlElement.classes.Any()) { foreach (var _class in currentXmlElement.classes) { if (currentXmlLayoutInstance.defaultAttributeValues[this.tagType].ContainsKey(_class)) { defaultAttributesMerged = XmlLayoutUtilities.MergeAttributes(defaultAttributesMerged, currentXmlLayoutInstance.defaultAttributeValues[this.tagType][_class]); } } } // remove any class attributes that have been defined directly on the element defaultAttributesMerged = new AttributeDictionary(defaultAttributesMerged.Where(a => !currentXmlElement.elementAttributes.Contains(a.Key)).ToDictionary(k => k.Key, v => v.Value)); // merge in the updated class attributes and apply them //currentXmlElement.attributes = XmlLayoutUtilities.MergeAttributes(defaultAttributesMerged, elementAttributes); currentXmlElement.ApplyAttributes(defaultAttributesMerged); } }
void LoadDefaults(XmlNode node) { if (node.HasChildNodes) { foreach (XmlNode childNode in node.ChildNodes) { if (childNode.NodeType == XmlNodeType.Text || childNode.NodeType == XmlNodeType.Comment) { continue; } var type = childNode.Name.ToLower(); if (type == "tooltip") { HandleDefaultTooltipNode(childNode); continue; } if (XmlLayoutUtilities.GetXmlTagHandler(type) == null) { continue; } var attributes = childNode.Attributes.ToAttributeDictionary(); var classes = attributes.ContainsKey("class") ? attributes["class"].Split(',', ' ').Select(s => s.Trim().ToLower()).ToList() : new List <string>() { "all" }; foreach (var _class in classes) { if (!defaultAttributeValues.ContainsKey(type)) { defaultAttributeValues.Add(type, new ClassAttributeCollectionDictionary()); } if (!defaultAttributeValues[type].ContainsKey(_class)) { defaultAttributeValues[type].Add(_class, new AttributeDictionary()); } defaultAttributeValues[type][_class] = XmlLayoutUtilities.MergeAttributes(defaultAttributeValues[type][_class], attributes); defaultAttributeValues[type][_class].Remove("class"); } } } }
/// <summary> /// Convert custom attributes (that aren't found via reflection, e.g. width/height) into useable values /// </summary> /// <param name="attributes"></param> /// <returns></returns> protected AttributeDictionary HandleCustomAttributes(AttributeDictionary attributes) { var elementName = XmlLayoutUtilities.GetTagName(GetType()); //var elementName = this.GetType().Name.Replace("TagHandler", String.Empty); var customAttributes = attributes.Where(k => XmlLayoutUtilities.IsCustomAttribute(k.Key)).ToList(); foreach (var attribute in customAttributes) { var customAttribute = XmlLayoutUtilities.GetCustomAttribute(attribute.Key); if (customAttribute.RestrictToPermittedElementsOnly) { if (!customAttribute.PermittedElements.Contains(elementName, StringComparer.OrdinalIgnoreCase)) { continue; } } if (customAttribute.UsesConvertMethod) { attributes = XmlLayoutUtilities.MergeAttributes( attributes, customAttribute.Convert(attribute.Value, attributes.AsReadOnly(), this.currentXmlElement)); } if (customAttribute.UsesApplyMethod) { customAttribute.Apply(currentXmlElement, attribute.Value, attributes.AsReadOnly()); } if (customAttribute.UsesApplyMethod && !defaultAttributeValues.ContainsKey(attribute.Key)) { defaultAttributeValues.Add(attribute.Key, customAttribute.DefaultValue); } if (!customAttribute.KeepOriginalTag) { attributes.Remove(attribute.Key); } } return(attributes); }
internal void ParseNode(XmlNode xmlNode, RectTransform parent, RectTransform element = null, bool parseChildren = true, XmlElement parentXmlElement = null) { if (xmlNode.NodeType == XmlNodeType.Text || xmlNode.NodeType == XmlNodeType.Comment) { return; } var type = xmlNode.Name.ToLower(); if (type == "include") { //LoadIncludeFile(xmlNode); LoadInlineIncludeFile(xmlNode, parent); return; } if (type == "defaults") { LoadDefaults(xmlNode); return; } var attributes = xmlNode.Attributes.ToAttributeDictionary(); var tagHandler = XmlLayoutUtilities.GetXmlTagHandler(type); if (tagHandler == null) { return; } tagHandler.SetInstance(element, this); XmlElement xmlElement = null; if (element == null) { xmlElement = tagHandler.GetInstance(parent, this, attributes.GetValue("prefabPath")); if (parentXmlElement != null) { parentXmlElement.AddChildElement(xmlElement, false); } } var tagTransform = element ?? xmlElement.rectTransform; tagHandler.SetInstance(tagTransform, this); if (xmlElement != null) { xmlElement.attributes = attributes; #if !ENABLE_IL2CPP xmlElement.DataSource = xmlElement.GetAttribute("vm-dataSource"); #endif } tagHandler.Open(attributes); // if the tag handler successfully parses the child nodes, then don't attempt to parse them here // (this is only used for specific elements, e.g. Dropdown) if (tagHandler.ParseChildElements(xmlNode)) { parseChildren = false; } if (parseChildren && xmlNode.HasChildNodes) { foreach (XmlNode childNode in xmlNode.ChildNodes) { if (childNode.NodeType == XmlNodeType.Text || childNode.NodeType == XmlNodeType.CDATA) { if (!attributes.ContainsKey("text")) { attributes.Add("text", ""); } var text = childNode.NodeType == XmlNodeType.Text ? childNode.ParentNode.InnerText.Trim() : childNode.InnerText.Trim(); // Strip out any instances of multiple spaces (as in HTML) while (text.Contains(" ")) { text = text.Replace(" ", " "); } while (text.Contains("\r\n ")) { text = text.Replace("\r\n ", "\r\n"); } attributes["text"] = text; } else { tagHandler.SetInstance(tagTransform, this); ParseNode(childNode, tagHandler.transformToAddChildrenTo, null, true, parentXmlElement); } } } tagHandler.SetInstance(tagTransform, this); if (attributes.ContainsKey("id")) { if (ElementsById.ContainsKey(attributes["id"])) { Debug.LogError("[XmlLayout] Ignoring duplicate id value '" + attributes["id"] + ". Id values must be unique."); } else { if (xmlElement != null) { ElementsById.Add(attributes["id"], xmlElement); } } } // Preserve which elements have been set manually (and aren't derived from a class) if (xmlElement != null) { xmlElement.elementAttributes = attributes.Keys.ToList(); } if (defaultAttributeValues.ContainsKey(type)) { var defaultAttributesMerged = new AttributeDictionary(); if (defaultAttributeValues[type].ContainsKey("all")) { defaultAttributesMerged = defaultAttributeValues[type]["all"]; } if (attributes.ContainsKey("class")) { var classes = attributes["class"].Split(',', ' ').Select(s => s.Trim().ToLower()).ToList(); if (xmlElement != null) { xmlElement.classes = classes; } foreach (var _class in classes) { if (defaultAttributeValues[type].ContainsKey(_class)) { defaultAttributesMerged = XmlLayoutUtilities.MergeAttributes(defaultAttributesMerged, defaultAttributeValues[type][_class]); } } } attributes = XmlLayoutUtilities.MergeAttributes(defaultAttributesMerged, attributes); } if (xmlElement != null) { if (attributes.ContainsKey("hoverClass")) { var hoverClasses = attributes["hoverClass"].Split(',', ' ').Select(s => s.Trim().ToLower()).Where(c => !String.IsNullOrEmpty(c)).ToList(); xmlElement.hoverClasses = hoverClasses; } xmlElement.ApplyAttributes(attributes); } else { tagHandler.ApplyAttributes(attributes); } tagHandler.Close(); if (!tagHandler.renderElement) { tagHandler.RemoveElement(); } }