From 92d86ea981f193b9fff23b34d06843c9b5e74a12 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sun, 11 Apr 2021 20:01:53 -0400 Subject: [PATCH 1/8] allow defining additional imports via frontmatter --- packages/cli/src/lifecycles/graph.js | 3 ++ .../plugins/resource/plugin-standard-html.js | 34 +++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lifecycles/graph.js b/packages/cli/src/lifecycles/graph.js index dde8db77a..75eac9de2 100644 --- a/packages/cli/src/lifecycles/graph.js +++ b/packages/cli/src/lifecycles/graph.js @@ -25,6 +25,7 @@ module.exports = generateGraph = async (compilation) => { const template = attributes.template || 'page'; const title = attributes.title || compilation.config.title || ''; const id = attributes.label || filename.split('/')[filename.split('/').length - 1].replace('.md', '').replace('.html', ''); + const imports = attributes.imports || []; const label = id.split('-') .map((idPart) => { return `${idPart.charAt(0).toUpperCase()}${idPart.substring(1)}`; @@ -97,6 +98,7 @@ module.exports = generateGraph = async (compilation) => { * filename: name of the file * id: filename without the extension * label: "pretty" text representation of the filename + * imports: per page JS or CSS file imports to be included in HTML output * path: path to the file relative to the workspace * route: URL route for a given page on outputFilePath * template: page template to use as a base for a generated component @@ -107,6 +109,7 @@ module.exports = generateGraph = async (compilation) => { filename, id, label, + imports, path: route === '/' || relativePagePath.lastIndexOf('/') === 0 ? `${relativeWorkspacePath}${filename}` : `${relativeWorkspacePath}/${filename}`, diff --git a/packages/cli/src/plugins/resource/plugin-standard-html.js b/packages/cli/src/plugins/resource/plugin-standard-html.js index 20339ed28..e8c911829 100644 --- a/packages/cli/src/plugins/resource/plugin-standard-html.js +++ b/packages/cli/src/plugins/resource/plugin-standard-html.js @@ -45,7 +45,7 @@ const getPageTemplate = (barePath, workspace, template) => { return contents; }; -const getAppTemplate = (contents, userWorkspace) => { +const getAppTemplate = (contents, userWorkspace, customImports = []) => { function sliceTemplate(template, pos, needle, replacer) { return template.slice(0, pos) + template.slice(pos).replace(needle, replacer); } @@ -140,6 +140,30 @@ const getAppTemplate = (contents, userWorkspace) => { } }); + customImports.forEach((customImport) => { + const extension = path.extname(customImport); + + switch (extension) { + + case '.js': + appTemplateContents = appTemplateContents.replace('', ` + + + `); + break; + case '.css': + appTemplateContents = appTemplateContents.replace('', ` + + + `); + break; + + default: + break; + + } + }); + return appTemplateContents; }; @@ -217,6 +241,8 @@ class StandardHtmlResource extends ResourceInterface { const config = Object.assign({}, this.compilation.config); const { userWorkspace, projectDirectory } = this.compilation.context; const normalizedUrl = this.getRelativeUserworkspaceUrl(url); + let customImports; + let body = ''; let template = null; let processedMarkdown = null; @@ -270,11 +296,15 @@ class StandardHtmlResource extends ResourceInterface { if (attributes.template) { template = attributes.template; } + + if (attributes.imports) { + customImports = attributes.imports; + } } } body = getPageTemplate(barePath, userWorkspace, template); - body = getAppTemplate(body, userWorkspace); + body = getAppTemplate(body, userWorkspace, customImports); body = getUserScripts(body, projectDirectory); body = getMetaContent(normalizedUrl, config, body); From 77b669be2dfe2ea8dfe59108ebe142cf94b5ec73 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sun, 11 Apr 2021 20:23:22 -0400 Subject: [PATCH 2/8] counter example --- www/components/counter/counter.css | 3 +++ www/components/counter/counter.js | 38 ++++++++++++++++++++++++++++++ www/pages/plugins/index.md | 5 ++++ 3 files changed, 46 insertions(+) create mode 100644 www/components/counter/counter.css create mode 100644 www/components/counter/counter.js diff --git a/www/components/counter/counter.css b/www/components/counter/counter.css new file mode 100644 index 000000000..e21e2c285 --- /dev/null +++ b/www/components/counter/counter.css @@ -0,0 +1,3 @@ +p { + color: red; +} \ No newline at end of file diff --git a/www/components/counter/counter.js b/www/components/counter/counter.js new file mode 100644 index 000000000..7cc0f92f7 --- /dev/null +++ b/www/components/counter/counter.js @@ -0,0 +1,38 @@ +const template = document.createElement('template'); + +template.innerHTML = ` +

My Counter

+ + + +`; + +class MyCounter extends HTMLElement { + constructor() { + super(); + this.count = 0; + this.attachShadow({ mode: 'open' }); + } + + async connectedCallback() { + this.shadowRoot.appendChild(template.content.cloneNode(true)); + this.shadowRoot.getElementById('inc').onclick = () => this.inc(); + this.shadowRoot.getElementById('dec').onclick = () => this.dec(); + this.update(); + } + + inc() { + this.update(++this.count); // eslint-disable-line + } + + dec() { + this.update(--this.count); // eslint-disable-line + } + + update(count) { + this.shadowRoot.getElementById('count').innerHTML = count || this.count; + } +} + +customElements.define('x-counter', MyCounter); +document.getElementById('plugins').textContent = document.getElementById('plugins').textContent + ' - hello from markdown JS import!'; \ No newline at end of file diff --git a/www/pages/plugins/index.md b/www/pages/plugins/index.md index be1726b00..7e9539571 100644 --- a/www/pages/plugins/index.md +++ b/www/pages/plugins/index.md @@ -3,10 +3,15 @@ label: 'plugins' menu: navigation title: Plugins index: 4 +imports: + - /components/counter/counter.js + - /components/counter/counter.css --- ## Plugins + + At its core, Greenwood provides a CLI to drive all the development related workflows for a Greenwood project. The CLI aims to provide a simple interface for quickly and simply building sites from as little as markdown files. However, for more complex sites and use cases, there will come a need to extend the default functionality of Greenwood and the standard web primitives (e.g. HTML, CSS, JS) for additional capabilities like: From 7a38bca8f06165ebf1e9acebd311e72fa025248c Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sun, 11 Apr 2021 20:23:33 -0400 Subject: [PATCH 3/8] update front matter import docs --- www/pages/docs/front-matter.md | 14 +++++++++----- www/pages/docs/markdown.md | 13 +++++-------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/www/pages/docs/front-matter.md b/www/pages/docs/front-matter.md index 203639a7f..ebb1659c0 100644 --- a/www/pages/docs/front-matter.md +++ b/www/pages/docs/front-matter.md @@ -25,20 +25,24 @@ label: 'My Blog Post from 3/5/2020' ### Imports -> ⛔ _**Coming Soon!**_ - - +> _See our [Markdown Docs](/docs/markdown#imports) for more information about rendering custom elements in markdown files._ ### Template diff --git a/www/pages/docs/markdown.md b/www/pages/docs/markdown.md index 1982a0ef8..a1f738e15 100644 --- a/www/pages/docs/markdown.md +++ b/www/pages/docs/markdown.md @@ -10,27 +10,24 @@ linkheadings: 3 In this section we'll cover some of the Markdown related feature of **Greenwood**, which by default supports the [CommonMark](https://commonmark.org/help/) specification and [**unifiedjs**](https://unifiedjs.com/) as the markdown / content framework. ### Imports -> ⛔ _**Coming Soon!**_ - - - ### Configuration Using your _greenwood.config.js_ you can have additional [markdown customizations and configurations](/docs/configuration#markdown) using unified presets and plugins. From 995066a3074da0e81c104767f1cb7a8824937437 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Thu, 15 Apr 2021 19:42:05 -0400 Subject: [PATCH 4/8] naive work around for markdown wrapped web components --- .../plugins/resource/plugin-standard-html.js | 14 +++ ...ault.workspace-frontmatter-imports.spec.js | 99 +++++++++++++++++++ .../src/components/counter/counter.css | 3 + .../src/components/counter/counter.js | 42 ++++++++ .../src/pages/examples/counter.md | 10 ++ .../src/pages/index.md | 3 + www/components/counter/counter.js | 8 +- 7 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js create mode 100644 packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.css create mode 100644 packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.js create mode 100644 packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md create mode 100644 packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/index.md diff --git a/packages/cli/src/plugins/resource/plugin-standard-html.js b/packages/cli/src/plugins/resource/plugin-standard-html.js index e8c911829..e8836e8a3 100644 --- a/packages/cli/src/plugins/resource/plugin-standard-html.js +++ b/packages/cli/src/plugins/resource/plugin-standard-html.js @@ -309,6 +309,20 @@ class StandardHtmlResource extends ResourceInterface { body = getMetaContent(normalizedUrl, config, body); if (processedMarkdown) { + // TODO this obviously a contrived regex example + // but my regex skills are poo and everything I wrote hung the browser :/ + const wrappedCustomElementRegex = /

(.*)<\/x-counter><\/p>/sg; + const ceTest = wrappedCustomElementRegex.test(processedMarkdown.contents); + + if (ceTest) { + const ceMatches = processedMarkdown.contents.match(wrappedCustomElementRegex); + const stripWrappingTags = ceMatches[0] + .replace('

', '') + .replace('

', ''); + + processedMarkdown.contents = processedMarkdown.contents.replace(ceMatches[0], stripWrappingTags); + } + body = body.replace(/\(.*)<\/content-outlet>/s, processedMarkdown.contents); } diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js new file mode 100644 index 000000000..69b700def --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js @@ -0,0 +1,99 @@ +/* + * Use Case + * Run Greenwood build command with a workspace that uses frontmatter imports. + * + * User Result + * Should generate a bare bones Greenwood build. + * + * User Command + * greenwood build + * + * User Config + * None (Greenwood Default) + * + * User Workspace + * src/ + * components/ + * counter/ + * counter.js + * counter.css + * pages/ + * examples/ + * counter.md + * index.md + */ +const expect = require('chai').expect; +const fs = require('fs'); +const glob = require('glob-promise'); +const { JSDOM } = require('jsdom'); +const path = require('path'); +const runSmokeTest = require('../../../../../test/smoke-test'); +const TestBed = require('../../../../../test/test-bed'); + +describe('Build Greenwood With: ', function() { + const LABEL = 'Default Greenwood Configuration and Workspace with Frontmatter Imports'; + let setup; + + before(async function() { + setup = new TestBed(); + this.context = await setup.setupTestBed(__dirname); + }); + + describe(LABEL, function() { + + before(async function() { + await setup.runGreenwoodCommand('build'); + }); + + runSmokeTest(['public', 'index'], LABEL); + + describe('Content and file output for the Counter page', function() { + let dom; + let html; + + before(async function() { + const htmlPath = path.resolve(this.context.publicDir, 'examples/counter', 'index.html'); + + dom = await JSDOM.fromFile(path.resolve(htmlPath)); + html = await fs.promises.readFile(htmlPath, 'utf-8'); + }); + + it('should output a counter.css file from frontmatter import', async function() { + const cssFiles = await glob.promise(`${this.context.publicDir}**/**/counter.*.css`); + + expect(cssFiles).to.have.lengthOf(1); + }); + + it('should output a counter.js file from frontmatter import', async function() { + const jsFiles = await glob.promise(`${this.context.publicDir}**/**/counter.*.js`); + + expect(jsFiles).to.have.lengthOf(1); + }); + + it('should output a custom element tag that is _not_ wrapped in a

tag', function() { + expect((/

/).test(html)).to.be.false; + expect((/<\/x-counter><\/p>/).test(html)).to.be.false; + }); + + it('should output a heading tag from the custom element', function() { + const heading = dom.window.document.querySelectorAll('body h3'); + + expect(heading.length).to.be.equal(1); + expect(heading[0].textContent).to.be.equal('My Counter'); + }); + + // JSDOM may not support this case of computing styles when using a tag? + // https://github.com/jsdom/jsdom/issues/2986 + xit('should have the color style for the output element', function() { + const output = dom.window.document.querySelector('body ~ h2'); + const computedStyle = dom.window.getComputedStyle(output); + + expect(computedStyle.color).to.equal('red'); + }); + }); + }); + + after(function() { + setup.teardownTestBed(); + }); +}); \ No newline at end of file diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.css b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.css new file mode 100644 index 000000000..d24b896b6 --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.css @@ -0,0 +1,3 @@ +h2 { + color: red; +} \ No newline at end of file diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.js b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.js new file mode 100644 index 000000000..b102faa27 --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/components/counter/counter.js @@ -0,0 +1,42 @@ +const template = document.createElement('template'); + +template.innerHTML = ` + +

My Counter

+ + + +`; + +class MyCounter extends HTMLElement { + constructor() { + super(); + this.count = 0; + this.attachShadow({ mode: 'open' }); + } + + async connectedCallback() { + this.shadowRoot.appendChild(template.content.cloneNode(true)); + this.shadowRoot.getElementById('inc').onclick = () => this.inc(); + this.shadowRoot.getElementById('dec').onclick = () => this.dec(); + this.update(); + } + + inc() { + this.update(++this.count); // eslint-disable-line + } + + dec() { + this.update(--this.count); // eslint-disable-line + } + + update(count) { + this.shadowRoot.getElementById('count').innerHTML = count || this.count; + } +} + +customElements.define('x-counter', MyCounter); \ No newline at end of file diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md new file mode 100644 index 000000000..0657863d2 --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md @@ -0,0 +1,10 @@ +--- +title: Counter Page +imports: + - /components/counter/counter.js + - /components/counter/counter.css +--- + +## Counter Page Example + + \ No newline at end of file diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/index.md b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/index.md new file mode 100644 index 000000000..db36a6f2d --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/index.md @@ -0,0 +1,3 @@ +## Home Page + +This is just a test. \ No newline at end of file diff --git a/www/components/counter/counter.js b/www/components/counter/counter.js index 7cc0f92f7..ff31e6f07 100644 --- a/www/components/counter/counter.js +++ b/www/components/counter/counter.js @@ -1,6 +1,11 @@ const template = document.createElement('template'); template.innerHTML = ` +

My Counter

@@ -34,5 +39,4 @@ class MyCounter extends HTMLElement { } } -customElements.define('x-counter', MyCounter); -document.getElementById('plugins').textContent = document.getElementById('plugins').textContent + ' - hello from markdown JS import!'; \ No newline at end of file +customElements.define('x-counter', MyCounter); \ No newline at end of file From 08276f3d1fc4110d37e0d8f3ab0d13fcca533f74 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sat, 17 Apr 2021 18:30:45 -0400 Subject: [PATCH 5/8] made unwrapping regex more flexible --- .../plugins/resource/plugin-standard-html.js | 15 +++--- ...ault.workspace-frontmatter-imports.spec.js | 53 ++++++++++++++----- .../src/pages/examples/counter.md | 4 +- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/packages/cli/src/plugins/resource/plugin-standard-html.js b/packages/cli/src/plugins/resource/plugin-standard-html.js index e8836e8a3..336cc196d 100644 --- a/packages/cli/src/plugins/resource/plugin-standard-html.js +++ b/packages/cli/src/plugins/resource/plugin-standard-html.js @@ -309,18 +309,19 @@ class StandardHtmlResource extends ResourceInterface { body = getMetaContent(normalizedUrl, config, body); if (processedMarkdown) { - // TODO this obviously a contrived regex example - // but my regex skills are poo and everything I wrote hung the browser :/ - const wrappedCustomElementRegex = /

(.*)<\/x-counter><\/p>/sg; + const wrappedCustomElementRegex = /

<[a-zA-Z]*-[a-zA-Z]*>(.*)<\/[a-zA-Z]*-[a-zA-Z]*><\/p>/g; const ceTest = wrappedCustomElementRegex.test(processedMarkdown.contents); if (ceTest) { const ceMatches = processedMarkdown.contents.match(wrappedCustomElementRegex); - const stripWrappingTags = ceMatches[0] - .replace('

', '') - .replace('

', ''); - processedMarkdown.contents = processedMarkdown.contents.replace(ceMatches[0], stripWrappingTags); + ceMatches.forEach((match) => { + const stripWrappingTags = match + .replace('

', '') + .replace('

', ''); + + processedMarkdown.contents = processedMarkdown.contents.replace(match, stripWrappingTags); + }); } body = body.replace(/\(.*)<\/content-outlet>/s, processedMarkdown.contents); diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js index 69b700def..fd5437b2a 100644 --- a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js @@ -70,25 +70,50 @@ describe('Build Greenwood With: ', function() { expect(jsFiles).to.have.lengthOf(1); }); - it('should output a custom element tag that is _not_ wrapped in a

tag', function() { - expect((/

/).test(html)).to.be.false; - expect((/<\/x-counter><\/p>/).test(html)).to.be.false; - }); - - it('should output a heading tag from the custom element', function() { - const heading = dom.window.document.querySelectorAll('body h3'); + it('should a page heading', function() { + const heading = dom.window.document.querySelectorAll('body h2'); expect(heading.length).to.be.equal(1); - expect(heading[0].textContent).to.be.equal('My Counter'); + expect(heading[0].textContent).to.be.equal('Counter Page Example'); }); - // JSDOM may not support this case of computing styles when using a tag? - // https://github.com/jsdom/jsdom/issues/2986 - xit('should have the color style for the output element', function() { - const output = dom.window.document.querySelector('body ~ h2'); - const computedStyle = dom.window.getComputedStyle(output); + describe('Counter component from front matter', () => { + it('should output a custom x-counter tag that', function() { + const counter = dom.window.document.querySelectorAll('body x-counter'); + + expect(counter.length).to.be.equal(1); + }); + + it('should output a custom element tag that is _not_ wrapped in a

tag', function() { + expect((/

/).test(html)).to.be.false; + expect((/<\/x-counter><\/p>/).test(html)).to.be.false; + }); + + it('should output a heading tag from the custom element', function() { + const heading = dom.window.document.querySelectorAll('body h3'); + + expect(heading.length).to.be.equal(1); + expect(heading[0].textContent).to.be.equal('My Counter'); + }); + }); - expect(computedStyle.color).to.equal('red'); + describe('Custom header component', () => { + it('should output a custom app-header tag that', function() { + const header = dom.window.document.querySelectorAll('body app-header'); + + expect(header.length).to.be.equal(1); + }); + + it('should output a app-header element tag that is _not_ wrapped in a

tag', function() { + expect((/

/).test(html)).to.be.false; + expect((/<\/app-header><\/p>/).test(html)).to.be.false; + }); + + it('should output a tag with expected content', function() { + const header = dom.window.document.querySelectorAll('body app-header'); + + expect(header[0].textContent).to.be.equal('I am a header'); + }); }); }); }); diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md index 0657863d2..bda25c58b 100644 --- a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md @@ -7,4 +7,6 @@ imports: ## Counter Page Example - \ No newline at end of file + + +I am a header \ No newline at end of file From 721ceaf7e26815e1e643ca4dc3aab55d160a6fba Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sat, 17 Apr 2021 20:42:03 -0400 Subject: [PATCH 6/8] multihyphen support --- .../plugins/resource/plugin-standard-html.js | 2 +- ...ault.workspace-frontmatter-imports.spec.js | 25 ++++++++++++++----- .../src/pages/examples/counter.md | 4 ++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/plugins/resource/plugin-standard-html.js b/packages/cli/src/plugins/resource/plugin-standard-html.js index 336cc196d..6a45d85a4 100644 --- a/packages/cli/src/plugins/resource/plugin-standard-html.js +++ b/packages/cli/src/plugins/resource/plugin-standard-html.js @@ -309,7 +309,7 @@ class StandardHtmlResource extends ResourceInterface { body = getMetaContent(normalizedUrl, config, body); if (processedMarkdown) { - const wrappedCustomElementRegex = /

