完成富文本编辑器的移植
parent
e057349494
commit
d5e8ddb613
|
@ -4,7 +4,19 @@
|
|||
* @date 2023/09/14 16:49:15
|
||||
*/
|
||||
|
||||
import { css, raw, html, Component, nextTick, styleMap } from 'wkit'
|
||||
import {
|
||||
css,
|
||||
raw,
|
||||
html,
|
||||
Component,
|
||||
bind,
|
||||
unbind,
|
||||
nextTick,
|
||||
styleMap,
|
||||
classMap,
|
||||
outsideClick,
|
||||
clearOutsideClick
|
||||
} from 'wkit'
|
||||
import ICONS from './svg.js'
|
||||
import '../form/input.js'
|
||||
import '../form/button.js'
|
||||
|
@ -34,11 +46,13 @@ const DEFAULT_TOOLS = [
|
|||
'delete',
|
||||
'ordered',
|
||||
'unordered',
|
||||
'table',
|
||||
'left',
|
||||
'center',
|
||||
'right',
|
||||
'link',
|
||||
'image'
|
||||
'image',
|
||||
'fullscreen'
|
||||
]
|
||||
|
||||
const COLORS = [
|
||||
|
@ -56,7 +70,18 @@ const COLORS = [
|
|||
'#000000'
|
||||
]
|
||||
|
||||
// 获取一维数组转二维的行
|
||||
function getY(i) {
|
||||
return (i / 9) >> 0
|
||||
}
|
||||
//获取一维数组转二维的列
|
||||
function getX(i) {
|
||||
return i % 9
|
||||
}
|
||||
|
||||
class Editor extends Component {
|
||||
static watches = ['value']
|
||||
|
||||
static props = {
|
||||
toolbar: {
|
||||
type: String,
|
||||
|
@ -70,9 +95,18 @@ class Editor extends Component {
|
|||
}
|
||||
}
|
||||
},
|
||||
value: 'str!',
|
||||
readonly: false,
|
||||
disabled: false
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
observer(v) {
|
||||
this.#updateStat()
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
observer(v) {
|
||||
this.#updateStat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static styles = [
|
||||
|
@ -84,6 +118,7 @@ class Editor extends Component {
|
|||
max-height: 720px;
|
||||
border-radius: 3px;
|
||||
transition: box-shadow 0.15s linear;
|
||||
background: var(--wc-editor-background, #fff);
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
|
@ -132,7 +167,7 @@ class Editor extends Component {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
border: 1px solid #e7e8eb;
|
||||
border: 1px solid var(--wc-editor-border-color, var(--color-grey-2));
|
||||
border-radius: inherit;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -141,7 +176,7 @@ class Editor extends Component {
|
|||
height: 34px;
|
||||
padding: 5px;
|
||||
line-height: 24px;
|
||||
border-bottom: 1px solid #e7e8eb;
|
||||
border-bottom: 1px solid var(--color-grey-1);
|
||||
|
||||
span {
|
||||
position: relative;
|
||||
|
@ -189,10 +224,13 @@ class Editor extends Component {
|
|||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.is-vertical {
|
||||
// visibility: hidden;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
@ -200,17 +238,15 @@ class Editor extends Component {
|
|||
justify-content: flex-end;
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
// opacity: 0;
|
||||
transition: opacity 0.3s linear, visibility 0.3s linear;
|
||||
|
||||
.thumb {
|
||||
display: block;
|
||||
width: 6px;
|
||||
height: 90px;
|
||||
height: 0;
|
||||
border-radius: 5px;
|
||||
background: rgba(44, 47, 53, 0.25);
|
||||
cursor: default;
|
||||
transition: width 0.1s linear, height 0.1s linear;
|
||||
transition: width 0.1s linear;
|
||||
|
||||
&:hover {
|
||||
width: 10px;
|
||||
|
@ -222,6 +258,7 @@ class Editor extends Component {
|
|||
.typearea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 54px;
|
||||
outline: none;
|
||||
text-wrap: wrap;
|
||||
word-break: break-all;
|
||||
|
@ -233,10 +270,10 @@ class Editor extends Component {
|
|||
`,
|
||||
|
||||
css`
|
||||
:host(:hover) {
|
||||
.is-vertical {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
:host([readonly]) {
|
||||
.editor {
|
||||
cursor: default;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
:host([disabled]) {
|
||||
|
@ -245,13 +282,6 @@ class Editor extends Component {
|
|||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
:host([readonly]) {
|
||||
.editor {
|
||||
cursor: default;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
:host([readonly]),
|
||||
:host([disabled]) {
|
||||
.toolbar {
|
||||
|
@ -264,6 +294,17 @@ class Editor extends Component {
|
|||
:host(:focus-within) {
|
||||
box-shadow: 0 0 0 2px var(--color-plain-a);
|
||||
}
|
||||
|
||||
:host(.fullscreen) {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
max-height: 100vh;
|
||||
border-radius: 0;
|
||||
}
|
||||
`,
|
||||
|
||||
css`
|
||||
|
@ -271,7 +312,8 @@ class Editor extends Component {
|
|||
|
||||
.font-layer,
|
||||
.color-layer,
|
||||
.link-layer {
|
||||
.link-layer,
|
||||
.table-layer {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
@ -326,6 +368,27 @@ class Editor extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
.table-layer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
left: 240px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 2px;
|
||||
background: #fff;
|
||||
|
||||
span {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: var(--color-plain-1);
|
||||
|
||||
&.active {
|
||||
background: rgba(77, 182, 172, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.link-layer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -342,6 +405,384 @@ class Editor extends Component {
|
|||
]
|
||||
|
||||
#toolbar = []
|
||||
#value = ''
|
||||
#cache = { bar: 0, y: 0 }
|
||||
#gridx = 0
|
||||
#gridy = 0
|
||||
|
||||
#select = null
|
||||
|
||||
get value() {
|
||||
let html = this.$refs.editor?.innerHTML || ''
|
||||
|
||||
html = html.replace(/<\!\-\-(.*?)\-\->/g, '')
|
||||
if (~html.indexOf('<table>') && !html.startsWith('<style>table')) {
|
||||
html =
|
||||
'<style>table{border-spacing:0;border-collapse:collapse;}table tr{background:#fff;}table thead tr{background:#f3f5fb;}table th,table td{padding:6px 12px;border:1px solid #dae1e9;}table th{font-weight: bold;}</style>' +
|
||||
html
|
||||
}
|
||||
return html
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
if (this.$refs.editor) {
|
||||
this.#value = val
|
||||
this.$refs.editor.innerHTML = val
|
||||
} else {
|
||||
nextTick(_ => (this.value = val))
|
||||
}
|
||||
}
|
||||
|
||||
__init__() {
|
||||
//
|
||||
let { outer, inner, thumb } = this.$refs
|
||||
let height = outer.offsetHeight
|
||||
let scrollHeight = inner.scrollHeight + 10
|
||||
|
||||
let bar = 50 // 滚动条的高度
|
||||
bar = (height * (height / scrollHeight)) >> 0
|
||||
|
||||
if (bar < 50) {
|
||||
bar = 50
|
||||
}
|
||||
|
||||
// 100%或主体高度比滚动条还短时不显示
|
||||
if (bar >= height) {
|
||||
bar = 0
|
||||
}
|
||||
|
||||
this.#cache.bar = bar
|
||||
thumb.style.height = bar + 'px'
|
||||
}
|
||||
|
||||
#updateStat() {
|
||||
if (this.$refs.editor) {
|
||||
if (this.readOnly || this.disabled) {
|
||||
this.$refs.editor.removeAttribute('contenteditable')
|
||||
} else {
|
||||
this.$refs.editor.setAttribute('contenteditable', '')
|
||||
}
|
||||
} else {
|
||||
nextTick(_ => this.#updateStat())
|
||||
}
|
||||
}
|
||||
|
||||
#fetchScroll(moveY) {
|
||||
let { bar } = this.#cache
|
||||
let { outer, thumb, inner } = this.$refs
|
||||
let height = outer.offsetHeight
|
||||
let scrollHeight = inner.scrollHeight + 10
|
||||
|
||||
if (moveY < 0) {
|
||||
moveY = 0
|
||||
} else if (moveY > height - bar) {
|
||||
moveY = height - bar
|
||||
}
|
||||
|
||||
inner.scrollTop = (scrollHeight - height) * (moveY / (height - bar))
|
||||
thumb.style.transform = `translateY(${moveY}px)`
|
||||
return moveY
|
||||
}
|
||||
|
||||
#hideLayers() {
|
||||
this.$refs.font.classList.remove('fadein')
|
||||
this.$refs.color.classList.remove('fadein')
|
||||
this.$refs.link.classList.remove('fadein')
|
||||
this.$refs.table.classList.remove('fadein')
|
||||
}
|
||||
|
||||
// 处理图片
|
||||
#handleImage(ev, file) {
|
||||
if (ev && ev.type === 'change') {
|
||||
file = ev.target.files[0]
|
||||
ev.target.value = ''
|
||||
}
|
||||
this.$emit('upload', {
|
||||
detail: {
|
||||
file,
|
||||
send: link => {
|
||||
this.$refs.editor.focus()
|
||||
this.restoreSelection()
|
||||
this.exec(ACTTION.image, link)
|
||||
this.saveSelection()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#handlePaste(ev) {
|
||||
let html = ev.clipboardData.getData('text/html')
|
||||
let txt = ev.clipboardData.getData('text/plain')
|
||||
let items = ev.clipboardData.items
|
||||
|
||||
// 先文件判断, 避免右键单击复制图片时, 当成html处理
|
||||
if (items && items.length) {
|
||||
let blob = null
|
||||
for (let it of items) {
|
||||
if (it.type.indexOf('image') > -1) {
|
||||
blob = it.getAsFile()
|
||||
}
|
||||
}
|
||||
|
||||
if (blob) {
|
||||
return this.#handleImage(null, blob)
|
||||
}
|
||||
}
|
||||
|
||||
if (html) {
|
||||
html = html
|
||||
.replace(/\t/g, ' ')
|
||||
.replace(/<\/?(meta|link|script)[^>]*?>/g, '')
|
||||
.replace(/<!--[\w\W]*?-->/g, '')
|
||||
.replace(
|
||||
/<a[^>]*? href\s?=\s?["']?([^"']*)["']?[^>]*?>/g,
|
||||
'<a href="$1">'
|
||||
)
|
||||
.replace(
|
||||
/<img[^>]*? src\s?=\s?["']?([^"']*)["']?[^>]*?>/g,
|
||||
'<img src="$1">'
|
||||
)
|
||||
.replace(/<(?!a|img)([\w\-]+)[^>]*>/g, '<$1>')
|
||||
.replace(/<xml[^>]*?>[\w\W]*?<\/xml>/g, '')
|
||||
.replace(/<style>[\w\W]*?<\/style>/g, '')
|
||||
|
||||
return this.exec('insertHtml', html)
|
||||
}
|
||||
|
||||
if (txt) {
|
||||
return this.exec('insertText', txt)
|
||||
}
|
||||
}
|
||||
|
||||
#toolbarClick(ev) {
|
||||
var target = ev.target
|
||||
var act
|
||||
|
||||
this.restoreSelection()
|
||||
|
||||
if (ev.target === ev.currentTarget) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.readOnly || this.disabled) {
|
||||
return
|
||||
}
|
||||
|
||||
while (target.tagName !== 'SPAN') {
|
||||
target = target.parentNode
|
||||
}
|
||||
|
||||
act = target.dataset.act
|
||||
|
||||
this.#hideLayers()
|
||||
|
||||
switch (act) {
|
||||
case 'font':
|
||||
case 'color':
|
||||
case 'link':
|
||||
case 'table':
|
||||
this.$refs[act].classList.add('fadein')
|
||||
break
|
||||
|
||||
case 'image':
|
||||
// 这里不作任何处理
|
||||
break
|
||||
|
||||
case 'copy':
|
||||
navigator.clipboard.writeText(this.value)
|
||||
break
|
||||
|
||||
case 'fullscreen':
|
||||
this.classList.toggle('fullscreen')
|
||||
break
|
||||
|
||||
default:
|
||||
this.$refs.editor.focus()
|
||||
this.restoreSelection()
|
||||
this.exec(ACTTION[act])
|
||||
this.saveSelection()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
#chnageFontSize(ev) {
|
||||
if (ev.target === ev.currentTarget) {
|
||||
return
|
||||
}
|
||||
this.$refs.font.classList.remove('fadein')
|
||||
this.$refs.editor.focus()
|
||||
this.restoreSelection()
|
||||
this.exec(ACTTION.font, ev.target.dataset.size)
|
||||
this.saveSelection()
|
||||
}
|
||||
|
||||
#chnageColor(ev) {
|
||||
if (ev.target === ev.currentTarget) {
|
||||
return
|
||||
}
|
||||
this.$refs.color.classList.remove('fadein')
|
||||
this.$refs.editor.focus()
|
||||
this.restoreSelection()
|
||||
this.exec(ACTTION.color, ev.target.dataset.value)
|
||||
this.saveSelection()
|
||||
}
|
||||
|
||||
#insertLink(ev) {
|
||||
let value = this.$refs.linkinput.value.trim()
|
||||
if (value) {
|
||||
this.$refs.link.classList.remove('fadein')
|
||||
this.$refs.editor.focus()
|
||||
this.restoreSelection()
|
||||
this.exec(ACTTION.link, value)
|
||||
this.saveSelection()
|
||||
this.$refs.linkinput.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
#insertTable(ev) {
|
||||
let th = `<th> </th>`.repeat(this.#gridx + 1)
|
||||
let td = `<td> </td>`.repeat(this.#gridx + 1)
|
||||
this.exec(
|
||||
'insertHtml',
|
||||
`<br>
|
||||
<table>
|
||||
<thead><tr>${th}</tr></thead>
|
||||
<tbody>${`<tr>${td}</tr>`.repeat(this.#gridy + 1)}</tbody>
|
||||
</table><br>`
|
||||
)
|
||||
this.$refs.table.classList.remove('fadein')
|
||||
}
|
||||
|
||||
#tableSelect(ev) {
|
||||
let grids = Array.from(this.$refs.table.children)
|
||||
if (ev.type === 'mousemove') {
|
||||
if (ev.target === ev.currentTarget) {
|
||||
return
|
||||
}
|
||||
let idx = +ev.target.dataset.idx
|
||||
let x = getX(idx)
|
||||
let y = getY(idx)
|
||||
|
||||
if (x === this.#gridx && y === this.#gridy) {
|
||||
return
|
||||
}
|
||||
this.#gridx = x
|
||||
this.#gridy = y
|
||||
|
||||
for (let i = 0; i < grids.length; i++) {
|
||||
let _x = getX(i)
|
||||
let _y = getY(i)
|
||||
grids[i].classList.toggle('active', _x <= x && _y <= y)
|
||||
}
|
||||
} else {
|
||||
grids.forEach(it => it.classList.remove('active'))
|
||||
}
|
||||
}
|
||||
|
||||
// 保存选中
|
||||
saveSelection() {
|
||||
var gs = this.root.getSelection()
|
||||
if (gs.getRangeAt && gs.rangeCount) {
|
||||
this.#select = gs.getRangeAt(0)
|
||||
}
|
||||
}
|
||||
|
||||
// 清除选中并重置选中
|
||||
restoreSelection() {
|
||||
var gs = this.root.getSelection()
|
||||
if (this.#select) {
|
||||
try {
|
||||
gs.removeAllRanges()
|
||||
} catch (err) {}
|
||||
gs.addRange(this.#select)
|
||||
}
|
||||
}
|
||||
// 执行命令
|
||||
exec(cmd, val = '') {
|
||||
document.execCommand(cmd, false, val)
|
||||
}
|
||||
|
||||
mounted() {
|
||||
let startY,
|
||||
moveY,
|
||||
mousemoveFn = ev => {
|
||||
let { y } = this.#cache
|
||||
if (startY !== undefined) {
|
||||
moveY = this.#fetchScroll(y + ev.pageY - startY)
|
||||
}
|
||||
},
|
||||
mouseupFn = ev => {
|
||||
startY = undefined
|
||||
this.#cache.y = moveY || 0
|
||||
delete this._active
|
||||
unbind(document, 'mousemove', mousemoveFn)
|
||||
unbind(document, 'mouseup', mouseupFn)
|
||||
}
|
||||
|
||||
this.exec('styleWithCSS', true)
|
||||
|
||||
bind(this.$refs.thumb, 'mousedown', ev => {
|
||||
startY = ev.pageY
|
||||
|
||||
this._active = true
|
||||
this.#hideLayers()
|
||||
|
||||
bind(document, 'mousemove', mousemoveFn)
|
||||
bind(document, 'mouseup', mouseupFn)
|
||||
})
|
||||
|
||||
// 鼠标滚动事件
|
||||
bind(this.$refs.inner, 'scroll', ev => {
|
||||
// 拖拽时忽略滚动事件
|
||||
if (this._active) {
|
||||
return
|
||||
}
|
||||
|
||||
let { bar, y } = this.#cache
|
||||
let { outer, thumb, inner } = this.$refs
|
||||
let height = outer.offsetHeight
|
||||
let scrollHeight = inner.scrollHeight + 10
|
||||
let scrollTop = inner.scrollTop
|
||||
|
||||
this.#hideLayers()
|
||||
|
||||
// y轴 都为0时, 不作任何处理
|
||||
if (bar === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
// 修正滚动条的位置
|
||||
// 滚动比例 y 滚动条的可移动距离
|
||||
let fixedY = ~~((scrollTop / (scrollHeight - height)) * (height - bar))
|
||||
|
||||
if (fixedY !== y) {
|
||||
this.#cache.y = fixedY
|
||||
thumb.style.transform = `translateY(${fixedY}px)`
|
||||
}
|
||||
})
|
||||
|
||||
this._clickoutsideFn = outsideClick(this, _ => this.#hideLayers())
|
||||
|
||||
this._scrollFn = new ResizeObserver(this.__init__.bind(this))
|
||||
this._scrollFn.observe(this.$refs.cont)
|
||||
|
||||
this._inputFn = new MutationObserver(_ => {
|
||||
this.$emit('input')
|
||||
})
|
||||
|
||||
this._inputFn.observe(this.$refs.editor, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
characterData: true
|
||||
})
|
||||
}
|
||||
|
||||
unmounted() {
|
||||
this._scrollFn?.disconnect()
|
||||
this._inputFn?.disconnect()
|
||||
|
||||
clearOutsideClick(this._clickoutsideFn)
|
||||
}
|
||||
|
||||
render() {
|
||||
toolbar = [
|
||||
|
@ -351,7 +792,7 @@ class Editor extends Component {
|
|||
|
||||
return html`
|
||||
<div class="editor">
|
||||
<section class="toolbar">
|
||||
<section class="toolbar" @click=${this.#toolbarClick}>
|
||||
${toolbar.map(
|
||||
it => html`
|
||||
<span data-act=${it}>
|
||||
|
@ -359,35 +800,65 @@ class Editor extends Component {
|
|||
<path d=${ICONS[it]} />
|
||||
</svg>
|
||||
${it === 'image'
|
||||
? html`<input type="file" accept="image/*" />`
|
||||
? html`<input
|
||||
type="file"
|
||||
:disabled=${this.readOnly || this.disabled}
|
||||
@change=${this.#handleImage}
|
||||
accept="image/*"
|
||||
/>`
|
||||
: ''}
|
||||
</span>
|
||||
`
|
||||
)}
|
||||
</section>
|
||||
<div class="scroll-outerbox">
|
||||
<div class="scroll-innerbox">
|
||||
<div contenteditable="true" class="typearea" spellcheck="false">
|
||||
${raw(this.value)}
|
||||
<div class="scroll-outerbox" ref="outer">
|
||||
<div class="scroll-innerbox" ref="inner">
|
||||
<div class="wrapper" ref="cont" @click=${this.#hideLayers}>
|
||||
<div
|
||||
ref="editor"
|
||||
contenteditable="true"
|
||||
class="typearea"
|
||||
@mouseleave=${this.saveSelection}
|
||||
@paste.prevent=${this.#handlePaste}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="is-vertical noselect">
|
||||
<span ref="y" class="thumb"></span>
|
||||
<span class="thumb" ref="thumb"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="font-layer noselect">
|
||||
<div
|
||||
class="font-layer noselect"
|
||||
ref="font"
|
||||
@click=${this.#chnageFontSize}
|
||||
>
|
||||
<span data-size="6">6号字体</span>
|
||||
<span data-size="5">5号字体</span>
|
||||
<span data-size="4">4号字体</span>
|
||||
<span data-size="3">3号字体</span>
|
||||
<span data-size="2">2号字体</span>
|
||||
</div>
|
||||
<div class="color-layer noselect">
|
||||
<div
|
||||
class="color-layer noselect"
|
||||
ref="color"
|
||||
@click=${this.#chnageColor}
|
||||
>
|
||||
${COLORS.map(c => html`<span data-value=${c}></span>`)}
|
||||
</div>
|
||||
<div class="link-layer noselect">
|
||||
<wc-input label="请输入链接地址"></wc-input>
|
||||
<wc-button color="teal" size="mini">插入</wc-button>
|
||||
<div
|
||||
class="table-layer noselect"
|
||||
ref="table"
|
||||
@click=${this.#insertTable}
|
||||
@mousemove=${this.#tableSelect}
|
||||
@mouseleave=${this.#tableSelect}
|
||||
>
|
||||
${Array(81)
|
||||
.fill(0)
|
||||
.map((_, n) => html`<span data-idx=${n}></span>`)}
|
||||
</div>
|
||||
<div class="link-layer noselect" ref="link">
|
||||
<wc-input ref="linkinput" label="请输入链接地址"></wc-input>
|
||||
<wc-button size="m" @click=${this.#insertLink}>插入</wc-button>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
|
|
@ -24,8 +24,12 @@ export default {
|
|||
'M232 872h560v-80H232v80m280-160c132.4 0 240-107.6 240-240V152H652v320c0 77.2-62.8 140-140 140s-140-62.8-140-140V152H272v320c0 132.4 107.6 240 240 240z',
|
||||
center:
|
||||
'M128 128h768v85.333H128V128m170.667 170.667h426.666V384H298.667v-85.333M128 469.333h768v85.334H128v-85.334M298.667 640h426.666v85.333H298.667V640M128 810.667h768V896H128v-85.333z',
|
||||
table:
|
||||
'M860 159H164c-19.88 0-36 16.93-36 37.82v630.36c0 20.89 16.12 37.82 36 37.82h696c19.88 0 36-16.93 36-37.82V196.82c0-20.89-16.12-37.82-36-37.82z m-422 26.74c20.98 0 38 17.01 38 38 0 20.98-17.02 38-38 38-20.99 0-38-17.01-38-38s17.02-38 38-38z m-108 0c20.98 0 38 17.01 38 38 0 20.98-17.02 38-38 38-20.99 0-38-17.01-38-38s17.01-38 38-38z m-108 0c20.98 0 38 17.01 38 38 0 20.98-17.01 38-38 38s-38-17.01-38-38 17.01-38 38-38zM664 808V664h176v144H664z m-64-144v144H424V664h176z m-416 0h176v144H184V664z m480-190h176v144H664V474zM424 618V474h176v144H424z m-64 0H184V474h176v144z m480-338v144H664V280h176z m-240 0v144H424V280h176z m-385.54 0H360v144H184V280h30.46z',
|
||||
unordered:
|
||||
'M298.667 213.333v85.334H896v-85.334M298.667 554.667H896v-85.334H298.667m0 341.334H896v-85.334H298.667m-128-14.08c-31.574 0-56.747 25.6-56.747 56.747s25.6 56.747 56.747 56.747c31.146 0 56.746-25.6 56.746-56.747s-25.173-56.747-56.746-56.747m0-519.253c-35.414 0-64 28.587-64 64s28.586 64 64 64c35.413 0 64-28.587 64-64s-28.587-64-64-64m0 256c-35.414 0-64 28.587-64 64s28.586 64 64 64c35.413 0 64-28.587 64-64s-28.587-64-64-64z',
|
||||
right:
|
||||
'M128 128h768v85.333H128V128m256 170.667h512V384H384v-85.333M128 469.333h768v85.334H128v-85.334M384 640h512v85.333H384V640M128 810.667h768V896H128v-85.333z'
|
||||
'M128 128h768v85.333H128V128m256 170.667h512V384H384v-85.333M128 469.333h768v85.334H128v-85.334M384 640h512v85.333H384V640M128 810.667h768V896H128v-85.333z',
|
||||
fullscreen:
|
||||
'M597.33 449.42l40.02 41.25 94.25-93.75 36.4 35V320H654.14l37.44 36.3-94.25 93.12z m-170.66 124.6l-40.41-40.68-93.53 93.93L256 592.76l0.95 111.24 113.96-0.9-37.78-35.78 93.54-93.3z m211.91-40.69l-41.25 40.02 93.75 94.24-35 36.4H768V590.14l-36.3 37.44-93.12-94.25z m-252.86-42.66l40.95-40.23-93.84-93.87L367.56 320l-111.56 0.5 0.48 113.91 36.02-37.62 93.22 93.88zM848 832H176c-26.47 0-48-19.57-48-43.64V235.64c0-24.06 21.53-43.64 48-43.64h672c26.47 0 48 19.58 48 43.64v552.73c0 24.06-21.53 43.63-48 43.63zM206.55 256c-8.02 0-14.55 5.74-14.55 12.8v486.4c0 7.06 6.53 12.8 14.55 12.8h610.91c8.02 0 14.55-5.74 14.55-12.8V268.8c0-7.06-6.53-12.8-14.55-12.8H206.55z'
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue