Commit ff81c193 authored by derek-knox's avatar derek-knox

Fix invalid front matter mid-edit scenario

Update front_matterify to handle yaml.safeLoad exception
case while ensuring the UI still works as expected
parent be02af42
......@@ -46,12 +46,12 @@ export default {
},
data() {
return {
saveable: false,
parsedSource: parseSourceFile(this.preProcess(true, this.content)),
editorMode: EDITOR_TYPES.wysiwyg,
isModified: false,
hasMatter: false,
isDrawerOpen: false,
isModified: false,
isSaveable: false,
};
},
imageRepository: imageRepository(),
......@@ -81,8 +81,11 @@ export default {
return templatedContent;
},
refreshEditHelpers() {
this.isModified = this.parsedSource.isModified();
this.hasMatter = this.parsedSource.hasMatter();
const { isModified, hasMatter, isMatterValid } = this.parsedSource;
this.isModified = isModified();
this.hasMatter = hasMatter();
const hasValidatedMatterCondition = this.hasMatter ? isMatterValid() : true;
this.isSaveable = this.isModified && hasValidatedMatterCondition;
},
onDrawerOpen() {
this.isDrawerOpen = true;
......@@ -138,12 +141,12 @@ export default {
@input="onInputChange"
@uploadImage="onUploadImage"
/>
<unsaved-changes-confirm-dialog :modified="isModified" />
<unsaved-changes-confirm-dialog :modified="isSaveable" />
<publish-toolbar
class="gl-fixed gl-left-0 gl-bottom-0 gl-w-full"
:has-settings="hasSettings"
:return-url="returnUrl"
:saveable="isModified"
:saveable="isSaveable"
:saving-changes="savingChanges"
@editSettings="onDrawerOpen"
@submit="onSubmit"
......
import jsYaml from 'js-yaml';
import { noop } from 'lodash';
const NEW_LINE = '\n';
......@@ -9,6 +8,19 @@ const hasMatter = (firstThreeChars, fourthChar) => {
return isYamlDelimiter && isFourthCharNewline;
};
const validateMatter = matterStr => {
let isMatterValid = true;
let matter;
try {
matter = jsYaml.safeLoad(matterStr);
} catch (error) {
isMatterValid = false;
}
return { matter, isMatterValid };
};
export const frontMatterify = source => {
let index = 3;
let offset;
......@@ -17,6 +29,8 @@ export const frontMatterify = source => {
const NO_FRONTMATTER = {
source,
matter: null,
hasMatter: false,
isMatterValid: false,
spacing: null,
content: source,
delimiter: null,
......@@ -40,12 +54,7 @@ export const frontMatterify = source => {
}
const matterStr = source.slice(index, offset);
let matter;
try {
matter = jsYaml.safeLoad(matterStr);
} catch (error) {
noop();
}
const { matter, isMatterValid } = validateMatter(matterStr);
let content = source.slice(offset + delimiter.length);
let spacing = '';
......@@ -59,6 +68,8 @@ export const frontMatterify = source => {
return {
source,
matter,
hasMatter: true,
isMatterValid,
spacing,
content,
delimiter,
......
......@@ -4,12 +4,24 @@ const parseSourceFile = raw => {
const remake = source => frontMatterify(source);
let editable = remake(raw);
let lastValidMatter = null;
const syncContent = (newVal, isBody) => {
if (isBody) {
editable.content = newVal;
} else {
// 1. Cache last valid matter to account for mid-edit resulting in matter invalidation
if (editable.hasMatter) {
lastValidMatter = editable.matter;
}
// 2. Update editable
editable = remake(newVal);
// 3. Use last valid matter cache if mid-edit results in matter invalidation
if (!editable.isMatterValid) {
editable.matter = lastValidMatter;
}
}
};
......@@ -23,10 +35,13 @@ const parseSourceFile = raw => {
const isModified = () => stringify(editable) !== raw;
const hasMatter = () => Boolean(editable.matter);
const hasMatter = () => editable.hasMatter;
const isMatterValid = () => editable.isMatterValid;
return {
matter,
isMatterValid,
syncMatter,
content,
syncContent,
......
......@@ -11,6 +11,8 @@ describe('static_site_editor/services/front_matterify', () => {
const frontMatterifiedContent = {
source: content,
matter: yamlFrontMatterObj,
hasMatter: true,
isMatterValid: true,
spacing,
content: body,
delimiter: '---',
......@@ -19,6 +21,8 @@ describe('static_site_editor/services/front_matterify', () => {
const frontMatterifiedBody = {
source: body,
matter: null,
hasMatter: false,
isMatterValid: false,
spacing: null,
content: body,
delimiter: null,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment