GithubHelp home page GithubHelp logo

ember-polyfills / ember-on-modifier Goto Github PK

View Code? Open in Web Editor NEW
38.0 3.0 6.0 1.8 MB

Implements the `{{on eventName this.someAction}}` element modifier from https://github.com/emberjs/rfcs/blob/master/text/0471-on-modifier.md

License: MIT License

JavaScript 95.30% HTML 4.57% Handlebars 0.13%
ember emberjs ember-addon ember-element-modifier ember-modifier polyfill

ember-on-modifier's People

Contributors

buschtoens avatar ctjhoa avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar ember-tomster avatar joshuaswift avatar mmun avatar rwjblue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ember-on-modifier's Issues

Add CI tests for IE11

#2 has added specific code to support IE11. We should have CI run the test suite in IE11 to guarantee that support.

This probably means configuring something like AppVeyor?

Documentation is wrong about `bubbles`

The title is not exactly true. I believe bubbles=false actually does both preventDefault and stopPropagation so you might want to note that in the documentation so people convert correctly their old code.

Move into ember-polyfills org?

I’ve been collecting the various polyfills that folks have made over in the ember-polyfills org. I’ve mostly been doing it as a way to increase bus factor, but it’s also super helpful to have a group of repo owners that are all conceptually familiar with the polyfill problem space.

Think this repo is a good candidate for ember-polyfills?

Make a "true" polyfill

  • Deprecate usage of the prevent-default template helper
  • #50 Use ember-cli-version-checker's .forEmber() to check if we are using >= 3.11.0-beta.1
    • if we are on 3.11+ disable treeForAddon
    • if we are on < 3.11, do normal processing

Disable polyfill for Ember 3.11

Sub-task of #45 (comment):

Use ember-cli-version-checker's .forEmber() to check if we are using >= 3.11.0-beta.1

  • if we are on 3.11+ disable treeForAddon
  • if we are on < 3.11, do normal processing

Should also print a warning in the CLI, if ember-on-modifier is a direct dependency, so that the user is aware and can uninstall ember-on-modifier.

Ensure stability when possible.

During the implementation of on upstream I noticed that the listeners were being setup and destroyed a ton. This is because the modifiers updateModifier hook is called whenever the arguments may have been changed, which in the case of {{on 'some-string' this.whatever}} means that any time this is updated we rerender. In the upstream implementation I do some extra backbending to ensure that we only call removeEventListener/addEventListener in updateModifier when absolutely required.

I think the following is a rough checklist to accomplish the stability we want for this as a polyfill:

  • Add a small snippet to track counts of add/remove
let adds = 0;
let removes = 0;
export function counts() { 
  return { adds, removes };
}

function setupListener(...) {
  adds++;
  // ...snip...
}

function destroyListener(...) {
  removes++;
  // ...snip...
}
  • Add a helpful assert.counts to the assert object:
// tests/test-helper.js
import { counts } from 'ember-on-modifier/modifiers/on';

QUnit.testStart(function() {
  this._startingCounts = counts();
});

QUnit.assert.counts = function(expected) {
  let current = counts();

  this.assert.deepEqual(
    current,
    {
      adds: expected.adds + this._startingCounts.adds,
      removes: expected.removes + this._startingCounts.removes,
    },
    `counters have incremented by ${JSON.stringify(expected)}`
  );
};
  • Add some assert.counts({ adds: 1, removes: 0}) style assertions to tests (will likely fail for "simple" things)
  • Add in manual stability checks in updateModifier, specifically checking if the named arguments have actually changed (e.g. doing oldCallback !== newCallback guards)

Deprecation warning after installing this package (implicit-modifier-manager-capabilities)

Hi! We recently installed this package and since installing get the following deprecation warning anytime the polyfill is used:

Custom modifier managers must define their capabilities using the capabilities() helper function [deprecation id: implicit-modifier-manager-capabilities]

We're running version 2.18.2 of ember-cli.

Let me know if you need any more info 😄

Allow excluding template helpers

Add a build option excludeHelpers to filter out the template helpers from the build.

  • false: (default) include all helpers
  • true: exclude all helpers
  • array of helper names: exclude the listed helpers

Ref #5, #9.

preventDefault

{{action}} supports a preventDefault option to automatically call event.preventDefault():

<a href="/" {{action this.someAction preventDefault=true}}>Click me</a>

We could either add the same option to {{on}}:

<a href="/" {{on "click" this.someAction preventDefault=true}}>Click me</a>

Or explore alternative solutions. For instance, we could create a prevent-default helper:

<a href="/" {{on "click" (prevent-default this.someAction)}}>Click me</a>
<a href="/" {{on "click" this.someAction}} {{on "click" (prevent-default)}}>Click me</a>

Currently all named parameters are passed through to addEventListener as event options. Adding a preventDefault would mean that we introduce special handling for some options.

Deprecate `(prevent-default)`

Sub-task of #45.

I moved the (prevent-default) template helper to a new addon: ember-event-helpers

Invoking the template helper should print a deprecation notice with a link to ember-event-helpers. The documentation for preventDefault should be replaced with documentation containing the keywords preventDefault, stopPropagation and stopImmediatePropagation (for easy Cmd + F access), linking to ember-event-helpers as well.

If ember-event-helpers is installed, the (prevent-default) helper from ember-on-modifier should be excluded from the build.

1.0 Release

@NullVoxPopuli asked me on Discord, whether there's anything blocking a 1.0 release.

I don't think so. AFAICT we have full feature-parity and all non-standard features that were not part of the RFC have been deprecated. There are also no known bugs.

If there are no further objections, tomorrow I will remove the deprecated features and cut a 1.0 release.

Make the IE11 `addEventListener` polyfill optional

IE11 has an incomplete and buggy implementation of Element#addEventListener, which is why I have added event-listener.js in #2 to make this addon just work™️ in IE11.

This polyfill is of course not required, if the targeted browsers do not include IE11.

We should add a config option to allow excluding the polyfill from the build. Ideally this option would by default depend on the support for { once: true } in the browsers defined in config/tragets.js, so that users don't need to configure this manually.

Passing additional parameters to listeners

As suggested by @pzuraq on Discord.

Action Parameters:

You can optionally pass arguments to the action handler. Any values passed to the {{action}} helper after the action name will be passed to the handler as arguments.

So for us this means:

<button {{on "click" this.onClick "foo" "bar"}}>Click me</button>
export default class extends Component {
  @action
  onClick(foo: string, bar: string, event: MouseEvent) {
    console.log({ foo, bar, event }); // => { foo: "foo", bar: "bar", event: Event { ... } }
  }
}

This will make the transition from {{action}} to {{on}} much easier.

Refactor tests to use `assert.verifySteps` API

Totally not an issue, but I wanted to mention that I've started using assert.step / assert.verifySteps for these sorts of "order tracking" use cases. This test would look like:

  test('{{on "click" (stop-propagation) capture=true}}', async function(assert) {
    assert.expect(1);

    this.outerListener = () => assert.step('outer');
    this.innerListener = () => assert.step('inner');

     await render(hbs`
      <div {{on "click" (stop-propagation this.outerListener) capture=true}}>
        <button {{on "click" this.innerListener}}>inner</button>
      </div>
    `);

     await click('button');

     assert.verifySteps(['outer'], 'it only runs the outer listener');
  });

See:

Originally posted by @rwjblue in #43

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.