Skip to content

Commit

Permalink
Update to modern Ember
Browse files Browse the repository at this point in the history
- Refactor <RenderMobiledoc> component to Glimmer
- Drop ember-wormhole in favor of in-element helper (via ember-in-element-polyfill)
- Drop support for looking up DOM document on old Ember versions
- Update dependencies
- Convert tests to use Glimmer components for cards and atoms
- Drop dependencies on ember-fetch, rsvp and chai
  • Loading branch information
lukemelia committed Dec 27, 2021
1 parent d2b31b5 commit e8c1673
Show file tree
Hide file tree
Showing 27 changed files with 279 additions and 556 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { A } from '@ember/array';
import Component from '@ember/component';
import { assert } from '@ember/debug';
import { computed } from '@ember/object';
import Component from '@glimmer/component';
import { join } from '@ember/runloop';
import Ember from 'ember';
import Renderer from 'ember-mobiledoc-dom-renderer';
import { RENDER_TYPE } from 'ember-mobiledoc-dom-renderer';
import layout from '../templates/components/render-mobiledoc';
import { getDocument } from '../utils/document';
import assign from '../utils/polyfilled-assign';
import { getDocument } from 'ember-mobiledoc-dom-renderer/utils/document';
import assign from 'ember-mobiledoc-dom-renderer/utils/polyfilled-assign';

const {
uuid
Expand Down Expand Up @@ -71,75 +68,75 @@ function createComponentAtom(name) {
};
}

