Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to set per-session preload scripts #10430

Merged
merged 12 commits into from
Dec 5, 2017
Merged

Add ability to set per-session preload scripts #10430

merged 12 commits into from
Dec 5, 2017

Conversation

MarshallOfSound
Copy link
Member

@MarshallOfSound MarshallOfSound commented Sep 2, 2017

This adds three new instance methods to session objects that allow you to set preload scripts, these scripts will be executed before normal preload scripts and you can have as many as you want.

API:

#### `ses.addPreload(preloadPath)`

* `preloadPath` String - An absolute path to the preload script

Adds a script that will be executed on ALL web contents that are associated with
this session just before normal `preload` scripts run.

#### `ses.removePreload(preloadPath)`

* `preloadPath` String - An absolute path to the preload script

Removes the given script from the list of preload scripts

#### `ses.getPreloads()`

Returns `String[]` an array of paths to preload scripts that have been registered

@MarshallOfSound MarshallOfSound requested a review from a team September 2, 2017 16:23
@@ -54,6 +54,10 @@ class Window : public mate::TrackableObject<Window>,

int32_t ID() const;

static void AddGlobalPreload(const base::FilePath::StringType preloadPath);
static void RemoveGlobalPreload(const base::FilePath::StringType preloadPath);
Copy link
Contributor

@poiru poiru Sep 4, 2017

Choose a reason for hiding this comment

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

Could this be const base::FilePath::StringType& (and std::vector<base::FilePath::StringType>& below) to avoid a copies?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done 👍

Copy link
Contributor

@poiru poiru left a comment

Choose a reason for hiding this comment

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

I'm curious what's the use case for this? Also, should we generalize this so that it can be used for other web contents as well (e.g. BrowserView)?

@MarshallOfSound
Copy link
Member Author

@poiru Two main use cases for me

  1. It allows electron modules to do stuff in renderer processes when initialized from the main process, modules such as electron-compile currently have to do fancy hax to inject initialization code into renderer processes.
  2. It lets people have multiple preload scripts
  3. It allows for generic "all window" setup logic (for instance custom window controls)

@MarshallOfSound
Copy link
Member Author

Also, should we generalize this so that it can be used for other web contents as well (e.g. BrowserView)?

I'm pretty sure this already works for BrowserView's as they still run the init.js script. The API is on BrowserWindow as it is the hierarchical parent of all webContents, even browser views are attached to browser windows.

@poiru
Copy link
Contributor

poiru commented Sep 5, 2017

I'm pretty sure this already works for BrowserView's as they still run the init.js script. The API is on BrowserWindow as it is the hierarchical parent of all webContents, even browser views are attached to browser windows.

Ah, I see! Since BrowserViews don't necessarily have to be attached to a window, perhaps a static methods on webContents might be better?

@MarshallOfSound
Copy link
Member Author

perhaps a static methods on webContents might be better?

I initially thought about putting them there but then decided against it because existing preloads go onto the BrowserWindow constructor. Happy to move it somewhere else if it makes more sense

@deepak1556
Copy link
Member

Happy to move it somewhere else if it makes more sense

I would suggest adding it to the session module #2605

@MarshallOfSound
Copy link
Member Author

@deepak1556 At the moment this isn't session scoped though, it's for all sessions. That issue refers to preloads for iframes as well, not sure this PR quite hits that issue perfectly.

@deepak1556
Copy link
Member

Having it scoped to session gives better control, doesn't have to worry about implementation for webContents, BrowserView, webView, BrowserWindow.

it's for all sessions

If the scripts are added to the global session, then it would address the use case you mentioned too.

Any reason why this shouldn't be session specific ?

@zcbenz
Copy link
Member

zcbenz commented Sep 11, 2017

I think it is better to be a session-wide API instead of a global API.

For single-session apps setting the preload script for the global session is as easy as setting the global preload script.

For multi-session apps, like browsers that use different sessions for UI and remote pages, they almost never use the same preload script for different sessions. So an API setting global preload script would be useless for those apps, while an API settings session-wide preload script can meet most needs.

@MarshallOfSound MarshallOfSound changed the title Add ability to set Global Preload scripts for all BrowserWindows Add ability to set per-session preload scripts Sep 16, 2017
@MarshallOfSound
Copy link
Member Author

@zcbenz @deepak1556 Moved the logic to be session based 👍

@@ -81,6 +82,9 @@ class Session: public mate::TrackableObject<Session>,
void GetBlobData(const std::string& uuid,
const AtomBlobReader::CompletionCallback& callback);
void CreateInterruptedDownload(const mate::Dictionary& options);
void AddPreload(const base::FilePath::StringType& preloadPath);
void RemovePreload(const base::FilePath::StringType& preloadPath);
std::vector<base::FilePath::StringType> GetPreloads();
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you use const std::vector<base::FilePath::StringType>& to avoid copying.

@@ -103,6 +107,7 @@ class Session: public mate::TrackableObject<Session>,
std::string devtools_network_emulation_client_id_;

scoped_refptr<AtomBrowserContext> browser_context_;
std::vector<base::FilePath::StringType> g_preloads;
Copy link
Contributor

@poiru poiru Sep 18, 2017

Choose a reason for hiding this comment

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

preload_paths_ is probably a better name.

@@ -81,6 +82,9 @@ class Session: public mate::TrackableObject<Session>,
void GetBlobData(const std::string& uuid,
const AtomBlobReader::CompletionCallback& callback);
void CreateInterruptedDownload(const mate::Dictionary& options);
void AddPreload(const base::FilePath::StringType& preloadPath);
Copy link
Contributor

Choose a reason for hiding this comment

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

s/preloadPath/preload_path

atom::api::WebContents::CreateFrom(isolate, web_contents);
auto session = atom::api::Session::CreateFrom(
isolate, api_web_contents.get()->GetBrowserContext());
for (auto preloadPath : session->GetPreloads()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

const auto& to avoid copy. Also preload_path.

auto session = atom::api::Session::CreateFrom(
isolate, api_web_contents.get()->GetBrowserContext());
for (auto preloadPath : session->GetPreloads()) {
if (base::FilePath(preloadPath).IsAbsolute())
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be better to do this check in AddPreload()?

Copy link
Member Author

Choose a reason for hiding this comment

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

For consistency with existing preload logic I think it's better to leave this here

@zcbenz
Copy link
Member

zcbenz commented Dec 5, 2017

I'm rebasing this branch on master.

@MarshallOfSound MarshallOfSound requested a review from a team December 5, 2017 02:36
By design the BrowserClient should not be aware of the api:: classes.
@zcbenz zcbenz closed this Dec 5, 2017
@zcbenz zcbenz reopened this Dec 5, 2017
Copy link
Member

@deepak1556 deepak1556 left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@@ -367,8 +368,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
const std::vector<base::string16>& labels);

private:
AtomBrowserContext* GetBrowserContext() const;
Copy link
Member

Choose a reason for hiding this comment

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

Do we want this method to be public ? Its not used in this PR.

} // namespace

// static
int SessionPreferences::kLocatorKey = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Would it be better to have the key as SessionPreferencesUserData just so it doesn't collide with anything from content layer in the future ?

Copy link
Member

Choose a reason for hiding this comment

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

The static member data has the class name in its symbol name, so we won't get symbol conflicts. The kLocatorKey is a pattern also used in other Chromium classes.

Copy link
Member

Choose a reason for hiding this comment

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

👍

@zcbenz zcbenz merged commit 95cb601 into master Dec 5, 2017
@zcbenz zcbenz deleted the global-preloads branch December 5, 2017 10:15
@carsonwright
Copy link

What would the js api look like for this?

@iffy
Copy link

iffy commented Dec 12, 2017

How will I know when this feature is released? (I've scoured the website looking for an RSS feed or a mailing list. Closest thing I can find is Twitter)

@lee-dohm
Copy link
Contributor

@iffy You can subscribe to an Atom feed of the releases or tags for any repository. Whether or not a particular PR is "released" is rather more complicated but hopefully that should get you started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants