Giter VIP home page Giter VIP logo

ember-render-modifiers's Issues

Weird issue when referencing `document` in callback of will-destroy

I'm not sure how/if this is really related to the modifiers, but I haven't been able to reproduce it without them. I believe it's some kind of interaction between babel/decorators/modifiers.

Apparently if in the callback passed to {{will-destroy}} I use the global document without having referenced it elsewhere, the compilation blows badly:

ReferenceError: document is not defined
    at BasicDropdownTrigger.removeGlobalHandlers (/var/folders/bt/62lj_mr106zbk82m8kl772b00000gn/T/broccoli-9932Xc3l4ZKiotlD/out-271-broccoli_merge_trees/assets/addon-tree-output/ember-basic-dropdown/components/basic-dropdown-trigger.js:140:1)
    at Object.destroyModifier (/var/folders/bt/62lj_mr106zbk82m8kl772b00000gn/T/broccoli-9932Xc3l4ZKiotlD/out-271-broccoli_merge_trees/assets/addon-tree-output/@ember/render-modifiers/modifiers/will-destroy.js:26:1)
    at CustomModifierState.destroy (/var/folders/bt/62lj_mr106zbk82m8kl772b00000gn/T/broccoli-9932Xc3l4ZKiotlD/out-271-broccoli_merge_trees/assets/vendor/ember-modifier-manager-polyfill.js:58:1)
    at SimpleBlockTracker.destroy (/var/folders/bt/62lj_mr106zbk82m8kl772b00000gn/T/broccoli-9932Xc3l4ZKiotlD/out-271-broccoli_merge_trees/assets/@glimmer/runtime.js:2411:1)
    at UpdatableBlockTracker.destroy (/var/folders/bt/62lj_mr106zbk82m8kl772b00000gn/T/broccoli-9932Xc3l4ZKiotlD/out-271-broccoli_merge_trees/assets/@glimmer/runtime.js:2411:1)

The reproduction can be this PR: cibernox/ember-basic-dropdown#449

