You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
5.4 KiB
JavaScript
216 lines
5.4 KiB
JavaScript
export class FileView extends HTMLElement {
|
|
icons = {
|
|
menu: `
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
|
|
<path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
|
|
</svg>
|
|
`,
|
|
down: `
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-down-fill" viewBox="0 0 16 16">
|
|
<path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/>
|
|
</svg>
|
|
`,
|
|
up: `
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-up-fill" viewBox="0 0 16 16">
|
|
<path d="m7.247 4.86-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 0 0 .753-1.659l-4.796-5.48a1 1 0 0 0-1.506 0z"/>
|
|
</svg>
|
|
`,
|
|
}
|
|
|
|
textEn = {
|
|
addAbove: 'Add above',
|
|
addBelow: 'Add below',
|
|
delete: 'Delete',
|
|
}
|
|
|
|
textEs = {
|
|
addAbove: 'Añadir arriba',
|
|
addBelow: 'Añadir abajo',
|
|
delete: 'Borrar',
|
|
}
|
|
|
|
constructor() {
|
|
super()
|
|
this.language = navigator.language
|
|
this.attachShadow({mode: 'open'})
|
|
this.headerEl = document.createElement('div')
|
|
this.headerEl.classList.add('header')
|
|
this.contentEl = document.createElement('div')
|
|
this.contentEl.classList.add('content')
|
|
this.shadowRoot.appendChild(this.headerEl)
|
|
this.shadowRoot.appendChild(this.contentEl)
|
|
this.nameEl = document.createElement('input')
|
|
this.nameEl.classList.add('name')
|
|
this.nameEl.setAttribute('spellcheck', 'false')
|
|
this.nameEl.addEventListener('input', e => {
|
|
this.setFileType(e.target.value)
|
|
})
|
|
this.headerEl.appendChild(this.nameEl)
|
|
this.collapseBtn = document.createElement(
|
|
'button'
|
|
)
|
|
this.collapseBtn.innerHTML = this.icons.up
|
|
this.collapseBtn.addEventListener('click', () => {
|
|
this.collapsed = !this.collapsed
|
|
})
|
|
this.headerEl.appendChild(this.collapseBtn)
|
|
this.menuBtn = document.createElement('button')
|
|
this.menuBtn.innerHTML = this.icons.menu
|
|
this.menuBtn.addEventListener('click', () => {
|
|
this.openMenu()
|
|
})
|
|
this.headerEl.appendChild(this.menuBtn)
|
|
this.menu = document.createElement(
|
|
'm-menu-dropdown'
|
|
)
|
|
this.shadowRoot.appendChild(this.menu)
|
|
}
|
|
|
|
connectedCallback() {
|
|
const style = document.createElement('style')
|
|
style.textContent = `
|
|
:host {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
div.header {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: stretch;
|
|
background-color: #f2dbd8;
|
|
color: #000;
|
|
padding: 3px 0;
|
|
}
|
|
div.header > * {
|
|
background: inherit;
|
|
color: inherit;
|
|
border: none;
|
|
}
|
|
.name {
|
|
flex-grow: 1;
|
|
padding: 0 5px;
|
|
font: inherit;
|
|
font-family: monospace;
|
|
outline: none;
|
|
}
|
|
div.header button svg {
|
|
margin-bottom: -3px;
|
|
}
|
|
div.content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
min-height: 5px;
|
|
}
|
|
div.content.collapsed > * {
|
|
display: none;
|
|
}
|
|
svg {
|
|
height: 20px;
|
|
width: 20px;
|
|
}
|
|
`
|
|
this.shadowRoot.appendChild(style)
|
|
}
|
|
|
|
openMenu() {
|
|
this.menu.clear()
|
|
this.menu.add(this.text.addAbove, () => {
|
|
this.dispatchEvent(new CustomEvent(
|
|
'click-add-above', {bubbles: true}
|
|
))
|
|
})
|
|
this.menu.add(this.text.addBelow, () => {
|
|
this.dispatchEvent(new CustomEvent(
|
|
'click-add-below', {bubbles: true}
|
|
))
|
|
})
|
|
if (this.fileCount.value > 1) {
|
|
this.menu.add(this.text.delete, () => {
|
|
this.remove()
|
|
this.fileCount.value -= 1
|
|
})
|
|
}
|
|
this.menu.open(this.menuBtn)
|
|
}
|
|
|
|
set codeMirror(value) {
|
|
this._codeMirror = value
|
|
const tagName = (
|
|
this.codeMirror ?
|
|
'm-editor-code-edit' : 'm-editor-text-edit'
|
|
)
|
|
this.editEl = document.createElement(tagName)
|
|
this.contentEl.replaceChildren(this.editEl)
|
|
}
|
|
|
|
get codeMirror() {
|
|
return this._codeMirror
|
|
}
|
|
|
|
set name(name) {
|
|
this.nameEl.value = name
|
|
this.setFileType(name)
|
|
}
|
|
|
|
get name() {
|
|
return this.nameEl.value
|
|
}
|
|
|
|
set data(data) {
|
|
this.editEl.value = data
|
|
}
|
|
|
|
get data() {
|
|
return this.editEl.value
|
|
}
|
|
|
|
set collapsed(value) {
|
|
const cl = this.contentEl.classList
|
|
if (value) {
|
|
cl.add('collapsed')
|
|
} else {
|
|
cl.remove('collapsed')
|
|
}
|
|
this.collapseBtn.innerHTML = (
|
|
value ?
|
|
this.icons.down : this.icons.up
|
|
)
|
|
}
|
|
|
|
get collapsed() {
|
|
return this.contentEl.classList.contains(
|
|
'collapsed'
|
|
)
|
|
}
|
|
|
|
setFileType(value) {
|
|
if (this.codeMirror && this.editEl) {
|
|
let fileType
|
|
if (value.endsWith('.js')) {
|
|
fileType = 'js'
|
|
} else if (value.endsWith('.html')) {
|
|
fileType = 'html'
|
|
} else if (value.endsWith('.css')) {
|
|
fileType = 'css'
|
|
} else if (value.endsWith('.json')) {
|
|
fileType = 'json'
|
|
}
|
|
this.editEl.fileType = fileType
|
|
}
|
|
}
|
|
|
|
get language() {
|
|
return this._language
|
|
}
|
|
|
|
set language(language) {
|
|
this._language = language
|
|
this.text = this.langEs ? this.textEs : this.textEn
|
|
}
|
|
|
|
get langEs() {
|
|
return /^es\b/.test(this.language)
|
|
}
|
|
} |