working implementation

This commit is contained in:
2025-10-05 00:54:47 +02:00
commit 9fc21c0f03
13 changed files with 1102 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
*.env
venv
*.venv
*.secret
elm-stuff/
elm.js

1
.tool-versions Normal file
View File

@@ -0,0 +1 @@
elm 0.19.1

13
README.md Normal file
View File

@@ -0,0 +1,13 @@
# MarkItUp Custom Element Example
This is a simple demonstration of using [HTML Custom Elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) in Elm.
Inspired by [Luke Westby](https://github.com/lukewestby)'s [Elm Europe talk](https://youtu.be/tyFe9Pw6TVE). The JavaScript custom element code is almost a verbatim copy.
To run it:
* git clone and cd into the local copy
* run `elm make src/Miu.elm --output js/miu-demo.js`
* open "demo.html" in a web browser

118
css/markitup-skin-simple.css Executable file
View File

@@ -0,0 +1,118 @@
/* -------------------------------------------------------------------
// markItUp! Universal MarkUp Engine, JQuery plugin
// By Jay Salvat - http://markitup.jaysalvat.com/
// ------------------------------------------------------------------*/
.markItUp * {
margin:0px; padding:0px;
outline:none;
}
.markItUp a:link,
.markItUp a:visited {
color:#000;
text-decoration:none;
}
.markItUp {
width:700px;
margin:5px 0 5px 0;
}
.markItUpContainer {
font:11px Verdana, Arial, Helvetica, sans-serif;
}
.markItUpEditor {
font:12px 'Courier New', Courier, monospace;
padding:5px;
width:690px;
height:320px;
clear:both;
line-height:18px;
overflow:auto;
}
.markItUpPreviewFrame {
overflow:auto;
background-color:#FFF;
width:99.9%;
height:300px;
margin:5px 0;
}
.markItUpFooter {
width:100%;
}
.markItUpResizeHandle {
overflow:hidden;
width:22px; height:5px;
margin-left:auto;
margin-right:auto;
background-image:url(images/handle.png);
cursor:n-resize;
}
/***************************************************************************************/
/* first row of buttons */
.markItUpHeader ul li {
list-style:none;
float:left;
position:relative;
}
.markItUpHeader ul li:hover > ul{
display:block;
}
.markItUpHeader ul .markItUpDropMenu {
background:transparent url(images/menu.png) no-repeat 115% 50%;
margin-right:5px;
}
.markItUpHeader ul .markItUpDropMenu li {
margin-right:0px;
}
/* next rows of buttons */
.markItUpHeader ul ul {
display:none;
position:absolute;
top:18px; left:0px;
background:#FFF;
border:1px solid #000;
}
.markItUpHeader ul ul li {
float:none;
border-bottom:1px solid #000;
}
.markItUpHeader ul ul .markItUpDropMenu {
background:#FFF url(images/submenu.png) no-repeat 100% 50%;
}
.markItUpHeader ul .markItUpSeparator {
margin:0 10px;
width:1px;
height:16px;
overflow:hidden;
background-color:#CCC;
}
.markItUpHeader ul ul .markItUpSeparator {
width:auto; height:1px;
margin:0px;
}
/* next rows of buttons */
.markItUpHeader ul ul ul {
position:absolute;
top:-1px; left:150px;
}
.markItUpHeader ul ul ul li {
float:none;
}
.markItUpHeader ul a {
display:block;
width:16px; height:16px;
text-indent:-10000px;
background-repeat:no-repeat;
padding:3px;
margin:0px;
}
.markItUpHeader ul ul a {
display:block;
padding-left:0px;
text-indent:0;
width:120px;
padding:5px 5px 5px 25px;
background-position:2px 50%;
}
.markItUpHeader ul ul a:hover {
color:#FFF;
background-color:#000;
}

135
css/mdset.css Normal file
View File

@@ -0,0 +1,135 @@
.markItUp {
width: auto;
margin: 5px 0 5px 0;
border: 5px solid #f5f5f5;
.markItUp a:link,
.markItUp a:visited {
color: black;
text-decoration: none;
}
.h1 a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABR0lEQVQ4T82TvWqDUBiGzehgB6cQKGZxSnAWF52SEhwEW72OxgsouYHeRxoDmTM5mSzZtIuTBASXTIL/oa+HKi2OLjlw8OA57/N9jz8jauAYDcxTDwIwTXMDlVmjc7/fdxhbVVXNoijeMKk8z/3T6fQhCMJLmqbLIAjeW/VOwTCMqK5rd7/fv7abiqLYCEsIT+bzuYT1GkApDMNJD6DrOgEcDocOIIqiXZaldLlcSIDjOCvLMiuO4z5A07QIh69VVX2hEvXbuoHAs+/7JDAejy3ct263Wx+wWq0ihN3j8dh1gLaJApxJgGVZAkiSpA9YLBYRNl3HcToAz/P2X2eGYSx02Wj0AbIsR6jmns/nDgBnG4el1pmmadIBntV/AMIbhGeNN+bO87ztdDo1ESavEWo+Kn9jvUT4CTZXzM/m+iBf4pAfarDCD4rK0hGjbt/3AAAAAElFTkSuQmCC");
}
.h2 a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABeklEQVQ4T82Sv2rCUBjFo5DFIYWMATGLk5mr3MVMDuIgxCZ736D0AcQn6AO0dLcm4BgyOQUfIOnioggZHBzU+CeJ2nNDvMVVFy985BLu+X3nfPfmuDtX7k499yAAwzB6iFKhcU6n0wCr32q1jCiKXlDc4XDwkyT52e1279gLcRx/TadTm55nEXRdD47Ho2tZVucyF1VVzfV6TfL5fHW73ZoQ2vv9ngBUwdnqcrmcM4CmaSlgOBwyQK1WMxeLBSkUCm+Aup7nzSVJIhSGsx3AXQZot9sBOsypVdjkMus6OhZ935curkRRpE4Unuef4WDFAM1mM4DYdRyHOVAUxQSMTCaTFADxB8TF8/nc3Ww2/tUMGo1GgK7uaDRigHK5bOIfmc1mUib+he1P7AV0fwLgfwb1ej1AN3c8HjNAqVQywzAkuJkOOn8D5iE7B6dFiLsoO40AcQ/iCs2NGmBYfVmWDeRPrxHiFb5CJqaSFer1KsKtT/pBnvKt9qnuD0N29xFsKIUWAAAAAElFTkSuQmCC");
}
.h3 a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABeElEQVQ4T82SvYrCQBSFkzLNFnYGgoKk0gcI02ijhVgIukm/sE/gE/gAwQfYZXvXBFK62ljFbGFnKhtBCKQJbCQ//rJnwu5AWm0cuBAyc757zp3huTsXf6eeexCApmlDRKnSONfrdYI17nQ62vF4fEZxh8PBPZ/Pn0mSDPD9dDqd3rfb7ZSeZxFUVfUul4ttmmb/fy6NRsOAgCyXS7FWq80Bs9M0JfhX9X1fzAF6vV4GsCyLARRFMdCNrFYrCpDW6/WuWCy+AqAGQdDMAbrdrofDO2oVB7g/6yo6Sq7ripVKRYqiaIQiEOr7/V7PAdrttgexPZvNmAN0zSJsNpvMbqFQkAD+wLkq6gU1ZTNotVoezbhYLBhAlmUjjmOCaE3sEdh+EwRBgtNviKkDnQHq9bqHbrbjOAxQKpWMMAwJz/M69ga4oT5gPxDP6TcAdgaAeEgnS3OjJhjWuFwua8ifXSOKziZEZ4kCIPlC5a/x1if9IE/5VvtU9wuEWf0R3RdGzAAAAABJRU5ErkJggg==");
}
.h4 a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABbElEQVQ4T82SvY6CQBSFB2O02wcwsYRsIhUNCZWNFDaSoPAC+wCbfQHDE+wbbC0LtBZW2mBB6NbGzpgQKsI2/gFmz0x2Z0OrjZNM5vd899w7I5A7m3CnnjwIwLZtB6n0aDqCIHiz2cwdjUZ2URSTsizJ+XzerFarKT2XZbl7uVxettstW/MULMtKIA5d1x3/1UXXdR9iDeIO3VNV9SnLsgCA791ux+7VAFVVhUEQcEC/32eA9XrNAKIofmDdA2CfpmkdYJpmAsAetj9/bVPrFi534zjuQPyOuYe9N4wETuoAwzASHITz+Zw7UBTFz/Nca7Va4+PxSKN/4Y6MIATdPZ1OU57CcDhMEDlcLBYcgIL5h8NBazQazxhlCAgADnV4vV5fMd9wAArGHCyXSw6AbR97GgrGakBbu932kSoB5D+FwWDgwFKPRsChF0WRK0mSDcsTdBp1g5zZszWbTeYArf6Mt37pB/nKt9qnuh+W4+gRT5uz1AAAAABJRU5ErkJggg==");
}
.h5 a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABZ0lEQVQ4T81TPY6CQBgdEvtNKEk22FDhAQwNNEuMoTBxF3pvYDyBB9A9wO4FUEwsjdtYAY2dVJZuxo6CEAMiZt8QnGxP4yQvM/B9733fmx+BNBxCQz55EgHHcaawojI79/t9ieFaluVcr9cPgOR5HtWzijVha+D7fD5vuAXbtmlZlv5qtXp/7IthGB4IWhAEUqfTYeuKXM+jOI4TLjAcDiuB9XrNBbrdrlcUhbbf7yVFUX5AXNxutw2l9PQowgUGgwFF8gkJi3+V7CzLXqMokmRZppfLhSBOkOemaTpmIlyg3+9TBP3tdss7qNvWjsejxJJFUVRB7gET7NUYdlwuYJomxQ9/t9txAbTtoaoGa2+I9aDxxXy3Wq1PFPvF94wL6LpO0bofhiEXQNtekiSaIAgzxCYgjTBvQPSAOeBXAiBPEVDr41keDge33W478F8dI3BC28z/C7phGxgATOhZbmKTB9X4Mf0BNtf9EZw071oAAAAASUVORK5CYII=");
}
.h6 a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABgklEQVQ4T82SvYrCQBSFE2IQmy0sA6KNIGivpNFmLYKFEE36fYIFH0B8gOwLLNirCVhKbFIlbmEXOxsRBhTiXyH+s2fC7oCtNg4MueTe891zZ4bnnlz8k3ruRQC6rrcwSpaOc7vdelidSqWin06nOjZ3PB4nnuc1aT6Tycj7/b5+uVy+CCFzNoKmaeR6vbqWZdX+z6VUKpkQyxBL+Xz+bbVatQHciaL4OZ1Od7SOAVRVDQH9fp8BCoWCeT6f5fF4LKXT6SHE29lsxvJ3gGq1SlA8h7UuunJ/1rUgCBLRaPRjs9m0eZ4f4H+C1lEXcLRjDhRFIRC7tm2zDrlczlwul3IsFjMOh0NjsVhI8Xg8gTP4gdsmQN8MUC6XCeiu4zgMANvmer2WI5GIgVwDHSVqWxAEOq6B0GCAYrFIYN0djUYMkEwmTXSTUfyO3BA3VEO8hdMwBsANARC3UJClc2P3fN/vpFIpHbbDa4RggryHrwYAlXSxB3eH+OiTfpGn/Kh9qvsF8uf0EffuWGQAAAAASUVORK5CYII=");
}
.ruler a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAIUlEQVR42mMYKqCB4T9OCAb/oSQGjxQFmIA0BbjhEAlmACV9KVjPWpB2AAAAAElFTkSuQmCC");
}
.bold a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADCSURBVCjPY/jPgB8yUEtBeUL5+ZL/Be+z61PXJ7yPnB8sgGFCcX3m/6z9IFbE/JD/XucxFOTWp/5PBivwr/f77/gfQ0F6ffz/aKACXwG3+27/LeZjKEioj/wffN+n3vW8y3+z/Vh8EVEf/N8LLGEy3+K/2nl5ATQF/vW+/x3BCrQF1P7r/hcvQFPgVg+0GWq0zH/N/wL1aAps6x3+64M9J12g8p//PZcCigKbBJP1uvvV9sv3S/YL7+ft51SgelzghgBKWvx6E5D1XwAAAABJRU5ErkJggg==");
}
.italic a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABxSURBVCjPY/jPgB8yUFtBdkPqh4T/kR+CD+A0Ie5B5P/ABJwmxBiE//f/gMeKkAlB/90W4FHg88Dzv20ATgVeBq7/bT7g8YXjBJf/RgvwKLB4YPFfKwCnAjMH0/8a/3EGlEmD7gG1A/IHJDfQOC4wIQALYP87Y6unEgAAAABJRU5ErkJggg==");
}
.stroke a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAACfSURBVCjPY/jPgB8yUFNBiWDBzOy01PKEmZG7sSrIe5dVDqIjygP/Y1GQm5b2P7kDwvbAZkK6S8L/6P8hM32N/zPYu2C1InJ36P/A/x7/bc+YoSooLy3/D4Px/23+SyC5G8kEf0EIbZSmfdfov9wZDCvc0uzLYWyZ/2J3MRTYppn/14eaIvKOvxxDgUma7ju1M/LlkmnC5bwdNIoL7BAAWzr8P9A5d4gAAAAASUVORK5CYII=");
}
.teletype a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAWklEQVR42mOgGnjP8B8NvkKRBwp0M4QwhADpfDC9G8hCU+AFpTXAdD+mAicUBS3oCg4yKKIoCASKoAO4AhigvwJJhgAg/M+QAyQ9GVgw5Nk7kELxF4MqA/0AAIG/KN52W2aDAAAAAElFTkSuQmCC");
}
.list-bullet a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVDjLY/j//z8DJZiBKgbkzH9cMHXX6wcgmiwDQJq3nv/4H0SD+OXl5dlA/L+kpOR/QUHB/+zs7P+pqan/ExIS/kdGRv4PDg7+T10XDHwgpsx8VNC56eWDkJ675Hmhbf3zB0uPvP1fuvQpOBDj4uKyIyIi/gcGBv738vL67+zs/N/Gxua/iYnJf11d3f9qamqogRjQcaugZPHjB66V14ZqINrmXyqIn3bvgXXeJfK8ANLcv+3lfxAN4hsZGWVra2v/V1FR+S8nJ/dfXFz8v5CQ0H8eHp7/7Ozs/5mZmVEDEWQzRS6gBAMAYBDQP57x26IAAAAASUVORK5CYII=");
}
.list-numeric a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAD3SURBVDjLY/j//z8DJRhM5Mx/rLLo8Lv/ZBsA0kyRATBDYOzy8vJsIP5fUlLyv6Cg4H92dvb/1NTU/wkJCf8jIyP/BwcH/8fqgkUHSXcFA1UCce7+t/9n7Xn9P2LiPRWyXRDae0+ld8tL8rwQ1HVHpXPTc7jmuLi47IiIiP+BgYH/vby8/js7O/+3sbH5b2Ji8l9XV/e/mpoaaiC2rX/+v3HN0/81q54OUCCWL3v8v3Tp4//Fix+T7wKQZuu8S+THAkgzzAVGRkbZ2tra/1VUVP7Lycn9FxcX/y8kJPSfh4fnPzs7+39mZmbUQARpBGG7oisddA9EAPd/1bRtLxctAAAAAElFTkSuQmCC");
}
.list-task a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAnklEQVR42n3RMY5BURgF4M+NTDfJjB3MdLOASZSisgoqrUKtV6kprUAl0ahETyEUElagdyN5zwL83jntV51D00kZtrDxy9Xd2jLoVmFFaaGuFvTTTqY0F+fDVhmBhrG/9yCZKgzeg47s6OsVJHU0nN21eAUjZ/9mChMpAn0PN9nBNxFIhh6yNjEg6eqpBaBqqOqp9zIXufqspmPF3T9PDKRvg85kdtEAAAAASUVORK5CYII=");
}
.image a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHwSURBVDjLpZM9a1RBFIafM/fevfcmC7uQjWEjUZKAYBHEVEb/gIWFjVVSWEj6gI0/wt8gprPQykIsTP5BQLAIhBVBzRf52Gw22bk7c8YiZslugggZppuZ55z3nfdICIHrrBhg+ePaa1WZPyk0s+6KWwM1khiyhDcvns4uxQAaZOHJo4nRLMtEJPpnxY6Cd10+fNl4DpwBTqymaZrJ8uoBHfZoyTqTYzvkSRMXlP2jnG8bFYbCXWJGePlsEq8iPQmFA2MijEBhtpis7ZCWftC0LZx3xGnK1ESd741hqqUaqgMeAChgjGDDLqXkgMPTJtZ3KJzDhTZpmtK2OSO5IRB6xvQDRAhOsb5Lx1lOu5ZCHV4B6RLUExvh4s+ZntHhDJAxSqs9TCDBqsc6j0iJdqtMuTROFBkIcllCCGcSytFNfm1tU8k2GRo2pOI43h9ie6tOvTJFbORyDsJFQHKD8fw+P9dWqJZ/I96TdEa5Nb1AOavjVfti0dfB+t4iXhWvyh27y9zEbRRobG7z6fgVeqSoKvB5oIMQEODx7FLvIJo55KS9R7b5ldrDReajpC+Z5z7GAHJFXn1exedVbG36ijwOmJgl0kS7lXtjD0DkLyqc70uPnSuIIwk9QCmWd+9XGnOFDzP/M5xxBInhLYBcd5z/AAZv2pOvFcS/AAAAAElFTkSuQmCC");
}
.link a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAA1UlEQVR42mMYLCCMe0Hp2Xff/+97uNh8scS+u9//n323oDSMGyrtxJbX9fA/BBy7t+fQ/x8g1sP/eV1ObGAFjn7rP/x/17Qt58+M/4//7/w/43/On6Zt/x+u/+DoBzGh68T3J+nFXBGf/0NBxOdirifpJ747dYEVWGXOfv+ypGJn9K+U/2VAmPI/+lfFzpcls99bZYIVGGsWXL/1/v/b//9f/1/zfzuQBIK3t94XXDfWBCvQY44wyL4/7cui74t+NsQ1OC/6tOj7tC/Z9yMM9JgZhgYAAE4Ogp9tIcEHAAAAAElFTkSuQmCC");
}
.quotes a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACyElEQVQ4T22Se0iTURjGn/Nt2kidOpto3sgZoYJaQV5yuIJUksJsLiTxDy0Ji0LQVEgpjAoFF4kJEcQwLVxFCplhZAQ6NZohIhkbKV6KjKltTrfPb6dvK7y0vXDgcM55f+/Dcx4CD1XS1CtZsZNmUKrkr709vSGE9Am8aRnxdFlwu7crNy36ZN5hGYQCxtMTvBqZwuN3Xw1ugLKWfl+T2bbUfjVTYF4DbOsAywEc5ZfDuSicTTIpg2uaIdd+WxXd6YsU+3lNN5dlYH6ZuppcAL5xEwIkhDFo0OrdAVsV/LIAVjtg5ztd0/+pIKA8QIC6tuFNwHWFQrhsm6iNlrJXJmIrfRTHlUKlPAYM+StyZpHCtEIR6k8Q7EfcPaiWS8ojxdYmK3WA7AyCMeocTEGpAGFwbH8EirPiXKAliw0vBozoG50dF+6gpzY8uKsQvQ5LPpItlQZi+OMnzM7MwMIKsDssvM2Yok5Tl8plPbzzb0dn1whDbnVUZdY7gRuA5rwgTW5la5G/iGLKaMCqZRneASFo/+wY23soO+H92NwKpah9WpOl3ur6BkB1QlVRfzaqITIhnYiEBDaOwZheR9VTySYwouonNZkPPQbKeZif3ynQflts0Rb+LE0KmCWc0BdC2DDwI4QWdwS25smkl7VaFf+Z7kUopcRL/ry+4syBGkXBHqZ/UAf7GgG7CiQlpkDfa+AevBy6yeoKb/Dx5T9ye5FUZUNFemJs40FlDkbMBK70WYE1MyCwU8TvAoxvuuikQV892F3f4AaYa4ync1EXoIEKKz7B4KwUdn46ywLrHIH37wXURD9DwPg9yOq+uCWXGO7nDOimJWmd9vOQZsvhzI2Dzz9vAlheyffuHlyK6EBcsOXDvotdGW4KZjrLJZPz5vAq3dHTZk5cIhJ5BcJBBOA4btXOrvpjQdOoGHwUEyqej1CpTf8D/gAqfTVYD/HkgwAAAABJRU5ErkJggg==");
}
.code a {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADb0lEQVQ4T1WTaUxcVRTH//ctM2/WN2+YoVWI0DE1lBRSMkILLlSN9YutW62QKQ1W29QaFAMal/hJ+4FoiDRBWjRFWqM1GJfEhTTFKCQ0BNqmK5YPUKGtjTDMQkFm3nI986ok3uTk3Nz3P7973jnnMvy7Xvh2psqw8FFEdVYv6RZyplsWlg0rxRlbYBxznHGT5AkGxDmEY86ighO0v712HZ9sKl/tPdhSG/7vyPaLWYKRJZZNZHVgIWPi6twt9E8uzROweQXQ8PnE+w9EtHf2VIcwkzQhMwaJvooSmQg4BPKCAJn2ywbHyNQSPh39c3YFUN976eCja8NNDRvDmJizSEwBHJAoIAcQckrOUaCKeK33D7TFitA+cBUrgGcOnf/Kp4V3MJnhpWgQ3ZfSkHWOxg1+eBUBIklFUkfCIlqPXMCT9xeic3D6hg2obp8Jal5zsqTQoyZTJnZFNRy9nEbIwzCfsBCr8MPvJAhlUnaHjIaOMWRknhYktp2VH5iqK7/H3RN2MyWRMNFYqcJgIlJUtO/HF5DnZfgrbSEacKCm1IdooYSdXSOwFCuv78WaeVb35c3UGk3yT8UzeJWCIctYomYJlPK12Sx+nkqjwCtielbHK5vzUVkko75jEILuCfS9eW+KrWu9Ule23tsTcovKYtrAU5S+6hORXDTRdzqJAAXPpnRU5rvwUIWK0lUMT7edNPrffczBGON2DTa2DpZ7fMFzd0c0JOcM7H98Fbp/i0P1CliI64jVhuBzSdDcDH5HFs+3D1wfOLCtMBdrA7a89XWJz+0dDwbXIZ7haNp2J7pO3oSUBRoeCcPlEO0O5FqYSCXQcviX0V8/2FFlAza3fBEyTavriQcrttc/XIKB8Sw8CqDQ5Cgyh0yDJNFQEAPFmogzV67jvd6hH4Y6YlttwH37jzxngfUUF4RdkeK1uEUZ6CZHRmfI0uMwTAsWDVBQVbFvy2qc+30Sh74b7hnu3L3bBmza0922tbbsjbdjm/73Bohhg7JGbgKBzv4beLYmHydOXcTRn8Y+HPlk7+s2INr48b6aDZGuqtK7qOIuBPwKAh4nVDKf2wEn/YpTEjAdN8gD3d8M48ehi82jn73ccRuw93CI/73cTLcUcc7z6IgMGgPXwJjqlCVZUWT4PTm4G+cnrk2ACbGzx5rGcoB/AP6XQx4dXg87AAAAAElFTkSuQmCC");
}
}
.markItUpContainer {
border: 1px solid #3c769d;
background: white;
padding: 5px 5px 2px 5px;
font: 11px Verdana, Arial, Helvetica, sans-serif;
}
.markItUpEditor {
padding: 5px 5px 5px 5px;
border: 3px solid #3c769d;
width: 99%;
height: 400px;
color: black;
background: white;
/* clear: both */
display: block;
font-family: monospace;
font-size: 14px;
line-height: 18px;
overflow: auto;
box-sizing: border-box;
}
.markItUpFooter {
width: 100%;
cursor: n-resize;
}
.markItUpResizeHandle {
display: none;
}
.markItUpHeader {
height: 22px;
ul {
li {
list-style: none;
float: left;
position: relative;
ul {
display: none;
}
&:hover > ul {
display: block;
}
}
a {
display: block;
width: 16px;
height: 16px;
text-indent: -10000px;
background-repeat: no-repeat;
padding: 3px;
margin: 0;
}
.markItUpSeparator {
margin: 0 10px;
width: 1px;
height: 16px;
overflow: hidden;
background-color: #cccccc;
}
}
}
textarea.markItUp:not(.markItUpEditor) {
width: 100%;
height: 10em;
}

