diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..6a086fa --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,17 @@ +image: alpine:latest + +before_script: | + apk update + apk add nodejs npm + +pages: + stage: deploy + script: | + npm install + npm run build:lib + node ./SpaccDotWeb.js 'SpaccDotWeb.AppBuildStandalone({ Page: "Example.html" })' + mkdir -p ./public + mv ./Build/* ./public + artifacts: + paths: + - public diff --git a/Example.html b/Example.html new file mode 100644 index 0000000..86a358d --- /dev/null +++ b/Example.html @@ -0,0 +1,33 @@ + + + + + + + + + + diff --git a/SpaccDotWeb.html b/SpaccDotWeb.html deleted file mode 100644 index 1fe3a59..0000000 --- a/SpaccDotWeb.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - diff --git a/SpaccDotWeb.js b/SpaccDotWeb.js index 34c3882..63f803e 100644 --- a/SpaccDotWeb.js +++ b/SpaccDotWeb.js @@ -8,14 +8,16 @@ let __scriptname; const platformIsNode = (typeof module === 'object' && typeof module.exports === 'object'); const platformIsBrowser = (typeof window !== 'undefined' && typeof window.document !== 'undefined'); +const __filename__ = (typeof __filename !== 'undefined' ? __filename : ''); +const JsdomOptions = { /*resources: "usable",*/ runScripts: /*"dangerously"*/"outside-only" }; if (platformIsNode) { Lib.fs = require('fs'); Lib.crypto = require('crypto'); Lib.childProcess = require('child_process'); Lib.jsdom = require('jsdom'); - __scriptname = __filename.split('/').slice(-1)[0]; - windowObject = new Lib.jsdom.JSDOM().window; + __scriptname = __filename__.split('/').slice(-1)[0]; + windowObject = new Lib.jsdom.JSDOM('', JsdomOptions).window; }; if (platformIsBrowser) { @@ -31,7 +33,7 @@ const SpaccDotWeb = ((args) => { ////////////////////////////////////////////// let SpaccDotWeb = {}; if (platformIsNode) { - SpaccDotWeb.AppBuildStandalone = (opts) => { + SpaccDotWeb.AppBuildStandalone = (opts) => { // TODO: build result of dom after JS, to make base page usable without JS isBuildingApp = true; opts ||= {}; opts.Page ||= 'index.html'; @@ -40,7 +42,7 @@ if (platformIsNode) { Lib.fs.mkdirSync(`${__dirname}/Build/App-${opts.Page}`, { recursive: true }); let htmlIndex = Lib.fs.readFileSync(opts.Page, 'utf8'); - windowObject = new Lib.jsdom.JSDOM(htmlIndex).window; + windowObject = new Lib.jsdom.JSDOM(htmlIndex, JsdomOptions).window; documentObject = windowObject.document; DomSetup(opts.Modules); @@ -56,11 +58,11 @@ if (platformIsNode) { const minifiedPath = `${__dirname}/Build/SpaccDotWeb.min.js`; const hashPath = `${__dirname}/Build/SpaccDotWeb.js.hash`; const hashOld = (Lib.fs.existsSync(hashPath) && Lib.fs.readFileSync(hashPath, 'utf8')); - const hashNew = Lib.crypto.createHash('sha256').update(Lib.fs.readFileSync(__filename, 'utf8')).digest('hex'); + const hashNew = Lib.crypto.createHash('sha256').update(Lib.fs.readFileSync(__filename__, 'utf8')).digest('hex'); if (!Lib.fs.existsSync(compiledPath) || !Lib.fs.existsSync(minifiedPath) || !(hashOld === hashNew)) { uptodate = false; Lib.fs.writeFileSync(hashPath, hashNew); - Lib.fs.writeFileSync(compiledPath, Lib.childProcess.execSync(`cat "${__filename}" | npx babel -f "${__scriptname}"`)); + Lib.fs.writeFileSync(compiledPath, Lib.childProcess.execSync(`cat "${__filename__}" | npx babel -f "${__scriptname}"`)); Lib.fs.writeFileSync(minifiedPath, Lib.childProcess.execSync(`cat "${compiledPath}" | npx uglifyjs`)); }; uptodate && console.log('Library is up-to-date.'); @@ -68,9 +70,10 @@ if (platformIsNode) { }; }; -SpaccDotWeb.AppInit = function AppInit(){ +SpaccDotWeb.AppInit = () => { try { DomSetup(); + return SpaccDotWeb; } catch(err) { console.log(err) }; }; @@ -90,46 +93,78 @@ SpaccDotWeb.Select = (query) => { return elem; }; -const AppMetaGet = () => JSON.parse(SpaccDotWeb.Select('#Meta').innerHTML); +SpaccDotWeb.RequireScript = (src) => { + if (platformIsBrowser) { + SpaccDotWeb.Select('body').Insert(SpaccDotWeb.Create('script', { src: src })); + //} else if (platformIsNode) { + // require(src); + } +}; + +// TODO: make Meta element optional without breaking things +const AppMetaGet = () => { + const elem = SpaccDotWeb.Select('script[module="Meta"]'); + if (elem) { + if (['application/json', 'text/json'].includes(elem.getAttribute('type'))) { + return JSON.parse(elem.innerHTML); + } else { + return eval(elem.innerHTML); + }; + }; +}; const DomMakeBase = (Modules) => { const meta = AppMetaGet(); - const htmlFrags = { - Title: (meta.Name ? `