Skip to content

Commit

Permalink
Merge pull request #59 from yapplabs/chore/glimmer
Browse files Browse the repository at this point in the history
[BREAKING] Update to use glimmer component
  • Loading branch information
lukemelia authored Dec 28, 2021
2 parents d2b31b5 + f47d771 commit 1eb0901
Show file tree
Hide file tree
Showing 31 changed files with 4,256 additions and 2,023 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ jobs:
fail-fast: false
matrix:
try-scenario:
- ember-lts-3.8
- ember-lts-3.12
- ember-lts-3.16
- ember-lts-3.20
- ember-lts-3.24
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ To learn more about mobiledoc see [mobiledoc-kit](https://github.com/bustlelabs/

## Requirements

* Ember.js v3.8 or above (tested in LTS versions starting 3.8 -- likely works on earlier releases)
* Ember CLI v3.8 or above
* Node.js v10 or above
* Ember.js v3.16 or above (for older versions of Ember, try 0.7.0)
* Ember CLI v3.16 or above
* Node.js v12 or above

### Usage

Expand Down
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';
16 changes: 0 additions & 16 deletions config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,6 @@ const getChannelURL = require('ember-source-channel-url');
module.exports = async function() {
return {
scenarios: [
{
name: 'ember-lts-3.8',
npm: {
devDependencies: {
'ember-source': "~3.8.1"
}
}
},
{
name: 'ember-lts-3.12',
npm: {
devDependencies: {
'ember-source': '~3.12.0'
}
}
},
{
name: 'ember-lts-3.16',
npm: {
Expand Down
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"
]
}
Loading

0 comments on commit 1eb0901

Please sign in to comment.