Этот документ является неофициальным переводом исходной английской версии W3C DOM4. Обратите внимание на то, что оригинальная версия документа существует только на английском языке. Данный перевод может содержать неточности и ошибки. Перевод выполнил Кирилл Топольян, 2017.

W3C

W3C DOM4

Рекомендация W3C от

Эта версия:
http://www.w3.org/TR/2015/REC-dom-20151119/
Последняя опубликованная версия:
http://www.w3.org/TR/dom/
Доклад о реализации:
http://w3c.github.io/test-results/dom/details.html
Баг-трекер:
сообщить о баге (открытые баги, старые баги)
Предыдущая версия:
http://www.w3.org/TR/2015/PR-dom-20151006/
Редакторы:
Anne van Kesteren, Mozilla (версия WHATWG)
Aryeh Gregor, Mozilla (версия WHATWG)
Ms2ger, Mozilla (версия WHATWG)
Alex Russell, Google
Robin Berjon, W3C

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

Также смотрите переводы.


Аннотация

DOM определяет платформо-независимую модель для событий и узлов деревьев. DOM4 добавляет Mutation Observers (наблюдатели изменений) как замену Mutation Events.

Статус этого документа

Этот раздел описывает статус данного документа на момент его публикации. Другие документы могут заменить этот документ. Список актуальных публикаций W3C и последняя ревизия этого технического доклада могут быть найдены в индексе технических докладов W3C по адресу http://www.w3.org/TR/.

Этот документ опубликован как снимок DOM Living Standard с намерением поддержания отличий от оригинала к строгому минимуму, и только через формирование подмножеств (только не реализованные вещи были удалены из этой публикации).

Предупреждение

Разработчики должны принять во внимание старый список багов в общем, но в особенности эти два бага, которые могут отрицательно повлиять на совместимость (более конкретно на Document интерфейс):

Этот документ был опубликован Рабочей группой HTML как Рекомендация.

Если вы хотите оставить комментарии к этому документу в порядке который отслеживается W3C, пожалуйста, добавьте их с помощью нашего публичного списка вопросов. Если вы не можете сделать это, вы можете отправить e-mail на www-dom@w3.org (подписка, архивы), и мы примем меры чтобы перенести комментарии в нашу публичную базу данных багов. Любая обратная связь приветствуется.

С момента предыдущей публикации изменений не было.

Доступен обширный набор тестов для этой спецификации. Посмотрите отчет о реализации Рабочей группы.

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

Этот документ был подготовлен группой действующей под Патентной политикой W3C от 5 февраля 2004. W3C поддерживает публичный список открытых патентов, сделанных в связи с результатами деятельности группы; эта страница также включает в себя инструкции по раскрытию патента. Человек, который имеет фактическое знание патента, соответствующего основным требованиям, должен раскрыть информацию в соответствии с разделом 6 патентной политики W3C.

Данный документ регулируется W3C Process Document от 14 октября 2005.

Содержание

  1. Цели
  2. 1 Соответствие
    1. 1.1 Зависимости
    2. 1.2 Расширяемость
  3. 2 Терминология
    1. 2.1 Деревья
    2. 2.2 Строки
    3. 2.3 Упорядоченные множества
    4. 2.4 Пространства имен
  4. 3 События
    1. 3.1 Введение в "DOM Events"
    2. 3.2 Интерфейс Event
    3. 3.3 Интерфейс CustomEvent
    4. 3.4 Создание событий
    5. 3.5 Определение интерфейсов событий
    6. 3.6 Интерфейс EventTarget
    7. 3.7 Отправка событий
    8. 3.8 Вызов событий
  5. 4 Узлы
    1. 4.1 Введение в "The DOM"
    2. 4.2 Дерево узлов
      1. 4.2.1 Алгоритмы изменений
      2. 4.2.2 Интерфейс NonElementParentNode
      3. 4.2.3 Интерфейс ParentNode
      4. 4.2.4 Интерфейс NonDocumentTypeChildNode
      5. 4.2.5 Интерфейс ChildNode
      6. 4.2.6 Коллекции старого типа: NodeList и HTMLCollection
        1. 4.2.6.1 Интерфейс NodeList
        2. 4.2.6.2 Интерфейс HTMLCollection
    3. 4.3 Наблюдатели изменений (Mutation observers)
      1. 4.3.1 Интерфейс MutationObserver
      2. 4.3.2 Очередь записи изменений
      3. 4.3.3 Интерфейс MutationRecord
      4. 4.3.4 Сборка мусора
    4. 4.4 Интерфейс Node
    5. 4.5 Интерфейс Document
      1. 4.5.1 Интерфейс DOMImplementation
    6. 4.6 Интерфейс DocumentFragment
    7. 4.7 Интерфейс DocumentType
    8. 4.8 Интерфейс Element
      1. 4.8.1 Интерфейс Attr
    9. 4.9 Интерфейс CharacterData
    10. 4.10 Интерфейс Text
    11. 4.11 Интерфейс ProcessingInstruction
    12. 4.12 Интерфейс Comment
  6. 5 Диапазоны
    1. 5.1 Введение в "DOM Ranges"
    2. 5.2 Интерфейс Range
  7. 6 Обход
    1. 6.1 Интерфейс NodeIterator
    2. 6.2 Интерфейс TreeWalker
    3. 6.3 Интерфейс NodeFilter
  8. 7 Множества
    1. 7.1 Интерфейс DOMTokenList
    2. 7.2 Интерфейс DOMSettableTokenList
  9. 8 История
    1. 8.1 DOM События
    2. 8.2 DOM Ядро
    3. 8.3 DOM Диапазоны
    4. 8.4 DOM Обход
  10. А Исключения и ошибки
    1. А.1 Исключения
    2. А.2 Интерфейс DOMError
    3. А.3 Имена ошибок
  11. Б Концепты CSS
  12. Ссылки
  13. Благодарности

Цели

Эта спецификация стандартизирует DOM. Она делает это следующим образом:

  1. Объединяя Ядро DOM Level 3 [DOM3CORE], Обход элементов [ELEMENTTRAVERSAL], Selectors API Level 2 [SELECTORSAPI], главы "Архитектура Событий DOM" и "Базовые Интерфейсы Событий" UI Events [UIEVENTS] (конкретный тип событий не входящий в Стандарт DOM), Обход и Диапазон DOM Level 2 [DOM2TR], и:

  2. Перемещая возможности из Стандарта HTML [HTML], которые имеют больше смысла быть частью Стандарта DOM.

  3. Определяя замену для глав "Mutation Events" и "Mutation Name Event Types" Спецификации UI Events (бывшая DOM Level 3 Events) [UIEVENTS] так как старая модель была проблемной.

    Заметка: Старая модель, как ожидается, будет удалена из реализаций в установленном порядке.

  4. Определяя новые возможности, которые упрощают частые операции DOM.

1 Соответствие

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

Ключевые слова "MUST" (должен), "MUST NOT" (не должен), "REQUIRED" (обязан), "SHALL", "SHALL NOT", "SHOULD" (следует), "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" (может) и "OPTIONAL" (опционально) в этом документе должны интерпретироваться как описано в RFC 2119. Для читабельности, эти слова не появляются капсом в этой спецификации. [RFC2119]

Требования сформулированные в императиве как часть алгоритмов (такие как "сократить пробелы в начале" or "возвратить false и прекратить шаги") должны интерпретироваться со значением ключевого слова ("должен", "следует", "может" и т.д.) использованного в представлении алгоритма.

Требования соответствия выраженные в виде алгоритмов или конкретных шагов могут быть реализованы любым способом, до тех пор пока конечный результат эквивалентен. (В частности, алгоритмы определенные в этой спецификации направлены на то чтобы им было легко следовать, и не предназначены чтобы быть производительными.)

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

Когда метод или атрибут говорить вызвать другой метод или атрибут, агент пользователя должен вызвать внутренний API для этого атрибута или метода, так что, например, автор не может изменить поведение путем переопределения атрибутов или методов с кастомными свойствами или функциями в JavaScript.

Если не указано иное, сравнение строк выполняется регистрозависимым образом.

1.1 Зависимости

Фрагменты IDL в этой спецификации должны интерпретироваться как обязаны для соответствия IDL фрагментам, как описано в спецификации Web IDL. [WEBIDL]

Некоторые из терминов использованных в этой спецификации определены в Encoding, Selectors, Web IDL, XML и Namespaces in XML. [ENCODING] [SELECTORS] [WEBIDL] [XML] [XMLNS]

1.2 Расширяемость

Специфические пропиетарные расширения к этой спецификации настоятельно не рекомендуются. Авторы не должны использовать такие расширения, так как это уменьшает совместимость и уменьшает охват пользователей, позволяя только пользователям со специфическими пользовательскими агентами иметь доступ к такому контенту.

Когда расширения нужны, Стандарт DOM может быть обновлен соответствующим образом, или написан новый стандарт, который охватывает возможности предусмотренных расширений для применимых спецификаций.

2 Терминология

Термин объект контекста означает объект на котором алгоритм, атрибут получения, атрибут присвоения или обсуждаемый метод был вызван. Когда объект контекста однозначен, этот термин может быть опущен.

2.1 Деревья

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

Объект который участвует в дереве имеет родителя, который является другим объектом либо null, и упорядоченный список из нуля или более дочерних объектов. Объект A, чей родитель это объект B, является дочерним от B.

Корень объекта это он сам, если его родитель это null, или если же им является корень его родителя.

Объект A называется потомком объекта B, если A является дочерним от B или A является дочерним объекта C, который наследник от B.

Включительный потомок это сам объект или один из его потомков.

Объект A называется предком объекта B только если B является потомком от A.

Включительный предок это сам объект или один из его предков.

Объект A называется сестринским объекта B только если B и A имеют одного не-null родителя.

Объект A является предшествующим объекту B если A и B в одном дереве и A идет перед B в порядке дерева.

Объект A является следующим объекту B если A и B в одном дереве и A идет после B в порядке дерева.

Первый дочерний объекта это его дочерний или null, если он не имеет дочерних.

Последний дочерний объекта это его дочерний или null, если он не имеет дочерних.

Предыдущий сестринский объекта это его предшествующий сестринский или null, если он не имеет предшествующего сестринского.

Следующий сестринский объекта это его следующий сестринский или null, если объект не имеет следующего сестринского.

Индекс объекта это количество его предшествующих сестринских.

2.2 Строки

Сравнение двух строк регистрозависимым образом означает точное их сравнение, символ кода к символу кода.

Сравнение двух строк ASCII регистрозависимым образом означает точное их сравнение, символ кода к символу кода, кроме того что символы в диапазоне от U+0041 до U+005A (т.е. от латинской заглавной A к латинской заглавной Z), включительно, и соответствующие символы в диапазоне от U+0061 до U+007A (т.е. от латинской маленькой A до латинской маленькой Z), включительно, считаются также соответствующими.

Конвертация строки к ASCII заглавным означает замену всех символов в диапазоне от U+0061 до U+007A (т.е. от латинской маленькой A до латинской маленькой Z), включительно, на соответствующие символы в диапазоне от U+0041 до U+005A (т.е. от латинской заглавной A до латинской заглавной Z).

Конвертация строки к ASCII строчным означает замену всех символов в диапазоне от U+0041 до U+005A (т.е. от латинской заглавной A до латинской заглавной Z), включительно, на соответствующие символы от U+0061 до U+007A (т.е. от латинской маленькой A до латинской маленькой Z).

Паттерн строки это prefix match для строки s, когда паттерн не длиннее чем s и отбрасывая s к длине паттерна, оставляя две строки как совпадающие друг с другом.

2.3 Упорядоченные множества

Парсер упорядоченных множеств принимает строку input и затем выполняет следующие шаги:

  1. Сделать position указателем на input, изначально указывающим на начало строки.

  2. Сделать tokens упорядоченным множеством токенов, изначально пустым.

  3. Пропустить ASCII пробелы.

  4. Пока position еще не после конца input:

    1. Собрать последовательность кодовых точек из кодовых точек, которые не являются ASCII пробелами.

    2. Если собранная строка не является tokens, добавить собранную строку к tokens.

    3. Пропустить ASCII пробелы.

  5. Возвратить tokens.

Чтобы собрать последовательность кодовых точек из code points, выполнить следующие шаги:

  1. Сделать input и position теми же переменными как те с именем которых алгоритм вызвал эти шаги.

  2. Сделать result пустой строкой.

  3. Пока position не показывает на конец от input и точка кода на position одна из code points, добавить эту точку кода в конец result и предыдущую position к следующей точке кода в input.

  4. Возвратить result.

Пропустить ASCII пробелы означает собрать последовательность кодовых точек ASCII пробелов и отбросить возвращаемое значение.

Сериализатор упорядоченных множеств принимает set и возвращает конкатенацию строк в set, отделенных друг от друга с помощью U+0020.

2.4 Пространства имен

HTML пространство имен это http://www.w3.org/1999/xhtml.

XML пространство имен это http://www.w3.org/XML/1998/namespace.

XMLNS пространство имен это http://www.w3.org/2000/xmlns/.

3 События

3.1 Введение в "DOM Events"

Во всех веб-платформах события отправляются к объектам чтобы сигнализировать возникновения, такие как активность сети или взаимодействие пользователя. Эти объекты реализуют интерфейс EventTarget и таким образом добавляют слушатели событий для наблюдения событий вызовом addEventListener():

obj.addEventListener("load", imgFetched)

function imgFetched(ev) {
  // успех
  …
}

Слушатели событий могут быть удалены путем использования метода removeEventListener(), передающего те же аргументы.

События также являются объектами и реализуют интерфейс Event (или производный интерфейс). В примере выше ev является событием. Он передается как аргумент к приемнику (callback) слушателя событий (обычно это функция JavaScript, как показано выше). Ключ слушателя событий от type события значения атрибута ("load" в примере выше). Target значения атрибута события возвращает объект к которому событие было отправлено (obj в примере выше).

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

// добавить соответствующий слушатель событий
obj.addEventListener("cat", function(e) { process(e.detail) })

// создать и отправить событие
var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}})
obj.dispatchEvent(event)

Кроме сигнализирования, события также иногда используются чтобы дать приложению контроль над тем что происходит дальше в операции. Например как часть отправки формы, событие, чье значение атрибута type равняется "submit", является отправленным. Если метод preventDefault() этого события вызван, отправка формы будет прервана. Приложения, которые хотят использовать эту функциональность через события, отправляемые приложением (синтетические события) могут использовать возвращаемое значение метода dispatchEvent():

if(obj.dispatchEvent(event)) {
  // событие не было отменено, время для магии
  …
}

Когда событие отправляется на объект, который участвует в дереве (например элемент), оно может достигать также слушателей событий на предках объекта. Сначала все слушатели событий предка, чья переменная capture установлена на true и вызвана, в порядке дерева. Затем, собственные слушатели событий объекта вызываются. И наконец, если только значение атрибута bubbles события является true, слушатели событий предка объекта вызываются заново, но теперь в обратном порядке дерева.

Давайте взглянем на пример того как события работают в дереве:

<!doctype html>
<html>
 <head>
  <title>Boring example</title>
 </head>
 <body>
  <p>Hello <span id=x>world</span>!</p>
  <script>
   function test(e) {
     debug(e.target, e.currentTarget, e.eventPhase)
   }
   document.addEventListener("hey", test, true)
   document.body.addEventListener("hey", test)
   var ev = new Event("hey", {bubbles:true})
   document.getElementById("x").dispatchEvent(ev)
  </script>
 </body>
</html>

Функция debug будет вызвана дважды. Каждый раз значение атрибута target события будет span элементом. В первый раз значение атрибута currentTarget будет document, второй раз — body элементом. Значение атрибута eventPhase переключается с CAPTURING_PHASE на BUBBLING_PHASE. Если бы слушатель событий был зарегистрирован для span элемента, то значение атрибута eventPhase было бы AT_TARGET.

3.2 Интерфейс Event

[Constructor(DOMString type, optional EventInit eventInitDict),
 Exposed=(Window,Worker)]
interface Event {
  readonly attribute DOMString type;
  readonly attribute EventTarget? target;
  readonly attribute EventTarget? currentTarget;

  const unsigned short NONE = 0;
  const unsigned short CAPTURING_PHASE = 1;
  const unsigned short AT_TARGET = 2;
  const unsigned short BUBBLING_PHASE = 3;
  readonly attribute unsigned short eventPhase;

  void stopPropagation();
  void stopImmediatePropagation();

  readonly attribute boolean bubbles;
  readonly attribute boolean cancelable;
  void preventDefault();
  readonly attribute boolean defaultPrevented;

  [Unforgeable] readonly attribute boolean isTrusted;
  readonly attribute DOMTimeStamp timeStamp;

  void initEvent(DOMString type, boolean bubbles, boolean cancelable);
};

dictionary EventInit {
  boolean bubbles = false;
  boolean cancelable = false;
};

Событие позволяет сигнализировать, что что-то произошло. Например то, что картинка полностью загрузилась. Это представлено в интерфейсе Event или в интерфейсе, который наследует Event интерфейс.

event = new Event(type [, eventInitDict])

Возвращает новое событие чье значение атрибута type установлено к type. Опциональный аргумент eventInitDict позволяет устанавливать атрибуты bubbles и cancelable через члены объекта того же имени.

event . type

Возвращает тип события, например "click", "hashchange" или "submit".

event . target

Возвращает объект к которому событие отправлено.

event . currentTarget

Возвращает объект чей приемник (callback) слушателя событий в настоящее время вызывается.

event . eventPhase

Возвращает фазу события, которая является одной из NONE, CAPTURING_PHASE, AT_TARGET и BUBBLING_PHASE.

event . stopPropagation()

Когда отправлено в дерево, вызов этого метода предотвращает событие от достижения других объектов кроме текущего объекта.

event . stopImmediatePropagation()

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

event . bubbles

Возвращает true или false в зависимости от того как событие было инициализировано. True если событие проходит через значение атрибута target предков в обратном порядке дерева, и false в другом случае.

event . cancelable

Возвращает true или false в зависимости от того как событие было инициализировано. Его возвращаемое значение не всегда несет смысл, но true может указывать что часть операции в течение которой событие было отправлено, может быть отменено вызовом метода preventDefault().

event . preventDefault()

Если вызвано когда значение атрибута cancelable является true, сигнализирует что операция вызвавшая отправку события должна быть отменена.

event . defaultPrevented

Возвращает true если preventDefault() был вызван во время значения атрибута cancelable true, и false в другом случае.

event . isTrusted

Возвращает true если событие было отправлено агентом пользователя, и false в другом случае.

event . timeStamp

Возвращает время создания события в виде количества миллисекунд прошедших с 00:00:00 UTC, 1 января 1970.

Атрибут type должен возвратить значение с которым он был инициализирован. Когда событие создано, атрибут должен быть инициализирован к пустой строке.

Атрибуты target и currentTarget должны возвратить значение с которыми они были инициализированы. Когда событие создано, атрибуты должны быть инициализированы к null.

Атрибут eventPhase должен возвратить значение с которым он был инициализирован, которое должно быть одним из следующих:

NONE (числовое значение 0)

События на данный момент не отправлены в этой фазе.

CAPTURING_PHASE (числовое значение 1)

Когда событие отправлено к объекту который участвует в дереве, оно будет в этой фазе перед тем как достигнет своего значения атрибута target.

AT_TARGET (числовое значение 2)

Когда событие отправлено, оно будет в этой фазе на своем значении атрибута target.

BUBBLING_PHASE (числовое значение 3)

Когда событие отправлено к объекту который участвует в дереве, оно будет в этой фазе после того как достигнет своего значения атрибута target.

Изначально атрибут должен быть инициализирован к значению NONE.


Каждое событие имеет следующие ассоциированные с ним флаги, которые изначально сняты:

Метод stopPropagation() должен устанавливать флаг остановки распространения.

Метод stopImmediatePropagation() должен устанавливать флаг остановки распространения и флаг остановки немедленного распространения.

Атрибуты bubbles и cancelable должны возвращать значения к которым они были инициализированы.

Метод preventDefault() должен устанавливать флаг отмены если значение атрибута cancelable является true.

Атрибут defaultPrevented должен возвращать true если флаг отмены установлен, и false в другом случае.


Атрибут isTrusted должен возвращать значение к которому был инициализирован. Когда событие создано, атрибут должен быть инициализирован к false.

