Поскольку я недавно прошел перчатку этой проблемы, я хочу поделиться некоторой информацией, которая мне кажется ценной.
Во-первых, ответ Роба верен. Тень DOM - правильное решение этой проблемы. Однако в моем случае мне не только нужна изоляция CSS, но также нужны события JavaScript. Например, что произойдет, если пользователь нажмет кнопку, которая живет в изолированном HTML? Это становится действительно уродливым только с Shadow DOM, но у нас есть другая технология веб-компонентов, Custom Elements, для спасения. За исключением того, что на момент написания этой статьи есть ошибка в chrome, которая предотвращает создание пользовательского элемента в chrome-расширениях. Здесь мои здесь и здесь и здесь есть ошибка .
Итак, где же это остается? Я считаю, что лучшим решением сегодня является IFrames, с которым я и пошел. Статья shahalpk связана велика, но она описывает только часть процесса. Вот как я это сделал:
Сначала создайте html-файл и js-файл для вашего изолированного виджета. Все внутри этих файлов будет работать в изолированной среде в iframe. Не забудьте загрузить файл js из html-файла.
//iframe.js
var button = document.querySelector('.my-button');
button.addEventListener('click', function() {
// do useful things
});
//iframe.html
Затем внутри вашего скрипта содержимого создайте элемент iframe в javascript. Вам нужно сделать это в javascript, потому что вам нужно использовать chrome.extension.getURL, чтобы захватить ваш файл iframe html:
var iframe = document.createElement('iframe');
iframe.src = chrome.extension.getURL("iframe.html");
document.body.appendChild(iframe);
И все.
имейте в виду: если вам нужно обмениваться информацией между iframe и остальной частью сценария контента, вам нужно выполнить chrome.runtime.sendMessage () на фоновой странице, а затем chrome.tabs.sendMessage с фоновой страницы обратно на вкладку , Они не могут напрямую общаться.
EDIT: я написал сообщение в блоге, в котором подробно описывалось все, что я узнал в моем процессе, включая полное расширение chrome примера и множество ссылок на различную информацию:
https://anderspitman.net/blog/chrome-extension-content-script-stylesheet-isolation/
В случае, если мой блог не работает, вот источники исходного сообщения :
Проверьте этот ответ на мой вопрос, который кажется очень похожим.
Что-то попробовать: вызвать ConfigureAwait(false)
в Задаче, возвращенной GetStreamAsync()
. Например,
var result = await httpClient.GetStreamAsync("weeklyplan")
.ConfigureAwait(continueOnCapturedContext:false);
Независимо от того, действительно ли это полезно, зависит от того, как вызывается этот код выше - в моем случае вызов метода async
с использованием Task.GetAwaiter().GetResult()
заставил код висеть.
Это связано с тем, что GetResult()
блокирует текущий поток, пока задача не завершится. Когда задача завершается, он пытается повторно ввести контекст потока, в котором он был запущен, но не может, потому что в этом контексте уже есть поток, который блокируется вызовом GetResult()
... deadlock!
Эта запись MSDN подробно рассказывает о том, как .NET синхронизирует параллельные потоки, и ответ на мой собственный вопрос дает некоторые рекомендации.