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.
Related
The Situation
I have this code below, which was working perfectly many many times the way it is, then all of a sudden it stopped working when it gets to the step of opening a new tab via javascript.
url = 'https://website'
opt = Options()
opt.add_argument('--start-maximized')
opt.add_argument("disable-infobars")
opt.add_experimental_option("detach", True)
service = Service(r'C:\Users\chromedriver_new.exe')
driver = webdriver.Chrome(options= opt,service = service)
login(url) ###function that opens the url and passes user/keyword - up to this part it's working perfectly
img_url = "https://website/" + url[30:55] + "/img.jpg" ##source of image I want to download
#The problem starts here, I've printed the img_url and I can open it fine in my navigator, but when I run the code it just stops here and never opens the new tab
#I've already tried changing the javascript by passing "+img_url+" directly
#I've also tried already to open a blank new tab and even this is not working
driver.execute_script('window.open(arguments[0],"_blank");',img_url) ###open link in new tab
time.sleep(2)
driver.switch_to.window(driver.window_handles[1]) ##change focus to new tab
time.sleep(2)
img_url_full = driver.find_element(By.XPATH,"/html/body/img").get_attribute("src") ##it gets the full path to the image, which includes a valid token that enables me to access (if I would try to downlaod the img_url directly it wouldn't work)
time.sleep(2)
urllib.request.urlretrieve(img_url_full,name) ##download image
Extra Information
I don't know if that has something to do with it, but usually my browser would always stay open unless I closed it manually (there is no close/quit on the code), but around the same time that the new tab stopped to work the browser started to close automatically right after the step of login - to avoid that I then had to add the
opt.add_experimental_option("detach", True)
(which is working).
The Question
Why is this happening and how could i debug this?
I'm trying to automatically send a motivational message to a friend who's studying for an exam over hangouts.
I'm using the hangouts app at https://hangouts.google.com/ (using the gmail site wouldn't allow me to access the DOM of the iframe because of the Same-Origin-Policy) and am already able to set the value of the chatbox-div:
var ifrm = document.getElementById('iframeid'); // changes after reload
var doc = ifrm.contentDocument;
var chat = doc.getElementById('chatdivid'); // also changes
chat.innerHTML = "go kathi go!";
This works already.
My problem now is: how do I either send the appropriate keypress to that div or fire the event/callback directly?
I already tried to send an enter-keypress like this:
var enterPress = new KeyboardEvent('keypress', {'key': 'Enter'});
chat.dispatchEvent(enterPress);
But this only deletes the faint informational "Send a message" message and doesn't submit the chat message.
I didn't find solution using JS for your problem, but I think (if you also didn't find it) you can use macroses.
I would use Firefox + iMacros. Chrome has this extension too, but it's worse.
I have a little application on web that uses JS Alerts. I am planning to use modal pops later, but for the time being, does anyone know how to detect if the user clicked on the "prevent this page from creating additional dialogs" and then fire some js function?
it is indeed possible to detect if prevent additional dialogs has been clicked by working with javascript date
you can try this lines of code
window.nativeAlert = window.alert;
window.alert = function(message) {
var timeBeforeAlert = new Date();
var confirmIfBlocked = nativeAlert(message);
var timeAfterAlert = new Date();
if ((timeAfterAlert - timeBeforeAlert) < 400) {
tellTheUserDialog("you can use a Div to tell the user he has blocked alert");
}
}
if users does not see alert then timeAfterAlert will be almost the same as timeBeforeAlert, i used 400 milliseconds just for reference you can come up with yours
You can't detect it because it is a browser feature which helps the user get rid of indefinite popups. This is particularly useful when your JavaScript code shows popups in a loop.
A good idea is to use modals or plugins like Bootbox to show alerts.
I noticed that if I have a gmail tab open with conversation view on/off, and then I open another tab and change the conversation view setting, my original tab stays in the conversation view state it started in such as when doing new searches etc. and the new tab uses the setting I just changed it to.
This led me to think there might be some JavaScript bookmarklet / favelet / "scriptlet" that could easily let us change the setting for a given gmail tab temporarily without having to go into the settings.
Does anyone know of this already in existence or is anyone able to create it? My thought would be to capture a load of gmail with it on and with it off and do a diff / winmerge on the two to see what's different and take it from there, but I'm hoping someone's already created it =).
I'll look into the gmail js and make a bookmarklet :P
Edit: seems the js is obfuscated A lot, copying the function from the original js is gonna be hard...
I'll check what the html changes are between both views and write a js function myself to apply those changes.
I went and instead made it a bit different, I wrote some js that does actually the thing that you would do yourself(it simulates going to settings and changing them).
I made a jsfiddle with a link that can be dragged into the bookmarks bar:
https://jsfiddle.net/randomengineer/0nc4hajp/4/
The bookmarklet code:
javascript:
window.location.hash = 'settings/general';
a = () => document.querySelector('tbody tr:nth-child(13) input:not(:checked)');
b = setInterval(() => {
if(a() != null) {
clearInterval(b);
a().click();
document.querySelector('[guidedhelpid=save_changes_button]').click();
}
}, 5);
Saved settings are just to reload the JS code in the way you prefer, so you are correct it can be made easy to change. seahorsepip did a good one on it, if you need a custom grease script to install to your chrome i would be glad to help.
Love the solution by seahorsepip. I combined it with the "Shortcut Manager" Chrome extension (http://www.makeuseof.com/tag/shortcut-manager-assign-hotkeys-to-various-browser-actions-chrome/) and now I can toggle with a keyboard shortcut!
New solution for 2019 (see Bookmarklet in JavaScript to toggle Gmail conversation view).
This will toggle the current state On/Off and Save:
window.location.href = "https://mail.google.com"+window.location.pathname+"#settings/general";
setTimeout(function() {
convTogs = document.getElementsByName("bx_vmb");
if (convTogs[0].checked) convTogs[1].click();
else convTogs[0].click();
document.querySelector("[guidedhelpid=save_changes_button]").click();
}, 2000);
(Thanks, #Zenoo!)
Note: If you have multiple Gmail accounts open (like me) this will work in your current window (unlike https://mail.google.com/mail/u/0/#settings/general which will go to your default account)
I have written a script that allows a customer to log in, and download their contract in PDF.
We want the contract PDF to open in a popup, but are experiencing problems with customers who don't understand the basics of web browsers...
Basically, the customer logs in and a link is generated for their contract. The link is bound through jQuery's live event handler, that takes the request, sends it to an AJAX logging function then opens the PDF via window.open.
Since it is a user's action that opens the window, I can only think that because it goes through 2 other functions first, it is making the pop-up blocker kick in.
Does anybody have any better ideas?
My code is all over the place, in differnt namespaces, so I hope you guys can figure it all out:
Generate the link in a call back function, if the customer's credentials are correct:
$("#pdfLinks").prepend("<span><a href='#' id='pdfLink'><img src='img/btnDownloadPdf.png' alt='Downdload PDF' /><br>Download Adobe © PDF<\/a><\/span>");
$("#pdfLink").live('click', function() {
UI.showWorkingDialog();
net.tssol.contract.log(contractId['contract'], "DOWNLOAD_PDF", lead);
});
$("#pdfLinks").prepend("<h5>Adobe PDF<\/h5>");
the tssol.log function:
log: function(contract, method, lead) {
$.post("log.php", { lead: lead,
method: method},
function(log) {
if (log['success'] == true) {
if (method == "DOWNLOAD_PDF") {
// change to window.open for popup
window.open("http://oururl.net/public_html/viewPdf.php?verify=" + contract, '', 'scrollbars=1,menubar=0,height=600,width=800,resizable=1,toolbar=0,location=0,status=0');
Let me know if you guys see any way to make the user experience better.
Thanks
Maybe you can provide a HTML Version of the contract in a popup and add a "Download PDF" Button at the bottom of the popup content?
But in general you shouldnt use popups since they are often blocked by the web browsers and are in users head synced with trash and viagra-advertising.. you know what I mean ;)
I would do a jQuery Lightbox-like popup inside the website with the HTML-Contract, and optionally offer a PDF Download Button!
Have a look at this one: http://fancybox.net/