Атрибут timeStamp должен возвращать значение к которому был установлен. Когда событие создано, атрибут должен быть установлен к количеству миллисекунд которые прошли с 00:00:00 UTC, 1 января 1970, игнорируя високосные секунды.


Чтобы инициализировать событие с type, bubbles и cancelable, выполнить следующие шаги:

  1. Установить флаг инициализации.

  2. Снять флаг остановки распространения, флаг остановки немедленного распространения распространения и флаг отмены.

  3. Установить атрибут isTrusted к false.

  4. Установить атрибут target к null.

  5. Установить атрибут type к type.

  6. Установить атрибут bubbles к bubbles.

  7. Установить атрибут cancelable к cancelable.

Метод initEvent(type, bubbles, cancelable), когда вызван, должен выполнить следующие шаги:

  1. Если флаг отправки объекта контекста установлен, прервать эти шаги.

  2. Инициализировать объект контекста с type, bubbles и cancelable.

Заметка: Так как события имеют конструкторы initEvent(), это является лишним. Тем не менее, это должно поддерживаться для наследия.

3.3 Интерфейс CustomEvent

[Constructor(DOMString type, optional CustomEventInit eventInitDict),
 Exposed=(Window,Worker)]
interface CustomEvent : Event {
  readonly attribute any detail;

  void initCustomEvent(DOMString type, boolean bubbles, boolean cancelable, any detail);
};

dictionary CustomEventInit : EventInit {
  any detail = null;
};

События с использованием интерфейса CustomEvent могут использоваться для кастомных данных.

event = new CustomEvent(type [, eventInitDict])

Работает аналогично конструктору для Event, кроме того что опциональный аргумент eventInitDict теперь позволяет устанавливать атрибут detail также.

event . detail

Возвращает любые кастомные данные с которыми событие было создано. Обычно используется для синтетических событий.

Атрибут detail должен возвращать значение с которым был инициализирован.

Метод initCustomEvent(type, bubbles, cancelable, detail) должен, когда вызван, выполнить следующие шаги:

  1. Если флаг отправки контекста события установлен, прервать эти шаги.

  2. Инициализировать объект контекста с type, bubbles и cancelable.

  3. Установить атрибут detail объекта контекста к detail.

3.4 Создание событий

Когда конструктор интерфейса Event, или интерфейс который наследует Event интерфейс, вызван, следующие шаги должны быть выполнены:

  1. Создать событие которое использует интерфейс с которым конструктор был вызван выше.

  2. Установить его флаг инициализации.

  3. Инициализировать атрибут type к аргументу type.

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

  5. Возвратить событие.

3.5 Определение интерфейсов событий

В общем, при определении нового интерфейса который наследует Event, пожалуйста, всегда просите обратной связи от WHATWG или почтового архива W3C www-dom@w3.org.

Интерфейс CustomEvent может использоваться как стартовая точка. Тем не менее, не вводите каких-либо методов init*Event(), так как они являются избыточными с конструкторами. Интерфейсы которые наследуют интерфейс Event, которые имеют такой метод, имеют его только по историческим причинам.

3.6 Интерфейс EventTarget

[Exposed=(Window,Worker)]
interface EventTarget {
  void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
  void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
  boolean dispatchEvent(Event event);
};

callback interface EventListener {
  void handleEvent(Event event);
};

EventTarget это объект к которому событие отправляется когда что-то произошло. Каждый EventTarget имеет связанный с ним список слушателей событий.

Слушатель событий ассоциирует callback с определенным событием. Каждый слушатель событий содержит переменные type (события), callback и capture.

Заметка: Callback назван EventListener по историческим причинам. Как видно из определения выше, слушатель событий является более широким концептом.

target . addEventListener(type, callback [, capture = false])

Добавляет слушатель событий для событий, чье значение атрибута type является type. Аргумент callback устанавливает callback, который будет вызван когда событие отправлено. Когда установлен к true, аргумент capture предотвращает callback от вызова, если значение атрибута eventPhase события равняется BUBBLING_PHASE. Когда false, callback не будет вызван когда значение атрибута eventPhase события равняется CAPTURING_PHASE. Так или иначе, callback будет вызван когда значение атрибута eventPhase события является AT_TARGET.

Слушатель событий добавляется к списку target слушателей событий и не добавляется если это дубликат, т.е. имеет те же значения type, callback и capture.

target . removeEventListener(type, callback [, capture = false])

Удаляет слушатель событий в списке target слушателей событий с теми же type, callback и capture.

target . dispatchEvent(event)

Отправляет синтетическое событие event к target и возвращает true если значение атрибута cancelable события равняется false, или его метод preventDefault() не был вызван, и false в другом случае.

Метод addEventListener(type, callback, capture) должен выполнить следующие шаги:

  1. Если callback равняется null, прервать эти шаги.

  2. Добавить слушатель событий в соответствующий список слушателей событий с type установленным к type, callback установленным к callback и capture установленным к capture, кроме как если уже есть слушатель событий в этом списке с теми же type, callback и capture.

Метод removeEventListener(type, callback, capture) должен выполнить следующие шаги:

  1. Удалить слушатель событий из соответствующего списка слушателей событий, чей type равняется name, callback равняется callback и capture равняется capture.

Метод dispatchEvent(event) должен выполнить следующие шаги:

  1. Если флаг отправки события установлен или если его флаг инициализации не установлен, выдать исключение "InvalidStateError".

  2. Инициализировать атрибут isTrusted события к false.

  3. Отправить событие и возвратить значение которое возвращается.

3.7 Отправка событий

Чтобы отправить событие к заданному объекту, с опциональным переопределением цели, выполнить следующие шаги:

  1. Сделать event событием которое отправлено.

  2. Установить флаг отправки события.

  3. Инициализировать атрибут target события к target override, если он задан, и объект к которому событие отправлено в другом случае.

  4. Если значение атрибута target события участвует в дереве, сделать event path статическим упорядоченным списком всех его предков в порядке дерева, и сделать event path пустым списком в другом случае.

  5. Инициализировать атрибут eventPhase события к CAPTURING_PHASE.

  6. Для каждого объекта в event path, вызвать его слушатели событий с событием event, до тех пор пока флаг остановки распространения события не снят.

  7. Инициализировать атрибут eventPhase события к AT_TARGET.

  8. Вызвать слушатели событий значения атрибута target события с event, если флаг остановки распространения события не установлен.

  9. Если значение атрибута bubbles события равняется true, выполнить следующие подшаги:

    1. Обратить порядок event path.

    2. Инициализировать атрибут eventPhase события к BUBBLING_PHASE.

    3. Для каждого объекта в event path, вызвать их слушатели событий, с событием event до тех пор пока флаг остановки распространения события не снят.

  10. Снять флаг отправки события.

  11. Инициализировать атрибут eventPhase события к NONE.

  12. Инициализировать атрибут currentTarget события к null.

  13. Возвратить false если флаг отмены события установлен, и true в другом случае.

Чтобы вызвать слушатели событий для объекта с событием, выполнить следующие шаги:

  1. Сделать event событием для которого вызваны слушатели событий.

  2. Сделать listeners копией слушателей событий ассоциированных с объектом для которого эти шаги выполняются.

  3. Инициализировать атрибут currentTarget события к объекту для которого эти шаги выполняются.

  4. Затем выполнить следующие подшаги для каждого слушателя событий в listeners:

    1. Если флаг остановки немедленного распространения события установлен, прекратить вызов алгоритма.

    2. Сделать listener слушателем событий.

    3. Если значение атрибута type события не равняется type слушателя (listener), прекратить эти подшаги (и выполнить их для следующего слушателя событий).

    4. Если значение атрибута eventPhase события равняется CAPTURING_PHASE и capture слушателя (listener) равняется false, прекратить эти подшаги (и выполнить их для следующего слушателя событий).

    5. Если значение атрибута eventPhase события равняется BUBBLING_PHASE и capture слушателя (listener) равняется true, прекратить эти подшаги (и выполнить их для следующего слушателя событий).

    6. Вызвать handleEvent callbackслушателя (listener), с событием переданным в этот алгоритм как первый аргумент и значение атрибута currentTarget события как callback this value. Если это выдает любое исключение, сообщите об исключении.

3.8 Вызов событий

Вызвать событие с именем e означает, что новое событие с помощью интерфейса Event, с его атрибутом type инициализированным к e и его атрибутом isTrusted инициализированным к true, должно быть отправлено к заданному объекту.

Заметка: Вызов в контексте DOM быстрый к созданию, инициализации и отправке события. Вызов события делает этот процесс проще для записи. Если событию нужны bubbles или инициализированный атрибут cancelable, можно написать "вызов события названного submit с его атрибутом cancelable инициализированным к true".

4 Узлы

4.1 Введение в "The DOM"

В своем первоначальном смысле, "The DOM" это API для для доступа и управления документами (в частности, документами HTML и XML). В этой спецификации термин "документ" используется для любых ресурсов на основе разметки, от коротких статических документов до длинных эссе или отчетов с множеством мультимедиа, так и для полноценных интерактивных приложений.

Эти документы представлены в виде дерева узлов. Некоторые из узлов в дереве могут иметь дочерние узлы, а некоторые нет.

Для иллюстрации рассмотрим этот HTML-документ:

<!DOCTYPE html>
<html class=e>
 <head><title>Aliens?</title></head>
 <body>Why yes.</body>
</html>

Он представлен следующим образом:

Стоит отметить, что из-за магии HTML-парсинга, не все ASCII пробелы были превращены в Text узлы, но общий концепт понятен. Разметка уходит, а дерево из узлов приходит.

Заметка: Отличный Live DOM Viewer может использоваться для изучения этого вопроса более детально.

4.2 Дерево узлов

Объекты реализующие Document, DocumentFragment, DocumentType, Element, Text, ProcessingInstruction или Comment интерфейс (проще сказать узлы), участвуют в дереве, проще названном дерево узлов.

Дерево узлов ограничивается следующим, выражаясь как отношения между типом узла и его разрешенными дочерними:

Document

В порядке дерева:

  1. Ноль или более узлов, каждый из которых ProcessingInstruction или Comment.

  2. Опционально один DocumentType узел.

  3. Ноль или более узлов, каждый из которых ProcessingInstruction или Comment.

  4. Опционально один Element узел.

  5. Ноль или более узлов, каждый из которых ProcessingInstruction или Comment.

DocumentFragment
Element

Ноль или более узлов, каждый из которых один из: Element, ProcessingInstruction, Comment или Text.

DocumentType
Text
ProcessingInstruction
Comment

Ничего.

Длина узла node зависит от node:

DocumentType

Ноль.

Text
ProcessingInstruction
Comment

Его значение атрибута length.

Любой другой узел

Его количество дочерних.

Узел считается пустым если его длина равняется нолю.

4.2.1 Алгоритмы изменений

Чтобы обеспечить валидность предварительной вставки узла в родительский перед дочерним, выполнить следующие шаги:

  1. Если родительский не является Document, DocumentFragment или Element узлом, выдать "HierarchyRequestError".

  2. Если узел является хост-включительным включительным предком родительского, выдать "HierarchyRequestError".

  3. Если дочерний не равен null и его родитель не parent, выдать исключение "NotFoundError".

  4. Если узел не DocumentFragment, DocumentType, Element, Text, ProcessingInstruction или Comment узел, выдать "HierarchyRequestError".

  5. Если узел это Text узел и родитель это document, или узел это doctype и parent не является document, выдать "HierarchyRequestError".

  6. Если родитель это document, и любые из утверждений ниже, переключенные на узел, являются true, выдать "HierarchyRequestError".

    DocumentFragment узел

    Если узел имеет больше одного дочернего элемента или имеет дочерний узел Text.

    В другом случае, если узел имеет один дочерний элемент element и родитель имеет дочерний элемент, дочерний это doctype или дочерний не null и doctype является следующим за дочерним объектом.

    элемент

    родитель имеет дочерний элемент, дочерний является doctype или дочерний не null и doctype является следующим за дочерним объектом.

    тип документа

    родитель имеет дочерний doctype, элемент является предшествующим дочернему, или дочерний равен null и родительский имеет дочерний элемент.

Чтобы предварительно вставить узел в parent перед child, выполнить следующие шаги:

  1. Обеспечить валидность предварительной вставки узла в parent перед child.

  2. Сделать reference child дочерним.

  3. Если reference child является node, установить его к следующему сестринскому узла.

  4. Принять узел в node document родительского.

  5. Вставить узел в parent перед reference child.

  6. Возвратить node.

Спецификации могут определять шаги вставки для всех или некоторых узлов. Алгоритм передает newNode как указано в алгоритме вставки ниже.

Чтобы вставить узел в parent перед child с опциональным флагом подавления наблюдений, выполнить следующие шаги:

  1. Сделать count количеством children узла если это узел DocumentFragment, или равным одному в другом случае.

  2. Если child не-null, выполнить эти шаги:

    1. Для каждого диапазона, чей начальный узел является parent и начальное смещение более чем index дочернего, увеличить их начальное смещение на count.

    2. Для каждого диапазона, чей конечный узел является parent и конечное смещение более чем index дочернего, увеличить их конечное смещение на count.

  3. Сделать узлы дочерними узла если узел является DocumentFragment узлом, и списком содержащим единственный узел в другом случае.

  4. Если node является DocumentFragment узлом, поставить в очередь запись изменения "childList" для node с removedNodes nodes.

    Заметка: Этот шаг намеренно не обращает внимания на флаг подавления наблюдателей.

  5. Если node является DocumentFragment узлом, удалить его дочерний с установленным флага подавления наблюдателей.

  6. Если флага подавления наблюдателей снят, поставить в очередь запись изменения "childList" для parent с addedNodes nodes, nextSibling child, и previousSibling предыдущим сестринским child или последним дочерним parent если child является null.

  7. Для каждого newNode в nodes, в порядке дерева, выполнить следующие шаги:

    1. Вставить newNode в parent перед child, либо в конце parent если child является null.

    2. Выполнить шаги вставки с newNode.

Чтобы добавить node к parent, предварительно вставить node в parent перед null.

Чтобы заменить child на node внутри parent, выполнить следующие шаги:

  1. Если parent не является Document, DocumentFragment или Element узлом, выдать исключение "HierarchyRequestError".

  2. Если node является хост-включающим включительным предком parent, выдать исключение "HierarchyRequestError".

  3. Если родитель child не является parent, выдать "NotFoundError" исключение.

  4. Если node не является DocumentFragment, DocumentType, Element, Text, ProcessingInstruction или Comment узлом, выдать исключение "HierarchyRequestError".

  5. Если node является Text узлом и parent является document, либо если node doctype и parent не являются document, выдать исключение "HierarchyRequestError".

  6. Если parent является document, и любые из утверждение ниже, переключенные на node, являются true, выдать исключение "HierarchyRequestError".

    DocumentFragment узел

    Если node имеет более одного дочернего элемента или имеет дочерний узел Text.

    В другом случае, если node имеет один дочерний элемент и parent имеет дочерний элемент, который не является child, или если doctype является следующим дочерним.

    элемент

    parent имеет дочерний элемент, не являющийся child, или doctype является следующим дочерним.

    doctype
    parent имеет дочерний doctype, не являющийся child, или элемент является предшествующим child.

    Заметка: Приведенные выше утверждения отличаются от алгоритма предварительной вставки.

  7. Сделать reference child следующим сестринским child.

  8. Если reference child является node, установить его к следующему сестринскому node.

  9. Принять node в документ узла parent-а.

  10. Удалить child с его parent с установленным флагом подавления наблюдателей.

  11. Вставить node в parent перед reference child с установленным флагом подавления наблюдателей.

  12. Сделать nodes дочерними node если node является узлом DocumentFragment, и списком содержащим единственную node в другом случае.

  13. Поставить в очередь запись изменения "childList" для целевого parent с addedNodes nodes, removedNodes списком содержащим единственный child, nextSibling reference child, и previousSibling предыдущим сестринским child.

  14. Возвратить child.

Чтобы заменить все с node внутри parent, выполнить следующие шаги:

  1. Если node не является null, принять node с узлом документа parent.

  2. Сделать removedNodes дочерним parent.

  3. Сделать addedNodes пустым списком если node является null, дочерним node если node является DocumentFragment узлом, или списком node в другом случае.

  4. Удалить все дочерние parent, в порядке дерева, с установленным флагом подавления наблюдателей.

  5. Если node не является null, вставить node в parent перед null с установленным флагом подавления наблюдателей.

  6. Поставить в очередь запись изменения "childList" для parent с addedNodes addedNodes и removedNodes removedNodes.

Заметка: Этот алгоритм не делает никаких проверок в отношении ограничений дерева узлов. Авторы спецификации должны использовать его с умом.

Чтобы предварительно удалить child из parent, выполнить следующие шаги:

  1. Если родитель child не является parent, выдать "NotFoundError" исключение.

  2. Удалить child из parent.

  3. Возвратить child.

Спецификации могут определять шаги удаления для всех или некоторых узлов. Алгоритм передает removedNode, oldParent, and oldPreviousSibling, как указано в алгоритме удаления ниже.

Чтобы удалить node из parent с опциональной установкой флага подавления наблюдателей, выполнить следующие шаги:

  1. Сделать index индексом node.

  2. Для каждого диапазона, чей начальный узел является включительным потомком node, установить его начало к (parent, index).

  3. Для каждого диапазона, чей конечный узел является включительным потомком node, установить его конец к (parent, index).

  4. Для каждого диапазона, чей начальный узел является parent и начальное смещение больше чем index, уменьшить его начальное смещение на единицу.

  5. Для каждого диапазона, чей конечный узел является parent и конечное смещение больше чем index, уменьшить его конечное смещение на единицу.

  6. Сделать oldPreviousSibling предыдущим сестринским node.

  7. Если флаг подавления наблюдателей снят, поставить в очередь запись изменения "childList" для parent с removedNodes списком содержащим единственную node, nextSibling следующим сестринским node, и previousSibling oldPreviousSibling.

  8. Для каждого предка ancestor node-ы, если ancestor имеет любые зарегистрированные наблюдатели, чье поддерево опций является true, то для каждого такого зарегистрированного наблюдателя registered добавить переходный зарегистрированный наблюдатель, чей наблюдатель и опции идентичны к registered и source, которые registered к списку зарегистрированных наблюдателей node.

  9. Удалить node из его parent.

  10. Выполнить шаги удаления с node, parent и oldPreviousSibling.

4.2.2 Интерфейс NonElementParentNode

Заметка: Метод getElementById() не на элементах для совместимости с более старыми версиями jQuery. Если со временем данная версия jQuery исчезнет, может быть мы сможем поддерживать это.

[NoInterfaceObject,
 Exposed=Window]
interface NonElementParentNode {
  Element? getElementById(DOMString elementId);
};
Document implements NonElementParentNode;
DocumentFragment implements NonElementParentNode;
node . getElementById(elementId)

Возвращает первый элемент внутри потомков node, чей ID это elementId.

Метод getElementById(elementId) должен возвратить первый элемент, в порядке дерева, внутри потомков объекта контекста, чей ID это elementId, либо null если такого элемента нет.

4.2.3 Интерфейс ParentNode

Макрос метода изменений:

  1. Сделать node null.

  2. Заменить каждую строку в nodes на узел Text, чьи данные являются строковым значением.

  3. Если nodes содержат более одного узла, установить node к новому DocumentFragment и добавить каждый узел в nodes к нему. Заново выдать любые исключения.

    В другом случае, установить node к единственному узлу, который nodes содержит.

[NoInterfaceObject,
 Exposed=Window]
interface ParentNode {
  [SameObject] readonly attribute HTMLCollection children;
  readonly attribute Element? firstElementChild;
  readonly attribute Element? lastElementChild;
  readonly attribute unsigned long childElementCount;

  Element? querySelector(DOMString selectors);
  [NewObject] NodeList querySelectorAll(DOMString selectors);
};
Document implements ParentNode;
DocumentFragment implements ParentNode;
Element implements ParentNode;
collection = node . children

Возвращает дочерние элементы.

element = node . firstElementChild

Возвращает первый дочерний, который является элементом, и null в другом случае.

element = node . lastElementChild

Возвращает последний дочерний, который является элементом, и null в другом случае.

node . querySelector(selectors)

Возвращает первый элемент, который является потомком node, который соответствует selectors.

node . querySelectorAll(selectors)

Возвращает все элементы потомки node, которые соответствуют selectors.

Атрибут children должен возвратить коллекцию HTMLCollection с корнем в объекте контекста, соответствующую только дочерним элементам.

