I'm currently in the midst of making myself a site-wide page-builder utilizing GrapesJS and JS/jQuery to get selected content, parse said content, and finally initialize GJS. My problems all stem from parsing and subsequently converting relative URLs to absolute URLs.
On my page, here's what happens from a visit:
- Prompt me for URL
- Load document from URL
- Strip all
<script>
s, add them to the GJS init variable (push script'ssrc
into init.canvas.scripts), if nosrc
is present, add enclosed code into variable for injection later - Repeat step 3 for
<style>
/<link>
tags - Convert all links to absolute URLs (uses modified version of this solution)
- Put manipulated page into
<div id="gjs"></div>
- Initialize GJS with customized
init
variable
At the moment, I load a document with jQuery's $.get()
function, then use the callback data (which is a string) for stripping, etc. However, this string is not able to be manipulated with jQuery without being parsed, so I use parsePage()
, which should ideally convert this string into a jQuery object. Using the "parsed" variable, I should be able to .find('img')
, no? It doesn't give me anything...
How can I correctly parse the page if I'm doing it incorrectly, and just as important, how can I strip this whole document to only what's inside the document's <body>
?
Below is all the JS I use to do this:
var nosrc_scripts = "";
var nosrc_styles = "";
var init = {
container: '#gjs',
fromElement: true,
width: 'auto',
height: 'auto',
storageManager: false,
panels: {
defaults: []
},
// load external css/scripts
// found the reference here: https://github.com/artf/grapesjs/blob/master/src/canvas/config/config.js
canvas: {
styles: [],
scripts: []
},
};
$(document).ready(function() {
var url = prompt("URL to load:");
if (url != null) {
// get page content in var
$.get(url, function(page) {
// fix relative images, scripts, stylesheets, etc.
page.find('img[src^="./"]').attr('src', function(_,existing){
return new URL(src, "https://example.com/").href;
});
// go through scripts, add tags into the config, and add <script>'s into a var to inject later
getScripts(page);
// go through stylesheets, add tags into the config, and add <style>'s into a var to inject later
getStyles(page);
// load page content into the div to load
$('#gjs').append(stripToBody(page));
});
// finally, initialize grapesjs with our custom init var
initializeGJS();
}
});
function initializeGJS() {
const editor = grapesjs.init(init);
// create tags to inject
var nosrc_scripts_tag = document.createElement('script');
var nosrc_styles_tag = document.createElement('script');
// set <script>/<style> tags to the variables to inject
nosrc_scripts_tag.text = nosrc_scripts;
nosrc_styles_tag.text = nosrc_styles;
// inject them into the head of the HTML using grapesjs's method
editor.Canvas.getDocument().head.appendChild(nosrc_scripts_tag);
editor.Canvas.getDocument().head.appendChild(nosrc_styles_tag);
}
function getScripts() {
...
}
function getStyles() {
...
}
function parsePage(page) {
// strip loaded page down to body HTML, with no <script> or <style> tags
return $.parseHTML(page.substring(page.indexOf("<body"), page.indexOf("</body>")), false);
}
Happy Thanksgiving!