示例#1
0
 public bool TryGetValue(string key, out string value)
 {
     // do not use trygetvalue from dictionary. We need default handling in Get
     value = Get(key);
     return(value != null ||
            Attributes.ContainsKey(DomData.TokenID(key, true)));
 }
示例#2
0
        /// <summary>
        /// Sets style setting with no parsing
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void SetRaw(string name, string value)
        {
            bool hadStyles = HasStyles;

            Styles[DomData.TokenID(name, true)] = value;
            UpdateIndex(hadStyles);
        }
示例#3
0
        bool ICollection <KeyValuePair <string, string> > .Remove(KeyValuePair <string, string> item)
        {
            //if (ContainsKey(item.Key)
            //    &&  Attributes[DomData.TokenID(item.Key,true)] == item.Value)
            //{
            //    return Remove(item.Key);
            //}
            //else
            //{
            //    return false;
            //}

            int index = InnerKeys.IndexOf(DomData.TokenID(item.Key, true));

            if (index < 0)
            {
                return(false);
            }
            else
            {
                if (InnerValues[index] == item.Value)
                {
                    return(Remove(item.Key));
                }
                else
                {
                    return(false);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Returns all the keys that should be in the index for this item (keys for class, tag, attributes, and id)
        /// </summary>
        /// <returns></returns>
        public IEnumerable <string> IndexKeys()
        {
            string path = Path;

            yield return("" + DomData.indexSeparator + path);

            yield return(IndexKey("+", nodeNameID, path));

            string id = Id;

            if (!String.IsNullOrEmpty(id))
            {
                yield return(IndexKey("#", DomData.TokenID(id), path));
            }
            if (HasClasses)
            {
                foreach (ushort clsId in _Classes)
                {
                    yield return(IndexKey(".", clsId, path));
                }
            }
            if (HasAttributes)
            {
                foreach (ushort attrId in Attributes.GetAttributeIds())
                {
                    yield return(IndexKey("!", attrId, path));
                }
            }
        }
示例#5
0
        public bool AddClass(string name)
        {
            bool result          = false;
            bool addedFirstClass = false;

            foreach (string cls in name.SplitClean())
            {
                if (!HasClass(cls))
                {
                    if (_Classes == null)
                    {
                        _Classes = new List <ushort>();
                    }
                    ushort tokenId = DomData.TokenID(cls);
                    addedFirstClass = !HasClasses;
                    _Classes.Add(tokenId);
                    if (!IsDisconnected)
                    {
                        Document.AddToIndex(IndexKey(".", tokenId), this);
                    }

                    result = true;
                }
                if (addedFirstClass && !IsDisconnected)
                {
                    // Must index the attributes for search just on attribute too
                    Document.AddToIndex(Attributes.IndexKey(DomData.ClassAttrId), this);
                }
            }
            return(result);
        }
示例#6
0
 protected IEnumerable <KeyValuePair <string, string> > GetAttributes()
 {
     foreach (var kvp in Attributes)
     {
         yield return(new KeyValuePair <string, string>(DomData.TokenName(kvp.Key), kvp.Value));
     }
 }
示例#7
0
 protected IEnumerable <KeyValuePair <string, string> > stylesEnumerable()
 {
     foreach (var kvp in Styles)
     {
         yield return(new KeyValuePair <string, string>(DomData.TokenName(kvp.Key), kvp.Value));
     }
     yield break;
 }
示例#8
0
        internal string IndexKey(string prefix, ushort keyTokenId, string path)
        {
#if DEBUG_PATH
            return(prefix + DomData.TokenName(keyTokenId) + DomData.indexSeparator + path);
#else
            return(prefix + (char)keyTokenId + DomData.indexSeparator + path);
#endif
        }
示例#9
0
        internal string IndexKey(string prefix, string key, string path)
        {
#if DEBUG_PATH
            return(prefix + key + DomData.indexSeparator + path);
#else
            return(IndexKey(prefix, DomData.TokenID(key), path));
#endif
        }
示例#10
0
        public string IndexKey(ushort attrId)
        {
#if DEBUG_PATH
            return("!" + DomData.TokenName(attrId) + DomData.indexSeparator + Owner.Path);
#else
            return("!" + (char)attrId + DomData.indexSeparator + Owner.Path);
#endif
        }
示例#11
0
 protected string Get(string name)
 {
     name = name.CleanUp();
     if (string.IsNullOrEmpty(name))
     {
         return(null);
     }
     return(Get(DomData.TokenID(name, true)));
 }
示例#12
0
 /// <summary>
 /// Adding an attribute implementation
 /// </summary>
 /// <param name="name"></param>
 /// <param name="value"></param>
 protected void Set(string name, string value)
 {
     if (String.IsNullOrEmpty(name))
     {
         throw new ArgumentException("Cannot set an attribute with no name.");
     }
     name = name.CleanUp();
     Set(DomData.TokenID(name, true), value);
 }
示例#13
0
        void ICollection <KeyValuePair <string, string> > .CopyTo(KeyValuePair <string, string>[] array, int arrayIndex)
        {
            array = new KeyValuePair <string, string> [Styles.Count];
            int index = 0;

            foreach (var kvp in Styles)
            {
                array[index++] = new KeyValuePair <string, string>(DomData.TokenName(kvp.Key), kvp.Value);
            }
        }
示例#14
0
        /// <summary>
        /// Sets a boolean only attribute having no value
        /// </summary>
        /// <param name="name"></param>
        internal void SetBooleanAttribute(string name)
        {
            ushort tokenId = DomData.TokenID(name, true);

            if (!Attributes.ContainsKey(tokenId))
            {
                AddToIndex(tokenId);
            }
            Attributes[tokenId] = null;
        }
示例#15
0
 protected IEnumerable <KeyValuePair <string, string> > GetAttributes()
 {
     //foreach (var kvp in Attributes)
     //{
     //    yield return new KeyValuePair<string, string>(DomData.TokenName(kvp.Key).ToLower(), kvp.Value);
     //}
     for (int i = 0; i < InnerKeys.Count; i++)
     {
         yield return(new KeyValuePair <string, string>(DomData.TokenName(InnerKeys[i]).ToLower(), InnerValues[i]));
     }
 }
示例#16
0
 bool ICollection <KeyValuePair <string, string> > .Remove(KeyValuePair <string, string> item)
 {
     if (ContainsKey(item.Key) &&
         Attributes[DomData.TokenID(item.Key, true)] == item.Value)
     {
         return(Remove(item.Key));
     }
     else
     {
         return(false);
     }
 }
示例#17
0
        public void TestDomReadWriteResourceCreateWithArticleResourceWithResourceLinkage()
        {
            // Arrange
            var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes;

            var articleResourceType   = serviceModel.GetResourceType <Article>();
            var articleTitleAttribute = articleResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Article>(x => x.Title));

            var commentResourceType = serviceModel.GetResourceType <Comment>();
            var personResourceType  = serviceModel.GetResourceType <Person>();

            var expectedArticle  = ApiSampleData.ArticleResourceWithResourceLinkage;
            var expectedAuthor   = ApiSampleData.PersonResource;
            var expectedComment1 = ApiSampleData.CommentResource1;
            var expectedComment2 = ApiSampleData.CommentResource2;

            // Act
            var actual = DomReadWriteResource.Create(
                DomType.CreateFromResourceType(articleResourceType),
                DomId.CreateFromApiResourceIdentity(articleResourceType, expectedArticle),
                DomAttributes.Create(
                    DomAttribute.CreateFromApiResource(articleTitleAttribute, expectedArticle)),
                DomReadWriteRelationships.Create(
                    DomReadWriteRelationship.Create(ApiSampleData.ArticleToAuthorRel,
                                                    DomReadWriteLinks.Create(
                                                        DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleToRelationshipsToAuthorHRef)),
                                                        DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.ArticleToAuthorHRef))),
                                                    DomData.CreateFromResourceIdentifier(
                                                        DomReadWriteResourceIdentifier.Create(
                                                            DomType.CreateFromResourceType(personResourceType),
                                                            DomId.CreateFromApiResourceIdentity(personResourceType, expectedAuthor)))),
                    DomReadWriteRelationship.Create(ApiSampleData.ArticleToCommentsRel,
                                                    DomReadWriteLinks.Create(
                                                        DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleToRelationshipsToCommentsHRef)),
                                                        DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.ArticleToCommentsHRef))),
                                                    DomDataCollection.CreateFromResourceIdentifiers(
                                                        DomReadWriteResourceIdentifier.Create(
                                                            DomType.CreateFromResourceType(commentResourceType),
                                                            DomId.CreateFromApiResourceIdentity(commentResourceType, expectedComment1)),
                                                        DomReadWriteResourceIdentifier.Create(
                                                            DomType.CreateFromResourceType(commentResourceType),
                                                            DomId.CreateFromApiResourceIdentity(commentResourceType, expectedComment2))))),
                DomReadWriteLinks.Create(
                    DomReadWriteLink.Create(Keywords.Canonical, DomHRef.Create(ApiSampleData.ArticleHRef)),
                    DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleHRef))),
                DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta));

            this.OutputDomTree(actual);

            // Assert
            DomReadWriteResourceAssert.Equal(expectedArticle, actual);
        }