Атрибут firstElementChild должен возвратить первый дочерний, который является элементом, и null в другом случае.

Атрибут lastElementChild должен возвратить последний дочерний, который является элементом, и null в другом случае.

Атрибут childElementCount должен возвратить количество дочерних объекта контекста, которые являются элементами.

Чтобы сопоставить относительную строку селекторов relativeSelectors против set, выполнить данные шаги:

  1. Сделать s результатом парсинга относительного селектора от relativeSelectors против set. [SELECTORS]

  2. Если s неудачен, выдать исключение "SyntaxError".

  3. Возвратить результат оценки селектора s, используя :scope elements set. [SELECTORS]

Чтобы scope-сопоставить строку селекторов selectors против node, выполнить данные шаги:

  1. Сделать s результатом парсинга селектора selectors. [SELECTORS]

  2. Если s неудачен, выдать исключение "SyntaxError".

  3. Возвратить результат оценки селектора s против корня node, используя scoping root node и метод scope-filtered. [SELECTORS].

Метод querySelector(selectors) должен возвратить первый результат выполнения scope-сопоставления строки селекторов selectors против объекта контекста, и null если результат является пустым списком.

Метод querySelectorAll(selectors) должен возвратить статический результат выполнения scope-сопоставления строки селекторов selectors против объекта контекста.

4.2.4 Интерфейс NonDocumentTypeChildNode

Заметка: Атрибуты previousElementSibling и nextElementSibling были удалены из узлов DocumentType по причинам совместимости. Если эти дополнения посчитаются достаточно совместимыми в будущем, они могут быть восстановлены.

[NoInterfaceObject,
 Exposed=Window]
interface NonDocumentTypeChildNode {
  readonly attribute Element? previousElementSibling;
  readonly attribute Element? nextElementSibling;
};
Element implements NonDocumentTypeChildNode;
CharacterData implements NonDocumentTypeChildNode;
element = node . previousElementSibling

Возвращает первый предшествующий сестринский, который является элементом, и null в другом случае.

element = node . nextElementSibling

Возвращает первый следующий сестринский, который является элементом, и null в другом случае.

Атрибут previousElementSibling должен возвратить первый предшествующий сестринский, который является элементом, и null в другом случае.

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

4.2.5 Интерфейс ChildNode

[NoInterfaceObject,
 Exposed=Window]
interface ChildNode {
  void remove();
};
DocumentType implements ChildNode;
Element implements ChildNode;
CharacterData implements ChildNode;
node . remove()

Удаляет node.

Метод remove() должен выполнить следующие шаги:

  1. Если объект контекста не имеет родителя, прекратить данные шаги.

  2. Удалить объект контекста из родителя объекта контекста.

4.2.6 Коллекции старого типа: NodeList и HTMLCollection

Коллекция это объект, представляющий собой список узлов DOM. Коллекция может быть живой или статичной. Если не указано иное, коллекция должна быть живой.

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

Когда коллекция создана, фильтр и корень ассоциированы с ней.

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

4.2.6.1 Интерфейс NodeList

Объект NodeList является коллекцией узлов.

[Exposed=Window]
interface NodeList {
  getter Node? item(unsigned long index);
  readonly attribute unsigned long length;
  iterable<Node>;
};
collection . length

Возвращает количество узлов в коллекции.

element = collection . item(index)
element = collection[index]

Возвращает узел с индексом index из коллекции. Узлы отсортированы в порядке дерева.

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

Атрибут length должен возвратить количество узлов представленных в коллекции.

Метод item(index) должен возвратить index-й узел в коллекции. Если нет index-го узла в коллекции, метод должен возвратить null.

4.2.6.2 Интерфейс HTMLCollection
[Exposed=Window]
interface HTMLCollection {
  readonly attribute unsigned long length;
  getter Element? item(unsigned long index);
  getter Element? namedItem(DOMString name);
};

Объект HTMLCollection является коллекцией элементов.

Заметка: Elements являются лучшим решением для представления коллекций элементов. HTMLCollection это исторический артефакт, от которого мы не можем избавить веб.

collection . length

Возвращает количество элементов в коллекции.

element = collection . item(index)
element = collection[index]

Возвращает элемент с индексом index из коллекции. Элементы отсортированы в порядке дерева.

element = collection . namedItem(name)
element = collection[name]

Возвращает первый элемент с ID или именем name из коллекции.

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

Атрибут length должен возвратить количество узлов представленных в коллекции.

Метод item(index) должен возвратить indexэлемент в коллекции. Если нет index-го элемента в коллекции, то метод должен возвратить null.

Поддерживаемые имена свойств, все не-числовые, являются значениями из списка возвращенного следующими шагами:

  1. Сделать result пустой строкой.

  2. Для каждого element представленного в коллекции, в порядке дерева, выполнить следующие подшаги:

    1. Если element имеет ID, которое не является пустой строкой и не в result, добавить ID элемента к result.

    2. Если element в пространстве имен HTML и имеет name атрибут, чье значение не является пустой строкой и не в result, добавить значение name атрибута элемента к result.

  3. Возвратить result.

Метод namedItem(key) должен выполнить следующие шаги:

  1. Если key является пустой строкой, возвратить null.
  2. Возвратить первый элемент в коллекции для которой как минимум одно из следующего true:

    или null если нет такого элемента.

4.3 Наблюдатели изменений (Mutation observers)

Каждая единица связанного similar-origin browsing контекста имеет флаг постановки в очередь составной микрозадачи наблюдателя изменений и ассоциированный список объектов MutationObserver, который изначально пуст. [HTML]

Чтобы поставить в очередь составную микрозадачу наблюдателя изменений, выполнить следующие шаги:

  1. Если флаг постановки в очередь составной микрозадачи наблюдателя изменений установлен, прекратить эти шаги.

  2. Установить флаг постановки в очередь составной микрозадачи наблюдателя изменений.

  3. Поставить в очередь составную микрозадачу к уведомлению наблюдателей изменений.

Чтобы уведомить наблюдатели изменений, выполнить следующие шаги:

  1. Снять флаг постановки в очередь составной микрозадачи наблюдателя изменений.

  2. Сделать notify list копией списка объектов MutationObserver единицы связанного similar-origin browsing контекста.

  3. Для каждого объекта MutationObserver mo в notify list, выполнить подзадачу составной микрозадачи, чтобы выполнить следующие шаги: [HTML]

    1. Сделать queue копией записи очереди mo.

    2. Очистить запись очереди mo.

    3. Удалить все переходные зарегистрированные наблюдатели, чьи observer являются mo.

    4. Если queue не является пустым, вызвать приемник mo с queue в качестве первого аргумента и mo (самим) в качестве второго аргумента, и передать это значение. Если это выдает исключение, уведомить об исключении.


Каждый узел имеет связанный список зарегистрированных наблюдателей.

Зарегистрированный наблюдатель состоит из наблюдателя (объект MutationObserver) и опций (словарь MutationObserverInit). Переходный зарегистрированный наблюдатель это конкретный тип зарегистрированного наблюдателя, который имеет source, который является зарегистрированным наблюдателем.

4.3.1 Интерфейс MutationObserver

[Constructor(MutationCallback callback)]
interface MutationObserver {
  void observe(Node target, MutationObserverInit options);
  void disconnect();
  sequence<MutationRecord> takeRecords();
};

callback MutationCallback = void (sequence<MutationRecord> mutations, MutationObserver observer);

dictionary MutationObserverInit {
  boolean childList = false;
  boolean attributes;
  boolean characterData;
  boolean subtree = false;
  boolean attributeOldValue;
  boolean characterDataOldValue;
  sequence<DOMString> attributeFilter;
};

Объект MutationObserver может использоваться для наблюдения изменений в дереве узлов.

Каждый объект MutationObserver имеет ассоциированные контексты:

observer = new MutationObserver(callback)

Конструирует объект MutationObserver и устанавливает его приемник к callback. callback вызывается с объектами списка MutationRecord в качестве первого аргумента, и построенным объектом MutationObserver в качестве второго аргумента. Он вызывается после узлов зарегистрированных с методом observe(), подверженных изменениям.

observer . observe(target, options)

Поручает агенту пользователя наблюдать заданный target (узел) и сообщать о любых изменениях на основе критериев заданных options (объект).

Аргумент options позволяет устанавливать параметры наблюдения изменений с помощью членов объекта. Это аргументы объекта, которые могут использоваться:

childList

Устанавливается к true если изменения дочерних target должны наблюдаться.

attributes

Устанавливается к true если изменения атрибутов target должны наблюдаться. Может быть опущен если attributeOldValue и/или attributeFilter заданы.

characterData

Устанавливается к true если изменения данных target должны наблюдаться. Может быть опущен если characterDataOldValue задан.

subtree

Устанавливается к true если изменения не только target, но также потомков target должны наблюдаться.

attributeOldValue

Устанавливается к true если attributes является true или опущены, и значение атрибута target перед изменением должно быть записано.

characterDataOldValue

Устанавливается к true если characterData установлен к true или опущен, и данные target перед изменением должны быть записаны.

attributeFilter

Устанавливается к списку локальных имен атрибутов (без пространства имен) если не все изменения атрибута должны наблюдаться, и attributes является true или опущены.

observer . disconnect()

Останавливает observer от наблюдения любых изменений. Пока метод observe() не используется снова, приемник observer-а не будет вызван.

observer . takeRecords()

Очищает запись очереди и возвращает то что там было.

Конструктор MutationObserver(callback) должен создать новый объект MutationObserver с приемником установленным к callback, добавить его к списку объектов MutationObserver единиц связанных similar-origin browsing контекста, и затем возвратить их.

Метод observe(target, options), когда вызван, должен выполнить следующие шаги:

  1. Если attributeOldValue или attributeFilter options представлены и options attributes опущены, установить options attributes к true.

  2. Если characterDataOldValue options представлен и options characterData опущен, установить options characterData к true.

  3. Если ни один из options childList attributes и characterData не является true, выдать исключение TypeError.

  4. Если options attributeOldValue является true и options attributes является false, выдать исключение JavaScript TypeError.

  5. Если options attributeFilter представлен и options attributes является false, выдать JavaScript TypeError.

  6. Если options characterDataOldValue является true и options characterData является false, выдать JavaScript TypeError.

  7. Для каждого зарегистрированного наблюдателя registered в списке зарегистрированных наблюдателей target, чьи observer являются объектами контекста:

    1. Удалить все переходные зарегистрированные наблюдатели, чьи source являются registered.

    2. Заменить опции registered на options.

  8. В другом случае, добавить новый зарегистрированный наблюдатель к списку зарегистрированных наблюдателей target на объект контекста как наблюдатель и options как опции, и добавить target к списку узлов объекта контекста на котором он зарегистрирован.

Метод disconnect() должен, для каждого узла node в списке узлов объекта контекста, удалить любые зарегистрированные наблюдатели на node для которых объект контекста является observer, и также очистить очередь записи объекта контекста.

Метод takeRecords() должен возвратить копию очереди записи и затем очистить очередь записи.

4.3.2 Очередь записи изменений

Чтобы поставить в очередь запись изменения type для target с одним или более (зависит от type) именем name, пространством имен namespace, oldValue oldValue, addedNodes addedNodes, removedNodes removedNodes, previousSibling previousSibling и nextSibling nextSibling, выполнить следующие шаги:

  1. Сделать interested observers изначально пустым набором объектов MutationObserver опционально в паре со строкой.

  2. Сделать nodes включительными предками для target.

  3. Затем, для каждого node в nodes, и затем для каждого registered observerопциями registered observer как options) в списке зарегистрированных наблюдателей node:

    1. Если node не является target и subtree options-й является false, то продолжить.

    2. Если type является "attributes" и attributes options-й не является true, то продолжить.

    3. Если type является "attributes", attributeFilter options-й представлен, и attributeFilter options-й не содержит name или namespace является не-null, то продолжить.

    4. Если type является "characterData" и characterData options-й не является true, то продолжить.

    5. Если type является "childList" и childList options-й является false, продолжить.

    6. Если наблюдатель registered observer не в interested observers, добавить observer registered observer-а к interested observers.

    7. Если type является "attributes" и attributeOldValue options-й является true, или type является "characterData" и characterDataOldValue options-й является true, установить парную строку наблюдателя registered observer-а в interested observers к oldValue.

  4. Затем, для каждого observer в interested observers:

    1. Сделать record новым объектом MutationRecord с его type установленным к type и target установленным к target.

    2. Если name и namespace заданы, установить attributeName record-а к name, и attributeNamespace record-а к namespace.

    3. Если addedNodes задан, установить addedNodes record-а к addedNodes.

    4. Если removedNodes задан, установить removedNodes record-а к removedNodes,

    5. Если previousSibling задан, установить previousSibling record-а к previousSibling.

    6. Если nextSibling задан, установить nextSibling record-а к nextSibling.

    7. Если observer имеет парную строку, установить oldValue record-а к парной строке observer-а.

    8. Добавить record к очереди записи observer-а.

  5. Поставить в очередь составную микрозадачу наблюдателя изменений.

4.3.3 Интерфейс MutationRecord

[Exposed=Window]
interface MutationRecord {
  readonly attribute DOMString type;
  readonly attribute Node target;
  [SameObject] readonly attribute NodeList addedNodes;
  [SameObject] readonly attribute NodeList removedNodes;
  readonly attribute Node? previousSibling;
  readonly attribute Node? nextSibling;
  readonly attribute DOMString? attributeName;
  readonly attribute DOMString? attributeNamespace;
  readonly attribute DOMString? oldValue;
};
record . type

Возвращает "attributes" если это было изменение атрибута. "characterData" если это было изменение CharacterData узла. И "childList" если это было изменение дерева узлов.

record . target

Возвращает узел который изменение затронуло, основываясь на type. Для "attributes", это элемент чей атрибут был изменен. Для "characterData", это CharacterData узел. Для "childList", это узел чей дочерний был изменен.

record . addedNodes
record . removedNodes

Возвращает добавленные и удаленные узлы соответственно.

record . previousSibling
record . nextSibling

Возвращает предыдущий и следующий сестринский добавленных и удаленных узлов соответственно, и null в другом случае.

record . attributeName

Возвращает локальное имя измененного атрибута, и null в другом случае.

record . attributeNamespace

Возвращает пространство имен измененного атрибута, и null в другом случае.

record . oldValue

Возвращаемое значение зависит от type. Для "attributes", это значение измененного атрибута перед изменением. Для "characterData", это данные измененного узла перед изменением. Для "childList", это null.

Атрибуты type и target должны возвращать значения к которым были инициализированы.

Атрибуты addedNodes и removedNodes должны возвращать значения к которым были инициализированы. Если не задано другое, когда объект MutationRecord создан, они оба должны быть инициализированы к пустому NodeList.

Атрибуты previousSibling, nextSibling, attributeName, attributeNamespace и oldValue должны возвращать значения к которым были инициализированы. Если не указано иное, когда объект MutationRecord создан, они должны быть инициализированы к null.

4.3.4 Сборка мусора

Узлы имеют сильное отношение к зарегистрированным наблюдателям в их списке зарегистрированных наблюдателей.

Зарегистрированные наблюдатели в списке зарегистрированных наблюдателей узла имеют слабое отношение к узлу.

4.4 Интерфейс Node

[Exposed=Window]
interface Node : EventTarget {
  const unsigned short ELEMENT_NODE = 1;
  const unsigned short ATTRIBUTE_NODE = 2; // historical
  const unsigned short TEXT_NODE = 3;
  const unsigned short CDATA_SECTION_NODE = 4; // historical
  const unsigned short ENTITY_REFERENCE_NODE = 5; // historical
  const unsigned short ENTITY_NODE = 6; // historical
  const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
  const unsigned short COMMENT_NODE = 8;
  const unsigned short DOCUMENT_NODE = 9;
  const unsigned short DOCUMENT_TYPE_NODE = 10;
  const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
  const unsigned short NOTATION_NODE = 12; // historical
  readonly attribute unsigned short nodeType;
  readonly attribute DOMString nodeName;

  readonly attribute DOMString? baseURI;

  readonly attribute Document? ownerDocument;
  readonly attribute Node? parentNode;
  readonly attribute Element? parentElement;
  boolean hasChildNodes();
  [SameObject] readonly attribute NodeList childNodes;
  readonly attribute Node? firstChild;
  readonly attribute Node? lastChild;
  readonly attribute Node? previousSibling;
  readonly attribute Node? nextSibling;

           attribute DOMString? nodeValue;
           attribute DOMString? textContent;
  void normalize();

  [NewObject] Node cloneNode(optional boolean deep = false);
  boolean isEqualNode(Node? node);

  const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
  const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
  const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
  const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
  const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
  const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
  unsigned short compareDocumentPosition(Node other);
  boolean contains(Node? other);

  DOMString? lookupPrefix(DOMString? namespace);
  DOMString? lookupNamespaceURI(DOMString? prefix);
  boolean isDefaultNamespace(DOMString? namespace);

  Node insertBefore(Node node, Node? child);
  Node appendChild(Node node);
  Node replaceChild(Node node, Node child);
  Node removeChild(Node child);
};

Заметка: Node является абстрактным интерфейсом и не существует как узел. Он используется всеми узлами (Document, DocumentFragment, DocumentType, Element, Text, ProcessingInstruction и Comment).

Каждый узел имеет ассоциированный документ узла, установленный при создании, который является документом.

Заметка: Документ узла узла может быть изменен с помощью алгоритма принятия.

Каждый узел также имеет ассоциированный базовый URL.

Заметка: Другие спецификации определяют значение базового URL и его наблюдаемое поведение. Эта спецификация определяет только концепт и атрибут baseURI.


node . nodeType

Возвращает тип node, представленный числом из списка ниже:

Node . ELEMENT_NODE (1)
node является элементом.
Node . TEXT_NODE (3)
node является Text узлом.
Node . PROCESSING_INSTRUCTION_NODE (7)
node является ProcessingInstruction узлом.
Node . COMMENT_NODE (8)
node является Comment узлом.
Node . DOCUMENT_NODE (9)
node является документом.
Node . DOCUMENT_TYPE_NODE (10)
node является типом документа.
Node . DOCUMENT_FRAGMENT_NODE (11)
node является DocumentFragment узлом.
node . nodeName

Возвращает строку соответствующую для типа node, а именно:

Element
Его значение атрибута tagName.
Text
"#text".
ProcessingInstruction
Его цель.
Comment
"#comment".
Document
"#document".
DocumentType
Его имя.
DocumentFragment
"#document-fragment".

Атрибут nodeType должен возвратить тип узла, который должен быть одним из следующих:

Атрибут nodeName должен возвратить следующее, в зависимости от типа объекта контекста:

Element

Его значение атрибута tagName.

Text

"#text".

ProcessingInstruction

Его цель.

Comment

"#comment".

Document

"#document".

DocumentType

Его имя.

DocumentFragment

"#document-fragment".


node . baseURI

Возвращает базовый URL.

Атрибут baseURI должен возвратить ассоциированный базовый URL.


node . ownerDocument

Возвращает документ узла.

Возвращает null для документов.

node . parentNode

Возвращает родителя.

node . parentElement

Возвращает родительский элемент.

node . hasChildNodes()

Возвращает имеет ли node дочерних.

node . childNodes

Возвращает дочерние.

node . firstChild

Возвращает первый дочерний.

node . lastChild

Возвращает последний дочерний.

node . previousSibling

Возвращает предыдущий сестринский.

node . nextSibling

Возвращает следующий сестринский.

Атрибут ownerDocument должен выполнить следующие шаги:

  1. Если объект контекста является документом, возвратить null.
  2. Возвратить документ узла.

Документ узла документа это сам этот документ.

Все узлы имеют документ в любое время.

Атрибут parentNode должен возвратить родителя.

Атрибут parentElement должен возвратить родительский элемент.

Метод hasChildNodes() должен возвратить true если объект контекста имеет дочерних, и false в другом случае.

Атрибут childNodes должен возвратить NodeList с корнем в объекте контекста соответствующий только дочерним.

Атрибут firstChild должен возвратить первый дочерний.

Атрибут lastChild должен возвратить последний дочерний.

Атрибут previousSibling должен возвратить предыдущий сестринский.

Атрибут nextSibling должен возвратить следующий сестринский.


Атрибут nodeValue должен возвратить следующее, в зависимости от объекта контекста:

Text
Comment
ProcessingInstruction

