Skip to content

Commit

Permalink
feat(extension): embed extension, youku/bilibili
Browse files Browse the repository at this point in the history
  • Loading branch information
mekery committed Apr 29, 2020
1 parent 3f0dd96 commit 1c83063
Show file tree
Hide file tree
Showing 24 changed files with 639 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/components/QuasarTiptap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import {
OFormatClear,
OPrint,
OImage,
OEmbed,
RecommendedExtensions
} from 'src/extentions'
Expand Down
13 changes: 13 additions & 0 deletions src/components/buttons/OAddMoreBtn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,21 @@
</o-meta-input>
</q-menu>
</o-common-item>
<o-common-item icon="mdi-iframe"
:label="$o.lang.editor.formula"
side-icon="keyboard_arrow_right">
<q-menu ref="formulaPopover" anchor="center right" self="center left" content-class="o-menu" :offset="[2, 0]">
<o-embed-menu @select="onSelectService" />
</q-menu>
</o-common-item>
</section>
</q-menu>
</o-menubar-btn>
</template>

<script>
import OMenubarBtn from 'src/components/buttons/OMenubarBtn'
import OEmbedMenu from 'src/components/buttons/OEmbedMenu'
import OCommonItem from 'src/components/common/OCommonItem'
import OMetaInput from 'src/components/common/OMetaInput'
export default {
Expand All @@ -70,6 +78,7 @@ export default {
},
components: {
OMenubarBtn,
OEmbedMenu,
OCommonItem,
OMetaInput
},
Expand All @@ -85,6 +94,10 @@ export default {
this.$refs.addPopover.hide()
}
},
onSelectService (service) {
console.log('service', service)
this.commands.embed({ service: service.value })
}
},
computed: {
Expand Down
105 changes: 105 additions & 0 deletions src/components/buttons/OEmbedMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<template>
<section class="o-embed-menu">
<section v-for="(group, i) of services" :key="`group-${i}`">
<div class="group">{{$o.lang.embed[group.value]}}</div>

<section class="row col-12 q-col-gutter-sm services">
<div class="row col-3" v-for="(service, j) of group.children" :key="`service-${i}-${j}`">
<q-item class="col-12" clickable v-close-popup @click="select(service)">
<q-item-section avatar>
<img :src="`statics/service/${service.svgIcon}.svg`" v-if="service.svgIcon" />
<q-icon :name="service.icon || 'apps'" :color="service.color" v-else />
</q-item-section>
<q-item-section>
{{$o.lang.embed[service.value]}}
</q-item-section>
</q-item>
</div>
</section>
</section>
</section>
</template>

<script>
import {
VideoServices,
MapServices,
DesignServices,
DevelopServices,
DataServices
} from 'src/data/embed'
export default {
name: 'o-embed-menu',
data () {
return {
}
},
methods: {
select (service) {
this.$emit('select', service)
}
},
computed: {
services () {
return [
{
label: 'Video',
value: 'video',
children: VideoServices
},
{
label: 'Map',
value: 'map',
children: MapServices
},
{
label: 'Design',
value: 'design',
children: DesignServices
},
{
label: 'Develop',
value: 'develop',
children: DevelopServices
},
{
label: '数据',
value: 'data',
children: DataServices
}
]
}
}
}
</script>

<style lang="stylus">
.o-embed-menu {
padding 0 1rem 1rem 1rem
.group {
padding-top 1rem
}
.services {
//
.q-item {
min-height 40px
min-width 80px
border-radius 4px
background rgba(0, 0, 0, 0.03)
}
.q-item__section--avatar {
min-width unset
img {
width 24px
height 24px
}
}
.q-item__section--side {
padding-right 0
}
}
}
</style>
149 changes: 149 additions & 0 deletions src/components/views/OEmbedView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<template>
<section class="o-embed iframe" :class="src ? '' : 'no-data'">
<div class="row col-12 o-toolbar" v-if="view.editable">
<q-input v-model="originalLink" placeholder="service" debounce="300" class="col text-red link" standout clearable @paste.stop.native>
<template v-slot:prepend>
<img :src="`statics/service/${service.svgIcon}.svg`" v-if="service.svgIcon" />
<q-icon :name="service.icon || 'apps'" :color="service.color" v-else />
</template>
</q-input>
<div class="row col-auto q-px-sm">
<q-btn label="示例" class="q-mx-sm" />
<q-btn label="确定" color="blue" @click="onConfirm" />
</div>
</div>
<iframe class="iframe"
:src="src"
:style="{height: `${height}px`}"
frameborder="0"
allowfullscreen="true"
v-if="src"></iframe>
</section>
</template>

<script>
import { getEmbedService, getServiceSrc } from 'src/data/embed'
export default {
name: 'o-embed',
data () {
return {
originalLink: ''
}
},
props: ['node', 'updateAttrs', 'view'],
components: {
},
methods: {
onConfirm () {
let result = getServiceSrc(this.service.value, this.originalLink)
if (!result.validLink || !result.validId) {
console.warn('invalid link')
this.$q.notify({
color: 'red',
icon: 'warning',
message: 'Invalid link',
timeout: 800
})
return
}
this.link = this.originalLink
this.src = result.src
}
},
computed: {
service () {
return getEmbedService(this.node.attrs.service)
},
link: {
get () {
return this.node.attrs.link
},
set (link) {
this.updateAttrs({
link
})
}
},
src: {
get () {
return this.node.attrs.src
},
set (src) {
this.updateAttrs({
src
})
}
},
height: {
get () {
return this.node.attrs.height || 500
},
set (height) {
this.updateAttrs({
height
})
}
}
},
mounted () {
this.originalLink = this.link
}
}
</script>

<style lang="stylus">
.o-embed {
position relative
min-height 40px
.o-toolbar {
position absolute
top -44px
width 100%
height 40px
margin 4px 0
background #efefef
border-radius 5px
visibility hidden
.link {
img {
width 24px
height 24px
}
}
.q-input {
padding 0 4px
}
.q-field__control, .q-field__marginal {
height 32px
}
.q-field__suffix {
line-height unset
}
}
.iframe {
width 100%
height 500px
border solid 1px rgba(0,0,0,0.05)
border-radius 5px
}
}
.o-embed.no-data {
.o-toolbar {
top 0
visibility visible
}
}
.o-embed:hover {
.o-toolbar {
visibility visible
}
}
</style>
2 changes: 1 addition & 1 deletion src/data/article.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1c83063

Please sign in to comment.