From e5cad9ca476ab5f3807c2ef0afb0a7f10c52995b Mon Sep 17 00:00:00 2001 From: Jen Weber Date: Fri, 1 Nov 2019 12:23:42 -0400 Subject: [PATCH] feat(read-only): can create editor as read-only --- README.md | 5 + addon/components/code-editor.ts | 6 +- editor/editor.ts | 6 +- .../components/code-editor-test.ts | 93 +++++++++++++------ 4 files changed, 77 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index dca58d5a..b3640c5d 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,11 @@ export default class Application extends Controller { }} ``` +**Additional options:** + +To create a read-only editor, pass `readOnly=true` to the `code-editor` component. +`readOnly` defaults to false. + ## Contributing ### Installation diff --git a/addon/components/code-editor.ts b/addon/components/code-editor.ts index f1abb12c..55a55092 100644 --- a/addon/components/code-editor.ts +++ b/addon/components/code-editor.ts @@ -15,6 +15,7 @@ export default class CodeEditor extends Component { public language?: string; public _conn!: IChildConnectionObject; public theme: 'vs-dark' | 'vs-light' = 'vs-dark'; // TODO: proper default value + public readOnly?: boolean; public onChange?: (v: string) => any; public onKeyCommand?: (evt: CodeEditorKeyCommand) => any; public onReady?: (editor: mon.editor.IStandaloneCodeEditor) => any; @@ -67,11 +68,12 @@ export default class CodeEditor extends Component { url: '/ember-monaco/frame.html' }); this._conn.promise.then(frameApi => { - const { code, theme, language } = this; + const { code, theme, language, readOnly } = this; frameApi.setupEditor({ language, theme, - value: code + value: code, + readOnly }); }); } diff --git a/editor/editor.ts b/editor/editor.ts index 0eba96cd..93271220 100644 --- a/editor/editor.ts +++ b/editor/editor.ts @@ -70,6 +70,7 @@ export function setupEditor(cfg: { theme: string; value: string; language: 'typescript' | 'javascript'; + readOnly?: boolean; }) { require(['vs/editor/editor.main'], async () => { if (typeof monaco !== 'undefined') { @@ -77,11 +78,12 @@ export function setupEditor(cfg: { if (!wrapper) { throw new Error('No wrapper found'); } - const { language, theme, value } = cfg; + const { language, theme, value, readOnly=false } = cfg; const ed = (editor = window.editor = monaco.editor.create(wrapper, { language, theme, - value + value, + readOnly })); const client = await conn.promise; ed.onDidChangeModelContent(event => { diff --git a/tests/integration/components/code-editor-test.ts b/tests/integration/components/code-editor-test.ts index fe1ddc36..ad0b93a8 100644 --- a/tests/integration/components/code-editor-test.ts +++ b/tests/integration/components/code-editor-test.ts @@ -3,6 +3,39 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, waitUntil, settled } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; +const setUpEditor = async function() { + await waitUntil(() => { + const frame = document.querySelector('iframe'); + if (!frame) return false; + const frameWin = frame.contentWindow; + if (!frameWin) return false; + return frameWin.document; + }); + + await waitUntil( + () => { + const frame = document.querySelector('iframe'); + if (!frame) throw new Error('No frame'); + const frameWin = frame.contentWindow; + if (!frameWin) throw new Error('No frame window'); + const frameDoc = frameWin.document; + if (!frameDoc) throw new Error('No frame document'); + const x = frameDoc.querySelector('.monaco-editor'); + if (!x) return false; + return x.innerText.trim(); + }, + { + timeout: 60000, + timeoutMessage: 'Waiting for line content' + } + ); + const frame = document.querySelector('iframe'); + if (!frame) throw new Error('No frame'); + const frameWin = frame.contentWindow; + if (!frameWin) throw new Error('No frame window'); + return frameWin +} + module('Integration | Component | code-editor', function(hooks) { setupRenderingTest(hooks); @@ -15,35 +48,8 @@ module('Integration | Component | code-editor', function(hooks) { language="typescript" }}`); await settled(); - await waitUntil(() => { - const frame = document.querySelector('iframe'); - if (!frame) return false; - const frameWin = frame.contentWindow; - if (!frameWin) return false; - return frameWin.document; - }); - - await waitUntil( - () => { - const frame = document.querySelector('iframe'); - if (!frame) throw new Error('No frame'); - const frameWin = frame.contentWindow; - if (!frameWin) throw new Error('No frame window'); - const frameDoc = frameWin.document; - const x = frameDoc.querySelector('.monaco-editor'); - if (!x) return false; - return x.innerText.trim(); - }, - { - timeout: 60000, - timeoutMessage: 'Waiting for line content' - } - ); - const frame = document.querySelector('iframe'); - if (!frame) throw new Error('No frame'); - const frameWin = frame.contentWindow; - if (!frameWin) throw new Error('No frame window'); - const frameDoc = frameWin.document; + const frameWin = await setUpEditor(); + const frameDoc = frameWin.document const linesContent = frameDoc.querySelector( '.lines-content' ); @@ -53,4 +59,33 @@ module('Integration | Component | code-editor', function(hooks) { "let x: string = 'foo';" ); }); + + test('readOnly mode works', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs`{{code-editor + code="let x: string = 'foo';" + language="typescript" + readOnly=true +}}`); + await settled(); + const frameWin = await setUpEditor(); + const isReadOnly = (frameWin).editor.getConfiguration().readOnly + assert.equal(isReadOnly, true); + }); + + test('readOnly defeaults to false', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs`{{code-editor + code="let x: string = 'foo';" + language="typescript" +}}`); + await settled(); + const frameWin = await setUpEditor(); + const isReadOnly = (frameWin).editor.getConfiguration().readOnly + assert.equal(isReadOnly, false); + }); });