From 4b9d9615898a84e263ed0a0b900ef138b93cd412 Mon Sep 17 00:00:00 2001 From: Bago Date: Fri, 10 Jun 2022 10:29:00 +0200 Subject: [PATCH] Update model importer function to deal with model "updating" When mosaico is loaded it also support updating an obsolete model to a newer template with additional properties, but "viewModel.importJSON" throw an error when the model is different from what is expected. Now viewModel.importJSON uses "checkModel" to update it when needed. See #279 --- src/js/template-loader.js | 66 ++++++++++++++++++++++----------------- src/js/viewmodel.js | 6 ++-- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/js/template-loader.js b/src/js/template-loader.js index 5235a2af5..4649c0267 100644 --- a/src/js/template-loader.js +++ b/src/js/template-loader.js @@ -160,6 +160,39 @@ var templateLoader = function(performanceAwareCaller, templateFileName, template }); }; +var checkAndImportNewContentModel = function(performanceAwareCaller, content, allBlocks, newModel) { + var compatibleTemplate = true; + + // we run a basic compatibility check between the content-model we expect and the initialization model + var checkModelRes = performanceAwareCaller('checkModel', templateConverter.checkModel.bind(undefined, content._plainObject(), allBlocks, newModel)); + // if checkModelRes is 1 then the model is not fully compatible but we fixed it + if (checkModelRes == 2) { + console.error("Model and template seems to be incompatible!", content._plainObject(), allBlocks, newModel); + compatibleTemplate = false; + } + + try { + content._plainObject(newModel); + } catch (ex) { + console.error("Unable to inject model content!", ex); + compatibleTemplate = false; + } + + if (!compatibleTemplate) { + $('#incompatible-template').dialog({ + modal: true, + appendTo: '#mo-body', + buttons: { + Ok: function() { + $(this).dialog("close"); + } + } + }); + } + + return compatibleTemplate; +}; + var templateCompiler = function(performanceAwareCaller, templateUrlConverter, templateName, templatecode, jsorjson, metadata, extensions, galleryUrl) { // we strip content before tag and after because jquery doesn't parse it. // we'll keep it "raw" and use it in the preview/output methods. @@ -243,6 +276,9 @@ var templateCompiler = function(performanceAwareCaller, templateUrlConverter, te var blockModels = performanceAwareCaller('generateBlockModels', templateConverter.generateBlockModels.bind(undefined, templateDef)); + + var modelImporter = checkAndImportNewContentModel.bind(undefined, performanceAwareCaller, content, blockModels.allBlocks); + var incompatibleTemplate = false; if (typeof jsorjson !== 'undefined' && jsorjson !== null) { var unwrapped; @@ -251,21 +287,7 @@ var templateCompiler = function(performanceAwareCaller, templateUrlConverter, te } else { unwrapped = jsorjson; } - - // we run a basic compatibility check between the content-model we expect and the initialization model - var checkModelRes = performanceAwareCaller('checkModel', templateConverter.checkModel.bind(undefined, content._plainObject(), blockModels.allBlocks, unwrapped)); - // if checkModelRes is 1 then the model is not fully compatible but we fixed it - if (checkModelRes == 2) { - console.error("Trying to compile an incompatible template version!", content._plainObject(), blockModels.allBlocks, unwrapped); - incompatibleTemplate = true; - } - - try { - content._plainObject(unwrapped); - } catch (ex) { - console.error("Unable to inject model content!", ex); - incompatibleTemplate = true; - } + incompatibleTemplate = !modelImporter(unwrapped); } // This build the template for the preview/output, but concatenating prefix, template and content and stripping the "replaced" prefix added to "problematic" tag (html/head/body) @@ -286,7 +308,7 @@ var templateCompiler = function(performanceAwareCaller, templateUrlConverter, te plugins.push(templatesPlugin); // initialize the viewModel object based on the content model. - var viewModel = performanceAwareCaller('initializeViewmodel', initializeViewmodel.bind(this, content, blockModels.blockList, templateUrlConverter, galleryUrl)); + var viewModel = performanceAwareCaller('initializeViewmodel', initializeViewmodel.bind(this, content, blockModels.blockList, templateUrlConverter, galleryUrl, modelImporter)); viewModel.metadata = metadata; // let's run some version check on template and editor used to build the model being loaded. @@ -311,18 +333,6 @@ var templateCompiler = function(performanceAwareCaller, templateUrlConverter, te pluginsCall(plugins, 'viewModel', [viewModel]); - if (incompatibleTemplate) { - $('#incompatible-template').dialog({ - modal: true, - appendTo: '#mo-body', - buttons: { - Ok: function() { - $(this).dialog("close"); - } - } - }); - } - return { model: viewModel, init: function() { diff --git a/src/js/viewmodel.js b/src/js/viewmodel.js index ccfcb939c..5c96ffc14 100644 --- a/src/js/viewmodel.js +++ b/src/js/viewmodel.js @@ -24,7 +24,7 @@ toastr.options = { "escapeHtml": "true" // XSS }; -function initializeEditor(content, blocks, thumbPathConverter, galleryUrl) { +function initializeEditor(content, blocks, thumbPathConverter, galleryUrl, contentModelImporter) { var viewModel = { galleryRecent: ko.observableArray([]).extend({ @@ -444,7 +444,9 @@ function initializeEditor(content, blocks, thumbPathConverter, galleryUrl) { viewModel.importJSON = function(json) { var unwrapped = ko.utils.parseJson(json); - viewModel.content._plainObject(unwrapped); + // TODO, we should use checkModel to upgrade the model if it was from a previous template version. + // viewModel.content._plainObject(unwrapped); + contentModelImporter(unwrapped); }; viewModel.exportTheme = function() {