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

Conversation

@TheOneWithTheBraid
Copy link
Contributor

@TheOneWithTheBraid TheOneWithTheBraid commented Aug 9, 2021

When using the Link widget, it's theoretically possible to open the link in a new tab, e.g. by dragging the widget in the tab bar of modern browsers. In This case, up to now, an invalid route was formed, as the leading # from Flutters named routes is not included in the Anchor node's href.

List which issues are fixed by this PR. You must list at least one issue.

I'm not exactly sure whether it's possible to cover a behavior like drag outside of Flutter to a new tab in tests. As I don't think so, I left out such a test.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Note that unlike the flutter/flutter repo, the flutter/plugins repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@google-cla
Copy link

google-cla bot commented Aug 9, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@TheOneWithTheBraid
Copy link
Contributor Author

@googlebot I signed it!

@google-cla google-cla bot added cla: yes and removed cla: no labels Aug 9, 2021
@stuartmorgan-g
Copy link
Contributor

Thanks for the submission.

I'm not exactly sure whether it's possible to cover a behavior like drag outside of Flutter to a new tab in tests. As I don't think so, I left out such a test.

Just because an end-to-end test may not be feasible does not mean a change can't have tests. You are transforming a property in a setter, which should be easily unit testable.

  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt.

In the future, please don't check things in the checklist that you have not actually done. Asserting yourself that you don't think it needs a test isn't one of the options described here.

@TheOneWithTheBraid
Copy link
Contributor Author

You are fully right, @stuartmorgan. I definitely should not tick a checkbox then there is an unanswered question on it, and you are right with the getter too. Thank you for the reminder. I just added a corresponding test, and it's passing (at least on my local machine).

Comment on lines 223 to 230
// in case an internal uri is given, a leading `#` must be added to avoid
// invalid links when opening in a new tab
if (!uri.hasScheme) {
href = '#' + href;
}
Copy link
Member

Choose a reason for hiding this comment

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

I am not entirely sure this is going to be true forever, for example, there's a new Uri Strategy that doesn't use the # and instead uses the browser history API.

/cc @mdebbar can you take a look at this fix and see if it can be applied as is?

Copy link
Contributor

Choose a reason for hiding this comment

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

You are right @ditman. This works only with the HashUrlStrategy. If someone uses the PathUrlStrategy or any other custom url strategy, it won't work.

We need to figure out a way to grab the current url strategy used by the app, and call prepareExternalUrl to obtain the correct path that should go in the link href.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

May you tell me whether my idea is right:

Would it be possible to somehow publicly make available _customUrlStrategy in engine:lib/web_ui/lib/src/engine/window.dart:38?

That way, the platform interface could check the present url strategy, right?

Would you mind if I create a corresponding getter in the file?

Copy link
Contributor Author

@TheOneWithTheBraid TheOneWithTheBraid Aug 27, 2021

Choose a reason for hiding this comment

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

Except of that it's nether public nor exported in the library, the UrlStrategy could be fetched from the web's platform dispatcher as in the following dummy code: EnginePlatformDispatcher.instance.(_windows[0]! as EngineFlutterWindow).browserHistory.urlStrategy; as depicted in engine:lib/web_ui/lib/src/engine/platform_dispatcher.dart:972

Copy link
Member

Choose a reason for hiding this comment

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

