setAttributeNS xmlns <svg>для библиотеки общего назначения - PullRequest
0 голосов
/ 29 сентября 2018

Похоже, что веб-браузеры выдают DOMException, когда для установки атрибута xmlns используется setAttributeNS на элементе <svg>.т.е.

>>> s = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
<svg>​</svg>​

>>> s.setAttributeNS(null, 'xmlns', '123')
Uncaught DOMException: Failed to execute 'setAttributeNS' 
  on 'Element': '' is an invalid namespace for attributes.

>>> s.setAttributeNS('http://www.w3.org/2000/svg', 'xmlns', 
      'http://www.w3.org/2000/svg')
Uncaught DOMException: Failed to execute 'setAttributeNS' 
  on 'Element': '' is an invalid namespace for attributes.

>>> s.setAttributeNS(null, 'xmlns', 'http://www.w3.org/2000/svg')
Uncaught DOMException: Failed to execute 'setAttributeNS' 
  on 'Element': '' is an invalid namespace for attributes.

Mozilla docs рекомендует всегда использовать setAttributeNS, однако в нем не упоминается эта возможность.Таким образом, в рекомендации, по-видимому, есть предостережения.

Спецификация DOM уровня 2 на setAttributeNS дает некоторое представление:

NAMESPACE_ERR: Повышается, если квалифицированное имя искажено, если для квалифицированного имени задан префикс, а namespaceURI равно нулю, если для квалифицированного имени задан префикс «xml», а namespaceURI отличается от «http://www.w3.org/XML/1998/namespace",, или если значение квалифицированного имени« xmlns »и namespaceURI отличаетсяfrom "http://www.w3.org/2000/xmlns/".

Таким образом, это конкретное исключение является частью более широкого набора случаев, которые могут завершиться неудачей.Сразу видно, что это за дела.

Я пишу tko / Knockout 4.0, веб-фреймворк общего назначения, и поэтому он должен поддерживать svg и другие теги вне основного пространства имен HTML.

Наиболее часто встречающаяся проблема связана с тегами xmlns на svg, поэтому является проблемой обошел этот , специально проверив, чтобы увидеть, установлен ли xmlns, и в этом случае setAttribute.

Этот обходной путь кажется довольно специфичным, и я обеспокоенобщий случай.Есть ли прецедент того, как обычно обрабатывать установки атрибутов с setAttributeNS и setAttribute?

Другие веб-фреймворки не решают эту проблему аккуратно - обычно они смешиваются с другой логикой;самый точный коммит, который я видел, относится к angular , но он не решает эту проблему напрямую.

Related: Разница между setAttribute и setAttributeNS (null,

1 Ответ

0 голосов
/ 29 сентября 2018

Это не будет охватывать все случаи, но это должно иметь большое значение:

const NAMESPACES = {
  svg: 'http://www.w3.org/2000/svg',
  html: 'http://www.w3.org/1999/xhtml',
  xml: 'http://www.w3.org/XML/1998/namespace',
  xlink: 'http://www.w3.org/1999/xlink',
  xmlns: 'http://www.w3.org/2000/xmlns/' // sic for the final slash...
}

class JsxObserver extends LifeCycle {
  ...

  setNodeAttribute (node, name, valueOrObservable) {
    const value = unwrap(valueOrObservable)
    NativeProvider.addValueToNode(node, name, valueOrObservable)
    if (value === undefined) {
      node.removeAttributeNS(null, name)
    } else if (isThenable(valueOrObservable)) {
      Promise.resolve(valueOrObservable)
        .then(v => this.setNodeAttribute(node, name, v))
    } else {
      const [prefix, ...unqualifiedName] = name.split(':')
      let ns = null
      if (prefix === 'xmlns' || unqualifiedName.length && NAMESPACES[prefix]) {
        ns = NAMESPACES[prefix]
      }
      node.setAttributeNS(ns, name, String(value))
    }
  }
}

Если обнаружен атрибут xmlns="http://www.w3.org/2000/svg", он будет добавлен с

.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg')

Если встречается атрибут xml:space="preserve" (то, что заведомо используют редакторы SVG), он будет добавлен с

.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...