function filterQ2LayoutJSON( contentFilename ){ let file = filesWithMetadata[contentFilename] if (!file) return // can be removed for URLs as those are not with metadata let contentType = file.contentType // mereology option let openingOptions = filesWithMetadata[contentFilename].openingOptions // can be used via e.g. showFile("https://fabien.benetou.fr/?action=source",{ mereology:"whole"}) // filtering, only applying what's next to a certain content type and/or with filename filtering with .startsWith() .endsWith() .includes() or regex if ( contentType.includes("json") && contentFilename.endsWith("_q2layout.json") ) { console.log('it is a Q2 Layout JSON file', contentFilename) fetch( contentFilename ).then( r => r.json() ).then( savedDataFromPreviousSession => { // console.log( savedDataFromPreviousSession ) savedDataFromPreviousSession.map( savedData => Array.from( document.querySelectorAll('.'+classNameItemsToSave) ) .filter( noteEl => noteEl.getAttribute("value") == savedData.value ) // search by value as in theory those are constant (but not necessarily unique, even though usually are) .map( foundNoteEl => { foundNoteEl.setAttribute("position", AFRAME.utils.coordinates.stringify(savedData.position) ) foundNoteEl.setAttribute("rotation", AFRAME.utils.coordinates.stringify(savedData.rotation) ) } ) // should also debug the unfound ones ) AFRAME.scenes[0].emit('q2layoutjsonloaded', contentFilename) // to use the event consider : //AFRAME.scenes[0].addEventListener("templateexampleloaded", e => console.log(e)) } ); } applyNextFilter( contentFilename ) // can stop here or move on to the next filter that might or not be applied } sequentialFilters.push( filterQ2LayoutJSON ) // adding this to the list of filters to go through, order matters // typically one would be generic filters first then more specific ones after