some tests passing
This commit is contained in:
parent
53114fcb01
commit
56576a589d
@ -260,7 +260,8 @@ function fillEachBlock(startNode, iterableExpression, itemExpression, endNode, c
|
||||
iterable = []
|
||||
}
|
||||
|
||||
|
||||
let firstItemFirstChild
|
||||
let lastItemLastChild
|
||||
|
||||
// create each loop result
|
||||
// using a for-of loop to accept all iterable values
|
||||
@ -284,11 +285,62 @@ function fillEachBlock(startNode, iterableExpression, itemExpression, endNode, c
|
||||
insideCompartment
|
||||
)
|
||||
|
||||
if(!firstItemFirstChild){
|
||||
firstItemFirstChild = itemFragment.firstChild
|
||||
}
|
||||
|
||||
// eventually, will be set to the last item's last child
|
||||
lastItemLastChild = itemFragment.lastChild
|
||||
|
||||
console.log('{#each} fragment', itemFragment.textContent)
|
||||
|
||||
endChild.parentNode.insertBefore(itemFragment, endChild)
|
||||
}
|
||||
|
||||
// add before-text if any
|
||||
const startNodePreviousSiblings = []
|
||||
let startNodePreviousSibling = startNode.previousSibling
|
||||
while(startNodePreviousSibling){
|
||||
startNodePreviousSiblings.push(startNodePreviousSibling)
|
||||
startNodePreviousSibling = startNodePreviousSibling.previousSibling
|
||||
}
|
||||
|
||||
// set the array back to tree order
|
||||
startNodePreviousSiblings.reverse()
|
||||
|
||||
if(startNodePreviousSiblings.length >= 1){
|
||||
let firstItemFirstestDescendant = firstItemFirstChild
|
||||
while(firstItemFirstestDescendant?.firstChild){
|
||||
firstItemFirstestDescendant = firstItemFirstestDescendant.firstChild
|
||||
}
|
||||
|
||||
for(const beforeFirstNodeElement of startNodePreviousSiblings){
|
||||
firstItemFirstestDescendant?.parentNode?.insertBefore(beforeFirstNodeElement, firstItemFirstestDescendant)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// add after-text if any
|
||||
const endNodeNextSiblings = []
|
||||
let endNodeNextSibling = endNode.nextSibling
|
||||
while(endNodeNextSibling){
|
||||
endNodeNextSiblings.push(endNodeNextSibling)
|
||||
endNodeNextSibling = endNodeNextSibling.nextSibling
|
||||
}
|
||||
|
||||
if(endNodeNextSiblings.length >= 1){
|
||||
let lastItemLatestDescendant = lastItemLastChild
|
||||
while(lastItemLatestDescendant?.lastChild){
|
||||
lastItemLatestDescendant = lastItemLatestDescendant.lastChild
|
||||
}
|
||||
|
||||
for(const afterEndNodeElement of endNodeNextSiblings){
|
||||
lastItemLatestDescendant?.parentNode?.appendChild(afterEndNodeElement)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
console.log('doc text after each', doc.textContent)
|
||||
|
||||
// remove block marker elements
|
||||
|
||||
@ -324,12 +324,26 @@ function consolidateMarkers(document){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {typeof closingIfMarker | typeof eachClosingMarker | typeof eachStartMarkerRegex.source | typeof elseMarker | typeof ifStartMarkerRegex.source | typeof variableRegex.source} MarkerType
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MarkerNode
|
||||
* @prop {Node} node
|
||||
* @prop {MarkerType} markerType
|
||||
*/
|
||||
|
||||
/**
|
||||
* isolate markers which are in Text nodes with other texts
|
||||
*
|
||||
* @param {Document} document
|
||||
* @returns {Map<Node, MarkerType>}
|
||||
*/
|
||||
function isolateMarkers(document){
|
||||
function isolateMarkerText(document){
|
||||
/** @type {ReturnType<isolateMarkerText>} */
|
||||
const markerNodes = new Map()
|
||||
|
||||
traverse(document, currentNode => {
|
||||
//console.log('isolateMarkers', currentNode.nodeName, currentNode.textContent)
|
||||
|
||||
@ -340,6 +354,8 @@ function isolateMarkers(document){
|
||||
while(remainingText.length >= 1) {
|
||||
let matchText;
|
||||
let matchIndex;
|
||||
/** @type {MarkerType} */
|
||||
let markerType;
|
||||
|
||||
// looking for a block marker
|
||||
for(const marker of [ifStartMarkerRegex, elseMarker, closingIfMarker, eachStartMarkerRegex, eachClosingMarker]) {
|
||||
@ -349,6 +365,7 @@ function isolateMarkers(document){
|
||||
if(index !== -1) {
|
||||
matchText = marker
|
||||
matchIndex = index
|
||||
markerType = marker
|
||||
|
||||
// found the first match
|
||||
break; // get out of loop
|
||||
@ -361,6 +378,7 @@ function isolateMarkers(document){
|
||||
if(match) {
|
||||
matchText = match[0]
|
||||
matchIndex = match.index
|
||||
markerType = marker.source
|
||||
|
||||
// found the first match
|
||||
break; // get out of loop
|
||||
@ -383,11 +401,21 @@ function isolateMarkers(document){
|
||||
|
||||
// per spec, currentNode now contains before-match and match text
|
||||
|
||||
/** @type {Node} */
|
||||
let matchTextNode
|
||||
|
||||
// @ts-ignore
|
||||
if(matchIndex > 0) {
|
||||
// @ts-ignore
|
||||
currentNode.splitText(matchIndex)
|
||||
matchTextNode = currentNode.splitText(matchIndex)
|
||||
}
|
||||
else{
|
||||
matchTextNode = currentNode
|
||||
}
|
||||
|
||||
markerNodes.set(matchTextNode, markerType)
|
||||
|
||||
// per spec, currentNode now contains only before-match text
|
||||
|
||||
if(afterMatchTextNode) {
|
||||
currentNode = afterMatchTextNode
|
||||
@ -407,8 +435,100 @@ function isolateMarkers(document){
|
||||
// skip
|
||||
}
|
||||
})
|
||||
|
||||
return markerNodes
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* after isolateMatchingMarkersStructure, matching markers (opening/closing each, if/then/closing if)
|
||||
* are put in isolated branches within their common ancestors
|
||||
*
|
||||
* UNFINISHED - maybe another day if relevant
|
||||
*
|
||||
* @param {Document} document
|
||||
* @param {Map<Node, MarkerType>} markerNodes
|
||||
*/
|
||||
//function isolateMatchingMarkersStructure(document, markerNodes){
|
||||
/** @type {MarkerNode[]} */
|
||||
/* let currentlyOpenBlocks = []
|
||||
|
||||
traverse(document, currentNode => {
|
||||
|
||||
const markerType = markerNodes.get(currentNode)
|
||||
|
||||
if(markerType){
|
||||
switch(markerType){
|
||||
case eachStartMarkerRegex.source:
|
||||
case ifStartMarkerRegex.source: {
|
||||
currentlyOpenBlocks.push({
|
||||
node: currentNode,
|
||||
markerType
|
||||
})
|
||||
break;
|
||||
}
|
||||
case eachClosingMarker: {
|
||||
const lastOpenedBlockMarkerNode = currentlyOpenBlocks.pop()
|
||||
|
||||
if(!lastOpenedBlockMarkerNode)
|
||||
throw new Error(`{/each} found without corresponding opening {#each x as y}`)
|
||||
|
||||
if(lastOpenedBlockMarkerNode.markerType !== eachStartMarkerRegex.source)
|
||||
throw new Error(`{/each} found while the last opened block was not an opening {#each x as y} (it was a ${lastOpenedBlockMarkerNode.markerType})`)
|
||||
|
||||
const openingEachNode = lastOpenedBlockMarkerNode.node
|
||||
const closingEachNode = currentNode
|
||||
|
||||
const commonAncestor = findCommonAncestor(openingEachNode, closingEachNode)
|
||||
|
||||
if(openingEachNode.parentNode !== commonAncestor && openingEachNode.parentNode.childNodes.length >= 2){
|
||||
if(openingEachNode.previousSibling){
|
||||
// create branch for previousSiblings
|
||||
let previousSibling = openingEachNode.previousSibling
|
||||
const previousSiblings = []
|
||||
while(previousSibling){
|
||||
previousSiblings.push(previousSibling.previousSibling)
|
||||
previousSibling = previousSibling.previousSibling
|
||||
}
|
||||
|
||||
// put previous siblings in tree order
|
||||
previousSiblings.reverse()
|
||||
|
||||
const parent = openingEachNode.parentNode
|
||||
const parentClone = parent.cloneNode(false)
|
||||
for(const previousSibling of previousSiblings){
|
||||
previousSibling.parentNode.removeChild(previousSibling)
|
||||
parentClone.appendChild(previousSibling)
|
||||
}
|
||||
|
||||
let openingEachNodeBranch = openingEachNode.parentNode
|
||||
let branchForPreviousSiblings = parentClone
|
||||
|
||||
while(openingEachNodeBranch.parentNode !== commonAncestor){
|
||||
const newParentClone = openingEachNodeBranch.parentNode.cloneNode(false)
|
||||
branchForPreviousSiblings.parentNode.removeChild(branchForPreviousSiblings)
|
||||
newParentClone.appendChild(branchForPreviousSiblings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new TypeError(`MarkerType not recognized: '${markerType}`)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
/**
|
||||
* This function prepares the template DOM tree in a way that makes it easily processed by the template execution
|
||||
* Specifically, after the call to this function, the document is altered to respect the following property:
|
||||
@ -425,5 +545,11 @@ function isolateMarkers(document){
|
||||
*/
|
||||
export default function prepareTemplateDOMTree(document){
|
||||
consolidateMarkers(document)
|
||||
isolateMarkers(document)
|
||||
// after consolidateMarkers, each marker is in at most one text node
|
||||
// (formatting with markers is removed)
|
||||
|
||||
isolateMarkerText(document)
|
||||
// after isolateMarkerText, each marker is in exactly one text node
|
||||
// (markers are separated from text that was before or after in the same text node)
|
||||
|
||||
}
|
||||
@ -277,13 +277,13 @@ test('template filling with text after {/each} in same text node', async t => {
|
||||
|
||||
Asperge,
|
||||
Betterave,
|
||||
Blette, en Printemps
|
||||
Blette, en Printemps
|
||||
`)
|
||||
|
||||
});
|
||||
|
||||
|
||||
test.skip('template filling of a table', async t => {
|
||||
test('template filling of a table', async t => {
|
||||
const templatePath = join(import.meta.dirname, '../fixtures/tableau-simple.odt')
|
||||
const templateContent = `Évolution énergie en kWh par personne en France
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user