UNPKG

appblocks

Version:

A lightweight javascript library for building micro apps for the front-end.

109 lines (88 loc) 3.82 kB
'use strict'; import {getProp} from './utils'; import {applyCustomFilter} from './filters'; // Returns the value of a placeholder. const getPlaceholderVal = function(comp, placeholder, pointers) { // if ( /{([^}]+)}/.test(placeholder) === false ) return; if ( typeof pointers === 'object' && pointers !== null ) { } const placeholderName = placeholder.replace(/{|}/g , ''); let propKeys = placeholderName.split('.'); let result = getProp(comp, propKeys, pointers); // Return empty text instead of undefined. if (result === undefined) return ''; return result; }; // Replaces all placeholders in all attributes in a node. export const updateAttributePlaceholders = function(comp, node, pointers) { const attrs = node.attributes; for (let i = 0; i < attrs.length; i++) { let attrValue = attrs[i].value; let match; // Use a while loop to find all placeholders in the current attribute value while ((match = /{([^}]+)}/.exec(attrValue)) !== null) { const fullMatch = match[0]; // This regex captures the propName and any filters separated by | const [, propName, filters] = fullMatch.match(/{([^|}]+)(\|[^}]+)?}/); const filterList = filters ? filters.split('|').slice(1) : []; let placeholderVal = getPlaceholderVal(comp, propName, pointers); // Process each filter filterList.forEach(filter => { // Apply the filter based on its name placeholderVal = applyCustomFilter(comp, placeholderVal, filter); }); attrValue = attrValue.replace(fullMatch, placeholderVal); } attrs[i].value = attrValue; } }; // Updates all the text nodes that contain placeholders `{}` and applies filters (if any). export const updateTextNodePlaceholders = function(comp, nodeTree, pointers) { const textWalker = document.createTreeWalker( nodeTree, NodeFilter.SHOW_TEXT, null, false ); let nodesToProcess = []; while (textWalker.nextNode()) { nodesToProcess.push(textWalker.currentNode); } nodesToProcess.forEach((node) => { let nodeVal = node.nodeValue; let match; // Use a while loop to find all placeholders in the current node value while ((match = /{([^}]+)}/.exec(nodeVal)) !== null) { const fullMatch = match[0]; // This regex captures the propName and any filters separated by | const [, propName, filters] = fullMatch.match(/{([^|}]+)(\|[^}]+)?}/); const filterList = filters ? filters.split('|').slice(1) : []; let placeholderVal = getPlaceholderVal(comp, propName, pointers); // Process each filter filterList.forEach(filter => { // Example: Apply the filter based on its name. switch (filter) { case 'asHTML': // For asHTML, we'll handle it separately outside this loop since this is a corner case and has to be // hardcoded. break; default: // Handles other filters, e.g., applying a custom function placeholderVal = applyCustomFilter(comp, placeholderVal, filter); break; } }); if (filterList.includes('asHTML')) { // Create a document fragment from the HTML const docFrag = document.createRange().createContextualFragment(placeholderVal); node.parentNode.insertBefore(docFrag, node); node.parentNode.removeChild(node); break; // Exit the loop since the node has been replaced } else { // Replace text as before nodeVal = nodeVal.replace(fullMatch, placeholderVal); } } // Update the node value only if it hasn't been replaced by HTML if (node.parentNode) { node.nodeValue = nodeVal; } }); };