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

Convert to Glimmer component #131

Merged
merged 1 commit into from
Jan 19, 2024
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
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>
56 changes: 21 additions & 35 deletions addon/components/markdown-to-html.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
/* 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, no-prototype-builtins */

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,

_globalOptions: null,
export default class ShowdownComponent extends Component {
_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 +40,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);
});
});