コード例 #1
0
ファイル: FormData.cs プロジェクト: dsisco11/CssUI
        public void set(string name, ReadOnlyMemory <byte> blobValue, string filename = null)
        {/* Docs: https://xhr.spec.whatwg.org/#dom-formdata-set */
            FormDataEntryValue entry = null;

            if (string.IsNullOrEmpty(filename))
            {
                /* 3) If value is a Blob object and not a File object, then set value to a new File object, representing the same bytes, whose name attribute value is "blob". */
                entry = new FormDataEntryValue(EFormDataValueType.Blob, name, new FileBlob(blobValue, "blob"));
            }
            else
            {
                entry = new FormDataEntryValue(EFormDataValueType.File, name, new FileBlob(blobValue, filename));
            }

            int index = Entries.FindIndex(e => StringCommon.StrEq(name, e.Item1));

            Entries.RemoveAll(e => StringCommon.StrEq(name, e.Item1));
            if (index < 0)
            {
                Entries.Add(new Tuple <string, FormDataEntryValue>(name, entry));
            }
            else
            {
                Entries.Insert(index, new Tuple <string, FormDataEntryValue>(name, entry));
            }
        }
コード例 #2
0
        public static bool Is_Valid_Custom_Element_Name(ReadOnlyMemory <char> data)
        {/* Docs: https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name */
            /* FORMAT:  [a-z] (PCENChar)* '-' (PCENChar)*  */
            if (data.IsEmpty || data.Length < 2)
            {
                return(false);
            }

            DataConsumer <char> Stream = new DataConsumer <char>(data, EOF);

            /* Must start with a lowercased alpha character */
            if (!Is_ASCII_Lower_Alpha(Stream.Next))
            {
                return(false);
            }

            /* Consume the first char */
            Stream.Consume();

            /* Consume any chars that are valid PCEN but NOT the first hypen */
            Stream.Consume_While(c => Is_PCEN_Char(c) && c != CHAR_HYPHEN_MINUS);

            /* The name must contain atleast one hypen */
            if (Stream.Next != CHAR_HYPHEN_MINUS)
            {
                return(false);
            }

            /* Consume all remaining PCEN chars */
            Stream.Consume_While(c => Is_PCEN_Char(c));

            /* All PCEN chars have been consumed, if this isnt EOF then its an invalid char */
            if (Stream.Next != EOF)
            {
                return(false);
            }

            /* name must not be any of the following:
             *      annotation-xml
             *      color-profile
             *      font-face
             *      font-face-src
             *      font-face-uri
             *      font-face-format
             *      font-face-name
             *      missing-glyph
             */
            for (int i = 0; i < FORBIDDEN_CUSTOM_ELEMENT_NAMES.Length; i++)
            {
                if (StringCommon.StrEq(data.Span, FORBIDDEN_CUSTOM_ELEMENT_NAMES[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #3
0
ファイル: AttributeValue.cs プロジェクト: dsisco11/CssUI
        public override bool Equals(object obj)
        {
            if (!(obj is AttributeValue other))
            {
                return(false);
            }

            if (Type == other.Type)
            {
                switch (Type)
                {
                case EAttributeType.Boolean:
                {        // A boolean attributes value is based on it's mere existance. So if the other object exists then they are both true and equal!
                    return(other.Value is object);
                }

                case EAttributeType.Integer:
                {        // cast to large type just incase
                    return((Int64)Value == (Int64)other.Value);
                }

                case EAttributeType.NonNegative_Integer:
                {        // cast to large type just incase
                    return((UInt64)Value == (UInt64)other.Value);
                }

                case EAttributeType.Enumerated:
                {
                    return((int)Value == (int)other.Value);
                }

                case EAttributeType.NonZero_Length:
                case EAttributeType.NonZero_Percentage:
                case EAttributeType.FloatingPoint:
                {
                    return((double)Value == (double)other.Value);
                }

                default:
                {
                    if (other.Type == EAttributeType.String)
                    {
                        return(((AtomicString)Value).Equals((AtomicString)other.Value));
                    }
                    else
                    {
                        return(StringCommon.StrEq(Data, other.Data));
                    }
                }
                }
            }
            else
            {/* Its possible these values are compatible but have different types */
                return(StringCommon.StrEq(Data, other.Data));
            }
        }
コード例 #4
0
        public override ENodeFilterResult acceptNode(Node node)
        {
            if (!(node is Element))
            {
                return(ENodeFilterResult.FILTER_SKIP);
            }

            // We test reference of string just incase the one being used is like a const or static decleration, or maybe an interned string. it's faster to match an address ptr than to check all chars in an array.
            if (ReferenceEquals((node as Element).localName, Name) || StringCommon.StrEq((node as Element).localName.AsSpan(), Name.AsSpan()))
            {
                return(ENodeFilterResult.FILTER_ACCEPT);
            }

            return(ENodeFilterResult.FILTER_SKIP);
        }
コード例 #5
0
ファイル: FormData.cs プロジェクト: dsisco11/CssUI
        public void set(string name, string value)
        {/* Docs: https://xhr.spec.whatwg.org/#dom-formdata-set */
            var entry = new FormDataEntryValue(EFormDataValueType.String, name, value);
            int index = Entries.FindIndex(e => StringCommon.StrEq(name, e.Item1));

            Entries.RemoveAll(e => StringCommon.StrEq(name, e.Item1));
            if (index < 0)
            {
                Entries.Add(new Tuple <string, FormDataEntryValue>(name, entry));
            }
            else
            {
                Entries.Insert(index, new Tuple <string, FormDataEntryValue>(name, entry));
            }
        }
コード例 #6
0
ファイル: XMLCommon.cs プロジェクト: dsisco11/CssUI
        public static void Validate_And_Extract(string Namespace, string qualifiedName, out string outPrefix, out string outLocalName)
        {/* Docs: https://dom.spec.whatwg.org/#validate-and-extract */
            /* 1) If namespace is the empty string, set it to null. */
            if (Namespace.Length <= 0)
            {
                Namespace = null;
            }

            /* 2) Validate qualifiedName. */
            Validate(qualifiedName);

            string prefix    = null;
            string localName = qualifiedName;

            /* 5) If qualifiedName contains a ":" (U+003E), then split the string on it and set prefix to the part before and localName to the part after. */
            if (qualifiedName.Contains(':'))
            {
                string[] tok = qualifiedName.Split(':');
                prefix    = tok[0];
                localName = tok[1];
            }

            if (prefix != null && Namespace == null)
            {
                throw new NamespaceError($"The qualified name contains a prefix but no namespace was specified");
            }

            /* 7) If prefix is "xml" and namespace is not the XML namespace, then throw a "NamespaceError" DOMException. */
            if (StringCommon.StrEq("xml".AsSpan(), prefix.AsSpan()) && !StringCommon.StrEq(Namespace.AsSpan(), DOMCommon.XMLNamespace.AsSpan()))
            {
                throw new NamespaceError($"The qualified names' prefix \"{qualifiedName}\" does not match the namespace specified \"{Namespace}\"");
            }

            /* 8) If either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace, then throw a "NamespaceError" DOMException. */
            if ((StringCommon.StrEq("xmlns".AsSpan(), qualifiedName.AsSpan()) || StringCommon.StrEq("xmlns".AsSpan(), prefix.AsSpan())) && !StringCommon.StrEq(Namespace.AsSpan(), DOMCommon.XMLNSNamespace.AsSpan()))
            {
                throw new NamespaceError($"The qualified names' prefix \"{qualifiedName}\" does not match the namespace specified \"{Namespace}\"");
            }

            /* 9) If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns", then throw a "NamespaceError" DOMException. */
            if ((!StringCommon.StrEq("xmlns".AsSpan(), qualifiedName.AsSpan()) || !StringCommon.StrEq("xmlns".AsSpan(), prefix.AsSpan())) && StringCommon.StrEq(Namespace.AsSpan(), DOMCommon.XMLNSNamespace.AsSpan()))
            {
                throw new NamespaceError($"The qualified names' prefix \"{qualifiedName}\" does not match the namespace specified \"{Namespace}\"");
            }

            outPrefix    = prefix;
            outLocalName = localName;
        }
コード例 #7
0
        public override ENodeFilterResult acceptNode(Node node)
        {/* Docs: https://html.spec.whatwg.org/multipage/input.html#radio-button-state-(type=radio):radio-button-group */
            if (!Subject_Is_Valid)
            {
                return(ENodeFilterResult.FILTER_REJECT);
            }

            if (node.nodeType != ENodeType.ELEMENT_NODE)
            {
                return(ENodeFilterResult.FILTER_REJECT);
            }

            /* Dont accept our own subject or else theyll end up in their own grouplist which doesnt make sense and will also screw up the logic of input element functions */
            if (ReferenceEquals(Subject, node))
            {
                return(ENodeFilterResult.FILTER_SKIP);
            }

            /* The input element b's type attribute is in the Radio Button state. */
            if (node is HTMLInputElement inputElement && inputElement.type == EInputType.Radio)
            {         /* Either a and b have the same form owner, or they both have no form owner. */
                if (ReferenceEquals(subjectForm, inputElement.form))
                {     /* Both a and b are in the same tree. */
                    if (ReferenceEquals(Subject.ownerDocument, inputElement.ownerDocument))
                    { /* They both have a name attribute, their name attributes are not empty, and the value of a's name attribute equals the value of b's name attribute. */
                        string nameStr = inputElement.name;
                        if (!ReferenceEquals(null, nameStr) && nameStr.Length > 0)
                        {
                            if (StringCommon.StrEq(subjectName, nameStr))
                            {
                                return(ENodeFilterResult.FILTER_ACCEPT);
                            }
                        }
                    }
                }
            }

            return(ENodeFilterResult.FILTER_SKIP);
        }
コード例 #8
0
        public override ENodeFilterResult acceptNode(Node node)
        {
            if (!(node is Element element))
            {
                return(ENodeFilterResult.FILTER_SKIP);
            }

            // We test reference of string just incase the one being used is like a const or static decleration, or maybe an interned string. it's faster to match an address ptr than to check all chars in an array.
            if (ReferenceEquals(element.id, Name) || StringCommon.StrEq(element.id.AsSpan(), Name.AsSpan()))
            {
                return(ENodeFilterResult.FILTER_ACCEPT);
            }

            if (ReferenceEquals(element.NamespaceURI, DOMCommon.HTMLNamespace) || StringCommon.StrEq(element.NamespaceURI.AsSpan(), DOMCommon.HTMLNamespace.AsSpan()))
            {
                var nameAttrValue = element.getAttribute(EAttributeName.Name)?.AsString();
                if (ReferenceEquals(nameAttrValue, Name) || StringCommon.StrEq(nameAttrValue.AsSpan(), Name.AsSpan()))
                {
                    return(ENodeFilterResult.FILTER_ACCEPT);
                }
            }

            return(ENodeFilterResult.FILTER_SKIP);
        }
コード例 #9
0
ファイル: StringCommonTests.cs プロジェクト: dsisco11/CssUI
 public void StrEqTest(string Left, string Right, bool Expected)
 {
     Assert.Equal(Expected, StringCommon.StrEq(Left, Right));
 }
コード例 #10
0
        override public bool Matches(Element E, params Node[] scopeElements)
        {
            switch (Operator)
            {
            // CSS 2.0 operators
            case ECssAttributeOperator.Isset:    // isset
            {
                return(E.hasAttribute(AttributeName));
            }

            case ECssAttributeOperator.Equals:    // equals
            {
                if (string.IsNullOrEmpty(Value))
                {
                    return(false);
                }
                return(StringCommon.StrEq(Value, E.getAttribute(AttributeName).AsString()));
            }

            case ECssAttributeOperator.PrefixedWith:    // equals or prefixed-with
            {
                if (!E.hasAttribute(AttributeName))
                {
                    return(false);
                }
                string val = E.getAttribute(AttributeName).AsString();
                if (StringCommon.StrEq(Value, val))
                {
                    return(true);
                }
                if (val.StartsWith(string.Concat(Value, '-')))
                {
                    return(true);
                }
                return(false);
            }

            case ECssAttributeOperator.Includes:    // list-contains
            {
                if (string.IsNullOrEmpty(Value))
                {
                    return(false);
                }
                /* First lets check the elements token-list map */
                if (E.tokenListMap.TryGetValue(AttributeName, out IAttributeTokenList listMap))
                {
                    var TokenList = (AttributeTokenList <string>)listMap;
                    return(TokenList.Contains(Value));
                }

                if (!E.hasAttribute(AttributeName))
                {
                    return(false);
                }
                var attr = E.getAttribute(AttributeName);
                var set  = DOMCommon.Parse_Ordered_Set(attr.AsAtomic().AsMemory());
                return(set.Contains(Value.AsMemory()));
            }

            // Sub-string operators
            case ECssAttributeOperator.StartsWith:    // starts-with
            {
                if (string.IsNullOrEmpty(Value))
                {
                    return(false);
                }
                if (!E.hasAttribute(AttributeName))
                {
                    return(false);
                }
                var attr = E.getAttribute(AttributeName);
                return(attr.AsString().StartsWith(Value));
            }

            case ECssAttributeOperator.EndsWith:    // ends-with
            {
                if (string.IsNullOrEmpty(Value))
                {
                    return(false);
                }
                if (!E.hasAttribute(AttributeName))
                {
                    return(false);
                }
                var attr = E.getAttribute(AttributeName);
                return(attr.AsString().EndsWith(Value));
            }

            case ECssAttributeOperator.Contains:    // contains
            {
                if (string.IsNullOrEmpty(Value))
                {
                    return(false);
                }
                if (!E.hasAttribute(AttributeName))
                {
                    return(false);
                }
                var attr = E.getAttribute(AttributeName);
                return(StringCommon.Contains(attr.AsAtomic().AsMemory().Span, Value.AsMemory().Span));
            }

            default:
                throw new CssSelectorException($"Attribute selector operator ({Enum.GetName(typeof(ECssAttributeOperator), Operator)}) logic not implemented!");
            }
        }
コード例 #11
0
ファイル: FormData.cs プロジェクト: dsisco11/CssUI
 public bool has(string name)
 {/* Docs: https://xhr.spec.whatwg.org/#dom-formdata-has */
     return(Entries.Any(e => StringCommon.StrEq(name, e.Item1)));
 }
コード例 #12
0
ファイル: FormData.cs プロジェクト: dsisco11/CssUI
 public IReadOnlyCollection <FormDataEntryValue> getAll(string name)
 {/* Docs: https://xhr.spec.whatwg.org/#dom-formdata-getall */
     return(Entries.Where(e => StringCommon.StrEq(name, e.Item1)).Select(e => e.Item2).ToArray());
 }
コード例 #13
0
ファイル: FormData.cs プロジェクト: dsisco11/CssUI
 public FormDataEntryValue get(string name)
 {/* Docs: https://xhr.spec.whatwg.org/#dom-formdata-get */
     return(Entries.First(e => StringCommon.StrEq(name, e.Item1)).Item2);
 }
コード例 #14
0
ファイル: FormData.cs プロジェクト: dsisco11/CssUI
 public void delete(string name)
 {/* Docs: https://xhr.spec.whatwg.org/#dom-formdata-delete */
     Entries.RemoveAll(e => StringCommon.StrEq(name, e.Item1));
 }