Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
215 views
in Technique[技术] by (71.8m points)

javascript - Open (Import) file in a chrome extension

I'm trying to develop import feature for my chrome extension, but this task seems more difficult then expected.

Actually my idea is to use an

<input type="file" id="myInput">

TO load the file and then add a change listener on that element:

element.addEventListener('change', function(evt){
    read_single_file(evt,tab);
}

Now there are several problem that i'm facing:

  1. The first problem is that the popup is closed when the open dialog opens, and it causes all related object and code to be destroyed with the popup page. And looking at other question, this is the normal behaviour of a chrome extension, when it lost focus the popup will be destroyed.
  2. I found another solution, that suggests to add the file logic into the background page, that will not be destroyed if the popup lost focus. Then i added this function in background:

    file_import = function(element, tab) {
    
        element.addEventListener('change', function(evt){
            read_single_file(evt,tab);
        }, false);
        element.click();
        console.log("uffa");
    }
    

And then i updated my popup.js to call the background method:

    get_current_tab(function(tab){
        var BGPage = chrome.extension.getBackgroundPage();
        BGPage.file_import(document.getElementById('myInput'), tab);
    });

And in that way the file_import is called by popup, it adds the change listener to myInput element, and opens up the File Open dialog but... opening the file dialog the popup is gone, and everything related to it, then... same problem again.

So i decided to try to create a new input file element in background page, and trigger click event from it, but obviously it doesn't work.

So, I'm stuck here, with no good ideas on how to solve that problem. Or at least i have few in my mind, but i don't know if they work, or they are just workaround.

  • One of them is to move the import feature into the devtools area (since it is an extension useful for developer it makes sense), where I hope that the open file dialog, doesn't cause to my extension to be destroyed.
  • Or another maybe could be to move the import file logic into an external page that opens a new tab and import the values from the files. In that case, since what I need only to access, except the file content is the current tab URL, maybe I don't have to use Google Chrome API.
  • The third idea is to inject an html element into the current page, and then access it from the extension adding the listener directly to that element, and in that case i don't think that my listener is destroyed if the popup is destroyed (the page will be reloaded just after the import, so my hidden input will stay just for the time needed for the operation).

To sum up my questions are:

  1. There is a clean way to read file content inside a chrome extension, without the need to use external files, open new tabs, etc (if possible i prefer to keep everything inside the extension)?
  2. If no is possible to prepopulate a new tab with a JavaScript file?
  3. Can i add a listener to DOM elements inside the current page?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Finally I decided for the third option, which was in my opinion, and for my purposes (read content from a file and update a URL) the easiest and fastest to implement.

Here what I did:

In my popup.js, when the user presses the import button, I call chrome.tabs.executeScript and read a file with the code to be injected into the current tab page:

else if(e.target.id=="import") {
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.executeScript(tabs[0].id, {file: "src/content_script.js"});
  });
}

Then I moved all the import logic in the content_script.js file, where I:

  1. Create a new input file element using document.createElement.
  2. Append this element as child of html <body>.
  3. Trigger click event from the element (it is important to remind that the .click event in chrome cannot be triggered on object that are not part of any DOM object).
  4. Handle change event for the input file.

Here is the code:

var fileChooser = document.createElement("input");
fileChooser.type = 'file';

fileChooser.addEventListener('change', function (evt) {
  var f = evt.target.files[0];
  if(f) {
    var reader = new FileReader();
    reader.onload = function(e) {
      var contents = e.target.result;
      /* Handle your document contents here */
      document.location.href = url_array; // My extension's logic
    }
    reader.readAsText(f);
  }
});

document.body.appendChild(fileChooser);
fileChooser.click();

It seems that in a content script I cannot access the chrome.tabs object, so in my case I just decided to use the usual document.location.href to change the URL.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...