Пользовательские операции вырезания, копирования и вставки для WKWebView

Я разрабатываю приложение Cocoa для упаковки разработанного мной веб-приложения JavaScript, которое обеспечивает редактирование графики SVG. У меня есть следующий вопрос, который мотивирован желанием настроить операции "Вырезать", "Копировать" и "Вставить" и связанные с ними пункты меню.

Как я могу:

  • замените моего собственного ответчика вместо WKWebView или
  • настроить его ответы на validateMenuItem: и cut: copy: and paste: selectors?

Меня особенно интересуют решения, которые сохраняют полезную функциональность WKWebView для предоставления вырезания, копирования и вставки для текстовых полей.

Любая помощь приветствуется. Далее следует деталь.


Цель моей обертки cocoa состоит из трех частей:

  1. обеспечить постоянство
  2. для обеспечения интеграции буфера обмена
  3. обеспечить печать

Я достиг 1, но заблокирован на 2 и 3; этот вопрос составляет около 2.

В частности, я не могу заставить фреймворк вызывать любую реализацию validateMenuItem: что я предоставляю - в результате я не могу контролировать, когда пункты меню "Вырезать", "Копировать" или "Вставить" доступны для выбора пользователем.

Я пробовал следующее:

  1. отметьте мой подкласс NSViewController как принимающий первого ответчика и переопределите validateMenyItem: там - моя реализация никогда не вызывалась
  2. подкласс WKWebView и переопределить validateMenuItem: - моя реализация никогда не вызывалась
  3. подкласс NSWindowController и переопределить validateMenuItem: - моя реализация никогда не вызывалась

Теперь у моего завернутого веб-приложения есть текстовые поля. Когда я даю один из этих фокусов и когда это уместно (текст находится в буфере обмена, я выделяю текст), опции "Вырезать", "Копировать" и "Вставить" в моем меню "Редактировать" автоматически активируются. Они даже работают. (Мне нравится эта функциональность и я хотел бы ее сохранить.) Поэтому я подозреваю, что происходит то, что WKWebView, как мой текущий первый ответчик, перехватывает любой вызов validateMenuItem: по цепочке ответчиков. Но мне также нужно иметь возможность активировать пункты меню в соответствии с другими состояниями в моем завершенном веб-приложении - например, когда пользователь выбирает SVG-графику.


Обновить

Я сделал дополнительный копать, пытаясь найти решение моей проблемы. В моем подклассе WKWebView я добавил пользовательский @IBAction. Я создал пункт меню для этого на моей доске объявлений и подключил пункт меню к FirstResponder, выбрав мое новое действие.

И мой validateMenuItem: на моем подклассе WKWebView был вызван. Но только для этого нового селектора, а не для copy: селектор, связанный с @IBAction который я ранее добавил в мой подкласс WKWebView.

Теперь мой метод copy: отмеченный с помощью @IBAction и имеющий подпись метода для вещей, которые Interface Builder (или что-то, что он назвал в наши дни), может использовать, не помечен как override. Когда я попытался пометить его override, я получил сообщение об ошибке. По-видимому, WKWebView не предоставляет метод copy:id даже если он предоставляет функции копирования и правильно обрабатывает пункт меню, когда выбран текст в текстовом поле.

Таким образом, похоже, что WKWebView каким-то образом автоматически (и всегда) обрабатывает проверку определенных селекторов, обычно привязанных к меню - в частности, cut: copy: и paste: Более того, подклассификация WKWebView и переопределение validateMenuItem: недостаточно для прерывания/принятия контроля над этим поведением по умолчанию. Что кажется странным.

Но, читая другие сообщения в WKWebView на StackOverflow, я знаю, что WKWebView на самом деле представляет собой довольно сложную функциональность. Меня особенно интересует, что WKWebView фактически запускает веб-контент в отдельном процессе. Поэтому я задаюсь вопросом, отвечает ли что-то, связанное с этим отдельным процессом, на проверку меню и обработку cut: copy: и paste: - что-то внутреннее для рамки и к которому у меня нет доступа.

Я все еще надеюсь на решение. Надеемся, что приведенное выше обновление окажется полезным.

Ответ 1

Как ни странно, я также рассматривал перенос векторного дизайна на Mac через WKWebView и столкнулся с той же проблемой. Похоже, вы можете управлять пунктами меню cut/copy/paste внутри JavaScript. Если вы добавите beforecopy и beforecut обработчики событий и preventDefault(), то пункты меню cut and copy будут включены. Однако я не могу включить элемент меню пасты. Я думаю, что это может быть связано с долгой ошибкой в WebKit. Вы все еще можете -V на клавиатуре, и вставка все равно произойдет, потому что в этом случае WebKit пропустит вызов beforepaste и просто вызовет событие paste напрямую. Я просто не могу понять, как включить элемент меню пасты. В качестве обходного пути я создал пункт меню "поддельные" вставки, который не переходит в обычный paste: селектор, но к моему собственному селектору, который WKWebView не будет перехватывать.