Диалог подтверждения теряет фокус на iOS10

В мобильной версии моего веб-сайта у меня есть диалоговое окно подтверждения JavaScript, которое появляется при определенных обстоятельствах. С помощью setTimeout Я запускаю диалоговое окно подтверждения. Независимо от того, на какой вкладке находится пользователь, он должен видеть confirm dialog но в iOS 10 теряет фокус.

В iOS версии 8 и 9 отлично работает, когда у меня есть две вкладки, и я на второй вкладке, диалог подтверждения появляется впереди, как и должно быть.

Есть ли какое-либо решение или обходной путь для этого?

var cf = confirm("Close?"); 
if (cf){ do that....} else { do this... }

1 ответ

SafariDriver реализован в JS, поэтому для перехвата вызовов alert, confirm, а также promptнеобходимо переопределить функции в контексте веб-страницы.

Измените внедренный скрипт, который будет вставлен как Start сценарий вместо End script - это означает, что сценарий внедряется после загрузки DOM, но до его анализа (в отличие от внедрения после события onload):

http://developer.apple.com/library/safari/#documentation/Tools/Conceptual/SafariExtensionGuide/InjectingScripts/InjectingScripts.html#//apple_ref/doc/uid/TP40009977-CH6-SW5

Переопределите глобальные функции оповещения в контексте тестируемой страницы, а не внедренного сценария. Это похоже на требования команды executeScript. Поэтому первое, что должен сделать наш внедренный скрипт, это добавить тег DOM для DOM, который устанавливает переопределения предупреждений. Этот тег сценария должен быть добавлен как первый дочерний элемент documentElement, чтобы обеспечить его выполнение перед любыми другими на странице. Это гарантирует, что мы настроим наши обработчики предупреждений до того, как что-либо на странице сможет сработать.

Когда срабатывает оповещение, мы должны уведомить расширение о наличии оповещения, одновременно блокируя текущий поток JS на странице. Обычно наши скрипты страницы взаимодействуют с внедренным скриптом, используя window.postMessage. postMessage запускает MessageEvent асинхронно. Чтобы поддерживать синхронность, мы можем вручную запустить MessageEvent:

Use a MessageEvent instead of some other DOM event so we can include a JSON object describing the alert.

var event = document.createEvent('MessageEvent');
event.initMessageEvent('message', false, false, {
  type: "alert",  // confirm, or prompt
  text: "hello"
}, window.location.origin, '0', window, null);
window.dispatchEvent(event);

Внедренный скрипт должен прослушивать ответ на предупреждающее сообщение страницы. Чтобы синхронно отправить предупреждение на расширение для обработки, мы можем (ab) использовать механизм расширения Safari для блокировки загрузки контента:

http://developer.apple.com/library/safari/#documentation/Tools/Conceptual/SafariExtensionGuide/MessagesandProxies/MessagesandProxies.html#//apple_ref/doc/uid/TP40009977-CH14-SW9

window.addEventListener('message', function(e) {
  // Create a beforeload event, which is required by the canLoad method
  var e = document.createEvent('Events');
  e.initEvent('beforeload', false, false);

  // canLoad sends and waits for a response synchronously. It is the only
  // synchronous function in the Safari extension messaging API.
  var response = safari.self.tab.canLoad(e, e.data);

  // Send the response back to the page using another MessageEvent.
  var responseEvent = document.createEvent('MessageEvent');
  responseEvent.initMessageEvent('message', false, false, {
    accepted: response.accepted,
    response: response.value
  }, window.location.origin, '0', window, null);
  window.dispatchEvent(responseEvent);
}, true);

Обратите внимание, что ответ на оповещение расширения должен быть передан обратно на страницу с помощью другого сообщения, поскольку мы пересекаем границы контекста. Единственный другой вариант - сохранить ответ на DOM для чтения на другой стороне.

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

Одна возможность состоит в том, чтобы клиент WebDriver участвовал в обработке предупреждений. Ожидается, что помимо предоставления сервера WebSocket, клиент WebDriver также будет предоставлять конечную точку XHR. При обнаружении предупреждения сервер отправит синхронный POST XHR к этой конечной точке. Клиент должен ответить только после того, как пользователь принял или отклонил предупреждение (или из-за другой команды возникла необработанная ошибка предупреждения). Когда ответ XHR получен, расширение завершает цепочку и отправляет ответ обратно внедренному сценарию.

Вы можете найти больше здесь.

Другие вопросы по тегам