adopted-ember-addons / ember-router-helpers

MIT License
39 stars 14 forks source link

{{url-for triggers browser transition #265

Open bobisjan opened 4 years ago

bobisjan commented 4 years ago

Hi,

we are facing issues presented in https://emberjs.github.io/rfcs/0391-router-helpers.html#anchor-tags while using {{url-for helper, and would like to resolve this.

I'm happy to work on this, but I'm not sure where to start - should this be handled like in ember-href-to or does this belongs into Ember itself.

Thanks

rwjblue commented 4 years ago

Sorry for the delay in responding. I think we can add support for the proposed solution here (almost making this repo a polyfill, but not quite).

Further down in that RFC the suggested path forward exists (from here):

In the past, only HTMLAnchorElements that were produced by {{link-to}}s would produce a transition when a user clicked on them. This RFC changes to the global EventDispatcher to allow for any HTMLAnchorElement with a valid root relative href to cause a transition. This will allow for us to not only allows us to support use cases like the ones described in the motivation, it makes teaching easier since people who know HTML don't need know an Ember specific API to participate in routing transitions.

I think we can do that by providing a custom event dispatcher.

bobisjan commented 4 years ago

Thanks for the response, I've made some working draft, if you can take a look and tell if it starts in good direction?

import Service, { inject as service } from "@ember/service";
import Ember from "ember";

export function initialize(application) {
  application.register(
    "event_dispatcher:main",
    class extends Ember.EventDispatcher {
      @service router;

      setup() {
        super.setup(...arguments);

        let rootElement = document.querySelector(this.rootElement);

        // TODO removeEventListener
        rootElement.addEventListener("click", (event) => {
          let target = event.target;
          let candidate = null;

          do {
            if (target instanceof HTMLAnchorElement) {
              candidate = target;
              break;
            }

            target = target.parentNode;
          } while (target && target.nodeType === 1);

          if (candidate === null) {
            return;
          } else if (candidate.classList.contains("ember-view")) {
            // skip LinkTo
            return;
          }
          // TODO skip other cases, see ember-href-to

          let href = candidate.getAttribute("href");

          if (href.startsWith(this.router.rootURL)) {
            if (this.router.recognize(href)) {
              event.preventDefault();
              this.router.transitionTo(href);
            }
          }
        });
      }
    }
  );
}

export default {
  initialize,
};
rwjblue commented 4 years ago

Generally speaking, it looks good though we should be able to remove the initializer in favor of a reexport at app/event_dispatcher.js (see prior art in https://github.com/rwjblue/ember-native-dom-event-dispatcher).

jordpo commented 3 years ago

I tried the EventDispatcher approach and ran into instantiation issues. @bobisjan did you ever get this working for you?

bobisjan commented 3 years ago

@jordpo yes, the https://github.com/rwjblue/ember-router-helpers/pull/267 did not work for you? IIRC there is one unresolved issue with disabling wildcard routes, but the rest should be working.

jordpo commented 3 years ago

Ok awesome - will double check. Thanks!