Disable Mutation Observer while saving (#563)

* Disable Mutation Observer while saving

* rm image
This commit is contained in:
Peter Savchenko 2018-12-20 23:47:27 +03:00 committed by GitHub
parent 41ae41cda7
commit 71315d902a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 21 deletions

12
dist/codex-editor.js vendored

File diff suppressed because one or more lines are too long

View file

@ -43,7 +43,6 @@
--> -->
<script src="./tools/header/dist/bundle.js"></script><!-- Header --> <script src="./tools/header/dist/bundle.js"></script><!-- Header -->
<script src="./tools/simple-image/dist/bundle.js"></script><!-- Image --> <script src="./tools/simple-image/dist/bundle.js"></script><!-- Image -->
<script src="./tools/image/dist/bundle.js"></script><!-- Image -->
<script src="./tools/delimiter/dist/bundle.js"></script><!-- Delimiter --> <script src="./tools/delimiter/dist/bundle.js"></script><!-- Delimiter -->
<script src="./tools/list/dist/bundle.js"></script><!-- List --> <script src="./tools/list/dist/bundle.js"></script><!-- List -->
<script src="./tools/quote/dist/bundle.js"></script><!-- Quote --> <script src="./tools/quote/dist/bundle.js"></script><!-- Quote -->
@ -93,13 +92,7 @@
* Or pass class directly without any configuration * Or pass class directly without any configuration
*/ */
image: { image: {
class: ImageTool, class: SimpleImage,
config: {
endpoints: {
byFile: 'http://localhost:8008/uploadFile',
byUrl: 'http://localhost:8008/fetchUrl',
},
},
inlineToolbar: ['link'], inlineToolbar: ['link'],
}, },
@ -235,9 +228,7 @@
{ {
type: 'image', type: 'image',
data: { data: {
file: { url: 'https://ifmo.su/upload/redactor_images/o_e48549d1855c7fc1807308dd14990126.jpg',
url: 'https://ifmo.su/upload/redactor_images/o_e48549d1855c7fc1807308dd14990126.jpg',
},
caption: '', caption: '',
stretched: false, stretched: false,
withBorder: true, withBorder: true,

View file

@ -1,6 +1,6 @@
{ {
"name": "codex.editor", "name": "codex.editor",
"version": "2.7.14", "version": "2.7.15",
"description": "CodeX Editor. Native JS, based on API and Open Source", "description": "CodeX Editor. Native JS, based on API and Open Source",
"main": "dist/codex-editor.js", "main": "dist/codex-editor.js",
"types": "./types/index.d.ts", "types": "./types/index.d.ts",

View file

@ -22,6 +22,11 @@ export default class ModificationsObserver extends Module {
*/ */
private observer: MutationObserver; private observer: MutationObserver;
/**
* Allows to temporary disable mutations handling
*/
private disabled: boolean;
/** /**
* Used to prevent several mutation callback execution * Used to prevent several mutation callback execution
* @type {Function} * @type {Function}
@ -52,6 +57,22 @@ export default class ModificationsObserver extends Module {
}, 1000); }, 1000);
} }
/**
* Allows to disable observer,
* for example when Editor wants to stealthy mutate DOM
*/
public disable() {
this.disabled = true;
}
/**
* Enables mutation handling
* Should be called after .disable()
*/
public enable() {
this.disabled = false;
}
/** /**
* setObserver * setObserver
* *
@ -80,9 +101,16 @@ export default class ModificationsObserver extends Module {
* @param observer * @param observer
*/ */
private mutationHandler(mutationList, observer) { private mutationHandler(mutationList, observer) {
/**
* Skip mutations in stealth mode
*/
if (this.disabled) {
return;
}
/** /**
* We divide two Mutation types: * We divide two Mutation types:
* 1) mutations that concerns client changes. For example, settings changes, symbol added, deletion, insertions and so on * 1) mutations that concerns client changes: settings changes, symbol added, deletion, insertions and so on
* 2) functional changes. On each client actions we set functional identifiers to interact with user * 2) functional changes. On each client actions we set functional identifiers to interact with user
*/ */
let contentMutated = false; let contentMutated = false;

View file

@ -24,15 +24,23 @@ export default class Saver extends Module {
* @return {OutputData} * @return {OutputData}
*/ */
public async save(): Promise<OutputData> { public async save(): Promise<OutputData> {
const blocks = this.Editor.BlockManager.blocks, const {BlockManager, Sanitizer, ModificationsObserver} = this.Editor;
const blocks = BlockManager.blocks,
chainData = []; chainData = [];
/**
* Disable modifications observe while saving
*/
ModificationsObserver.disable();
blocks.forEach((block: Block) => { blocks.forEach((block: Block) => {
chainData.push(block.save()); chainData.push(block.save());
}); });
const extractedData = await Promise.all(chainData); const extractedData = await Promise.all(chainData);
const sanitizedData = await this.Editor.Sanitizer.sanitizeBlocks(extractedData); const sanitizedData = await Sanitizer.sanitizeBlocks(extractedData);
ModificationsObserver.enable();
return this.makeOutput(sanitizedData); return this.makeOutput(sanitizedData);
} }