Skip to content

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

Merged
bors-servo merged 1 commit intoservo:masterfrom
sadmansk:url_param_browser
Jun 12, 2017
Merged

Pass URL to Browser::new(), delegate url checking logic to 3rd party#16477
bors-servo merged 1 commit intoservo:masterfrom
sadmansk:url_param_browser

Conversation

@sadmansk
Copy link
Copy Markdown
Contributor

@sadmansk 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.


  • There are tests for these changes

This change is Reviewable

@highfive
Copy link
Copy Markdown

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.

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Apr 15, 2017
@sadmansk sadmansk force-pushed the url_param_browser branch from 8cb16b0 to 9504711 Compare April 15, 2017 20:14
Some(&opt_match.free[0][..])
} else {
homepage_pref.as_string()
None
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

None.

Copy link
Copy Markdown
Contributor

@paulrouget paulrouget Apr 17, 2017

Choose a reason for hiding this comment

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

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).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Assign None.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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,
    |                 ^^^^

Copy link
Copy Markdown
Contributor

@paulrouget paulrouget Apr 25, 2017

Choose a reason for hiding this comment

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

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).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
Copy Markdown
Contributor

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();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It can't be None at this point.

Some(&opt_match.free[0][..])
} else {
homepage_pref.as_string()
None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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()))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Some(&opt_match.free[0][..])
} else {
homepage_pref.as_string()
None
Copy link
Copy Markdown
Contributor

@paulrouget paulrouget Apr 17, 2017

Choose a reason for hiding this comment

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

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
Copy Markdown
Contributor

r? @paulrouget

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

@bors-servo delegate=paulrouget

@bors-servo
Copy link
Copy Markdown
Contributor

✌️ @paulrouget can now approve this pull request

@paulrouget
Copy link
Copy Markdown
Contributor

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

@sadmansk
Copy link
Copy Markdown
Contributor Author

@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 url_param_browser branch from 9504711 to a26079d Compare April 23, 2017 23:23
@sadmansk sadmansk reopened this Apr 24, 2017
@sadmansk sadmansk force-pushed the url_param_browser branch from cb61240 to fdaa887 Compare April 24, 2017 00:27
@sadmansk
Copy link
Copy Markdown
Contributor Author

@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()))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
Copy Markdown
Contributor

@paulrouget paulrouget left a comment

Choose a reason for hiding this comment

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

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()))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 url_param_browser branch from 6c66110 to c867f1e Compare May 7, 2017 07:37
@sadmansk
Copy link
Copy Markdown
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
Copy Markdown
Contributor

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

@highfive highfive added the S-needs-rebase There are merge conflict errors. label May 7, 2017
@sadmansk sadmansk force-pushed the url_param_browser branch from b5ccecb to 656bf8f Compare May 8, 2017 03:02
Copy link
Copy Markdown
Contributor

@paulrouget paulrouget left a comment

Choose a reason for hiding this comment

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

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,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

let opts = Opts {
is_running_problem_test: is_running_problem_test,
url: Some(url),
url: url,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Keep url_opt:

url: url_opt

args_fail("servo asks that you provide a URL")
}
None => None,
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
Copy Markdown
Contributor

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
Copy Markdown
Contributor

Ok. It looks good now.

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

@sadmansk
Copy link
Copy Markdown
Contributor Author

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);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

@sadmansk sadmansk May 20, 2017

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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)); }

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;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

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();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

assign about:blank directly.

@paulrouget
Copy link
Copy Markdown
Contributor

@sadmansk anything I can do to help?

@sadmansk
Copy link
Copy Markdown
Contributor Author

@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
Copy Markdown
Contributor

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

@paulrouget
Copy link
Copy Markdown
Contributor

@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
Copy Markdown
Contributor

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

@sadmansk
Copy link
Copy Markdown
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 url_param_browser branch from 3831b6a to 13b1815 Compare June 9, 2017 01:38
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 url_param_browser branch from be1d68f to 708c561 Compare June 9, 2017 02:06
@sadmansk
Copy link
Copy Markdown
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
Copy Markdown
Contributor

@bors-servo r+

@bors-servo
Copy link
Copy Markdown
Contributor

📌 Commit 708c561 has been approved by paulrouget

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. S-needs-rebase There are merge conflict errors. labels Jun 12, 2017
@bors-servo
Copy link
Copy Markdown
Contributor

⌛ Testing commit 708c561 with merge 8714064...

bors-servo pushed 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
Copy Markdown
Contributor

CEF Follow up: #17273

@bors-servo
Copy link
Copy Markdown
Contributor

☀️ Test successful - android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css1, mac-rel-css2, mac-rel-wpt1, mac-rel-wpt2, mac-rel-wpt3, mac-rel-wpt4, windows-msvc-dev
Approved by: paulrouget
Pushing 8714064 to master...

@bors-servo bors-servo merged commit 708c561 into servo:master Jun 12, 2017
@highfive highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Jun 12, 2017
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.

Pass the initial URL as an argument to Browser::new, not as a opts property

6 participants