Skip to content
This repository was archived by the owner on Jan 22, 2019. It is now read-only.

feat: accept settings updates from Sourcegraph pages#146

Merged
chrismwendt merged 1 commit intomasterfrom
settings-from-sourcegraph
Sep 12, 2018
Merged

feat: accept settings updates from Sourcegraph pages#146
chrismwendt merged 1 commit intomasterfrom
settings-from-sourcegraph

Conversation

@chrismwendt
Copy link

@chrismwendt chrismwendt commented Sep 7, 2018

2018-09-07 16 00 38

This connects the browser extension to Sourcegraph pages so that Sourcegraph can instruct the browser extension to edit client settings on its behalf.

This will allow us to eliminate the extensions list from the browser extension (see #132) and from e-c-c (see TODO).

I didn't piggyback on the existing document.dispatchEvent code because we might want to embed Sourcegraph in an iframe, in which case I think the origin will be different.

@chrismwendt chrismwendt requested a review from ijsnow as a code owner September 7, 2018 23:28
@chrismwendt chrismwendt force-pushed the settings-from-sourcegraph branch 2 times, most recently from be4f84e to b001513 Compare September 8, 2018 06:42
* Where a message originated from, used to disambiguate between the content
* script's own messages and messages from the page.
*/
type Source = 'Page' | 'Client'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these need to be synced with what is in your ecc PR? Can't they share?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they can share. I haven't updated this PR, but I will once the e-c-c PR gets merged in.

* pings back. This always resolves to true.
*/
function connectToPage(): Promise<boolean> {
return new Promise(resolve => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minimize the logic in a Promise constructor:

new Promise(resolve => window.addEventListenter('message', resolve)
	.then(...)

}

let isConnected = false
window.addEventListener('message', event => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't cleanup the listener after the Promise is resolved, so nothing here can be garbage collected. I would recommend just using fromEvent+filter+toPromise.

@chrismwendt chrismwendt force-pushed the settings-from-sourcegraph branch 3 times, most recently from eb8fd9e to 27ae8c0 Compare September 12, 2018 09:11
}

// Generate and insert DOM element, in case this code executes first.
document.body.appendChild(marker)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This marker used to only be added at DOM load, which created a window of time during which this inject function was being called twice.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it doesn't wait for DOM load, how do you ensure that document.body has already loaded? Afaik it's not safe to do DOM manipulation until the DOM is loaded

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I don't understand your above comment. Was the issue that this event handler would get dispatched before the one that adds the marker, and now both add the marker?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, what I said was ambiguous. If you look at the red part of the diff where this statement used to be, you'll see that it's inside a callback to the load event, which executes asynchronously with respect to this function call.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. Not exactly sure why it uses the load event but might have a reason.

@chrismwendt chrismwendt force-pushed the settings-from-sourcegraph branch from 27ae8c0 to bf8b125 Compare September 12, 2018 09:24
@chrismwendt chrismwendt merged commit 0c49ab1 into master Sep 12, 2018
@chrismwendt chrismwendt deleted the settings-from-sourcegraph branch September 12, 2018 09:39
}
return new Promise<undefined>(resolve =>
storage.setSync({ clientSettings }, () => {
resolve(undefined)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you pass resolve directly? Since the callback has no parameters, it should fit the type void

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally avoid that because it makes me less confident that the return value of the Promise will be what I intend for it to be.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, if that's a concern I would eliminate it with in a different way with .then(() => undefined). That keeps logic in Promise constructors minimal (no point for the next dev to think "I need to add this logic, I can just add it here before the resolve call")

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like this? new Promise(resolve => setSync(..., resolve)).then(() => undefined)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. (Except if it's inside another .then() handler, in which case the .then() should be on the outer Promise to not nest them, but same thing)


if (document.readyState === 'complete' || document.readyState === 'interactive') {
dispatchSourcegraphEvents(marker)
dispatchSourcegraphEvents()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this fire the event twice portentially?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it to me, yeah

@sourcegraph-bot
Copy link

🎉 This PR is included in version 1.14.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants