-4

I'm editing a message in GMail. I'd like to press one of the styling buttons, like "indent", "outdent", "right-to-left", etc.

I want to do this not by pressing, but by typing a piece of javascript in the address bar and pressing enter.

(I'm interested in doing this so I could write a script that presses buttons using the keyboard rather than the mouse.)

Is this possible?

Bounty:

The bounty will go to whoever supplies a full, working solution that I can put in Chrome's address bar to cause the buttons (like "Indent", "Link", "Outdent", "Right-to-left", etc.) to be pressed. (Different line for each button, of course.)

Ram Rachum
  • 71,442
  • 73
  • 210
  • 338
  • 1
    This doesn't make sense. Adding javascript to the address in the addressbar??? – PeeHaa Jul 02 '12 at 10:11
  • 3
    actually yes: `javascript:/*html-encdoed js code here*/;` you can drop that in the address bar and it executes. – nbrooks Jul 02 '12 at 10:11
  • 1
    See this question: http://stackoverflow.com/questions/961532/firing-a-keyboard-event-in-javascript and/or this answer http://stackoverflow.com/a/7524096/803925 -- might be useful – nbrooks Jul 02 '12 at 10:18
  • @nbrooks You can, but only when that's the only thing in the addressbar and not when there is already an URL in it. – PeeHaa Jul 02 '12 at 11:18
  • 2
    @PeeHaa no...you can get rid of what ever's in the url bar, paste in your js and execute. it runs on the current page. – nbrooks Jul 02 '12 at 11:22

4 Answers4

4

To select the element you first need to select the iframe

var inlineFrame = document.getElementById("canvas_frame");

Next from the iframe you can get the contentwindow (the window scope of the iframe) like this:

var contentwindow = inlineFrame.contentWindow;

Next using queryselector (real browsers only (IE8- not supported)) you can select the button like this. ([command='+bold'] simply means: any element with an attribute command whose value is '+bold', just like in CSS).

var button = contentwindow.document.querySelector("[command='+bold']");

If you inspect the relevant buttons they all contain the command attribute which you can use to select them. And next you can do with the button whatever you want (look for other answers on stackoverflow for different ways to simulate events, as you should be able to do that yourself).

And if you want to have it as a bookmarklet you can of course make a single line out of it as well, but I thought it would be clearer like this as an answer.

David Mulder
  • 24,033
  • 8
  • 45
  • 104
  • Sounds good. Can you spare me the suspense and tell me what's the name of the function that clicks the button? I tried a few earlier but they didn't work. – Ram Rachum Jul 06 '12 at 08:44
  • 1
    It's not a one function fit's all case, because google could have bound the `click`, `mousedown`, `mouseup` or even a range of more exotic options (try creating an event (http://stackoverflow.com/questions/2490825/how-to-trigger-event-in-javascript) and fire it at the deepest child of the element above something along the lines of `"[command='+bold'] > div > div > div"` or loop and fire it at all `"[command='+bold'],[command='+bold'] *"`). I only quickly tried the click one which didn't seem to be it, but stopped at that point, as it was only manual labour rather than knowledge. – David Mulder Jul 06 '12 at 11:03
  • chrome's web inspector says its on the 'onmousedown' event handler – badunk Jul 11 '12 at 08:45
  • I've tried `mousedown` on all the children with no success. I hope someone can find a solution. – Ram Rachum Jul 11 '12 at 09:14
1

Try Ctrl+B, Ctrl+I, Ctrl+U Is that what you mean?

Michal B.
  • 5,497
  • 6
  • 39
  • 65
1

First, you need to figure out the ID / tag index / css class of the DOM element you want to be "clicked", then use a selector to access it and finally call its click event.

To dynamically select a DOM element, you can use document.getElementById(<id>) if you know its ID, then document.getElementsByTagName(<tagName>)[<index>] if you know its tag name and index.

If you only know that the element uses a specific css class, you can still loop on every tags until element.className==<className> or dynamically import jquery then call $('.<className>').trigger('click');

Hope this helps

Frederik.L
  • 5,139
  • 2
  • 22
  • 39
  • David Mulder's solution already figured out how to select the button. What's left is triggering the event on it. I've tried to do it but failed, and I'm pretty frustrated with trying. – Ram Rachum Jul 10 '12 at 11:53
  • 1
    I see, they obfuscated everything and especially event handlers... interesting, I will try to figure this out, maybe it's harder than we thought, doesn't seem to work on nested divs neither – Frederik.L Jul 10 '12 at 12:24
0

Disclaimer: More or a generic answer, not directly related to Gmail.

To click any element on a page, you can use the element.click() method. Please note that all elements do not have the click method. <input> elements support though.

I'm not sure if you can access the document object from the URL bar. So if I were using Firefox, I would open Firebg or better, the Scratch Pad (Tools > Web Developer > Scratch Pad) and write something like this:-

javascript:function foo(){document.getElementById('link1').click();}foo();

Upon executing the above code, it will invoke the click method on the element with the ID 'link1'.

Sparky
  • 4,159
  • 7
  • 33
  • 51
  • The button's id is `:lc`, but doing `document.getElementById(':lc')` in Chrome's shell gives `null`. Also, the id of the button changes on every load. If I had jQuery, I could select the button by other attributes, but I don't... – Ram Rachum Jul 02 '12 at 10:43
  • Everything you can do in jQuery you can do in plain javascript. It's just usually more work, but if you are determined enough, that should not be the problem. – Michal B. Jul 02 '12 at 10:47
  • This answer says you can not start an ID with a colon! (http://stackoverflow.com/questions/70579/what-are-valid-values-for-the-id-attribute-in-html) Sure it is the ID?? – Sparky Jul 02 '12 at 10:51
  • Technically..."ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".")." – nbrooks Jul 02 '12 at 10:51
  • Yes, I'm sure: `
    `
    – Ram Rachum Jul 02 '12 at 10:54
  • It shouldn't. Your element selector won't work with an invalid id. Anyway, if the id is changing use a different selector. `.getElementsByClassName()`, `.getElementsByName()`, etc. – nbrooks Jul 02 '12 at 10:56
  • 1
    Despite the fact that it shouldn't have a colon, it does have a colon. – Ram Rachum Jul 02 '12 at 11:01
  • None of the `.getElementsBy*` methods work either. Give it a try. – Ram Rachum Jul 02 '12 at 11:01
  • May be the page is using frames. – Sparky Jul 02 '12 at 11:05
  • @RamRachum they return arrays of elements, not just a single element like `getElementById`, so you have to do array indexing to get the element after calling the method. Could that be the prob? – nbrooks Jul 02 '12 at 11:25
  • Those arrays were empty. I now find out how to select them, but can't trigger a click that'll make GMail indent the text. – Ram Rachum Jul 02 '12 at 11:32