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

Pass URL to Browser::new(), delegate url checking logic to 3rd party #16477

Merged
merged 1 commit into from Jun 12, 2017

Conversation

@sadmansk
Copy link
Contributor

sadmansk commented Apr 15, 2017

  1. Move the logic of computing the initial url from opts.rs to /ports/servo/main.rs
  2. Add a ServoUrl argument to Browser::new

Based on the requested changes by @paulrouget:

We can read the pref in main() instead. shell.homepage would be used if the url is not passed as an argument. I'm trying to decouple the "app" logic and the "web engine" logic. I think it's up to the app to set the initial URL, and I'm not sure the initial url should be part of opts.


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #15636
  • There are tests for these changes

This change is Reviewable

@highfive
Copy link

highfive commented Apr 15, 2017

Thanks for the pull request, and welcome! The Servo team is excited to review your changes, and you should hear from @cbrewster (or someone else) soon.

@sadmansk sadmansk force-pushed the sadmansk:url_param_browser branch from 8cb16b0 to 9504711 Apr 15, 2017
let url_opt = if !opt_match.free.is_empty() {
Some(&opt_match.free[0][..])
} else {
homepage_pref.as_string()
None

This comment has been minimized.

Copy link
@sadmansk

sadmansk Apr 15, 2017

Author Contributor

Flag: what should the url_opt be set to if it can't be parsed from the cmdline?

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 17, 2017

Contributor

None.

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 17, 2017

Contributor

Also, Servo exits early if it can't find a URL. See https://github.com/sadmansk/servo/blob/95047114eeed77c4c9b310e6d4f04d3a3295a9e2/components/config/opts.rs#L678

This is not necessary anymore. Because the initial URL is now handled in main.rs, main.rs can do 2 things: either use about:blank or exit with the same error message (now sure which option is best).

This comment has been minimized.

Copy link
@sadmansk

sadmansk Apr 25, 2017

Author Contributor

How would you like me to handle the case if it is null? Should I print the usage or simply assign None?

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 25, 2017

Contributor

Assign None.

This comment has been minimized.

Copy link
@sadmansk

sadmansk Apr 25, 2017

Author Contributor

Forgive my newbiness, but I'm having some problem with assigning None on a matching statement. I couldn't search up exactly why it does not work. I was wondering if you could give me a pointer for the syntax.

error[E0308]: match arms have incompatible types
   --> /home/sadman/repos/servo/components/config/opts.rs:673:15
    |
673 |       let url = match url_opt {
    |  _______________^ starting here...
674 | |         Some(url_string) => {
675 | |             parse_url_or_filename(&cwd, url_string)
676 | |                 .unwrap_or_else(|()| args_fail("URL parsing failed"))
677 | |         },
678 | |         None => None,
679 | |     };
    | |_____^ ...ending here: expected struct `servo_url::ServoUrl`, found enum `std::option::Option`
    |
    = note: expected type `servo_url::ServoUrl`
               found type `std::option::Option<_>`
note: match arm with an incompatible type
   --> /home/sadman/repos/servo/components/config/opts.rs:678:17
    |
678 |         None => None,
    |                 ^^^^

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 25, 2017

Contributor

Forgive my newbiness

I've been through this too ^^

but I'm having some problem with assigning None on a matching statement. I couldn't search up exactly why it does not work. I was wondering if you could give me a pointer for the syntax.

Sure. The issue here is that the variable url is a ServoUrl. So the first branch of the match does return a ServoUrl. But the None branch returns a Option<ServoUrl> (which is None in this case).

Before your PR, we had a url_opt (optional url: Option<ServoUrl>) that was transformed to url (ServoUrl). Because we didn't want url to be optional. Now we want. So we want to keep url optional.

So in this function, we don't want to unwrap the url (which mean moving from Option<X> to X), we want to keep it optional.

So this block of code your working on, was doing 2 things: 1) calling parse_url_or_filename to make sure it's a valid url and that a file path is transformed into a url, and 2) unwrap the url to enforce it (not make it optional).

Now we only want 1) to happen.

Let me know if you need more info. You can also ping me on irc (paul).

This comment has been minimized.

Copy link
@sadmansk

sadmansk Apr 25, 2017

Author Contributor

First of all, thanks so much for giving me the time!
I do understand what we now want, I'm just having a bit of trouble understanding how to do it. Like, for instance, do I need to completely replace the match block and try unwrapping url_opt and save the value in url_string, and then only call parse_url_or_file on url_string if it isn't equal to either None or empty string?

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 25, 2017