Данные объекта контекста.

Любой другой узел

Null.

Атрибут nodeValue должен, при установке, если новое значение является null, действовать как если бы это была пустая строка, затем выполнить описанное ниже, в зависимости от объекта контекста:

Text
Comment
ProcessingInstruction

Заменить данные на узел объекта контекста, смещение 0, подсчет на значение атрибута length, и данные на новое значение.

Любой другой узел

Не делать ничего.

Атрибут textContent должен возвратить следующее, в зависимости от объекта контекста:

DocumentFragment
Element

Конкатенация данных всех потомков узла Text объекта контекста, в порядке дерева.

Text
ProcessingInstruction
Comment

Данные объекта контекста.

Любой другой узел

Null.

Атрибут textContent должен, при установке, если новое значение является null, действовать как если бы это была пустая строка, затем выполнить описанное ниже, в зависимости от объекта контекста:

DocumentFragment
Element
  1. Сделать node null.

  2. Если новое значение не является пустой строкой, установить node к новому узлу Text, чьи данные это новое значение.

  3. Заменить всё на node внутри объекта контекста.

Text
ProcessingInstruction
Comment

Заменить данные на узел объекта контекста, смещение 0, подсчет на значение атрибута длины, и данные на новое значение.

Любой другой узел

Не делать ничего


node . normalize()

Удаляет пустой узел Text и конкатенирует данные остающихся смежных Text узлов в первые их узлы.

Метод normalize() должен выполнить следующие шаги:

Для каждого потомка узла Text объекта контекста:

  1. Сделать node потомком узла Text.

  2. Сделать length значением атрибута length node.

  3. Если length равняется нолю, удалить node и продолжить со следующим Text узлом, если имеется.

  4. Сделать data конкатенацией данных смежных Text узлов node (за исключением себя), в порядке дерева.

  5. Заменить данные на узел node, смещение length, подсчет 0, и данные data.

  6. Сделать current node следующим сестринским node.

  7. Пока current node является Text узлом:

    1. Для каждого диапазона, чей начальный узел это current node, добавить length к его начальному смещению и установить его начальный узел к node.

    2. Для каждого диапазона, чей конечный узел это current node, добавить length к его конечному смещению и установить его конечный узел к node.

    3. Для каждого диапазона, чей начальный узел это родитель current node и начальное смещение это индекс current node, установить его начальный узел к node и его начальное смещение к length.

    4. Для каждого диапазона, чей конечный узел является родителем current node и конечное смещение является индексом current node, установить его конечный узел к node и его конечное смещение к length.

    5. Добавить значение атрибута length current node к length.

    6. Установить current node к его следующему сестринскому.

  8. Удалить смежные Text узлы node (за исключением его самого), в порядке дерева.


node . cloneNode([deep = false])

Возвращает копию node. Если deep является true, копия также включает потомков node.

node . isEqualNode(other)

Возвращает имеют ли node и other одинаковые свойства.

Спецификации могут определять шаги клонирования для всех или некоторых узлов. Алгоритм передает copy, node, document и опционально clone children flag, как указано в алгоритме клонирования.

Заметка: HTML определяет шаги клонирования для элементов script и input. SVG должен делать то же самое для его элементов script, но не называет это на данный момент.

Чтобы клонировать node, опционально с document и флагом клонирования дочерних, выполнить данные шаги:

  1. Если document не задан, сделать document документом узла node.

  2. Сделать copy узлом реализующим те же интерфейсы, что и node.

  3. Если copy является документом, установить его документ узла и document к copy.

    В другом случае, установить документ узла copy к document.

  4. Копировать следующее из node в copy, в зависимости от типа node:

    Document

    Его кодировку, тип контента, URL, его режим (режим совместимости, ограниченный режим совместимости или не-совместимый режим) и его тип (XML документ или HTML документ).

    DocumentType

    Его имя, публичный ID и системный ID.

    Element

    Его пространство имен, префикс пространства имен, локальное имя и его список атрибутов.

    Text
    Comment

    Его данные.

    ProcessingInstruction

    Его цель и данные.

    Любой другой узел

  5. Выполнить любые шаги клонирования определенные для node в других применимых спецификациях, затем передать copy, node, document и флаг клонирования дочерних если установлен, в качестве параметров.

  6. Если флаг клонирования дочерних установлен, клонировать все дочерние node и добавить их к copy, с указанным document и установленным флагом клонирования дочерних.

  7. Возвратить copy.

Метод cloneNode(deep) должен возвратить клон объекта контекста, с установленным флагом клонирования дочерних если deep является true.

Узел A равняется узлу B если все следующие условия равняются true:

Метод isEqualNode(node) должен возвратить true если node не является null и объект контекста равняется node, и false в другом случае.


node . compareDocumentPosition(other)

Возвращает битмаск указывающий позицию other по отношению к node. Следующие биты могут быть установлены:

Node . DOCUMENT_POSITION_DISCONNECTED (1)
Устанавливается когда node и other не находятся в одном дереве.
Node . DOCUMENT_POSITION_PRECEDING (2)
Устанавливается когда other является предшествующим node.
Node . DOCUMENT_POSITION_FOLLOWING (4)
Устанавливается когда other является следующим node.
Node . DOCUMENT_POSITION_CONTAINS (8)
Устанавливается когда other является предком node.
Node . DOCUMENT_POSITION_CONTAINED_BY (16, 10 в шестнадцатеричном)
Устанавливается когда other является потомком node.
node . contains(other)

Возвращает true если other является включительным потомком node, и false в другом случае.

Эти константы compareDocumentPosition() возвращаются как маска:

Метод compareDocumentPosition(other) должен выполнить следующие шаги:

  1. Сделать reference объектом контекста.

  2. Если other и reference это один и тот же объект, возвратить ноль.

  3. Если other и reference не находятся в одном дереве, возвратить результат добавления DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC и DOCUMENT_POSITION_PRECEDING либо DOCUMENT_POSITION_FOLLOWING, с тем ограничением, что это должно быть последовательным, вместе.

    Заметка: Хотя возврат DOCUMENT_POSITION_PRECEDING или DOCUMENT_POSITION_FOLLOWING обычно реализуется с помощью сравнения указателей. В JavaScript могут использоваться реализации Math.random().

  4. Если other является предком reference, возвратить результат добавления DOCUMENT_POSITION_CONTAINS к DOCUMENT_POSITION_PRECEDING.

  5. Если other является потомком reference, возвратить результат добавления DOCUMENT_POSITION_CONTAINED_BY к DOCUMENT_POSITION_FOLLOWING.

  6. Если other является предшествующим reference, возвратить DOCUMENT_POSITION_PRECEDING.

  7. Возвратить DOCUMENT_POSITION_FOLLOWING.

Метод contains(other) должен возвратить true если other является включительным потомком объекта контекста, и false в другом случае (включая когда other является null).


Чтобы найти префикс пространства имен для element с помощью namespace, выполнить следующие шаги:

  1. Если пространство имен element-а является namespace и его префикс пространства имен не null, возвратить его префикс пространства имен.

  2. Если element имеет атрибут чей префикс пространства имен это "xmlns" и значение это namespace, то возвратить первое такое локальное имя атрибута element-а.

  3. Если родительский элемент element-а является null, возвратить результат выполнения поиска префикса пространства имен на этом элементе с помощью namespace. В другом случае, возвратить null.

Чтобы найти пространство имен для node используя prefix в зависимости от node:

Element
  1. Если его пространство имен не является null и его префикс пространства имен является prefix, возвратить пространство имен.

  2. Если он имеет атрибут чье пространство имен является XMLNS пространством имен, префикс пространства имен это "xmlns" и локальное имя это prefix, или если prefix не null и имеет атрибут чье пространство имен является XMLNS пространством имен, префикс пространства имен является null и локальное имя является "xmlns":

    1. Сделать value его значением если это не пустая строка, и null в другом случае.

    2. Возвратить value.

  3. Если его родительский элемент является null, возвратить null.

  4. Возвратить результат выполнения поиска пространства имен на его родительском элементе используя prefix.

Document
  1. Если его элемент документа является null, возвратить null.

  2. Возвратить результат выполнения поиска пространства имен на его элементе документа используя prefix.

DocumentType
DocumentFragment

Возвратить null.

Любой другой узел
  1. Если его родительский элемент является null, возвратить null.

  2. Возвратить результат выполнения поиска пространства имен на его родительском элементе используя prefix.

Метод lookupPrefix(namespace) должен выполнить следующие шаги:

  1. Если namespace является null или пустой строкой, возвратить null.

  2. В другом случае это зависит от объекта контекста:

    Element

    Возвратить результат поиска префикса пространства имен для узла с помощью namespace.

    Document

    Возвратить результат поиска префикса пространства имен для его элемента документа, если он не является null, и null в другом случае.

    DocumentType
    DocumentFragment

    Возвратить null.

    Любой другой узел

    Возвратить результат поиска префикса пространства имен для его родительского элемента, или если он является null, null.

Метод lookupNamespaceURI(prefix) должен выполнить следующие шаги:

  1. Если prefix является пустой строкой, установить его к null.

  2. Возвратить результат выполнения поиска пространства имен для объекта контекста с помощью prefix.

Метод isDefaultNamespace(namespace) должен выполнить следующие шаги:

  1. Если namespace является пустой строкой, установить его к null.

  2. Сделать defaultNamespace результатом выполнения поиска пространства имен для объекта контекста используя null.

  3. Возвратить true если defaultNamespace является тем же что и namespace, и false в другом случае.


Метод insertBefore(node, child) должен возвратить результат предварительной вставки node в объекта контекста перед child.

Метод appendChild(node) должен возвратить результат добавления node к объекту контекста.

Метод replaceChild(node, child) должен возвратить результат замены child на node внутри объекта контекста.

Метод removeChild(child) должен возвратить результат предварительного удаления child из объекта контекста.


Список элементов с локальным именем localName для узла root это HTMLCollection возвращенная следующим алгоритмом:

  1. Если localName является "*" (U+002A), возвратить HTMLCollection с корнем в root, чей фильтр соответствует только элементам.

  2. В другом случае, если документ узла root является HTML документом, возвратить HTMLCollection с корнем в root, чей фильтр соответствует следующим элементам потомкам:

  3. В другом случае, возвратить HTMLCollection с корнем в root, чей фильтр соответствует элементам потомкам, чьи local name это localName.

Когда вызван с тем же аргументом, тот же объект HTMLCollection может быть возвращен, как и в предыдущем вызове.

Список элементов с пространством имен namespace и локальным именем localName для узла root это HTMLCollection возвращенный следующим алгоритмом:

  1. Если namespace является пустой строкой, установить его к null.

  2. Если namespace и localName являются "*" (U+002A), возвратить HTMLCollection с корнем в root, чей фильтр соответствует элементам потомкам.

  3. В другом случае, если namespace является "*" (U+002A), возвратить HTMLCollection с корнем в root, чей фильтр соответствует элементам потомкам чье локальное имя это localName.

  4. В другом случае, если localName является "*" (U+002A), возвратить HTMLCollection с корнем в root, чей фильтр соответствует элементам потомкам чье пространство имен это namespace.

  5. В другом случае, возвратить HTMLCollection с корнем в root, чей фильтр соответствует элементам потомкам чье пространство имен это namespace и локальное имя это localName.

Когда вызван с теми же аргументами, тот же объект HTMLCollection может быть возвращен, как возвращался в предыдущем вызове.

Список элементом с именами классов classNames для node root это HTMLCollection возвращенный следующим алгоритмом:

  1. Сделать classes результатом выполнения парсера упорядоченного множества на classNames.

  2. Если classes является пустым множеством, возвратить пустой HTMLCollection.

  3. Возвратить HTMLCollection с корнем в root, чей фильтр соответствует элементам потомкам, которые имеют все их классы в classes.

    Сравнения для классов должны быть сделаны ASCII регистрозависимым образом, если документ узла root-а в режиме совместимости, и регистрозависимым образом в другом случае.

Когда вызван с тем же аргументом, тот же объект HTMLCollection может быть возвращен, как возвращался в предыдущем вызове.

4.5 Интерфейс Document

[Constructor,
 Exposed=Window]
interface Document : Node {
  [SameObject] readonly attribute DOMImplementation implementation;
  readonly attribute DOMString URL;
  readonly attribute DOMString documentURI;
  readonly attribute DOMString origin;
  readonly attribute DOMString compatMode;
  readonly attribute DOMString characterSet;
  readonly attribute DOMString contentType;

  readonly attribute DocumentType? doctype;
  readonly attribute Element? documentElement;
  HTMLCollection getElementsByTagName(DOMString localName);
  HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
  HTMLCollection getElementsByClassName(DOMString classNames);

  [NewObject] Element createElement(DOMString localName);
  [NewObject] Element createElementNS(DOMString? namespace, DOMString qualifiedName);
  [NewObject] DocumentFragment createDocumentFragment();
  [NewObject] Text createTextNode(DOMString data);
  [NewObject] Comment createComment(DOMString data);
  [NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);

  [NewObject] Node importNode(Node node, optional boolean deep = false);
  Node adoptNode(Node node);

  [NewObject] Event createEvent(DOMString interface);

  [NewObject] Range createRange();

