Skip to content

Commit

Permalink
Add support for deprecated blocks
Browse files Browse the repository at this point in the history
Also:
- renamed some blockDefs to blocksObj because they are "model object" and not "definition object".
- moved blocks model generation to model.js instead of editor.js by creating a new generateBlockModels returning both a blockList of non deprecated blocks and an allBlocks map of all known blocks.
  • Loading branch information
bago committed Jun 7, 2022
1 parent a302738 commit 61fdc50
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 38 deletions.
22 changes: 11 additions & 11 deletions src/js/converter/checkmodel.js
Expand Up @@ -2,15 +2,15 @@
var console = require("console");

// returns 0 if equal (0.0.x release), 1 with backward compatible additions (0.x.0 release), 2 on lost data or incompatible data (x.0.0 release)
var checkModel = function(reference, blockDefs, model, origPrefix, reverse) {
var blockDefsObj, i, prefix;
var checkModel = function(reference, blocks, model, origPrefix, reverse) {
var blocksObj, i, prefix;
var valid = 0;
if (typeof reverse == 'undefined') reverse = false;
if (typeof blockDefs !== 'undefined' && typeof blockDefs.splice == 'function') {
blockDefsObj = {};
for (i = 0; i < blockDefs.length; i++) blockDefsObj[blockDefs[i].type] = blockDefs[i];
if (typeof blocks !== 'undefined' && typeof blocks.splice == 'function') {
blocksObj = {};
for (i = 0; i < blocks.length; i++) blocksObj[blocks[i].type] = blocks[i];
} else {
blockDefsObj = blockDefs;
blocksObj = blocks;
}
for (var prop in reference)
if (reference.hasOwnProperty(prop)) {
Expand Down Expand Up @@ -66,18 +66,18 @@ var checkModel = function(reference, blockDefs, model, origPrefix, reverse) {
}
}
} else {
// in the case of different array we check blockDefs
// in the case of different array we check blocks
for (i = 0; i < reference[prop].length; i++) {
if (typeof reference[prop][i].type !== 'string') {
console.log("TODO found an object with no type", prefix, reference[prop][i]);
valid = Math.max(valid, 2);
} else if (!blockDefsObj.hasOwnProperty(reference[prop][i].type)) {
} else if (!blocksObj.hasOwnProperty(reference[prop][i].type)) {
console.warn("TODO the model uses a block type not defined by the template. REMOVING IT!!", prefix, reference[prop][i]);
reference[prop].splice(i, 1);
i--;
valid = Math.max(valid, 2);
} else {
valid = Math.max(valid, checkModel(blockDefsObj[reference[prop][i].type], blockDefsObj, reference[prop][i], prefix + "[" + i + "." + reference[prop][i].type + "]"));
valid = Math.max(valid, checkModel(blocksObj[reference[prop][i].type], blocksObj, reference[prop][i], prefix + "[" + i + "." + reference[prop][i].type + "]"));
}
}
}
Expand All @@ -94,7 +94,7 @@ var checkModel = function(reference, blockDefs, model, origPrefix, reverse) {
model[prop] = reference[prop];
}
} else {
valid = Math.max(valid, checkModel(reference[prop], blockDefsObj, model[prop], prefix, reverse));
valid = Math.max(valid, checkModel(reference[prop], blocksObj, model[prop], prefix, reverse));
}
}
} else if (model[prop] !== null) {
Expand All @@ -107,7 +107,7 @@ var checkModel = function(reference, blockDefs, model, origPrefix, reverse) {
}

}
if (!reverse) valid = Math.max(valid, checkModel(model, blockDefs, reference, typeof origPrefix !== 'undefined' ? origPrefix + "!R" : "!R", true));
if (!reverse) valid = Math.max(valid, checkModel(model, blocksObj, reference, typeof origPrefix !== 'undefined' ? origPrefix + "!R" : "!R", true));
return valid;
};

Expand Down
2 changes: 1 addition & 1 deletion src/js/converter/declarations.js
Expand Up @@ -135,7 +135,7 @@ var elaborateDeclarations = function(newStyle, declarations, templateUrlConverte
}

if (needDefaultValue && propDefaultValue === null) {
console.error("Cannot find default value for", declarations[i].name, declarations);
console.error("Cannot find default value for", declarations[i].name, declarations, element, newStyle, declarations[i]);
throw "Cannot find default value for " + declarations[i].name + ": " + declarations[i].value + " in " + element + " (" + typeof newStyle + "/" + propName + ")";
}
var bindDefaultValue = propDefaultValue;
Expand Down
6 changes: 0 additions & 6 deletions src/js/converter/editor.js
Expand Up @@ -288,7 +288,6 @@ var _propEditor = function(withBindingProvider, widgets, templateUrlConverter, m
return html;
};