Contributor

Sounds about right.

The match block should be replaced with something that would achieve this:

if url_opt is None, keep it None.
If url_opt is Some(foo), url_opt should become Some(parse_url_or_filename(foo).unwrap()), but if the result of parse_url_or_filename(foo) is Err(), we should call args_fail (which will exit).

Achieving this should be easy with some combinaison of unwrap and map calls (methods of Option and Result types).

parse_url_or_filename return a Result that is more or less like an Option.

Make sure to understand:

This should be one or two lines of code. I let you try to understand what this should look like. Manipulating options is a core concept of Rust. It's worth the time understanding it.

Do not hesitate to ask more questions.

This comment has been minimized.

Copy link
@KiChjang

KiChjang Apr 25, 2017

Member

The map function for Option should work very well here.

if let Some(url) = url {
constellation_chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();
};
constellation_chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();

This comment has been minimized.

Copy link
@sadmansk

sadmansk Apr 15, 2017

Author Contributor

Flag: should we do a check here to see if url is None?

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 17, 2017

Contributor

It can't be None at this point.

@sadmansk sadmansk changed the title WIP: Pass URL to Browser::new(), delegate url checking logic to 3rd party Pass URL to Browser::new(), delegate url checking logic to 3rd party Apr 16, 2017
@paulrouget
Copy link
Contributor

paulrouget commented Apr 16, 2017

Thank you for taking care of this. I'll look at this PR early next week.

if let Some(url) = url {
constellation_chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();
};
constellation_chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 17, 2017

Contributor

It can't be None at this point.