示例#18
0
        public override string ToString()
        {
            string style = String.Empty;

            if (HasStyles)
            {
                foreach (var kvp in Styles)
                {
                    style += DomData.TokenName(kvp.Key) + ":" + kvp.Value + ";";
                }
            }
            return(style);
        }
示例#19
0
        protected string Get(string name)
        {
            string value;

            if (Styles.TryGetValue(DomData.TokenID(name, true), out value))
            {
                return(value);
            }
            else
            {
                return(null);
            }
        }
示例#20
0
        void ICollection <KeyValuePair <string, string> > .CopyTo(KeyValuePair <string, string>[] array, int arrayIndex)
        {
            //array = new KeyValuePair<string, string>[Attributes.Count];
            //int index = 0;
            //foreach (var kvp in Attributes)
            //{
            //    array[index++] = new KeyValuePair<string, string>(DomData.TokenName(kvp.Key), kvp.Value);
            //}

            array = new KeyValuePair <string, string> [InnerKeys.Count];
            for (int index = 0; index < InnerKeys.Count; index++)
            {
                array[index++] = new KeyValuePair <string, string>(DomData.TokenName(InnerKeys[index]), InnerValues[index]);
            }
        }
示例#21
0
        bool ICollection <KeyValuePair <string, string> > .Contains(KeyValuePair <string, string> item)
        {
            //return ContainsKey(item.Key)
            //&& Attributes[DomData.TokenID(item.Key,true)] == item.Value;

            int index = InnerKeys.IndexOf(DomData.TokenID(item.Key, true));

            if (index < 0)
            {
                return(false);
            }
            else
            {
                return(InnerValues[index] == item.Value);
            }
        }
示例#22
0
        public override bool RemoveAttribute(string name)
        {
            if (_Attributes == null)
            {
                return(false);
            }
            ushort tokenId = DomData.TokenID(name, true);

            if (tokenId == DomData.ClassAttrId)
            {
                _Classes = null;
                return(true);
            }
            else
            {
                return(Attributes.Remove(name.ToLower()));
            }
        }
示例#23
0
        public bool RemoveClass(string name)
        {
            bool result = false;

            foreach (string cls in name.SplitClean())
            {
                if (HasClass(cls))
                {
                    ushort tokenId = DomData.TokenID(cls);
                    _Classes.Remove(tokenId);
                    if (!IsDisconnected)
                    {
                        Document.RemoveFromIndex(IndexKey(".", tokenId));
                        if (!HasClasses)
                        {
                            Document.RemoveFromIndex(Attributes.IndexKey(DomData.ClassAttrId));
                        }
                    }

                    result = true;
                }
            }
            return(result);
        }
示例#24
0
        bool ICollection <KeyValuePair <string, string> > .Remove(KeyValuePair <string, string> item)
        {
            var kvp = new KeyValuePair <ushort, string>(DomData.TokenID(item.Key), item.Value);

            return(Styles.Remove(kvp));
        }
示例#25
0
 public override bool TryGetAttribute(string name, out string value)
 {
     return(TryGetAttribute(DomData.TokenID(name, true), out value));
 }
示例#26
0
 /// <summary>
 /// Returns the value of an attribute or a default value if it could not be found.
 /// </summary>
 /// <param name="name"></param>
 /// <returns></returns>
 public override string GetAttribute(string name, string defaultValue)
 {
     return(GetAttribute(DomData.TokenID(name, true), defaultValue));
 }
示例#27
0
 public bool HasClass(string name)
 {
     return(HasClasses &&
            _Classes.Contains(DomData.TokenID(name)));
 }
