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

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 - Ограничения на содержимое элементов скрипта script - https://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-разметки

 

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

Стандарт ECMAScript - https://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

Стандарт DOM - https://dom.spec.whatwg.org

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