예제 #1
0
        public static object CreateJsFromXElement <TElement, TAttribute, TObject>(IElementProvider <TElement, TAttribute, TObject> elementProvider, TElement xelement)
        {
            var index = new Dictionary <string, object>();

            index["name"] = elementProvider.LocalName(xelement);
            if (elementProvider.Namespace(xelement) != null)
            {
                index["ns"] = elementProvider.Namespace(xelement);
            }
            var attrs = elementProvider.Attributes(xelement).Select(attr => new { name = elementProvider.LocalName(attr), value = elementProvider.Value(attr) }).ToArray();

            if (attrs.Any())
            {
                index["a"] = attrs;
            }
            var elements = elementProvider.Elements(xelement).Select(child => CreateJsFromXElement(elementProvider, child)).Where(child => child != null).ToArray();

            if (elements.Any())
            {
                index["e"] = elements;
            }
            var texts = elementProvider.Texts(xelement).ToArray();

            if (texts.Any())
            {
                index["t"] = new { value = texts.JoinToString(null) }
            }
            ;
            var raws = elementProvider.Raws(xelement).ToArray();

            if (raws.Any())
            {
                index["h"] = raws.JoinToString(null);
            }
            return(index);
        }
    }
예제 #2
0
        public static IEnumerable <object> JsSync <TElement, TAttribute, TObject>(IElementProvider <TElement, TAttribute, TObject> elementProvider, TElement oldBody, TElement body, params object[] path)
        {
            if (oldBody == null)
            {
                oldBody = elementProvider.Element("body");

                yield return(new { path, cmd = "clear-all" });
            }

            var oldElements = elementProvider.Elements(oldBody).ToArray();
            var newElements = elementProvider.Elements(body).ToArray();

            var lastText = elementProvider.Texts(oldBody).JoinToString(null);
            var newText  = elementProvider.Texts(body).JoinToString(null);

            var lastHtml = elementProvider.Raws(oldBody).JoinToString(null);
            var newHtml  = elementProvider.Raws(body).JoinToString(null);

            if (oldElements.Length > 0 != newElements.Length > 0 && (lastText != "") != (newText != "") || lastHtml != "" && newHtml == "")
            {
                yield return(new { path, cmd = "clear" });

                oldElements = Array <TElement> .Empty;
                lastText    = "";
                lastHtml    = "";
            }


            var left_i = 0;

            for (var i = 0; i < Math.Max(oldElements.Length, newElements.Length); ++i)
            {
                var oldChild = oldElements.ElementAtOrDefault(i);
                var newChild = newElements.ElementAtOrDefault(i);
                if (newChild == null)
                {
                    yield return new { path = path.Concat(new[] { new { kind = "element", index = left_i } }).ToArray(), cmd = "remove" }
                }
                ;
                else if (oldChild == null || elementProvider.LocalName(oldChild) != elementProvider.LocalName(newChild) || elementProvider.Attribute_Get(oldChild, "data-id") != elementProvider.Attribute_Get(newChild, "data-id"))
                {
                    if (oldChild != null)
                    {
                        yield return new { path = path.Concat(new[] { new { kind = "element", index = left_i } }).ToArray(), cmd = "remove" }
                    }
                    ;

                    if (i == 0)
                    {
                        yield return new { path, cmd = "insert", value = CreateJsFromXElement(elementProvider, newChild) }
                    }
                    ;
                    else
                    {
                        yield return
                            new
                            {
                                path  = path.Concat(new[] { new { kind = "element", index = i - 1 } }).ToArray(),
                                cmd   = "after",
                                value = CreateJsFromXElement(elementProvider, newChild)
                            }
                    };

                    left_i++;
                }
                else
                {
                    foreach (var res in JsSync(elementProvider, oldChild, newChild, path.Concat(new[] { new { kind = "element", index = i } }).ToArray()))
                    {
                        yield return(res);
                    }

                    left_i++;
                }
            }

            var attributes = elementProvider.Attributes(body).ToArray();


            var attrs = elementProvider.Attributes(oldBody)
                        .OuterJoin(attributes, lastAtr => elementProvider.LocalName(lastAtr), newAtr => elementProvider.LocalName(newAtr), (lastAttr, newAttr) => new { lastAttr, newAttr })
                        .Where(pair => elementProvider.Value(pair.lastAttr) != elementProvider.Value(pair.newAttr))
                        .Select(pair =>
            {
                var attrName = pair.lastAttr._f(_ => elementProvider.LocalName(_)) ?? pair.newAttr._f(_ => elementProvider.LocalName(_));
                return(new { name = attrName, value = elementProvider.Value(pair.newAttr) });
            }
                                )
                        .ToArray();

            var t = newText != lastText ? new { value = newText } : null;
            var h = newHtml != lastHtml ? newHtml : null;

            if (attrs.Any() || t != null || h != null)
            {
                yield return(new { path, cmd = "set", value = new { a = attrs, t, h } });
            }

            if (true)
            {
                var jsUpdate = attributes.FirstOrDefault(_attr => elementProvider.LocalName(_attr) == "js-update");
                if (jsUpdate != null)
                {
                    yield return new { path, cmd = "js-update", value = elementProvider.Value(jsUpdate) }
                }
                ;
            }
        }