If (this line)[https://github.com/cibernox/ember-basic-dropdown/pull/449/files#diff-e8b1232b23cd9aba9a4b4c3f74b118fcR18] referencing the global document is removed the code fails to compile.

Support conditional modifiers

Since (to my knowledge) its not possible to conditionally add a modifier. Something like this:

// doesnt work
<div
  {{if @onInsertTextArea (did-insert @onInsertTextArea)}}
/>
// doesnt work
<div
  {{#if @onInsertTextArea}}
	did-insert @onInsertTextArea
  {{/if}}
/>

then maybe the modifiers provided by this library could silently handle undefined functions, so you could do:

<div
  {{did-insert @onInsertTextArea}}
/>

and when @onInsert is undefined it wont throw an error, like it does now.

Either make the current modifiers silently handle undefined or make new ones to handle modifier function that might no always be provided. This is mostly for general components.

Another option might be to provide -if version of the modifiers:

<div
  {{did-insert-if @onInsertTextArea @onInsertTextArea}}
/>

Error: Invalid modifier manager compatibility specified

Hi, I'm having some issues with the helpers when using the latest version (2.0.4) with Ember version 4.4.0. Using did-insert in a template triggers the following: Error: Invalid modifier manager compatibility specified.

Using with `mut` results in render error

Hello!

Say I have a component Test:
components/test/template.hbs
<div {{did-insert (fn (mut this.element))}} {{will-destroy (fn (mut this.element) null)}} />

When that component is destroyed, it results in the following error:
You modified "element" twice on [object Object] in a single render. It was rendered in undefined and modified in undefined. [...]

If I instead perform the registering/unregistering like so:
components/test/template.hbs
<div {{did-insert this.register}} {{will-destroy this.unregister}} />

components/test/component.js

@action
register(element) {
  this.element = element;
}

@action
unregister() {
  this.element = null;
}

Destroying the component doesn't result in an error.

This happens when mut-ing any property with any value on destroy, by the way, not just an element or a property that has been set before.

For reference, here's the code I used to test it:

{{#if this.show}}
  <Test />
{{/if}}

<Button @onClick={{toggle-action 'show' this}}>Toggle</Button>

Also, I'm not sure it makes any difference, but I'm on a canary build of Ember:
"ember-source": "https://s3.amazonaws.com/builds.emberjs.com/canary/shas/55f876ebc10bd1645e1e62fc5e0408266952259b.tgz"
"ember-cli": "github:ember-cli/ember-cli#ba9e3ea9bcad1c6e2299e40fe265cffe61d7a25b"

Any help would be appreciated!

UPDATE: It works if I use the action helper instead of fn. It also passes if I use ember-fn-helper-polyfill for fn. If I use the Ember 3.11 version of fn however, it fails with the error specified above.

New release with ember v5 support?

With #70 being merged, and now that ember v5 is in beta channel, I think a new release is warranted here to so that consumers of this addon can test against beta without receiving a version warning.

Documentation!

  • API docs
    • did-insert
    • did-update
    • will-destroy
  • General usage guides
    • Copy usage examples from emberjs/rfcs#415 (#3)
    • Identify common example scenarios, document how to handle them...

Unexpected token '.' in Gitlab pipeline

After installing ember-render-modifiers version 2.0.3 or 2.0.4 the local building process works fine, but the Gitlab pipeline fails with the error Unexpected token '.' and nothing else in the logs. We use a docker container in the pipeline that executes ember build --environment=test. Then it builds, cleans up and logs the error message.

Is there anything I can do to get more info about that error? Has anyone encountered that before?

Modifiers don't seem to work when applied to elements are ember components with `tagName=''`

Using modifiers on an element that is itself a classic Ember component (@ember/component) doesn't seem to work.
This poses difficulties because the developer now has to 'know' :godmode: what the
other component is.

This works great:

<div {{did-insert this.someFunc}}>
</div>

This not so much (doesn't error, doesn't execute).

<SomeOtherEmberComponent {{did-insert this.someFunc}}>
</SomeOtherEmberComponent>

Improve the error message when `this` is undefined

If you try to use this within methods called by {{on}} and {{fn}}, they show a helpful error instructing the developer to use the @action decorator. The render modifiers could show something like that too.

Here's an example "error" use case for did-insert:

<div class="my-container" {{did-insert this.renderEditor}}></div>
import Component from '@glimmer/component';

export default class CodeEditor extends Component {
  renderEditor(el) {
    console.log(this.args.code)
  }
}

TypeError: this is undefined

{{fn}} uses this error message:

You accessed this.arg2 from a function passed to the fn helper, but the function itself was not bound to a valid this context. Consider updating to usage of @action.

Node 12/14 unsupported?

As Node 10 is coming up on EOL, I tried to update my project to Node 14 (and 12). In both cases, when I did, I got the following build error:

Build Error (broccoli-persistent-filter:Babel > [Babel: @ember/render-modifiers]) in @ember/render-modifiers/modifiers/did-insert.js

No "exports" main defined in /Users/stephen.weiss/code/olo/expo-web-client/node_modules/@ember/render-modifiers/node_modules/@babel/helper-compilation-targets/package.json


Stack Trace and Error Report: /var/folders/dz/43k2z2yn53g6g5wgzbx0gw8m0000gp/T/error.dump.f35dc8ac0b4685c4fa73ca1fd5ee7483.log

Is there anything we can do to accommodate newer Node versions? Or is there any recommended path forward?

My believe is that I am currently only using this in one place:

<form onKeyPress={{action this.handleKeyPress}} onSubmit={{action this.handleFormSubmit}}
          {{did-insert this.handleFormInsert}} tabindex="0">
    //...
</form>

where handleFormInsert is really meant to just add focus:

  handleFormInsert(element) {
    element.focus();
  }

Cannot install library - Not Found

I'm getting the following error when installing this library:
error An unexpected error occurred: "https://registry.yarnpkg.com/@ember%2frender-modifiers: Not found".

Dependency error when using Glint types (`@glint/template`)

When following the Glint setup as described in the README, I'm seeing the following error.

../node_modules/@ember/render-modifiers/types/-private.d.ts:1:30 - error TS2307: Cannot find module '@glint/template' or its corresponding type declarations.

import { ModifierLike } from '@glint/template';

Monorepo environment:

  • Node.js v18.18.2
  • pnpm 8.6.5
  • ember-source 4.12.3

In the addon, locally declared as devDependency:

"@glint/core": "^1.2.1",
"@glint/environment-ember-loose": "^1.2.1",
"@glint/template": "^1.2.1",

The dependency is declared as peer in package.json, which seems correct so I'm kind of puzzled why this error is popping up.

For now we're using glint-template-types.

@model hash and did-update don't play well together

I've created a reproduction of this issue which I'll attempt to describe here:

When returning a hash from the routes model hook and then passing that hash into a component as split properties <Consumer @one={{@model.one}} @two={{@model.two}} /> and then using those split properties in getters of the component to invoke did-update an exception will be thrown when leaving the route. You can see this in the reproduction by navigating between the routes with the console open. This same thing doesn't happen if this.model is used in place of @model.

What I suspect is happening is that @model gets torn down early and re-assigned to the incoming route. This causes the first property @model.first to change which triggers did-update to call the second getter which is now unable to access this.args.second because it is also gone.

I've reproduced this as a synchronous action, but we're hitting this issue when did-update calls a task which loads async state. That's why the modifier needs to trigger the action and it can't just be a getter itself.

I'm not sure if this is an issue with did-update or a broader issue with modifiers and tracked properties using the @model pattern, but this seemed like the right place to start.

Timing issues without didRender

In the process of rewriting components to Octane and using modifiers I ran into timing issues when didRender could no longer be used. The component in question renders text and based on if the text is scrollable or not adds an ‘expand text’ button, which when clicked shows the whole text without having to scroll.

See the following image for some explanation:
truncated-toggle

  1. Short text that is not scrollable
  2. Long text that scrolls, button is shown
  3. When the long text is expanded (There is also a button to collapse the content, but forgot to add it in the image)
  4. New text is loaded, should show button

The problem occurs when you expand the text and then load in new text. Every time new text gets loaded the text gets collapsed by default, then it checks if the text is scrollable. But because it takes some time to render the collapsing it does not see the text as scrollable and no button is shown.

Component.js :

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking'

export default class TruncatedToggle extends Component {
  @tracked
  hasOverflow = false;

  @tracked
  opened = false;

  @action
  init() {
    this.opened = false;
  }

  @action
  getOverflow(element) {
    this.hasOverflow =  element.scrollHeight-1 > element.clientHeight;
  }

  @action
  buttonClicked() {
    this.opened = !this.opened;
  }
}

Previously the getOverflow code was in didRender in which the element scrollHeight and clientHeight gave correct values. Tried to set opened in the init() function to have some time between getting the overflow and collapsing the content, but that was in vain.

Component hbs:

<div class="truncated-toggle"
  {{did-update this.init @content}}
>
  <div class="truncated-toggle__content"
    {{did-insert this.getOverflow}}
    {{did-update this.getOverflow @content}}
  >
    {{{@content}}}
  </div>

  {{#if this.hasOverflow}}
    <button {{action 'buttonClicked'}} class="btn btn--default">
      {{#if this.opened}}
        Collapse text
      {{else}}
        Expand text
      {{/if}}
    </button>
  {{/if}}
</div>

I am able to make this work by adding a timeout:

  @action
  getOverflow(element) {
    setTimeout(() => {
      this.hasOverflow =  element.scrollHeight-1 > element.clientHeight;
    })
  }

But this feels a bit hacky to me. Is this the way to go, or is there a solution that I do not know about?

modifierManagerCapabilities is not a function

We've seen this error popping up at various projects. The reason being we have the dependency: "@ember/render-modifier": "^1.0.0". With 1.0.0 it was working fine but after an upgrade to 1.0.1 we are seeing this error message:

Uncaught (in promise) TypeError: Ember._modifierManagerCapabilities is not a function
    at vendor.js:89048
    at RuntimeResolver._lookupModifier (vendor.js:20216)
    at RuntimeResolver.lookupModifier (vendor.js:20127)
    at CompileTimeLookup.lookupModifier (vendor.js:16613)
    at LazyCompiler.resolveModifier (vendor.js:52478)
    at vendor.js:51567
    at Compilers.compile (vendor.js:51537)
    at compile (vendor.js:52230)
    at LazyCompiler.add (vendor.js:52424)
    at CompilableProgram.compile (vendor.js:52188)

Our workaround was to specify the version of this package to v1.0.0. That said it doesn't necessarily have to be this package cause it, but can be a very mixed constellation of packages that is causing it.

will-destroy does not invoke re-rendering

This happened when I tried to write a HOC with a parent passing a function to its child, and the function gets called when the child is inserted and going to be destroyed. I made an integration test to demonstrate the issue.

import Component from '@glimmer/component';
import { click, find, render } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { action } from '@ember/object';
import hbs from 'htmlbars-inline-precompile';
import { setupRenderingTest } from 'ember-qunit';
import { tracked } from '@glimmer/tracking';

module('Integration | Modifier | will-destroy', hooks => {
  setupRenderingTest(hooks);

  test('it should invoke UI re-rendering when changing tracked properties', async function(assert) {
    this.owner.register(
      'component:parent-component',
      class extends Component {
        @tracked text = '';

        get message() {
          return this.text;
        }

        @action changeText(text) {
          this.text = text;
        }
      }
    );

    this.owner.register(
      'template:components/parent-component',
      hbs`
        <div data-dummy>{{this.message}}</div>
        {{yield (hash changeText=this.changeText)}}
      `
    );

    this.set('show', true);

    await render(
      hbs`
        <ParentComponent as |parent|>
          {{#if show}}
            <div
              {{did-insert (fn parent.changeText "Hello")}}
              {{will-destroy (fn parent.changeText "World")}}
            >
            </div>
          {{/if}}
          <button data-button {{on "click" (fn parent.changeText "World")}}>Change Text</button>
        </ParentComponent>
      `
    );

    // did-insert invokes re-rendering correctly, now the message is "Hello".
    assert.strictEqual(find('[data-dummy]').innerText, 'Hello'); 

    // trigger destroying. should change text.
    this.set('show', false);

    // will-destroy does not invoke re-rendering. message supposed to be "World".
    assert.strictEqual(find('[data-dummy]').innerText, 'Hello'); 

    await click('[data-button]');
    // if the changeText function is called by other ways, it works seamlessly.
    assert.strictEqual(find('[data-dummy]').innerText, 'World');
  });
});

Also attached some dependencies info here.

"devDependencies": {
  "@ember/optional-features": "^0.7.0",
  "@ember/render-modifiers": "^1.0.2",
  "@glimmer/component": "^0.14.0-alpha.13",
  "ember-cli": "~3.13.1",
  "ember-cli-babel": "^7.7.3",
  "ember-source": "~3.13.2"
},

Octane needs types added in resolver

at present, these need to be added manually:

  // required for @ember/element-modifiers
  modifier: { definitiveCollection: 'main' },

in src/resolver.js.

Whenever there are hooks for addons to do this themselves, this addon should add the modifier collection.

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.