Как настроить Firefox, чтобы позволить Javascript перехватывать значение, вставленное из буфера обмена?

Мне нужно отфильтровать определенные символы, когда пользователь вставляет из буфера обмена. (На самом деле я не хочу изменять то, что находится в буфере обмена.) У меня уже есть это работает в IE. Вздох...

ТЛ; др: capability.policy элементы в user.js преобразуются в prefs.js, но не вступают в силу.

К вашему сведению, все пользователи могут установить user.js. Но никто из нас не имеет доступа администратора к нашим машинам, так что это все, что я могу сделать в отношении конфигурации.

Спасибо за любую помощь!

Замечания:

  1. Для целей этого вопроса я не хочу "обойти" доступ к буферу обмена -
    Например, я не хочу работать со значением элемента DOM после вставки
  2. Я не хочу решение, которое требует рамки / библиотеки (например, jQuery, Dojo, Prototype, YUI, ...)

Шаги следовали

  1. Определите местоположение папки моего профиля, перейдя по URL-адресу о: support => Каталог профиля => Открыть папку, содержащую

  2. Попытался включить буфер обмена в Firefox, создав user.js со следующими строками:
    user_pref("just.mike", "проверить, работает ли user.js.");
    user_pref("ability.policy.policynames", "allowclipboard");
    user_pref("ability.policy.allowclipboard.sites", "https://my-site.com");
    user_pref("ability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
    user_pref("ability.policy.allowclipboard.Clipboard.paste", "allAccess");
    
    Примечание: https://my-site.com не является реальным сайтом.

  3. Как оказалось, capability.policy элементы не видны, используя about:config - из-за Bugzilla Bug 284673 - about:config скрывает настройки "ability.policy ". Тем не менее, я думаю, что эти элементы user.js "сработали" и что файл находится в правильной папке, потому что потом:
    • о: конфиг показал just.mike запись
    • prefs.js содержит все новые строки, но в другом порядке - в алфавитном порядке:
      user_pref("ability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
      user_pref("ability.policy.allowclipboard.Clipboard.paste", "allAccess");
      user_pref("ability.policy.allowclipboard.sites", "https://my-site.com");
      user_pref("ability.policy.policynames "," allowclipboard ");
      ...
      user_pref("just.mike", "проверить, работает ли user.js.");
      
    (К вашему сведению, я тоже пытался Zallowclipboard везде, чтобы policynames линия появилась первой из-за алфавитизации, но это тоже не сработало.)

  4. Попытка прочитать буфер обмена в Firefox после onpaste событие со следующим:
    var clipboard = Components.classes ["@ mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard);
    if (! clipboard) {
        выбросить новую ошибку ("внутренняя ошибка - не удалось создать объект буфера обмена");
    }
    
    var transferable = Components.classes ["@ mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
    если (! передаваемый) {
        выбросить новую ошибку ("внутренняя ошибка - не удалось создать передаваемый объект");
    }
    
    transferable.addDataFlavor ("текст / юникод");
    clipboard.getData(передаваемый, clipboard.kGlobalClipboard);
    
    var clipboard_data = new Object ();
    var clipboard_length = new Object ();
    
    transferable.getTransferData ("text / unicode", clipboard_data, clipboard_length);
    
    var clipboard_text = '';
    if (!! clipboard_data) {
        var clipboard_nsISupportsString = clipboard_data.value.QueryInterface (Components.interfaces.nsISupportsString);
        clipboard_text = clipboard_nsISupportsString.data.substring (0, clipboard_length.value / 2);
    }
    
    возвращать (clipboard_text);
    

  5. Код завершается ошибкой в первой строке, возвращая эту ошибку в консоли Firebug:
    В  отказано в доступе к свойству XPCComponents.classes
    
    Примечание. На самом деле я запускаю его по реальному URL-адресу, который отображается в сообщении об ошибке - я просто изменил его на фиктивное имя.

  6. Я также видел несколько других примеров, когда createInstance был использован в первой строке вместо getService, но первая строка все еще генерирует тот же текст ошибки:
    var clipboard = Components.classes ["@ mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard);
    // ...
    


Окружающая среда (это вне моего контроля)

  • Нет доступа администратора к компьютеру
  • Виндоус виста
  • Mozilla Firefox 10

Рекомендации

3 ответа

Короче говоря, я не думаю, что можно делать то, что вы хотите делать, как вы хотите это сделать. Mozilla (и большинство современных браузеров) ограничивают доступ к буферу обмена из соображений безопасности. То, что вы, кажется, легко обошли это ограничение в IE, - не утешительная мысль.

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

Если все, что вам нужно, - это запретить ввод определенных строк в текстовое поле, лучше всего следить за событиями в самом текстовом поле.

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

  1. Установите текстовое поле на readonlyи всплывающую виртуальную клавиатуру, чтобы заставить пользователя "печатать" в поле с помощью мыши. (Вы должны будете сами построить клавиатуру из HTML и JavaScript или найти где-нибудь подходящее решение.)
  2. Контролировать oninput событие; если текстовое поле изменяется быстрее, чем можно разумно ожидать от человека, отклоните изменения.

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

Можем ли мы сказать, что вы хотите найти альтернативу в обнаружении вставки в буфер обмена? С тех пор, когда вы знаете, что там было раньше, вы знаете, что изменилось.

Так почему бы просто не зацепить обмен? Все символы, идентичные с начала и конца содержимого, не вставляются. Если вы хотите отличить это от простых нажатий клавиш, послушайте нажатие клавиш / нажатие клавиш, тогда вы знаете, какие изменения происходят из "других мест".

Грубый, но перекрестный способ - сравнить текущее значение с предыдущим событием onchange.

Если его длина увеличивается или значение отличается слишком сильно (не только уменьшено, но и много новых символов) - возможно, что-то вставлено из буфера обмена. Что-то вроде этого:

$('input, textarea').change(function(){
  var prev = $(this).data('prev-val'), 
      current = $(this).val();
  if (is_big_changes(prev,current)) {
    $(this).val(my_filter_func(current));
  }
  if (!prev) {
     $(this).data('prev-val', current);
  } 
})

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

Где is_big_changes и my_filter_func - функции, которые нужно реализовать.

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

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