export default Component.extend({
layout: layout,

didReceiveAttrs() {
let mobiledoc = this.mobiledoc;
assert(`Must pass mobiledoc to render-mobiledoc component`, !!mobiledoc);

if (this._teardownRender) {
this._teardownRender();
this._teardownRender = null;
}
this._renderMobiledoc();
},
export default class extends Component {
_teardownRender;

// pass in an array of card names that the mobiledoc may have. These
// map to component names using `cardNameToComponentName`
cardNames: [], // eslint-disable-line
get cardNames() {
return this.args.cardNames || [];
}

// pass in an array of atom names that the mobiledoc may have. These
// map to component names using `atomNameToComponentName`
atomNames: [], // eslint-disable-line
get atomNames() {
return this.args.atomNames || [];
}

get mdcCards() {
return this.cardNames.map(createComponentCard);
}

_mdcCards: computed('cardNames', function() {
return this.cardNames.map(name => createComponentCard(name));
}),
get mdcAtoms() {
return this.atomNames.map(createComponentAtom);
}

_mdcAtoms: computed('atomNames', function() {
return this.atomNames.map(name => createComponentAtom(name));
}),
get renderedMobiledoc() {
if (this._teardownRender) {
this._teardownRender();
this._teardownRender = null;
}

_renderMobiledoc() {
let dom = getDocument(this);
let { mobiledoc } = this.args;
let renderer = new Renderer(this._buildRendererOptions(dom));
let { result, teardown } = renderer.render(mobiledoc);

// result is a document fragment, and glimmer2 errors when cleaning it up.
// We must append the document fragment to a static wrapper.
// Related: https://github.com/tildeio/glimmer/pull/331 and
// https://github.com/yapplabs/ember-wormhole/issues/66#issuecomment-246207622
let wrapper = this._createElement(dom, 'div');
wrapper.appendChild(result);

let mobiledoc = this.mobiledoc;
this._teardownRender = teardown;
return wrapper;
}

_buildRendererOptions(dom) {
let options = {
dom,
cards: this._mdcCards,
atoms: this._mdcAtoms
cards: this.mdcCards,
atoms: this.mdcAtoms,
};
[
'mobiledoc', 'sectionElementRenderer', 'markupElementRenderer',
'unknownCardHandler', 'unknownAtomHandler'
].forEach(option => {
let value = this.get(option);
let value = this.args[option];
if (value) {
options[option] = value;
}
});

let passedOptions = this.cardOptions;
let passedOptions = this.args.cardOptions;
let cardOptions = this._cardOptions;
options.cardOptions = passedOptions ? assign(passedOptions, cardOptions) : cardOptions;

let renderer = new Renderer(options);
let { result, teardown } = renderer.render(mobiledoc);

// result is a document fragment, and glimmer2 errors when cleaning it up.
// We must append the document fragment to a static wrapper.
// Related: https://github.com/tildeio/glimmer/pull/331 and
// https://github.com/yapplabs/ember-wormhole/issues/66#issuecomment-246207622
let wrapper = this._createElement(dom, 'div');
wrapper.appendChild(result);

this.set('renderedMobiledoc', wrapper);
this._teardownRender = teardown;
},
cardOptions = passedOptions ? assign(passedOptions, cardOptions) : cardOptions;
options.cardOptions = cardOptions;
return options;
}

_cardOptions: computed(function() {
get _cardOptions() {
return {
[ADD_CARD_HOOK]: ({env, options, payload}) => {
let { name: cardName, dom } = env;
Expand All @@ -149,7 +146,7 @@ export default Component.extend({

let card = {
componentName,
destinationElementId: element.getAttribute('id'),
destinationElement: element,
payload,
options
};
Expand All @@ -164,7 +161,7 @@ export default Component.extend({

let atom = {
componentName,
destinationElementId: element.getAttribute('id'),
destinationElement: element,
payload,
value,
options
Expand All @@ -175,63 +172,58 @@ export default Component.extend({
[REMOVE_CARD_HOOK]: (card) => this.removeCard(card),
[REMOVE_ATOM_HOOK]: (atom) => this.removeAtom(atom)
};
}),
}

willDestroyElement() {
willDestroy() {
if (this._teardownRender) {
this._teardownRender();
}
return this._super(...arguments);
},
return super.willDestroy(...arguments);
}

// override in subclass to change the mapping of card name -> component name
cardNameToComponentName(name) {
return name;
},
}

// override in subclass to change the mapping of atom name -> component name
atomNameToComponentName(name) {
return name;
},
}

// @private

_componentCards: computed(function() {
return A();
}),

_componentAtoms: computed(function() {
return A();
}),
_componentCards = A();
_componentAtoms = A();

addCard(card) {
this._componentCards.pushObject(card);
},
}

removeCard(card) {
join(() => {
this._componentCards.removeObject(card);
});
},
}

addAtom(atom) {
this._componentAtoms.pushObject(atom);
},
}

removeAtom(atom) {
join(() => {
this._componentAtoms.removeObject(atom);
});
},
}

generateUuid() {
return `${UUID_PREFIX}${uuid()}`;
},
}

_createElement(dom, tagName, classNames=[]) {
let el = dom.createElement(tagName);
el.setAttribute('id', this.generateUuid());
el.setAttribute('class', classNames.join(' '));
return el;
}
});
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
{{this.renderedMobiledoc}}
<div ...attributes>
{{this.renderedMobiledoc}}
</div>

{{#each this._componentCards as |card|}}
{{#ember-wormhole to=card.destinationElementId}}
{{#in-element card.destinationElement}}
{{component card.componentName options=(readonly card.options) payload=(readonly card.payload)}}
{{/ember-wormhole}}
{{/in-element}}
{{/each}}
{{#each this._componentAtoms as |atom|}}
{{#ember-wormhole to=atom.destinationElementId}}
{{#in-element atom.destinationElement}}
{{component atom.componentName options=(readonly atom.options) payload=(readonly atom.payload) value=(readonly atom.value)}}
{{/ember-wormhole}}
{{/in-element}}
{{/each}}
13 changes: 3 additions & 10 deletions addon/utils/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@ import { getOwner } from '@ember/application';
// Private Ember API usage. Get the dom implementation used by the current
// renderer, be it native browser DOM or Fastboot SimpleDOM
export function getDocument(context) {
let container = getOwner ? getOwner(context) : context.container;
let documentService = container.lookup('service:-document');

if (documentService) { return documentService; }

let renderer = container.lookup('renderer:-dom');

if (renderer._dom && renderer._dom.document) { // pre Ember 2.6
return renderer._dom.document;
} else {
let documentService = getOwner(context).lookup('service:-document');
if (!documentService) {
throw new Error('ember-mobiledoc-dom-renderer could not get DOM');
}
return documentService;
}
1 change: 1 addition & 0 deletions app/components/render-mobiledoc/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ember-mobiledoc-dom-renderer/components/render-mobiledoc/component';
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default } from 'ember-mobiledoc-dom-renderer/components/render-mobiledoc';
export { default } from 'ember-mobiledoc-dom-renderer/components/render-mobiledoc/template';
14 changes: 14 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "es6",
"experimentalDecorators": true
},
"exclude": [
"node_modules",
"bower_components",
"tmp",
"vendor",
".git",
"dist"
]
}
17 changes: 7 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,19 @@
"version": "npm run update-changelog && git add CHANGELOG.md"
},
"dependencies": {
"broccoli-funnel": "^1.2.0",
"broccoli-merge-trees": "^2.0.0",
"ember-cli-babel": "^7.19.0",
"ember-cli-htmlbars": "^4.3.1",
"ember-fetch": "^8.0.1",
"ember-wormhole": "^0.5.2",
"mobiledoc-dom-renderer": "^0.7.0",
"rsvp": "^4.8.5"
"broccoli-funnel": "^3.0.3",
"broccoli-merge-trees": "^4.2.0",
"ember-cli-babel": "^7.20.5",
"ember-cli-htmlbars": "^5.1.2",
"ember-in-element-polyfill": "^1.0.0",
"mobiledoc-dom-renderer": "^0.7.0"
},
"devDependencies": {
"@ember/optional-features": "^1.3.0",
"@glimmer/component": "^1.0.0",
"@glimmer/tracking": "^1.0.0",
"babel-eslint": "^10.1.0",
"broccoli-asset-rev": "^3.0.0",
"chai": "^4.1.1",
"conventional-changelog": "^1.1.4",
"conventional-changelog-cli": "^1.3.2",
"ember-auto-import": "^1.5.3",
Expand All @@ -64,7 +61,7 @@
"ember-source-channel-url": "^2.0.1",
"ember-template-lint": "^2.6.0",
"ember-try": "^1.4.0",
"eslint": "^6.8.0",
"eslint": "^7.2.0",
"eslint-plugin-ember": "^8.4.0",
"eslint-plugin-node": "^11.1.0",
"loader.js": "^4.7.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Component from 'ember-mobiledoc-dom-renderer/components/render-mobiledoc/component';

export default class extends Component {
willDestroy() {
this.args.onWillDestroy();
super.willDestroy(...arguments);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ember-mobiledoc-dom-renderer/components/render-mobiledoc/template';
10 changes: 10 additions & 0 deletions tests/dummy/app/components/name-changing-renderer/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Component from 'ember-mobiledoc-dom-renderer/components/render-mobiledoc/component';

export default class extends Component {
cardNameToComponentName(cardName) {
return cardName.replace('sample', 'sample-changed-name');
}
atomNameToComponentName(cardName) {
return cardName.replace('sample', 'sample-changed-name');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ember-mobiledoc-dom-renderer/components/render-mobiledoc/template';
5 changes: 0 additions & 5 deletions tests/dummy/app/components/sample-card.js

This file was deleted.

3 changes: 3 additions & 0 deletions tests/dummy/app/components/sample-card/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
<h3>sample!!!!!!! foo: {{@payload.foo}}</h3>
</div>
5 changes: 0 additions & 5 deletions tests/dummy/app/components/sample-changed-name-test-atom.js

This file was deleted.

5 changes: 0 additions & 5 deletions tests/dummy/app/components/sample-changed-name-test-card.js

This file was deleted.

5 changes: 0 additions & 5 deletions tests/dummy/app/components/sample-test-atom.js

This file was deleted.

5 changes: 0 additions & 5 deletions tests/dummy/app/components/sample-test-card.js

This file was deleted.

1 change: 0 additions & 1 deletion tests/dummy/app/templates/components/sample-card.hbs

This file was deleted.

1 change: 0 additions & 1 deletion tests/fastboot/rendering-mobiledoc-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ module('FastBoot | rendering tests', function(hooks) {
test('renders simple mobiledoc', async function(assert) {
let name = 'simple';
let { htmlDocument } = await visit('/fastboot');

let wrapper = `.render-mobiledoc-wrapper.${name}`;
assert.dom(wrapper, htmlDocument).exists({ count: 1});

Expand Down
Loading

0 comments on commit e8c1673

Please sign in to comment.