Контекстное меню JavaScript не может получить выделенный текст, если текст является входным тегом/текстовым полем

У меня была очень большая проблема, чтобы каким-то образом получить выделенный текст с веб-страницы, а затем обработать его с помощью контекстного меню... когда я решил для Chrome, Firefox и IE11, я обнаружил, что не могу получить выделенный текст в Firefox и Internet Explorer когда выделенный текст находится в поле ввода....

Я искал несколько дней, чтобы как-то решить, и, наконец, я добился успеха...

Это был оригинальный сценарий для Internet Explorer

var parentwin = external.menuArguments
var selectedText = getSel();


function getSel(){
  var w=window,d=parentwin.document,gS='getSelection';
  return (''+(w[gS]?w[gS]():d[gS]?d[gS]():d.selection.createRange().text)).replace(/(^\s+|\s+$)/g,'');
}

И это для FireFox

var contextMenu = require("sdk/context-menu");
var tabs = require("sdk/tabs");
var clipboard = require("sdk/clipboard");
var {Cc,Ci} = require('chrome');
var simpleGetLibrary = null;
var menuItem = contextMenu.Item({
  label: "Get selected text",
  context: contextMenu.SelectionContext(),
  contentScript: 'self.on("click", function () {' +
                 '  var text = window.getSelection().toString();' +
                 '  self.postMessage(text);' +
                 '});',
  onMessage: function (selectionText) {
    console.log(selectionText);
	clipboard.set(selectionText);   //this line copy the selected text to Clipboard
}

Но я понятия не имел, как я могу каким-то образом получить текст, когда он находится в поле ввода... <INPUT> ...</INPUT> Решение следующее...


person RobiGo    schedule 15.01.2015    source источник


Ответы (1)


Для Internet Explorer IE11

var parentwin = external.menuArguments
var selectedText = getSel();


function getSel(){
  var w=parentwin.window,d=parentwin.document,gS='getSelection';
  var selectedText;
  var rv=(''+(w[gS]?w[gS]():d[gS]?d[gS]():d.selection.createRange().text)).replace(/(^\s+|\s+$)/g,'');
  parentwin.console.log("the selected text is in first try is:"+rv);
  
 if (rv=="") {
   var allinput = parentwin.document.getElementsByTagName("input");  //I get an array of all input tags
   var index;
   var newsel;
   var found="false";
   for (index = 0; index < allinput.length; index++) {
    parentwin.console.log("index: "+index);
    newsel="";
    parentwin.console.log("newsel= ");
    try {
      var ss = allinput[index].selectionStart;
      parentwin.console.log("ss");
      var se = allinput[index].selectionEnd;
      parentwin.console.log("se");
      if (typeof ss === "number" && typeof se === "number") {
        newsel=allinput[index].value.substring(ss, se);
        found=newsel;
        if (newsel.length>0){
        rv=newsel;
        found="true";
        allinput[index].selectionEnd=allinput[index].selectionStart;
        newsel="";
        }
      }
    }
    catch(err){}
    parentwin.console.log("input fields "+index+"/"+allinput.length+" fieldname:"+allinput[index].getAttribute("name")+" selection: "+newsel);
    if (found=="true"){
    index=allinput.length;
    }
   }
   parentwin.console.log("found=:"+found);
 }
  return rv;
}

И для Firefox это немного сложно, потому что у меня нет доступа к DOM, поэтому мне нужно разрешить это в сборке ContentScript, а затем я отправляю результат напрямую... потому что я не могу решить, как получить только выбор, Я отправляю значение поля ввода, не имеет значения, если не все выбрано...

var contextMenu = require("sdk/context-menu");
var tabs = require("sdk/tabs");
var clipboard = require("sdk/clipboard");
var preferences = require("sdk/simple-prefs").prefs;
var {Cc,Ci} = require('chrome');
var simpleGetLibrary = null;
var menuItem = contextMenu.Item({
  label: "Get selected text",
  context: contextMenu.SelectionContext(),
  contentScript: 'self.on("click", function (node, data) {' +
                 '  var text = window.getSelection().toString();' +
				 '  console.log("Selected node is: "+node.nodeName);' +
				 '  console.log("Selected value is: "+node.value);' +
                 '  if (text.lenght>0)' +
				 '  self.postMessage(text);' +
				 '  else ' +
				 '  if (node.nodeName=="INPUT")' +
				 '  self.postMessage(node.value);' +
				 '});',
  onMessage: function (selectionText) {
    console.log("Selection sent for processing is: "+selectionText);
    clipboard.set(selectionText);   //this line copy the selected text to Clipboard
  }

person RobiGo    schedule 15.01.2015
comment
Какое замечательное решение! Красиво напечатано! Всегда поддерживаю людей, которые разбираются в своем вопросе, возвращаются и делятся ответом! - person Noitidart; 16.01.2015