提交 9c3954ea 编写于 作者: fxy060608's avatar fxy060608

feat: createIntersectionObserver

上级 313f1354
此差异已折叠。
import { initIntersectionObserverPolyfill } from './intersection-observer'
export interface RequestComponentObserverOptions {
selector?: string
rootMargin?: string
relativeToSelector?: string
}
function normalizeRect(rect: DOMRect) {
const { bottom, height, left, right, top, width } = rect || {}
return {
bottom,
height,
left,
right,
top,
width,
}
}
export function requestComponentObserver(
$el: HTMLElement,
options: UniApp.CreateIntersectionObserverOptions &
RequestComponentObserverOptions,
callback: WechatMiniprogram.IntersectionObserverObserveCallback
) {
// 为了摇树优化,不直接引入该polyfill
initIntersectionObserverPolyfill()
const root = options.relativeToSelector
? $el.querySelector(options.relativeToSelector)
: null
const intersectionObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entrie) => {
callback({
intersectionRatio: entrie.intersectionRatio,
intersectionRect: normalizeRect(entrie.intersectionRect),
boundingClientRect: normalizeRect(entrie.boundingClientRect),
relativeRect: normalizeRect(entrie.rootBounds!),
time: Date.now(),
// dataset: normalizeDataset(entrie.target),
// id: entrie.target.id,
})
})
},
{
root,
rootMargin: options.rootMargin,
threshold: options.thresholds,
}
)
if (options.observeAll) {
;(intersectionObserver as any).USE_MUTATION_OBSERVER = true
const nodeList = $el.querySelectorAll(options.selector!)
for (let i = 0; i < nodeList.length; i++) {
intersectionObserver.observe(nodeList[i])
}
} else {
;(intersectionObserver as any).USE_MUTATION_OBSERVER = false
const el = $el.querySelector(options.selector!)
if (!el) {
console.warn(
`Node ${options.selector} is not found. Intersection observer will not trigger.`
)
} else {
intersectionObserver.observe(el)
}
}
return intersectionObserver
}
......@@ -38,3 +38,4 @@ export { getCurrentPageVm } from './helpers/utils'
export { handlePromise } from './helpers/api/promise'
export { invokeApi, wrapperReturnValue } from './helpers/interceptor'
export { requestComponentObserver } from './helpers/requestComponentObserver'
import { extend } from '@vue/shared'
import { ComponentPublicInstance } from 'vue'
import { extend, isFunction } from '@vue/shared'
import {
addIntersectionObserver,
removeIntersectionObserver,
} from '@dcloudio/uni-platform'
import { defineSyncApi } from '../../helpers/api'
import { getCurrentPageVm } from '../../helpers/utils'
import { RequestComponentObserverOptions } from '../../helpers/requestComponentObserver'
const defaultOptions = {
thresholds: [0],
initialRatio: 0,
observeAll: false,
}
interface Margins {
bottom?: number
left?: number
right?: number
top?: number
}
interface RelativeInfo {
selector: string
margins: Margins
export interface AddIntersectionObserverArgs {
reqId: number
component: ComponentPublicInstance
options: ServiceIntersectionObserverOptions
callback: WechatMiniprogram.IntersectionObserverObserveCallback
}
type ObserveResultCallback = (result: UniApp.ObserveResult) => void
interface requestComponentObserver {
export interface RemoveIntersectionObserverArgs {
reqId: number
reqEnd: boolean
res: UniApp.ObserveResult
component: ComponentPublicInstance
}
let reqComponentObserverId = 1
type ServiceIntersectionObserverOptions = UniApp.CreateIntersectionObserverOptions &
RequestComponentObserverOptions
const reqComponentObserverCallbacks: Record<number, ObserveResultCallback> = {}
const defaultOptions = {
thresholds: [0],
initialRatio: 0,
observeAll: false,
}
export const API_CREATE_INTERSECTION_OBSERVER = 'createIntersectionObserver'
const MARGINS = ['top', 'right', 'bottom', 'left']
UniServiceJSBridge.subscribe(
'requestComponentObserver',
({ reqId, reqEnd, res }: requestComponentObserver) => {
const callback = reqComponentObserverCallbacks[reqId]
if (callback) {
if (reqEnd) {
return delete reqComponentObserverCallbacks[reqId]
}
callback(res)
}
}
)
let reqComponentObserverId = 1
function normalizeRootMargin(margins: WechatMiniprogram.Margins = {}) {
return MARGINS.map(
(name) =>
`${Number(margins[name as keyof WechatMiniprogram.Margins]) || 0}px`
).join(' ')
}
class ServiceIntersectionObserver {
private _reqId?: number
private _options: UniApp.CreateIntersectionObserverOptions
private _component: any
private _pageId: number
private _relativeInfo: RelativeInfo[]
private _component: ComponentPublicInstance
private _options: ServiceIntersectionObserverOptions
constructor(
component: any,
component: ComponentPublicInstance,
options: UniApp.CreateIntersectionObserverOptions
) {
this._pageId = component.$page.id
this._component = component._$id || component // app-plus 平台传输_$id
this._options = extend({}, defaultOptions, options || {})
this._relativeInfo = []
this._pageId = component.$page && component.$page.id
this._component = component
this._options = extend({}, defaultOptions, options)
}
relativeTo(selector: string, margins: Margins) {
if (this._reqId) {
throw new Error(
'Relative nodes cannot be added after "observe" call in IntersectionObserver'
)
}
this._relativeInfo.push({
selector,
margins,
})
relativeTo(selector: string, margins?: WechatMiniprogram.Margins) {
this._options.relativeToSelector = selector
this._options.rootMargin = normalizeRootMargin(margins)
return this
}
relativeToViewport(margins: Margins) {
return this.relativeTo((null as unknown) as string, margins)
relativeToViewport(margins?: WechatMiniprogram.Margins) {
this._options.relativeToSelector = undefined
this._options.rootMargin = normalizeRootMargin(margins)
return this
}
observe(selector: string, callback: ObserveResultCallback) {
if (typeof callback !== 'function') {
observe(
selector: string,
callback: WechatMiniprogram.IntersectionObserverObserveCallback
) {
if (!isFunction(callback)) {
return
}
if (this._reqId) {
throw new Error(
'"observe" call can be only called once in IntersectionObserver'
)
}
this._options.selector = selector
this._reqId = reqComponentObserverId++
reqComponentObserverCallbacks[this._reqId] = callback
UniServiceJSBridge.publishHandler(
'addIntersectionObserver',
addIntersectionObserver(
{
selector,
reqId: this._reqId,
component: this._component,
options: this._options,
relativeInfo: this._relativeInfo,
callback,
},
this._pageId
)
}
disconnect() {
UniServiceJSBridge.publishHandler(
'removeIntersectionObserver',
{
reqId: this._reqId,
},
this._pageId
)
this._reqId &&
removeIntersectionObserver(
{ reqId: this._reqId, component: this._component },
this._pageId
)
}
}
export const createIntersectionObserver = defineSyncApi<
typeof uni.createIntersectionObserver
>(API_CREATE_INTERSECTION_OBSERVER, (context?, options?) => {
if (!context) {
context = getCurrentPageVm()
>('createIntersectionObserver', (context?, options?) => {
if (context && !context.$page) {
options = context
context = null
}
if (context) {
return new ServiceIntersectionObserver(context, options)
}
return new ServiceIntersectionObserver(context, options)
return new ServiceIntersectionObserver(getCurrentPageVm(), options)
})
......@@ -19,10 +19,7 @@
}"
class="uni-scroll-view-refresher"
>
<div
v-if="refresherDefaultStyle !== 'none'"
class="uni-scroll-view-refresh"
>
<div v-if="refresherDefaultStyle !== 'none'" class="uni-scroll-view-refresh">
<div class="uni-scroll-view-refresh-inner">
<svg
v-if="refreshState == 'pulling'"
......@@ -65,10 +62,12 @@
</uni-scroll-view>
</template>
<script>
import { passive } from '@dcloudio/uni-shared'
import scroller from '../../mixins/scroller/index'
import { disableScrollBounce } from '../../helpers/disable-scroll-bounce'
const passiveOptions = { passive: true }
const passiveOptions = passive(true)
// const PULLING = 'pulling'
// const REFRESHING = 'refreshing'
......@@ -185,14 +184,14 @@ export default {
this._scrollTopChanged(this.scrollTopNumber)
this._scrollLeftChanged(this.scrollLeftNumber)
this._scrollIntoViewChanged(this.scrollIntoView)
this.__handleScroll = function (e) {
this.__handleScroll = function(e) {
event.preventDefault()
event.stopPropagation()
self._handleScroll.bind(self, event)()
}
var touchStart = null
var needStop = null
this.__handleTouchMove = function (event) {
this.__handleTouchMove = function(event) {
var x = event.touches[0].pageX
var y = event.touches[0].pageY
var main = self.$refs.main
......@@ -255,7 +254,7 @@ export default {
}
}
this.__handleTouchStart = function (event) {
this.__handleTouchStart = function(event) {
if (event.touches.length === 1) {
disableScrollBounce({
disable: true,
......@@ -274,7 +273,7 @@ export default {
}
}
}
this.__handleTouchEnd = function (event) {
this.__handleTouchEnd = function(event) {
touchStart = null
disableScrollBounce({
disable: false,
......@@ -296,9 +295,7 @@ export default {
this.__handleTouchMove,
passiveOptions
)
this.$refs.main.addEventListener('scroll', this.__handleScroll, {
passive: false,
})
this.$refs.main.addEventListener('scroll', this.__handleScroll, passive(false))
this.$refs.main.addEventListener(
'touchend',
this.__handleTouchEnd,
......@@ -321,9 +318,7 @@ export default {
this.__handleTouchMove,
passiveOptions
)
this.$refs.main.removeEventListener('scroll', this.__handleScroll, {
passive: false,
})
this.$refs.main.removeEventListener('scroll', this.__handleScroll, passive(false))
this.$refs.main.removeEventListener(
'touchend',
this.__handleTouchEnd,
......@@ -331,13 +326,13 @@ export default {
)
},
methods: {
scrollTo: function (t, n) {
scrollTo: function(t, n) {
var i = this.$refs.main
t < 0
? (t = 0)
: n === 'x' && t > i.scrollWidth - i.offsetWidth
? (t = i.scrollWidth - i.offsetWidth)
: n === 'y' &&
? (t = i.scrollWidth - i.offsetWidth)
: n === 'y' &&
t > i.scrollHeight - i.offsetHeight &&
(t = i.scrollHeight - i.offsetHeight)
var r = 0
......@@ -381,7 +376,7 @@ export default {
this.$refs.content.style.webkitTransform = o
}
},
_handleTrack: function ($event) {
_handleTrack: function($event) {
if ($event.detail.state === 'start') {
this._x = $event.detail.x
this._y = $event.detail.y
......@@ -394,7 +389,7 @@ export default {
if (this._noBubble === null && this.scrollY) {
if (
Math.abs(this._y - $event.detail.y) /
Math.abs(this._x - $event.detail.x) >
Math.abs(this._x - $event.detail.x) >
1
) {
this._noBubble = true
......@@ -405,7 +400,7 @@ export default {
if (this._noBubble === null && this.scrollX) {
if (
Math.abs(this._x - $event.detail.x) /
Math.abs(this._y - $event.detail.y) >
Math.abs(this._y - $event.detail.y) >
1
) {
this._noBubble = true
......@@ -419,7 +414,7 @@ export default {
$event.stopPropagation()
}
},
_handleScroll: function ($event) {
_handleScroll: function($event) {
if (!($event.timeStamp - this._lastScrollTime < 20)) {
this._lastScrollTime = $event.timeStamp
const target = $event.target
......@@ -444,9 +439,9 @@ export default {
}
if (
target.scrollTop +
target.offsetHeight +
this.lowerThresholdNumber >=
target.scrollHeight &&
target.offsetHeight +
this.lowerThresholdNumber >=
target.scrollHeight &&
this.lastScrollTop - target.scrollTop < 0 &&
$event.timeStamp - this.lastScrollToLowerTime > 200
) {
......@@ -469,9 +464,9 @@ export default {
}
if (
target.scrollLeft +
target.offsetWidth +
this.lowerThresholdNumber >=
target.scrollWidth &&
target.offsetWidth +
this.lowerThresholdNumber >=
target.scrollWidth &&
this.lastScrollLeft - target.scrollLeft < 0 &&
$event.timeStamp - this.lastScrollToLowerTime > 200
) {
......@@ -485,7 +480,7 @@ export default {
this.lastScrollLeft = target.scrollLeft
}
},
_scrollTopChanged: function (val) {
_scrollTopChanged: function(val) {
if (this.scrollY) {
if (this._innerSetScrollTop) {
this._innerSetScrollTop = false
......@@ -498,7 +493,7 @@ export default {
}
}
},
_scrollLeftChanged: function (val) {
_scrollLeftChanged: function(val) {
if (this.scrollX) {
if (this._innerSetScrollLeft) {
this._innerSetScrollLeft = false
......@@ -511,7 +506,7 @@ export default {
}
}
},
_scrollIntoViewChanged: function (val) {
_scrollIntoViewChanged: function(val) {
if (val) {
if (!/^[_a-zA-Z][-_a-zA-Z0-9:]*$/.test(val)) {
console.group('scroll-into-view="' + val + '" 有误')
......@@ -546,7 +541,7 @@ export default {
}
}
},
_transitionEnd: function (val, type) {
_transitionEnd: function(val, type) {
this.$refs.content.style.transition = ''
this.$refs.content.style.webkitTransition = ''
this.$refs.content.style.transform = ''
......@@ -590,96 +585,4 @@ export default {
},
},
}
</script>
<style>
uni-scroll-view {
display: block;
width: 100%;
}
uni-scroll-view[hidden] {
display: none;
}
.uni-scroll-view {
position: relative;
-webkit-overflow-scrolling: touch;
width: 100%;
/* display: flex; 时在安卓下会导致scrollWidth和offsetWidth一样 */
height: 100%;
max-height: inherit;
}
.uni-scroll-view-content {
width: 100%;
height: 100%;
}
.uni-scroll-view-refresher {
position: relative;
overflow: hidden;
}
.uni-scroll-view-refresh {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.uni-scroll-view-refresh-inner {
display: flex;
align-items: center;
justify-content: center;
line-height: 0;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.117647),
0 1px 4px rgba(0, 0, 0, 0.117647);
}
.uni-scroll-view-refresh__spinner {
transform-origin: center center;
animation: uni-scroll-view-refresh-rotate 2s linear infinite;
}
.uni-scroll-view-refresh__spinner > circle {
stroke: currentColor;
stroke-linecap: round;
animation: uni-scroll-view-refresh-dash 2s linear infinite;
}
@keyframes uni-scroll-view-refresh-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes uni-scroll-view-refresh-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
</style>
</script>
\ No newline at end of file
{
"private": true,
"name": "@dcloudio/uni-view",
"name": "@dcloudio/uni-core",
"version": "3.0.0",
"description": "@dcloudio/uni-view",
"description": "@dcloudio/uni-core",
"sideEffects": false,
"repository": {
"type": "git",
"url": "git+https://github.com/dcloudio/uni-app.git",
"directory": "packages/uni-view"
"directory": "packages/uni-core"
},
"license": "Apache-2.0",
"bugs": {
......
export * from './util'
export * from './icon'
export * from './getRealRoute'
export * from './getWindowOffset'
export * from './bridge'
export * from './plugin'
export { getWindowOffset } from './helpers/getWindowOffset'
import { extend } from '@vue/shared'
import { getWindowOffset } from '../helpers/getWindowOffset'
import { getWindowOffset } from '../../helpers/getWindowOffset'
export function findUniTarget($event: Event, $el: HTMLElement): HTMLElement {
let target = $event.target as HTMLElement
......
import { passive } from '@dcloudio/uni-shared'
const LONGPRESS_TIMEOUT = 350
const LONGPRESS_THRESHOLD = 10
const passiveOptions = { passive: true } // TODO caniuse?
const passiveOptions = passive(true)
let longPressTimer = 0
......
uni-canvas {
width: 300px;
height: 150px;
display: block;
position: relative;
}
uni-canvas > canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
uni-checkbox-group[hidden] {
display: none;
}
.ql-container {
display: block;
position: relative;
box-sizing: border-box;
-webkit-user-select: text;
user-select: text;
outline: none;
overflow: hidden;
width: 100%;
height: 200px;
min-height: 200px;
}
.ql-container[hidden] {
display: none;
}
.ql-container .ql-editor {
position: relative;
font-size: inherit;
line-height: inherit;
font-family: inherit;
min-height: inherit;
width: 100%;
height: 100%;
padding: 0;
overflow-x: hidden;
overflow-y: auto;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
-webkit-overflow-scrolling: touch;
}
.ql-container .ql-editor::-webkit-scrollbar {
width: 0 !important;
}
.ql-container .ql-editor.scroll-disabled {
overflow: hidden;
}
.ql-container .ql-image-overlay {
display: flex;
position: absolute;
box-sizing: border-box;
border: 1px dashed #ccc;
justify-content: center;
align-items: center;
-webkit-user-select: none;
user-select: none;
}
.ql-container .ql-image-overlay .ql-image-size {
position: absolute;
padding: 4px 8px;
text-align: center;
background-color: #fff;
color: #888;
border: 1px solid #ccc;
box-sizing: border-box;
opacity: 0.8;
right: 4px;
top: 4px;
font-size: 12px;
display: inline-block;
width: auto;
}
.ql-container .ql-image-overlay .ql-image-toolbar {
position: relative;
text-align: center;
box-sizing: border-box;
background: #000;
border-radius: 5px;
color: #fff;
font-size: 0;
min-height: 24px;
z-index: 100;
}
.ql-container .ql-image-overlay .ql-image-toolbar span {
display: inline-block;
cursor: pointer;
padding: 5px;
font-size: 12px;
border-right: 1px solid #fff;
}
.ql-container .ql-image-overlay .ql-image-toolbar span:last-child {
border-right: 0;
}
.ql-container .ql-image-overlay .ql-image-toolbar span.triangle-up {
padding: 0;
position: absolute;
top: -12px;
left: 50%;
transform: translatex(-50%);
width: 0;
height: 0;
border-width: 6px;
border-style: solid;
border-color: transparent transparent black transparent;
}
.ql-container .ql-image-overlay .ql-image-handle {
position: absolute;
height: 12px;
width: 12px;
border-radius: 50%;
border: 1px solid #ccc;
box-sizing: border-box;
background: #fff;
}
.ql-container img {
display: inline-block;
max-width: 100%;
}
.ql-clipboard p {
margin: 0;
padding: 0;
}
.ql-editor {
box-sizing: border-box;
height: 100%;
outline: none;
overflow-y: auto;
tab-size: 4;
-moz-tab-size: 4;
text-align: left;
white-space: pre-wrap;
word-wrap: break-word;
}
.ql-editor > * {
cursor: text;
}
.ql-editor p,
.ql-editor ol,
.ql-editor ul,
.ql-editor pre,
.ql-editor blockquote,
.ql-editor h1,
.ql-editor h2,
.ql-editor h3,
.ql-editor h4,
.ql-editor h5,
.ql-editor h6 {
margin: 0;
padding: 0;
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol > li,
.ql-editor ul > li {
list-style-type: none;
}
.ql-editor ul > li::before {
content: '\2022';
}
.ql-editor ul[data-checked=true],
.ql-editor ul[data-checked=false] {
pointer-events: none;
}
.ql-editor ul[data-checked=true] > li *,
.ql-editor ul[data-checked=false] > li * {
pointer-events: all;
}
.ql-editor ul[data-checked=true] > li::before,
.ql-editor ul[data-checked=false] > li::before {
color: #777;
cursor: pointer;
pointer-events: all;
}
.ql-editor ul[data-checked=true] > li::before {
content: '\2611';
}
.ql-editor ul[data-checked=false] > li::before {
content: '\2610';
}
.ql-editor li::before {
display: inline-block;
white-space: nowrap;
width: 2em;
}
.ql-editor ol li {
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
counter-increment: list-0;
}
.ql-editor ol li:before {
content: counter(list-0, decimal) '. ';
}
.ql-editor ol li.ql-indent-1 {
counter-increment: list-1;
}
.ql-editor ol li.ql-indent-1:before {
content: counter(list-1, lower-alpha) '. ';
}
.ql-editor ol li.ql-indent-1 {
counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-2 {
counter-increment: list-2;
}
.ql-editor ol li.ql-indent-2:before {
content: counter(list-2, lower-roman) '. ';
}
.ql-editor ol li.ql-indent-2 {
counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-3 {
counter-increment: list-3;
}
.ql-editor ol li.ql-indent-3:before {
content: counter(list-3, decimal) '. ';
}
.ql-editor ol li.ql-indent-3 {
counter-reset: list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-4 {
counter-increment: list-4;
}
.ql-editor ol li.ql-indent-4:before {
content: counter(list-4, lower-alpha) '. ';
}
.ql-editor ol li.ql-indent-4 {
counter-reset: list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-5 {
counter-increment: list-5;
}
.ql-editor ol li.ql-indent-5:before {
content: counter(list-5, lower-roman) '. ';
}
.ql-editor ol li.ql-indent-5 {
counter-reset: list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-6 {
counter-increment: list-6;
}
.ql-editor ol li.ql-indent-6:before {
content: counter(list-6, decimal) '. ';
}
.ql-editor ol li.ql-indent-6 {
counter-reset: list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-7 {
counter-increment: list-7;
}
.ql-editor ol li.ql-indent-7:before {
content: counter(list-7, lower-alpha) '. ';
}
.ql-editor ol li.ql-indent-7 {
counter-reset: list-8 list-9;
}
.ql-editor ol li.ql-indent-8 {
counter-increment: list-8;
}
.ql-editor ol li.ql-indent-8:before {
content: counter(list-8, lower-roman) '. ';
}
.ql-editor ol li.ql-indent-8 {
counter-reset: list-9;
}
.ql-editor ol li.ql-indent-9 {
counter-increment: list-9;
}
.ql-editor ol li.ql-indent-9:before {
content: counter(list-9, decimal) '. ';
}
.ql-editor .ql-indent-1:not(.ql-direction-rtl) {
padding-left: 2em;
}
.ql-editor li.ql-indent-1:not(.ql-direction-rtl) {
padding-left: 2em;
}
.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right {
padding-right: 2em;
}
.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right {
padding-right: 2em;
}
.ql-editor .ql-indent-2:not(.ql-direction-rtl) {
padding-left: 4em;
}
.ql-editor li.ql-indent-2:not(.ql-direction-rtl) {
padding-left: 4em;
}
.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right {
padding-right: 4em;
}
.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right {
padding-right: 4em;
}
.ql-editor .ql-indent-3:not(.ql-direction-rtl) {
padding-left: 6em;
}
.ql-editor li.ql-indent-3:not(.ql-direction-rtl) {
padding-left: 6em;
}
.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right {
padding-right: 6em;
}
.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right {
padding-right: 6em;
}
.ql-editor .ql-indent-4:not(.ql-direction-rtl) {
padding-left: 8em;
}
.ql-editor li.ql-indent-4:not(.ql-direction-rtl) {
padding-left: 8em;
}
.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right {
padding-right: 8em;
}
.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right {
padding-right: 8em;
}
.ql-editor .ql-indent-5:not(.ql-direction-rtl) {
padding-left: 10em;
}
.ql-editor li.ql-indent-5:not(.ql-direction-rtl) {
padding-left: 10em;
}
.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right {
padding-right: 10em;
}
.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right {
padding-right: 10em;
}
.ql-editor .ql-indent-6:not(.ql-direction-rtl) {
padding-left: 12em;
}
.ql-editor li.ql-indent-6:not(.ql-direction-rtl) {
padding-left: 12em;
}
.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right {
padding-right: 12em;
}
.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right {
padding-right: 12em;
}
.ql-editor .ql-indent-7:not(.ql-direction-rtl) {
padding-left: 14em;
}
.ql-editor li.ql-indent-7:not(.ql-direction-rtl) {
padding-left: 14em;
}
.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right {
padding-right: 14em;
}
.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right {
padding-right: 14em;
}
.ql-editor .ql-indent-8:not(.ql-direction-rtl) {
padding-left: 16em;
}
.ql-editor li.ql-indent-8:not(.ql-direction-rtl) {
padding-left: 16em;
}
.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right {
padding-right: 16em;
}
.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right {
padding-right: 16em;
}
.ql-editor .ql-indent-9:not(.ql-direction-rtl) {
padding-left: 18em;
}
.ql-editor li.ql-indent-9:not(.ql-direction-rtl) {
padding-left: 18em;
}
.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right {
padding-right: 18em;
}
.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right {
padding-right: 18em;
}
.ql-editor .ql-direction-rtl {
direction: rtl;
text-align: inherit;
}
.ql-editor .ql-align-center {
text-align: center;
}
.ql-editor .ql-align-justify {
text-align: justify;
}
.ql-editor .ql-align-right {
text-align: right;
}
.ql-editor.ql-blank::before {
color: rgba(0, 0, 0, 0.6);
content: attr(data-placeholder);
font-style: italic;
pointer-events: none;
position: absolute;
}
.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before {
pointer-events: none;
}
.ql-clipboard {
left: -100000px;
height: 1px;
overflow-y: hidden;
position: absolute;
top: 50%;
}
@keyframes once-show {
from {
top: 0;
}
}
uni-resize-sensor,
uni-resize-sensor > div {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
uni-resize-sensor {
display: block;
z-index: -1;
visibility: hidden;
animation: once-show 1ms;
}
uni-resize-sensor > div > div {
position: absolute;
left: 0;
top: 0;
}
uni-resize-sensor > div:first-child > div {
width: 100000px;
height: 100000px;
}
uni-resize-sensor > div:last-child > div {
width: 200%;
height: 200%;
}
.uni-label-pointer {
cursor: pointer;
}
uni-movable-view {
display: inline-block;
width: 10px;
height: 10px;
top: 0px;
left: 0px;
position: absolute;
cursor: grab;
}
uni-movable-view[hidden] {
display: none;
}
uni-radio {
-webkit-tap-highlight-color: transparent;
display: inline-block;
cursor: pointer;
}
uni-radio[hidden] {
display: none;
}
uni-radio[disabled] {
cursor: not-allowed;
}
uni-radio .uni-radio-wrapper {
display: -webkit-inline-flex;
display: inline-flex;
-webkit-align-items: center;
align-items: center;
vertical-align: middle;
}
uni-radio .uni-radio-input {
-webkit-appearance: none;
appearance: none;
margin-right: 5px;
outline: 0;
border: 1px solid #D1D1D1;
background-color: #ffffff;
border-radius: 50%;
width: 22px;
height: 22px;
position: relative;
}
uni-radio:not([disabled]) .uni-radio-input:hover {
border-color: #007aff;
}
uni-radio .uni-radio-input.uni-radio-input-checked:before {
font: normal normal normal 14px/1 "uni";
content: "\EA08";
color: #ffffff;
font-size: 18px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -48%) scale(0.73);
-webkit-transform: translate(-50%, -48%) scale(0.73);
}
uni-radio .uni-radio-input.uni-radio-input-disabled {
background-color: #E1E1E1;
border-color: #D1D1D1;
}
uni-radio .uni-radio-input.uni-radio-input-disabled:before {
color: #ADADAD;
}
uni-radio-group {
display: block;
}
uni-radio-group[hidden] {
display: none;
}
uni-swiper-item {
display: block;
overflow: hidden;
will-change: transform;
position: absolute;
width: 100%;
height: 100%;
cursor: grab;
}
uni-swiper-item[hidden] {
display: none;
}
uni-switch {
-webkit-tap-highlight-color: transparent;
display: inline-block;
cursor: pointer;
}
uni-switch[hidden] {
display: none;
}
uni-switch[disabled] {
cursor: not-allowed;
}
uni-switch .uni-switch-wrapper {
display: -webkit-inline-flex;
display: inline-flex;
-webkit-align-items: center;
align-items: center;
vertical-align: middle;
}
uni-switch .uni-switch-input {
-webkit-appearance: none;
appearance: none;
position: relative;
width: 52px;
height: 32px;
margin-right: 5px;
border: 1px solid #DFDFDF;
outline: 0;
border-radius: 16px;
box-sizing: border-box;
background-color: #DFDFDF;
transition: background-color 0.1s, border 0.1s;
}
uni-switch[disabled] .uni-switch-input {
opacity: .7;
}
uni-switch .uni-switch-input:before {
content: " ";
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 30px;
border-radius: 15px;
background-color: #FDFDFD;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
}
uni-switch .uni-switch-input:after {
content: " ";
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 30px;
border-radius: 15px;
background-color: #FFFFFF;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
}
uni-switch .uni-switch-input.uni-switch-input-checked {
border-color: #007aff;
background-color: #007aff;
}
uni-switch .uni-switch-input.uni-switch-input-checked:before {
-webkit-transform: scale(0);
transform: scale(0);
}
uni-switch .uni-switch-input.uni-switch-input-checked:after {
-webkit-transform: translateX(20px);
transform: translateX(20px);
}
uni-switch .uni-checkbox-input {
margin-right: 5px;
-webkit-appearance: none;
appearance: none;
outline: 0;
border: 1px solid #D1D1D1;
background-color: #FFFFFF;
border-radius: 3px;
width: 22px;
height: 22px;
position: relative;
color: #007aff;
}
uni-switch:not([disabled]) .uni-checkbox-input:hover {
border-color: #007aff;
}
uni-switch .uni-checkbox-input.uni-checkbox-input-checked:before {
font: normal normal normal 14px/1 "uni";
content: "\EA08";
color: inherit;
font-size: 22px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -48%) scale(0.73);
-webkit-transform: translate(-50%, -48%) scale(0.73);
}
uni-switch .uni-checkbox-input.uni-checkbox-input-disabled {
background-color: #E1E1E1;
}
uni-switch .uni-checkbox-input.uni-checkbox-input-disabled:before {
color: #ADADAD;
}
uni-textarea {
width: 300px;
height: 150px;
display: block;
position: relative;
font-size: 16px;
line-height: normal;
white-space: pre-wrap;
word-break: break-all;
}
uni-textarea[hidden] {
display: none;
}
.uni-textarea-wrapper,
.uni-textarea-placeholder,
.uni-textarea-line,
.uni-textarea-compute,
.uni-textarea-textarea {
outline: none;
border: none;
padding: 0;
margin: 0;
text-decoration: inherit;
}
.uni-textarea-wrapper {
display: block;
position: relative;
width: 100%;
height: 100%;
}
.uni-textarea-placeholder,
.uni-textarea-line,
.uni-textarea-compute,
.uni-textarea-textarea {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
white-space: inherit;
word-break: inherit;
}
.uni-textarea-placeholder {
color: grey;
overflow: hidden;
}
.uni-textarea-line,
.uni-textarea-compute {
visibility: hidden;
height: auto;
}
.uni-textarea-line {
width: 1em;
}
.uni-textarea-textarea {
resize: none;
background: none;
color: inherit;
opacity: 1;
-webkit-text-fill-color: currentcolor;
font: inherit;
line-height: inherit;
letter-spacing: inherit;
text-align: inherit;
text-indent: inherit;
text-transform: inherit;
text-shadow: inherit;
}
/* 用于解决 iOS textarea 内部默认边距 */
.uni-textarea-textarea-fix-margin {
width: auto;
right: 0;
margin: 0 -3px;
}
.uni-async-error {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #999;
padding: 100px 10px;
text-align: center;
}
.uni-async-loading {
box-sizing: border-box;
width: 100%;
padding: 50px;
text-align: center;
}
.uni-async-loading .uni-loading {
width: 30px;
height: 30px;
}
此差异已折叠。
......@@ -25,6 +25,6 @@
},
"dependencies": {
"safe-area-insets": "^1.4.1",
"vue-router": "^4.0.5"
"vue-router": "^4.0.6"
}
}
import { ComponentPublicInstance } from 'vue'
const WINDOW_NAMES = ['VUniLeftWindow', 'VUniTopWindow', 'VUniRightWindow']
export function isInWindows(vm: ComponentPublicInstance) {
while (vm) {
const name = vm.$options.name
if (name && WINDOW_NAMES.indexOf(name) !== -1) {
return true
}
vm = vm.$parent!
}
return false
}
import { ComponentPublicInstance } from 'vue'
import { getRealRoute } from '@dcloudio/uni-core'
export function findElem(vm: ComponentPublicInstance) {
return vm.$el
}
const SCHEME_RE = /^([a-z-]+:)?\/\//i
const DATA_RE = /^data:.*,.*/
......
export * from './getRealPath'
export * from './dom'
export { getBaseSystemInfo } from '../service/api/base/getBaseSystemInfo'
export { operateVideoPlayer } from '../service/api/context/operateVideoPlayer'
export {
addIntersectionObserver,
removeIntersectionObserver,
} from '../service/api/ui/intersectionObserver'
import {
requestComponentObserver,
AddIntersectionObserverArgs,
RemoveIntersectionObserverArgs,
} from '@dcloudio/uni-api'
import { findElem } from '../../../platform/dom'
export function addIntersectionObserver(
{ reqId, component, options, callback }: AddIntersectionObserverArgs,
_pageId: number
) {
const $el = findElem(component)
;($el.__io || ($el.__io = {}))[reqId] = requestComponentObserver(
$el,
options,
callback
)
}
export function removeIntersectionObserver(
{ reqId, component }: RemoveIntersectionObserverArgs,
_pageId: number
) {
const $el = findElem(component)
const intersectionObserver = $el.__io && $el.__io[reqId]
if (intersectionObserver) {
intersectionObserver.disconnect()
delete $el.__io[reqId]
}
}
<template>
<uni-video
:id="id"
v-on="$listeners"
>
<uni-video :id="id" v-on="$listeners">
<div
ref="container"
class="uni-video-container"
......@@ -10,11 +7,11 @@
@touchend="touchend"
@touchmove="touchmove"
@fullscreenchange.stop="onFullscreenChange"
@webkitfullscreenchange.stop="onFullscreenChange($event,true)"
@webkitfullscreenchange.stop="onFullscreenChange($event, true)"
>
<video
ref="video"
:style="{objectFit:objectFit}"
:style="{ objectFit: objectFit }"
:muted="muted"
:loop="loop"
:src="srcSync"
......@@ -39,85 +36,49 @@
@webkitendfullscreen="emitFullscreenChange(false)"
@x5videoexitfullscreen="emitFullscreenChange(false)"
/>
<div
v-show="controlsShow"
class="uni-video-bar uni-video-bar-full"
@click.stop
>
<div v-show="controlsShow" class="uni-video-bar uni-video-bar-full" @click.stop>
<div class="uni-video-controls">
<div
v-show="showPlayBtn"
:class="{'uni-video-control-button-play':!playing,'uni-video-control-button-pause':playing}"
:class="{ 'uni-video-control-button-play': !playing, 'uni-video-control-button-pause': playing }"
class="uni-video-control-button"
@click.stop="trigger"
/>
<div class="uni-video-current-time">
{{ currentTime|time }}
</div>
<div class="uni-video-current-time">{{ currentTime | time }}</div>
<div
ref="progress"
class="uni-video-progress-container"
@click.stop="clickProgress($event)"
>
<div class="uni-video-progress">
<div
:style="{width:buffered+'%'}"
class="uni-video-progress-buffered"
/>
<div
ref="ball"
:style="{left:progress+'%'}"
class="uni-video-ball"
>
<div :style="{ width: buffered + '%' }" class="uni-video-progress-buffered" />
<div ref="ball" :style="{ left: progress + '%' }" class="uni-video-ball">
<div class="uni-video-inner" />
</div>
</div>
</div>
<div class="uni-video-duration">
{{ (duration||durationTime)|time }}
</div>
<div class="uni-video-duration">{{ (duration || durationTime) | time }}</div>
</div>
<div
v-if="danmuBtn"
:class="{'uni-video-danmu-button-active':enableDanmuSync}"
:class="{ 'uni-video-danmu-button-active': enableDanmuSync }"
class="uni-video-danmu-button"
@click.stop="triggerDanmu"
>
{{ $$t("uni.video.danmu") }}
</div>
>{{ $$t("uni.video.danmu") }}</div>
<div
v-show="showFullscreenBtn"
:class="{'uni-video-type-fullscreen':fullscreen}"
:class="{ 'uni-video-type-fullscreen': fullscreen }"
class="uni-video-fullscreen"
@click.stop="triggerFullscreen(!fullscreen)"
/>
</div>
<div
v-show="start&&enableDanmuSync"
ref="danmu"
style="z-index: 0;"
class="uni-video-danmu"
/>
<div
v-if="centerPlayBtnShow"
class="uni-video-cover"
@click.stop
>
<div
class="uni-video-cover-play-button"
@click.stop="play"
/>
<p class="uni-video-cover-duration">
{{ (duration||durationTime)|time }}
</p>
<div v-show="start && enableDanmuSync" ref="danmu" style="z-index: 0;" class="uni-video-danmu" />
<div v-if="centerPlayBtnShow" class="uni-video-cover" @click.stop>
<div class="uni-video-cover-play-button" @click.stop="play" />
<p class="uni-video-cover-duration">{{ (duration || durationTime) | time }}</p>
</div>
<div
:class="{'uni-video-toast-volume':gestureType==='volume'}"
class="uni-video-toast"
>
<div class="uni-video-toast-title">
{{ $$t("uni.video.volume") }}
</div>
<div :class="{ 'uni-video-toast-volume': gestureType === 'volume' }" class="uni-video-toast">
<div class="uni-video-toast-title">{{ $$t("uni.video.volume") }}</div>
<svg
class="uni-video-toast-icon"
width="200px"
......@@ -131,10 +92,7 @@
/>
</svg>
<div class="uni-video-toast-value">
<div
:style="{width:volumeNew*100+'%'}"
class="uni-video-toast-value-content"
>
<div :style="{ width: volumeNew * 100 + '%' }" class="uni-video-toast-value-content">
<div class="uni-video-toast-volume-grids">
<div
v-for="(item,index) in 10"
......@@ -145,13 +103,8 @@
</div>
</div>
</div>
<div
:class="{'uni-video-toast-progress':gestureType=='progress'}"
class="uni-video-toast"
>
<div class="uni-video-toast-title">
{{ currentTimeNew|time }} / {{ durationTime|time }}
</div>
<div :class="{ 'uni-video-toast-progress': gestureType == 'progress' }" class="uni-video-toast">
<div class="uni-video-toast-title">{{ currentTimeNew | time }} / {{ durationTime | time }}</div>
</div>
<div class="uni-video-slots">
<slot />
......@@ -160,20 +113,19 @@
</uni-video>
</template>
<script>
import {
passive
} from '@dcloudio/uni-shared'
import {
subscriber,
interact
} from 'uni-mixins'
import {
supportsPassive
} from 'uni-shared'
import {
i18nMixin
} from 'uni-core/helpers/i18n'
const passiveOptions = supportsPassive ? {
passive: false
} : false
const passiveOptions = passive(false)
const GestureType = {
NONE: 'none',
......@@ -185,7 +137,7 @@ const GestureType = {
export default {
name: 'Video',
filters: {
time (val) {
time(val) {
val = val > 0 && val < Infinity ? val : 0
let h = Math.floor(val / 3600)
let m = Math.floor(val % 3600 / 60)
......@@ -220,7 +172,7 @@ export default {
},
danmuList: {
type: Array,
default () {
default() {
return []
}
},
......@@ -285,7 +237,7 @@ export default {
default: true
}
},
data () {
data() {
return {
start: false,
playing: false,
......@@ -311,41 +263,41 @@ export default {
}
},
computed: {
centerPlayBtnShow () {
centerPlayBtnShow() {
return this.showCenterPlayBtn && !this.start
},
controlsShow () {
controlsShow() {
return !this.centerPlayBtnShow && this.controls && this.controlsVisible
},
autoHideContorls () {
autoHideContorls() {
return this.controlsShow && this.playing && !this.controlsTouching
},
srcSync () {
srcSync() {
return this.$getRealPath(this.src)
}
},
watch: {
enableDanmuSync (val) {
enableDanmuSync(val) {
this.$emit('update:enableDanmu', val)
},
autoHideContorls (val) {
autoHideContorls(val) {
if (val) {
this.autoHideStart()
} else {
this.autoHideEnd()
}
},
srcSync (val) {
srcSync(val) {
this.playing = false
this.currentTime = 0
},
currentTime () {
currentTime() {
this.updateProgress()
},
duration () {
duration() {
this.updateProgress()
},
buffered (buffered) {
buffered(buffered) {
if (buffered !== 0) {
this.$trigger('progress', {}, {
buffered
......@@ -353,7 +305,7 @@ export default {
}
}
},
created () {
created() {
this.otherData = {
danmuList: [],
danmuIndex: {
......@@ -363,11 +315,11 @@ export default {
hideTiming: null
}
const danmuList = this.otherData.danmuList = JSON.parse(JSON.stringify(this.danmuList || []))
danmuList.sort(function (a, b) {
danmuList.sort(function(a, b) {
return (a.time || 0) - (a.time || 0)
})
},
mounted () {
mounted() {
const self = this
let originX
let originY
......@@ -385,7 +337,7 @@ export default {
ball.addEventListener('touchmove', touchmove, passiveOptions)
})
function touchmove (event) {
function touchmove(event) {
const toucher = event.targetTouches[0]
const pageX = toucher.pageX
const pageY = toucher.pageY
......@@ -406,7 +358,7 @@ export default {
event.stopPropagation()
}
function touchend (event) {
function touchend(event) {
self.controlsTouching = false
if (self.touching) {
ball.removeEventListener('touchmove', touchmove, passiveOptions)
......@@ -421,12 +373,12 @@ export default {
ball.addEventListener('touchend', touchend)
ball.addEventListener('touchcancel', touchend)
},
beforeDestroy () {
beforeDestroy() {
this.triggerFullscreen(false)
clearTimeout(this.otherData.hideTiming)
},
methods: {
_handleSubscribe ({
_handleSubscribe({
type,
data = {}
}) {
......@@ -447,27 +399,27 @@ export default {
this[type](options)
}
},
trigger () {
trigger() {
if (this.playing) {
this.$refs.video.pause()
} else {
this.$refs.video.play()
}
},
play () {
play() {
this.start = true
this.$refs.video.play()
},
pause () {
pause() {
this.$refs.video.pause()
},
seek (position) {
seek(position) {
position = Number(position)
if (typeof position === 'number' && !isNaN(position)) {
this.$refs.video.currentTime = position
}
},
clickProgress (event) {
clickProgress(event) {
const $progress = this.$refs.progress
let element = event.target
let x = event.offsetX
......@@ -482,25 +434,25 @@ export default {
this.seek(this.$refs.video.duration * progress)
}
},
triggerDanmu () {
triggerDanmu() {
this.enableDanmuSync = !this.enableDanmuSync
},
playDanmu (danmu) {
playDanmu(danmu) {
const p = document.createElement('p')
p.className = 'uni-video-danmu-item'
p.innerText = danmu.text
let style = `bottom: ${Math.random() * 100}%;color: ${danmu.color};`
p.setAttribute('style', style)
this.$refs.danmu.appendChild(p)
setTimeout(function () {
setTimeout(function() {
style += 'left: 0;-webkit-transform: translateX(-100%);transform: translateX(-100%);'
p.setAttribute('style', style)
setTimeout(function () {
setTimeout(function() {
p.remove()
}, 4000)
}, 17)
},
sendDanmu (danmu) {
sendDanmu(danmu) {
const otherData = this.otherData
otherData.danmuList.splice(otherData.danmuIndex.index + 1, 0, {
text: String(danmu.text),
......@@ -508,10 +460,10 @@ export default {
time: this.$refs.video.currentTime || 0
})
},
playbackRate (rate) {
playbackRate(rate) {
this.$refs.video.playbackRate = rate
},
triggerFullscreen (val) {
triggerFullscreen(val) {
const container = this.$refs.container
const video = this.$refs.video
let mockFullScreen
......@@ -546,29 +498,29 @@ export default {
this.emitFullscreenChange(val)
}
},
onFullscreenChange ($event, webkit) {
onFullscreenChange($event, webkit) {
if (webkit && document.fullscreenEnabled) {
return
}
this.emitFullscreenChange(!!(document.fullscreenElement || document.webkitFullscreenElement))
},
emitFullscreenChange (val) {
emitFullscreenChange(val) {
this.fullscreen = val
this.$trigger('fullscreenchange', {}, {
fullScreen: val,
direction: 'vertical'
})
},
requestFullScreen () {
requestFullScreen() {
this.triggerFullscreen(true)
},
exitFullScreen () {
exitFullScreen() {
this.triggerFullscreen(false)
},
onDurationChange ({ target }) {
onDurationChange({ target }) {
this.durationTime = target.duration
},
onLoadedMetadata ($event) {
onLoadedMetadata($event) {
const initialTime = Number(this.initialTime) || 0
const video = $event.target
if (initialTime > 0) {
......@@ -581,34 +533,34 @@ export default {
})
this.onProgress($event)
},
onProgress ($event) {
onProgress($event) {
const video = $event.target
const buffered = video.buffered
if (buffered.length) {
this.buffered = buffered.end(buffered.length - 1) / video.duration * 100
}
},
onWaiting ($event) {
onWaiting($event) {
this.$trigger('waiting', $event, {})
},
onVideoError ($event) {
onVideoError($event) {
this.playing = false
this.$trigger('error', $event, {})
},
onPlay ($event) {
onPlay($event) {
this.start = true
this.playing = true
this.$trigger('play', $event, {})
},
onPause ($event) {
onPause($event) {
this.playing = false
this.$trigger('pause', $event, {})
},
onEnded ($event) {
onEnded($event) {
this.playing = false
this.$trigger('ended', $event, {})
},
onTimeUpdate ($event) {
onTimeUpdate($event) {
const video = $event.target
const otherData = this.otherData
const currentTime = this.currentTime = video.currentTime
......@@ -646,10 +598,10 @@ export default {
duration: video.duration
})
},
triggerControls () {
triggerControls() {
this.controlsVisible = !this.controlsVisible
},
touchstart (event) {
touchstart(event) {
const toucher = event.targetTouches[0]
this.touchStartOrigin = {
x: toucher.pageX,
......@@ -659,8 +611,8 @@ export default {
this.volumeOld = null
this.currentTimeOld = this.currentTimeNew = 0
},
touchmove (event) {
function stop () {
touchmove(event) {
function stop() {
event.stopPropagation()
event.preventDefault()
}
......@@ -705,7 +657,7 @@ export default {
}
}
},
touchend (event) {
touchend(event) {
if (this.gestureType !== GestureType.NONE && this.gestureType !== GestureType.STOP) {
event.stopPropagation()
event.preventDefault()
......@@ -715,7 +667,7 @@ export default {
}
this.gestureType = GestureType.NONE
},
changeProgress (x) {
changeProgress(x) {
const duration = this.$refs.video.duration
let currentTimeNew = x / 600 * duration + this.currentTimeOld
if (currentTimeNew < 0) {
......@@ -725,7 +677,7 @@ export default {
}
this.currentTimeNew = currentTimeNew
},
changeVolume (y) {
changeVolume(y) {
const valueOld = this.volumeOld
let value
if (typeof valueOld === 'number') {
......@@ -739,19 +691,19 @@ export default {
this.volumeNew = value
}
},
autoHideStart () {
autoHideStart() {
this.otherData.hideTiming = setTimeout(() => {
this.controlsVisible = false
}, 3000)
},
autoHideEnd () {
autoHideEnd() {
const otherData = this.otherData
if (otherData.hideTiming) {
clearTimeout(otherData.hideTiming)
otherData.hideTiming = null
}
},
updateProgress () {
updateProgress() {
if (!this.touching) {
this.progress = this.currentTime / this.durationTime * 100
}
......
uni-scroll-view {
display: block;
width: 100%;
}
uni-scroll-view[hidden] {
display: none;
}
.uni-scroll-view {
position: relative;
-webkit-overflow-scrolling: touch;
width: 100%;
/* display: flex; 时在安卓下会导致scrollWidth和offsetWidth一样 */
height: 100%;
max-height: inherit;
}
.uni-scroll-view-content {
width: 100%;
height: 100%;
}
.uni-scroll-view-refresher {
position: relative;
overflow: hidden;
}
.uni-scroll-view-refresh {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.uni-scroll-view-refresh-inner {
display: flex;
align-items: center;
justify-content: center;
line-height: 0;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.117647),
0 1px 4px rgba(0, 0, 0, 0.117647);
}
.uni-scroll-view-refresh__spinner {
transform-origin: center center;
animation: uni-scroll-view-refresh-rotate 2s linear infinite;
}
.uni-scroll-view-refresh__spinner > circle {
stroke: currentColor;
stroke-linecap: round;
animation: uni-scroll-view-refresh-dash 2s linear infinite;
}
@keyframes uni-scroll-view-refresh-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes uni-scroll-view-refresh-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
......@@ -8,6 +8,10 @@
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-mp-alipay/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
......
export {
getRealPath,
addIntersectionObserver,
removeIntersectionObserver,
} from '@dcloudio/uni-mp-platform'
export function getBaseSystemInfo() {
return my.getSystemInfoSync()
}
export function getRealPath() {}
......@@ -8,6 +8,10 @@
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-mp-baidu/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
......
export {
getRealPath,
addIntersectionObserver,
removeIntersectionObserver,
} from '@dcloudio/uni-mp-platform'
export function getBaseSystemInfo() {
return swan.getSystemInfoSync()
}
export function getRealPath() {}
......@@ -27,8 +27,8 @@ export { initMocks, initComponentInstance } from './runtime/componentInstance'
export { handleEvent } from './runtime/componentEvents'
export { $createComponent, $destroyComponent } from './runtime/component'
export {
initVueIds,
initRefs,
initVueIds,
initWxsCallMethods,
findVmByVueId,
} from './runtime/util'
......
export function getRealPath() {}
export function addIntersectionObserver() {}
export function removeIntersectionObserver() {}
......@@ -8,6 +8,10 @@
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-mp-qq/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
......
export {
getRealPath,
addIntersectionObserver,
removeIntersectionObserver,
} from '@dcloudio/uni-mp-platform'
export function getBaseSystemInfo() {
return qq.getSystemInfoSync()
}
export function getRealPath() {}
......@@ -8,6 +8,10 @@
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-mp-toutiao/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
......
export {
getRealPath,
addIntersectionObserver,
removeIntersectionObserver,
} from '@dcloudio/uni-mp-platform'
export function getBaseSystemInfo() {
return tt.getSystemInfoSync()
}
export function getRealPath() {}
......@@ -8,6 +8,10 @@
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-mp-weixin/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
......
export {
getRealPath,
addIntersectionObserver,
removeIntersectionObserver,
} from '@dcloudio/uni-mp-platform'
export function getBaseSystemInfo() {
return wx.getSystemInfoSync()
}
export function getRealPath() {}
......@@ -8,6 +8,10 @@
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-quickapp-webview/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
......
export {
getRealPath,
addIntersectionObserver,
removeIntersectionObserver,
} from '@dcloudio/uni-mp-platform'
export function getBaseSystemInfo() {
return qa.getSystemInfoSync()
}
export function getRealPath() {}
......@@ -4,23 +4,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
var shared = require('@vue/shared');
const NAVBAR_HEIGHT = 44;
const TABBAR_HEIGHT = 50;
const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff';
function debounce(fn, delay) {
let timeout;
const newFn = function () {
clearTimeout(timeout);
const timerFn = () => fn.apply(this, arguments);
timeout = setTimeout(timerFn, delay);
};
newFn.cancel = function () {
clearTimeout(timeout);
};
return newFn;
function passive(passive) {
return { passive };
}
function normalizeDataset(el) {
// TODO
return JSON.parse(JSON.stringify(el.dataset || {}));
}
function plusReady(callback) {
......@@ -33,26 +22,6 @@ function plusReady(callback) {
document.addEventListener('plusready', callback);
}
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (shared.isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
const BUILT_IN_TAGS = [
'ad',
'audio',
......@@ -128,6 +97,45 @@ function isNativeTag(tag) {
const COMPONENT_SELECTOR_PREFIX = 'uni-';
const COMPONENT_PREFIX = 'v-' + COMPONENT_SELECTOR_PREFIX;
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (shared.isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
function debounce(fn, delay) {
let timeout;
const newFn = function () {
clearTimeout(timeout);
const timerFn = () => fn.apply(this, arguments);
timeout = setTimeout(timerFn, delay);
};
newFn.cancel = function () {
clearTimeout(timeout);
};
return newFn;
}
const NAVBAR_HEIGHT = 44;
const TABBAR_HEIGHT = 50;
const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff';
exports.BUILT_IN_TAGS = BUILT_IN_TAGS;
exports.COMPONENT_NAME_PREFIX = COMPONENT_NAME_PREFIX;
exports.COMPONENT_PREFIX = COMPONENT_PREFIX;
......@@ -141,5 +149,7 @@ exports.debounce = debounce;
exports.isBuiltInComponent = isBuiltInComponent;
exports.isCustomElement = isCustomElement;
exports.isNativeTag = isNativeTag;
exports.normalizeDataset = normalizeDataset;
exports.passive = passive;
exports.plusReady = plusReady;
exports.stringifyQuery = stringifyQuery;
......@@ -20,6 +20,12 @@ export declare function isNativeTag(tag: string): boolean;
export declare const NAVBAR_HEIGHT = 44;
export declare function normalizeDataset(el: Element): any;
export declare function passive(passive: boolean): {
passive: boolean;
};
export declare function plusReady(callback: () => void): void;
export declare const PRIMARY_COLOR = "#007aff";
......
import { isPlainObject, isHTMLTag, isSVGTag } from '@vue/shared';
import { isHTMLTag, isSVGTag, isPlainObject } from '@vue/shared';
const NAVBAR_HEIGHT = 44;
const TABBAR_HEIGHT = 50;
const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff';
function debounce(fn, delay) {
let timeout;
const newFn = function () {
clearTimeout(timeout);
const timerFn = () => fn.apply(this, arguments);
timeout = setTimeout(timerFn, delay);
};
newFn.cancel = function () {
clearTimeout(timeout);
};
return newFn;
function passive(passive) {
return { passive };
}
function normalizeDataset(el) {
// TODO
return JSON.parse(JSON.stringify(el.dataset || {}));
}
function plusReady(callback) {
......@@ -29,26 +18,6 @@ function plusReady(callback) {
document.addEventListener('plusready', callback);
}
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
const BUILT_IN_TAGS = [
'ad',
'audio',
......@@ -124,4 +93,43 @@ function isNativeTag(tag) {
const COMPONENT_SELECTOR_PREFIX = 'uni-';
const COMPONENT_PREFIX = 'v-' + COMPONENT_SELECTOR_PREFIX;
export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, debounce, isBuiltInComponent, isCustomElement, isNativeTag, plusReady, stringifyQuery };
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
function debounce(fn, delay) {
let timeout;
const newFn = function () {
clearTimeout(timeout);
const timerFn = () => fn.apply(this, arguments);
timeout = setTimeout(timerFn, delay);
};
newFn.cancel = function () {
clearTimeout(timeout);
};
return newFn;
}
const NAVBAR_HEIGHT = 44;
const TABBAR_HEIGHT = 50;
const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff';
export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, debounce, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, passive, plusReady, stringifyQuery };
export function passive(passive: boolean) {
return { passive }
}
export function normalizeDataset(el: Element) {
// TODO
return JSON.parse(JSON.stringify((el as HTMLElement).dataset || {}))
}
export * from './constants'
export * from './debounce'
export * from './plusReady'
export * from './query'
export * from './dom'
export * from './plus'
export * from './tags'
export * from './query'
export * from './debounce'
export * from './constants'
......@@ -41,7 +41,8 @@
},
"devDependencies": {
"@types/mime": "^2.0.3",
"@types/sass": "^1.16.0"
"@types/sass": "^1.16.0",
"@vue/compiler-sfc": "^3.0.11"
},
"uni-app": {
"compilerVersion": "3.1.2"
......
......@@ -145,11 +145,11 @@ function resolveManifestFeature(
options: VitePluginUniResolvedOptions
): ManifestFeatures {
const features: ManifestFeatures = {
wx: true,
wxs: true, // 是否启用 wxs 支持,如:getComponentDescriptor 等(uni-core/src/view/plugin/appConfig)
promise: false, // 是否启用旧版本的 promise 支持(即返回[err,res]的格式)
longpress: true, // 是否启用longpress
routerMode: '"hash"', // 启用的 router 类型(uni-h5/src/framework/plugin/router)
wx: false,
wxs: true,
promise: false,
longpress: true,
routerMode: '"hash"',
}
const manifest = parse(
fs.readFileSync(path.join(options.inputDir, 'manifest.json'), 'utf8')
......
......@@ -30,7 +30,10 @@
"@dcloudio/uni-mp-polyfill": [
"packages/uni-mp-core/src/runtime/polyfill"
],
"@dcloudio/uni-platform": ["packages/uni-h5/src/platform/index.ts"]
"@dcloudio/uni-platform": ["packages/uni-h5/src/platform/index.ts"],
"@dcloudio/uni-mp-platform": [
"packages/uni-mp-core/src/platform/index.ts"
]
}
},
"include": [
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册