Почему вызов Window.scroll() дает доверенное событие?

У меня есть расширение Chrome, которое должно создавать человекоподобное поведение мыши и клавиатуры (в частности, генерировать события со значением isTrusted true). Я могу делать все, что мне нужно, кроме прокрутки с помощью API chrome.debugger.

Но кажется, что для этой цели достаточно Window.scroll() до Chrome 52 и Firefox 48.0a1. Это можно наблюдать, подключив прослушиватель событий к странице следующим образом:

document.addEventListener("scroll", function (event) { 
    console.log("event trusted? " + event.isTrusted);
});

а затем запустите нечто вроде window.scroll(0, 10); в консоли разработчика. Это приведет к регистрации event trusted? true в консоли разработчика.

Мой вопрос: почему это так? Если в этом случае свойство isTrusted не должно быть isTrusted, так как событие прокрутки было явно сгенерировано с помощью script?

Ответ 1

Это по спецификации, за DOM Living Standard:

ПРИМЕЧАНИЕ: isTrusted - это удобство, которое указывает, что event отправлено пользовательским агентом (в отличие от использования dispatchEvent()). Единственным исключением является click(), что заставляет пользовательский агент отправлять event, атрибут isTrusted инициализируется как false.

Кроме того, в DOM Level 3 Events Specification:

3.4. Надежные события

События, которые генерируются пользовательским агентом , либо в результате взаимодействия с пользователем, либо как прямой результат изменений в DOM, доверяются пользовательскому агенту с привилегиями , которые не предоставляются событиям, генерируемым script, через createEvent(), измененный с помощью метода initEvent() или отправленного с помощью метода dispatchEvent(). isTrusted атрибута доверенных событий имеет значение true, а недоверенные события имеют значение атрибута isTrusted false.

Таким образом, isTrusted отражает только если событие было отправлено или создано искусственно с использованием createEvent, initEvent или dispatchEvent. Теперь рассмотрим определение Window.scroll за CSSOM View Module Editor Draft:

При вызове метода scroll() эти шаги должны выполняться:

[...]

  1. Если вызывается с двумя аргументами, выполните следующие шаги:

      [...]

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

Нигде в методе это искусственное событие, созданное с помощью createEvent, initEvent или dispatchEvent, поэтому значение isTrusted равно true. Обратите внимание, что использование Window.scroll по-прежнему запускает обработчик событий, потому что он интегрируется с циклом события, а событие scroll испускается при прокрутке видового экрана или элемента. Однако это не использует createEvent, initEvent или dispatchEvent.

Использование события isTrusted не является надежным способом обнаружения, вызвало ли событие script событие. Он определяет только, было ли событие создано и отправлено с помощью createEvent, initEvent или dispatchEvent.

Ответ 2

Кажется, что *.scroll или изменение свойства scrollTop не создает событие правильно. Как вы можете видеть в примере, isTrusted есть false, если я создаю событие самостоятельно. Я думаю, что это ошибка в Engine

"use strict";
var event = new Event('scroll');

//target.addEventListener(type, listener[, options]);
//target.addEventListener(type, listener[, useCapture]);
//target.addEventListener(type, listener[, useCapture, wantsUntrusted  ]); // Gecko/Mozilla only
window.addEventListener('scroll', function(e) {
  console.log(e.isTrusted);
}, false);

console.log('JS engine event:');
window.scroll(10, 10);

setTimeout(function() {
  console.log('Selfmade event:');
  window.dispatchEvent(event);
}, 1000);

setTimeout(function() {
  console.log('Another event triggered by changing the scrollTop property:');
  window.scrollTop = '20px';
}, 2000);
#container {
  width: 100px;
  height: 10000px;
  overflow: scroll;
}
<div id="container">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
  sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
  Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</div>