示例#28
0
        /// <summary>
        /// Select from DOM using index. First non-class/tag/id selector will result in this being passed off to GetMatches
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        public IEnumerable <IDomObject> Select(IDomDocument document, IEnumerable <IDomObject> context)
        {
            if (Selectors == null)
            {
                throw new ArgumentException("No selectors provided.");
            }
            if (Selectors.Count == 0)
            {
                yield break;
            }
            Document = document;
            IEnumerable <IDomObject> lastResult      = null;
            HashSet <IDomObject>     output          = new HashSet <IDomObject>();
            IEnumerable <IDomObject> selectionSource = context;

            // Disable the index if there is no context (e.g. disconnected elements)
            bool useIndex = context.IsNullOrEmpty() || !context.First().IsDisconnected;

            // Copy the list because it may change during the process
            ActiveSelectors = new List <Selector>(Selectors);

            for (activeSelectorId = 0; activeSelectorId < ActiveSelectors.Count; activeSelectorId++)
            {
                var            selector       = ActiveSelectors[activeSelectorId];
                CombinatorType combinatorType = selector.CombinatorType;
                SelectorType   selectorType   = selector.SelectorType;
                TraversalType  traversalType  = selector.TraversalType;

                // Determine what kind of combining method we will use with previous selection results

                if (activeSelectorId != 0)
                {
                    switch (combinatorType)
                    {
                    case CombinatorType.Cumulative:
                        // do nothing
                        break;

                    case CombinatorType.Root:
                        selectionSource = context;
                        if (lastResult != null)
                        {
                            output.AddRange(lastResult);
                            lastResult = null;
                        }
                        break;

                    case CombinatorType.Chained:
                        selectionSource = lastResult;
                        lastResult      = null;
                        break;
                        // default (chained): leave lastresult alone
                    }
                }

                HashSet <IDomObject>     tempResult    = null;
                IEnumerable <IDomObject> interimResult = null;

                string key = "";
                if (useIndex && !selector.NoIndex)
                {
#if DEBUG_PATH
                    if (type.HasFlag(SelectorType.Attribute))
                    {
                        key   = "!" + selector.AttributeName;
                        type &= ~SelectorType.Attribute;
                        if (selector.AttributeValue != null)
                        {
                            InsertAttributeValueSelector(selector);
                        }
                    }
                    else if (type.HasFlag(SelectorType.Tag))
                    {
                        key   = "+" + selector.Tag;
                        type &= ~SelectorType.Tag;
                    }
                    else if (type.HasFlag(SelectorType.ID))
                    {
                        key   = "#" + selector.ID;
                        type &= ~SelectorType.ID;
                    }
                    else if (type.HasFlag(SelectorType.Class))
                    {
                        key   = "." + selector.Class;
                        type &= ~SelectorType.Class;
                    }
#else
                    if (selectorType.HasFlag(SelectorType.Attribute))
                    {
                        key           = "!" + (char)DomData.TokenID(selector.AttributeName);
                        selectorType &= ~SelectorType.Attribute;
                        if (selector.AttributeValue != null)
                        {
                            InsertAttributeValueSelector(selector);
                        }
                    }
                    else if (selectorType.HasFlag(SelectorType.Tag))
                    {
                        key           = "+" + (char)DomData.TokenID(selector.Tag, true);
                        selectorType &= ~SelectorType.Tag;
                    }
                    else if (selectorType.HasFlag(SelectorType.ID))
                    {
                        key           = "#" + (char)DomData.TokenID(selector.ID);
                        selectorType &= ~SelectorType.ID;
                    }
                    else if (selectorType.HasFlag(SelectorType.Class))
                    {
                        key           = "." + (char)DomData.TokenID(selector.Class);
                        selectorType &= ~SelectorType.Class;
                    }
#endif
                }

                // If part of the selector was indexed, key will not be empty. Return initial set from the
                // index. If any selectors remain after this they will be searched the hard way.

                if (key != String.Empty)
                {
                    int  depth       = 0;
                    bool descendants = true;

                    switch (traversalType)
                    {
                    case TraversalType.Child:
                        depth       = selector.ChildDepth;;
                        descendants = false;
                        break;

                    case TraversalType.Filter:
                        depth       = 0;
                        descendants = false;
                        break;

                    case TraversalType.Descendent:
                        depth       = 1;
                        descendants = true;
                        break;
                    }

                    if (selectionSource == null)
                    {
                        interimResult = document.QueryIndex(key + DomData.indexSeparator, depth, descendants);
                    }
                    else
                    {
                        interimResult = new HashSet <IDomObject>();
                        foreach (IDomObject obj in selectionSource)
                        {
                            ((HashSet <IDomObject>)interimResult)
                            .AddRange(document.QueryIndex(key + DomData.indexSeparator + obj.Path,
                                                          depth, descendants));
                        }
                    }
                }
                else if (selectorType.HasFlag(SelectorType.Elements))
                {
                    selectorType &= ~SelectorType.Elements;
                    HashSet <IDomObject> source = new HashSet <IDomObject>(selectionSource);
                    interimResult = new HashSet <IDomObject>();

                    foreach (IDomObject obj in selectionSource)
                    {
                        key = DomData.indexSeparator + obj.Path;
                        HashSet <IDomObject> srcKeys = new HashSet <IDomObject>(document.QueryIndex(key));
                        foreach (IDomObject match in selector.SelectElements)
                        {
                            if (srcKeys.Contains(match))
                            {
                                ((HashSet <IDomObject>)interimResult).Add(match);
                            }
                        }
                    }
                }
                // TODO - GetMatch should work if passed with no selectors (returning nothing), now it returns everything
                // 12/10/11 - this todo is not verified, much has changed since it was written. TODO confirm this and
                // fix if needed. If having the conversation with self again, remove comments and forget it. This is
                // an example of why comments can do more harm than good.

                if ((selectorType & ~(SelectorType.SubSelectorNot | SelectorType.SubSelectorHas)) != 0)
                {
                    IEnumerable <IDomObject> finalSelectWithin =
                        interimResult
                        ?? (combinatorType == CombinatorType.Chained ? lastResult : null)
                        ?? selectionSource
                        ?? document.ChildElements;

                    // if there are no temporary results (b/c there was no indexed selector) then use the whole set
                    interimResult = GetMatches(finalSelectWithin, selector);
                }

                // Deal with subselectors: has() and not() test for the presence of a selector within the children of
                // an element. This is essentially similar to the manual selection above.

                if (selectorType.HasFlag(SelectorType.SubSelectorHas) ||
                    selectorType.HasFlag(SelectorType.SubSelectorNot))
                {
                    bool isHasSelector = selectorType.HasFlag(SelectorType.SubSelectorHas);

                    IEnumerable <IDomObject> subSelectWithin = interimResult
                                                               ?? (combinatorType == CombinatorType.Chained ? lastResult : null)
                                                               ?? selectionSource;

                    // subselects are a filter. start a new interim result.

                    HashSet <IDomObject> filteredResults = new HashSet <IDomObject>();

                    foreach (IDomObject obj in subSelectWithin)
                    {
                        bool match = true;
                        foreach (var sub in selector.SubSelectors)
                        {
                            List <IDomObject> listOfOne = new List <IDomObject>();
                            listOfOne.Add(obj);

                            bool has = !sub.Select(document, listOfOne).IsNullOrEmpty();

                            match &= isHasSelector == has;
                        }
                        if (match)
                        {
                            filteredResults.Add(obj);
                        }
                    }
                    interimResult = filteredResults;
                }
                tempResult = new HashSet <IDomObject>();
                if (lastResult != null)
                {
                    tempResult.AddRange(lastResult);
                }
                if (interimResult != null)
                {
                    tempResult.AddRange(interimResult);
                }
                lastResult = tempResult;
            }


            if (lastResult != null)
            {
                output.AddRange(lastResult);
            }

            if (output.IsNullOrEmpty())
            {
                yield break;
            }
            else
            {
                // Selectors always return in DOM order. Selections may end up in a different order but
                // we always sort here.

                foreach (IDomObject item in output.OrderBy(item => item.Path, StringComparer.Ordinal))
                {
                    yield return(item);
                }
            }
            ActiveSelectors.Clear();
        }
示例#29
0
 bool IDictionary <string, string> .ContainsKey(string key)
 {
     return(Styles.ContainsKey(DomData.TokenID(key, true)));
 }
示例#30
0
 bool ICollection <KeyValuePair <string, string> > .Contains(KeyValuePair <string, string> item)
 {
     return(Styles.Contains(new KeyValuePair <ushort, string>(DomData.TokenID(item.Key), item.Value)));
 }