Подтвердить что ты не робот

Пути в веб-компонентах относятся к корням

Я создаю веб-компонент, используя собственную реализацию, в которой html-шаблон имеет ссылки на изображения. Однако эти ссылки работают только в том случае, если они являются абсолютными или относительно основного документа, что означает, что этот компонент не может использоваться повторно или переноситься. Кроме того, это очень противоречиво.

В настоящее время я добавляю атрибут data-url_prefix ко всем элементам, которые должны использовать изображения. Затем, создав теневой корень для моего настраиваемого элемента, я заменил {{URL_PREFIX}} на значение этого аргумента.

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


Я нашел интересную цитату на странице http://webcomponents.org/polyfills/html-imports/:

POLYFILL ПРИМЕЧАНИЯ

В импортированных документах, атрибутах href и src в HTML и URL-адресе свойства в файлах CSS, относятся к местоположению импортированных документ, а не основной документ.

почему полифилл использует разную логику, чтобы нативная реализация?


Веб-компоненты В идеале должны инкапсулировать все их зависимости, но если веб-компонент требует изображения, он должен знать абсолютный URL-адрес этого изображения, что не позволяет просто перемещать компонент в структуре файла.

Скажем, например, у меня есть следующая структура:

  • index.html
  • CSS
    • main.css
  • JS
    • main.js
  • web_components
    • cool_web_component
      • cool_web_component.html
      • icon.png

Если я изменил его на следующее:

  • index.html
  • CSS
    • main.css
  • JS
    • main.js
  • cool_web_component
    • cool_web_component.html
    • icon.png

Мне нужно будет изменить указатель на icon.png где-нибудь в этих файлах Мой вопрос - как избежать этого, или решить его элегантным способом. Кроме того, почему фактическая нативная реализация находится в конфликте с полиполками?

4b9b3361

Ответ 1

Спецификация веб-компонента определяет, что URL-адреса всегда относятся к основному документу. Это, конечно же, нарушает инкапсуляцию веб-компонентов, как вы правильно сделали вывод. Другими словами, спецификация ошибочна, и многие люди жалуются на это. Вот почему polyfill не соответствует спецификации: он исправляет проблему.

Спецификация изменится. Однако, поскольку это не так уж и сложно, это может занять некоторое время. См. Следующие ссылки:

https://lists.w3.org/Archives/Public/public-webapps/2014OctDec/0013.html

https://www.w3.org/Bugs/Public/show_bug.cgi?id=20976#c8

На данный момент решение заключается в том, что ваш компонент изменит URL-адрес его шаблонных изображений по сравнению с абсолютным. Вы можете получить templateBaseUrl следующим образом:

(function (window, document)
    {
    var proto = Object.create(HTMLElement.prototype);

    var template = document.currentScript.ownerDocument.querySelector("template");
    var templateBaseUrl = template.baseURI;

    proto.createdCallback = function ()
        {
        // Now find all images inside the template and change their src attribute, 
        // using templateBaseUrl. Also you must change CSS background-image: url(...);
        ...
        };

    document.registerElement('test-element', {prototype: proto});
    })(window, document);

Другим способом устранения этого в случае небольших изображений, таких как значки, является встраивание данных изображения непосредственно в документ с помощью URI данных. Это также сохраняет HTTP-запросы (пока у нас нет Http/2). Например:

<img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />

Ответ 2

Это поведение, по-видимому, специфично для изображений.
Для script и тегов ссылок относительные пути из импортированного документа работают как ожидалось.

Также я заметил, что это не что-то конкретное для полиполков, даже для собственной реализации (хром) эта проблема (?), похоже, существует.

Похоже, что только вариант состоит в том, чтобы включить script в импортированный html, который преобразует эти относительные пути в их абсолютные копии.
Чтобы это было удобно, вы можете избежать URL-адресов жесткого кодирования в своем script и сгенерировать его, используя URL-адрес вашего импортирующего документа. Вы можете получить это от document.currentScript.ownerDocument (или document._currentScript.ownerDocument в многозадачном сценарии).

Итак, чтобы ответить на ваш второй вопрос, я не вижу разницы в нативной и многозадачной реализации, по крайней мере, с точки зрения поведения атрибутов src и href.
Цитата, которую вы упомянули из http://webcomponents.org/polyfills/html-imports/, по-видимому, специфична для href/src script и связывает теги, и они работают как написано.

Надеюсь, что это поможет.

Ответ 3

Реакция на мой собственный предыдущий комментарий к ответу MarcG - необходимость того, чтобы модули знали свой собственный путь, стала общепризнанной, и в настоящее время ее можно получить с помощью import.meta.url !

Так что теперь гораздо проще написать утилиту для извлечения компонента HTML/CSS.

Кроме того, если CSS НЕ извлекается, но в документ динамически добавляется новая ссылка на таблицу стилей - этот CSS также очень хорошо работает с относительными путями.

Имея это, сегодня, ожидая некоторого стандартного способа указать мою базовую ссылку на компонент, мой подход заключается в том, чтобы предоставить компоненту 2 ресурса:

  • Основной/единственный HTML извлекается через API fetch, превращается в шаблон, кэшируется и затем клонируется в компонент каждый раз, когда его новый экземпляр присоединяется к DOM
  • Основной CSS связан стандартным элементом link
  • имена этих 2 совпадают с именами основного файла JS, предоставляющего класс компонента, что упрощает превращение всего этого беспорядка в утилиту с дюжиной строк
  • дополнительные CSS-ресурсы, при необходимости, добавляются как обычный относительный импорт в основной CSS
  • изображения, если это возможно, добавляются в качестве фона URL с использованием относительного импорта
  • очевидно, не больше, чем отдельный HTML-ресурс