forked from handsontable/hyperformula
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'handsontable-feature/issue-1441'
- Loading branch information
Showing
80 changed files
with
8,394 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
# Common files | ||
node_modules | ||
|
||
# example files | ||
docs/examples/ | ||
|
||
# 3rd party | ||
src/interpreter/plugin/3rdparty | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<template> | ||
</template> | ||
|
||
<script> | ||
const decode = (base64data) => { | ||
return decodeURI(base64data); | ||
}; | ||
const useCodePreview = (code) => { | ||
const scriptElement = document.createElement('script'); | ||
scriptElement.type = 'text/javascript'; | ||
scriptElement.innerHTML = code; | ||
return [ | ||
(container) => { | ||
container.appendChild(scriptElement); | ||
return () => { scriptElement.parentElement.removeChild(scriptElement); }; | ||
}, | ||
]; | ||
}; | ||
export default { | ||
name: 'ScriptLoader', | ||
props: ['code'], | ||
mounted() { | ||
const [append] = useCodePreview(decode(this.$props.code)); | ||
this.removeScript = append(this.$el); | ||
}, | ||
beforeDestroy() { | ||
this.removeScript(); | ||
}, | ||
methods: { | ||
decode | ||
} | ||
}; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,16 +2,22 @@ const highlight = require('./highlight'); | |
const regexPlugin = require('markdown-it-regex').default; | ||
const footnotePlugin = require('markdown-it-footnote'); | ||
const searchBoxPlugin = require('./plugins/search-box'); | ||
const examples = require('./plugins/examples/examples'); | ||
const HyperFormula = require('../../dist/hyperformula.full'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const includeCodeSnippet = require('./plugins/markdown-it-include-code-snippet'); | ||
|
||
const searchPattern = new RegExp('^/api', 'i'); | ||
|
||
module.exports = { | ||
title: 'HyperFormula (v' + HyperFormula.version + ')', | ||
description: 'HyperFormula is an open-source, high-performance calculation engine for spreadsheets and web applications.', | ||
head: [ | ||
// Import HF (required for the examples) | ||
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/hyperformula.full.min.js' } ], | ||
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/languages/enUS.js' } ], | ||
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/languages/frFR.js' } ], | ||
// Import moment (required for the examples) | ||
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/moment/moment.min.js' } ], | ||
// Google Tag Manager, an extra element within the `ssr.html` file. | ||
['script', {}, ` | ||
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': | ||
|
@@ -41,11 +47,11 @@ module.exports = { | |
`], | ||
[ | ||
'script', | ||
{ | ||
id: 'Sentry.io', | ||
src: 'https://js.sentry-cdn.com/50617701901516ce348cb7b252564a60.min.js', | ||
crossorigin: 'anonymous', | ||
}, | ||
{ | ||
id: 'Sentry.io', | ||
src: 'https://js.sentry-cdn.com/50617701901516ce348cb7b252564a60.min.js', | ||
crossorigin: 'anonymous', | ||
}, | ||
], | ||
// Favicon | ||
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/favicon/apple-touch-icon.png' }], | ||
|
@@ -57,14 +63,7 @@ module.exports = { | |
base: '/', | ||
plugins: [ | ||
searchBoxPlugin, | ||
// [ | ||
// 'vuepress-plugin-clean-urls', | ||
// { | ||
// normalSuffix: '', | ||
// indexSuffix: '/', | ||
// notFoundPath: '/404.html', | ||
// }, | ||
// ], | ||
['container', examples()], | ||
{ | ||
extendPageData ($page) { | ||
// inject current HF version as {{ $page.version }} variable | ||
|
@@ -109,6 +108,7 @@ module.exports = { | |
replace: () => `'${HyperFormula.releaseDate}'` | ||
}) | ||
md.use(footnotePlugin) | ||
md.use(includeCodeSnippet) | ||
} | ||
}, | ||
// TODO: It doesn't work. It's seems that this option is bugged. Documentation says that this option is configurable, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
const { transformSync } = require('@babel/core'); | ||
|
||
const babelConfig = { | ||
presets: [ | ||
'@babel/preset-env', | ||
'@babel/preset-react', | ||
'@babel/preset-typescript', | ||
], | ||
plugins: [ | ||
'@babel/plugin-transform-modules-commonjs', | ||
'@babel/plugin-syntax-class-properties', | ||
['@babel/plugin-proposal-decorators', { legacy: true }], | ||
['@babel/plugin-proposal-class-properties', { loose: true }], | ||
['@babel/plugin-proposal-private-methods', { loose: true }], | ||
['@babel/plugin-proposal-private-property-in-object', { loose: true }] | ||
], | ||
targets: { | ||
ie: 9 | ||
} | ||
}; | ||
|
||
const buildCode = (filename, contentJs, relativePath = '') => { | ||
try { | ||
return transformSync(contentJs, { ...babelConfig, filename }).code; | ||
} catch (error) { | ||
// eslint-disable-next-line | ||
console.error(`Babel error when building ${relativePath}`); | ||
throw error; | ||
} | ||
}; | ||
|
||
module.exports = { buildCode }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
const Token = require('markdown-it/lib/token'); | ||
const { buildCode } = require('./code-builder'); | ||
const { stackblitz } = require('./stackblitz'); | ||
|
||
/** | ||
* Matches into: `example #ID .class :preset --css 2 --html 0 --js 1 --ts 3 --no-edit`. | ||
* | ||
* @type {RegExp} | ||
*/ | ||
const EXAMPLE_REGEX = /^(example)\s*(#\S*|)\s*(\.\S*|)\s*(:\S*|)\s*([\S|\s]*)$/; | ||
|
||
const parseCode = (content) => { | ||
if (!content) return ''; | ||
|
||
return content | ||
// Remove the all "/* start:skip-in-preview */" and "/* end:skip-in-preview */" comments | ||
.replace(/\/\*(\s+)?(start|end):skip-in-preview(\s+)?\*\/\n/gm, '') | ||
// Remove the all "/* start:skip-in-sandbox */" and "/* end:skip-in-sandbox */" comments | ||
.replace(/\/\*(\s+)?(start|end):skip-in-sandbox(\s+)?\*\/\n/gm, '') | ||
// Remove the code between "/* start:skip-in-compilation */" and "/* end:skip-in-compilation */" expressions | ||
.replace(/\/\*(\s+)?start:skip-in-compilation(\s+)?\*\/\n.*?\/\*(\s+)?end:skip-in-compilation(\s+)?\*\/\n/msg, '') | ||
// Remove /* end-file */ | ||
.replace(/\/\* end-file \*\//gm, ''); | ||
}; | ||
|
||
const parseCodeSandbox = (content) => { | ||
if (!content) return ''; | ||
|
||
return content | ||
// Remove the code between "/* start:skip-in-sandbox */" and "/* end:skip-in-sandbox */" expressions | ||
.replace(/\/\*(\s+)?start:skip-in-sandbox(\s+)?\*\/\n.*?\/\*(\s+)?end:skip-in-sandbox(\s+)?\*\/\n/msg, '') | ||
// Remove the all "/* start:skip-in-preview */" and "/* end:skip-in-preview */" comments | ||
.replace(/\/\*(\s+)?(start|end):skip-in-preview(\s+)?\*\/\n/gm, '') | ||
// Remove the all "/* start:skip-in-compilation */" and "/* end:skip-in-compilation */" comments | ||
.replace(/\/\*(\s+)?(start|end):skip-in-compilation(\s+)?\*\/\n/gm, ''); | ||
}; | ||
|
||
module.exports = function() { | ||
return { | ||
type: 'example', | ||
render(tokens, index, _opts, env) { | ||
const token = tokens[index]; | ||
const m = token.info.trim().match(EXAMPLE_REGEX); | ||
|
||
if (token.nesting !== 1 || !m) { | ||
return ''; | ||
} | ||
|
||
let [, , id, klass, preset, args] = m; | ||
|
||
id = id ? id.substring(1) : 'example1'; | ||
klass = klass ? klass.substring(1) : ''; | ||
preset = preset ? preset.substring(1) : 'hot'; | ||
args = args || ''; | ||
|
||
const htmlPos = args.match(/--html (\d*)/)?.[1]; | ||
const htmlIndex = htmlPos ? index + Number.parseInt(htmlPos, 10) : 0; | ||
const htmlToken = htmlPos ? tokens[htmlIndex] : undefined; | ||
const htmlContent = htmlToken | ||
? htmlToken.content | ||
: `<div id="${id}" class="hot ${klass}"></div>`; | ||
const htmlContentRoot = `<div data-preset-type="${preset}" data-example-id="${id}" >${htmlContent}</div>`; | ||
|
||
const cssPos = args.match(/--css (\d*)/)?.[1]; | ||
const cssIndex = cssPos ? index + Number.parseInt(cssPos, 10) : 0; | ||
const cssToken = cssPos ? tokens[cssIndex] : undefined; | ||
const cssContent = cssToken ? cssToken.content : ''; | ||
|
||
const jsPos = args.match(/--js (\d*)/)?.[1] || 1; | ||
const jsIndex = jsPos ? index + Number.parseInt(jsPos, 10) : 0; | ||
const jsToken = jsPos ? tokens[jsIndex] : undefined; | ||
|
||
const tsPos = args.match(/--ts (\d*)/)?.[1]; | ||
const tsIndex = tsPos ? index + Number.parseInt(tsPos, 10) : 0; | ||
const tsToken = tsPos ? tokens[tsIndex] : undefined; | ||
|
||
// Parse code | ||
const codeToCompile = parseCode(jsToken?.content); | ||
const tsCodeToCompileSandbox = parseCodeSandbox(tsToken?.content); | ||
|
||
[htmlIndex, jsIndex, tsIndex, cssIndex].filter(x => !!x).sort().reverse().forEach((x) => { | ||
tokens.splice(x, 1); | ||
}); | ||
|
||
const newTokens = [ | ||
new Token('container_div_open', 'div', 1), | ||
new Token('container_div_close', 'div', -1), | ||
new Token('container_div_open', 'div', 1), | ||
new Token('container_div_close', 'div', -1), | ||
]; | ||
|
||
tokens.splice(index + 1, 0, ...newTokens); | ||
|
||
const builtCode = buildCode( | ||
id + '.js', | ||
codeToCompile, | ||
env.relativePath | ||
); | ||
const encodedCode = encodeURI(builtCode); | ||
|
||
return ` | ||
<div class="example-container"> | ||
<style v-pre>${cssContent}</style> | ||
<div v-pre>${htmlContentRoot}</div> | ||
<ScriptLoader code="${encodedCode}"></ScriptLoader> | ||
</div> | ||
<div class="example-controls"> | ||
${stackblitz( | ||
id, | ||
htmlContent, | ||
tsCodeToCompileSandbox, | ||
cssContent, | ||
'ts' | ||
)} | ||
</div> | ||
`; | ||
}, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
const buildJavascriptBody = ({ id, html, js, css, hyperformulaVersion, lang }) => { | ||
return { | ||
files: { | ||
'package.json': { | ||
content: `{ | ||
"name": "hyperformula-demo", | ||
"version": "1.0.0", | ||
"main": "index.html", | ||
"dependencies": { | ||
"hyperformula": "${hyperformulaVersion}", | ||
"moment": "latest" | ||
} | ||
}` | ||
}, | ||
'index.html': { | ||
content: `<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>HyperFormula demo</title> | ||
</head> | ||
<body> | ||
${html || `<div id="${id}"></div>`} | ||
</body> | ||
</html>` | ||
}, | ||
'styles.css': { | ||
content: css | ||
}, | ||
[`index.${lang}`]: { | ||
content: `import './styles.css' | ||
${js}` | ||
}, | ||
} | ||
}; | ||
}; | ||
|
||
const stackblitz = (id, html, js, css, lang) => { | ||
const hyperformulaVersion = 'latest'; | ||
const body = buildJavascriptBody({ id, html, js, css, hyperformulaVersion, lang }); | ||
const template = lang === 'ts' ? 'typescript' : 'node'; | ||
|
||
const projects = body?.files | ||
? Object.entries(body?.files).map(([key, value]) => ( | ||
`<textarea class="hidden" name="project[files][${key}]" readOnly v-pre>${value.content}</textarea>` | ||
)) : []; | ||
|
||
return ` | ||
<form | ||
class="form-stackblitz-external" | ||
action="https://stackblitz.com/run" | ||
method="post" | ||
target="_blank" | ||
> | ||
${projects.join('\n')} | ||
<input type="hidden" name="project[title]" value="hyperformula-demo"/> | ||
<input type="hidden" name="project[dependencies]" | ||
value='{"hyperformula":"${hyperformulaVersion}", "moment": "latest"}' | ||
/> | ||
<input type="hidden" name="project[template]" value="${template}"/> | ||
<div class="js-stackblitz-link"> | ||
<button type="submit"> | ||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" | ||
width="10.43" height="15" preserveAspectRatio="xMidYMid" viewBox="0 0 256 368" class="icon outbound"> | ||
<path fill="currentColor" d="M109.586 217.013H0L200.34 0l-53.926 150.233H256L55.645 367.246l53.927-150.233z"/> | ||
</svg> | ||
Open in Stackblitz | ||
</button> | ||
</div> | ||
</form> | ||
`; | ||
}; | ||
|
||
module.exports = { stackblitz }; |
Oops, something went wrong.