<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<script src="https://cdn.tiny.cloud/1/9utiyh0y9yef2xx1l742k6flhf4z9g44qgrkru5ztb8s7i2r/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
<style>
pre {
background-color: ghostwhite;
border: 1px solid silver;
padding: 10px 20px;
margin: 0;
box-sizing: border-box;
}
html, body{
margin: 0;
}
.json-key {
color: brown;
}
.json-value {
color: navy;
}
.json-string {
color: olive;
}
.content-area{
height: 100vh;
width: 100vw;
display: flex;
flex-wrap: wrap;
}
.adf-output{
flex: 1 1 50%;
min-width: 300px;
}
.input-area{
position: relative;
flex: 1 1 50%;
min-width: 300px;
}
.btn-toggle{
position: absolute;
display: block;
margin: auto;
left: calc(50% - 45px);
width: 90px;
background: #51beff;
border: none;
padding: 5px 5px 10px 5px;
color: white;
font-weight: bold;
border-radius: 0 0 15px 15px;
cursor: pointer;
z-index: 3;
}
.hidden{
display: none;
}
.input-raw, .input-rich{
height: 100%;
width: 100%;
}
.btn-toggle{
background: #28a7f2;
}
.input-rich.hidden + .tox-tinymce{
display: none;
}
</style>
<script defer type="module">
import init, {convert} from "https://unpkg.com/htmltoadf@0.1.6/htmltoadf.js";
let editor;
const INITIAL_CONTENT = `
<h1>Header 1</h1>
<ol>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ol>
<p style='color: #F00; text-decoration: underline;'>Some colored text with <em>emphasis</em></p>
`
const inputRaw = document.querySelector('.input-raw');
const inputRich = document.querySelector('.input-rich');
const adfOutput = document.querySelector('.adf-output');
const btnToggle = document.querySelector('.btn-toggle');
const jsonFormatter = {
replacer: function(match, pIndent, pKey, pVal, pEnd) {
var key = '<span class=json-key>';
var val = '<span class=json-value>';
var str = '<span class=json-string>';
var r = pIndent || '';
if (pKey)
r = r + '"'+key + pKey.replace(/[": ]/g, '') + '"</span>: ';
if (pVal)
r = r + (pVal[0] == '"' ? str : val) + pVal + '</span>';
return r + (pEnd || '');
},
prettyPrint: function(obj) {
var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
return JSON.stringify(obj, null, 3)
.replace(/&/g, '&').replace(/\\"/g, '"')
.replace(/</g, '<').replace(/>/g, '>')
.replace(jsonLine, jsonFormatter.replacer);
}
};
tinymce.init({
selector:'.input-rich',
plugins: 'table',
toolbar: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | splitContent | table | forecolor backcolor ',
setup: function(ed) {
editor = ed;
editor.on('keyup', () => {
inputRaw.value = editor.getContent()
output(editor.getContent())
})
editor.on('change', () => {
inputRaw.value = editor.getContent()
output(editor.getContent())
})
}
})
inputRaw.addEventListener('keyup', event => {
editor.setContent(event.target.value)
output(event.target.value)
})
btnToggle.addEventListener('click', () => {
if(inputRaw.classList.contains('hidden')){
inputRich.classList.add('hidden')
inputRaw.classList.remove('hidden')
btnToggle.innerText = "Show Rich"
}else{
inputRaw.classList.add('hidden')
inputRich.classList.remove('hidden')
btnToggle.innerText = "Show Raw"
}
})
function output(html){
adfOutput.innerHTML = jsonFormatter.prettyPrint(JSON.parse(convert(html)))
}
init().then(() => {
inputRaw.value = INITIAL_CONTENT
editor.setContent(INITIAL_CONTENT)
output(INITIAL_CONTENT)
})
</script>
</head>
<body>
<a href="https://github.com/wouterken/htmltoadf" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<main class='content-area'>
<div class='input-area'>
<button class='btn-toggle'>
Show Raw
</button>
<textarea class='input-raw hidden'></textarea>
<div class='input-rich'>
</div>
</div>
<pre class='adf-output'>
</pre>
</main>
</body>
</html>