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


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

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

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


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

ЗАМЕТКИ О ПОЛИФИЛЕ

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

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


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

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

  • индекс.html
  • css
    • главная.css
  • js
    • главная.js
  • web_компоненты
    • cool_web_компонент
      • cool_web_компонент.html
      • икона.png

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

  • индекс.html
  • css
    • главная.css
  • js
    • главная.js
  • cool_web_компонент
    • cool_web_компонент.html
    • икона.png

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

2 9

2 ответа:

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

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

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);

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

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

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

Также я заметил, что это не является чем-то специфичным для polyfills, даже для родной реализации (chrome) эта проблема(?) кажется, есть.

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

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

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