  // NodeFilter.SHOW_ALL = 0xFFFFFFFF
  [NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
  [NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
};

[Exposed=Window]
interface XMLDocument : Document {};

Узлы Document проще называются документами.

Каждый документ имеет ассоциированную кодировку, тип контента и URL. [ENCODING] [URL]

Если не указано другое, кодировка документа это utf-8 кодировка, его тип контента это "application/xml" и URL это "about:blank".

Если не указано иное, происхождение документа это глобально уникальный идентификатор и его effective script origin это зеркало происхождения. [HTML]

документ считается XML документом если только он не помечен как HTML документ. Является ли документ HTML документом или XML документом, это влияет на поведения конкретных API.

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

Заметка: Режим изменяется с режима по умолчанию только лишь когда документ создан HTML парсером, в зависимости от присутствия, отсутствия или значения строки DOCTYPE. [HTML]

Заметка: Не-совместимый режим изначально назывался "стандартным режимом", ограничено-совместимый режим когда-то был известен как "почти стандартный режим". Они были переименованы потому что теперь их детали определены стандартами. (И потому что Ian Hickson наложил вето на их первоначальные имена, потому что они бессмысленны.)


document = new Document()

Возвращает новый документ.

document . implementation

Возвращает объект DOMImplementation document-а.

document . URL
document . documentURI

Возвращает URL document-а.

document . origin

Возвращает происхождение document-а.

document . compatMode

Возвращает строку "CSS1Compat" если document в не-совместимом режиме или ограничено-совместимом режиме, и "BackCompat" если document в режиме совместимости.

document . characterSet

Возвращает кодировку document-а.

document . contentType

Возвращает тип контента document-а.

Конструктор Document() должен возвратить новый документ, чье происхождение является зеркалом к происхождению ассоциированного документа глобального объекта, и effective script origin является зеркалом к effective script origin ассоциированного документа глобального объекта. [HTML]

Заметка: В отличие от createDocument(), этот конструктор возвращает не объект XMLDocument, а документ (объект Document).

Атрибут implementation должен возвратить объект DOMImplementation, который ассоциирован с документом.

Атрибуты URL и documentURI должны возвратить URL.

Атрибут origin должен возвратить Unicode сериализацию происхождения объекта контекста.

Атрибут compatMode должен возвратить "BackCompat" если объект контекста в режиме совместимости, и "CSS1Compat" в другом случае.

Получатель атрибута characterSet и получатель атрибута inputEncoding должны выполнить следующие шаги:

  1. Сделать name именем кодировки.

  2. Если name находится в первой колонке таблицы ниже, установить name к значению второй колонки той же строки:

    Имя Имя совместимости
    utf-8 "UTF-8"
    ibm866 "IBM866"
    iso-8859-2 "ISO-8859-2"
    iso-8859-3 "ISO-8859-3"
    iso-8859-4 "ISO-8859-4"
    iso-8859-5 "ISO-8859-5"
    iso-8859-6 "ISO-8859-6"
    iso-8859-7 "ISO-8859-7"
    iso-8859-8 "ISO-8859-8"
    iso-8859-8-i "ISO-8859-8-I"
    iso-8859-10 "ISO-8859-10"
    iso-8859-13 "ISO-8859-13"
    iso-8859-14 "ISO-8859-14"
    iso-8859-15 "ISO-8859-15"
    iso-8859-16 "ISO-8859-16"
    koi8-r "KOI8-R"
    koi8-u "KOI8-U"
    gbk "GBK"
    big5 "Big5"
    euc-jp "EUC-JP"
    iso-2022-jp "ISO-2022-JP"
    shift_jis "Shift_JIS"
    euc-kr "EUC-KR"
    utf-16be "UTF-16BE"
    utf-16le "UTF-16LE"
  3. Возвратить name.

Атрибут contentType должен возвратить тип контента.


document . doctype

Возвращает doctype или null если его нет.

document . documentElement

Возвращает document element.

collection = document . getElementsByTagName(localName)

Если localName является "*", возвращает HTMLCollection всех элементов потомков.

В другом случае, возвращает HTMLCollection всех элементов потомков, чье локальное имя это localName. (Сравнивается регистронезависимо против элементов в HTML пространстве имен внутри HTML документа.)

collection = document . getElementsByTagNameNS(namespace, localName)

Если namespace и localName являются "*", возвращает HTMLCollection всех элементов потомков.

Если только namespace является "*", возвращает HTMLCollection всех элементов потомков, чье локальное имя это localName.

Если только localName является "*", возвращает HTMLCollection всех элементов потомков, чье пространство имен это namespace.

В другом случае, возвращает HTMLCollection всех элементов потомков, чье пространство имен это namespace и локальное имя это localName.

collection = document . getElementsByClassName(classes)
collection = element . getElementsByClassName(classes)

Возвращает HTMLCollection элементов в объекте на котором метод был вызван (документ или элемент), который имеет все классы заданные в classes.

Аргумент classes интерпретируется как разделенный пробелами список классов.

Атрибут doctype должен возвратить дочерний документа, который является doctype, и null в другом случае.

Атрибут documentElement должен возвратить document element.

Метод getElementsByTagName(localName) должен возвратить список элементов с локальным именем localName для объекта контекста.

Заметка: Таким образом, в HTML документе, под document.getElementsByTagName("FOO") будут подходить элементы FOO, которые не в HTML пространстве имен, и элементы foo, которые в HTML пространстве имен, но не элементы FOO, которые в HTML пространстве имен.

Метод getElementsByTagNameNS(namespace, localName) должен возвратить список элементов с пространством имен namespace и локальным именем localName для объекта контекста.

Метод getElementsByClassName(classNames) должен возвратить список элементов с именами классов classNames для объекта контекста.

На примере следующего XHTML фрагмента:

<div id="example">
  <p id="p1" class="aaa bbb"/>
  <p id="p2" class="aaa ccc"/>
  <p id="p3" class="bbb ccc"/>
</div>

Вызов document.getElementById('example').getElementsByClassName('aaa') возвратил бы HTMLCollection с параграфами p1 и p2 в нем.

Вызов getElementsByClassName('ccc bbb') возвратил бы только один узел, а именно p3. Вызов document.getElementById('example').getElementsByClassName('bbb ccc ') возвратил бы то же самое.

Вызов getElementsByClassName('aaa,bbb') не возвратил бы узлов; ни один из элементов выше не в классе aaa,bbb.


element = document . createElement(localName)

Возвращает элемент в HTML пространстве имен [смотрите баг 19431] с localName в качестве локального имени. (В HTML документе localName строчными буквами.)

Если localName не соответствует производному Name, будет выдано исключение "InvalidCharacterError".

element = document . createElementNS(namespace, qualifiedName)

Возвражает элемент с пространством имен namespace. Его префикс пространства имен будет всем перед ":" (U+003E) в qualifiedName или null. Его локальное имя будет всем после ":" (U+003E) в qualifiedName или qualifiedName.

Если localName не соответствует производному Name, будет выдано исключение "InvalidCharacterError".

Если одно из следующих условий является true, будет выдано исключение "NamespaceError":

documentFragment = document . createDocumentFragment()

Возвращает DocumentFragment узел.

text = document . createTextNode(data)

Возвращает узел Text, чьи данные это data.

comment = document . createComment(data)

Возвращает узел Comment, чьи данные это data.

processingInstruction = document . createProcessingInstruction(target, data)

Возвращает ProcessingInstruction узел, чья цель является target и данные это data.

Если target не соответствует производному Name, будет выдано исключение "InvalidCharacterError".

Если data содержит "?>", будет выдано исключение "InvalidCharacterError".

Элемент интерфейса для любого name и namespace это Element, если не указано другое.

Заметка: Стандарт HTML определит, к примеру, что для html и HTML пространства имен используется интерфейс HTMLHtmlElement. [HTML]

Метод createElement(localName) должен выполнить следующие шаги:

  1. Если localName не соответствует любому производному Name, выдать исключение "InvalidCharacterError".

  2. Если объект контекста является HTML документом, сделать localName конвертированным в ASCII строчные.

  3. Сделать interface элементом интерфейса для localName и HTML пространства имен.

  4. Возвращает новый элемент, который реализует interface, без атрибутов, пространство имен установленное к HTML пространству имен [смотрите баг 19431], локальное имя установленное к localName, и узел документа установленный к объекту контекста.

Метод createElementNS(namespace, qualifiedName) должен выполнить следующие шаги:

  1. Если namespace является пустой строкой, установить его к null.

  2. Если qualifiedName не соответствует производному Name, выдать исключение "InvalidCharacterError".

  3. Если qualifiedName не соответствует производному QName, выдать исключение "NamespaceError".

  4. Если qualifiedName содержит ":" (U+003E), то разделить строку на нем и сделать prefix первой частью, и localName второй частью. В другом случае, сделать prefix null и localName qualifiedName.

  5. Если prefix не является null и namespace является null, выдать a "NamespaceError" исключение.

  6. Если prefix это "xml" и namespace не является XML пространством имен, выдать исключение "NamespaceError".

  7. Если qualifiedName или prefix это "xmlns" и namespace не является XMLNS пространством имен, выдать исключение "NamespaceError".

  8. Если namespace не XMLNS пространство имен и ни qualifiedName, ни prefix не являются "xmlns", выдать исключение "NamespaceError".

  9. Сделать interface элементом интерфейса для localName и namespace.

  10. Возвратить новый элемент, который реализует interface, без атрибутов, пространством имен установленным к namespace, префиксом пространства имен установленным к prefix, локальным именем установленным к localName, и узлом документа установленным к объекту контекста.

Метод createDocumentFragment() должен возвратить новый узел DocumentFragment с его узлом документа установленным к объекту контекста.

Метод createTextNode(data) должен возвратить новый узел Text с его данными установленными к data и узлом документа установленным к объекту контекста.

Заметка: Не выполняется проверка того что data состоит из символов соответствующих производному Char.

Метод createComment(data) должен возвратить новый узел Comment с его данными установленными к data и узлом документа установленным к объекту контекста.

Заметка: Не производится проверка того что data состоит из символов, которые соответствуют производному Char или что он содержит два смежных дефиса или оканчивается на дефис.

Метод createProcessingInstruction(target, data) должен выполнить следующие шаги:

  1. Если target не соответствует производному Name, выдать исключение "InvalidCharacterError".

  2. Если data содержит строку "?>", выдать исключение "InvalidCharacterError".

  3. Возвратить новый узел ProcessingInstruction, с целью установленной к target, данными установленными к data, и узлом документа установленным к объекту контекста.

Заметка: Не выполняется проверка того что target содержит "xml" или ":", или что data содержит символы которые соответствуют производному Char.


clone = document . importNode(node [, deep = false])

Возвращает копию node. Если deep является true, копия также включает потомков node.

Если node является документом, выдает исключение "NotSupportedError".

node = document . adoptNode(node)

Перемещает node из другого документа и возвращает его.

Если node является документом, выдает исключение "NotSupportedError".

Метод importNode(node, deep) должен выполнить следующие шаги:

  1. Если node является документом, выдать исключение "NotSupportedError".

  2. Возвратить клон node, с объектом контекста и установленным флагом клонирования дочерних если deep является true.

Спецификации могут определять шаги принятия для всех или некоторых узлов. Алгоритм передает node и oldDocument, как указано в алгоритме принятия.

Чтобы принять node в document, выполнить следующие шаги:

  1. Сделать oldDocument узлом документа node.

  2. Если родитель node не является null, удалить node из его родителя.

  3. Установить узел документа включительного потомка node к document.

  4. Выполнить любые шаги принятия определенные для node в других применимых спецификациях и передать node и oldDocument в качестве параметров.

Метод adoptNode(node) должен выполнить следующие шаги:

  1. Если node является документом, выдать исключение "NotSupportedError".

  2. Принять node в объект контекста.

  3. Возвратить node.


Метод createEvent(interface) должен выполнить следующие шаги:

  1. Сделать constructor null.

  2. Если interface является ASCII регистрозависимым, сопоставить для любых строк из первой колонки таблицы ниже, установить constructor к интерфейсу из второй колонки того же ряда что и соответствующая строка:

    СтрокаИнтерфейсЗаметки
    "customevent"CustomEvent
    "event"Event
    "events"Event
    "htmlevents"Event
    "keyboardevent"KeyboardEvent[UIEVENTS]
    "keyevents"KeyboardEvent[UIEVENTS]
    "messageevent"MessageEvent[HTML]
    "mouseevent"MouseEvent[UIEVENTS]
    "mouseevents"MouseEvent[UIEVENTS]
    "touchevent"TouchEvent[TOUCHEVENTS]
    "uievent"UIEvent[UIEVENTS]
    "uievents"UIEvent[UIEVENTS]
  3. Если constructor является null, выдать исключение "NotSupportedError".

  4. Сделать event результатом вызова изначального значения constructor с пустой строкой в качестве аргумента.

  5. Снять флаг инициализации event.

  6. Возвратить event.

Заметка: Конструкторы событий могут использоваться вместо этого.


Метод createRange() должен возвратить новый диапазон с (объект контекста, 0) в качестве его начала и конца.

Заметка: Конструктор Range() может использоваться вместо этого.


Метод createNodeIterator(root, whatToShow, filter) должен выполнить следующие шаги:

  1. Создать объект NodeIterator.

  2. Установить корень и инициализировать атрибут referenceNode к аргументу root.

  3. Инициализировать атрибут pointerBeforeReferenceNode к true.

  4. Установить whatToShow к аргументу whatToShow.

  5. Установить фильтр к filter.

  6. Возвратить только что созданный объект NodeIterator.

Метод createTreeWalker(root, whatToShow, filter) должен выполнить следующие шаги:

  1. Создать объект TreeWalker.

  2. Установить корень и инициализировать атрибут currentNode к аргументу root.

  3. Установить whatToShow к аргументу whatToShow.

  4. Установить фильтр к filter.

  5. Возвратить только что созданный объект TreeWalker.

4.5.1 Интерфейс DOMImplementation

Пользовательские агенты должны создавать объект DOMImplementation всякий раз когда документ создан и ассоциировать с этим документом.

[Exposed=Window]
interface DOMImplementation {
  [NewObject] DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
  [NewObject] XMLDocument createDocument(DOMString? namespace, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
  [NewObject] Document createHTMLDocument(optional DOMString title);

  boolean hasFeature(); // useless; always returns true
};
doctype = document . implementation . createDocumentType(qualifiedName, publicId, systemId)

Возвращает doctype, с заданным qualifiedName, publicId и systemId. Если qualifiedName не соответствует производному Name, выдается исключение "InvalidCharacterError", и если он не соответствует производному QName, выдается исключение "NamespaceError".

doc = document . implementation . createDocument(namespace, qualifiedName [, doctype = null])

Возвращает XMLDocument [смотрите баг 22960], с элементом документа чье локальное имя это qualifiedName и чье пространство имен это namespace (кроме случая если qualifiedName является пустой строкой), и с doctype, если он задан, в качестве его типа документа.

Этот метод выдает те же исключения что и createElementNS метод, когда вызван с теми же аргументами.

doc = document . implementation . createHTMLDocument([title])

Возвращает документ, с уже построенным базовым деревом включая элемент title, кроме случае если элемент title опущен.

Метод createDocumentType(qualifiedName, publicId, systemId) должен выполнить следующие шаги:

  1. Если qualifiedName не соответствует производному Name, выдать исключение "InvalidCharacterError".

  2. Если qualifiedName не соответствует производному QName, выдать исключение "NamespaceError".

  3. Возвратить новый тип документа, с qualifiedName в качестве его имени, publicId в качестве публичного ID и systemId в качестве системного ID, и с его документом узла установленным к соответствующему документу объекта контекста.

Заметка: Не производится проверка того что publicId соответствует производному PublicChar или того что systemId не содержит '"' и "'".

Метод createDocument(namespace, qualifiedName, doctype) должен выполнить следующие шаги:

  1. Сделать document новым XMLDocument [смотрите баг 22960].

    Заметка: Этот метод создает XMLDocument, а не обычный документ. Они являются идентичными, за исключением метода развертывания контента load(), на который он полагается. [HTML]

  2. Сделать element null.

  3. Если qualifiedName не является пустой строкой, установить element к результату вызова метода createElementNS() с аргументами namespace и qualifiedName на document. Заново выдать любые исключения.

  4. Если doctype не является null, добавить doctype к document.

  5. Если element не является null, добавить element к document.

  6. Происхождение document-а это зеркало происхождения ассоциированного документа объекта контекста, и effective script origin document-а это зеркало к effective script origin ассоциированного документа объекта контекста. [HTML]

  7. Возвратить document.

Метод createHTMLDocument(title) должен выполнить следующие шаги:

  1. Сделать doc новым документом, который является HTML документом.

  2. Установить тип контента doc-а к "text/html".

  3. Создать тип документа, с "html" в качестве его имени и с его узлом документа установленным к doc. Добавить созданный узел к doc.

  4. Создать элемент html в HTML пространстве имен и добавить его к doc.

  5. Создать элемент head в HTML пространстве имен и добавить его к элементу html созданному в предыдущем шаге.

  6. Если аргумент title не опущен:

    1. Создать элемент title в HTML пространстве имен и добавить его к элементу head созданному в предыдущем шаге.

    2. Создать Text узел, установить его данные к title (который может являться пустой строкой), и добавить его к элементу title созданному в предыдущем шаге.

  7. Создать элемент body в HTML пространстве имен и добавить его к элементу html созданному в предыдущем шаге.

  8. Происхождение doc-а является зеркалом к происхождению ассоциированного документа объекта контекста, и effective script origin doc-а является зеркалом к effective script origin ассоциированного документа объекта контекста. [HTML]

  9. Возвратить doc.

Метод hasFeature() должен возвратить true.

Заметка: Изначально hasFeature() сообщал поддерживает ли агент пользователя заданную функцию DOM, но опыт показал, что это даже не близко так надежно как простая проверка существуют ли нужные объекты, атрибуты или методы. Как таковой, он больше не должен использоваться, но продолжает существовать (и просто возвращать true), таким образом старые страницы не перестают работать.

4.6 Интерфейс DocumentFragment

[Constructor,
 Exposed=Window]
interface DocumentFragment : Node {
};

Узел DocumentFragment может иметь ассоциированный элемент под названием host.

Объект A является хост-содержащим включительным предком объекта B, если A является включительным предком B, либо если корень B имеет ассоциированный хост и A имеет хост-содержащего включительного предка хоста корня B.

Заметка: Концепт хоста узла DocumentFragment полезен для элемента template HTML и объекта ShadowRoot, и влияет на алгоритмы предварительной вставки и замены.

tree = new DocumentFragment()

Возвращает новый узел DocumentFragment.

Конструктор DocumentFragment() должен вернуть новый узел DocumentFragment, чей документ узла это ассоциированный документ глобального объекта.

4.7 Интерфейс DocumentType

[Exposed=Window]
interface DocumentType : Node {
  readonly attribute DOMString name;
  readonly attribute DOMString publicId;
  readonly attribute DOMString systemId;
};

Узлы DocumentType проще называются типом документа.

Типы документа имеют ассоциированное имя, публичный ID и системный ID.

Когда тип документа создан, его имя всегда является заданным. Если оно явно не задано когда тип документа создан, его публичный ID и системный ID являются пустой строкой.

Атрибут name должен возвратить имя.

Атрибут publicId должен возвратить публичный ID.

Атрибут systemId должен возвратить системный ID.

4.8 Интерфейс Element

[Exposed=Window]
interface Element : Node {
  readonly attribute DOMString? namespaceURI;
  readonly attribute DOMString? prefix;
  readonly attribute DOMString localName;
  readonly attribute DOMString tagName;

           attribute DOMString id;
           attribute DOMString className;
  [SameObject] readonly attribute DOMTokenList classList;

  [SameObject] readonly attribute NamedNodeMap attributes;
  DOMString? getAttribute(DOMString name);
  DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
  void setAttribute(DOMString name, DOMString value);
  void setAttributeNS(DOMString? namespace, DOMString name, DOMString value);
  void removeAttribute(DOMString name);
  void removeAttributeNS(DOMString? namespace, DOMString localName);
  boolean hasAttribute(DOMString name);
  boolean hasAttributeNS(DOMString? namespace, DOMString localName);


  HTMLCollection getElementsByTagName(DOMString localName);
  HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
  HTMLCollection getElementsByClassName(DOMString classNames);
};

Узлы Element проще называются элементами.

Элементы имеют ассоциированное пространство имен, префикс пространства имен и локальное имя. Когда элемент создан, его локальное имя всегда задано. Если не заданы явно при создании элемента, его пространство имен и префикс пространства имен являются null.

Элементы также имеют упорядоченный список атрибутов. Если не задан явно при создании элемента, его список атрибутов является пустым. Элемент имеет атрибут A если A в его списке атрибутов.

Применимые спецификации и эта спецификация (могут) использовать крюки атрибут установлен, атрибут изменен, атрибут добавлен и атрибут удален, для дальнейшей обработки значения атрибута.

Чтобы получить атрибут для элемента element при помощи localName и опционально namespace, выполнить следующие шаги:

  1. Если namespace не задан, установить его к null.

  2. Возвратить значение атрибута в списке атрибутов element-а, чье пространство имен является namespace и локальное имя это localName, если он имеет его, и null в другом случае.

Чтобы установить атрибут для элемента element с помощью localName и value, и опционально name, prefix и namespace, выполнить следующие шаги:

  1. Если name не задан, установить его к localName.

  2. Если prefix не задан, установить его к null.

  3. Если namespace не задан, установить его к null.

  4. Сделать attribute атрибутом в списке атрибутов element-а, чье пространство имен является namespace и чье локальное имя является localName, либо null если нет такого атрибута.

  5. Если attribute является null, создать атрибут чье локальное имя это localName, значение это value, имя это name, пространство имен это namespace и префикс пространства имен это prefix, и затем добавить этот атрибут к element и прекратить данные шаги.

  6. Изменить attribute с element на value.

Чтобы изменить атрибут attribute с элемента element на value, выполнить следующие шаги:

  1. Поставить в очередь запись изменения "attributes" для element с именем локального имени attribute-а, пространством имен пространства имен attribute-а, и oldValue значением attribute-а.

  2. Установить значение attribute-а к value.

  3. Атрибут установлен и атрибут изменен.

Чтобы добавить атрибут attribute к элементу element, выполнить следующие шаги:

  1. Поставить в очередь запись изменения "attributes" для element с именем локального имени attribute-а, пространством имен пространства имен attribute-а, и oldValue null.

  2. Добавить attribute к списку атрибутов element-а.

  3. Атрибут установлен и атрибут добавлен.

Чтобы удалить атрибут attribute из элемента element, выполнить следующие шаги:

  1. Поставить в очередь запись изменения "attributes" для element с именем локального имени attribute-а, пространством имен пространства имен attribute-а, и oldValue значением attribute-а.

  2. Удалить attribute из списка атрибутов element-а.

  3. Атрибут удален.


Элементы могут иметь ассоциированный уникальный идентификатор (ID) и иметь ассоциированный объект DOMTokenList. Локальное имя ассоциированного атрибута объекта DOMTokenList это class, и его ассоциированное упорядоченное множество токенов называется классами element-а.

Заметка: Исторически элементы могли иметь несколько идентификаторов, например с помощью использования HTML атрибута id и DTD. Эта спецификация делает ID концептом для DOM и позволяет только один для элемента, заданный атрибутом id.

Когда создан элемент, имеющий атрибут id чье значение не является пустой строкой, либо когда атрибут id element-а является установленным к значению отличному от пустой строки, установить ID элемента к новому значению.

Когда атрибут id elementудален или установлен к пустой строке, снять ID element-а.

Когда создан элемент, имеющий атрибут class, либо когда атрибут class элемента установлен, установить классы element-а к новому значению, обработанному.

Когда атрибут class elementудален, установить классы element-а к пустой строке.

Заметка: В то время как эта спецификация определяет требования к обработке пользовательскими агентами атрибутов id и class на любых элементах, она не делает заявлений о соответствии их использования.


Родитель узла типа Element называется родительским элементом. Если узел имеет родителя другого типа, его родительский элемент является null.

Элемент документа документа это элемент чей родитель является этим документом, если существует, и null в другом случае.

Заметка: Из-за ограничений дерева узлов может быть только один такой элемент.

Когда элемент или один из его предков является элементом документа, он в документе.


namespace = element . namespaceURI

Возвращает пространство имен.

prefix = element . prefix

Возвращает префикс пространства имен.

localName = element . localName

Возвращает локальное имя.

qualifiedName = element . tagName

Если префикс пространства имен не является null, возвращает конкатенацию префикса пространства имен, ":" и локального имени. В другом случае он возвращает локальное имя. (Возвращаемое значение капсом для HTML документа.)

Атрибут namespaceURI должен возвратить пространство имен объекта контекста.

Атрибут prefix должен возвратить префикс пространства имен объекта контекста.

Атрибут localName должен возвратить локальное имя объекта контекста.

Атрибут tagName должен выполнить следующие шаги:

  1. Если префикс пространства имен объекта контекста не является null, сделать qualified name его префиксом пространства имен, идущим перед ":" (U+003A), который идет перед локальным именем. В другом случае, сделать qualified name его локальным именем.

  2. Если объект контекста в HTML пространстве имен и его узел документа является HTML документом, сделать qualified name конвертированным в ASCII верхний регистр.

  3. Возвратить qualified name.


Некоторые атрибуты IDL должны отражать конкретное содержание атрибута заданного имени. Это означает что при получении данные шаги должны быть выполнены:

  1. Получить атрибут для объекта контекста используя имя атрибута содержимого и сделать value результатом.

  2. Если value является null, возвратить пустую строку.

  3. Возвратить value.

При установке, установить атрибут для объекта контекста используя имя атрибута и заданное значение.

Атрибут id должен отражать атрибут содержимого "id".

Атрибут className должен отражать атрибут содержимого "class".

Атрибут classList должен возвратить ассоциированный объект DOMTokenList представляющий классы объекта контекста.


Атрибут attributes должен возвратить NamedNodeMap.

Метод getAttribute(name) должен выполнить следующие шаги:

  1. Если объект контекста я HTML пространстве имен и его документ узла в HTML документе, сделать name конвертированным в ASCII строчные.

  2. Возвратить значение первого атрибута в списке атрибутов объекта контекста чье имя является name, и null в другом случае.

Метод getAttributeNS(namespace, localName) должен выполнить следующие шаги:

  1. Если namespace является пустой строкой, установить его к null.

  2. Возвратить получение атрибута для объекта контекста используя localName и namespace.

Метод setAttribute(name, value) должен выполнить следующие шаги:

  1. Если name не соответствует производному Name в XML, выдать исключение "InvalidCharacterError".

  2. Если context object is in the HTML пространство имен и его документ узла являются HTML документом, сделать name конвертированным в ASCII строчные.

  3. Сделать attribute первым атрибутом в списке атрибутов объекта контекста чье имя является name, либо null если нет такого атрибута.

  4. Если attribute является null, создать атрибут чье локальное имя является name и значение это value, затем добавить этот атрибут к объекту контекста и прекратить эти шаги.

  5. Изменить attribute с объекта контекста на value.

Метод setAttributeNS(namespace, name, value) должен выполнить следующие шаги:

  1. Если namespace является пустой строкой, установить его к null.

  2. Если name не соответствует производному Name в XML, выдать исключение "InvalidCharacterError".

  3. Если name не соответствует производному QName в Пространствах имен XML, выдать исключение "NamespaceError".

  4. Если name содержит ":" (U+003E), то разделить строку на нем и сделать prefix первой частью и localName второй частью. В другом случае, сделать prefix null и localName name.

  5. Если prefix не является null и namespace является null, выдать a "NamespaceError" исключение.

  6. Если prefix является "xml" и namespace не в XML пространстве имен, выдать исключение "NamespaceError".

  7. Если name или prefix является "xmlns" и namespace не XMLNS пространство имен, выдать "NamespaceError" исключение.

  8. Если namespace является XMLNS пространством имен, и ни name, ни prefix не являются "xmlns", выдать "NamespaceError" исключение.

  9. Установить атрибут для объекта контекста используя localName, value и также name, prefix, namespace.

Метод removeAttribute(name) должен выполнить следующие шаги:

  1. Если объект контекста в HTML пространстве имен и его документ узла это HTML документ, сделать name конвертированным в ASCII строчные.

  2. Удалить первый атрибут из объекта контекста чье имя является name, если есть.

Метод removeAttributeNS(namespace, localName) должен выполнить следующие шаги:

  1. Если namespace является пустой строкой, установить его к null.

  2. Удалить атрибут из объекта контекста чье пространство имен является namespace и локальное имя это localName, если есть.

Метод hasAttribute(name) должен выполнить следующие шаги:

  1. Если объект контекста в HTML пространстве имен и его документ узла это HTML документ, сделать name конвертированным в ASCII строчные.

  2. Возвратить true если объект контекста имеет атрибут чье имя это name, и false в другом случае.

Метод hasAttributeNS(namespace, localName) должен выполнить следующие шаги:

  1. Если namespace является пустой строкой, установить его к null.

  2. Возвратить true если объект контекста имеет атрибут чье пространство имен это namespace и локальное имя это localName, и false в другом случае.


Метод getElementsByTagName(localName) должен возвратить список элементов с локальным именем localName для объекта контекста.

Метод getElementsByTagNameNS(namespace, localName) должен возвратить список элементов с пространством имен namespace и локальным именем localName для объекта контекста.

Метод getElementsByClassName(classNames) должен возвратить список элементов с именами классов classNames для объекта контекста.

4.8.1 Интерфейс Attr

[Exposed=Window]
interface Attr {
  readonly attribute DOMString? namespaceURI;
  readonly attribute DOMString? prefix;
  readonly attribute DOMString localName;
  readonly attribute DOMString name;
           attribute DOMString value;

  readonly attribute boolean specified; // useless; always returns true
};

Объекты Attr проще называются атрибутами. Их иногда называют атрибутами контента, чтобы избежать путаницы с IDL атрибутами.

Атрибуты имеют пространство имен (null или не-пустая строка), префикс пространства имен (null или не-пустая строка), локальное имя (не-пустая строка), имя (не-пустая строка), значение (строка) и элемент (null или элемент).

Заметка: Если бы были разработаны сегодня, они бы имели просто имя и значение.

Когда атрибут создан, его локальное имя и значение всегда заданы. Если не заданы явно при создании атрибута, его имя идентично его локальному имени, его пространство имен и префикс пространства имен являются null.

Атрибут A является атрибутом, чье локальное имя это A и чьи пространство имен и префикс пространства имен являются null.

Атрибут namespaceURI должен возвратить пространство имен.

Атрибут prefix должен возвратить префикс пространства имен.

Атрибут localName должен возвратить локальное имя.

Получатель атрибута name должен возвратить имя.

Получатель атрибута value и получатель атрибута textContent должны (оба) возвратить значение.

Установка атрибута value должна изменить значение к новому значению.

Установщик атрибута value и установщик атрибута textContent должны (оба) выполнить следующие шаги:

  1. Если элемент объекта контекста является null, установить значение объекта контекста к заданному значению.

  2. В другом случае, изменить объект контекста с элемента объекта контекста на заданное значение.

В отличие от элемента узла, никакой специальной обработки null не требуется.

Атрибут specified должен возвратить true.

4.9 Интерфейс CharacterData

[Exposed=Window]
interface CharacterData : Node {
  [TreatNullAs=EmptyString] attribute DOMString data;
  readonly attribute unsigned long length;
  DOMString substringData(unsigned long offset, unsigned long count);
  void appendData(DOMString data);
  void insertData(unsigned long offset, DOMString data);
  void deleteData(unsigned long offset, unsigned long count);
  void replaceData(unsigned long offset, unsigned long count, DOMString data);
};

Заметка: CharacterData является абстрактным интерфейсом и не существует в виде узла. Он используется узлами Text, Comment и ProcessingInstruction.

Каждый узел наследующий интерфейс CharacterData имеет ассоциированную подверженную изменениям строку под названием данные.

Чтобы заменить данные узла node на смещение offset, подсчет count и данные data, выполнить следующие шаги:

  1. Сделать length значением атрибута length node-ы.

  2. Если offset больше чем length, выдать исключение "IndexSizeError".

  3. Если offset плюс count больше чем length, сделать count результатом length минус offset.

  4. Поставить в очередь запись изменения "characterData" для node с oldValue данными node.

  5. Вставить data в данные node-ы после offset единиц кода.

  6. Сделать delete offset результатом offset плюс количество единиц кода в data.

  7. Начиная с единиц кода delete offset, удалить единицы кода count из данных node.

  8. Для каждого диапазона, чей начальный узел это node и начальное смещение больше чем offset, но менее или равно offset плюс count, установить его начальное смещение к offset.

  9. Для каждого диапазона, чей конечный узел это node и конечное смещение больше чем offset, но менее или равно offset плюс count, установить его конечное смещение к offset.

  10. Для каждого диапазона, чей начальный узел это node и начальное смещение больше чем offset плюс count, увеличить его начальное смещение на количество единиц кода в data, затем уменьшить его на count.

  11. Для каждого диапазона, чей конечный узел это node и конечное смещение больше чем offset плюс count, увеличить его конечное смещение на количество единиц кода в data, затем уменьшить его на count.

Чтобы извлечь данные с узла node, смещения offset и подсчета count, выполнить следующие шаги:

  1. Сделать length значением атрибута length node.

  2. Если offset больше чем length, выдать "IndexSizeError" исключение.

  3. Если offset плюс count больше чем length, возвратить строку чье значение это единицы кода от offset единицы кода до конца данных node, и затем прекратить данные шаги.

  4. Возвратить строку чье значение это единицы кода от offset единицы кода до offset+count единицы кода в данных node.

Атрибут data должен возвратить данные, а при установке, должен заменить данные на узел объекта контекста смещение 0, подсчет на значение атрибута length и данные на новое значение.

Атрибут length должен возвратить количество единиц кода в данных.

Метод substringData(offset, count) должен извлечь данные из узла объекта контекста, смещения offset и подсчета count.

Метод appendData(data) должен заменить данные на узел объекта контекста, смещение на значение атрибута length, подсчет 0, и данные data.

Метод insertData(offset, data) должен заменить данные на узел объекта контекста, смещение offset, подсчет 0, и данные data.

Метод deleteData(offset, count) должен заменить данные на узел объекта контекста, смещение offset, подсчет count и данные на пустую строку.

Метод replaceData(offset, count, data) должен заменить данные на узел объекта контекста, смещение offset, подсчет count и данные data.

4.10 Интерфейс Text

[Constructor(optional DOMString data = ""),
 Exposed=Window]
interface Text : CharacterData {
  [NewObject] Text splitText(unsigned long offset);
  readonly attribute DOMString wholeText;
};
text = new Text([data = ""])

Возвращает новый узел Text, чьи данные data это data.

text . splitText(offset)

Разделяет данные на заданном offset и возвращает остальное как узел Text.

text . wholeText

Возвращает комбинированные данные всех прямых сестринских узла Text.

Конструктор Text(data) должен возвратить новый node Text, чьи данные это data и документ узла это ассоциированный документ глобального объекта.

Чтобы разделить узел Text node со смещением offset, выполнить следующие шаги:

  1. Сделать length значением атрибута length node.

  2. Если offset больше чем length, выдать "IndexSizeError" исключение.

  3. Сделать count результатом length минус offset.

  4. Сделать new data результатом извлечения данных с узла node, смещения offset и подсчета count.

  5. Сделать new node новым узлом Text, с тем же документом узла что и node. Установить данные new node к new data.

  6. Сделать parent родителем node.

  7. Если parent не является null, выполнить следующие шаги:

    1. Вставить new node в parent перед следующим сестринским node.

    2. Для каждого диапазона, чей начальный узел это node и начальное смещение больше чем offset, установить его начальный узел к new node и уменьшить его начальное смещение на offset.

    3. Для каждого диапазона, чей конечный узел это node и конечное смещение больше чем offset, установить его конечный узел к new node и уменьшить его конечное смещение на offset.

    4. Для каждого диапазона, чей начальный узел это parent и начальное смещение равняется индексу node + 1, увеличить его начальное смещение на один.

    5. Для каждого диапазона, чей конечный узел это parent и конечное смещение равняется индексу node + 1, увеличить его конечное смещение на один.

  8. Заменить данные на узел node, смещение offset, подсчет count и данные на пустую строку.

  9. Если parent является null, выполнить следующие подшаги:

    1. Для каждого диапазона, чей начальный узел это node и начальное смещение больше чем offset, установить его начальное смещение к offset.

    2. Для каждого диапазона, чей конечный узел это node и конечное смещение больше чем offset, установить его конечное смещение к offset.

  10. Возвратить new node.

Метод splitText(offset) должен разделить объект контекста со смещением offset.

Смежные Text узлы узла это сам узел, предыдущий сестринский Text узел (если есть) и его смежные Text узлы, и следующий сестринский Text узел (если есть) со своими смежными Text узлами, избегая дубликатов.

Атрибут wholeText должен возвратить конкатенацию данных смежных Text узлов объекта контекста, в порядке дерева.

4.11 Интерфейс ProcessingInstruction

[Exposed=Window]
interface ProcessingInstruction : CharacterData {
  readonly attribute DOMString target;
};

Узлы ProcessingInstruction имеют ассоциированную цель.

Атрибут target должен возвратить цель.

4.12 Интерфейс Comment

[Constructor(optional DOMString data = ""),
 Exposed=Window]
interface Comment : CharacterData {
};
comment = new Comment([data = ""])

Возвращает новый узел Comment, чьи данные являются data.

Конструктор Comment(data) должен возвратить новый узел Comment, чьи данные являются data и документ узла это ассоциированный документ глобального объекта.

5 Диапазоны

5.1 Введение в "DOM Ranges"

Объект Range (диапазон) представляет собой последовательность содержания в дереве узлов. Каждый диапазон имеет начало и конец, которые являются конечными точками. Конечная точка является набором, содержащим узел и не-отрицательное числовое смещение. Так что другими словами, диапазон представляет собой часть содержания внутри дерева элементов между двумя конечными точками.

Диапазоны часто используются при редактировании для выделения и копирования контента.

В дереве узлов выше, диапазон может использоваться для представления предложения “syndata is awes”. Предполагая, что p присваивается p элементу и em присваивается em элементу, это можно сделать следующим образом:

var range = new Range(),
    firstText = p.childNodes[1],
    secondText = em.firstChild
range.setStart(firstText, 9) // не забудьте пробел
range.setEnd(secondText, 4)
// теперь диапазон принадлежит к вышеупомянутой цитате

Заметка: Атрибуты такие как src и alt в дереве узлов выше не могут быть представлены с помощью диапазона. Концепт диапазонов полезен только для узлов.

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

Заметка: Смотрите алгоритмы вставки и удаления, метод normalize(), алгоритмы замены данных и разделения для более подробных деталей.

5.2 Интерфейс Range

[Constructor,
 Exposed=Window]
interface Range {
  readonly attribute Node startContainer;
  readonly attribute unsigned long startOffset;
  readonly attribute Node endContainer;
  readonly attribute unsigned long endOffset;
  readonly attribute boolean collapsed;
  readonly attribute Node commonAncestorContainer;

  void setStart(Node node, unsigned long offset);
  void setEnd(Node node, unsigned long offset);
  void setStartBefore(Node node);
  void setStartAfter(Node node);
  void setEndBefore(Node node);
  void setEndAfter(Node node);
  void collapse(optional boolean toStart = false);
  void selectNode(Node node);
  void selectNodeContents(Node node);

  const unsigned short START_TO_START = 0;
  const unsigned short START_TO_END = 1;
  const unsigned short END_TO_END = 2;
  const unsigned short END_TO_START = 3;
  short compareBoundaryPoints(unsigned short how, Range sourceRange);

  void deleteContents();
  [NewObject] DocumentFragment extractContents();
  [NewObject] DocumentFragment cloneContents();
  void insertNode(Node node);
  void surroundContents(Node newParent);

  [NewObject] Range cloneRange();
  void detach();

  boolean isPointInRange(Node node, unsigned long offset);
  short comparePoint(Node node, unsigned long offset);

  boolean intersectsNode(Node node);

  stringifier;
};

Объекты Range проще называются диапазонами.

Граничная точка это (узел, смещение) набор, в котором смещение это не-негативное целое число.

Заметка: В общем говоря, смещение граничной точки будет между нолем и длиной узла граничной точки, включительно. Алгоритмы которые изменяют дерево (в частности алгоритмы вставки, удаления, замены данных и разделения) также изменяют диапазоны связанные с этим деревом.

Если два узла от граничных точек (узел A, смещение A) и (узел B, смещение B) имеют тот же корень, положение первого по отношению ко второму является перед, равно или после, как возвращается следующим алгоритмом:

  1. Если node A тот же что и node B, возвратить equal если offset A тот же что и offset B, before если offset A меньше чем offset B, и after если offset A больше чем offset B.

  2. Если node A является следующей за node B, вычислить положение (node B, offset B) по отношению к (node A, offset A). Если оно перед, возвратить after. Если оно после, возвратить before.

  3. Если node A является предком для node B:

    1. Сделать child равным node B.

    2. Пока child не является дочерним от node A, установить child к его родительскому.

    3. Если индекс child-а меньше чем offset A, возвратить after.

  4. Возвратить before.

Каждый диапазон имеет две соответствующих граничных точкиначальная и конечная.

Для удобства, начальный узел это узел начала, начальное смещение это смещение начала, конечный узел это узел конца, и конечное смещение это узел конца.

Корень диапазона это корень его начального узла.

Узел node содержится в диапазоне range если корень node тот же, что и корень диапазона, и (node, 0) идет после начала range, и (node, длина node) идет перед концом range.

Узел частично содержится в диапазоне если он является включительным предком начального узла диапазона, но не его конечного узла, и наоборот.

Некоторые факты, чтобы лучше понять эти определения:


range = new Range()

Возвращает новый диапазон.

Конструктор Range() должен возвратить новый диапазон с (соответствующим документом главного объекта, 0) как его начало и конец.


node = range . startContainer

Возвращает начальный узел диапазона.

offset = range . startOffset

Возвращает начальное смещение диапазона.

node = range . endContainer

Возвращает конечный узел диапазона.

offset = range . endOffset

Возвращает конечное смещение диапазона.

collapsed = range . collapsed

Возвращает true если начало диапазона и конец являются одним и тем же, и false в другом случае.

container = range . commonAncestorContainer

Возвращает узел дальний от документа, который является предком начального узла и конечного узла диапазона.

Атрибут startContainer должен возвратить начальный узел.

Атрибут startOffset должен возвратить начальное смещение.

Атрибут endContainer должен возвратить конечный узел.

Атрибут endOffset должен возвратить конечное смещение.

Атрибут collapsed должен возвратить true если начало является тем же что и конец, и false в другом случае.

Атрибут commonAncestorContainer должен выполнить следующие шаги:

  1. Сделать container начальным узлом.

  2. Пока container не является включительным предком конечного узла, сделать container родителем container-а.

  3. Возвратить container.


Чтобы установить начало или конец диапазона к граничной точке (node, offset), выполнить следующие шаги:

  1. Если node является doctype, выдать исключение "InvalidNodeTypeError".

  2. Если offset больше чем длина node, выдать исключение "IndexSizeError".

  3. Сделать bp граничной точкой (node, offset).

  4. Если эти шаги были вызваны как "установка начала"
    1. Если bp идет после конца диапазона, или если корень диапазона не равен корню узла, установить конец диапазона к bp.

    2. Установить начало диапазона к bp.

    Если эти шаги были вызваны как "установка конца"
    1. Если bp идет перед началом диапазона, или если корень диапазона является корнем узла, установить начало диапазона к bp.

    2. Установить конец диапазона к bp.

Метод setStart(node, offset) должен установить начало объекта контекста к граничной точке (node, offset).

Метод setEnd(node, offset) должен установить конец объекта контекста к граничной точке (node, offset).

Метод setStartBefore(node) должен выполнить следующие шаги:

  1. Сделать parent родителем node.

  2. Если parent является null, выдать "InvalidNodeTypeError" исключение.

  3. Установить начало объекта контекста к граничной точке (parent, индексу node).

Метод setStartAfter(node) должен выполнить следующие шаги:

  1. Сделать parent родителем node.

  2. Если parent является null, выдать исключение "InvalidNodeTypeError".

  3. Установить начало объекта контекста к граничной точке (parent, индексу node плюс один).

Метод setEndBefore(node) должен выполнить следующие шаги:

  1. Сделать parent родителем node.

  2. Если parent является null, выдать исключение "InvalidNodeTypeError".

  3. Установить конец объекта контекста к граничной точке (parent, индексу node).

Метод setEndAfter(node) должен выполнить следующие шаги:

  1. Сделать parent родителем node.

  2. Если parent является null, выдать "InvalidNodeTypeError" исключение.

  3. Установить конец объекта контекста к граничной точке (parent, индексу node плюс один).

Метод collapse(toStart), когда вызван, должен если toStart является true, установить конец к началу, или установить начало к концу в другом случае.

Чтобы выбрать узел node внутри диапазона range, выполнить следующие шаги:

  1. Сделать parent родителем node.

  2. Если parent является null, выдать "InvalidNodeTypeError".

  3. Сделать index индексом node.

  4. Установить начало диапазона к граничной точке (parent, index).

  5. Установить конец диапазона к граничной точке (parent, index плюс один).

Метод selectNode(node) должен выбрать node внутри объекта контекста.

Метод selectNodeContents(node) должен выполнить следующие шаги:

  1. Если node является doctype, выдать "InvalidNodeTypeError".

  2. Сделать length длиной node.

  3. Установить начало к граничной точке (node, 0).

  4. Установить конец к граничной точке (node, length).


Метод compareBoundaryPoints(how, sourceRange) должен выполнить следующие шаги:

  1. Если how не является одним из

    выдать исключение "NotSupportedError".

  2. Если корень объекта контекста не тот же что и корень sourceRange, выдать исключение "WrongDocumentError".

  3. Если how является:

    START_TO_START:

    Сделать эту точку началом объекта контекста.

    Сделать другую точку началом sourceRange.

    START_TO_END:

    Сделать эту точку концом объекта контекста.

    Сделать другую точку началом sourceRange.

    END_TO_END:

    Сделать эту точку концом объекта контекста.

    Сделать другую точку концом sourceRange.

    END_TO_START:

    Сделать эту точку началом объекта контекста.

    Сделать другую точку концом sourceRange.

  4. Если положение этой точки по отношению к другой точке является

    перед
    Возвратить −1.
    равно
    Возвратить 0.
    после
    Возвратить 1.

Метод deleteContents() должен выполнить следующие шаги:

  1. Если начало равняется концу, прекратить данные шаги.

  2. Сделать original start node, original start offset, original end node и original end offset начальным узлом, начальным смещением, конечным узлом и конечным смещением объекта контекста соответственно.

  3. Если original start node и original end node являются одним и тем же, и они являются узлами Text, ProcessingInstruction или Comment, заменить данные на узел original start node, смещение original start offset, подсчет original end offset минус original start offset, и данные на пустую строку, и затем прекратить данные шаги.

  4. Сделать nodes to remove списком всех узлов которые содержатся в объекте контекста, в порядке дерева, минуя любые узлы чьи родители также содержатся в объекте контекста.

  5. Если original start node является включительным предком original end node, установить new node к original start node и new offset к original start offset.

  6. В другом случае:

    1. Сделать reference node равным original start node.

    2. Пока родитель reference node не является null и не является включительным предком original end node, установить reference node к его родителю.

    3. Установить new node к родителю reference node, и new offset к одному плюс индекс reference node.

      Заметка: Если бы родитель reference node был null, он был бы корнем объекта контекста, таким образом был бы включительным предком original end node, и мы не смогли бы достичь этой точки.

  7. Если original start node является узлом Text, ProcessingInstruction или Comment, заменить данные на узел original start node, смещение original start offset, подсчет на длину original start node минус original start offset, и данные на пустую строку.

  8. Для каждого узла в nodes to remove, в порядке дерева, удалить узел с его родителя.

  9. Если original end node является узлом Text, ProcessingInstruction или Comment, заменить данные на узел original end node, смещение на 0, подсчет original end offset и данные на пустую строку.

  10. Установить начало и конец к (new node, new offset).

Чтобы извлечь диапазон range, выполнить следующие шаги:

  1. Сделать fragment новым DocumentFragment узла чей документ узла является документом узла стартового узла диапазона.

  2. Если начало диапазона равняется его концу, возвратить fragment.

  3. Сделать original start node, original start offset, original end node и original end offset начальным узлом, начальным смещением, конечным узлом и конечным смещением диапазона соответственно.

  4. Если original start node равняется original end node, и они являются узлами Text, ProcessingInstruction или Comment:

    1. Сделать clone клоном original start node.

    2. Установить данные clone к результату извлечения данных с узла original start node, смещения original start offset, и подсчета original end offset минус original start offset.

    3. Добавить clone к fragment.

    4. Заменить данные на узел original start node, смещение original start offset, подсчет original end offset минус original start offset, и данные на пустую строку.

    5. Возвратить fragment.

  5. Сделать общий предок original start node.

  6. Пока общий предок не является включительным предком original end node, установить общий предок к его собственному родителю.

  7. Сделать первый частично содержащийся дочерний null.

  8. Если original start node не является включительным предком original end node, установить первый частично содержащийся дочерний к первому дочернему общего предка который частично содержится в диапазоне.

  9. Сделать первый частично содержащийся дочерний null.

  10. Если original end node не является включительным предком original start node, установить первый частично содержащийся дочерний к последнему дочернему общего предка который частично содержится в диапазоне.

    Заметка: Эти назначения переменных фактически всегда имеют смысл. Например, если original start node не является включительным предком original end node, сам original start node частично содержится в диапазоне, и также все его предки вплоть до дочернего common ancestor. common ancestor не может быть original start node, потому что он должен быть включительным предком original end node. Другой случай аналогичен. Также заметьте, что два дочерних никогда не равны, если оба являются определенными.

  11. Сделать contained children списком всех дочерних common ancestor которые содержатся в range, в порядке дерева.

  12. Если любой член contained children является doctype, выдать "HierarchyRequestError" исключение.

    Заметка: Мы не должны волноваться о первом или последнем частично содержащемся узле, потому что doctype никогда не может частично содержаться. Он не может быть граничной точкой диапазона и не может быть предком ничего.

  13. Если original start node является включительным предком original end node, установить new node к original start node и new offset к original start offset.

  14. В другом случае:

    1. Сделать reference node равной original start node.

    2. Пока родитель reference node не null и не включительный предок original end node, установить reference node к его родителю.

    3. Установить new node к родителю reference node, и new offset к одному плюс индекс reference node.

      Заметка: Если родитель reference node был бы null, он бы был корнем range, таким образом включительным предком original end node, и мы не смогли бы достигнуть этой точки.

  15. Если first partially contained child является Text, ProcessingInstruction или Comment узлом:

    Заметка: В этом случае first partially contained child является original start node.

    1. Сделать clone клоном original start node.

    2. Установить данные clone к результату извлечения данных с узла original start node, смещения original start offset, и подсчета на длину original start node минус original start offset.

    3. Добавить clone к fragment.

    4. Заменить данные на узел original start node, смещение original start offset, подсчет на длину original start node минус original start offset, и данные на пустую строку.

  16. В другом случае, если first partially contained child не является null:

    1. Сделать clone клоном first partially contained child.

    2. Добавить clone к fragment.

    3. Сделать subrange новым диапазоном, чье начало является (original start node, original start offset) и чей конец является (first partially contained child, длина first partially contained child).

    4. Сделать subfragment результатом извлечения subrange.

    5. Добавить subfragment к clone.

  17. Для каждого contained child в contained children, добавить contained child к fragment.

  18. Если last partially contained child является Text, ProcessingInstruction или Comment узлом:

    Заметка: В этом случае last partially contained child является original end node.

    1. Сделать clone клоном original end node.

    2. Установить данные clone к результату извлечения данных на узел original end node, смещение 0, и подсчет original end offset.

    3. Добавить clone к fragment.

    4. Заменить данные на узел original end node, смещение 0, подсчет original end offset, и данные на пустую строку.

  19. В другом случае, если last partially contained child не является null:

    1. Сделать clone клоном last partially contained child.

    2. Добавить clone к fragment.

    3. Сделать subrange новым диапазоном, чье начало является (last partially contained child, 0) и чей конец является (original end node, original end offset).

    4. Сделать subfragment результатом извлечения subrange.

    5. Добавить subfragment к clone.

  20. Установить начало и конец range к (new node, new offset).

  21. Возвратить fragment.

Метод extractContents() должен возвратить результат извлечения объекта контекста.

Чтобы клонировать диапазон range, выполнить следующие шаги:

  1. Сделать fragment новым узлом DocumentFragment, чей документ узла является документом узла стартового узла range.

  2. Если начало range равняется его концу, возвратить fragment.

  3. Сделать original start node, original start offset, original end node и original end offset начальным узлом, начальным смещением, конечным узлом и конечным смещением range соответственно.

  4. Если original start node равняется original end node, и они являются Text, ProcessingInstruction или Comment узлами:

    1. Сделать clone клоном original start node.

    2. Установить данные clone к результату извлечения данных с узла original start node, смещения original start offset, и подсчета original end offset минус original start offset.

    3. Добавить clone к fragment.

    4. Возвратить fragment.

  5. Сделать original start node общим предком.

  6. Пока common ancestor не является включительным предком original end node, установить common ancestor к его собственному родителю.

  7. Сделать first partially contained child null.

  8. Если original start node не является включительным предком original end node, установить first partially contained child к первому дочернему common ancestor который частично содержится в range.

  9. Сделать last partially contained child null.

  10. Если original end node не является включительным предком original start node, установить last partially contained child к последнему дочернему common ancestor-а, который частично содержится в range.

    Заметка: Эти назначения переменных фактически всегда имеют смысл. Например, если original start node не является включительным предком original end node, сам original start node частично содержится в range, и также все его предки вплоть до дочернего common ancestor. common ancestor не может быть original start node, потому что он должен быть включительным предком original end node. Другой случай аналогичен. Также заметьте, что два дочерних никогда не равны, если оба являются определенными.

  11. Сделать contained children списком всех дочерних common ancestor, которые содержатся в range, в порядке дерева.

  12. Если любой член contained children является doctype, выдать "HierarchyRequestError" исключение.

    Заметка: Мы не должны беспокоиться о первом или последнем частично содержащемся узле, потому что doctype никогда не может частично содержаться. Он не может быть граничной точкой диапазона и не может быть предком ничего.

  13. Если first partially contained child является Text, ProcessingInstruction или Comment узлом:

    Заметка: В этом случае first partially contained child является original start node.

    1. Сделать clone клоном original start node.

    2. Установить данные clone к результату извлечения данных с узла original start node, смещения original start offset и подсчета на длину original start node минус original start offset.

    3. Добавить clone к fragment.

  14. В другом случае, если first partially contained child не является null:

    1. Сделать clone клоном first partially contained child.

    2. Добавить clone к fragment.

    3. Сделать subrange новым диапазоном, чье начало является (original start node, original start offset) и чей конец является (first partially contained child, длина first partially contained child).

    4. Сделать subfragment результатом клонирования subrange.

    5. Добавить subfragment к clone.

  15. Для каждого contained child в contained children:

    1. Сделать clone клоном contained child с установленным clone children флагом.

    2. Добавить clone к fragment.

  16. Если last partially contained child является Text, ProcessingInstruction или Comment узлом:

    Заметка: В этом случае last partially contained child является original end node.

    1. Сделать clone клоном original end node.

    2. Установить данные clone к результату извлечения данных с узла original end node, смещения 0, и подсчета original end offset.

    3. Добавить clone к fragment.

  17. В другом случае, если last partially contained child не является null:

    1. Сделать clone клоном last partially contained child.

    2. Добавить clone к fragment.

    3. Сделать subrange новым диапазоном, чье начало является (last partially contained child, 0) и чей конец является (original end node, original end offset).

    4. Сделать subfragment результатом клонирования subrange.

    5. Добавить subfragment к clone.

  18. Возвратить fragment.

Метод cloneContents() должен возвратить результат клонирования объекта контекста.

Чтобы вставить узел node в диапазон range, выполнить следующие шаги:

  1. Если начальный узел range является ProcessingInstruction или Comment узлом, или узлом Text чей родитель является null, выдать исключение "HierarchyRequestError".

  2. Сделать referenceNode null.

  3. Если начальный узел range является узлом Text, установить referenceNode к этому Text узлу.

  4. В другом случае, установить referenceNode дочерним начального узла, чей индекс является начальным смещением, и null если такого дочернего нет.

  5. Сделать parent начальным узлом range если referenceNode является null, и родителем referenceNode в другом случае.

  6. Обеспечить валидность предварительной вставки node в parent перед referenceNode.

  7. Если начальный узел range являетсяText узлом, разделить его со смещением равным начальному смещению range, установить referenceNode к результату, и установить parent к родителю referenceNode.

  8. Если node равняется referenceNode, установить referenceNode к его следующему сестринскому.

  9. Если родитель node не является null, удалить node из его родителя.

  10. Сделать newOffset длиной parent если referenceNode является null, и индексом referenceNode в другом случае.

  11. Увеличинь newOffset на длину node, если node является DocumentFragment узлом, и на один в другом случае.

  12. Предварительно вставить node в parent перед referenceNode.

  13. Если начало и конец range являются одним и тем же, установить конец range к (parent, newOffset).

Метод insertNode(node) должен вставить node в объект контекста.

Метод surroundContents(newParent) должен выполнить следующие шаги:

  1. Если не-Text узел частично содержится в объекте контекста, выдать исключение "InvalidStateError".

  2. Если newParent является Document, DocumentType или DocumentFragment узлом, выдать исключение "InvalidNodeTypeError".

  3. Сделать fragment результатом извлечения объекта контекста.

  4. Если newParent имеет дочерние, заменить все на null внутри newParent.

  5. Вставить newParent в объект контекста.

  6. Добавить fragment к newParent.

  7. Выбрать newParent внутри объекта контекста.

Метод cloneRange() должен возвратить новый диапазон с тем же началом и концом как и у объекта контекста.

Метод detach() должен не делать ничего. Заметка: Его функциональность (отключение объекта Range) была удалена, но сам метод остается для совместимости.


position = range . comparePoint( parent, offset )

Возвращает −1 если точка перед диапазоном, 0 если точка внутри диапазона, и 1 если точка после диапазона.

intersects = range . intersectsNode( node )

Возвращает пересекает ли range node-у.

Метод isPointInRange(node, offset) должен выполнить следующие шаги:

  1. Если корень node отличается от корня объекта контекста, возвратить false.

  2. Если node является doctype, выдать "InvalidNodeTypeError" исключение.

  3. Если offset больше чем длина node, выдать "IndexSizeError" исключение.

  4. Если (node, offset) идет перед началом или после конца, возвратить false.

  5. Возвратить true.

Метод comparePoint(node, offset) должен выполнить следующие шаги:

  1. Если корень node отличается от корня объекта контекста, выдать исключение "WrongDocumentError".

  2. Если node является doctype, выдать "InvalidNodeTypeError" исключение.

  3. Если offset больше чем node длина, выдать исключение "IndexSizeError".

  4. Если (node, offset) идет перед началом, возвратить −1.

  5. Если (node, offset) идет после конца, возвратить 1.

  6. Возвратить 0.


Метод intersectsNode(node) должен выполнить следующие шаги:

  1. Если корень node отличается от корня объекта контекста, возвратить false.

  2. Сделать parent родителем node.

  3. Если parent является null, возвратить true.

  4. Сделать offset индексом node.

  5. Если (parent, offset) идет перед концом и (parent, offset + 1) идет после начала, возвратить true.

  6. Возвратить false.


Метод stringifier должен выполнить следующие шаги:

  1. Сделать s пустой строкой.

  2. Если начальный узел равняется конечным узлом и Text узлом, возвратить извлечение данных этого Text узла, начиная на начальном смещении и заканчивая на конечном смещении.

  3. Если начальный узел является Text узлом, добавить к s извлечение данных этого узла от начального смещения до конца.

  4. Добавить к s конкатенацию, в порядке дерева, данных всех Text узлов, которые содержатся в объекте контекста.

  5. Если конечный узел является Text узлом, добавить к s извлечение данных этого узла от начала до конечного смещения.

  6. Возвратить s.


Заметка: Методы createContextualFragment(), getClientRects() и getBoundingClientRect() определены в других спецификациях. [DOMPS] [CSSOMVIEW]

6 Обход

Объекты NodeIterator и TreeWalker могут использоваться для фильтрации и обхода деревьев узлов.

Каждый объект NodeIterator и TreeWalker также имеет соответствующий корневой узел, whatToShow битмаск и filter приемник (callback).

Чтобы фильтровать узел, выполните следующие шаги:

  1. Сделать n значением атрибута nodeType узла минус 1.

  2. Если n бит (где 0 является последним значительным битом) от whatToShow не установлен, возвратить FILTER_SKIP.

  3. Если filter равен null, возвратить FILTER_ACCEPT.

  4. Сделать result возвращенным значением вызова acceptNode фильтра с node в качестве аргумента. Повторно выбросить какие-либо исключения.

  5. Возвратить result.

6.1 Интерфейс NodeIterator

[Exposed=Window]
interface NodeIterator {
  [SameObject] readonly attribute Node root;
  readonly attribute Node referenceNode;
  readonly attribute boolean pointerBeforeReferenceNode;
  readonly attribute unsigned long whatToShow;
  readonly attribute NodeFilter? filter;

  Node? nextNode();
  Node? previousNode();

  void detach();
};

Заметка: объекты NodeIterator могут быть созданы использованием метода createNodeIterator().

Каждый объект NodeIterator имеет соответствующий набор итераторов, который представляет собой коллекцию с корнем в корне, чей фильтр соответствует любому узлу.

Каждый объект NodeIterator имеет следующие шаги удаления с oldNode, oldParent и oldPreviousSibling:

  1. Если oldNode не является включительным предком значения атрибута referenceNode, прекратить данные шаги.

  2. Если значение атрибута pointerBeforeReferenceNode является true, выполнить следующие подшаги:

    1. Сделать nextSibling следующим дочерним oldPreviousSibling-а, если oldPreviousSibling не является null, и первого дочернего oldParent-а в другом случае.

    2. Если nextSibling не является null, установить атрибут referenceNode к nextSibling и прекратить данные шаги.

    3. Сделать next первым узлом следующего oldParent.

    4. Если next не является включительным предком корня, установить атрибут referenceNode к next и прекратить данные шаги.

    5. В другом случае, установить атрибут pointerBeforeReferenceNode к false.

      Заметка: Шаги не прерываются здесь.

  3. Установить атрибут referenceNode к первому узлу предшествующему oldPreviousSibling, если oldPreviousSibling не является null, и к oldParent в другом случае.

Заметка: Как упоминалось ранее, объекты NodeIterator имеют соответствующий корневой узел, whatToShow битмаск и filter приемник (callback) также.


Атрибут root должен возвратить корень.

Атрибуты referenceNode и pointerBeforeReferenceNode должны возвратить то к чему они инициализированы.

Атрибут whatToShow должен возвратить whatToShow.

Атрибут filter должен возвратить filter.

Чтобы обойти в направлении direction, выполнить следующие шаги:

  1. Сделать node значением атрибута referenceNode.

  2. Сделать before node значением pointerBeforeReferenceNode атрибута.

  3. Выполнить следующие подшаги:

    1. Если направление является next

      Если before node равняется false, сделать node первым узлом следующим node в наборе итераторов. Если нет такого узла, возвратить null.

      Если before node равняется true, установить ее к false.

      Если направление является previous

      Если before node является true, сделать node первым узлом предшествующим узлу в наборе итераторов. Если нет такого узла, возвратить null.

      Если before node является false, установить ее к true.

    2. Фильтровать node и сделать result возвращаемым значением.

    3. Если result является FILTER_ACCEPT, перейти к следующему шагу в общем наборе шагов.

      В другом случае, выполнить эти подшаги заново.

  4. Установить атрибут referenceNode к node, установить атрибут pointerBeforeReferenceNode к before node, и возвратить node.

Метод nextNode() должен обойти в направлении next.

Метод previousNode() должен обойти в направлении previous.

Метод detach() должен не делать ничего. Заметка: Его функциональность (отключение объекта NodeIterator) была удалена, но сам метод остается для совместимости.

6.2 Интерфейс TreeWalker

[Exposed=Window]
interface TreeWalker {
  [SameObject] readonly attribute Node root;
  readonly attribute unsigned long whatToShow;
  readonly attribute NodeFilter? filter;
           attribute Node currentNode;

  Node? parentNode();
  Node? firstChild();
  Node? lastChild();
  Node? previousSibling();
  Node? nextSibling();
  Node? previousNode();
  Node? nextNode();
};

Заметка: Объекты TreeWalker могут быть созданы использованием метода createTreeWalker().

Заметка: Как упоминалось ранее, объекты TreeWalker имеют соответствующий корневой узел, whatToShow битмаск и filter приемник (callback).

Атрибут root должен возвратить root.

Атрибут whatToShow должен возвратить whatToShow.

Атрибут filter должен возвратить filter.

Атрибут currentNode должен возвратить то к чему был инициализирован.

Установка атрибута currentNode должна установить его к новому значению.

Метод parentNode() должен выполнить следующие шаги:

  1. Сделать node значением атрибута currentNode.

  2. Пока node не является null и не является корнем, выполнить следующие подшаги:

    1. Сделать node родительским для node.

    2. Если node не является null и фильтрация узла возвращает FILTER_ACCEPT, то установить атрибут currentNode к node, возвратить node.

  3. Возвратить null.

Чтобы обойти дочерние типа type, выполнить следующие шаги:

  1. Сделать node значением атрибута currentNode.

  2. Установить node к первому дочернему узла если type является первым, и последним дочерним узла если type является последним.

  3. Главный: Пока node не является null, выполнить следующие подшаги:

    1. Фильтровать node и сделать result возвращаемым значением.

    2. Если result является FILTER_ACCEPT, то установить атрибут currentNode к node и возвратить node.

    3. Если result является FILTER_SKIP, выполнить следующие подшаги:

      1. Сделать child первым дочерним узлаесли type является первым, и последним дочерним узла если type является последним.

      2. Если child не является null, установить node к child и перейти к Главному.

    4. Пока node не является null, выполнить следующие шаги:

      1. Сделать sibling следующим сестринским узла если type является первым, и предыдущим сестринским узла если type является последним.

      2. Если сестринский не является null, установить node к sibling и перейти к Главному.

      3. Сделать parent родительским узла.

      4. Если parent не является null, parent является root или parent является значением атрибута currentNode, возвратить null.

      5. В другом случае, установить node к parent.

  4. Возвратить null.

Метод firstChild() должен обойти дочерние первого типа.

Метод lastChild() должен обойти дочерние последнего типа.

Чтобы обойти дочерние типа type, выполнить следующие шаги:

  1. Сделать node значением атрибута currentNode.

  2. Если node является корневым, возвратить null.

  3. Выполнить следующие подшаги:

    1. Сделать sibling следующим сестринским узла если type является следующим, и предыдущим сестринским узла если type является предыдущим.

    2. Пока sibling не является null, выполнить следующие подшаги:

      1. Установить node к sibling.

      2. Фильтровать node и сделать result возвращаемым значением.

      3. Если result является FILTER_ACCEPT, то установить атрибут the currentNode к node и возвратить node.

      4. Установить sibling к первому дочернему узла если type является следующим, и последним дочерним узла если type является предыдущим.

      5. Если result является FILTER_REJECT или sibling является null, то установить sibling к следующему сестринскому узла если type является следующим, и предыдущий сестринский узла если type является предыдущим.

    3. Установить node к его родительскому.

    4. Если node является null или является корнем возвратить null.

    5. Фильтровать node и если возвращаемое значение является FILTER_ACCEPT, то возвратить null.

    6. Выполнить данные подшаги заново.

Метод nextSibling() должен обойти сестринские последнего типа.

Метод previousSibling() должен обойти сестринские предыдущего типа.

Метод previousNode() должен выполнить следующие шаги:

  1. Сделать node значением атрибута currentNode.

  2. Пока node не является корневым, выполнить следующие шаги:

    1. Сделать sibling предыдущим сестринским узла.

    2. Пока sibling не является null, выполнить следующие подшаги:

      1. Установить node к sibling.

      2. Фильтровать node и сделать result возвращаемым значением.

      3. Пока result не является FILTER_REJECT и node имеет дочерний, установить node к своему последнему дочернему и затем filter node and установить result как возвращаемое значение.

      4. Если result является FILTER_ACCEPT, то установить атрибут currentNode к node и возвратить node.

      5. Установить sibling к предыдущему сестринскому узла.

    3. Если node является корнем или родительский узла является null, возвратить null.

    4. Установить node к его родительскому.

    5. Фильтровать node и если возвращаемое значение FILTER_ACCEPT, то установить атрибут currentNode к node и возвратить node.

  3. Возвратить null.

Метод nextNode() должен выполнить следующие шаги:

  1. Сделать node значением атрибута currentNode.

  2. Сделать result FILTER_ACCEPT.

  3. Выполнить следующие подшаги:

    1. Пока result не является FILTER_REJECT и node имеет child, выполнить следующие подшаги:

      1. Установить node к его первому дочернему.

      2. Фильтровать node и установить result к возвращаемому значению.

      3. Если result является FILTER_ACCEPT, то установить атрибут currentNode к node и возвратить node.

    2. Если node является следующим узлом и не является следующим корня, установить node к первому такому узлу.

      В другом случае, возвратить null.

    3. Фильтровать node и установить result как возвращаемое значение.

    4. Если result является FILTER_ACCEPT, то установить атрибут currentNode к node и возвратить node.

    5. Выполнить эти подшаги заново.

6.3 Интерфейс NodeFilter

[Exposed=Window]
callback interface NodeFilter {
  // Constants for acceptNode()
  const unsigned short FILTER_ACCEPT = 1;
  const unsigned short FILTER_REJECT = 2;
  const unsigned short FILTER_SKIP = 3;

  // Constants for whatToShow
  const unsigned long SHOW_ALL = 0xFFFFFFFF;
  const unsigned long SHOW_ELEMENT = 0x1;
  const unsigned long SHOW_ATTRIBUTE = 0x2; // historical
  const unsigned long SHOW_TEXT = 0x4;
  const unsigned long SHOW_CDATA_SECTION = 0x8; // historical
  const unsigned long SHOW_ENTITY_REFERENCE = 0x10; // historical
  const unsigned long SHOW_ENTITY = 0x20; // historical
  const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40;
  const unsigned long SHOW_COMMENT = 0x80;
  const unsigned long SHOW_DOCUMENT = 0x100;
  const unsigned long SHOW_DOCUMENT_TYPE = 0x200;
  const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400;
  const unsigned long SHOW_NOTATION = 0x800; // historical

  unsigned short acceptNode(Node node);
};

Объекты NodeFilter могут использоваться как filter приемники и предоставлять константы для whatToShow битмаска.

Заметка: Это обычно реализуется в виде JavaScript функции.

Данные константы могут использоваться как возвращаемое значение приемника (callback):

Данные константы могут использоваться для whatToShow битмаска:

7 Множества

Заметка: Да, имена DOMTokenList и DOMSettableTokenList это не очень удачно унаследованные казусы.

7.1 Интерфейс DOMTokenList

interface DOMTokenList {
  readonly attribute unsigned long length;
  getter DOMString? item(unsigned long index);
  boolean contains(DOMString token);
  void add(DOMString... tokens);
  void remove(DOMString... tokens);
  boolean toggle(DOMString token, optional boolean force);
  stringifier;
  iterable<DOMString>;
};

Объект DOMTokenList имеет соответствующий упорядоченный набор токенов, который изначально пуст.

Объект DOMTokenList также имеет соответствующий элемент и локальное имя атрибута.

Шаги обновления объекта DOMTokenList это:

  1. Если нет соответствующего атрибута (когда объект является DOMSettableTokenList), прекратить эти шаги.

  2. Установить атрибут для соответствующего элемента используя соответствующее локальное имя атрибута и результат выполнения сериализатора упорядоченных множеств для токенов.

tokenlist . length

Возвращает количество токенов.

tokenlist . item(index)
tokenlist[index]

Возвращает токен с индексом index.

tokenlist . contains(token)

Возвращает true если token присутствует, и false в другом случае.

Выдает исключение "SyntaxError" если token является пустой строкой.

Выдает исключение "InvalidCharacterError" если token содержит любые ASCII пробелы.

tokenlist . add(tokens…)

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

Выдает исключение "SyntaxError" если один из аргументов является пустой строкой.

Выдает исключение "InvalidCharacterError" если один из аргументов содержит любые ASCII пробелы.

tokenlist . remove(tokens…)

Удаляет переданные аргументы, если они присутствуют.

Выдает исключение "SyntaxError" если один из аргументов является пустой строкой.

Выдает исключение "InvalidCharacterError" если один из аргументов содержит любые ASCII пробелы.

tokenlist . toggle(token [, force])

Если force не задано, "переключает" token, удаляя его если он присутствует, и добавляет если нет. Если force равняется true, добавляет token (то же что и add()). Если force равняется false, удаляет token (то же что и remove()).

Возвращает true если token теперь присутствует, и false в другом случае.

Выдает исключение "SyntaxError" если token является пустым.

Выдает исключение "InvalidCharacterError" если token содержит любые пробелы.

Атрибут length возвращает количество токенов tokens.

Индексы поддерживаемых свойств объекта это числа в диапазоне от нуля до количества tokens минус один, кроме случая если tokens пуст, тогда нет индекса поддерживаемых свойств.

Метод item(index) должен выполнить следующие шаги:

  1. Если index равен или более чем количество токенов в tokens in tokens, возвратить null.

  2. Возвратить index-й токен в tokens.

Метод contains(token) должен выполнить следующие шаги:

  1. Если token является пустой строкой, то выдать исключение "SyntaxError".

  2. Если token содержит любые ASCII пробелы, то выдать исключение "InvalidCharacterError".

  3. Возвратить true если token находится в tokens, и false в другом случае.

Метод add(tokens…) должен выполнить следующие шаги:

  1. Если один из tokens является пустой строкой, выдать "SyntaxError" исключение.

  2. Если один из tokens содержит любые ASCII пробелы, то выдать "InvalidCharacterError" исключение.

  3. Для каждого token в tokens, в заданном порядке, который не в tokens, добавить token в tokens.

  4. Выполнить шаги обновления.

Метод remove(tokens…) должен выполнить следующие шаги:

  1. Если один из tokens является пустой строкой, выдать исключение "SyntaxError".

  2. Если один из tokens содержит любые ASCII пробелы, то выдать исключение "InvalidCharacterError".

  3. Для каждого token в tokens, удалить token из tokens.

  4. Выполнить шаги обновления.

Метод toggle(token, force) должен выполнить следующие шаги:

  1. Если token является пустой строкой, выдать исключение "SyntaxError".

  2. Если token содержит любые ASCII пробелы, выдать исключение "InvalidCharacterError".

  3. Если token в tokens, выполнить следующие подшаги:

    1. Если force не передан либо false, то удалить token из tokens, выполнить шаги обновления, и возвратить false.

    2. В другом случае, возвратить true.

  4. В другом случае, выполнить следующие подшаги:

    1. Если force передан и равен false, возвратить false.

    2. В другом случае, добавить token в tokens, выполнить шаги обновления и возвратить true.

stringifier должен возвратить результат сериализатора упорядоченного списка для tokens.

7.2 Интерфейс DOMSettableTokenList

interface DOMSettableTokenList : DOMTokenList {
            attribute DOMString value;
};

Объект DOMSettableTokenList эквивалентен объекту DOMTokenList без соответствующего атрибута.

tokenlist . value

Возвращает соответствующее множество как строку.

Может быть установлен, чтобы изменить соответствующее множество с помощью строки.

Атрибут value должен возвратить результат сериализатора упорядоченных множеств для tokens.

Установка атрибута value должна выполнить парсер упорядоченных множеств для заданного значения и установить tokens в качестве результата.

8 История

Как объяснялось в целях, эта спецификация является значительным пересмотром различных DOM спецификаций. Этот раздел пытается перечислить изменения.

8.1 DOM События

Таковы изменения внесенные в функции описанные в главах "DOM Event Architecture", "Basic Event Interfaces", "Mutation Events" и "Mutation Name Event Types" UI Events Specification (ранее DOM Level 3 Events). [UIEVENTS]

8.2 DOM Ядро

Таковы изменения, внесенные в функции описанные в DOM Level 3 Core.

DOMString и DOMTimeStamp теперь определены в Web IDL.

Узел теперь наследует EventTarget.

Узлы неявно приняты через границы документа.

Doctypes не всегда имеют node document и могут быть перемещены через границы документа.

ProcessingInstruction теперь наследует CharacterData.

attributes перемещены с Node в Element.

namespaceURI, prefix и localName перемещены с Node в Element и Attr.

Оставшаяся часть интерфейсов и членов интерфейса перечисленная в этом разделе была удалена, чтобы упростить DOM платформу. Реализации, соответствующие данной спецификации, не будут поддерживать их.

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

Интерфейсы:

Члены интерфейса:

Node
Document
DOMImplementation
Attr

Больше не наследует Node и, следовательно, полностью изменился.

Element
DocumentType
Text

8.3 DOM Диапазоны

Таковы изменения, внесенные в функции описанные в главе "Document Object Model Range" DOM Level 2 Traversal and Range.

8.4 DOM Обход

Таковы изменения, внесенные в функции описанные в главе "Document Object Model Traversal" DOM Level 2 Traversal and Range.

А. Исключения и ошибки

А.1 Исключения

Весь этот раздел был перенесен в IDL. Обратитесь к [Web IDL] для последних определений.

Исключение это тип объекта, который представляет ошибку и который может быть выдан или обработан как значение первого типа в реализациях. Web IDL не позволяет исключениям быть определяемыми, но вместо этого имеет ряд предопределенных исключений, на которые можно ссылаться и выдавать в собственных определениях операций, атрибутов и так далее. Исключения имеют имя ошибки, DOMString, которое является типом ошибки которую исключение представляет, и сообщение, которое является опциональным, определенное пользовательским агентом значение, которое предоставляет читабельные людьми подробности ошибки.

Один вид исключений это DOMException, которое является исключением содержащим имя и опциональный целочисленный код, для совместимости с исторически определенными исключениями в DOM.

Для DOMException, имя ошибки должно быть одним из имен перечисленных в таблице имен ошибок ниже. В таблице также указаны целочисленные коды DOMException для этого имени ошибки, если оно имеет его.

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

А.2 Интерфейс DOMError

[Constructor(DOMString name, optional DOMString message = "")]
interface DOMError {
  readonly attribute DOMString name;
  readonly attribute DOMString message;
};

DOMError является устаревшим и не должен использоваться. Смотрите Error в WebIDL вместо него.

Этот интерфейс используется исключительно по историческим причинам. Как и с исключениями, используется таблица имен ошибок.

Конструктор DOMError(name, message) должен возвратить новый объект DOMError, чей атрибут name инициализирован к name и чей атрибут message инициализирован к message.

Атрибут name должен возвратить значение к которому был инициализирован.

Атрибут message должен возвратить значение к которому был инициализирован.

Значение message обычно будет зависеть от реализации и используется только для информативной цели.

Имя DOMError означает объект DOMError, чей атрибут name инициализирован к name и чей атрибут message инициализирован к полезному зависящему от реализации сообщению, описывающему ошибку.

А.3 Имена ошибок

Таблица имен ошибок ниже содержит все разрешенные имена ошибок, описание и унаследованный code ошибок (когда имя ошибки используется для выдачи исключения).

Весь этот раздел был перенесен в WebIDL. Обратитесь к [Web IDL] за последними определениями.

ИмяОписаниеУнаследованный code исключения (если есть)
"IndexSizeError" Index вне дозволенного диапазона. INDEX_SIZE_ERR (1)
"HierarchyRequestError" Операция привела бы к некорректному дереву узлов. HIERARCHY_REQUEST_ERR (3)
"WrongDocumentError" Объект находится в неправильном документе. WRONG_DOCUMENT_ERR (4)
"InvalidCharacterError" Строка содержит невалидные символы. INVALID_CHARACTER_ERR (5)
"NoModificationAllowedError" Объект не может быть изменен. NO_MODIFICATION_ALLOWED_ERR (7)
"NotFoundError" Объект не может быть найден здесь. NOT_FOUND_ERR (8)
"NotSupportedError" Операция не поддерживается. NOT_SUPPORTED_ERR (9)
"InvalidStateError" Объект находится в недопустимом состоянии. INVALID_STATE_ERR (11)
"SyntaxError" Строка не подходит к ожидаемому паттерну. SYNTAX_ERR (12)
"InvalidModificationError" Объект не может быть изменен данным образом. INVALID_MODIFICATION_ERR (13)
"NamespaceError" Операция не разрешена в Пространствах имен XML. [XMLNS] NAMESPACE_ERR (14)
"InvalidAccessError" Объект не поддерживает операцию или аргумент. INVALID_ACCESS_ERR (15)
"SecurityError" Операция небезопасна. SECURITY_ERR (18)
"NetworkError" Произошла ошибка сети. NETWORK_ERR (19)
"AbortError" Операция была прервана. ABORT_ERR (20)
"URLMismatchError" Заданный URL не соответствует другому URL. URL_MISMATCH_ERR (21)
"QuotaExceededError" Квота превышена. QUOTA_EXCEEDED_ERR (22)
"TimeoutError" Время операции вышло. TIMEOUT_ERR (23)
"InvalidNodeTypeError" Соответствующий узел неправилен или имеет неправильного предка для этой операции. INVALID_NODE_TYPE_ERR (24)
"DataCloneError" Объект не может быть клонирован. DATA_CLONE_ERR (25)
"EncodingError" Операция кодирования (или декодирования) не удалась.
"NotReadableError" Операция чтения I/O не удалась.

Б. Концепты CSS

Заметка: Этот раздел содержит концепты представленные в Selectors Level 4 и будет удален в будущем, как только спецификация Selectors Level 4 будет обновлена. Обратитесь к [SELECTORS] для актуальных определений.

scoping root
Некоторые приложения могут выбрать область использования селекторов в конкретном поддереве или фрагменте документа. Корень области использования поддерева называется scoping root.
:scope elements
Корень поддерева области использования, scoping root, может быть true элементом (элементом области использования) или виртуальным (таким как DocumentFragment).
scope-filtered
Когда применяется scope, селектор соответствует элементу только если элемент внутри scope, даже если другие компоненты селектора находятся за пределами scope. (Элемент области использования рассматривается как находящийся в scope.)
parse a relative selector
Метод для парсинга относящегося селектора из исходной строки, против :scope elements refs. Он возвращает комплексный список селекторов, либо ошибку.
evaluate a selector
Метод оценки селектор против набора элементов.
parse a selector
Метод для парсинга селектора из исходной строки. Он возвращает комплексный список селекторов, либо ошибку.

Ссылки

[CSSOMVIEW]
(Не-нормативные)
[DOM2TR]
(Не-нормативная) Document Object Model (DOM) Level 2 Traversal and Range Specification, Joe Kesselman, Jonathan Robie, Mike Champion и другие. W3C.
[DOM3CORE]
(Не-нормативная) Document Object Model (DOM) Level 3 Core Specification, Arnaud Le Hors, Philippe Le Hégaret, Lauren Wood и другие. W3C.
[DOMPS]
(Не-нормативная) DOM Parsing and Serialization, T. Leithead. Работа в процессе. W3C.
[ELEMENTTRAVERSAL]
(Не-нормативная) Element Traversal Specification, Doug Schepers. W3C.
[ENCODING]
Encoding, A. van Kesteren, J. Bell, A. Phillips. W3C.
[HTML]
HTML5, R. Berjon, T. Leithead, E. Doyle Navara, E. O'Connor, S. Pfeiffer. W3C.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF.
[SELECTORS]
Selectors Level 4, E. Etemad, T. Atkins. W3C.
[SELECTORSAPI]
(Не-нормативная) Selectors API Level 2, Lachlan Hunt. W3C.
[TOUCHEVENTS]
Touch Events, Doug Schepers, Sangwhan Moon, Matt Brubeck и Arthur Barstow. W3C.
[UIEVENTS]
UI Events (formerly DOM Level 3 Events), Gary Kacmarcik и Travis Leithead. W3C.
[URL]
(Не-нормативная)

Заметка: URL-адреса могут использоваться множеством различных способов, во многих различных контекстах. Для получения строгих URL вы можете рассмотреть [RFC3986] [RFC3987]. Спецификация W3C URL определяет термин URL, различные алгоритмы для работы с URL-адресами и API для построения, парсинга и разрешения URL-адресов. Разработчикам веб-браузеров советуется быть в курсе последних разработок URL путем отслеживания прогресса на https://url.spec.whatwg.org/. Мы ожидаем, что черновик W3C URL будет развиваться по пути Рекомендации как сообщество сходится в определении обработки URL.

  • URL, Anne van Kesteren. WHATWG.
  • RFC3986, T. Berners-Lee; R. Fielding; L. Masinter. IETF.
  • RFC3987, M. Duerst, M. Suignard. IETF.
[WEBIDL]
Web IDL Level 1, Cameron McCormack, Boris Zbarsky, Yves Lafon, Travis Leithead. W3C.
[XML]
Extensible Markup Language, Tim Bray, Jean Paoli, C. M. Sperberg-McQueen и другие. W3C.
[XMLNS]
Namespaces in XML, Tim Bray, Dave Hollander, Andrew Layman и другие. W3C.

Благодарности

Было много людей, которые помогали сделать DOM более совместимым на протяжении лет и тем самым способствовали достижению целей этого стандарта. Также много людей помогли сделать этот стандарт тем чем он является сегодня.

Так что, большое спасибо Adam Klein, Adrian Bateman, Alex Russell, Arkadiusz Michalski, Arnaud Le Hors, Arun Ranganathan, Björn Höhrmann, Boris Zbarsky, Brandon Slade, Brandon Wallace, Brian Kardell, Cameron McCormack, Christophe Dumez, Daniel Glazman, David Bruant, David Flanagan, David Håsäther, Dethe Elza, Dimitri Glazkov, Domenic Denicola, Dominic Cooney, Dominique Hazaël-Massieux, Don Jordan, Doug Schepers, Erik Arvidsson, Gavin Nicol, Geoffrey Sneddon, Glenn Maynard, Harald Alvestrand, Henri Sivonen, Ian Hickson, Igor Bukanov, Jacob Rossi, Jake Archibald, Jake Verbaten, James Graham, James Robinson, Jens Lindström, João Eiras, Joe Kesselman, Jonas Sicking, Jonathan Robie, Joshua Bell, Justin Summerlin, 呂康豪 (Kang-Hao Lu), Kevin Sweeney, Lachlan Hunt, Lauren Wood, Manish Goregaokar, Manish Tripathi, Marcos Caceres, Mark Miller, Mats Palmgren, Mounir Lamouri, Michael™ Smith, Mike Champion, Ojan Vafai, Olli Pettay, Ondřej Žára, Peter Sharpe, Philip Jägenstedt, Philippe Le Hégaret, Rafael Weinstein, Rick Waldron, Robbert Broersma, Robin Berjon, Rune F. Halvorsen, Ryosuke Niwa, Seo Sanghyeon, Shiki Okasaka, Simon Pieters, Steve Byrne, Stig Halvorsen, Tab Atkins, Timo Tijhof, Tom Pixley, Travis Leithead, Vidur Apparao, Warren He, Yehuda Katz, Yoichi Osato и Zack Weinberg за то что они такие молодцы!

Этот стандарт написан Anne van Kesteren (Mozilla, annevk@annevk.nl) с существенным вкладом Aryeh Gregor (Mozilla, ayg@aryeh.name) и Ms2ger (Mozilla, ms2ger@gmail.com).

Под лицензией CC0, насколько это возможно по закону, редакторы WHATWG отказались от копирайта и связанных или смежных прав на WHATWG работу.