var createBlockEditor = function(defs, widgets, themeUpdater, templateUrlConverter, rootModelName, templateName, editType, templateCreator, baseThreshold, trackGlobalStyles, trackUsage, fromLevel) {
if (typeof trackUsage == 'undefined') trackUsage = true;
var model = modelDef.getDef(defs, templateName);
Expand Down Expand Up @@ -337,16 +336,11 @@ var generateEditors = function(templateDef, widgets, templateUrlConverter, templ
var templateName = templateDef.templateName;
var blocks = templateDef._blocks;
var idx;
var blockDefs = [];
for (idx = 0; idx < blocks.length; idx++) {
if (typeof blocks[idx].container !== 'undefined') {
blockDefs.push(modelDef.generateModel(defs, blocks[idx].block));
}
createBlockEditors(defs, widgets, undefined, templateUrlConverter, blocks[idx].root, blocks[idx].block, templateCreator, baseThreshold);
}

if (typeof defs['theme'] != 'undefined') createBlockEditor(defs, widgets, undefined, templateUrlConverter, templateName, 'theme', 'styler', templateCreator, undefined, false, false, -1);
return blockDefs;
};

module.exports = generateEditors;
1 change: 1 addition & 0 deletions src/js/converter/main.js
Expand Up @@ -41,6 +41,7 @@ module.exports = {
translateTemplate: translateTemplate,
wrappedResultModel: wrappedResultModel,
generateResultModel: modelDef.generateResultModel,
generateBlockModels: modelDef.generateBlockModels,
generateEditors: generateEditors,
checkModel: checkModel,
checkDefs: checkDefs
Expand Down
39 changes: 33 additions & 6 deletions src/js/converter/model.js
Expand Up @@ -157,15 +157,15 @@ var _generateModelFromDef = function(modelDef, defs) {
return res;
};

var _generateModel = function(defs, name) {
var modelDef = _getModelDef(defs, name, false, true);
return _generateModelFromDef(modelDef, defs);
};

var _getDef = function(defs, name) {
return _getModelDef(defs, name, false, true);
};

var _generateModel = function(defs, name) {
var modelDef = _getDef(defs, name);
return _generateModelFromDef(modelDef, defs);
};

var _getModelDef = function(defs, name, returnClone, readonly) {
// lookup "name" in the template definition
if (typeof defs[name] == 'undefined') {
Expand Down Expand Up @@ -485,6 +485,32 @@ var generateResultModel = function(templateDef) {
return finalModelContent;
};

// returns 2 object: "blockList" and "allBlocks".
// we use "blockList" to decide which blocks to show in the blocklist
// we use instead allBlocks to know the model of a block by its name
var generateBlockModels = function(templateDef) {
var defs = templateDef._defs;
var blocks = templateDef._blocks;

var res = {
blockList: [],
allBlocks: {}
};
var idx, blockDef, blockModel;

for (idx = 0; idx < blocks.length; idx++) {
if (typeof blocks[idx].container !== 'undefined') {
blockDef = _getDef(defs, blocks[idx].block);
blockModel = _generateModelFromDef(blockDef);
if (typeof blockDef._deprecated == 'undefined') {
res.blockList.push(blockModel);
}
res.allBlocks[blocks[idx].block] = blockModel;
}
}
return res;
};

module.exports = {
// used to compile the template
ensurePathAndGetBindValue: modelEnsurePathAndGetBindValue.bind(undefined, false),
Expand All @@ -493,5 +519,6 @@ module.exports = {
generateModel: _generateModel,
generateResultModel: generateResultModel,
getDef: _getDef,
createOrUpdateBlockDef: _modelCreateOrUpdateBlockDef
createOrUpdateBlockDef: _modelCreateOrUpdateBlockDef,
generateBlockModels: generateBlockModels
};
4 changes: 2 additions & 2 deletions src/js/converter/stylesheet.js
Expand Up @@ -42,7 +42,7 @@ var _removeOptionalQuotes = function(str) {

var _processStyleSheetRules_processBlockDef = function(blockDefsUpdater, rules, templateUrlConverter) {
var properties, namedProps, decls;
// name, contextName, globalStyle, themeOverride, extend, min, max, widget, options, category, variant, visibility, help, blockDescription, version,
// name, contextName, globalStyle, themeOverride, extend, min, max, widget, options, category, variant, visibility, deprecated, help, blockDescription, version,
for (var i = 0; i < rules.length; i++) {
if (rules[i].type == 'rule') {
var sels = rules[i].selectors;
Expand Down Expand Up @@ -78,7 +78,7 @@ var _processStyleSheetRules_processBlockDef = function(blockDefsUpdater, rules,
else namedProps[decls[k].name] = declarations.declarationValueUrlPrefixer(val, templateUrlConverter);
// NOTE in past we detected unsupported properties, while now we simple push every declaration in a namedProperty.
// This make it harder to spot errors in declarations.
// Named properties we supported were extend, min, max, options, widget, category, variant, visibility, help, blockDescription, version
// Named properties we supported were extend, min, max, options, widget, category, variant, visibility, deprecated, help, blockDescription, version
// console.warn("Unknown property processing @supports -ko-blockdefs ", decls[k], sels);
}
for (var l = 0; l < sels.length; l++) {
Expand Down
11 changes: 6 additions & 5 deletions src/js/template-loader.js
Expand Up @@ -177,7 +177,6 @@ var templateCompiler = function(performanceAwareCaller, templateUrlConverter, te
if (basicStructure[ele] > 1) throw "ERROR: multiple element "+ele+"> occourences are not supported (found "+basicStructure[ele]+" occourences)";
}
var postfix = res[3];
var blockDefs = [];
var enableUndo = true;
var enableRecorder = true;
var baseThreshold = '+$root.contentListeners()';
Expand Down Expand Up @@ -240,7 +239,9 @@ var templateCompiler = function(performanceAwareCaller, templateUrlConverter, te
for (var wi = 0; wi < widgetPlugins.length; wi++) {
widgets[widgetPlugins[wi].widget] = widgetPlugins[wi];
}
blockDefs.push.apply(blockDefs, performanceAwareCaller('generateEditors', templateConverter.generateEditors.bind(undefined, templateDef, widgets, templateUrlConverter, myTemplateCreator, baseThreshold)));
performanceAwareCaller('generateEditors', templateConverter.generateEditors.bind(undefined, templateDef, widgets, templateUrlConverter, myTemplateCreator, baseThreshold));

var blockModels = performanceAwareCaller('generateBlockModels', templateConverter.generateBlockModels.bind(undefined, templateDef));

var incompatibleTemplate = false;
if (typeof jsorjson !== 'undefined' && jsorjson !== null) {
Expand All @@ -252,10 +253,10 @@ var templateCompiler = function(performanceAwareCaller, templateUrlConverter, te
}

// 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(), blockDefs, unwrapped));
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(), blockDefs, unwrapped);
console.error("Trying to compile an incompatible template version!", content._plainObject(), blockModels.allBlocks, unwrapped);
incompatibleTemplate = true;
}

Expand Down Expand Up @@ -285,7 +286,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, blockDefs, templateUrlConverter, galleryUrl));
var viewModel = performanceAwareCaller('initializeViewmodel', initializeViewmodel.bind(this, content, blockModels.blockList, templateUrlConverter, galleryUrl));

viewModel.metadata = metadata;
// let's run some version check on template and editor used to build the model being loaded.
Expand Down
8 changes: 4 additions & 4 deletions src/js/viewmodel.js
Expand Up @@ -24,7 +24,7 @@ toastr.options = {
"escapeHtml": "true" // XSS
};

function initializeEditor(content, blockDefs, thumbPathConverter, galleryUrl) {
function initializeEditor(content, blocks, thumbPathConverter, galleryUrl) {

var viewModel = {
galleryRecent: ko.observableArray([]).extend({
Expand Down Expand Up @@ -57,8 +57,8 @@ function initializeEditor(content, blockDefs, thumbPathConverter, galleryUrl) {

// viewModel.content = content._instrument(ko, content, undefined, true);
viewModel.content = content;
viewModel.blockDefs = blockDefs;

viewModel.blocks = blocks;
viewModel.notifier = toastr;

// Does token substitution in i18next style
Expand Down Expand Up @@ -164,7 +164,7 @@ function initializeEditor(content, blockDefs, thumbPathConverter, galleryUrl) {

// test method, command line use only
viewModel.loadDefaultBlocks = function() {
var input = viewModel.blockDefs;
var input = viewModel.blocks;
// Make sure undomanager consider this as a single action.
viewModel.startMultiple();
// empty the mainblock container
Expand Down
6 changes: 3 additions & 3 deletions src/tmpl/toolbox.tmpl.html
Expand Up @@ -6,7 +6,7 @@
</ul>

<div id="toolblocks" data-bind="scrollable: true">
<div class="block-list" data-bind="foreach: blockDefs" style="text-align: center">
<div class="block-list" data-bind="foreach: blocks" style="text-align: center">
<div class="draggable-item" data-bind="withProperties: { templateMode: 'show' }">
<div class="block" data-bind="extdraggable: { connectClass: 'sortable-blocks-edit', data: $data, dropContainer: '#main-wysiwyg-area', dragging: $root.dragging, 'options': { handle: '.handle', distance: 10, 'appendTo': '#page' } }, click: $root.addBlock" style="position: relative;">
<div title="Click or drag to add this block to the template" class="handle" data-bind="attr: { title: $root.t('Click or drag to add this block to the template') }, tooltips: {}"></div>
Expand Down Expand Up @@ -90,8 +90,8 @@
<!-- ko if: $root.debug -->
Content:
<pre data-bind='text: ko.toJSON(content, null, 2)' style="overflow: auto; height: 20%"></pre>
BlockDefs:
<pre data-bind='text: ko.toJSON(blockDefs, null, 2)' style="overflow: auto; height: 20%"></pre>
Blocks:
<pre data-bind='text: ko.toJSON(blocks, null, 2)' style="overflow: auto; height: 20%"></pre>
<!-- /ko -->
<a href="javascript:void(0)" data-bind="click: $root.exportHTMLtoTextarea.bind($element, '#outputhtml'); clickBubble: false, button: { text: true, label:'Generate' }">Output</a>
<a href="javascript:void(0)" data-bind="click: $root.exportJSONtoTextarea.bind($element, '#outputhtml'); clickBubble: false, button: { text: true, label:'Export' }">Export</a>
Expand Down

0 comments on commit 61fdc50

Please sign in to comment.