Разбор CSS с помощью JavaScript.Несоответствие по Edge и Chrome - PullRequest
0 голосов
/ 29 ноября 2018

Я анализирую с помощью JS CSS и пытаюсь получить целочисленное значение Unicode для правила CSS «content», но оно обрабатывается по-разному в Edge и Chrome.

В Edge «content»это строка из 7 символов:

enter image description here

В Chrome это строка из 3 символов:

enter image description here

csDef - моя переменная JS.

Вот как выглядит правило CSS:

enter image description here

Почему значение по-разному обрабатывается в веб-браузерах?А в JS и как я могу правильно получить целочисленное значение Unicode для этих веб-браузеров?

EDIT:

Вот как я загружаю правила CSS:

        var rulesForCssText = function (styleContent) {
            var doc = document.implementation.createHTMLDocument(""),
                styleElement = document.createElement("style");

            styleElement.textContent = styleContent;
            doc.body.appendChild(styleElement);

            return styleElement.sheet.cssRules;
        };

       var cssDefs =  Array.from(rulesForCssText(fileContent));

fileContent - это содержимое файла, полученное с использованием объекта File, у меня есть input type="file", и пользователь выбирает файл с диска.

1 Ответ

0 голосов
/ 05 декабря 2018

Отказ от ответственности : У меня нет однозначного ответа, но я многому научился из анализа и думаю, что результаты могут быть интересны для других людей.


Прежде всего, позвольте мне поделиться двумя контрольными примерами.На основе CSS воспроизводится описанная вами проблема:

var d = document.implementation.createHTMLDocument("");
var s = document.createElement("style");
s.textContent = '.foo{content: "\\20ac";}';
d.body.appendChild(s);
var c = s.sheet.cssRules[0].style.getPropertyValue("content");
console.log("String '%s' has length %d", c, c.length);

Desktop Firefox и Chrome отображают числовую ссылку на символ (String '"€"' has length 3), а Edge - нет (String '"\20ac"' has length 7).

Интересно, что секундаТестовый пример на основе HTML, похоже, не представляет никаких проблем:

var s = document.getElementsByTagName("span")[0].textContent;
console.log("String '%s' has length %d", s, s.length);
<span>&#x20ac;</span>

Оба браузера отображают сущность (String '€' has length 1).

Итак, кто здесь?Черновик редактора CSS Object Model (CSSOM) гласит:

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

… и вот где я полностью потерялся.

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

function browserRendersCharacterReferences() {
  var d = document.implementation.createHTMLDocument("");
  var s = document.createElement("style");
  s.textContent = '.foo{content: "\\20ac";}';
  d.body.appendChild(s);
  return s.sheet.cssRules[0].style.getPropertyValue("content").length === 1;
}

function renderCharacterEntities(t) {
  // THIS FUNCTION IS WRONG, DON'T USE IT, IT'S JUST A QUICK EXAMPLE
  var r = /\\([\da-f]{4})\s?/gi;
  t = t.replace(r, function (match, codePoint) {
    return String.fromCharCode(parseInt(codePoint, 16));
  } );
  return t;
}

function rulesForCssText(css) {
  var d = document.implementation.createHTMLDocument("");
  var s = document.createElement("style");
  var c;
  s.textContent = css;
  d.body.appendChild(s);
  c = s.sheet.cssRules[0].style.getPropertyValue("content");
  if (!browserRendersCharacterReferences()) {
    c = renderCharacterEntities(c);
  }
  return c;
}

console.log(rulesForCssText('.foo{content: "\\20ac  and \\f102";}'));

PS Сначала я сделал несколько замечаний по поводу \f102, которые были совершенно неверными.Это полностью действительный escape-символ CSS :

Экранирование начинается с обратной косой черты, за которой следует шестнадцатеричное число, представляющее шестнадцатеричное значение кода Unicode.

… который соответствует полностью действительному символу Unicode, хотя и в блоке Область личного пользования :

диапазон кодовых точек, которые по определению не будут назначеныперсонажи Консорциума Unicode.[…] Их намеренно оставляют неопределенными, чтобы третьи стороны могли определять свои собственные символы, не вступая в конфликт с назначениями Консорциума Unicode.

Другими словами, он зарезервирован для частного использования.Какие виды использования?Например, Ionicons Font Icon , который вы, похоже, используете (обычный шрифт, который отображает символы на неиспользуемые позиции Unicode, поэтому он не мешает обычному тексту):

<link href="https://unpkg.com/ionicons@4.2.2/dist/css/ionicons.min.css" rel="stylesheet">
<i class="icon ion-ios-add"></i>
...