0

I have a chrome extension and I want to be able to edit the description or location field of a google calendar event when a user clicks a button.

I have the button set up and can access the nodes of the popup window for a calendar extension.

The add description or attachments field is not a text box until clicked. If you click this span in the UI

<span class="DD3VVc" data-key="description" jsaction="clickonly:OVoCkb; mousedown:nzqhhd">description</span>

it will become a text box.

However, if I dispatch a click event via the button like

button.addEventListener("click", function() {
            var descriptions = document.querySelectorAll("[data-key^='description']");
            var description = descriptions[0];
            console.log(description) //prove that I have the right thing.
            description.dispatchEvent(new MouseEvent('mousedown'));
            description.dispatchEvent(new MouseEvent('clickonly'));
}

It does not seem to accept the click as valid and create the text box. I also tried adding a description.focus(); befor the clicks with no difference. It does log the span to the console and it is the one I want. It also will trigger the mousedown event if you use the event breakpoints in the dev console.

Is there a way to trigger this programmatically with JS so it creates the text box?

To see the menus below:

  1. Go to calendar.google.com
  2. Click any timeslot once so the modal pops up
  3. See a menu like the images below

gcalendar

desired state (minus the text, hopefully I can just innerHTML that or something

enter image description here

humanbeing
  • 1,617
  • 3
  • 17
  • 30

1 Answers1

3

Inspect the element in devtools' Event Listeners panel: uncheck [ ] Ancestors there and you'll see this element has no event listeners at all! Now, check [x] Ancestors and you'll see a lot of listeners. The meaning is that it uses delegated events so we need to dispatch a bubbling event for some interested ancestor to see it.

document.querySelector("[data-key^='description']")
  .dispatchEvent(new MouseEvent('click', {bubbles: true}));

Then add the notes:

setTimeout(() => {
  const el = document.querySelector('[contenteditable="true"]');
  el.focus();
  for (const type of ['keydown', 'keypress', 'keyup'])
    el.dispatchEvent(new KeyboardEvent(type));
  document.execCommand('insertHTML', false, 'Your <b>HTML</b> here');
});

There are other methods to insert HTML instead of execCommand, which was marked as obsolete in 2020 but it'll work until a new editing API specification is agreed upon and that usually takes [many] years.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • This solves my issue 100%. Thank you for also explaining how bubbling works so I understand the why and not just the how. Cheers! – humanbeing Sep 28 '20 at 15:30