637 lines
22 KiB
JavaScript
637 lines
22 KiB
JavaScript
/* eslint-disable no-use-before-define */
|
|
/* eslint-disable no-param-reassign */
|
|
/* eslint-disable jsdoc/require-param-type */
|
|
/* eslint-disable jsdoc/require-param-description */
|
|
/* eslint-disable jsdoc/require-returns */
|
|
import dynamicStrings from '@/constants/dynamic-strings';
|
|
import { useMainStore } from '@/store';
|
|
|
|
/**
|
|
* @function getStringWithCustomValues
|
|
* @summary Returns str with all custom values replaced in accordance with the provided customValueMap
|
|
* @param {string} str
|
|
* @param {Dictionary} customValueMap
|
|
* @returns {string}
|
|
*/
|
|
export function getStringWithCustomValues(str, customValueMap) {
|
|
let newString = str ?? '';
|
|
if (customValueMap != null) {
|
|
Object.keys(customValueMap).forEach((key) => {
|
|
newString = newString.replaceAll(`{custom:${key}}`, customValueMap[key]);
|
|
});
|
|
}
|
|
return newString;
|
|
}
|
|
|
|
// This function will process the widget item and replace any global state variables with their values.
|
|
// This is a recursive function, it will call itself until it runs out of items to iterate on given the object.
|
|
/**
|
|
* @function processWidgetItemForReplacement
|
|
* @param widgetModel
|
|
* @param key
|
|
*/
|
|
function processWidgetItemForReplacement(widgetModel, key) {
|
|
// If we have a string, and it needs to be replaced.
|
|
if (typeof widgetModel[key] === 'string') {
|
|
if (widgetModel[key].includes('{if:')) {
|
|
widgetModel[key] = processIfStatements(
|
|
widgetModel[key],
|
|
dynamicStrings.GLOBAL_STATE,
|
|
getStoreValueFromString
|
|
);
|
|
}
|
|
|
|
if (widgetModel[key].includes(dynamicStrings.MODAL_LINK)) {
|
|
widgetModel[key] = mapStringToModal(widgetModel[key]);
|
|
}
|
|
if (widgetModel[key].includes(dynamicStrings.EXTERNAL_LINK)) {
|
|
widgetModel[key] = mapStringToLink(widgetModel[key]);
|
|
}
|
|
if (widgetModel[key].includes(dynamicStrings.GLOBAL_STATE)) {
|
|
widgetModel[key] = mapStringToState(widgetModel[key]);
|
|
}
|
|
return widgetModel[key];
|
|
}
|
|
|
|
// If we have an object. array, etc
|
|
if (typeof widgetModel[key] === 'object' && Object.keys(widgetModel[key]).length) {
|
|
Object.keys(widgetModel[key]).forEach((item) => {
|
|
processWidgetItemForReplacement(widgetModel[key], item);
|
|
});
|
|
|
|
return widgetModel[key];
|
|
}
|
|
|
|
// If we have something else like a number, boolean, etc. just return it
|
|
return widgetModel[key];
|
|
}
|
|
|
|
// Parent function for processWidgetItemForReplacement. This will loop through the parent
|
|
// object and pass any objects that need additional processing to the processWidgetItemForReplacement function.
|
|
/**
|
|
* @function processWidgetItemForfindAndReplaceGlobalStateValuesReplacement
|
|
* @param widgetModel
|
|
* @param widgetName
|
|
*/
|
|
function findAndReplaceGlobalStateValues(widgetModel, widgetName) {
|
|
const objWithReplacements = {
|
|
Name: widgetName,
|
|
Model: {}
|
|
};
|
|
|
|
Object.keys(widgetModel).forEach((key) => {
|
|
const modelWithReplacements = processWidgetItemForReplacement(widgetModel, key);
|
|
|
|
objWithReplacements.Model[key] = modelWithReplacements;
|
|
});
|
|
|
|
return objWithReplacements;
|
|
}
|
|
|
|
// Support method for processing the page data from the CMS call.
|
|
// widgets = current widget collection used by page.
|
|
// baseResponse = contains the widgets from the base page.
|
|
// clientResponse = contains the widgets from the client override page. (null if none)
|
|
/**
|
|
* @function processPageData
|
|
* @param baseResponse
|
|
* @param clientResponse
|
|
*/
|
|
function processPageData(baseResponse, clientResponse) {
|
|
const pageDataFromCms = {};
|
|
let widgets = [];
|
|
|
|
if (!baseResponse?.data?.Result) {
|
|
console.error('No result data found'); // Something has gone terribly wrong.
|
|
return {};
|
|
}
|
|
if (!clientResponse?.data?.Result) {
|
|
widgets = baseResponse.data.Result;
|
|
} else {
|
|
// Override any base widgets with the client override widgets if found.
|
|
baseResponse.data.Result.forEach((baseWidget) => {
|
|
let found = false;
|
|
clientResponse.data.Result.forEach((clientWidget) => {
|
|
if (clientWidget.Name === baseWidget.Name) {
|
|
widgets.push(clientWidget);
|
|
found = true;
|
|
}
|
|
});
|
|
|
|
if (!found) {
|
|
widgets.push(baseWidget);
|
|
}
|
|
});
|
|
|
|
// Add any unique client widgets that does not exist in the current main widgets collection.
|
|
clientResponse.data.Result.forEach((clientWidget) => {
|
|
let found = false;
|
|
widgets.forEach((currentWidget) => {
|
|
if (clientWidget.Name === currentWidget.Name) {
|
|
found = true;
|
|
}
|
|
});
|
|
|
|
if (!found) {
|
|
widgets.push(clientWidget);
|
|
}
|
|
});
|
|
}
|
|
|
|
widgets.forEach((widget) => {
|
|
// Global state value replacement.
|
|
const widgetWithReplacements = findAndReplaceGlobalStateValues(widget.Model, widget.Name);
|
|
|
|
// If we already have this widget, push it on the collection
|
|
if (widgetWithReplacements.Name in pageDataFromCms) {
|
|
pageDataFromCms[widgetWithReplacements.Name].push(widgetWithReplacements.Model);
|
|
return;
|
|
}
|
|
|
|
pageDataFromCms[widgetWithReplacements.Name] = [widgetWithReplacements.Model];
|
|
});
|
|
|
|
Object.keys(pageDataFromCms).forEach((key) => {
|
|
if (pageDataFromCms[key].length === 1) {
|
|
pageDataFromCms[key] = pageDataFromCms[key][0];
|
|
}
|
|
});
|
|
|
|
return pageDataFromCms;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param issPage
|
|
*/
|
|
export function fetchCmsContentForPage(issPage) {
|
|
const store = useMainStore();
|
|
const { clientName } = store.issConfig;
|
|
const { parentAccountNumber } = store.issConfig;
|
|
const clientOverride = clientName.length > 0 && parentAccountNumber > 0;
|
|
|
|
return (
|
|
store
|
|
.getPageData(issPage)
|
|
// Get the base/default page first.
|
|
.then((baseResponse) => {
|
|
if (!clientOverride) {
|
|
// Return the base page if there are no client override.
|
|
return processPageData(baseResponse, null);
|
|
}
|
|
// Else get the client override page.
|
|
const pageName = `${issPage}_${clientName.toLowerCase().replace(/ /g, '')}`;
|
|
|
|
return store.getPageData(pageName).then(
|
|
(clientResponse) =>
|
|
// Process the client override if it exists.
|
|
processPageData(baseResponse, clientResponse),
|
|
(error) => {
|
|
console.error(error);
|
|
// Process the just the base if no client override exists.
|
|
return processPageData(baseResponse, null);
|
|
}
|
|
);
|
|
})
|
|
);
|
|
}
|
|
|
|
export function fetchGlobalCmsContent(issComponent) {
|
|
const store = useMainStore();
|
|
|
|
return (
|
|
store.getPageData(issComponent)
|
|
.then((baseResponse) => processPageData(baseResponse, null)));
|
|
}
|
|
|
|
export function updateCmsSiteHeader(cmsResponse) {
|
|
const clientCmsSiteHeader = getCmsSiteHeader(cmsResponse);
|
|
useMainStore().issConfig.clientHeader = clientCmsSiteHeader;
|
|
}
|
|
|
|
function getCmsSiteHeader(cmsResponse) {
|
|
if (cmsResponse?.SiteHeaderWidget) {
|
|
const siteHeader = cmsResponse?.SiteHeaderWidget;
|
|
if (siteHeader.Answers) {
|
|
const { parentAccountNumber } = useMainStore().issConfig;
|
|
let headerAnswersToUse = siteHeader.Answers
|
|
.find((answer) => answer.AccountNumber === parentAccountNumber.toString());
|
|
if (headerAnswersToUse == null) {
|
|
headerAnswersToUse = siteHeader.Answers
|
|
.find((answer) => answer.AccountNumber === '0');
|
|
}
|
|
|
|
if (headerAnswersToUse) {
|
|
return {
|
|
altText: headerAnswersToUse.AltText,
|
|
clientName: headerAnswersToUse.ClientName,
|
|
hexCode: headerAnswersToUse.HexCode,
|
|
imageId: headerAnswersToUse.ImageId,
|
|
imageUrl: headerAnswersToUse.AnswerImageUrl
|
|
};
|
|
}
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
/**
|
|
* @function mapStringToModal
|
|
* @param str
|
|
*/
|
|
function mapStringToModal(str) {
|
|
const startIndex = str.indexOf(`{${dynamicStrings.MODAL_LINK}`);
|
|
let linkToReplace = str.substring(startIndex, str.length);
|
|
linkToReplace = linkToReplace.substring(0, linkToReplace.indexOf('}') + 1);
|
|
|
|
const params = linkToReplace.substring(
|
|
dynamicStrings.MODAL_LINK.length + 2,
|
|
linkToReplace.length - 1
|
|
);
|
|
const splitParams = params.split(',');
|
|
|
|
const bodyText =
|
|
`<a href="#" modalTarget="${splitParams[0]}" class="modal-text"><span class="sr-only">Link:</span>${splitParams[1]}</a>`;
|
|
|
|
let returnVal = str.replace(linkToReplace, bodyText);
|
|
|
|
if (returnVal.includes(dynamicStrings.MODAL_LINK)) {
|
|
returnVal = mapStringToModal(returnVal);
|
|
}
|
|
return returnVal;
|
|
}
|
|
|
|
/**
|
|
* @function mapStringToLink
|
|
* @param str
|
|
*/
|
|
function mapStringToLink(str) {
|
|
const startIndex = str.indexOf(`{${dynamicStrings.EXTERNAL_LINK}`);
|
|
let linkToReplace = str.substring(startIndex, str.length);
|
|
linkToReplace = linkToReplace.substring(0, linkToReplace.indexOf('}') + 1);
|
|
|
|
const params = linkToReplace.substring(
|
|
dynamicStrings.EXTERNAL_LINK.length + 2,
|
|
linkToReplace.length - 1
|
|
);
|
|
const splitParams = params.split(',');
|
|
|
|
const bodyText = `<a href="${splitParams[0]}" class="external-text" target="_blank">${splitParams[1]}</a>`;
|
|
|
|
let returnVal = str.replace(linkToReplace, bodyText);
|
|
|
|
if (returnVal.includes(dynamicStrings.EXTERNAL_LINK)) {
|
|
returnVal = mapStringToLink(returnVal);
|
|
}
|
|
return returnVal;
|
|
}
|
|
|
|
// Function to convert a string, into a matching global state item.
|
|
/**
|
|
* @function mapStringToState
|
|
* @param str
|
|
*/
|
|
function mapStringToState(str) {
|
|
// Pull all matches out of the string.
|
|
const regexExp = /{([^{}]*?):([^{}]*?)}/g;
|
|
const regexMatches = [...str.matchAll(regexExp)];
|
|
const globalStateMatches = regexMatches.filter((match) => match[1] === dynamicStrings.GLOBAL_STATE);
|
|
|
|
// Our final string value that will be built from the matches.
|
|
const stringBuilder = '';
|
|
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
for (const match of globalStateMatches) {
|
|
// Reset store state for each match.
|
|
const valueFromStore = getStoreValueFromString(match[2]);
|
|
if (!valueFromStore) {
|
|
console.warn('Unable to resolve global state data.');
|
|
return ''; // if we can't map our string to state data, return an empty string.
|
|
}
|
|
const stringWithReplacement = str.replace(match[0], valueFromStore);
|
|
|
|
// If we still have values we need to substitute, call this function again.
|
|
if (stringWithReplacement.includes(dynamicStrings.GLOBAL_STATE)) {
|
|
return mapStringToState(stringWithReplacement);
|
|
}
|
|
|
|
// Concatenate the string.
|
|
str = `${stringBuilder} ${stringWithReplacement}`;
|
|
}
|
|
|
|
return str.trimStart();
|
|
}
|
|
|
|
/**
|
|
* @function getStoreValueFromString
|
|
* @param str
|
|
*/
|
|
function getStoreValueFromString(str) {
|
|
if (!str) return '';
|
|
|
|
let storeOrStateObject = useMainStore();
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
for (const s of str.split('.')) {
|
|
if (s === 'getters') continue; // For backward compatibility
|
|
// TODO: I don't think this next line is doing what they think it's doing.
|
|
// eslint-disable-next-line eqeqeq, valid-typeof
|
|
if (typeof storeOrStateObject[s] != undefined) {
|
|
storeOrStateObject = storeOrStateObject[s];
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return storeOrStateObject ?? '';
|
|
}
|
|
|
|
/// ////////////////////////////////
|
|
// If Statement Processing Logic //
|
|
/// ////////////////////////////////
|
|
|
|
/**
|
|
* Recursive function - replaces all instances of if statements from the CMS that utilize the specified ifConditionKeyword
|
|
* @param {*} str string - Input string to be processed
|
|
* @param {*} ifConditionKeyword string - Defines which if statements to process ex: 'globalState'
|
|
* @param {*} replacePlaceholderCallback function - Callback to replace CMS placeholder values
|
|
* @returns The processed string
|
|
*/
|
|
export function processIfStatements(str, ifConditionKeyword, replacePlaceholderCallback) {
|
|
const containsRelevantIfStatement = new RegExp(`{if:${ifConditionKeyword}:.+?}`, 'g').test(str);
|
|
|
|
if (!containsRelevantIfStatement) {
|
|
return str;
|
|
}
|
|
const ifStatementRegexExpression = getIfStatementRegexExpression();
|
|
const ifStatementRegexMatches = [...str.matchAll(ifStatementRegexExpression)];
|
|
const completeIfStatementArray = getAndFlagFirstNonNestedIfStatementWithKeyword(
|
|
ifStatementRegexMatches,
|
|
ifConditionKeyword
|
|
);
|
|
executeIfStatementAndSetProcessedStrings(completeIfStatementArray, replacePlaceholderCallback);
|
|
const reconstructedPostProcessedString = joinProcessedRegexArray(ifStatementRegexMatches);
|
|
return processIfStatements(
|
|
reconstructedPostProcessedString,
|
|
ifConditionKeyword,
|
|
replacePlaceholderCallback
|
|
);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param matches
|
|
* @param ifConditionKeyword
|
|
*/
|
|
function getAndFlagFirstNonNestedIfStatementWithKeyword(matches, ifConditionKeyword) {
|
|
let index = 0;
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
for (const match of matches) {
|
|
if (match.groups.isIfStatement && match.groups.ifConditionType === ifConditionKeyword) {
|
|
let interiorIndex = 0;
|
|
let nestedLevel = 0;
|
|
let elseStatementIndex = null;
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
for (const interiorMatch of matches.slice(index + 1)) {
|
|
if (interiorMatch.groups.isIfStatement) {
|
|
if (interiorMatch.groups.ifConditionType === ifConditionKeyword) {
|
|
break;
|
|
} else {
|
|
nestedLevel++;
|
|
}
|
|
} else if (interiorMatch.groups.isElseStatement) {
|
|
if (!nestedLevel) {
|
|
elseStatementIndex = interiorIndex + 1;
|
|
}
|
|
} else if (interiorMatch.groups.isEndStatement) {
|
|
if (nestedLevel) {
|
|
nestedLevel--;
|
|
} else {
|
|
const ifStatementArray = matches.slice(index, index + interiorIndex + 2);
|
|
flagMatchesForProcessing(ifStatementArray, elseStatementIndex);
|
|
return ifStatementArray;
|
|
}
|
|
}
|
|
interiorIndex++;
|
|
}
|
|
}
|
|
index++;
|
|
}
|
|
console.error('Did not find end in conditional logic');
|
|
return matches;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param matches
|
|
* @param elseStatementIndex
|
|
*/
|
|
function flagMatchesForProcessing(matches, elseStatementIndex) {
|
|
matches[0].isFlaggedForProcessing = true;
|
|
matches[matches.length - 1].isFlaggedForProcessing = true;
|
|
if (elseStatementIndex) {
|
|
matches[elseStatementIndex].isFlaggedForProcessing = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param regexMatches
|
|
*/
|
|
function joinProcessedRegexArray(regexMatches) {
|
|
let processedString = '';
|
|
regexMatches.forEach((match) => {
|
|
const rawString = match[0];
|
|
processedString += match.groups.processedString ?? rawString;
|
|
});
|
|
return processedString;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param ifStatementArray
|
|
* @param replacePlaceholderCallback
|
|
*/
|
|
function executeIfStatementAndSetProcessedStrings(ifStatementArray, replacePlaceholderCallback) {
|
|
const ifCondition = replacePlaceholderCallback(ifStatementArray[0].groups.ifCondition);
|
|
let isInsideDesiredBlock = ifCondition;
|
|
|
|
ifStatementArray.forEach((entry) => {
|
|
if (entry.groups.isElseStatement && entry.isFlaggedForProcessing) {
|
|
isInsideDesiredBlock = !ifCondition;
|
|
} else if (entry.groups.isEndStatement && entry.isFlaggedForProcessing) {
|
|
isInsideDesiredBlock = true;
|
|
}
|
|
setProcessedStringOnEntry(entry, isInsideDesiredBlock);
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param entry
|
|
* @param isInsideDesiredBlock
|
|
*/
|
|
function setProcessedStringOnEntry(entry, isInsideDesiredBlock) {
|
|
if (!isInsideDesiredBlock) {
|
|
entry.groups.processedString = '';
|
|
} else if (entry.groups.isIfStatement) {
|
|
entry.groups.processedString = entry.isFlaggedForProcessing
|
|
? entry.groups.ifTrailingString
|
|
: entry[0];
|
|
} else if (entry.groups.isElseStatement) {
|
|
entry.groups.processedString = entry.isFlaggedForProcessing
|
|
? entry.groups.elseTrailingString
|
|
: entry[0];
|
|
} else {
|
|
entry.groups.processedString = entry.isFlaggedForProcessing
|
|
? entry.groups.endTrailingString
|
|
: entry[0];
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function getIfStatementRegexExpression() {
|
|
// Matches but does not capture:
|
|
// {if:...} or {else} or {end}
|
|
const anyLogicOperatorNonCapture = '(?:{(?:end|else|if:.*?)})';
|
|
// NOTE: ?<variableName> syntax stores the captured match like so: match.groups.variableName
|
|
const matchStartOfString =
|
|
'(?<processedString>^.+?)' // Match and Capture all characters (lazy), cannot be empty
|
|
+ '(?=(?:{if))'; // Looks ahead but does not capture {if
|
|
const matchIfOperator =
|
|
'(?<isIfStatement>{if:)' // Match & Capture {if:
|
|
+ '(?<ifConditionType>.*?):' // Match all chars up to and including next ':' - Capture all chars up to ':'
|
|
+ '(?<ifCondition>.*?)}' // Match all chars up to and including next '}' - Capture all chars up to '}'
|
|
+ '(?<ifTrailingString>.*?)' // Match and Capture all characters (lazy), can be empty
|
|
+ `(?=${anyLogicOperatorNonCapture})`; // Looks ahead but does not capture the next logic operator
|
|
const matchElseOperator =
|
|
'(?<isElseStatement>{else})' // Match & Capture {else}
|
|
+ '(?<elseTrailingString>.*?)' // Match & Capture all characters (lazy), can be empty
|
|
+ `(?=${anyLogicOperatorNonCapture})`; // Looks ahead but does not capture the next logic operator
|
|
const matchEndOperator =
|
|
'(?<isEndStatement>{end})' // Match & Capture {end}
|
|
+ '(?<endTrailingString>.*?)' // Match & Capture all characters (lazy), can be empty
|
|
+ `(?=${anyLogicOperatorNonCapture}|$)`; // Looks ahead but does not capture the next logic operator
|
|
// Combine all matching patterns, separated by 'or' pipes
|
|
return new RegExp(
|
|
`${matchStartOfString}|${matchIfOperator}|${matchElseOperator}|${matchEndOperator}`,
|
|
'g'
|
|
);
|
|
}
|
|
|
|
/// ///////////////////////////////////////
|
|
// End of If Statement Processing Logic //
|
|
/// ///////////////////////////////////////
|
|
|
|
/**
|
|
*
|
|
* @param copy
|
|
*/
|
|
export function doesCopyContainTextLink(copy) {
|
|
return copy.includes(dynamicStrings.TEXT_LINK);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param context
|
|
*/
|
|
export function setupModalLinks(context) {
|
|
context.$nextTick(() => {
|
|
const elements = document.getElementsByClassName('modal-text');
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
for (const element of elements) {
|
|
const target = element.getAttribute('modalTarget');
|
|
if (target) {
|
|
element.addEventListener('click', () => context.$refs[target].openModal());
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param context
|
|
* @param desiredTarget
|
|
*/
|
|
export function setupModalLink(context, desiredTarget) {
|
|
context.$nextTick(() => {
|
|
const element = document.querySelector(`[modalTarget=${desiredTarget}]`);
|
|
if (element) {
|
|
element.addEventListener('click', () => context.$refs[desiredTarget].openModal());
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param copy
|
|
*/
|
|
export function doesCopyContainRouterLink(copy) {
|
|
return copy.includes(this.dynamicStrings.ROUTER_LINK);
|
|
}
|
|
|
|
/**
|
|
* splits copy on { ... } such as {routerlink: ...}
|
|
* @param copy
|
|
* @returns array of strings
|
|
*/
|
|
export function splitCopyOnCMSPlaceHolder(copy) {
|
|
// splits copy on { ... } such as {routerlink: ...}
|
|
return copy.split(/{(.*?)}/g);
|
|
}
|
|
|
|
export function getExternalLink(copy) {
|
|
const url = copy.split(':')[1].split(',')[0];
|
|
if (url.includes('https-')) {
|
|
const prefixAdded = url.replace('https-', 'https://');
|
|
return prefixAdded;
|
|
}
|
|
|
|
return '#!';
|
|
}
|
|
|
|
/**
|
|
* Returns string2 of input following this pattern: {string1:string2,string3}
|
|
* @param copy
|
|
* @returns string
|
|
*/
|
|
export function getRouterLinkRouteFromCopy(copy) {
|
|
// sample input: {routerLink:estimate,provide your VIN}
|
|
// first split would return 'estimate,provide your VIN'
|
|
// second split would return 'estimate'
|
|
return copy.split(':')[1].split(',')[0];
|
|
}
|
|
|
|
/**
|
|
* Returns string3 of input following this pattern: { string1: string2, string3 }
|
|
* @param copy
|
|
* @returns string
|
|
*/
|
|
export function getRouterLinkDisplayTextFromCopy(copy) {
|
|
// sample input: {routerLink:estimate,provide your VIN}
|
|
// first split would return 'estimate,provide your VIN'
|
|
// second split would return 'provide your VIN'
|
|
return copy.split(':')[1].split(',')[1];
|
|
}
|
|
|
|
/**
|
|
* Returns a router link as an 'a' tag element
|
|
* @param copy
|
|
* @returns string
|
|
*/
|
|
export function getRouterLinkHtmlStringFromCopy(copy) {
|
|
return `<a href='/?issPage=${getRouterLinkRouteFromCopy(copy)}' class='router-link'>${getRouterLinkDisplayTextFromCopy(copy)}</a>`;
|
|
}
|
|
|
|
// Copy returned from the CMS that has newlines will return blocks wrapped in
|
|
// <p ... >...</p>
|
|
// This function returns an array of each paragraph, works with or without html
|
|
// attributes present
|
|
/**
|
|
*
|
|
* @param copy
|
|
*/
|
|
export function splitCMSCopyOnParagraphTag(copy) {
|
|
// filter removes empty strings that are a result of string.split with regex
|
|
return copy.split(/(?:<p(?:.*?)>)|(?:<\/p>)/g).filter((paragraph) => paragraph !== '');
|
|
}
|