I made a crop screenshot and upload addon for Firefox. I would like to bring a feature that allows user to tweet the images.
Manually (as human does it) the process is this:
- Open twitter.com (if not signed in tell user to sign in)
- Click "new tweet" this is done
- Attach images by doing "Add photo" and browse to file
- This is gif of this process:
- Then I focus the tab and focus the tweet input box
- So user can type the message, then "whose in the photos" if they want, then click tweet. The great thing is with this method, the images have not bothered twitter servers, as the images are not uploaded until users final write off, when they click the "Tweet" button. So user has chance to decide to click X to remove a screenshot attached before hitting "Tweet". I find this way very friendly to the user and to the twitter servers. (If there is a file size limit that can be attached ill do that check in my addon and let user know it cant go in)
The problem
I am trying to automate steps 1-4. I can do 1, 2, and 4 perfectly.
I am trying to programmatically do step 3. It seems Twitter does not use the input[type=file].files
html5 api, they are doing some custom javascript. Does anyone know how I can programtically add in images? I have full privelaged javascirpt code access as this is a Firefox addon.
One big reason I cant tell user to go attach themslves is these image are stored in memory for performance, not in file, so I need to attach them programtically.
Code I tried (HTML5 FileList API)
It uses the mozSetFileArray
defined here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement and its brother mozSetFileNameArray
here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/mozSetFileNameArray
// Step 1 - Open twitter.com (for testing purposes, twitter.com is open in tab 7 so I dont load it here)
var aContentWindow = gBrowser.tabContainer.childNodes[6].linkedBrowser.contentWindow; // gets window of tab 7
var aContentDocument = aContentWindow.document;
// Step 2 - Open tweet modal
var btnNewTweet = aContentDocument.getElementById('global-new-tweet-button');
console.info('btnNewTweet:', btnNewTweet);
if (!btnNewTweet) {
throw new Error('global tweet button not found, probably not logged in');
}
btnNewTweet.click();
// Step 3 - Attach two File instances for test purposes (in production will attach Blob)
var inputAddPhoto = aContentDocument.getElementById('global-tweet-dialog').querySelector('input[type=file]');
console.info('inputAddPhoto:', inputAddPhoto, inputAddPhoto.mozGetFileNameArray);
if (!inputAddPhoto) {
throw new Error('add photo button not found! i have no idea what could cause this');
}
var newFiles = [];
var myFile1 = new File('C:\\Users\\Vayeate\\Pictures\\Screenshot - Tuesday, August 11, 2015 6-33-58 AM.png'); // using local file for testing
var myFile2 = new File('C:\\Users\\Vayeate\\Pictures\\Screenshot - Tuesday, August 11, 2015 6-38-08 AM.png'); // using local file for testing
newFiles.push(myFile1);
newFiles.push(myFile2);
inputAddPhoto.mozSetFileArray(newFiles);
// Step 4 - Focus message field
// var richInputTweetMsg = aContentDocument.getElementById('tweet-box-global');
// richInputTweetMsg.focus(); // not needed because as when the modal opens twitter puts focus into here anways
// Step 5 - Done, now user can choose to type message, tag "whose in photo", and remove previews. The great thing is with this method, the images have not bothered twitter servers, the images are not uploaded until users final write off, when they click the "Tweet" button
Inspection
I did some debugger inspection, I put a breakpoint on drop, and found that it comes in here, there's some kind of add
function.