Вставка настраиваемого элемента с помощью AngleSharp - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь обновить сайт, который использует дезинфицирующее средство на основе AngleSharp для обработки пользовательского контента HTML. Пользователи сайта должны иметь возможность встраивать фреймы, и я пытаюсь использовать белый список, чтобы контролировать, какие домены может загружать фрейм. Я хотел бы переписать «заблокированные» iframe на новый пользовательский элемент «blocked-iframe», который затем будет удален дезинфицирующим средством, чтобы мы могли проверить, нужно ли добавлять другие домены в белый список.

Я пытаюсь использовать решение, основанное на этом ответе: { ссылка }

Это выглядит так:

    string BlockIFrames(string content)
    {
        var parser = new HtmlParser(new HtmlParserOptions { });

        var doc = parser.Parse(content);

        foreach (var element in doc.QuerySelectorAll("iframe"))
        {
            var src = element.GetAttribute("src");

            if (string.IsNullOrEmpty(src) || !Settings.Sanitization.IFrameWhitelist.Any(wls => src.StartsWith(wls)))
            {
                var newElement = doc.CreateElement("blocked-iframe");
                foreach (var attr in element.Attributes)
                {
                    newElement.SetAttribute(attr.Name, attr.Value);
                }

                element.Insert(AdjacentPosition.BeforeBegin, newElement.OuterHtml);

                element.Remove();
            }
        }

        return doc.FirstElementChild.OuterHtml;
    }

Якобы работает, но я замечаю что угловые скобки в теге нового элемента экранируются при вставке, поэтому результат просто записывается на страницу в виде текста. Думаю, я мог бы построить карту замен и просто выполнить их для строки перед отправкой обратно, но мне интересно, есть ли способ сделать это с помощью API AngleSharp. В настоящее время сайт использует версию 0.9.9, и я не уверен, насколько далеко мы сможем выполнить обновление, учитывая некоторые другие существующие зависимости.

1 Ответ

0 голосов
/ 08 мая 2020

Покопавшись в источнике, я нашел метод ReplaceChild в INode, который работает, если вызывается из родительского элемента element

    string BlockIFrames(string content)
    {
        var parser = new HtmlParser(new HtmlParserOptions { });

        var doc = parser.Parse(content);

        foreach (var element in doc.QuerySelectorAll("iframe"))
        {
            var src = element.GetAttribute("src");

            if (string.IsNullOrEmpty(src) ||
                !Settings.Sanitization.IFrameWhitelist.Any(wls => src.StartsWith(wls)))
            {
                var newElement = doc.CreateElement("blocked-iframe");
                foreach (var attr in element.Attributes)
                {
                    newElement.SetAttribute(attr.Name, attr.Value);
                }

                element.Parent.ReplaceChild(newElement, element);
            }
        }

        return doc.FirstElementChild.OuterHtml;
    }

Я буду продолжать тестирование, но это кажется достаточно приличным, чтобы мне, если есть лучший способ, я бы хотел это услышать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...