Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BREAKING] Update to use glimmer component #59

Merged
merged 2 commits into from
Dec 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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