SVG-метрики CreepJS: поля и ограничения
Проследите поля SVG-отчёта CreepJS до закреплённого сборщика, отделите агрегирование с потерями от геометрии и трактуйте блокировки без вывода об идентичности.
BotBrowser Team
Нужна структурированная документация по теме Отпечатки?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Измерения SVG-текста используют браузерные SVG- и DOM API, а не обозначают устройство. BotBrowser позволяет задавать профильные наборы шрифтов для проверки совместимости; профильные настройки сами по себе не запускают CreepJS и не обещают одинаковые SVG-измерения на разных платформах.
TL;DR
Закреплённый SVG-сборщик CreepJS создаёт текстовый образец вне экрана, сводит ограничивающий прямоугольник SVG, сохраняет по одному emoji на каждую отличающуюся строку getComputedTextLength() и сравнивает измерения до переключения класса shift-svg, пока он добавлен и после удаления. Поля описывают измерения и ветви этой реализации. Они не устанавливают операционную систему, устройство или личность. В частности, svgrectSystemSum представляет собой агрегат с потерями по разным строкам длины; исходный код не определяет его как системную метрику.
Содержание
- Создание образца и границы сборщика
- Происхождение семи полей отчёта
- Отсутствующие, заблокированные и ошибочные ветви
- Различия геометрии SVG, Canvas и DOM
- Минимальная запись интерпретации
- Возможности и ограничения BotBrowser
- Практический вывод
Создание образца и границы сборщика
BotBrowser документирует наборы шрифтов профиля и резервные варианты, но это не превращает результат CreepJS в идентификатор ОС или устройства. Полезный вопрос уже: какие операции закреплённого src/svg/index.ts формируют поля, которые рендерер называет SVGRect?
Сборщик начинает с объединения нескольких уже рассчитанных признаков несогласованности, включая свойства SVGRect, SVGRectElement.getBBox() и три метода SVGTextContentElement. Затем он выбирает ссылку на документ, добавляет div и вставляет SVG с узлом <text> для каждого элемента EMOJIS. Образец располагается вне экрана; текстовые узлы используют настроенное семейство шрифтов и размер 200px. Сборщик добавляет и затем удаляет shift-svg между двумя чтениями. Базовый и дополнительный CSS-селекторы задают одинаковый масштаб, а второй добавляет !important, поэтому эти правила не устанавливают числовое изменение масштаба.
Это факты исходного кода, а не измеренные результаты. Код не доказывает, что каждый браузер отрисует образец, что все заданные шрифты установлены или что полученные значения уникальны для платформы. Поэтому таблица происхождения полезнее предполагаемой метки ОС: каждая строка связывает поле с операцией и показывает потерю информации.
Сборщик также ожидает queueEvent(timer) до измерения и во время него. Это описывает поток закреплённой реализации, но не доказывает создание отчёта в активной браузерной сессии. Здесь не заявляется запуск страницы CreepJS или измерение браузера.
Происхождение семи полей отчёта
Возвращаемый объект data содержит семь свойств. Рендерер делит отображаемые bBox, char, subs и text на 10,000, а ложные значения, включая ноль, заменяет на BLOCKED. Ложный svgrectSystemSum отображается как UNSUPPORTED. Для emojiSet вызывается formatEmojiSet(); подсказка содержит короткий хеш и список представителей.
| Поле | Исходная операция | Преобразование или граница |
|---|---|---|
bBox | svgBox.getBBox() | reduceToObject() оставляет свойства, не являющиеся функциями; getObjectSum() складывает их абсолютные значения. |
extentOfChar | svgElems[0].getExtentOfChar(EMOJIS[0]) | Аргументом передаётся первый заданный emoji. Сам исходный код не обосновывает, что значение является полной протяжённостью emoji. |
subStringLength | svgElems[0].getSubStringLength(0, 10) | Первый узел запрашивается с началом 0 и длиной 10; это форма вызова, а не межбраузерный результат. |
computedTextLength | svgElems[0].getComputedTextLength() | Одно измерение первого узла сохраняется отдельно от набора представителей. |
emojiSet | getComputedTextLength() каждого узла | Для каждой ещё не встречавшейся строки длины после преобразования в текст сохраняется один emoji. |
svgrectSystemSum | Набор pattern этих строк | Числовые части разных строк складываются, затем сумма умножается на 0.00001. |
lied | Предыдущие признаки и предикат смещения | Начинается с выбранных признаков и может стать true, если сравнение смещения и восстановления различается. |
bBox не является сериализованным прямоугольником. reduceToObject() перечисляет ключи nativeObj.__proto__, исключает элементы-функции и возвращает остальные свойства. Затем getObjectSum() складывает абсолютное значение каждого свойства. Поэтому нельзя восстанавливать x, y, width и height, будто отчёт сохранил кортеж прямоугольника. Результат представляет собой скаляр, полученный из объекта прямоугольного типа.
Названия методов также различают входы. getBBox() возвращает ограничивающий прямоугольник графического элемента SVG. getComputedTextLength() возвращает длину текстового содержимого. getSubStringLength() принимает пару индексов, похожую на диапазон. Вызов getExtentOfChar() получает строку EMOJIS[0]. Не установив отдельно преобразование аргумента самой API, следует сохранять буквальную форму вызова и не приписывать результату смысл длины всего emoji.
Карта соответствий «поле и операция» служит основным артефактом: форма исходника, преобразование и ограничение остаются видны вместе. Общая метка «SVG-отпечаток» скрыла бы различия и означала бы больше, чем доказывает код.
Почему emojiSet теряет кратность
Сборщик создаёт pattern = new Set() и список элементов .svgrect-emoji. Для элемента с индексом i он считывает getComputedTextLength(), превращает результат в строку и проверяет, есть ли эта строка в pattern. Только новая строка попадает в набор, и только тогда EMOJIS[i] добавляется в emojiSet.
Последовательность важна. Если несколько emoji дают одинаковую строку длины, emojiSet сохраняет первый emoji для этого значения. Он не сохраняет все исходные emoji, частоты, имя файла шрифта, цепочку резервных вариантов или список поддерживаемых глифов. Набор представителей не является инвентарём.
Например, чисто иллюстративная последовательность строк "42", "42", "57" даёт в pattern две записи, а не три. Выбранными emoji будут первый для "42" и первый для "57". Числа показывают только арифметику и не являются выводом CreepJS. Пример делает потерю информации видимой, не публикуя корпус и не утверждая стабильное значение для конкретного emoji.
Эта политика отличается от статьи о границах метрик emoji CreepJS, где рассматриваются кортежи Canvas TextMetrics и отдельная группировка. Результат также не является инвентарём шрифтов: document.fonts.check() или список шрифтов профиля отвечает на другой вопрос, чем вычисленная длина текста SVG-узла. Документация шрифтов BotBrowser описывает наборы, резервные варианты и параметры рендеринга, но не превращает длину текста в список установленных файлов.
Операция Set удаляет частоты. Если десять входов имеют одну длину, а один отличается, последующая сумма видит две уникальные строки. Она не может определить, было ли в первой группе два emoji или двести. Называть emojiSet количеством, процентом покрытия или полным списком поддержки противоречило бы потоку данных.
Что вычисляет и отбрасывает svgrectSystemSum
В имени переменной есть System, но реализация задаёт более узкий расчёт. Для каждой строки из pattern код делит её по запятым, преобразует части унарным +, подставляет 0 для ложного числового результата и складывает части. Затем складываются итоги для строк, а общий результат умножается на 0.00001.
Логику можно записать так:
sum(pattern.map(s => sum(s.split(',').map(part => +part || 0)))) * 0.00001
На вход подаются разные строки getComputedTextLength(), а не все исходные узлы и не семикомпонентный геометрический кортеж. Повторы уже удалены, поэтому сумма теряет информацию до разделения по запятым. Коэффициент уменьшает величину, но не возвращает пропущенную структуру и не идентифицирует платформу.
Рассмотрим явно гипотетический набор {"42", "57"}. Две числовые части дают 99; умножение на 0.00001 даёт 0.00099. Если десять узлов выдали "42", а один "57", тот же набор разных значений даст тот же расчёт. Это иллюстрация, а не результат браузера или образец CreepJS.
Расчёт также не сохраняет API-источник каждого значения, исходный индекс emoji, число повторов или объяснение по шрифту. Не следует переименовывать его в «системный балл», «сумму ОС» или «отпечаток шрифта». Обоснованная формулировка: «масштабированная сумма числовых частей различных строк длины текста согласно этому закреплённому исходнику».
Различие с Canvas важно. Руководство по измерению текста посвящено Canvas measureText() и TextMetrics: это другая API и другие возвращаемые размеры. SVG-сборщик не повторяет эти поля под другим названием. Аналогично, проверки согласованности ClientRects относятся к прямоугольным фрагментам Element и Range, а не к длинам текста SVG и набору представителей.
Проверка смещения и состояние lied
После построения набора представителей сборщик выбирает svgElems[0] и читает начальный getComputedTextLength(). Он добавляет shift-svg, считывает значение снова, удаляет класс и получает восстановленное значение. Сравнение выглядит так:
initial - shifted != unshifted - shifted;
Если выражение истинно, сборщик устанавливает lied = true и вызывает documentLie('SVGTextContentElement.getComputedTextLength', 'failed unshift calculation'). Это описывает ветвь исходника. Оно не задаёт универсальный инвариант браузера, не доказывает причину различия двух чисел и не показывает, что внешний сервис назовёт среду автоматизированной.
Поле lied инициализируется не только этой проверкой. До неё оно берётся из выбранных записей lieProps, включая свойства SVGRect, getBBox, getExtentOfChar, getSubStringLength и getComputedTextLength. Поэтому false означает лишь, что накопленный предикат остался ложным для входов и ветви этой реализации. Это не подтверждает, что всё поведение SVG нативно, не изменено или одинаково на разных платформах.
Таблица отделяет наблюдение от объяснения:
| Видимое в исходнике состояние | Что устанавливает код | Чего оно не устанавливает |
|---|---|---|
| Начальное, смещённое и восстановленное значения удовлетворяют сравнению | На этой ветви предикат не установил lied. | Нормальный профиль, конкретную ОС или неизменённый браузер. |
| Сравнение отличается | Сборщик устанавливает lied и записывает указанную запись documentLie. | Причину, намерение или последующее решение. |
Выбранная предыдущая запись lieProps истинна | Начальное значение lied уже может быть истинным. | Какое именно изменение стало причиной без соответствующего источника доказательств. |
| Вызов выбрасывает исключение | Обработчик записывает passed: false и возвращает без объекта данных. | Что SVG не поддерживается, заблокирован политикой или отсутствует по конкретной причине. |
Это справочная таблица по исходнику, не результат проверки. Она не позволяет превратить имя ветви в причинный вывод.
Отсутствующие, заблокированные и ошибочные ветви
В рендерере результата есть отдельная ветвь для !fp.svg. Она показывает заголовок SVGRect и заблокированные заполнители для bBox, char, subs, text и блока сводки. Экран не объясняет, почему отсутствует fp.svg. Без независимых данных такой заполнитель нельзя переименовать в «SVG отключён», «шрифт недоступен» или «обнаружен бот».
Сбор выполняется и внутри try/catch. При исключении исходник вызывает logTestResult({ test: 'svg', passed: false }), передаёт ошибку в captureError и возвращает значение. Это отличается от успешно возвращённого data с lied: true и от вызова svgHTML() для объекта без svg. В записи интерпретации эти ветви нужно сохранять раздельно, а не сводить три наблюдения к слову «ошибка».
Для записи поддержки или исследования достаточно минимума: закреплённая версия исходника, имя поля, видимое значение или заполнитель и обсуждаемая ветвь. Не сохраняйте полные профили браузера, необработанные идентификаторы пользователей или весь результат CreepJS, если достаточно заметки по полю. Хеш или короткая метка тоже являются данными и требуют цели хранения.
Если поля нет, сначала запишите: «в этом отображаемом результате отсутствует». Затем перечислите возможные ветви исходника как гипотезы, например !fp.svg или catch, и отметьте их неподтверждёнными, если нет свидетельства выполнения. Закреплённый исходник показывает наличие ветвей, но не сообщает, какая произошла для отчёта без трассировки выполнения.
Различия геометрии SVG, Canvas и DOM
Три соседние темы используют похожие геометрические значения, но отвечают на разные вопросы. getBBox() и методы SVGTextContentElement работают с графикой или текстом SVG. Canvas measureText() возвращает TextMetrics для текста холста. CSSOM getClientRects() возвращает прямоугольники отображаемых фрагментов элемента или диапазона. Похожие имена не делают данные взаимозаменяемыми.
Граница API подсказывает, что проверять. Для длины SVG-текста отслеживайте точный элемент и вызов, например getComputedTextLength() в src/svg/index.ts. Для Canvas фиксируйте вход measureText() и свойства вроде ширины или фактических границ. Для геометрии CSSOM отдельно сохраняйте фрагменты элемента или диапазона и их сведение. Статья о согласованности ClientRects описывает последнюю задачу; она не объясняет svgrectSystemSum.
Разделение полезно и для вопросов о продукте. Шрифты профиля могут влиять на отображение, но поле коллектора не раскрывает файл, предоставивший глиф, факт резервной подстановки или источник разных длин. Для этого нужны данные о соответствующей загрузке шрифтов и рендеринге, а не только результат CreepJS.
Минимальная запись интерпретации
Шаблон связывает утверждение с доказательством, не превращая запись в профиль пользователя:
collector: CreepJS src/svg/index.ts
source_revision: 10aa6724cd33a1015db1574211890518cd04f0cc
report_field: emojiSet | svgrectSystemSum | lied | other named field
source_operation: exact method or branch
display_state: value shown | blocked placeholder | absent | error recorded
claim: source-bounded description of what was observed
not_established: OS, device, person, cause, or external verdict
retention: reason and deletion date
Это шаблон документации, а не генератор отчёта. В нём намеренно нет числовых примеров результата, профилей браузера и списков emoji по пользователям. Если для сравнения нужно значение, сохраняйте минимально необходимое и отмечайте источник; не заявляйте о новом запуске без реальной записи запуска.
Сравнивая две разрешённые записи, сначала выровняйте версию исходника, поле, видимую ветвь и преобразование. Сравнение строк emojiSet не равно сравнению всех входных emoji. Сравнение svgrectSystemSum не сравнивает исходное распределение длин, потому что Set удалил кратность. Сравнение lied сопоставляет предикат сборщика, а не доказывает подлинность одной среды и неподлинность другой.
Возможности и ограничения BotBrowser
BotBrowser документирует наборы шрифтов профиля, резервное поведение и кроссплатформенные настройки рендеринга. Эти возможности полезны для разрешённого сравнения совместимости, если вопрос касается поведения приложения с документированной конфигурацией. Публичная документация шрифтов не обещает одинаковые измерения SVGTextContentElement на всех платформах, не предоставляет результат SVG-сборщика и не определяет смысл svgrectSystemSum в CreepJS.
Ограничение существенно: настройки профиля не превращают разбор исходника в результат запуска или утверждение о конкретном устройстве. Здесь не заявляется, что BotBrowser запускает CreepJS, меняет значение SVG, скрывает отчёт или гарантирует межплатформенное совпадение. Для реального анализа совместимости сравнивайте указанную тестовую страницу при документированных конфигурациях и сохраняйте лишь доказательства, нужные для этого вопроса.
FAQ
svgrectSystemSum определяет операционную систему?
Нет. Закреплённый исходник вычисляет его из числовых частей разных строк длины и умножает итог на 0.00001. Код не определяет метку ОС или обратимый классификатор.
Является ли emojiSet полным списком поддерживаемых emoji?
Нет. Сборщик сохраняет первый emoji для каждой отличающейся строки getComputedTextLength(). Set удаляет повторения, а код не записывает число поддержанных значений и соответствие файлам шрифтов.
extentOfChar измеряет целый emoji?
Исходник передаёт EMOJIS[0] как аргумент метода. Код не устанавливает, что значение описывает весь emoji; такой вывод не следует делать.
lied: false доказывает нативность измерений?
Нет. Это только означает, что накопленный предикат не стал истинным на представленной ветви. Это не общая аттестация поведения SVG или каждого вызова API.
Что означает заблокированный заполнитель?
Рендерер показывает заполнители, когда отсутствует fp.svg. Видимое состояние не раскрывает причину отсутствия. Обработчик catch сборщика представляет собой отдельную ветвь, её нельзя выводить без данных выполнения.
Источники
- Закреплённый SVG-сборщик CreepJS,
src/svg/index.ts - MDN:
SVGGraphicsElement.getBBox() - MDN:
SVGTextContentElement.getComputedTextLength() - MDN:
SVGTextContentElement.getExtentOfChar() - MDN:
SVGTextContentElement.getSubStringLength() - Документация шрифтов BotBrowser
Практический вывод
Читайте карточку SVG CreepJS как последовательность операций исходника: сведение ограничивающего прямоугольника, измерение длины каждого текстового узла образца, выбор первого представителя для каждой уникальной строки, агрегат с потерями после масштабирования и предикат смещения/восстановления. Связывайте bBox, extentOfChar, subStringLength, computedTextLength, emojiSet, svgrectSystemSum и lied с их преобразованиями. Отсутствующий заполнитель и исключение считайте разными состояниями. Ни одно поле само по себе не устанавливает ОС, устройство, человека, инвентарь шрифтов или внешний вердикт.
Эта статья входит в руководство: Что такое отпечаток браузера?
Похожие статьи
Метрики эмодзи CreepJS: множества и суммы
ОтпечаткиОтчёт Intl CreepJS: поля и отсутствующие значения
ОтпечаткиОтчёт CreepJS WebRTC: происхождение полей
ОтпечаткиFingerprinting измерения текста: субпиксельное отслеживание
ОтпечаткиСигналы Math в CreepJS: источники полей
ОтпечаткиАудиоотчёт CreepJS: рендеринг и пропуски
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.