2023-03-21 16:50:02 +08:00
|
|
|
/**
|
|
|
|
* {}
|
|
|
|
* @author yutent<yutent.io@gmail.com>
|
|
|
|
* @date 2023/03/20 18:02:01
|
|
|
|
*/
|
|
|
|
import { html, css, Component, nextTick } from '@bd/core'
|
|
|
|
|
|
|
|
class Code extends Component {
|
|
|
|
static props = {
|
|
|
|
code: { type: String, default: '', attribute: false },
|
|
|
|
lang: ''
|
|
|
|
}
|
|
|
|
|
|
|
|
static styles = [
|
|
|
|
css`
|
|
|
|
:host {
|
|
|
|
display: flex;
|
|
|
|
border-radius: 3px;
|
|
|
|
}
|
|
|
|
.code-box {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
position: relative;
|
|
|
|
width: 100%;
|
|
|
|
margin: 10px 0;
|
2023-04-21 17:31:40 +08:00
|
|
|
padding-bottom: 6px;
|
2023-03-21 16:50:02 +08:00
|
|
|
border-radius: 3px;
|
|
|
|
background: #f7f8fb;
|
|
|
|
color: var(--color-dark-1);
|
|
|
|
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
|
.title {
|
|
|
|
flex-shrink: 0;
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
width: 100%;
|
|
|
|
height: 32px;
|
|
|
|
padding: 0 12px;
|
|
|
|
line-height: 1;
|
|
|
|
font-size: 14px;
|
|
|
|
user-select: none;
|
|
|
|
|
|
|
|
section {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
i {
|
|
|
|
display: block;
|
|
|
|
width: 12px;
|
|
|
|
height: 12px;
|
|
|
|
margin-right: 6px;
|
|
|
|
border-radius: 50%;
|
|
|
|
background: var(--color-red-1);
|
|
|
|
|
|
|
|
&:nth-child(2) {
|
|
|
|
background: var(--color-orange-1);
|
|
|
|
}
|
|
|
|
&:nth-child(3) {
|
|
|
|
background: var(--color-green-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
css`
|
|
|
|
.code-block {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
overflow: hidden;
|
|
|
|
overflow-y: auto;
|
|
|
|
line-height: 20px;
|
|
|
|
font-size: 14px;
|
|
|
|
color: var(--color-dark-1);
|
|
|
|
cursor: text;
|
|
|
|
counter-reset: code;
|
|
|
|
|
|
|
|
code {
|
|
|
|
display: block;
|
|
|
|
position: relative;
|
|
|
|
min-height: 20px;
|
|
|
|
padding: 0 8px 0 45px;
|
|
|
|
font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
|
|
|
|
white-space: pre-wrap;
|
|
|
|
word-break: break-word;
|
|
|
|
|
|
|
|
&::before {
|
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
width: 40px;
|
|
|
|
height: 100%;
|
|
|
|
padding-right: 5px;
|
|
|
|
text-align: right;
|
|
|
|
color: var(--color-grey-1);
|
|
|
|
content: counter(code);
|
|
|
|
counter-increment: code;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`
|
|
|
|
]
|
|
|
|
|
|
|
|
mounted() {
|
|
|
|
var txt = this.innerHTML || this.textContent
|
|
|
|
txt = txt.trim().replace(/^[\r\n]|\s{2,}$/g, '')
|
|
|
|
if (txt.startsWith('<xmp>') && txt.endsWith('</xmp>')) {
|
|
|
|
txt = txt.slice(5, -6).trim()
|
|
|
|
}
|
|
|
|
if (txt) {
|
|
|
|
this.textContent = ''
|
|
|
|
nextTick(_ => {
|
|
|
|
this.code = txt.replace(/</g, '<').replace(/>/g, '>')
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return html`
|
|
|
|
<div class="code-box">
|
|
|
|
<header class="title">
|
|
|
|
<section><i></i><i></i><i></i></section>
|
|
|
|
<section>${this.lang}</section>
|
|
|
|
</header>
|
|
|
|
<div class="code-block">
|
|
|
|
${this.code.split('\n').map(s => html`<code>${s}</code>`)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Code.reg('code')
|