25
elm.json Normal file
View File

@@ -0,0 +1,25 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/json": "1.1.4",
"elm-explorations/markdown": "1.0.0"
},
"indirect": {
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.4"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

View File

@@ -0,0 +1,58 @@
const mySettings = {
onTab: { keepDefault: true },
onShiftEnter: { keepDefault: false, openWith: '\n\n' },
markupSet: [
{ name:'Heading 1', key:"1", className: 'h1', openWith:'# ', placeHolder:'Your title here...' },
{ name:'Heading 2', key:"2", className: 'h2', openWith:'## ', placeHolder:'Your title here...' },
{ name:'Heading 3', key:"3", className: 'h3', openWith:'### ', placeHolder:'Your title here...' },
{ name:'Heading 4', key:"4", className: 'h4', openWith:'#### ', placeHolder:'Your title here...' },
{ name:'Heading 5', key:"5", className: 'h5', openWith:'##### ', placeHolder:'Your title here...' },
{ name:'Heading 6', key:"6", className: 'h6', openWith:'###### ', placeHolder:'Your title here...' },
{ separator: '---------------' },
{ name: 'Bold', openWith: '**', closeWith: '**', className: 'bold' },
{ name: 'Italic', openWith: '__', closeWith: '__', className: 'italic' },
{ name: 'Stroke', openWith: '~~', closeWith: '~~', className: 'stroke' },
{ name: 'Teletype', openWith: '`', closeWith: '`', className: 'teletype' },
{ separator: '---------------' },
{ name: 'Ruler', openWith: '---\n', closeWith: '', className: 'ruler' },
{ name: 'Bulleted List', openWith: '* ', className: 'list-bullet'},
{ name: 'Numeric List', className: 'list-numeric', openWith: function(m) { return m.line + '. '; } },
{ name: 'Task List', className: 'list-task', openWith: '- [ ] ', placeHolder: "task", closeWith:'\n' },
{ separator: '---------------' },
{ name: 'Picture', openWith: '![', closeWith: ']([![Url:!:http://]!])', placeHolder: "Titre de l'image", className: 'image' },
{ name: 'Link', openWith: '[', closeWith: ']([![Url:!:http://]!])', placeHolder: 'Texte du lien', className: 'link' },
{ separator: '---------------' },
{ name: 'Quotes', openWith: '> ', className: 'quotes' },
{ name: 'Code Block', className: 'code', openWith:'```[![langage:!:mermaid]!]\n', placeHolder: "code", closeWith:'\n```', multiline:false },
]
};
customElements.define('markitup-textarea', class extends HTMLElement {
constructor() {
super();
this._editor = document.createElement("textarea");
}
get editorValue() {
return this._editor.value;
}
set editorValue(value) {
if (this._editor.value === value) return;
if (!this._editor) return;
this._editor.value = value;
}
connectedCallback() {
const on = (e) => {
//console.debug("customElements markitup-textarea event", e);
this.dispatchEvent(new CustomEvent('editorChanged'));
};
this._editor.onchange = on;
this._editor.oninput = on;
this.appendChild(this._editor)
jQuery(this._editor).markItUp(mySettings); // decorate the textarea with toolbar
}
});

2
js/jquery-3.7.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
js/jquery.js vendored Symbolic link
View File

@@ -0,0 +1 @@
jquery-3.7.1.min.js

656
js/jquery.markitup-1.1.5.js Executable file
View File

@@ -0,0 +1,656 @@
// ----------------------------------------------------------------------------
// markItUp! Universal MarkUp Engine, JQuery plugin
// v 1.1.x
// Dual licensed under the MIT and GPL licenses.
// ----------------------------------------------------------------------------
// Copyright (C) 2007-2012 Jay Salvat
// http://markitup.jaysalvat.com/
// ----------------------------------------------------------------------------
(function($) {
$.fn.markItUp = function(settings, extraSettings) {
var method, params, options, ctrlKey, shiftKey, altKey; ctrlKey = shiftKey = altKey = false;
if (typeof settings == 'string') {
method = settings;
params = extraSettings;
}
options = { id: '',
nameSpace: '',
root: '',
previewHandler: false,
previewInWindow: '', // 'width=800, height=600, resizable=yes, scrollbars=yes'
previewInElement: '',
previewAutoRefresh: true,
previewPosition: 'after',
previewTemplatePath: '~/templates/preview.html',
previewParser: false,
previewParserPath: '',
previewParserVar: 'data',
previewParserAjaxType: 'POST',
resizeHandle: true,
beforeInsert: '',
afterInsert: '',
onEnter: {},
onShiftEnter: {},
onCtrlEnter: {},
onTab: {},
markupSet: [ { /* set */ } ]
};
$.extend(options, settings, extraSettings);
// compute markItUp! path
if (!options.root) {
$('script').each(function(a, tag) {
var miuScript = $(tag).get(0).src.match(/(.*)jquery\.markitup(\.pack)?\.js$/);
if (miuScript !== null) {
options.root = miuScript[1];
}
});
}
// Quick patch to keep compatibility with jQuery 1.9
var uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
var matched = uaMatch( navigator.userAgent );
var browser = {};
if (matched.browser) {
browser[matched.browser] = true;
browser.version = matched.version;
}
if (browser.chrome) {
browser.webkit = true;
} else if (browser.webkit) {
browser.safari = true;
}
return this.each(function() {
var $$, textarea, levels, scrollPosition, caretPosition, caretOffset,
clicked, hash, header, footer, previewWindow, template, iFrame, abort;
$$ = $(this);
textarea = this;
levels = [];
abort = false;
scrollPosition = caretPosition = 0;
caretOffset = -1;
options.previewParserPath = localize(options.previewParserPath);
options.previewTemplatePath = localize(options.previewTemplatePath);
if (method) {
switch(method) {
case 'remove':
remove();
break;
case 'insert':
markup(params);
break;
default:
$.error('Method ' + method + ' does not exist on jQuery.markItUp');
}
return;
}
// apply the computed path to ~/
function localize(data, inText) {
if (inText) {
return data.replace(/("|')~\//g, "$1"+options.root);
}
return data.replace(/^~\//, options.root);
}
// init and build editor
function init() {
id = ''; nameSpace = '';
if (options.id) {
id = 'id="'+options.id+'"';
} else if ($$.attr("id")) {
id = 'id="markItUp'+($$.attr("id").substr(0, 1).toUpperCase())+($$.attr("id").substr(1))+'"';
}
if (options.nameSpace) {
nameSpace = 'class="'+options.nameSpace+'"';
}
$$.wrap('<div '+nameSpace+'></div>');
$$.wrap('<div '+id+' class="markItUp"></div>');
$$.wrap('<div class="markItUpContainer"></div>');
$$.addClass("markItUpEditor");
// add the header before the textarea
header = $('<div class="markItUpHeader"></div>').insertBefore($$);
$(dropMenus(options.markupSet)).appendTo(header);
// add the footer after the textarea
footer = $('<div class="markItUpFooter"></div>').insertAfter($$);
// add the resize handle after textarea
if (options.resizeHandle === true && browser.safari !== true) {
resizeHandle = $('<div class="markItUpResizeHandle"></div>')
.insertAfter($$)
.bind("mousedown.markItUp", function(e) {
var h = $$.height(), y = e.clientY, mouseMove, mouseUp;
mouseMove = function(e) {
$$.css("height", Math.max(20, e.clientY+h-y)+"px");
return false;
};
mouseUp = function(e) {
$("html").unbind("mousemove.markItUp", mouseMove).unbind("mouseup.markItUp", mouseUp);
return false;
};
$("html").bind("mousemove.markItUp", mouseMove).bind("mouseup.markItUp", mouseUp);
});
footer.append(resizeHandle);
}
// listen key events
$$.bind('keydown.markItUp', keyPressed).bind('keyup', keyPressed);
// bind an event to catch external calls
$$.bind("insertion.markItUp", function(e, settings) {
if (settings.target !== false) {
get();
}
if (textarea === $.markItUp.focused) {
markup(settings);
}
});
// remember the last focus
$$.bind('focus.markItUp', function() {
$.markItUp.focused = this;
});
if (options.previewInElement) {
refreshPreview();
}
}
// recursively build header with dropMenus from markupset
function dropMenus(markupSet) {
var ul = $('<ul></ul>'), i = 0;
$('li:hover > ul', ul).css('display', 'block');
$.each(markupSet, function() {
var button = this, t = '', title, li, j;
button.title ? title = (button.key) ? (button.title||'')+' [Ctrl+'+button.key+']' : (button.title||'') : title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||'');
key = (button.key) ? 'accesskey="'+button.key+'"' : '';
if (button.separator) {
li = $('<li class="markItUpSeparator">'+(button.separator||'')+'</li>').appendTo(ul);
} else {
i++;
for (j = levels.length -1; j >= 0; j--) {
t += levels[j]+"-";
}
li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="#" '+key+' title="'+title+'">'+(button.name||'')+'</a></li>')
.bind("contextmenu.markItUp", function() { // prevent contextmenu on mac and allow ctrl+click
return false;
}).bind('click.markItUp', function(e) {
e.preventDefault();
}).bind("focusin.markItUp", function(){
$$.focus();
}).bind('mouseup', function(e) {
if (button.call) {
eval(button.call)(e); // Pass the mouseup event to custom delegate
}
setTimeout(function() { markup(button) },1);
return false;
}).bind('mouseenter.markItUp', function() {
$('> ul', this).show();
$(document).one('click', function() { // close dropmenu if click outside
$('ul ul', header).hide();
}
);
}).bind('mouseleave.markItUp', function() {
$('> ul', this).hide();
}).appendTo(ul);
if (button.dropMenu) {
levels.push(i);
$(li).addClass('markItUpDropMenu').append(dropMenus(button.dropMenu));
}
}
});
levels.pop();
return ul;
}
// markItUp! markups
function magicMarkups(string) {
if (string) {
string = string.toString();
string = string.replace(/\(\!\(([\s\S]*?)\)\!\)/g,
function(x, a) {
var b = a.split('|!|');
if (altKey === true) {
return (b[1] !== undefined) ? b[1] : b[0];
} else {
return (b[1] === undefined) ? "" : b[0];
}
}
);
// [![prompt]!], [![prompt:!:value]!]
string = string.replace(/\[\!\[([\s\S]*?)\]\!\]/g,
function(x, a) {
var b = a.split(':!:');
if (abort === true) {
return false;
}
value = prompt(b[0], (b[1]) ? b[1] : '');
if (value === null) {
abort = true;
}
return value;
}
);
return string;
}
return "";
}
// prepare action
function prepare(action) {
if ($.isFunction(action)) {
action = action(hash);
}
return magicMarkups(action);
}
// build block to insert
function build(string) {
var openWith = prepare(clicked.openWith);
var placeHolder = prepare(clicked.placeHolder);
var replaceWith = prepare(clicked.replaceWith);
var closeWith = prepare(clicked.closeWith);
var openBlockWith = prepare(clicked.openBlockWith);
var closeBlockWith = prepare(clicked.closeBlockWith);
var multiline = clicked.multiline;
if (replaceWith !== "") {
block = openWith + replaceWith + closeWith;
} else if (selection === '' && placeHolder !== '') {
block = openWith + placeHolder + closeWith;
} else {
string = string || selection;
var lines = [string], blocks = [];
if (multiline === true) {
lines = string.split(/\r?\n/);
}
for (var l = 0; l < lines.length; l++) {
line = lines[l];
var trailingSpaces;
if (trailingSpaces = line.match(/ *$/)) {
blocks.push(openWith + line.replace(/ *$/g, '') + closeWith + trailingSpaces);
} else {
blocks.push(openWith + line + closeWith);
}
}
block = blocks.join("\n");
}
block = openBlockWith + block + closeBlockWith;
return { block:block,
openBlockWith:openBlockWith,
openWith:openWith,
replaceWith:replaceWith,
placeHolder:placeHolder,
closeWith:closeWith,
closeBlockWith:closeBlockWith
};
}
// define markup to insert
function markup(button) {
var len, j, n, i;
hash = clicked = button;
get();
$.extend(hash, { line:"",
root:options.root,
textarea:textarea,
selection:(selection||''),
caretPosition:caretPosition,
ctrlKey:ctrlKey,
shiftKey:shiftKey,
altKey:altKey
}
);
// callbacks before insertion
prepare(options.beforeInsert);
prepare(clicked.beforeInsert);
if ((ctrlKey === true && shiftKey === true) || button.multiline === true) {
prepare(clicked.beforeMultiInsert);
}
$.extend(hash, { line:1 });
if ((ctrlKey === true && shiftKey === true)) {
lines = selection.split(/\r?\n/);
for (j = 0, n = lines.length, i = 0; i < n; i++) {
if ($.trim(lines[i]) !== '') {
$.extend(hash, { line:++j, selection:lines[i] } );
lines[i] = build(lines[i]).block;
} else {
lines[i] = "";
}
}
string = { block:lines.join('\n')};
start = caretPosition;
len = string.block.length + ((browser.opera) ? n-1 : 0);
} else if (ctrlKey === true) {
string = build(selection);
start = caretPosition + string.openWith.length;
len = string.block.length - string.openWith.length - string.closeWith.length;
len = len - (string.block.match(/ $/) ? 1 : 0);
len -= fixIeBug(string.block);
} else if (shiftKey === true) {
string = build(selection);
start = caretPosition;
len = string.block.length;
len -= fixIeBug(string.block);
} else {
string = build(selection);
start = caretPosition + string.block.length ;
len = 0;
start -= fixIeBug(string.block);
}
if ((selection === '' && string.replaceWith === '')) {
caretOffset += fixOperaBug(string.block);
start = caretPosition + string.openBlockWith.length + string.openWith.length;
len = string.block.length - string.openBlockWith.length - string.openWith.length - string.closeWith.length - string.closeBlockWith.length;
caretOffset = $$.val().substring(caretPosition, $$.val().length).length;
caretOffset -= fixOperaBug($$.val().substring(0, caretPosition));
}
$.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } );
if (string.block !== selection && abort === false) {
insert(string.block);
set(start, len);
} else {
caretOffset = -1;
}
get();
$.extend(hash, { line:'', selection:selection });
// callbacks after insertion
if ((ctrlKey === true && shiftKey === true) || button.multiline === true) {
prepare(clicked.afterMultiInsert);
}
prepare(clicked.afterInsert);
prepare(options.afterInsert);
$$.trigger("change");
// refresh preview if opened
if (previewWindow && options.previewAutoRefresh) {
refreshPreview();
}
// reinit keyevent
shiftKey = altKey = ctrlKey = abort = false;
}
// Substract linefeed in Opera
function fixOperaBug(string) {
if (browser.opera) {
return string.length - string.replace(/\n*/g, '').length;
}
return 0;
}
// Substract linefeed in IE
function fixIeBug(string) {
if (browser.msie) {
return string.length - string.replace(/\r*/g, '').length;
}
return 0;
}
// add markup
function insert(block) {
if (document.selection) {
var newSelection = document.selection.createRange();
newSelection.text = block;
} else {
textarea.value = textarea.value.substring(0, caretPosition) + block + textarea.value.substring(caretPosition + selection.length, textarea.value.length);
}
}
// set a selection
function set(start, len) {
if (textarea.createTextRange){
// quick fix to make it work on Opera 9.5
if (browser.opera && browser.version >= 9.5 && len == 0) {
return false;
}
range = textarea.createTextRange();
range.collapse(true);
range.moveStart('character', start);
range.moveEnd('character', len);
range.select();
} else if (textarea.setSelectionRange ){
textarea.setSelectionRange(start, start + len);
}
textarea.scrollTop = scrollPosition;
textarea.focus();
}
// get the selection
function get() {
textarea.focus();
scrollPosition = textarea.scrollTop;
if (document.selection) {
selection = document.selection.createRange().text;
if (browser.msie) { // ie
var range = document.selection.createRange(), rangeCopy = range.duplicate();
rangeCopy.moveToElementText(textarea);
caretPosition = -1;
while(rangeCopy.inRange(range)) {
rangeCopy.moveStart('character');
caretPosition ++;
}
} else { // opera
caretPosition = textarea.selectionStart;
}
} else { // gecko & webkit
caretPosition = textarea.selectionStart;
selection = textarea.value.substring(caretPosition, textarea.selectionEnd);
}
return selection;
}
// open preview window
function preview() {
if (typeof options.previewHandler === 'function') {
previewWindow = true;
} else if (options.previewInElement) {
previewWindow = $(options.previewInElement);
} else if (!previewWindow || previewWindow.closed) {
if (options.previewInWindow) {
previewWindow = window.open('', 'preview', options.previewInWindow);
$(window).unload(function() {
previewWindow.close();
});
} else {
iFrame = $('<iframe class="markItUpPreviewFrame"></iframe>');
if (options.previewPosition == 'after') {
iFrame.insertAfter(footer);
} else {
iFrame.insertBefore(header);
}
previewWindow = iFrame[iFrame.length - 1].contentWindow || frame[iFrame.length - 1];
}
} else if (altKey === true) {
if (iFrame) {
iFrame.remove();
} else {
previewWindow.close();
}
previewWindow = iFrame = false;
}
if (!options.previewAutoRefresh) {
refreshPreview();
}
if (options.previewInWindow) {
previewWindow.focus();
}
}
// refresh Preview window
function refreshPreview() {
renderPreview();
}
function renderPreview() {
var phtml;
var parsedData = $$.val();
if (options.previewParser && typeof options.previewParser === 'function') {
parsedData = options.previewParser(parsedData);
}
if (options.previewHandler && typeof options.previewHandler === 'function') {
options.previewHandler(parsedData);
} else if (options.previewParserPath !== '') {
$.ajax({
type: options.previewParserAjaxType,
dataType: 'text',
global: false,
url: options.previewParserPath,
data: options.previewParserVar+'='+encodeURIComponent(parsedData),
success: function(data) {
writeInPreview( localize(data, 1) );
}
});
} else {
if (!template) {
$.ajax({
url: options.previewTemplatePath,
dataType: 'text',
global: false,
success: function(data) {
writeInPreview( localize(data, 1).replace(/<!-- content -->/g, parsedData) );
}
});
}
}
return false;
}
function writeInPreview(data) {
if (options.previewInElement) {
$(options.previewInElement).html(data);
} else if (previewWindow && previewWindow.document) {
try {
sp = previewWindow.document.documentElement.scrollTop
} catch(e) {
sp = 0;
}
previewWindow.document.open();
previewWindow.document.write(data);
previewWindow.document.close();
previewWindow.document.documentElement.scrollTop = sp;
}
}
// set keys pressed
function keyPressed(e) {
shiftKey = e.shiftKey;
altKey = e.altKey;
ctrlKey = (!(e.altKey && e.ctrlKey)) ? (e.ctrlKey || e.metaKey) : false;
if (e.type === 'keydown') {
if (ctrlKey === true) {
li = $('a[accesskey="'+((e.keyCode == 13) ? '\\n' : String.fromCharCode(e.keyCode))+'"]', header).parent('li');
if (li.length !== 0) {
ctrlKey = false;
setTimeout(function() {
li.triggerHandler('mouseup');
},1);
return false;
}
}
if (e.keyCode === 13 || e.keyCode === 10) { // Enter key
if (ctrlKey === true) { // Enter + Ctrl
ctrlKey = false;
markup(options.onCtrlEnter);
return options.onCtrlEnter.keepDefault;
} else if (shiftKey === true) { // Enter + Shift
shiftKey = false;
markup(options.onShiftEnter);
return options.onShiftEnter.keepDefault;
} else { // only Enter
markup(options.onEnter);
return options.onEnter.keepDefault;
}
}
if (e.keyCode === 9) { // Tab key
if (shiftKey == true || ctrlKey == true || altKey == true) {
return false;
}
if (caretOffset !== -1) {
get();
caretOffset = $$.val().length - caretOffset;
set(caretOffset, 0);
caretOffset = -1;
return false;
} else {
markup(options.onTab);
return options.onTab.keepDefault;
}
}
}
}
function remove() {
$$.unbind(".markItUp").removeClass('markItUpEditor');
$$.parent('div').parent('div.markItUp').parent('div').replaceWith($$);
var relativeRef = $$.parent('div').parent('div.markItUp').parent('div');
if (relativeRef.length) {
relativeRef.replaceWith($$);
}
$$.data('markItUp', null);
}
init();
});
};
$.fn.markItUpRemove = function() {
return this.each(function() {
$(this).markItUp('remove');
}
);
};
$.markItUp = function(settings) {
var options = { target:false };
$.extend(options, settings);
if (options.target) {
return $(options.target).each(function() {
$(this).focus();
$(this).trigger('insertion', [options]);
});
} else {
$('textarea').trigger('insertion', [options]);
}
};
})(jQuery);

1
js/jquery.markitup.js Symbolic link
View File

@@ -0,0 +1 @@
jquery.markitup-1.1.5.js

18
miu-demo.html Normal file
View File

@@ -0,0 +1,18 @@
<html>
<head>
<title>Markitup Custom Element Demo</title>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.markitup.js"></script>
<script type='text/javascript' src='js/custom-element-markitup.js'></script>
<script type='text/javascript' src='js/miu-demo.js'></script>
<link rel="stylesheet" type="text/css" href="css/markitup-skin-simple.css" />
<link rel="stylesheet" type="text/css" href="css/mdset.css" />
</head>
<body>
<div id='elm'></div>
<script type='text/javascript'>
Elm.Miu.init({node: document.getElementById('elm')});
</script>
</body>
</html>

68
src/Miu.elm Normal file
View File

@@ -0,0 +1,68 @@
module Miu exposing (main)
import Browser
import Html exposing (Attribute, Html, a, br, div, h2, hr, p, text)
import Html.Attributes exposing (href, property)
import Html.Events exposing (on)
import Json.Decode as JD exposing (Decoder)
import Json.Encode as JE exposing (Value)
import Markdown
main =
Browser.sandbox
{ init = { value = "## Preview" }
, update = update
, view = view
}
type alias Model =
{ value : String
}
type Msg
= CodeChanged String
update : Msg -> Model -> Model
update msg model =
case msg of
CodeChanged value ->
{ model | value = value }
{-| Here's our custom element, defined in js/custom-element-markitup.js
-}
markItUp : List (Attribute msg) -> List (Html msg) -> Html msg
markItUp =
Html.node "markitup-textarea"
{-| This is how you set the contents of the editor.
-}
editorValue : String -> Attribute msg
editorValue value =
property "editorValue" <|
JE.string value
{-| This is how you receive changes to the contents of the editor.
-}
onEditorChanged : (String -> msg) -> Attribute msg
onEditorChanged tagger =
on "editorChanged" <|
JD.map tagger <|
JD.at [ "target", "editorValue" ]
JD.string
view : Model -> Html Msg
view model =
div []
[ h2 [] [ text "Markitup Custom Element from Elm" ]
, markItUp [ editorValue model.value, onEditorChanged CodeChanged ] []
, hr [] []
, Markdown.toHtml [] model.value
]