class MewElement extends HTMLElement { constructor() { super() if (this.hasAttribute('draw')) return this.init() } drawComplete() { this.setAttribute('draw', true) } } document.addEventListener('DOMContentLoaded', () => { customElements.define( 'mew-hide', class MewHide extends MewElement { init() { let $this = $(this) const $mainContent = $this.closest('.main-content') this.options = { target: $mainContent.attr('data-target'), id: $mainContent.attr('data-id') } if (this.options.target && this.options.id) { let commentIds = localStorage.getItem(window.encrypt('mew-hide-' + this.options.target)) commentIds = commentIds ? JSON.parse(window.decrypt(commentIds)) : [] if (commentIds.includes(this.options.id)) { $this.before(this.innerHTML) $this.remove() } else { let isToc = $this.find('h1,h2,h3,h4,h5').length !== 0 this.setAttribute('hide', window.encrypt(this.innerHTML)) this.innerHTML = '' if(isToc) { this.setAttribute('toc', true) commonContext.initTocAndNotice() } this.onclick = function () { let $haloComment = $(`halo-comment[id='${this.options.id}'][type='${this.options.target.substring(0, this.options.target.length - 1)}']`) if ($haloComment.length === 0 || $haloComment.is(':hidden')) { return } Utils.animateScroll($haloComment[0], 20, (window.innerHeight || document.documentElement.clientHeight) / 4) } } } this.drawComplete() } } ) customElements.define( 'mew-subtitle', class MewSubtitle extends MewElement { init() { this.innerHTML = `${this.innerText || '默认标题'}` this.drawComplete() } } ) customElements.define( 'mew-music', class MewMusic extends HTMLElement { constructor() { super() this.innerHTML = '音乐播放器加载中...' this.options = { container: this, theme: this.getAttribute('theme') || 'var(--theme)', loop: this.getAttribute('loop') || 'all', autoplay: this.hasAttribute('autoplay') && this.getAttribute('autoplay') !== 'false', lrcType: 3, } if (!('APlayer' in window)) { if (!MewMusic.prototype.load) { MewMusic.prototype.load = true MewMusic.prototype.await = [] new Promise((resolve) => { const $head = $('head') $head.append('') Utils.cachedScript('https://unpkg.com/aplayer@1.10.1/dist/APlayer.min.js') .done(() => resolve()) .fail(() => resolve()) }).then(() => { this.render() MewMusic.prototype.await && MewMusic.prototype.await.forEach(n => n()) }) } else { MewMusic.prototype.await.push(() => this.render()) } } else { this.render() } } render() { if (!('APlayer' in window)) { this.innerHTML = '未开启音乐播放器!' return } // eslint-disable-next-line no-async-promise-executor new Promise(async (resolve) => { if (this.hasAttribute('song')) { this.options.audio = await fetch( 'https://api.i-meto.com/meting/api?server=netease&type=song&id=' + this.getAttribute('song') ).then((response) => response.json()) } else if (this.hasAttribute('playlist')) { this.options.listFolded = this.getAttribute('fold') this.options.order = this.getAttribute('order') this.options.audio = await fetch( 'https://api.i-meto.com/meting/api?server=netease&type=playlist&id=' + this.getAttribute('playlist') ).then((response) => response.json()) } else if (this.hasAttribute('url')) { this.options.audio = [{ name: this.getAttribute('name') || '音乐', url: this.getAttribute('url'), artist: this.getAttribute('artist') || '未知歌手', cover: this.getAttribute('cover'), lrc: this.getAttribute('lrc') || (this.options.lrcType = undefined), }] } else { this.innerHTML = '未指定播放的音乐!' return resolve() } this.aplayer = new APlayer(this.options) resolve() }) } disconnectedCallback() { this.aplayer && this.aplayer.destroy() } } ) customElements.define( 'mew-bilibili', class MewBilibili extends MewElement { init() { this.options = { bvid: this.getAttribute('bvid'), width: /^\d{1,3}%$/.test(this.getAttribute('width')) ? this.getAttribute('width') : '100%', } if (this.options.bvid) { this.style.padding = `calc(${this.options.width} * 0.3) 0` this.innerHTML = `` } else this.innerHTML = 'bvid未填写!' this.drawComplete() } } ) customElements.define( 'mew-tabs', class MewTabs extends MewElement { init() { const $tabPage = $(this).children('mew-tab-page') if ($tabPage.length === 0) { this.innerHTML = '没有标签页!' this.drawComplete() return } let navs = '' let contents = '' let active = false $tabPage.each((index, elem) => { let title = elem.getAttribute('title') || '默认标签' let id = `${index}-${new Date().getTime()}` if (!active && elem.hasAttribute('active')) { active = true navs += `
${title}
` contents += `
${elem.innerHTML}
` } else { navs += `
${title}
` contents += `
${elem.innerHTML}
` } }) this.innerHTML = `
${navs}
${contents}
` !active && $(this).find('div>div:first-child').addClass('active') this.drawComplete() } connectedCallback() { $(this).find('.tabs-head').on('click', 'div:not(.active)', function () { const $container = $(this).parent().parent() $container.find('.active').removeClass('active') $(this).addClass('active') $container.find($(this).attr('data-id')).addClass('active') }) } } ) customElements.define( 'mew-cloud', class MewCloud extends MewElement { init() { this.options = { type: this.getAttribute('type') || 'default', title: this.innerText || '资源文件分享', url: this.getAttribute('url'), password: this.getAttribute('password'), } const type = { default: '网络来源', 360: '360云盘', bd: '百度网盘', wy: '微云', ali: '阿里云盘', github: 'Github仓库', gitee: 'Gitee仓库', lz: '蓝奏云网盘', } this.innerHTML = `
${this.options.title}
来源:${type[this.options.type] || '网络来源'}${this.options.password ? ' | 提取码:' + this.options.password : ''}
` this.drawComplete() } } ) customElements.define( 'mew-progress', class MewProgress extends MewElement { init() { this.options = { value: /^\d{1,3}%$/.test(this.getAttribute('value')) ? this.getAttribute('value') : '50%', color: this.getAttribute('color') || 'var(--theme)', } this.innerHTML = `
${this.options.value}
` this.drawComplete() } }) customElements.define( 'mew-panel', class MewPanel extends MewElement { init() { this.options = { title: this.getAttribute('title') || '', color: this.getAttribute('color') || 'var(--theme)', } this.innerHTML = `
${this.options.title}
${this.innerHTML}
` this.style.background = this.options.color this.style.color = this.options.color this.drawComplete() } }) customElements.define( 'mew-message', class MewMessage extends MewElement { init() { this.options = { type: /^(success|info|warning|error)$/.test( this.getAttribute('type') ) ? this.getAttribute('type') : 'info', content: this.innerHTML || '消息内容', } this.innerHTML = this.options.content this.setAttribute('type', this.options.type) this.drawComplete() } }) customElements.define( 'mew-hr', class MewHr extends MewElement { init() { this.startColor = this.getAttribute('startColor') || '#01d0ff' this.endColor = this.getAttribute('endColor') || '#fc3e85' this.style.backgroundImage = `repeating-linear-gradient(-45deg, ${this.startColor} 0,${this.startColor} 20%, transparent 0,transparent 35%, ${this.endColor} 0,${this.endColor} 65%, transparent 0,transparent 80%, ${this.startColor} 0,${this.startColor} 100%)` this.drawComplete() } }) customElements.define( 'mew-timeline', class MewTimeline extends MewElement { init() { let content = '' let child = this.firstChild while (child) { if (child.tagName === 'MEW-TIMELINE-TITLE') { content += `
${child.innerHTML}
` } else if (child.tagName === 'MEW-TIMELINE-ITEM') { const type = child.getAttribute('type') || '' const title = child.getAttribute('title') ? `${child.getAttribute('title')}` : '' content += `
${title}
${child.innerHTML}
` } child = child.nextElementSibling } this.innerHTML = content this.drawComplete() } } ) customElements.define( 'mew-btn', class MewBtn extends MewElement { init() { this.options = { color: this.getAttribute('color') || 'var(--theme)', href: this.getAttribute('href'), target: this.getAttribute('target') || '_blank', icon: this.getAttribute('icon'), } this.innerHTML = `${this.options.icon ? `` : ''}${this.innerHTML}` const btn = this.querySelector('a.mew-btn') this.options.href && (btn.href = this.options.href, btn.target = this.options.target) this.drawComplete() } }) customElements.define( 'mew-quote', class MewQuote extends MewElement { init() { this.options = { avatar: this.getAttribute('avatar'), href: this.getAttribute('href'), name: this.getAttribute('name'), } const avatarElem = this.options.avatar ? `` : '' const nameElem = this.options.name ? `${this.options.name}` : '' this.innerHTML = `
${avatarElem}

${this.innerHTML}

${nameElem}
` this.drawComplete() } }) customElements.define( 'mew-link', class MewLink extends MewElement { async init() { this.options = { img: this.getAttribute('img'), href: this.getAttribute('href') || '', title: this.getAttribute('title'), slug: this.getAttribute('slug'), id: this.getAttribute('id'), type: this.getAttribute('type') || 'post', desc: this.innerHTML } if (this.options.id || this.options.slug) { await Utils.request({ url: this.options.id? `/api/content/${this.options.type}s/${this.options.id}` : `/api/content/${this.options.type}s/slug?slug=${this.options.slug}`, method: 'GET', }) .then(res=>{ this.options.img = this.options.img || res.thumbnail this.options.href = this.options.title || res.fullPath this.options.title = this.options.title || res.title this.options.desc = this.options.desc || res.summary }) .catch(error => { this.options.desc = `Error: ${error}` }) } const imageElem = this.options.img ? `` : '' const descElem = this.options.desc ? `${this.options.desc}` : `${this.options.href}` this.innerHTML = `

${this.options.title || '我分享了一个网站'}

${descElem}
${imageElem}
` this.drawComplete() } }) customElements.define( 'mew-video', class MewVideo extends MewElement { init() { this.options = { src: this.getAttribute('src'), type: this.getAttribute('type'), autoplay: this.hasAttribute('autoplay') && this.getAttribute('autoplay') !== 'false', controls: this.getAttribute('controls') !== 'false', loop: this.hasAttribute('loop') && this.getAttribute('loop') !== 'false', muted: this.hasAttribute('muted') && this.getAttribute('muted') !== 'false', // 静音播放 preload: this.hasAttribute('preload') && this.getAttribute('preload') !== 'false', poster: this.getAttribute('poster'), // 加载图片 width: /^\d{1,3}%$/.test(this.getAttribute('width')) ? this.getAttribute('width') : '100%', } this.innerHTML = `` this.drawComplete() } }) customElements.define( 'mew-photos', class MewPhotos extends MewElement { init() { if (!($.fn.justifiedGallery)) { if (!MewPhotos.prototype.load) { MewPhotos.prototype.load = true MewPhotos.prototype.await = [] new Promise((resolve) => { Utils.cachedScript('https://unpkg.com/justifiedGallery@3.8.1/dist/js/jquery.justifiedGallery.min.js') .done(() => resolve()) .fail(() => resolve()) }).then(() => { this.render() MewPhotos.prototype.await && MewPhotos.prototype.await.forEach(n => n()) }) } else { MewPhotos.prototype.await.push(() => this.render()) } } else { this.render() } } render() { this.options = { captions: this.hasAttribute('captions') && this.getAttribute('captions') !== 'false', margins: this.getAttribute('margins') || '4' } $(this).find('img').each((i, elem) => { $(elem).wrap(`
`) }) $(this).justifiedGallery({captions: this.options.captions, margins: this.options.margins}) this.drawComplete() } }) customElements.define( 'mew-raw', class MewRaw extends MewElement { init() { let html = this.innerHTML this.innerHTML = '' const shadowRoot = this.attachShadow({ mode: 'closed' }) shadowRoot.innerHTML = html this.drawComplete() } } ) })