<[a-zA-Z]*-[a-zA-Z]*>(.*)<\/[a-zA-Z]*-[a-zA-Z]*><\/p>/g; + const wrappedCustomElementRegex = /

<[a-zA-Z]*-[a-zA-Z](.*)>(.*)<\/[a-zA-Z]*-[a-zA-Z](.*)><\/p>/g; const ceTest = wrappedCustomElementRegex.test(processedMarkdown.contents); if (ceTest) { diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js index fd5437b2a..98c8daa6e 100644 --- a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js @@ -77,14 +77,14 @@ describe('Build Greenwood With: ', function() { expect(heading[0].textContent).to.be.equal('Counter Page Example'); }); - describe('Counter component from front matter', () => { - it('should output a custom x-counter tag that', function() { + describe('Counter component from front matter', () => { + it('should output a custom tag that', function() { const counter = dom.window.document.querySelectorAll('body x-counter'); expect(counter.length).to.be.equal(1); }); - it('should output a custom element tag that is _not_ wrapped in a

tag', function() { + it('should output a custom tag that is _not_ wrapped in a

tag', function() { expect((/

/).test(html)).to.be.false; expect((/<\/x-counter><\/p>/).test(html)).to.be.false; }); @@ -97,14 +97,14 @@ describe('Build Greenwood With: ', function() { }); }); - describe('Custom header component', () => { - it('should output a custom app-header tag that', function() { + describe('Custom component', () => { + it('should output a custom tag that', function() { const header = dom.window.document.querySelectorAll('body app-header'); expect(header.length).to.be.equal(1); }); - it('should output a app-header element tag that is _not_ wrapped in a

tag', function() { + it('should output a tag that is _not_ wrapped in a

tag', function() { expect((/

/).test(html)).to.be.false; expect((/<\/app-header><\/p>/).test(html)).to.be.false; }); @@ -115,6 +115,19 @@ describe('Build Greenwood With: ', function() { expect(header[0].textContent).to.be.equal('I am a header'); }); }); + + describe('Custom Multihypen component', () => { + it('should output a custom tag that', function() { + const header = dom.window.document.querySelectorAll('body multihyphen-custom-element'); + + expect(header.length).to.be.equal(1); + }); + + it('should output a tag that is _not_ wrapped in a

tag', function() { + expect((/

/).test(html)).to.be.false; + expect((/<\/multihyphen-custom-element><\/p>/).test(html)).to.be.false; + }); + }); }); }); diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md index bda25c58b..c77fc15f7 100644 --- a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/src/pages/examples/counter.md @@ -9,4 +9,6 @@ imports: -I am a header \ No newline at end of file +I am a header + + \ No newline at end of file From 56ea4d5d2138e9b03ee55cd1a6a23c7e6dd0b531 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sat, 24 Apr 2021 10:45:36 -0400 Subject: [PATCH 7/8] remove example from website --- www/components/counter/counter.css | 3 --- www/components/counter/counter.js | 42 ------------------------------ www/pages/plugins/index.md | 5 ---- 3 files changed, 50 deletions(-) delete mode 100644 www/components/counter/counter.css delete mode 100644 www/components/counter/counter.js diff --git a/www/components/counter/counter.css b/www/components/counter/counter.css deleted file mode 100644 index e21e2c285..000000000 --- a/www/components/counter/counter.css +++ /dev/null @@ -1,3 +0,0 @@ -p { - color: red; -} \ No newline at end of file diff --git a/www/components/counter/counter.js b/www/components/counter/counter.js deleted file mode 100644 index ff31e6f07..000000000 --- a/www/components/counter/counter.js +++ /dev/null @@ -1,42 +0,0 @@ -const template = document.createElement('template'); - -template.innerHTML = ` - -

My Counter

- - - -`; - -class MyCounter extends HTMLElement { - constructor() { - super(); - this.count = 0; - this.attachShadow({ mode: 'open' }); - } - - async connectedCallback() { - this.shadowRoot.appendChild(template.content.cloneNode(true)); - this.shadowRoot.getElementById('inc').onclick = () => this.inc(); - this.shadowRoot.getElementById('dec').onclick = () => this.dec(); - this.update(); - } - - inc() { - this.update(++this.count); // eslint-disable-line - } - - dec() { - this.update(--this.count); // eslint-disable-line - } - - update(count) { - this.shadowRoot.getElementById('count').innerHTML = count || this.count; - } -} - -customElements.define('x-counter', MyCounter); \ No newline at end of file diff --git a/www/pages/plugins/index.md b/www/pages/plugins/index.md index 7e9539571..be1726b00 100644 --- a/www/pages/plugins/index.md +++ b/www/pages/plugins/index.md @@ -3,15 +3,10 @@ label: 'plugins' menu: navigation title: Plugins index: 4 -imports: - - /components/counter/counter.js - - /components/counter/counter.css --- ## Plugins - - At its core, Greenwood provides a CLI to drive all the development related workflows for a Greenwood project. The CLI aims to provide a simple interface for quickly and simply building sites from as little as markdown files. However, for more complex sites and use cases, there will come a need to extend the default functionality of Greenwood and the standard web primitives (e.g. HTML, CSS, JS) for additional capabilities like: From 24ec47163f3128ddb63e8f0f74d04217098fc32e Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sat, 24 Apr 2021 11:38:05 -0400 Subject: [PATCH 8/8] update to use gallinago Runner --- ...fault.workspace-frontmatter-imports.spec.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js index 98c8daa6e..70e13e0d8 100644 --- a/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js +++ b/packages/cli/test/cases/build.default.workspace-frontmatter-imports/build.default.workspace-frontmatter-imports.spec.js @@ -27,22 +27,28 @@ const fs = require('fs'); const glob = require('glob-promise'); const { JSDOM } = require('jsdom'); const path = require('path'); +const { getSetupFiles, getOutputTeardownFiles } = require('../../../../../test/utils'); const runSmokeTest = require('../../../../../test/smoke-test'); -const TestBed = require('../../../../../test/test-bed'); +const Runner = require('gallinago').Runner; describe('Build Greenwood With: ', function() { const LABEL = 'Default Greenwood Configuration and Workspace with Frontmatter Imports'; - let setup; + const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js'); + const outputPath = __dirname; + let runner; before(async function() { - setup = new TestBed(); - this.context = await setup.setupTestBed(__dirname); + this.context = { + publicDir: path.join(outputPath, 'public') + }; + runner = new Runner(); }); describe(LABEL, function() { before(async function() { - await setup.runGreenwoodCommand('build'); + await runner.setup(outputPath, getSetupFiles(outputPath)); + await runner.runCommand(cliPath, 'build'); }); runSmokeTest(['public', 'index'], LABEL); @@ -132,6 +138,6 @@ describe('Build Greenwood With: ', function() { }); after(function() { - setup.teardownTestBed(); + runner.teardown(getOutputTeardownFiles(outputPath)); }); }); \ No newline at end of file