@tinymce/tinymce-react
Advanced tools
Comparing version 3.3.1 to 3.3.2
@@ -0,1 +1,4 @@ | ||
## 3.3.2 (2019-08-29) | ||
* Fixed an issue that caused `onEditorChange` to fire multiple times | ||
## 3.3.1 (2019-08-16) | ||
@@ -2,0 +5,0 @@ * Changed referrer policy to origin to allow cloud caching |
@@ -102,5 +102,8 @@ "use strict"; | ||
editor.on('change keyup setcontent', function (e) { | ||
_this.currentContent = editor.getContent(); | ||
if (Utils_1.isFunction(_this.props.onEditorChange)) { | ||
_this.props.onEditorChange(_this.currentContent, editor); | ||
var newContent = editor.getContent(); | ||
if (newContent !== _this.currentContent) { | ||
_this.currentContent = newContent; | ||
if (Utils_1.isFunction(_this.props.onEditorChange)) { | ||
_this.props.onEditorChange(_this.currentContent, editor); | ||
} | ||
} | ||
@@ -107,0 +110,0 @@ }); |
import { Chain } from '@ephox/agar'; | ||
declare const EventState: () => { | ||
cEach: (name: string, assertState: (args: any[]) => void) => Chain<any, any>; | ||
createHandler: (name: string) => (...args: any[]) => void; | ||
get: (name: string) => any; | ||
import { EventHandler } from 'src/main/ts/Events'; | ||
interface EventHandlerArgs<T> { | ||
editorEvent: T; | ||
editor: any; | ||
} | ||
declare const EventStore: () => { | ||
cEach: (name: string, assertState: (state: EventHandlerArgs<any>[]) => void) => Chain<any, any>; | ||
createHandler: <T = any>(name: string) => EventHandler<T>; | ||
cClearState: Chain<{}, {}>; | ||
}; | ||
export { EventState }; | ||
export { EventStore }; |
@@ -16,17 +16,14 @@ "use strict"; | ||
var katamari_1 = require("@ephox/katamari"); | ||
var EventState = function () { | ||
var EventStore = function () { | ||
var state = katamari_1.Cell({}); | ||
var createHandler = function (name) { | ||
return function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return function (event, editor) { | ||
var _a; | ||
state.set(__assign({}, state.get(), (_a = {}, _a[name] = args, _a))); | ||
var oldState = state.get(); | ||
var eventHandlerState = katamari_1.Obj.get(oldState, name) | ||
.getOr([]) | ||
.concat([{ editorEvent: event, editor: editor }]); | ||
state.set(__assign({}, oldState, (_a = {}, _a[name] = eventHandlerState, _a))); | ||
}; | ||
}; | ||
var get = function (name) { | ||
return state.get()[name]; | ||
}; | ||
var cEach = function (name, assertState) { | ||
@@ -46,6 +43,5 @@ return agar_1.Chain.fromChains([ | ||
createHandler: createHandler, | ||
get: get, | ||
cClearState: cClearState | ||
}; | ||
}; | ||
exports.EventState = EventState; | ||
exports.EventStore = EventStore; |
@@ -13,61 +13,61 @@ "use strict"; | ||
}; | ||
var eventState = TestHelpers_1.EventState(); | ||
var eventStore = TestHelpers_1.EventStore(); | ||
agar_1.Pipeline.async({}, [ | ||
agar_1.Logger.t('Assert structure of tinymce and tinymce-react events', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({ | ||
onEditorChange: eventState.createHandler('onEditorChange'), | ||
onSetContent: eventState.createHandler('onSetContent') | ||
onEditorChange: eventStore.createHandler('onEditorChange'), | ||
onSetContent: eventStore.createHandler('onSetContent') | ||
}), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cSetContent('<p>Initial Content</p>')), | ||
// tinymce native event | ||
eventState.cEach('onSetContent', function (args) { return agar_1.Assertions.assertEq('First arg should be event from Tiny', '<p>Initial Content</p>', args[0].content); }), | ||
eventState.cEach('onSetContent', function (args) { return agar_1.Assertions.assertEq('Second arg should be editor', true, isEditor(args[1])); }), | ||
eventStore.cEach('onSetContent', function (integrationEvents) { | ||
agar_1.Assertions.assertEq('First arg should be event from Tiny', '<p>Initial Content</p>', integrationEvents[0].editorEvent.content); | ||
agar_1.Assertions.assertEq('Second arg should be editor', true, isEditor(integrationEvents[0].editor)); | ||
}), | ||
// tinymce-react unique event | ||
eventState.cEach('onEditorChange', function (args) { return agar_1.Assertions.assertEq('First arg should be new content', '<p>Initial Content</p>', args[0]); }), | ||
eventState.cEach('onEditorChange', function (args) { return agar_1.Assertions.assertEq('Second arg should be editor', true, isEditor(args[1])); }), | ||
eventState.cClearState, | ||
eventStore.cEach('onEditorChange', function (integrationEvents) { | ||
agar_1.Assertions.assertEq('First arg should be new content', '<p>Initial Content</p>', integrationEvents[0].editorEvent); | ||
agar_1.Assertions.assertEq('Second arg should be editor', true, isEditor(integrationEvents[0].editor)); | ||
}), | ||
eventStore.cClearState, | ||
Loader_1.cRemove | ||
])), | ||
agar_1.Logger.t('onEditorChange should only fire when the editors content changes', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({ | ||
onEditorChange: eventStore.createHandler('onEditorChange') | ||
}), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cSetContent('<p>Initial Content</p>')), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cSetContent('<p>Initial Content</p>')), | ||
eventStore.cEach('onEditorChange', function (integrationEvents) { | ||
agar_1.Assertions.assertEq('onEditorChange should have been fired once', 1, integrationEvents.length); | ||
}), | ||
eventStore.cClearState, | ||
Loader_1.cRemove | ||
])), | ||
agar_1.Logger.t('Should be able to register an event handler after initial render', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({ initialValue: '<p>Initial Content</p>' }), | ||
Loader_1.cReRender({ onSetContent: eventState.createHandler('onSetContent') }), | ||
Loader_1.cReRender({ onSetContent: eventStore.createHandler('onSetContent') }), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cAssertContent('<p>Initial Content</p>')), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cSetContent('<p>New Content</p>')), | ||
eventState.cEach('onSetContent', function (args) { return agar_1.Assertions.assertEq('Should have bound handler, hence new content', '<p>New Content</p>', args[0].content); }), | ||
eventState.cClearState, | ||
eventStore.cEach('onSetContent', function (integrationEvents) { | ||
agar_1.Assertions.assertEq('Should have bound handler, hence new content', '<p>New Content</p>', integrationEvents[0].editorEvent.content); | ||
}), | ||
eventStore.cClearState, | ||
Loader_1.cRemove | ||
])), | ||
agar_1.Logger.t('Providing a new event handler and re-rendering should unbind old handler and bind new handler', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({ onSetContent: eventState.createHandler('InitialHandler') }), | ||
Loader_1.cRender({ onSetContent: eventStore.createHandler('InitialHandler') }), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cSetContent('<p>Initial Content</p>')), | ||
Loader_1.cReRender({ onSetContent: eventState.createHandler('NewHandler') }), | ||
Loader_1.cReRender({ onSetContent: eventStore.createHandler('NewHandler') }), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cSetContent('<p>New Content</p>')), | ||
eventState.cEach('InitialHandler', function (args) { | ||
return agar_1.Assertions.assertEq('Initial handler should have been unbound, hence initial content', '<p>Initial Content</p>', args[0].content); | ||
eventStore.cEach('InitialHandler', function (integrationEvents) { | ||
agar_1.Assertions.assertEq('Initial handler should have been unbound, hence initial content', '<p>Initial Content</p>', integrationEvents[0].editorEvent.content); | ||
}), | ||
eventState.cEach('NewHandler', function (args) { | ||
return agar_1.Assertions.assertEq('New handler should have been bound, hence new content', '<p>New Content</p>', args[0].content); | ||
eventStore.cEach('NewHandler', function (integrationEvents) { | ||
agar_1.Assertions.assertEq('New handler should have been bound, hence new content', '<p>New Content</p>', integrationEvents[0].editorEvent.content); | ||
}), | ||
eventState.cClearState, | ||
eventStore.cClearState, | ||
Loader_1.cRemove | ||
])), | ||
agar_1.Logger.t('Test value prop', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({ value: '<p>Initial Value</p>' }), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cAssertContent('<p>Initial Value</p>')), | ||
Loader_1.cReRender({ value: '<p>New Value</p>' }), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cAssertContent('<p>New Value</p>')), | ||
Loader_1.cRemove | ||
])), | ||
agar_1.Logger.t('Test disabled prop', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({}), | ||
Loader_1.cEditor(agar_1.Chain.op(function (editor) { | ||
agar_1.Assertions.assertEq('Should be design mode', 'design', editor.mode.get()); | ||
})), | ||
Loader_1.cReRender({ disabled: true }), | ||
Loader_1.cEditor(agar_1.Chain.op(function (editor) { | ||
agar_1.Assertions.assertEq('Should be readonly mode', 'readonly', editor.mode.get()); | ||
})), | ||
Loader_1.cRemove | ||
])) | ||
], success, failure); | ||
}); |
@@ -6,2 +6,3 @@ "use strict"; | ||
var Loader_1 = require("../alien/Loader"); | ||
var mcagar_1 = require("@ephox/mcagar"); | ||
bedrock_1.UnitTest.asynctest('Editor.test', function (success, failure) { | ||
@@ -69,3 +70,21 @@ var cAssertProperty = function (propName, expected) { | ||
])), | ||
agar_1.Logger.t('Value prop should propagate changes to editor', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({ value: '<p>Initial Value</p>' }), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cAssertContent('<p>Initial Value</p>')), | ||
Loader_1.cReRender({ value: '<p>New Value</p>' }), | ||
Loader_1.cEditor(mcagar_1.ApiChains.cAssertContent('<p>New Value</p>')), | ||
Loader_1.cRemove | ||
])), | ||
agar_1.Logger.t('Disabled prop should disable editor', agar_1.Chain.asStep({}, [ | ||
Loader_1.cRender({}), | ||
Loader_1.cEditor(agar_1.Chain.op(function (editor) { | ||
agar_1.Assertions.assertEq('Should be design mode', 'design', editor.mode.get()); | ||
})), | ||
Loader_1.cReRender({ disabled: true }), | ||
Loader_1.cEditor(agar_1.Chain.op(function (editor) { | ||
agar_1.Assertions.assertEq('Should be readonly mode', 'readonly', editor.mode.get()); | ||
})), | ||
Loader_1.cRemove | ||
])) | ||
], success, failure); | ||
}); |
@@ -100,5 +100,8 @@ /** | ||
editor.on('change keyup setcontent', function (e) { | ||
_this.currentContent = editor.getContent(); | ||
if (isFunction(_this.props.onEditorChange)) { | ||
_this.props.onEditorChange(_this.currentContent, editor); | ||
var newContent = editor.getContent(); | ||
if (newContent !== _this.currentContent) { | ||
_this.currentContent = newContent; | ||
if (isFunction(_this.props.onEditorChange)) { | ||
_this.props.onEditorChange(_this.currentContent, editor); | ||
} | ||
} | ||
@@ -105,0 +108,0 @@ }); |
import { Chain } from '@ephox/agar'; | ||
declare const EventState: () => { | ||
cEach: (name: string, assertState: (args: any[]) => void) => Chain<any, any>; | ||
createHandler: (name: string) => (...args: any[]) => void; | ||
get: (name: string) => any; | ||
import { EventHandler } from 'src/main/ts/Events'; | ||
interface EventHandlerArgs<T> { | ||
editorEvent: T; | ||
editor: any; | ||
} | ||
declare const EventStore: () => { | ||
cEach: (name: string, assertState: (state: EventHandlerArgs<any>[]) => void) => Chain<any, any>; | ||
createHandler: <T = any>(name: string) => EventHandler<T>; | ||
cClearState: Chain<{}, {}>; | ||
}; | ||
export { EventState }; | ||
export { EventStore }; |
@@ -13,18 +13,15 @@ var __assign = (this && this.__assign) || function () { | ||
import { Chain, Assertions } from '@ephox/agar'; | ||
import { Cell } from '@ephox/katamari'; | ||
var EventState = function () { | ||
import { Cell, Obj } from '@ephox/katamari'; | ||
var EventStore = function () { | ||
var state = Cell({}); | ||
var createHandler = function (name) { | ||
return function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return function (event, editor) { | ||
var _a; | ||
state.set(__assign({}, state.get(), (_a = {}, _a[name] = args, _a))); | ||
var oldState = state.get(); | ||
var eventHandlerState = Obj.get(oldState, name) | ||
.getOr([]) | ||
.concat([{ editorEvent: event, editor: editor }]); | ||
state.set(__assign({}, oldState, (_a = {}, _a[name] = eventHandlerState, _a))); | ||
}; | ||
}; | ||
var get = function (name) { | ||
return state.get()[name]; | ||
}; | ||
var cEach = function (name, assertState) { | ||
@@ -44,6 +41,5 @@ return Chain.fromChains([ | ||
createHandler: createHandler, | ||
get: get, | ||
cClearState: cClearState | ||
}; | ||
}; | ||
export { EventState }; | ||
export { EventStore }; |
@@ -6,3 +6,3 @@ import { Assertions, Chain, Logger, Pipeline } from '@ephox/agar'; | ||
import { getTinymce } from '../../../main/ts/TinyMCE'; | ||
import { EventState } from '../alien/TestHelpers'; | ||
import { EventStore } from '../alien/TestHelpers'; | ||
UnitTest.asynctest('Editor.test', function (success, failure) { | ||
@@ -12,61 +12,61 @@ var isEditor = function (val) { | ||
}; | ||
var eventState = EventState(); | ||
var eventStore = EventStore(); | ||
Pipeline.async({}, [ | ||
Logger.t('Assert structure of tinymce and tinymce-react events', Chain.asStep({}, [ | ||
cRender({ | ||
onEditorChange: eventState.createHandler('onEditorChange'), | ||
onSetContent: eventState.createHandler('onSetContent') | ||
onEditorChange: eventStore.createHandler('onEditorChange'), | ||
onSetContent: eventStore.createHandler('onSetContent') | ||
}), | ||
cEditor(ApiChains.cSetContent('<p>Initial Content</p>')), | ||
// tinymce native event | ||
eventState.cEach('onSetContent', function (args) { return Assertions.assertEq('First arg should be event from Tiny', '<p>Initial Content</p>', args[0].content); }), | ||
eventState.cEach('onSetContent', function (args) { return Assertions.assertEq('Second arg should be editor', true, isEditor(args[1])); }), | ||
eventStore.cEach('onSetContent', function (integrationEvents) { | ||
Assertions.assertEq('First arg should be event from Tiny', '<p>Initial Content</p>', integrationEvents[0].editorEvent.content); | ||
Assertions.assertEq('Second arg should be editor', true, isEditor(integrationEvents[0].editor)); | ||
}), | ||
// tinymce-react unique event | ||
eventState.cEach('onEditorChange', function (args) { return Assertions.assertEq('First arg should be new content', '<p>Initial Content</p>', args[0]); }), | ||
eventState.cEach('onEditorChange', function (args) { return Assertions.assertEq('Second arg should be editor', true, isEditor(args[1])); }), | ||
eventState.cClearState, | ||
eventStore.cEach('onEditorChange', function (integrationEvents) { | ||
Assertions.assertEq('First arg should be new content', '<p>Initial Content</p>', integrationEvents[0].editorEvent); | ||
Assertions.assertEq('Second arg should be editor', true, isEditor(integrationEvents[0].editor)); | ||
}), | ||
eventStore.cClearState, | ||
cRemove | ||
])), | ||
Logger.t('onEditorChange should only fire when the editors content changes', Chain.asStep({}, [ | ||
cRender({ | ||
onEditorChange: eventStore.createHandler('onEditorChange') | ||
}), | ||
cEditor(ApiChains.cSetContent('<p>Initial Content</p>')), | ||
cEditor(ApiChains.cSetContent('<p>Initial Content</p>')), | ||
eventStore.cEach('onEditorChange', function (integrationEvents) { | ||
Assertions.assertEq('onEditorChange should have been fired once', 1, integrationEvents.length); | ||
}), | ||
eventStore.cClearState, | ||
cRemove | ||
])), | ||
Logger.t('Should be able to register an event handler after initial render', Chain.asStep({}, [ | ||
cRender({ initialValue: '<p>Initial Content</p>' }), | ||
cReRender({ onSetContent: eventState.createHandler('onSetContent') }), | ||
cReRender({ onSetContent: eventStore.createHandler('onSetContent') }), | ||
cEditor(ApiChains.cAssertContent('<p>Initial Content</p>')), | ||
cEditor(ApiChains.cSetContent('<p>New Content</p>')), | ||
eventState.cEach('onSetContent', function (args) { return Assertions.assertEq('Should have bound handler, hence new content', '<p>New Content</p>', args[0].content); }), | ||
eventState.cClearState, | ||
eventStore.cEach('onSetContent', function (integrationEvents) { | ||
Assertions.assertEq('Should have bound handler, hence new content', '<p>New Content</p>', integrationEvents[0].editorEvent.content); | ||
}), | ||
eventStore.cClearState, | ||
cRemove | ||
])), | ||
Logger.t('Providing a new event handler and re-rendering should unbind old handler and bind new handler', Chain.asStep({}, [ | ||
cRender({ onSetContent: eventState.createHandler('InitialHandler') }), | ||
cRender({ onSetContent: eventStore.createHandler('InitialHandler') }), | ||
cEditor(ApiChains.cSetContent('<p>Initial Content</p>')), | ||
cReRender({ onSetContent: eventState.createHandler('NewHandler') }), | ||
cReRender({ onSetContent: eventStore.createHandler('NewHandler') }), | ||
cEditor(ApiChains.cSetContent('<p>New Content</p>')), | ||
eventState.cEach('InitialHandler', function (args) { | ||
return Assertions.assertEq('Initial handler should have been unbound, hence initial content', '<p>Initial Content</p>', args[0].content); | ||
eventStore.cEach('InitialHandler', function (integrationEvents) { | ||
Assertions.assertEq('Initial handler should have been unbound, hence initial content', '<p>Initial Content</p>', integrationEvents[0].editorEvent.content); | ||
}), | ||
eventState.cEach('NewHandler', function (args) { | ||
return Assertions.assertEq('New handler should have been bound, hence new content', '<p>New Content</p>', args[0].content); | ||
eventStore.cEach('NewHandler', function (integrationEvents) { | ||
Assertions.assertEq('New handler should have been bound, hence new content', '<p>New Content</p>', integrationEvents[0].editorEvent.content); | ||
}), | ||
eventState.cClearState, | ||
eventStore.cClearState, | ||
cRemove | ||
])), | ||
Logger.t('Test value prop', Chain.asStep({}, [ | ||
cRender({ value: '<p>Initial Value</p>' }), | ||
cEditor(ApiChains.cAssertContent('<p>Initial Value</p>')), | ||
cReRender({ value: '<p>New Value</p>' }), | ||
cEditor(ApiChains.cAssertContent('<p>New Value</p>')), | ||
cRemove | ||
])), | ||
Logger.t('Test disabled prop', Chain.asStep({}, [ | ||
cRender({}), | ||
cEditor(Chain.op(function (editor) { | ||
Assertions.assertEq('Should be design mode', 'design', editor.mode.get()); | ||
})), | ||
cReRender({ disabled: true }), | ||
cEditor(Chain.op(function (editor) { | ||
Assertions.assertEq('Should be readonly mode', 'readonly', editor.mode.get()); | ||
})), | ||
cRemove | ||
])) | ||
], success, failure); | ||
}); |
import { Assertions, Chain, GeneralSteps, Logger, Pipeline } from '@ephox/agar'; | ||
import { UnitTest } from '@ephox/bedrock'; | ||
import { cRemove, cRender, cDOMNode } from '../alien/Loader'; | ||
import { cRemove, cRender, cDOMNode, cEditor, cReRender } from '../alien/Loader'; | ||
import { ApiChains } from '@ephox/mcagar'; | ||
UnitTest.asynctest('Editor.test', function (success, failure) { | ||
@@ -66,3 +67,21 @@ var cAssertProperty = function (propName, expected) { | ||
])), | ||
Logger.t('Value prop should propagate changes to editor', Chain.asStep({}, [ | ||
cRender({ value: '<p>Initial Value</p>' }), | ||
cEditor(ApiChains.cAssertContent('<p>Initial Value</p>')), | ||
cReRender({ value: '<p>New Value</p>' }), | ||
cEditor(ApiChains.cAssertContent('<p>New Value</p>')), | ||
cRemove | ||
])), | ||
Logger.t('Disabled prop should disable editor', Chain.asStep({}, [ | ||
cRender({}), | ||
cEditor(Chain.op(function (editor) { | ||
Assertions.assertEq('Should be design mode', 'design', editor.mode.get()); | ||
})), | ||
cReRender({ disabled: true }), | ||
cEditor(Chain.op(function (editor) { | ||
Assertions.assertEq('Should be readonly mode', 'readonly', editor.mode.get()); | ||
})), | ||
cRemove | ||
])) | ||
], success, failure); | ||
}); |
{ | ||
"name": "@tinymce/tinymce-react", | ||
"version": "3.3.1", | ||
"version": "3.3.2", | ||
"description": "Official TinyMCE React Component", | ||
@@ -5,0 +5,0 @@ "repository": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
80954
1701