@TheOneWithTheBraid: at the plugins level we can't know (for now) what's the URL strategy picked by the current app (even if we exposed that information from the engine, it'd take a few months for it to trickle down to the stable channel), to add a # or not.

However, programmers of web apps do know what type of links their web app needs.

As an alternative solution, have you tried setting your link widget with a URL similar to:

#/another/internal/route instead of /another/internal/route (I think this was the example in the originally reported issue)?

Is the problem then that when clicking on the URL it doesn't work?

I think it might be easier to teach the Link widget/Flutter framework to recognize those URLs when dealing with the onClick of the Link element, rather than attempting to "fix" the URL that the programmer is setting in links.

(Note that now we have 2 URL strategies, but if more end up being added, we might end up needing some extra behavior for each of them!)

Apologies if I'm misunderstanding the problem, but as far as I'm currently understanding this, I think we're attempting a fix in the wrong component!

Copy link
Member

Choose a reason for hiding this comment

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

it might be useful to access to current URL strategy anyway, right?

Yes, I don't have any problem with some of that information being exposed (or maybe a Link generator component that is compatible with the current URL strategy). The biggest problem of exposing these web-only APIs (for now) is that there's not a good place to expose them in a consistent way. (this is not a problem exclusive of this particular API, it's a flutter web issue in general!)

The purpose of the link is to work as a "normal" a href, with regards to clicking, copy-pasting and dragging to the address bar; we need to review that flutter is not doing "too much" with links for them to work (because the browser will not do that much)

Copy link
Contributor

Choose a reason for hiding this comment

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

May you tell me whether my idea is right:

Would it be possible to somehow publicly make available _customUrlStrategy in engine:lib/web_ui/lib/src/engine/window.dart:38?

That way, the platform interface could check the present url strategy, right?

Would you mind if I create a corresponding getter in the file?

Yes, this should work.

However, programmers of web apps do know what type of links their web app needs.

The idea is that inside your app, you don't need to know how the URL is represented in the browser. It could be a simple path /route or a hash path #/route or something completely different, depending on the url strategy. But your app shouldn't care about this difference. Only the url strategy needs to know about this (and you could implement your own url strategy if you want to customize this).

The url strategy has two methods to handle this:

  • prepareExternalUrl: converts an app route name to the path that goes in the browser url bar and <a> elements, etc. For example, HashUrlStrategy.prepareExternalUrl adds a # to the beginning of the route name to make it a hash path.

  • getPath: converts a path from the browser url bar to a route name for the app to consume. For example, HashUrlStrategy.getPath gets the hash part of the browser location, and strips the # from it.

(Note that now we have 2 URL strategies, but if more end up being added, we might end up needing some extra behavior for each of them!)

It doesn't matter how many url strategies there are (actually, users can create their own custom url strategies today, so we already have more than two). The Link widget shouldn't do any #-specific behavior/logic. It should just call UrlStrategy.prepareExternalUrl and let it handle the hash if necessary.

Copy link
Member

Choose a reason for hiding this comment

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

maybe a Link generator component that is compatible with the current URL strategy

Ahh, there you go @mdebbar, the prepareExternalUrl from each strategy!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I now opened flutter/flutter#90708 exposing a getter required to call prepareExternalUrl. Let's wait for it to trickle down, I'd propose. Right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mdebbar I now use the newly implemented getter here. May you check whether my implementation is proper?

@TheOneWithTheBraid TheOneWithTheBraid changed the title [url_launcher] Fixed missing # in links href when opening in new tab on the web [url_launcher] WIP: Waiting for master to trickle down - Fixed missing # in links href when opening in new tab on the web Oct 18, 2021
@stuartmorgan-g stuartmorgan-g marked this pull request as draft November 4, 2021 20:31
@stuartmorgan-g
Copy link
Contributor

Marking as a draft to remove it from our review queue; please remove the draft designation once this can proceed on stable.

@stuartmorgan-g
Copy link
Contributor

Was the necessary change in 2.8? I see that the commit has some 2.8.0-*.pre tags, which suggest yes, but I know there were some version oddities on master.

@godofredoc godofredoc changed the base branch from master to main January 6, 2022 23:36
@TheOneWithTheBraid TheOneWithTheBraid marked this pull request as ready for review January 28, 2022 08:31
@TheOneWithTheBraid TheOneWithTheBraid changed the title [url_launcher] WIP: Waiting for master to trickle down - Fixed missing # in links href when opening in new tab on the web [url_launcher] Fixed missing # in links href when opening in new tab on the web Jan 28, 2022
@TheOneWithTheBraid
Copy link
Contributor Author

It seems like the urlStrategy getter trickled down to stable. Could you check whether this PR is now eligible for merging?

@TheOneWithTheBraid
Copy link
Contributor Author

The PR is now rebased on the current HEAD. It would be wonderful to have it merged before new conflicts occur.

@stuartmorgan-g
Copy link
Contributor

Could you check whether this PR is now eligible for merging?

It would be wonderful to have it merged before new conflicts occur.

We don't merge unreviewed PRs; this PR has not been approved by any reviewer.

@stuartmorgan-g stuartmorgan-g requested review from ditman and removed request for LHLL, bparrishMines, cyanglaz and gaaclarke February 9, 2022 17:10
- fix the the CHANGELOG in order to use the requestd past-tense
  statements

Signed-off-by: TheOneWithTheBraid <[email protected]>
Copy link
Contributor

@mdebbar mdebbar left a comment

Choose a reason for hiding this comment

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

Looks good to me! I would love for @ditman to take a look too in case there's some plugins-specific stuff that I missed.

Copy link
Member

@ditman ditman left a comment

Choose a reason for hiding this comment

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

If @mdebbar is happy, I'm happy. I checked that the minimum version of flutter is >=2.10.0 so this only resolves for users in a modern enough version of the stable channel.

Ship it!

@ditman ditman added last mile waiting for tree to go green (Use "autosubmit") This PR is approved and tested, but waiting for the tree to be green to land. labels Feb 25, 2022
@fluttergithubbot fluttergithubbot merged commit 06922c0 into flutter:main Feb 25, 2022
@TheOneWithTheBraid TheOneWithTheBraid deleted the new-tab-fix branch February 28, 2022 06:40
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Feb 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

cla: yes p: url_launcher platform-web waiting for tree to go green (Use "autosubmit") This PR is approved and tested, but waiting for the tree to be green to land.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[url_launcher] Missing # in links href when opening in new tab on the web

5 participants