XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using AngleSharp.Dom;
using AngleSharp.Html.Parser;

namespace XFESystem.Browser.Tests;

public sealed class BrowserRangeGeometryTests
{
    private sealed class Metrics : IBrowserTextMetrics
    { public double Measure(string text, BrowserFont font) => text.Sum(c => c == 'W' ? 10 : c == 'i' ? 2 : 5); }
    private static (IDocument Document, BrowserDisplayList List) Page(string content, string css = "", double scrollY = 0)
    {
        var document = new HtmlParser().ParseDocument("<style>body{margin:0;font:10px/20px monospace}" + css + "</style><div id=A>" + content + "</div>");
        return (document, new BrowserLayoutEngine().Layout(document, new(800, 600, 0, scrollY), textMetrics: new Metrics()));
    }
    private static IText Text(IDocument document, string id = "A") => document.GetElementById(id)!.ChildNodes.OfType<IText>().First();
    [Fact] public void PartialTextOffsetsUseActualNonUniformGlyphAdvances()
    {
        var (document, list) = Page("WWiiW"); var text = Text(document);
        var rect = Assert.Single(list.GetRangeRects(text, 1, text, 4));
        Assert.Equal(new(10, 0, 14, 20), rect);
        var caret = Assert.Single(list.GetRangeClientRects(text, 4, text, 4)); Assert.Equal(new(24, 0, 0, 20), caret);
    }
    [Fact] public void CrossNodeRangeUsesDocumentOrderAndAppliesViewportScroll()
    {
        var (document, list) = Page("<span id=B>WW</span><span id=C>iiW</span>", "#A{margin-top:30px}", 10);
        var start = Text(document, "B"); var end = Text(document, "C"); var rects = list.GetRangeRects(start, 1, end, 2);
        Assert.Equal(2, rects.Count); Assert.Equal(new(10, 20, 10, 20), rects[0]); Assert.Equal(new(20, 20, 4, 20), rects[1]);
    }
    [Fact] public void ElementChildBoundariesSelectOnlyCorrespondingChildren()
    {
        var (document, list) = Page("<span>WW</span><span>iiW</span>"); var parent = document.GetElementById("A")!;
        var rect = Assert.Single(list.GetRangeRects(parent, 1, parent, 2)); Assert.Equal(new(20, 0, 14, 20), rect);
    }
    [Fact] public void PreNewlinesAndTabsKeepTheirOriginalDomOffsets()
    {
        var (document, list) = Page("W\ti\nWi", "#A{white-space:pre}"); var text = Text(document);
        var tab = Assert.Single(list.GetRangeRects(text, 1, text, 2)); Assert.Equal(new(10, 0, 20, 20), tab);
        var second = Assert.Single(list.GetRangeRects(text, 4, text, 6)); Assert.Equal(new(0, 20, 12, 20), second);
        Assert.Equal(2, list.GetRangeRects(text, 0, text, 6).Count);
    }
    [Fact] public void WrappingAndCollapsedWhitespaceRetainPartialWordOffsets()
    {
        var (document, list) = Page("WW  ii WW", "#A{width:40px}"); var text = Text(document);
        var secondLine = Assert.Single(list.GetRangeRects(text, 7, text, 9)); Assert.Equal(new(0, 20, 20, 20), secondLine);
        var middle = Assert.Single(list.GetRangeRects(text, 4, text, 6)); Assert.Equal(new(25, 0, 4, 20), middle);
    }
    [Fact] public void HiddenDisplayHasNoRangeRectsAndInvalidBoundariesAreRejected()
    {
        var (document, list) = Page("<span id=B style='display:none'>WW</span>ii"); var hidden = Text(document, "B"); var visible = Text(document);
        Assert.Empty(list.GetRangeRects(hidden, 0, hidden, 2));
        Assert.Throws<ArgumentOutOfRangeException>(() => list.GetRangeRects(visible, 0, visible, 3));
    }
    [Fact] public void DetachedRangeCannotPoisonTheCachedDocumentGeometry()
    {
        var (document, list) = Page("WW"); var detached = document.CreateTextNode("ii");
        Assert.Empty(list.GetRangeRects(detached, 0, detached, 2));
        Assert.Equal(new(0, 0, 20, 20), Assert.Single(list.GetRangeRects(Text(document), 0, Text(document), 2)));
    }
    [Fact] public void PointerEventsInheritanceAndExplicitChildOverrideAffectActualTarget()
    {
        var (document, list) = Page("<div id=B style='height:30px'>WW</div>", "#A{pointer-events:none}");
        Assert.NotSame(document.GetElementById("B"), list.HitTest(5, 5)?.Element);
        document.GetElementById("B")!.SetAttribute("style", "height:30px;pointer-events:auto");
        list = new BrowserLayoutEngine().Layout(document, new(800, 600)); Assert.Same(document.GetElementById("B"), list.HitTest(5, 5)!.Element);
    }
}