Skip to content

Commit

Permalink
Merge pull request #247 from ckeditor/i/246
Browse files Browse the repository at this point in the history
Feature: Added `disableTwoWayDataBinding` property that allows disabling the two-way data binding. It increases performance when working with large documents. Closes #246.
  • Loading branch information
psmyrek committed Apr 17, 2023
2 parents 8d94b65 + 38e7de6 commit 928e2d2
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 2 deletions.
22 changes: 22 additions & 0 deletions demo/src/App.vue
Expand Up @@ -4,6 +4,7 @@
<ckeditor
v-model="data"
tag-name="textarea"
:disable-two-way-data-binding="isTwoWayDataBindingDisabled"
:editor="ClassicEditor"
:config="config"
:disabled="disabled"
Expand All @@ -18,6 +19,17 @@
{{ disabled ? 'Enable' : 'Disable' }} editor
</button>

<button @click="toggleTwoWayBinding">
{{ isTwoWayDataBindingDisabled ? 'Enable' : 'Disable' }} two way binding
</button>

<button
v-if="isTwoWayDataBindingDisabled"
@click="setEditorData"
>
Set editor data
</button>

<h2>Live editor data</h2>

<textarea v-model="data" />
Expand All @@ -33,11 +45,21 @@ const data = ref( '<p>Hello world!</p>' );
const disabled = ref( false );
const isTwoWayDataBindingDisabled = ref( false );
const config = reactive( {
toolbar: [ 'heading', '|', 'bold', 'italic' ]
} );
// Methods
function setEditorData() {
data.value = window.editor.getData();
}
function toggleTwoWayBinding() {
isTwoWayDataBindingDisabled.value = !isTwoWayDataBindingDisabled.value;
}
function toggleEditorDisabled() {
disabled.value = !disabled.value;
}
Expand Down
9 changes: 9 additions & 0 deletions dist/ckeditor.d.ts
Expand Up @@ -31,6 +31,10 @@ declare const _default: import("vue").DefineComponent<{
type: BooleanConstructor;
default: boolean;
};
disableTwoWayDataBinding: {
type: BooleanConstructor;
default: boolean;
};
}, unknown, CKEditorComponentData, {}, {
setUpEditorEvents(): void;
}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "ready" | "destroy" | "blur" | "focus" | "input")[], "update:modelValue" | "ready" | "destroy" | "blur" | "focus" | "input", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
Expand All @@ -56,6 +60,10 @@ declare const _default: import("vue").DefineComponent<{
type: BooleanConstructor;
default: boolean;
};
disableTwoWayDataBinding: {
type: BooleanConstructor;
default: boolean;
};
}>> & {
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
onReady?: ((...args: any[]) => any) | undefined;
Expand All @@ -68,5 +76,6 @@ declare const _default: import("vue").DefineComponent<{
disabled: boolean;
config: EditorConfig;
tagName: string;
disableTwoWayDataBinding: boolean;
}>;
export default _default;
2 changes: 1 addition & 1 deletion dist/ckeditor.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/ckeditor.js.map

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions dist/plugin.d.ts
Expand Up @@ -34,6 +34,10 @@ declare const _default: {
type: BooleanConstructor;
default: boolean;
};
disableTwoWayDataBinding: {
type: BooleanConstructor;
default: boolean;
};
}, unknown, import("./ckeditor").CKEditorComponentData, {}, {
setUpEditorEvents(): void;
}, Vue.ComponentOptionsMixin, Vue.ComponentOptionsMixin, ("update:modelValue" | "ready" | "destroy" | "blur" | "focus" | "input")[], "update:modelValue" | "ready" | "destroy" | "blur" | "focus" | "input", Vue.VNodeProps & Vue.AllowedComponentProps & Vue.ComponentCustomProps, Readonly<Vue.ExtractPropTypes<{
Expand All @@ -59,6 +63,10 @@ declare const _default: {
type: BooleanConstructor;
default: boolean;
};
disableTwoWayDataBinding: {
type: BooleanConstructor;
default: boolean;
};
}>> & {
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
onReady?: ((...args: any[]) => any) | undefined;
Expand All @@ -71,6 +79,7 @@ declare const _default: {
disabled: boolean;
config: import("@ckeditor/ckeditor5-core").EditorConfig;
tagName: string;
disableTwoWayDataBinding: boolean;
}>;
};
export default _default;
Expand Down
8 changes: 8 additions & 0 deletions src/ckeditor.ts
Expand Up @@ -45,6 +45,10 @@ export default defineComponent( {
disabled: {
type: Boolean,
default: false
},
disableTwoWayDataBinding: {
type: Boolean,
default: false
}
},

Expand Down Expand Up @@ -174,6 +178,10 @@ export default defineComponent( {
// is set twice in a time span shorter than the debounce time.
// See https://github.com/ckeditor/ckeditor5-vue/issues/149.
const emitDebouncedInputEvent = debounce( evt => {
if ( this.disableTwoWayDataBinding ) {
return;
}

// Cache the last editor data. This kind of data is a result of typing,
// editor command execution, collaborative changes to the document, etc.
// This data is compared when the component modelValue changes in a 2-way binding.
Expand Down
38 changes: 38 additions & 0 deletions tests/ckeditor.js
Expand Up @@ -295,6 +295,44 @@ describe( 'CKEditor Component', () => {
} );
} );

describe( '#disableTwoWayDataBinding', () => {
it( 'should set disableTwoWayDataBinding to false by default', async () => {
const { wrapper, vm } = mountComponent();

await nextTick();

expect( vm.disableTwoWayDataBinding ).to.equal( false );

wrapper.unmount();
} );

it( 'should not update #modelValue when disableTwoWayDataBinding is true', async () => {
const { wrapper, vm } = mountComponent( { disableTwoWayDataBinding: true } );

sandbox.stub( ModelDocument.prototype, 'on' );

await nextTick();

sandbox.stub( vm.instance.data, 'get' ).returns( 'foo' );

const on = vm.instance.model.document.on;
const evtStub = {};

expect( on.calledOnce ).to.be.true;
expect( on.firstCall.args[ 0 ] ).to.equal( 'change:data' );

expect( wrapper.emitted().input ).to.be.undefined;

on.firstCall.args[ 1 ]( evtStub );

await timeout( 350 );

expect( wrapper.emitted().input ).to.be.undefined;

wrapper.unmount();
} );
} );

it( '#instance should be defined', async () => {
const { wrapper, vm } = mountComponent();

Expand Down

0 comments on commit 928e2d2

Please sign in to comment.