Skip to content

Commit

Permalink
Convert to Glimmer component
Browse files Browse the repository at this point in the history
- this might fix a memory leak, but should be done in any case as a general upgrade
  • Loading branch information
jaredgalanis committed Jan 19, 2024
1 parent 8939ab6 commit 95e7bd0
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 53 deletions.
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 18.17.0
1 change: 1 addition & 0 deletions addon/components/markdown-to-html.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div>{{this.html}}</div>
55 changes: 20 additions & 35 deletions addon/components/markdown-to-html.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,34 @@
/* eslint-disable ember/no-classic-components, ember/no-classic-classes, ember/require-tagless-components, prettier/prettier, ember/no-assignment-of-untracked-properties-used-in-tracking-contexts, ember/no-get, no-prototype-builtins */
/* eslint-disable prettier/prettier */
import showdown from 'showdown';
import Component from '@ember/component';
import Component from '@glimmer/component';
import { htmlSafe } from '@ember/template';
import { get, computed } from '@ember/object';
import { getOwner } from '@ember/application';
import layout from '../templates/components/markdown-to-html';

const CONFIG_LOOKUP = 'config:environment';

const ShowdownComponent = Component.extend({
layout,
markdown: '',
extensions: null,
export default class ShowdownComponent extends Component {
_globalOptions = null

_globalOptions: null,

defaultOptionKeys: computed(function() {
get defaultOptionKeys() {
return Object.keys(showdown.getDefaultOptions());
}).readOnly(),
}

init() {
this._super(...arguments);
constructor() {
super(...arguments);
const owner = getOwner(this);

if (!this.extensions) {
this.extensions = [];
}

if (owner && owner.hasRegistration(CONFIG_LOOKUP)) {
this._globalOptions = (
owner.resolveRegistration(CONFIG_LOOKUP) || {}
).showdown;
}
},
}

html: computed('converter', 'defaultOptionKeys', 'markdown', function() {
get html() {
let showdownOptions = this.getShowdownProperties(
get(this, 'defaultOptionKeys')
this.defaultOptionKeys
);
let converter = get(this, 'converter');
let converter = this.converter;

for (let option in showdownOptions) {
if (
Expand All @@ -49,36 +39,31 @@ const ShowdownComponent = Component.extend({
}
}

return htmlSafe(converter.makeHtml(get(this, 'markdown')));
}).readOnly(),
return htmlSafe(converter.makeHtml(this.args.markdown));
}

converter: computed('extensions', function() {
let extensions = get(this, 'extensions');
get converter() {
let extensions = this.args.extensions ?? [];

if (typeof extensions === 'string') {
extensions = extensions.split(' ');
}

return new showdown.Converter({ extensions });
}),
}

getShowdownProperties(keyNames) {
return keyNames.reduce((accumulator, keyName) => {
let value = get(this, keyName);
let value = this.args[keyName];

if (value === undefined && this._globalOptions) {
value = get(this._globalOptions, keyName);
value = this._globalOptions[keyName];
}

accumulator[keyName] = value;

return accumulator;
}, {});
}
});

ShowdownComponent.reopenClass({
positionalParams: ['markdown']
});
}

export default ShowdownComponent;
1 change: 0 additions & 1 deletion addon/templates/components/markdown-to-html.hbs

This file was deleted.

6 changes: 3 additions & 3 deletions tests/dummy/app/templates/application.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{{! template-lint-disable require-input-label no-curly-component-invocation no-implicit-this }}
<h2 id="title">ember-cli-showdown demo</h2>

{{textarea value=editableText}}
{{markdown-to-html markdown=editableText}}
<Textarea @value={{this.editableText}} />
<MarkdownToHtml @markdown={{this.editableText}}/>

{{markdown-to-html markdown="#Markdown is cool [link](https://google.com)"}}
<MarkdownToHtml @markdown={{"#Markdown is cool [link](https://google.com)"}} />

{{outlet}}
28 changes: 14 additions & 14 deletions tests/integration/components/markdown-to-html-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module('Integration | Component | markdown-to-html', function(hooks) {

test('it renders', async function(assert) {
this.set('markdown', '*hello world*');
await render(hbs`{{markdown-to-html this.markdown}}`);
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} />`);

assert.strictEqual(this.element.querySelector('div').innerHTML.trim(), '<p><em>hello world</em></p>');
});
Expand All @@ -28,9 +28,9 @@ module('Integration | Component | markdown-to-html', function(hooks) {

test('it produces markdown', async function(assert) {
this.markdown = '##Hello, [world](#)';
await render(hbs`{{markdown-to-html this.markdown}}`);
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} />`);

let expectedHtml = '<h2 id="helloworld">Hello, <a href="#">world</a></h2>\n';
let expectedHtml = '<h2 id="helloworld">Hello, <a href="#">world</a></h2>';

assert.strictEqual(
this
Expand All @@ -43,21 +43,21 @@ module('Integration | Component | markdown-to-html', function(hooks) {

test('it inserts <br> tag', async function(assert) {
this.markdown = 'foo \nbar';
await render(hbs`{{markdown-to-html this.markdown}}`);
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} />`);

let actualHtml = this.element.querySelector('div').innerHTML;

assert.strictEqual(actualHtml, '<p>foo<br>\nbar</p>\n');
assert.strictEqual(actualHtml, '<p>foo<br>\nbar</p>');
});

test('supports setting showdown options', async function(assert) {
assert.expect(1);

this.markdown = '# title\nI ~~dislike~~ enjoy visiting http://www.google.com';
await render(hbs`{{markdown-to-html this.markdown simplifiedAutoLink=true headerLevelStart=3 strikethrough=true}}`);
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} @simplifiedAutoLink={{true}} @headerLevelStart={{3}} @strikethrough={{true }} />`);

let expectedHtml =
'<h3 id="title">title</h3>\n<p>I <del>dislike</del> enjoy visiting <a href="http://www.google.com">http://www.google.com</a></p>\n';
'<h3 id="title">title</h3>\n<p>I <del>dislike</del> enjoy visiting <a href="http://www.google.com">http://www.google.com</a></p>';

assert.strictEqual(this.element.querySelector('div').innerHTML, expectedHtml);
});
Expand All @@ -72,10 +72,10 @@ module('Integration | Component | markdown-to-html', function(hooks) {
});

this.markdown = '# title\nI ~~dislike~~ enjoy visiting http://www.google.com';
await render(hbs`{{markdown-to-html this.markdown headerLevelStart=3 strikethrough=true}}`);
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} @headerLevelStart={{3}} @strikethrough={{true}} />`);

let expectedHtml =
'<h3 id="title">title</h3>\n<p>I <del>dislike</del> enjoy visiting <a href="http://www.google.com">http://www.google.com</a></p>\n';
'<h3 id="title">title</h3>\n<p>I <del>dislike</del> enjoy visiting <a href="http://www.google.com">http://www.google.com</a></p>';

assert.strictEqual(this.element.querySelector('div').innerHTML, expectedHtml);
});
Expand All @@ -96,9 +96,9 @@ module('Integration | Component | markdown-to-html', function(hooks) {
});

this.markdown = 'this is an ember showdown!'
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} @extensions="demo" />`);
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} @extensions={{"demo"}} />`);

let expectedHtml = "<p>no it isn't!</p>\n";
let expectedHtml = "<p>no it isn't!</p>";
assert.strictEqual(this.element.querySelector('div').innerHTML, expectedHtml);
});

Expand All @@ -112,7 +112,7 @@ module('Integration | Component | markdown-to-html', function(hooks) {
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} />`);


let expectedHtml = '<p><del>dislike</del></p>\n';
let expectedHtml = '<p><del>dislike</del></p>';

assert.strictEqual(this.element.querySelector('div').innerHTML, expectedHtml);

Expand Down Expand Up @@ -149,7 +149,7 @@ module('Integration | Component | markdown-to-html', function(hooks) {
this.markdown = 'this is a showdown';
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} @extensions="demo excited" />`);

let expectedHtml = '<p>this is an ember showdown!</p>\n';
let expectedHtml = '<p>this is an ember showdown!</p>';
assert.strictEqual(this.element.querySelector('div').innerHTML, expectedHtml);
});

Expand All @@ -160,7 +160,7 @@ module('Integration | Component | markdown-to-html', function(hooks) {
await render(hbs`<MarkdownToHtml @markdown={{this.markdown}} @ghCodeBlocks={{true}} />`);

let expectedHtml =
'<pre><code class="html language-html">&lt;strong&gt;hello&lt;/strong&gt;\n&lt;em&gt;world&lt;/em&gt;\n</code></pre>\n';
'<pre><code class="html language-html">&lt;strong&gt;hello&lt;/strong&gt;\n&lt;em&gt;world&lt;/em&gt;\n</code></pre>';
assert.strictEqual(this.element.querySelector('div').innerHTML, expectedHtml);
});
});

0 comments on commit 95e7bd0

Please sign in to comment.