summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/static_site_editor/services/parse_source_file.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/static_site_editor/services/parse_source_file.js')
-rw-r--r--app/assets/javascripts/static_site_editor/services/parse_source_file.js55
1 files changed, 55 insertions, 0 deletions
diff --git a/app/assets/javascripts/static_site_editor/services/parse_source_file.js b/app/assets/javascripts/static_site_editor/services/parse_source_file.js
new file mode 100644
index 00000000000..f32c693411f
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/services/parse_source_file.js
@@ -0,0 +1,55 @@
+const parseSourceFile = raw => {
+ const frontMatterRegex = /(^---$[\s\S]*?^---$)/m;
+ const preGroupedRegex = /([\s\S]*?)(^---$[\s\S]*?^---$)(\s*)([\s\S]*)/m; // preFrontMatter, frontMatter, spacing, and content
+ let initial;
+ let editable;
+
+ const hasFrontMatter = source => frontMatterRegex.test(source);
+
+ const buildPayload = (source, header, spacing, body) => {
+ return { raw: source, header, spacing, body };
+ };
+
+ const parse = source => {
+ if (hasFrontMatter(source)) {
+ const match = source.match(preGroupedRegex);
+ const [, preFrontMatter, frontMatter, spacing, content] = match;
+ const header = preFrontMatter + frontMatter;
+
+ return buildPayload(source, header, spacing, content);
+ }
+
+ return buildPayload(source, '', '', source);
+ };
+
+ const computedRaw = () => `${editable.header}${editable.spacing}${editable.body}`;
+
+ const syncBody = () => {
+ /*
+ We re-parse as markdown editing could have added non-body changes (preFrontMatter, frontMatter, or spacing).
+ Re-parsing additionally gets us the desired body that was extracted from the mutated editable.raw
+ Additionally we intentionally mutate the existing editable's key values as opposed to reassigning the object itself so consumers of the potentially reactive property stay in sync.
+ */
+ Object.assign(editable, parse(editable.raw));
+ };
+
+ const syncRaw = () => {
+ editable.raw = computedRaw();
+ };
+
+ const isModifiedRaw = () => initial.raw !== editable.raw;
+ const isModifiedBody = () => initial.raw !== computedRaw();
+
+ initial = parse(raw);
+ editable = parse(raw);
+
+ return {
+ editable,
+ isModifiedRaw,
+ isModifiedBody,
+ syncRaw,
+ syncBody,
+ };
+};
+
+export default parseSourceFile;