let url_opt = if !opt_match.free.is_empty() {
Some(&opt_match.free[0][..])
} else {
homepage_pref.as_string()
None

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 17, 2017

Contributor

None.

browser: Browser::new(window.clone()),
browser: Browser::new(window.clone(), opts::get().url.clone()
.unwrap_or(ServoUrl::parse(PREFS.get("shell.homepage").as_string().unwrap())
.unwrap()))

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 17, 2017

Contributor

opts::get().url default value should be None, not Some("about:blank") (see here).

If PREFS.get("shell.homepage") doesn't exist, we should use "about:blank" (or exist early).

So you always have a valid URL.

This comment has been minimized.

Copy link
@sadmansk

sadmansk Apr 23, 2017

Author Contributor

about:blank sounds like a good idea to me, I'll go with that.

let url_opt = if !opt_match.free.is_empty() {
Some(&opt_match.free[0][..])
} else {
homepage_pref.as_string()
None

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 17, 2017

Contributor

Also, Servo exits early if it can't find a URL. See https://github.com/sadmansk/servo/blob/95047114eeed77c4c9b310e6d4f04d3a3295a9e2/components/config/opts.rs#L678

This is not necessary anymore. Because the initial URL is now handled in main.rs, main.rs can do 2 things: either use about:blank or exit with the same error message (now sure which option is best).

@cbrewster
Copy link
Member

cbrewster commented Apr 17, 2017

@highfive highfive assigned paulrouget and unassigned cbrewster Apr 17, 2017
@cbrewster
Copy link
Member

cbrewster commented Apr 17, 2017

@bors-servo delegate=paulrouget

@bors-servo
Copy link
Contributor

bors-servo commented Apr 17, 2017

✌️ @paulrouget can now approve this pull request

@paulrouget
Copy link
Contributor

paulrouget commented Apr 17, 2017

@sadmansk let me know if you have any question about my comments.

@sadmansk
Copy link
Contributor Author

sadmansk commented Apr 17, 2017

@paulrouget just give me a few days, I have exams this week, I'll address your comments as soon as that's done 😅

@sadmansk sadmansk closed this Apr 23, 2017
@sadmansk sadmansk force-pushed the sadmansk:url_param_browser branch from 9504711 to a26079d Apr 23, 2017
@sadmansk sadmansk reopened this Apr 24, 2017
@sadmansk sadmansk force-pushed the sadmansk:url_param_browser branch from cb61240 to fdaa887 Apr 24, 2017
@sadmansk
Copy link
Contributor Author

sadmansk commented Apr 24, 2017

@paulrouget Made that change you requested. Please take another look and let me know if there was anything else you wanted me to change. Thanks.

browser: Browser::new(window.clone(),
opts::get().url.clone()
.unwrap_or(ServoUrl::parse(PREFS.get("shell.homepage").as_string()
.unwrap_or("about:blank")).unwrap()))

This comment has been minimized.

Copy link
@KiChjang

KiChjang Apr 24, 2017

Member

This line should get at least one more level of indentation to show that the method isn't operating at the same level as the previous line.

Copy link
Contributor

paulrouget left a comment

opts.rs' from_cmdline_args method needs some more work. url_opt can be None, and this is valid now as we fallback to the preference or about:blank in main.rs. See

args_fail("servo asks that you provide a URL")
<- remove this

Also, the default url should be None I think:

url: Some(ServoUrl::parse("about:blank").unwrap()),

browser: Browser::new(window.clone(),
opts::get().url.clone()
.unwrap_or(ServoUrl::parse(PREFS.get("shell.homepage").as_string()
.unwrap_or("about:blank")).unwrap()))

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 24, 2017

Contributor

Can you split that in a way that it's easier to understand?
Maybe move the url resolution above, and add a comment to explain the logic.

@sadmansk sadmansk force-pushed the sadmansk:url_param_browser branch from 6c66110 to c867f1e May 7, 2017
@sadmansk
Copy link
Contributor Author

sadmansk commented May 7, 2017

@paulrouget I made the requested changes as I understood. Please let me know if I misunderstood anything. Also, if the parsing of the URL fails, i.e. parse_url_or_filename() returns an error, then I'm assigning None to url without any feedback. Should I print a message indicating that the parsing of the url failed?

@bors-servo
Copy link
Contributor

bors-servo commented May 7, 2017

The latest upstream changes (presumably #16757) made this pull request unmergeable. Please resolve the merge conflicts.

@sadmansk sadmansk force-pushed the sadmansk:url_param_browser branch from b5ccecb to 656bf8f May 8, 2017
Copy link
Contributor

paulrouget left a comment

Address my comments, squash and rebase, and I think that should do it.

Thank you!

match parse_url_or_filename(&cwd, url_string) {
Ok(v) => Some(v),
Err(_) => None,
}

This comment has been minimized.

Copy link
@paulrouget

paulrouget May 8, 2017

Contributor

You can transform an Result into an Option with parse_url_or_filename().ok().
See https://doc.rust-lang.org/std/result/enum.Result.html#method.ok

@@ -795,7 +793,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {

let opts = Opts {
is_running_problem_test: is_running_problem_test,
url: Some(url),
url: url,

This comment has been minimized.

Copy link
@paulrouget

paulrouget May 8, 2017

Contributor

Keep url_opt:

url: url_opt
print_usage(app_name, &opts);
args_fail("servo asks that you provide a URL")
}
None => None,
};

This comment has been minimized.

Copy link
@paulrouget

paulrouget May 8, 2017

Contributor

I think you can combine all of this with and_then, something like this:

let url_opt = url_opt.and_then(|url_string| parse_url_or_filename(…).ok());

Also, rename url to url_opt (still an option at this point)

@paulrouget
Copy link
Contributor

paulrouget commented May 8, 2017

Also, if the parsing of the URL fails, i.e. parse_url_or_filename() returns an error, then I'm assigning None to url without any feedback. Should I print a message indicating that the parsing of the url failed?

Yes, maybe a warning.

@paulrouget
Copy link
Contributor

paulrouget commented May 10, 2017

Ok. It looks good now.

You also need to update ports/cef. You can build it with ./mach build-cef.

@sadmansk
Copy link
Contributor Author

sadmansk commented May 11, 2017

updated ports/cef. I had to set the home URL before making the call to the browser new. Is this okay?

let servo_browser = Browser::new(glutin_window.clone());
let home_url = ServoUrl::parse(PREFS.get("shell.homepage").as_string()
.unwrap_or("about:blank")).unwrap();
let servo_browser = Browser::new(glutin_window.clone(), home_url);

This comment has been minimized.

Copy link
@paulrouget

paulrouget May 11, 2017

Contributor

If I'm not mistaken, ServoCefBrowser::new is called by browser_host_create, which comes with a url. So you should use it instead of use about:blank.

This comment has been minimized.

Copy link
@sadmansk

sadmansk May 20, 2017

Author Contributor

Sorry a bit confused, should I change the function signature of ServoCefBrowser::new so that it gets the url from browser_host_create and use that instead?

This comment has been minimized.

Copy link
@sadmansk

sadmansk Jun 2, 2017

Author Contributor

@paulrouget Hey, still waiting on this clarification. Please let me know at your earliest convenience

This comment has been minimized.

Copy link
@paulrouget

paulrouget Jun 5, 2017

Contributor

should I change the function signature of ServoCefBrowser::new so that it gets the url from browser_host_create and use that instead?

Yes.

And then I don't think it's necessary to call frame.set_url:

unsafe { browser.downcast().frame.set_url(CefWrap::to_rust(url)); }

@@ -9,6 +9,8 @@ use interfaces::{CefBrowser, CefBrowserHost, CefClient, CefFrame, CefRequestCont
use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t};
use interfaces::{cef_request_context_t};
use servo::Browser;
use servo::servo_config::prefs::PREFS;

This comment has been minimized.

Copy link
@paulrouget

paulrouget May 11, 2017

Contributor

I don't know much about CEF, but I think you should not use PREFS here. Just use about:blank directly.

@@ -171,7 +175,9 @@ impl ServoCefBrowserExtensions for CefBrowser {
if window_info.windowless_rendering_enabled != 0 {
let window = window::Window::new(window_info.width, window_info.height);
window.set_browser(self.clone());
let servo_browser = Browser::new(window.clone());
let home_url = ServoUrl::parse(PREFS.get("shell.homepage").as_string()
.unwrap_or("about:blank")).unwrap();

This comment has been minimized.

Copy link
@paulrouget

paulrouget May 11, 2017

Contributor

assign about:blank directly.

@paulrouget
Copy link
Contributor

paulrouget commented May 18, 2017

@sadmansk anything I can do to help?

@sadmansk
Copy link
Contributor Author

sadmansk commented May 18, 2017

@paulrouget Sorry about that, it's been a really busy week at work, so didn't get a chance to work on it. I will get to it as soon as I catch a breath

@paulrouget
Copy link
Contributor

paulrouget commented May 19, 2017

No worries. Just wanted to make sure you were not stuck.

@paulrouget
Copy link
Contributor

paulrouget commented Jun 7, 2017

@sadmansk if you want, we can land this as it is, and add the url to ServoCefBrowser::new in another PR.

@bors-servo
Copy link
Contributor

bors-servo commented Jun 7, 2017

The latest upstream changes (presumably #17068) made this pull request unmergeable. Please resolve the merge conflicts.

@sadmansk
Copy link
Contributor Author

sadmansk commented Jun 8, 2017

@paulrouget yeah ofcourse, that sounds like a good plan, i'll rebase tonight and ping you for the merge, and also start working on the cef browser stuff.

@sadmansk sadmansk force-pushed the sadmansk:url_param_browser branch from 3831b6a to 13b1815 Jun 9, 2017
Use Option instead of ServoUrl for url in opts

Cleaner mapping from parse_url to url_opt

Add comment about url parsing error

Print reason for parsing error

Remove comment about warning

Add home url when openning new browser window in CEF

Fix merge error
@sadmansk sadmansk force-pushed the sadmansk:url_param_browser branch from be1d68f to 708c561 Jun 9, 2017
@sadmansk
Copy link
Contributor Author

sadmansk commented Jun 9, 2017

@paulrouget merge is ready now, i'll work on the cef browser things on a different PR

@paulrouget
Copy link
Contributor

paulrouget commented Jun 12, 2017

@bors-servo
Copy link
Contributor

bors-servo commented Jun 12, 2017

📌 Commit 708c561 has been approved by paulrouget

@bors-servo
Copy link
Contributor

bors-servo commented Jun 12, 2017

Testing commit 708c561 with merge 8714064...

bors-servo added a commit that referenced this pull request Jun 12, 2017
Pass URL to Browser::new(), delegate url checking logic to 3rd party

<!-- Please describe your changes on the following line: -->
1. Move the logic of computing the initial url from `opts.rs` to `/ports/servo/main.rs`
2. Add a `ServoUrl` argument to `Browser::new`

Based on the requested changes by @paulrouget:
>We can read the pref in main() instead. shell.homepage would be used if the url is not passed as an argument. I'm trying to decouple the "app" logic and the "web engine" logic. I think it's up to the app to set the initial URL, and I'm not sure the initial url should be part of opts.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #15636

<!-- Either: -->
- [ ] There are tests for these changes

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16477)
<!-- Reviewable:end -->
@paulrouget
Copy link
Contributor

paulrouget commented Jun 12, 2017

CEF Follow up: #17273

@bors-servo
Copy link
Contributor

bors-servo commented Jun 12, 2017

@bors-servo bors-servo merged commit 708c561 into servo:master Jun 12, 2017
3 checks passed
3 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

6 participants
You can’t perform that action at this time.