JavaScript | Как получить все HTML-комментарии на HTML-странице?

JavaScript | Как получить все HTML-комментарии на HTML-странице?

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

Давайте разбираться.

 

Решение

В решении нам поможет стандарт объектной модели документа (DOM) и стандарт языка разметки гипертекста (HTML).

И самым главным инструментом всех наших вычислений будут регулярные выражения RegExp из JavaScript.

За выборку данных будет отвечать стандарт (Fetch).

Также нам нужно хорошо понимать, что считается комментарием в HTML, как они оформляются, что можно и что нельзя.

 

Шаг № 1 — Получение всей разметки страницы в виде одной большой строки

Если мы находимся в стандартном вебе и пользуемся доступом к контенту через URI-схемы:

http, https, ipns, chrome-untrusted, ipfs, data, chrome, chrome-extension

то можно смело посылать запрос на выборку данных с сервера по текущему адресу

let str = await fetch(location.pathname).then(resp=>resp.text())

Эта команда вернёт нам нужную строковую разметку текущего открытого документа в браузере.

Получили HTML-разметку текущей открытой страницы в браузере в виде строки JavaScript
Получили HTML-разметку текущей открытой страницы в браузере в виде строки JavaScript

Строка уже есть.

 

Шаг № 2 — Что считается HTML-комментарием?

Здесь нужно собрать немного информации из разных мест документации по HTML.

Справка № 1 — Раздел «13.1.6 Comments» — https://html.spec.whatwg.org/multipage/syntax.html#comments

Комментарии должны иметь следующий формат:

  1. Строка «<!—«.
  2. Опционально, текст с дополнительным ограничением: текст не должен начинаться со строки «>«, начинаться со строки «->» и содержать строки «<!—«, «—>» или » —!>«, и не заканчиваться строкой «<!-«.
  3. Строка «—>«.

Примечание!

Текст может заканчиваться строкой «<!«, как в <!— Моими любимыми операторами являются > и <!—>.

 

HTML-комментарий использующий в тексте угловые скобки
HTML-комментарий использующий в тексте угловые скобки

Из этого следует то, что комментарии нельзя вкладывать один в один. Браузер это не распознает корректно.

 

Справка № 2 — ОШИБКА: Вложенный комментарий — https://html.spec.whatwg.org/#parse-error-nested-comment

Эта ошибка возникает, если синтаксический анализатор встречает вложенный комментарий (например, <!— <!— вложенный —> —>). Такой комментарий будет закрыт первой попавшейся последовательностью кодовых точек «—>«, а все последующие будут рассматриваться как разметка.

 

Вложенный HTML-комментарий развалился--Часть попала в видимую область документа - HTML
Вложенный HTML-комментарий развалился—Часть попала в видимую область документа — HTML

 

Справка № 3 — Неожиданный вопросительный знак вместо имени тега — https://html.spec.whatwg.org/#parse-error-unexpected-question-mark-instead-of-tag-name

Эта ошибка возникает, если синтаксический анализатор встречает кодовую точку U+003F (?), где ожидается первая кодовая точка имени начального тега. U+003F (?) и всё содержимое, следующее за кодовой точкой U+003E (>) (если присутствует) или до конца входного потока, рассматриваются как комментарий.

Например, рассмотрим следующую разметку:

<?xml-stylesheet type=»text/css» href=»style.css»?>

Распространенной причиной этой ошибки является инструкция по обработке XML (например, <?xml-stylesheet type=»text/css» href=»style.css»?>) или декларация XML (например, <?xml version=»1.0 » encoding=»UTF-8″?>) используется в HTML.

 

Конвертация уловых скобок с вопросами в комментарий HTML
Конвертация уловых скобок с вопросами в комментарий HTML

 

Справка № 4 — Ограничения на содержимое элементов скрипта scripthttps://html.spec.whatwg.org/#restrictions-for-contents-of-script-elements

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

  • «<!—» как «\x3C!—«
  • «<script» как «\x3Cscript«
  • «</script» как «\x3C/script«

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

 

Это говорит о том, что в строке, полученной через JavaScript могут быть начальные символы «\x3C!—» для открывания комментария.

Самые первые комментарии HTML-документа и их место в строке разметки
Самые первые комментарии HTML-документа и их место в строке разметки

 

Есть ещё моменты касающиеся doctype, но мы их не будем учитывать. Нам это мало интересно. Но если вам нужно, то придётся усчитывать.

 

Написание кода с учётом условий

Первое регулярное выражение:

/<!--.*?-->/g[Symbol.match](str)||[]

или

Второе регулярное выражение:

/\x3C!--.*?-->/g[Symbol.match](str)||[]

Каждое выражение должно возвращать одинаковый массив элементов. Если сопоставления не будут найдены, то метод [Symbol.match]() вернёт нам null. При сравнении null и пустого массива, нам вернётся пустой массив. То есть мы в любом случае получим массив.

 

Пример работы выражений:

Получили 19 HTML-комментариев из разметки документа, игнорируя невалидные последовательности символов - JavaScript
Получили 19 HTML-комментариев из разметки документа, игнорируя невалидные последовательности символов — JavaScript

Обязательно добавляйте символ вопроса для квантификатора звёздочки. Так вы будете отбирать самые короткие последовательности сопоставления.

 

Тестовые строки для проверки

let str2 = 'Стол<!-- Петя -->Стул<-- Дима -->Кровать<!-- Коля --><-- Гриша --><!-- Иван --><-- Маша -->'
Получили 3 HTML-комментария из разметки документа, игнорируя невалидные последовательности символов - JavaScript
Получили 3 HTML-комментария из разметки документа, игнорируя невалидные последовательности символов — JavaScript

 

Функция для извлечения HTML-комментариев из строки разметки

function getHTMLCommentsArr(str){return /<!—.*?—>/g[Symbol.match](str)||[]}

 

Собственный метод, расширяющий стандартный класс String

Мы можем написать свой собственный метод для расширения стандартного набора методов класса String.

String.prototype.getHTMLCommentsArr = function(){return /<!--.*?-->/g[Symbol.match](this)||[]}

Пример работы метода:

Собственный метод для экземпляров строк на получение массива комментариев из HTML-разметки
Собственный метод для экземпляров строк на получение массива комментариев из HTML-разметки

 

Информационные ссылки

Стандарт ECMAScripthttps://tc39.es/ecma262/multipage/

Стандарт ECMAScript — Раздел «22.2.5.8 RegExp.prototype [ @@match ] ( string )» — https://tc39.es/ecma262/multipage/text-processing.html#sec-regexp.prototype-@@match

Стандарт ECMAScript — Раздел «22.1.3.12 String.prototype.match ( regexp )» — https://tc39.es/ecma262/multipage/text-processing.html#sec-regexp.prototype-@@match

Стандарт DOMhttps://dom.spec.whatwg.org

Стандарт DOMРусская версия