├── App.vue
├── android
├── assets
│ ├── logo.png
│ └── splash.png
└── com
│ └── itstudy
│ └── io
│ ├── GetComicContent.java
│ ├── GetComicList.java
│ ├── GetDirectoryList.java
│ ├── GetExtSDCardPathList.java
│ ├── GetFileList.java
│ └── GetText.java
├── assets
└── js
│ ├── config.js
│ ├── gb2312.js
│ ├── html-parse.js
│ ├── index.js
│ └── util.js
├── changelog.md
├── common
├── mixin
│ ├── app.js
│ ├── book.js
│ ├── bookcertify.js
│ ├── cache.js
│ ├── index.js
│ ├── lyric.js
│ ├── music.js
│ └── musiccertify.js
└── online
│ ├── getBook.js
│ ├── getComic.js
│ └── getMusic.js
├── components
├── bubble-item
│ └── bubble-item.nvue
├── bubble
│ └── bubble.nvue
├── c-button
│ └── c-button.nvue
├── c-icon
│ └── c-icon.nvue
├── c-image
│ └── c-image.nvue
├── c-switch
│ └── c-switch.nvue
├── comic-image
│ └── comic-image.nvue
├── crosswise
│ └── crosswise.nvue
├── fileList
│ └── fileList.nvue
├── fixed-button
│ └── fixed-button.nvue
├── gap-bar
│ └── gap-bar.nvue
├── list-scroll
│ └── list-scroll.nvue
├── loading
│ └── loading.nvue
├── music-btn
│ └── music-btn.nvue
├── music-icon
│ └── music-icon.nvue
├── music-lyric
│ └── music-lyric.nvue
├── nav-bar
│ └── nav-bar.nvue
├── no-data
│ └── no-data.nvue
├── progress
│ └── progress.nvue
└── search
│ └── search.nvue
├── js_sdk
└── mmmm-image-tools
│ └── index.js
├── main.js
├── manifest.json
├── modules
├── actionSheet.nvue
├── catalog.nvue
├── confirm.nvue
├── edit.nvue
└── security.nvue
├── nativeplugins
└── YingBingNativePlugin
│ ├── android
│ └── uniplugin_yingbing-release.aar
│ └── package.json
├── package.json
├── pages.json
├── pages
├── about
│ └── index.nvue
├── book
│ ├── detail
│ │ └── index.nvue
│ ├── online
│ │ └── index.nvue
│ ├── read
│ │ └── index.vue
│ ├── search
│ │ └── index.nvue
│ └── setting
│ │ └── index.nvue
├── comic
│ ├── detail
│ │ └── index.nvue
│ ├── online
│ │ └── index.nvue
│ ├── read
│ │ └── index.nvue
│ ├── search
│ │ └── index.nvue
│ └── setting
│ │ └── index.nvue
├── index
│ └── index.nvue
├── menu
│ └── menu.nvue
├── music
│ ├── index.nvue
│ ├── online.nvue
│ ├── player.nvue
│ └── search.nvue
└── setting
│ └── index.nvue
├── plugins
├── dom
│ └── index.js
├── index.js
├── request
│ ├── index.js
│ └── request.js
├── router
│ ├── index.js
│ └── router.js
└── xhr
│ ├── index.js
│ └── xhr.js
├── readme.md
├── static
├── cover
│ ├── cover_1.png
│ ├── cover_2.png
│ ├── cover_3.png
│ ├── cover_4.png
│ ├── cover_5.png
│ ├── cover_6.png
│ └── cover_default.jpg
├── menuBack.png
├── music
│ ├── border-default.png
│ ├── border-night.png
│ ├── loop.png
│ ├── music-bg.jpg
│ ├── music-icon.png
│ ├── music-list.png
│ ├── music-type.png
│ ├── next.png
│ ├── once.png
│ ├── pause.png
│ ├── play.png
│ ├── prev.png
│ └── random.png
└── no-data.png
├── store
├── config.js
├── index.js
└── modules
│ ├── app.js
│ ├── book.js
│ ├── bookcertify.js
│ ├── cache.js
│ ├── music.js
│ ├── musiccertify.js
│ └── skin.js
└── uni_modules
└── yingbing-ReadPage
├── changelog.md
├── components
├── computed-page
│ └── computed-page.vue
├── flip-page
│ └── flip-page.vue
├── page-no-chapter
│ └── page-no-chapter.vue
├── page-refresh
│ └── page-refresh.vue
├── scroll-page
│ ├── scroll-page - 副本.vue
│ └── scroll-page.vue
└── yingbing-ReadPage
│ └── yingbing-ReadPage.vue
├── node_modules
└── @better-scroll
│ ├── core
│ ├── LICENSE
│ ├── README.md
│ ├── README_zh-CN.md
│ ├── dist
│ │ ├── core.esm.js
│ │ ├── core.js
│ │ ├── core.min.js
│ │ └── types
│ │ │ ├── BScroll.d.ts
│ │ │ ├── Instance.d.ts
│ │ │ ├── Options.d.ts
│ │ │ ├── animater
│ │ │ ├── Animation.d.ts
│ │ │ ├── Base.d.ts
│ │ │ ├── Transition.d.ts
│ │ │ └── index.d.ts
│ │ │ ├── base
│ │ │ └── ActionsHandler.d.ts
│ │ │ ├── index.d.ts
│ │ │ ├── scroller
│ │ │ ├── Actions.d.ts
│ │ │ ├── Behavior.d.ts
│ │ │ ├── DirectionLock.d.ts
│ │ │ ├── Scroller.d.ts
│ │ │ └── createOptions.d.ts
│ │ │ ├── translater
│ │ │ └── index.d.ts
│ │ │ └── utils
│ │ │ ├── bubbling.d.ts
│ │ │ ├── compare.d.ts
│ │ │ ├── compat.d.ts
│ │ │ └── typesHelper.d.ts
│ ├── package.json
│ └── src
│ │ ├── BScroll.ts
│ │ ├── Instance.ts
│ │ ├── Options.ts
│ │ ├── __mocks__
│ │ ├── Options.ts
│ │ └── index.ts
│ │ ├── __tests__
│ │ ├── Options.spec.ts
│ │ ├── __utils__
│ │ │ ├── event.ts
│ │ │ └── layout.ts
│ │ └── index.spec.ts
│ │ ├── animater
│ │ ├── Animation.ts
│ │ ├── Base.ts
│ │ ├── Transition.ts
│ │ ├── __mocks__
│ │ │ ├── Animation.ts
│ │ │ ├── Transition.ts
│ │ │ └── index.ts
│ │ ├── __tests__
│ │ │ ├── Animation.spec.ts
│ │ │ ├── Transition.spec.ts
│ │ │ └── index.spec.ts
│ │ └── index.ts
│ │ ├── base
│ │ ├── ActionsHandler.ts
│ │ ├── __mocks__
│ │ │ └── ActionsHandler.ts
│ │ └── __tests__
│ │ │ └── ActionsHandler.spec.ts
│ │ ├── index.ts
│ │ ├── scroller
│ │ ├── Actions.ts
│ │ ├── Behavior.ts
│ │ ├── DirectionLock.ts
│ │ ├── Scroller.ts
│ │ ├── __mocks__
│ │ │ ├── Actions.ts
│ │ │ ├── Behavior.ts
│ │ │ ├── DirectionLock.ts
│ │ │ └── Scroller.ts
│ │ ├── __tests__
│ │ │ ├── Actions.spec.ts
│ │ │ ├── Behavior.spec.ts
│ │ │ ├── DirectionLock.spec.ts
│ │ │ ├── Scroller.spec.ts
│ │ │ └── createOptions.spec.ts
│ │ └── createOptions.ts
│ │ ├── translater
│ │ ├── __mocks__
│ │ │ └── index.ts
│ │ ├── __tests__
│ │ │ └── index.spec.ts
│ │ └── index.ts
│ │ └── utils
│ │ ├── __tests__
│ │ └── bubbling.spec.ts
│ │ ├── bubbling.ts
│ │ ├── compare.ts
│ │ ├── compat.ts
│ │ └── typesHelper.ts
│ ├── pull-down
│ ├── LICENSE
│ ├── README.md
│ ├── README_zh-CN.md
│ ├── dist
│ │ ├── pull-down.esm.js
│ │ ├── pull-down.js
│ │ ├── pull-down.min.js
│ │ └── types
│ │ │ ├── index.d.ts
│ │ │ └── propertiesConfig.d.ts
│ ├── package.json
│ └── src
│ │ ├── __tests__
│ │ └── index.spec.ts
│ │ ├── index.ts
│ │ └── propertiesConfig.ts
│ └── pull-up
│ ├── LICENSE
│ ├── README.md
│ ├── README_zh-CN.md
│ ├── dist
│ ├── pull-up.esm.js
│ ├── pull-up.js
│ ├── pull-up.min.js
│ └── types
│ │ ├── index.d.ts
│ │ └── propertiesConfig.d.ts
│ ├── package.json
│ └── src
│ ├── __tests__
│ └── index.spec.ts
│ ├── index.ts
│ └── propertiesConfig.ts
├── package.json
└── readme.md
/App.vue:
--------------------------------------------------------------------------------
1 |
32 |
33 |
87 |
--------------------------------------------------------------------------------
/android/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/android/assets/logo.png
--------------------------------------------------------------------------------
/android/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/android/assets/splash.png
--------------------------------------------------------------------------------
/android/com/itstudy/io/GetDirectoryList.java:
--------------------------------------------------------------------------------
1 | package com.itstudy.io;
2 |
3 |
4 | import org.json.JSONArray;
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 | import java.text.SimpleDateFormat;
11 |
12 | /**
13 | * @Title: FileList
14 | * @author: 康雷 e-mail: 1014295211@qq.com
15 | * @date: 2020/9/22 16:51
16 | * @ClassName: GetDirectoryList
17 | * @Description: 获取指定路径下的文件夹列表
18 | */
19 | public class GetDirectoryList {
20 |
21 |
22 | public String getDirectories(String path) throws IOException, JSONException {
23 | File file = new File(path);
24 | File[] files = file.listFiles();
25 | JSONArray folderJsonArray = new JSONArray();
26 | for (File value : files) {
27 | if ( !value.isHidden() ) {
28 | JSONObject jsonObject = new JSONObject();
29 | if (value.isDirectory()) {
30 | jsonObject.put("name", value.getName());
31 | jsonObject.put("path", value.getPath());
32 | jsonObject.put("type", "folder");
33 | jsonObject.put("size", "0B");
34 | jsonObject.put("time", this.getFileTime(value));
35 | jsonObject.put("createTime",value.lastModified());
36 | folderJsonArray.put(jsonObject);
37 | }
38 | }
39 | }
40 | return folderJsonArray.toString();
41 | }
42 |
43 | private String getFileTime(File file) {
44 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
45 | return formatter.format(file.lastModified());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/android/com/itstudy/io/GetExtSDCardPathList.java:
--------------------------------------------------------------------------------
1 | package com.itstudy.io;
2 |
3 |
4 | import android.os.Build;
5 | import android.os.Environment;
6 | import android.os.UserHandle;
7 | import android.support.annotation.RequiresApi;
8 |
9 | import org.json.JSONArray;
10 | import org.json.JSONException;
11 | import org.json.JSONObject;
12 |
13 | import java.io.File;
14 | import java.io.IOException;
15 | import java.lang.reflect.Constructor;
16 | import java.lang.reflect.Method;
17 |
18 | /**
19 | * @Title: FileList
20 | * @author: 康雷 e-mail: 1014295211@qq.com
21 | * @date: 2020/9/22 16:51
22 | * @ClassName: GetExtSDCardPathList
23 | * @Description: 获取扩展TF卡路径
24 | */
25 | public class GetExtSDCardPathList {
26 |
27 |
28 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
29 | public static String getSDPath() throws IOException, JSONException{
30 | JSONArray paths = new JSONArray();
31 | try {
32 | //===========================获取UserEnvironment================
33 | Class> userEnvironment = Class.forName("android.os.Environment$UserEnvironment");
34 | Method getExternalDirs =userEnvironment.getDeclaredMethod("getExternalDirs");
35 | getExternalDirs.setAccessible(true);
36 | //========获取构造UserEnvironment的必要参数UserId================
37 | Class> userHandle = Class.forName("android.os.UserHandle");
38 | Method myUserId = userHandle.getDeclaredMethod("myUserId");
39 | myUserId.setAccessible(true);
40 | int mUserId = (int) myUserId.invoke(UserHandle.class);
41 | Constructor> declaredConstructor = userEnvironment.getDeclaredConstructor(Integer.TYPE);
42 | // 得到UserEnvironment instance
43 | Object instance = declaredConstructor.newInstance(mUserId);
44 | File[] files = (File[]) getExternalDirs.invoke(instance);
45 | for (int i = 0; i < files.length; i++) {
46 | if (Environment.isExternalStorageRemovable(files[i])){
47 | JSONObject jsonObject = new JSONObject();
48 | jsonObject.put("path", files[i].getPath());
49 | paths.put(jsonObject);
50 | }
51 | }
52 | } catch (Exception e) {
53 |
54 | }
55 | return paths.toString();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/android/com/itstudy/io/GetText.java:
--------------------------------------------------------------------------------
1 | package com.itstudy.io;
2 |
3 | import java.io.*;
4 |
5 | /**
6 | * @Title: TestTranslate
7 | * @author: 何杰 e-mail: 734412450@qq.com
8 | * @date: 2020/8/26 16:45
9 | * @ClassName: GetText
10 | * @Description: 获取txt文本内容
11 | */
12 | public class GetText {
13 |
14 |
15 |
16 | //判断编码格式方法
17 | private static String getFileCharset(File sourceFile) {
18 | String charset = "GBK";
19 | byte[] first3Bytes = new byte[3];
20 | try {
21 | boolean checked = false;
22 | BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile));
23 | bis.mark(0);
24 | int read = bis.read(first3Bytes, 0, 3);
25 | //文件编码为 ANSI
26 | if (read == -1) {
27 | return charset;
28 | } else if (first3Bytes[0] == (byte) 0xFF
29 | && first3Bytes[1] == (byte) 0xFE) {
30 | //文件编码为 Unicode
31 | charset = "UTF-16LE";
32 | checked = true;
33 | } else if (first3Bytes[0] == (byte) 0xFE
34 | && first3Bytes[1] == (byte) 0xFF) {
35 | //文件编码为 Unicode big endian
36 | charset = "UTF-16BE";
37 | checked = true;
38 | } else if (first3Bytes[0] == (byte) 0xEF
39 | && first3Bytes[1] == (byte) 0xBB
40 | && first3Bytes[2] == (byte) 0xBF) {
41 | //文件编码为 UTF-8
42 | charset = "UTF-8";
43 | checked = true;
44 | }
45 | bis.reset();
46 | if (!checked) {
47 | int loc = 0;
48 | while ((read = bis.read()) != -1) {
49 | loc++;
50 | if (read >= 0xF0) {
51 | break;
52 | }
53 | // 单独出现BF以下的,也算是GBK
54 | if (0x80 <= read && read <= 0xBF) {
55 | break;
56 | }
57 | if (0xC0 <= read && read <= 0xDF) {
58 | read = bis.read();
59 | // 双字节 (0xC0 - 0xDF)
60 | if (0x80 <= read && read <= 0xBF)
61 | // (0x80
62 | // - 0xBF),也可能在GB编码内
63 | {
64 | continue;
65 | } else {
66 | break;
67 | }
68 | // 也有可能出错,但是几率较小
69 | } else if (0xE0 <= read && read <= 0xEF) {
70 | read = bis.read();
71 | if (0x80 <= read && read <= 0xBF) {
72 | read = bis.read();
73 | if (0x80 <= read && read <= 0xBF) {
74 | charset = "UTF-8";
75 | break;
76 | } else{
77 | break;}
78 | } else {
79 | break;
80 | }
81 | }
82 | }
83 | }
84 | bis.close();
85 | } catch (Exception e) {
86 | e.printStackTrace();
87 | }
88 | return charset;
89 | }
90 |
91 | public String getTextFromText(String filePath) {
92 |
93 | try {
94 | // 获取输入流
95 | InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), getFileCharset(new File(filePath)));
96 | BufferedReader br = new BufferedReader(isr);
97 |
98 | StringBuffer sb = new StringBuffer();
99 | String temp = null;
100 | while ((temp = br.readLine()) != null) {
101 | sb.append(temp+"\r\n");
102 | }
103 | br.close();
104 | return sb.toString();
105 | } catch (FileNotFoundException e) {
106 | // TODO Auto-generated catch block
107 | e.printStackTrace();
108 |
109 | } catch (IOException e) {
110 | // TODO Auto-generated catch block
111 | e.printStackTrace();
112 | }
113 | return null;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/assets/js/config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | //小说网站链接
3 | BOOKURL: {
4 | 'baoshuu': {
5 | title: '手机宝书',
6 | href: 'http://m.baoshuu.com'
7 | }
8 | },
9 |
10 | //漫画网站链接
11 | COMICURL: {
12 | 'mangabz': {
13 | title: 'mangaBz',
14 | href: 'http://www.mangabz.com'
15 | },
16 | 'sixmh': {
17 | title: '6漫画',
18 | href: 'http://m.sixmh7.com'
19 | },
20 | 'dmzj': {
21 | title: '动漫之家',
22 | href: 'https://www.dmzj.com'
23 | }
24 | },
25 | //音乐网站链接
26 | MUSICURL: {
27 | 'qqmusic': {
28 | title: 'QQ音乐',
29 | href: 'https://c.y.qq.com'
30 | },
31 | '163music': {
32 | title: '网易云音乐',
33 | href: 'https://autumnfish.cn'
34 | }
35 | },
36 |
37 | //青壮年内容
38 | ADULTS: [],
39 |
40 | //QQ音乐请求常量
41 | commonParams: {
42 | g_tk: 5381,
43 | loginUin: 0,
44 | hostUin: 0,
45 | format: 'json',
46 | inCharset: 'utf8',
47 | outCharset: 'utf-8',
48 | notice: 0,
49 | platform: 'yqq.json',
50 | needNewCode: 0
51 | },
52 |
53 |
54 | //请求成功编码
55 | ERR_OK: 200,
56 | //请求失败编码
57 | ERR_FALSE: 300,
58 | //请求超时时间
59 | TIMEOUT: 50000
60 | }
61 |
--------------------------------------------------------------------------------
/assets/js/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Utils from './util.js';
3 | import Config from './config.js';
4 |
5 | Vue.prototype.$utils = Utils;
6 | Vue.prototype.$config = Config;
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | ## 2.9.8.5(2021-10-19)
2 | * 更新阅读插件
3 | * 修复显示一些图片app会卡死的问题
4 | * 优化部分图片缓存问题
5 | ## 2.9.8.4(2021-10-14)
6 | * 新增小说接口
7 | * 添加青少年模式
8 | * 接入最新版阅读插件
9 | * 添加在线小说阅读页面进度条显示
10 | ## 2.9.8.3(2021-09-22)
11 | * 修复阅读在线小说有时部分页面不显示的bug
12 | * 修复在线小说阅读新章节时会继承上次阅读章节的阅读位置的bug
13 | * 更改音乐播放全局控件样式,更改播放列表样式
14 | ## 2.9.8.2(2021-09-17)
15 | * 修复某个漫画接口不能显示图片的问题
16 | * 修改了在线小说内容获取方式
17 | * 修改了在线漫画内容获取方式
18 | * 删除了一个漫画接口
19 | ## 2.9.81(2021-09-08)
20 | * 修复了漫画阅读页面不能切换章节的问题
21 | * 现在将获取本地小说文本内容的原生方法封装成了插件,同时获取文件列表的方法也使用native.js方法获取,如果你不需要阅读本地漫画,就可以直接云打包
22 | ## 2.9.8(2021-09-06)
23 | * 修复阅读本地小说到最后会从开始重新排版的bug
24 | * 修复阅读小说设置窗口可能打不开的bug
25 | ## 2.9.7(2021-09-04)
26 | * 新增在线小说接口
27 | * 修复部分在线漫画接口
28 | * 优化了代码格式
29 | * 优化了文件结构
30 | ## 2.9.6(2021-08-28)
31 | * 更新了失效的音乐搜索接口
32 | * 将文件搜索列表独立成组件
33 | * 更新了获取漫画内容的方式
34 | * 更新小说分页组件,现在被独立成一个插件,大家可以去看看我新发布的分页插件[小说阅读分页插件](https://ext.dcloud.net.cn/plugin?id=6026)
35 | ## 2.9.5(2021-06-14)
36 | * 新增小说编辑功能,非常适合发现有错别字并且有强迫症的人
37 | * 一些组件添加了点击交互效果
38 | * 本地小说搜索页替换了新的获取文件的方法,不再调用原生方法,但还有某些问题,想要使用原生方法的可以使用同文件夹下的副本页面
39 | ## 2.9.4(2021-04-06)
40 | * 1、新增一个在线音乐接口
41 | * 2、修复和优化问题若干
42 | ## 2.9.3(2021-03-23)
43 | * 1、新增音乐播放界面
44 | * 2、新增歌词显示功能
45 | * 3、新增全局歌词显示功能
46 | * 4、修改了播放列表样式
47 | * ps(需要注意此次更新修改了音乐数据的格式,所以打包apk安装之前,请将原本保存的歌曲先清空掉,避免出现bug)
48 | ## 2.9.0(2021-03-18)
49 | * 1、新增2个获取在线漫画的来源
50 | * 2、新增获取在线音乐的接口
51 | * 3、设置页面新增控制在线音乐和在线漫画来源的按钮
52 | * 4、修复若干bug
53 | ## 2.8.4(2021-02-27)
54 | * 1、修复一些显示bug
55 | * 2、优化漫画图片尺寸问题
56 | * 3、优化一些漫画阅读细节问题
57 | ## 2.8.2(2021-02-21)
58 | * 1、修改漫画阅读页图片尺寸不对的问题
59 | * 2、修复获取在线漫画内容开头闪屏的问题
60 | * 3、修复在线漫画搜索页搜索框清空内容会触发搜索事件的问题
61 | * 4、修复在线漫画会出现已读完的问题
62 | ## 2.8.0(2021-02-20)
63 | * 1、新增一个添加在线漫画的接口
64 | * 2、新增一个漫画详情页面
65 | * 3、新增一个获取漫画详情信息的接口
66 | * 4、新增一个html页面用于获取漫画内容
67 | ## 2.7.5(2021-01-05)
68 | * 1、优化翻页方式切换逻辑
69 | * 2、将弹出确认框做成全局方法,并优化样式
70 | * 3、将弹出选择框做成全局方法,并优化样式
71 | ## 2.7.0(2020-12-26)
72 | * 1、小说阅读方式新增 【伪·仿真翻页】【覆盖翻页】(ps: 因为只能横向翻页,所以叫伪·仿真翻页)
73 | * 2、修复首页书籍之间间隔不一样的问题
74 | * 3、修复音乐列表名称过长没有隐藏的问题
75 | * 4、优化路由跳转代码,将路由跳转的代码写在公共方法中
76 | ## 2.6.1(2020-11-24)
77 | * 优化长列表,减少白屏时间
78 | * 不知道是不是错觉,总感觉优化后变卡了,哪位测试过麻烦告诉我一下
79 | ## 2.6.0(2020-11-23)
80 | * 新增文件分享功能,可以在添加小说,音乐,漫画页面分享文件
81 | * ps(只支持单文件分享)
82 | ## 2.5.1(2020-11-20)
83 | * 优化音乐控件的触摸事件,解决点击和拖动的冲突
84 | ## 2.5.0(2020-11-19)
85 | * 新增音乐播放功能,只支持应用内播放
86 | ## 2.1.0(2020-11-16)
87 | * 1、修改原生方法,新增生成缩略图的方法,现在读取漫画列表时,会在每本漫画一级文件夹下生成一张叫做 “000_preview.jpg” 的图片,是由漫画第一张图片压缩成的,这样做是为了减少手机内存负担
88 | * 2、新增获取扩展内存卡的方法,但不适配所有手机
89 | ## 2.0.5(2020-11-13)
90 | * 1、新增读取漫画内容和漫画列表的原生方法,提升了读取漫画内容的速度
91 | * 2、修复了添加小说页面直接阅读小说,进度显示NaN的bug
92 | * 3、删除了漫画阅读页面夜间模式下亮度会降低的设置
93 | * 4、修复了旋转屏幕后,图片高度异常的bug
94 | ## 2.0.0(2020-11-12)
95 | * 1、新增阅读本地漫画的功能
96 | * ps: 漫画资源结构有2种,分别为:
97 | - 1、漫画文件夹 => 漫画图片
98 | - 2、漫画文件夹 => 章节文件夹 => 漫画图片;
99 | - 3、如果漫画文件夹下同时存在图片和文件夹,以文件夹优先,会忽略图片。
100 | * 2、更改了关于页面内容
101 | * 3、更改了原生方法,如果要打包的朋友,注意替换原生方法
102 | * 4、与读取小说内容一样,读取漫画内容也分调试用的方法和正式打包使用的方法,都是注释好了的,根据情况选择使用
103 | ## 1.2.5(2020-11-02)
104 | * 1、优化了列表组件和导航栏组件的代码,去除了不必要的传参
105 | * 2、修复了阅读页文本有时右边会超出一部分的bug
106 | * 3、修改了首页书籍列表展示布局
107 | * 4、修复了阅读页拖动进度条到100%时,无法点击回上一页的bug
108 | ## 1.2.0(2020-10-21)
109 | * 1、新增滑动阅读功能分为上下滑动和左右滑动同时保留点击翻页
110 | * 2、开放设置界面,用于设置阅读方式和动画时间
111 | * 3、此版本几乎重构了整个阅读页,如果要打包安装的朋友请将原本的版本数据清空
112 | ## 1.1.0(2020-10-12)
113 | * 1、将阅读页面设置窗口改为原生子窗体,现在设置窗口的滑入和滑出动画更加流畅
114 | * 2、修复访问文件夹时滚动条位置不变的bug
115 | * 3、修复进度条拖动bug
116 | ## 1.0.2(2020-10-09)
117 | * 1、修复了首页和本地文件页面,不能搜索的bug
118 | * 2、本地文件页面也能直接读取txt文件内容
119 | * 3、稍微优化了下自定义列表组件的代码
120 | * 4、除了原生的弹框,其余自定义组件的弹窗都适配了夜间模式
121 | * 5、优化了删除提示,删除单个文件时,会提示文件名称,避免删错文件
122 | ## 1.0.0(2020-09-29)
123 | * 主要功能:
124 | * 1、首页显示本地导入的小说列表(显示信息包括(阅读进度、导入时间,小说名称))
125 | * 2、可拖曳的抽屉菜单(效果不是很好)
126 | * 3、搜索本地txt文件列表
127 | * 4、导入本地txt文档
128 | * 5、删除txt文件
129 | * 6、小说左右分页阅读(只有左右分页且没有动画效果)
130 | * 7、可以跳转进度阅读小说
131 | * 8、查看小说章节,如果小说的章节格式符合规格的话
132 | * 9、保存书签,显示书签列表
133 |
--------------------------------------------------------------------------------
/common/mixin/app.js:
--------------------------------------------------------------------------------
1 | import { mapGetters, mapMutations } from 'vuex'
2 | const appMixin = {
3 | computed: {
4 | ...mapGetters({
5 | getAdult: 'app/getAdult',
6 | getAdultPwd: 'app/getAdultPwd'
7 | })
8 | },
9 | methods: {
10 | ...mapMutations({
11 | setAdult: 'app/setAdult',
12 | setAdultPwd: 'app/setAdultPwd'
13 | })
14 | }
15 | }
16 |
17 | export default appMixin;
--------------------------------------------------------------------------------
/common/mixin/book.js:
--------------------------------------------------------------------------------
1 | import { mapGetters, mapMutations } from 'vuex'
2 | const bookMixin = {
3 | computed: {
4 | ...mapGetters({
5 | bookList: 'book/bookList',
6 | bookmarks: 'book/bookmarks',
7 | bookPathHistory: 'book/bookPathHistory',
8 | bookReadMode: 'book/bookReadMode',
9 | getBookSourcesController: 'book/getBookSourcesController',
10 | comicPathHistory: 'book/comicPathHistory',
11 | comicOrienMode: 'book/comicOrienMode',
12 | getComicSourcesController: 'book/getComicSourcesController',
13 | })
14 | },
15 | methods: {
16 | ...mapMutations({
17 | addBooks: 'book/addBooks',
18 | deleteBook: 'book/deleteBook',
19 | clearBooks: 'book/clearBooks',
20 | updateBookInfo: 'book/updateBookInfo',
21 | updateBookPath: 'book/updateBookPath',
22 | changeBookFontSize: 'book/changeBookFontSize',
23 | changeBookReadPageType: 'book/changeBookReadPageType',
24 | changeBookReadLineHeight: 'book/changeBookReadLineHeight',
25 | changeBookLight: 'book/changeBookLight',
26 | saveBookmark: 'book/saveBookmark',
27 | clearBookmark: 'book/clearBookmark',
28 | setBookSourcesController: 'book/setBookSourcesController',
29 | setComicSourcesController: 'book/setComicSourcesController',
30 | updateComicPath: 'book/updateComicPath',
31 | clearComicPath: 'book/clearComicPath',
32 | changeComicOrien: 'book/changeComicOrien',
33 | setComicSourcesController: 'book/setComicSourcesController'
34 | })
35 | }
36 | }
37 |
38 | export default bookMixin;
--------------------------------------------------------------------------------
/common/mixin/bookcertify.js:
--------------------------------------------------------------------------------
1 | import { mapGetters, mapMutations } from 'vuex'
2 | const bookcertifyMixin = {
3 | computed: {
4 | ...mapGetters({
5 | bookInfo: 'bookcertify/getBookInfo',
6 | bookChapters: 'bookcertify/getBookChapters',
7 | pageInfo: 'bookcertify/getBookPageInfo'
8 | })
9 | },
10 | methods: {
11 | ...mapMutations({
12 | setBookInfo: 'bookcertify/setBookInfo',
13 | setBookChapters: 'bookcertify/setBookChapters',
14 | setBookPageInfo: 'bookcertify/setBookPageInfo'
15 | })
16 | }
17 | }
18 |
19 | export default bookcertifyMixin;
--------------------------------------------------------------------------------
/common/mixin/cache.js:
--------------------------------------------------------------------------------
1 | import { mapGetters, mapMutations } from 'vuex'
2 | const cacheMixin = {
3 | computed: {
4 | ...mapGetters({
5 | imageCache: 'cache/getImageCache'
6 | })
7 | },
8 | methods: {
9 | ...mapMutations({
10 | addImageCache: 'cache/addImageCache',
11 | removeImageCache: 'cache/removeImageCache',
12 | clearImageCache: 'cache/clearImageCache'
13 | })
14 | }
15 | }
16 |
17 | export default cacheMixin;
--------------------------------------------------------------------------------
/common/mixin/index.js:
--------------------------------------------------------------------------------
1 | import { mapGetters, mapMutations } from 'vuex'
2 | export const skinMixin = {
3 | computed: {
4 | ...mapGetters({
5 | skinMode: 'skin/skinMode',
6 | skinColor: 'skin/skinColor'
7 | })
8 | },
9 | methods: {
10 | ...mapMutations({
11 | changeSkin: 'skin/changeSkin',
12 | })
13 | }
14 | }
15 |
16 | //菜单拖曳显示
17 | export const menuTouchMixin = {
18 | data () {
19 | return {
20 | pointX: 0,
21 | touchTime: 0,
22 | menuLate: 0,
23 | menuOpac: 0,
24 | //控制列表是否滚动
25 | scrollable: true
26 | }
27 | },
28 | methods: {
29 | touchstart (e) {
30 | if ( e.touches.length > 1 ) {
31 | return;
32 | }
33 | const touch = e.touches[0];
34 | this.pointX = touch.pageX;
35 | this.scrollable = false;
36 | this.$refs.leftMenu.open();
37 | this.timer = setInterval(() => {
38 | this.touchTime += 0.1;
39 | }, 100)
40 | },
41 | touchmove (e) {
42 | if ( this.touchTime < 0.3 ) {
43 | return;
44 | }
45 | const touch = e.touches[0];
46 | this.menuLate = this.$refs.leftMenu.mulriple * (touch.pageX - this.pointX);
47 | this.menuOpac = this.menuLate / Math.abs(this.$refs.leftMenu.anima.late) * this.$refs.leftMenu.anima.opac;
48 | },
49 | touchend (e) {
50 | if ( this.timer ) {
51 | clearInterval(this.timer);
52 | }
53 | if ( this.$refs.leftMenu.popuplate >= -240 || (this.touchTime <= 0.3 && this.$refs.leftMenu.popuplate > -540) ) {
54 | this.$refs.leftMenu.show();
55 | } else {
56 | this.$refs.leftMenu.hide();
57 | setTimeout(() => {
58 | this.menuLate = -30;
59 | }, this.$refs.leftMenu.anima.duration)
60 | }
61 | this.$nextTick(() => {
62 | this.pointX = 0;
63 | this.touchTime = 0;
64 | this.scrollable = true;
65 | })
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/common/mixin/lyric.js:
--------------------------------------------------------------------------------
1 | import musicMixin from '@/common/mixin/music.js'
2 | import musiccertifyMixin from '@/common/mixin/musiccertify.js'
3 | const lyricMixin = {
4 | mixins: [musicMixin, musiccertifyMixin],
5 | computed: {
6 | //播放记录
7 | playRecord () {
8 | return this.getMusicPlayRecord;
9 | },
10 | //已播放时长
11 | playTime () {
12 | return this.getMusicPlayTime;
13 | },
14 | playLyric () {
15 | return this.getMusicLyric;
16 | },
17 | //是否显示歌词
18 | lyricShow () {
19 | return this.getMusicLyricShow;
20 | },
21 | //当前歌词字符串
22 | lyricNowTitle () {
23 | return this.playLyric.length > 0 && this.lyricNowIndex > -1 ? this.playLyric[this.lyricNowIndex].title : this.musicInfo ? this.musicInfo.name : '暂无歌曲';
24 | },
25 | //当前歌词位置索引
26 | lyricNowIndex () {
27 | let len = this.playLyric.length;
28 | let nowLyricTime = 0;
29 | let prevLyricTime = 0;
30 | let nextLyricTime = 0;
31 | for ( let i = 0; i < len; i++ ) {
32 | nowLyricTime = this.playLyric[i].time;
33 | switch(i) {
34 | case 0:
35 | nextLyricTime = this.playLyric[i + 1].time;
36 | if ( this.playTime < nextLyricTime && this.playTime >= nowLyricTime ) return i;
37 | break;
38 | case this.playLyric.length - 1:
39 | prevLyricTime = this.playLyric[i - 1].time;
40 | if ( this.playTime > prevLyricTime && this.playTime >= nowLyricTime ) return i;
41 | break;
42 | default:
43 | prevLyricTime = this.playLyric[i - 1].time;
44 | nextLyricTime = this.playLyric[i + 1].time;
45 | if ( this.playTime > prevLyricTime && this.playTime < nextLyricTime && this.playTime >= nowLyricTime ) return i;
46 | }
47 | }
48 | return -1;
49 | }
50 | }
51 | }
52 | export default lyricMixin;
--------------------------------------------------------------------------------
/common/mixin/music.js:
--------------------------------------------------------------------------------
1 | import { mapGetters, mapMutations } from 'vuex'
2 | const musicMixin = {
3 | computed: {
4 | ...mapGetters({
5 | playList: 'music/playList',
6 | musicPathHistory: 'music/musicPathHistory',
7 | getMusicPlayMode: 'music/getMusicPlayMode',
8 | getMusicPlayRecord: 'music/getMusicPlayRecord',
9 | getMusicLyricShow: 'music/getMusicLyricShow',
10 | getMusicSourcesController: 'music/getMusicSourcesController'
11 | })
12 | },
13 | methods: {
14 | ...mapMutations({
15 | addMusic: 'music/addMusic',
16 | deleteMusic: 'music/deleteMusic',
17 | clearMusic: 'music/clearMusic',
18 | updateMusicPlayRecord: 'music/updateMusicPlayRecord',
19 | changeMusicPlayMode: 'music/changeMusicPlayMode',
20 | setMusicLyricShow: 'music/setMusicLyricShow',
21 | updateMusicPath: 'music/updateMusicPath',
22 | setMusicSourcesController: 'music/setMusicSourcesController'
23 | })
24 | }
25 | }
26 |
27 | export default musicMixin;
--------------------------------------------------------------------------------
/common/mixin/musiccertify.js:
--------------------------------------------------------------------------------
1 | import { mapGetters, mapMutations } from 'vuex'
2 | const musiccertifyMixin = {
3 | computed: {
4 | ...mapGetters({
5 | musicInfo: 'musiccertify/getMusicInfo',
6 | getMusicPlayStatus: 'musiccertify/getMusicPlayStatus',
7 | getMusicPlayTime: 'musiccertify/getMusicPlayTime',
8 | getMusicPlayDuration: 'musiccertify/getMusicPlayDuration',
9 | getMusicLyric: 'musiccertify/getMusicLyric'
10 | })
11 | },
12 | methods: {
13 | ...mapMutations({
14 | setMusicInfo: 'musiccertify/setMusicInfo',
15 | setMusicPlayStatus: 'musiccertify/setMusicPlayStatus',
16 | setMusicPlayTime: 'musiccertify/setMusicPlayTime',
17 | setMusicPlayDuration: 'musiccertify/setMusicPlayDuration',
18 | setMusicLyric: 'musiccertify/setMusicLyric'
19 | })
20 | }
21 | }
22 |
23 | export default musiccertifyMixin;
--------------------------------------------------------------------------------
/components/bubble-item/bubble-item.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{title}}
4 |
5 |
6 |
7 |
24 |
25 |
36 |
--------------------------------------------------------------------------------
/components/bubble/bubble.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
91 |
92 |
124 |
--------------------------------------------------------------------------------
/components/c-button/c-button.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{title}}
6 |
7 |
8 |
9 |
68 |
69 |
103 |
--------------------------------------------------------------------------------
/components/c-switch/c-switch.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{trueText}}
5 | {{falseText}}
6 |
7 |
8 |
9 |
69 |
70 |
99 |
--------------------------------------------------------------------------------
/components/comic-image/comic-image.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
87 |
88 |
98 |
--------------------------------------------------------------------------------
/components/crosswise/crosswise.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
52 |
53 |
62 |
--------------------------------------------------------------------------------
/components/fixed-button/fixed-button.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
70 |
71 |
84 |
--------------------------------------------------------------------------------
/components/gap-bar/gap-bar.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
28 |
31 |
--------------------------------------------------------------------------------
/components/list-scroll/list-scroll.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | |
16 |
17 |
18 | |
19 |
20 |
21 | |
22 |
23 |
24 |
25 |
26 |
27 |
176 |
177 |
186 |
--------------------------------------------------------------------------------
/components/loading/loading.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
54 |
55 |
58 |
--------------------------------------------------------------------------------
/components/music-lyric/music-lyric.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
59 |
60 |
62 |
--------------------------------------------------------------------------------
/components/nav-bar/nav-bar.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {{title}}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
78 |
79 |
135 |
--------------------------------------------------------------------------------
/components/no-data/no-data.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{title}}
5 |
6 |
7 |
8 |
22 |
23 |
42 |
--------------------------------------------------------------------------------
/components/search/search.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 搜索
13 |
14 |
15 |
16 |
58 |
59 |
90 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 | import store from './store'//引入vuex
4 | import '@/plugins'
5 | import '@/assets/js'
6 |
7 | Vue.config.productionTip = false
8 |
9 | App.mpType = 'app'
10 |
11 | const app = new Vue({
12 | ...App,
13 | store
14 | })
15 | app.$mount()
16 |
--------------------------------------------------------------------------------
/modules/actionSheet.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
20 |
21 |
22 |
110 |
111 |
153 |
--------------------------------------------------------------------------------
/modules/confirm.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
21 |
22 |
23 |
24 |
108 |
109 |
179 |
--------------------------------------------------------------------------------
/modules/edit.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
21 |
135 |
136 |
189 |
--------------------------------------------------------------------------------
/nativeplugins/YingBingNativePlugin/android/uniplugin_yingbing-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/nativeplugins/YingBingNativePlugin/android/uniplugin_yingbing-release.aar
--------------------------------------------------------------------------------
/nativeplugins/YingBingNativePlugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "YingBingNativePlugin",
3 | "id": "YingBingNativePlugin",
4 | "version": "1.0",
5 | "description": "个人原生插件集合(获取txt文件内容,处理防盗链图片)",
6 | "_dp_type":"nativeplugin",
7 | "_dp_nativeplugin":{
8 | "android": {
9 | "plugins": [
10 | {
11 | "type": "module",
12 | "name": "YingBingNativePlugin-Reader",
13 | "class": "com.yingbing.nativeplugin.Reader"
14 | },
15 | {
16 | "type": "module",
17 | "name": "YingBingNativePlugin-BaseImage",
18 | "class": "com.yingbing.nativeplugin.BaseImage"
19 | }
20 | ],
21 | "hooksClass": "",
22 | "integrateType": "aar",
23 | "dependencies": [
24 | ],
25 | "compileOptions": {
26 | "sourceCompatibility": "1.8",
27 | "targetCompatibility": "1.8"
28 | },
29 | "abis": [
30 | "armeabi-v7a",
31 | "x86"
32 | ],
33 | "minSdkVersion": "22",
34 | "permissions": [
35 | ],
36 | "parameters": {
37 | "android_appid": {
38 | "des": "请填写appid",
39 | "key": "TM123456",
40 | "placeholder": ""
41 | }
42 | }
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "haoyong-reader",
3 | "displayName": "小说和漫画阅读器(好用阅读器)",
4 | "version": "2.9.8.5",
5 | "description": "能阅读小说和漫画, 还能播放音乐的阅读器",
6 | "keywords": [
7 | "小说",
8 | "漫画",
9 | "阅读",
10 | "翻页",
11 | "音乐"
12 | ],
13 | "repository": "https://github.com/yingbing-developer/uni-reader.git",
14 | "engines": {
15 | "HBuilderX": "^3.1.0"
16 | },
17 | "dcloudext": {
18 | "category": [
19 | "前端页面模板",
20 | "uni-app前端项目模板"
21 | ],
22 | "sale": {
23 | "regular": {
24 | "price": "0.00"
25 | },
26 | "sourcecode": {
27 | "price": "0.00"
28 | }
29 | },
30 | "contact": {
31 | "qq": "1014295211"
32 | },
33 | "declaration": {
34 | "ads": "无",
35 | "data": "无",
36 | "permissions": "系统存储权限"
37 | },
38 | "npmurl": ""
39 | },
40 | "uni_modules": {
41 | "dependencies": [],
42 | "encrypt": [],
43 | "platforms": {
44 | "cloud": {
45 | "tcb": "y",
46 | "aliyun": "y"
47 | },
48 | "client": {
49 | "App": {
50 | "app-vue": "y",
51 | "app-nvue": "y"
52 | },
53 | "H5-mobile": {
54 | "Safari": "n",
55 | "Android Browser": "n",
56 | "微信浏览器(Android)": "n",
57 | "QQ浏览器(Android)": "n"
58 | },
59 | "H5-pc": {
60 | "Chrome": "n",
61 | "IE": "n",
62 | "Edge": "n",
63 | "Firefox": "n",
64 | "Safari": "n"
65 | },
66 | "小程序": {
67 | "微信": "n",
68 | "阿里": "n",
69 | "百度": "n",
70 | "字节跳动": "n",
71 | "QQ": "n"
72 | },
73 | "快应用": {
74 | "华为": "n",
75 | "联盟": "n"
76 | },
77 | "Vue": {
78 | "vue2": "y",
79 | "vue3": "n"
80 | }
81 | }
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/pages.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
3 | {
4 | "path": "pages/index/index"
5 | },
6 | //本地小说添加页
7 | {
8 | "path": "pages/book/search/index"
9 | },
10 | //在线小说添加页
11 | {
12 | "path": "pages/book/online/index"
13 | },
14 | //小说详情页
15 | {
16 | "path": "pages/book/detail/index"
17 | },
18 | //小说阅读页
19 | {
20 | "path": "pages/book/read/index",
21 | "style": {
22 | "disableScroll": false,
23 | "app-plus": {
24 | "bounce":"none"
25 | }
26 | }
27 | },
28 | //小说设置页
29 | {
30 | "path": "pages/book/setting/index",
31 | "style": {
32 | "backgroundColor": "transparent",
33 | "app-plus": {
34 | "bounce":"none",
35 | "animationType": "fade-in",
36 | "background": "transparent", // 背景透明
37 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明
38 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
39 | }
40 | }
41 | },
42 | //本地漫画添加页
43 | {
44 | "path": "pages/comic/search/index"
45 | },
46 | //在线漫画添加页
47 | {
48 | "path": "pages/comic/online/index"
49 | },
50 | //漫画详情页
51 | {
52 | "path": "pages/comic/detail/index"
53 | },
54 | //漫画阅读页
55 | {
56 | "path": "pages/comic/read/index"
57 | },
58 | //设置页
59 | {
60 | "path": "pages/setting/index"
61 | },
62 | //关于软件
63 | {
64 | "path": "pages/about/index"
65 | },
66 | //音乐播放页面
67 | {
68 | "path": "pages/music/player",
69 | "style": {
70 | "backgroundColor": "transparent"
71 | }
72 | },
73 | //音乐播放列表
74 | {
75 | "path": "pages/music/index",
76 | "style": {
77 | "backgroundColor": "transparent",
78 | "app-plus": {
79 | "bounce":"none",
80 | "animationType": "fade-in",
81 | "background": "transparent", // 背景透明
82 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明
83 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
84 | }
85 | }
86 | },
87 | //添加音乐
88 | {
89 | "path": "pages/music/search"
90 | },
91 | //添加在线音乐
92 | {
93 | "path": "pages/music/online"
94 | },
95 | //确认弹窗
96 | {
97 | "path": "modules/confirm",
98 | "style": {
99 | "backgroundColor": "transparent",
100 | "app-plus": {
101 | "bounce":"none",
102 | "animationType": "fade-in",
103 | "background": "transparent", // 背景透明
104 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明
105 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
106 | }
107 | }
108 | },
109 | //选择对话框
110 | {
111 | "path": "modules/actionSheet",
112 | "style": {
113 | "backgroundColor": "transparent",
114 | "app-plus": {
115 | "bounce":"none",
116 | "animationType": "fade-in",
117 | "background": "transparent", // 背景透明
118 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明
119 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
120 | }
121 | }
122 | },
123 | //文本编辑框
124 | {
125 | "path": "modules/edit",
126 | "style": {
127 | "backgroundColor": "transparent",
128 | "app-plus": {
129 | "bounce":"none",
130 | "animationType": "fade-in",
131 | "background": "transparent", // 背景透明
132 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明
133 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
134 | }
135 | }
136 | },
137 | //章节书签展示页
138 | {
139 | "path": "modules/catalog",
140 | "style": {
141 | "backgroundColor": "transparent",
142 | "app-plus": {
143 | "bounce":"none",
144 | "animationType": "fade-in",
145 | "background": "transparent", // 背景透明
146 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明
147 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
148 | }
149 | }
150 | },
151 | //安全密码
152 | {
153 | "path": "modules/security",
154 | "style": {
155 | "backgroundColor": "transparent",
156 | "app-plus": {
157 | "bounce":"none",
158 | "animationType": "fade-in",
159 | "background": "transparent", // 背景透明
160 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明
161 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
162 | }
163 | }
164 | }
165 | ],
166 | "globalStyle": {
167 | "disableScroll": true, // 不嵌套 scroller
168 | "navigationStyle": "custom",
169 | "navigationBarTextStyle": "white",
170 | "navigationBarBackgroundColor": "transparent",
171 | "app-plus": {
172 | "titleNView": false
173 | }
174 | },
175 | "condition" : { //模式配置,仅开发期间生效
176 | "current": 0, //当前激活的模式(list 的索引项)
177 | "list": [
178 | {
179 | "name": "", //模式名称
180 | "path": "", //启动页面,必选
181 | "query": "" //启动参数,在页面的onLoad函数里面得到
182 | }
183 | ]
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/pages/about/index.nvue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 好用阅读器
6 | yingbing
7 | 版本:V{{version}}
8 |
9 |
10 |
11 |
12 | {{item.title}}
13 | {{item.link}}
14 |
15 | |
16 |
17 |
18 |
19 |
20 |
48 |
49 |
78 |
--------------------------------------------------------------------------------
/plugins/dom/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | //选择对话框
3 | actionSheet (list, current = -1) {
4 | return new Promise((resolve, reject) => {
5 | uni.navigateTo({
6 | url: `/modules/actionSheet?list=${encodeURIComponent(JSON.stringify(list))}¤t=${current}`,
7 | complete: (res) => {
8 | setTimeout(() => {
9 | uni.$on('actionSheet-btn', (data) => {
10 | resolve(data)
11 | uni.navigateBack({delta: 1})
12 | uni.$off('actionSheet-btn');
13 | })
14 | }, 60)
15 | }
16 | });
17 | })
18 | },
19 | //确认对话框
20 | confirm (title = '', message = '') {
21 | return new Promise((resolve, reject) => {
22 | uni.navigateTo({
23 | url: `/modules/confirm?title=${title}&message=${encodeURIComponent(message)}`,
24 | complete: (res) => {
25 | setTimeout(() => {
26 | uni.$on('message-btn', (data) => {
27 | resolve(data.flag)
28 | uni.navigateBack({delta: 1})
29 | uni.$off('message-btn');
30 | })
31 | }, 60)
32 | }
33 | });
34 | })
35 | },
36 | catalog (type) {
37 | return new Promise((resolve, reject) => {
38 | uni.navigateTo({
39 | url: `/modules/catalog?type=${type}`,
40 | complete: (res) => {
41 | uni.$on('catalog-btn', (data) => {
42 | resolve(data)
43 | uni.navigateBack({delta: 1});
44 | uni.$off('catalog-btn');
45 | })
46 | }
47 | });
48 | })
49 | },
50 | security (data = {}) {
51 | const type = data.type || 'input'
52 | const title = data.title || '请输入安全密码'
53 | return new Promise((resolve, reject) => {
54 | uni.navigateTo({
55 | url: `/modules/security?type=${type}&title=${title}`,
56 | complete: (res) => {
57 | uni.$on('security-btn', (data) => {
58 | resolve(data)
59 | uni.navigateBack({delta: 1});
60 | uni.$off('security-btn');
61 | })
62 | }
63 | });
64 | })
65 | }
66 | }
--------------------------------------------------------------------------------
/plugins/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import { Route } from '@/plugins/router/router.js';
3 | import Router from '@/plugins/router';
4 | import Http from '@/plugins/request'
5 | import Xhr from '@/plugins/xhr'
6 | import Dom from '@/plugins/dom'
7 | Vue.prototype.$http = Http;
8 | Vue.prototype.$xhr = Xhr;
9 | Vue.prototype.$dom = Dom;
10 | Vue.prototype.$Router = Router;
11 | Vue.prototype.$Route = new Route();
--------------------------------------------------------------------------------
/plugins/request/index.js:
--------------------------------------------------------------------------------
1 | import Http from './request.js'
2 | const http = new Http();
3 | export default http;
--------------------------------------------------------------------------------
/plugins/request/request.js:
--------------------------------------------------------------------------------
1 | import Config from '@/assets/js/config.js'
2 | const { TIMEOUT } = Config
3 |
4 |
5 | //request封装
6 | function request (type = 'GET', url, options) {
7 | return new Promise((resolve,reject) => {
8 | uni.request({
9 | url: url,
10 | data: options.params || {},
11 | method: type || 'GET',
12 | header: options.headers || {},
13 | responseType: options.responseType || 'text',
14 | timeout: TIMEOUT,
15 | sslVerify: false,
16 | success: ((res) => {
17 | resolve(res)
18 | }),
19 | fail:((err)=>{
20 | plus.nativeUI.toast("网络错误!", {verticalAlign: 'bottom'});
21 | reject(err);
22 | })
23 | })
24 | })
25 | }
26 |
27 | export default class http {
28 | get(url, options = {}) {
29 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径
30 | return request('GET', url, options)
31 | }
32 | postget(url, options = {}) {
33 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径
34 | return request('POST', url, options)
35 | }
36 | post(url, options = {}) {
37 | return request('POST', url, options)
38 | }
39 | }
40 |
41 | function param(data, charset) {
42 | let url = ''
43 | for (var k in data) {
44 | let value = data[k] !== undefined ? data[k] : ''
45 | url += charset == 'utf-8' ? `&${k}=${encodeURIComponent(value)}` : `&${k}=${value}`
46 | }
47 | return url ? url.substring(1) : ''
48 | }
--------------------------------------------------------------------------------
/plugins/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Router from './router.js';
3 |
4 | const guard = new Router();
5 | /**
6 | * 路由前置守卫
7 | */
8 | guard.beforeEach((to, from, next) => {
9 | next();
10 | });
11 |
12 |
13 | /**
14 | * 路由后置守卫
15 | */
16 | guard.afterEach((to, from) => {
17 | });
18 |
19 |
20 | /**
21 | * 报错钩子
22 | */
23 | guard.onError((errMsg) => {
24 | console.log('my route-guards error: ' + errMsg);
25 | });
26 | export default guard;
--------------------------------------------------------------------------------
/plugins/xhr/index.js:
--------------------------------------------------------------------------------
1 | import Xhr from './xhr.js'
2 | const xhr = new Xhr();
3 | export default xhr;
--------------------------------------------------------------------------------
/plugins/xhr/xhr.js:
--------------------------------------------------------------------------------
1 | import Config from '@/assets/js/config.js'
2 | const { TIMEOUT } = Config
3 |
4 | //xhr封装
5 | function xhrRequest (type = 'GET', url, options) {
6 | let xhrHttp = new plus.net.XMLHttpRequest();
7 | return new Promise((resolve,reject) => {
8 | xhrHttp.onreadystatechange = function () {
9 | console.log(xhrHttp.readyState);
10 | if ( xhrHttp.readyState == 4 ) {
11 | if ( xhrHttp.status == 200 ) {
12 | resolve({code: xhrHttp.status, data: xhrHttp.responseText})
13 | } else {
14 | plus.nativeUI.toast("网络错误!", {verticalAlign: 'bottom'});
15 | reject({code: xhrHttp.status, data: ''});
16 | }
17 | }
18 | }
19 | xhrHttp.open(type, url);
20 | if ( options.mimeType ) {
21 | xhrHttp.overrideMimeType(options.mimeType);
22 | }
23 | xhrHttp.responseType = options.responseType || 'json';
24 | for ( let i in options.headers || {} ) {
25 | xhrHttp.setRequestHeader(i, options.headers[i]);
26 | }
27 | xhrHttp.timeout = TIMEOUT;
28 | xhrHttp.send(options.params || {});
29 | })
30 | }
31 |
32 | export default class Xhr {
33 | get(url, options = {}) {
34 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径
35 | return xhrRequest('GET', url, options)
36 | }
37 | postget(url, options = {}) {
38 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径
39 | return xhrRequest('POST', url, options)
40 | }
41 | post(url, options = {}) {
42 | return xhrRequest('POST', url, options)
43 | }
44 | }
45 |
46 | function param(data, charset) {
47 | let url = ''
48 | for (var k in data) {
49 | let value = data[k] !== undefined ? data[k] : ''
50 | url += charset == 'utf-8' ? `&${k}=${encodeURIComponent(value)}` : `&${k}=${value}`
51 | }
52 | return url ? url.substring(1) : ''
53 | }
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | #使用须知
2 |
3 | * 1、这个项目只支持android app端,因为没有会IOS的同事,且没有苹果手机
4 | * 2、请注意压缩包中有个android文件夹,里面放的是原生插件,具体是做什么用的,方法里面已经写好了
5 | * 3、请注意压缩包中的原生插件,只是普通的java文件,不是打包好的插件,只能用离线打包的方式使用,需要下载官方的离线SDK包,使用方法见这个帖子:[uniapp直接调用安卓自定义方法](https://ask.dcloud.net.cn/article/36065)
6 | * 4、现在将获取本地小说文本内容的原生方法封装成了插件,同时获取文件列表的方法也使用native.js方法获取,如果你不需要阅读本地漫画,就可以直接云打包
7 | * 5、如果只是想体验下的朋友,可以直接运行使用,项目中有为了调试而写的方法,只是性能不如原生插件,只能调试用,根据情况选择就行,方法都是注释好了的(调试用方法已经没有了,现在读取本地小说内容只有原生方法了)
8 | * 6、小说翻页方式包括(左右滑动,上下滑动,点击翻页, 伪·仿真翻页,覆盖翻页);漫画翻页方式只有上下滚动
9 | * 7、以nvue的list组件为基础写了个列表滚动组件,做了虚拟列表优化,不过效果不是很好, 白屏时间较长
10 | * 8、首页的拖曳菜单,效果不是很好,有些bug,能力有限,只能写成这样,期望有大佬能告知更好的实现方法
11 | * 9、如果想要使用原生方法调试也可以本地制作自定义基座,以自定义基座的方式来运行,本地制作自定义基座的方法与本地打包的方法类似,具体见这里:[uni本地打包android自定义基座](https://www.cnblogs.com/fdxjava/articles/13354591.html)
12 | * 10、获取扩展TF卡路径的方法只有原生,如果不需要可以删掉
13 | * 11、音乐播放只支持应用内播放,不支持后台播放(经过测试某些手机后台也能继续播放)
14 | * 12、在线小说、漫画和音乐的接口仅供学习使用,请不要拿来做商业活动,也请不要随意攻击别人的网站,因此而造成的后果,请自己承担
15 | * 13、在线小说和漫画有个接口部分网络访问有问题,我家里的电信宽带可以访问,但手机的移动网络无法访问
16 | * 14、如果有什么问题都可以说
--------------------------------------------------------------------------------
/static/cover/cover_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/cover/cover_1.png
--------------------------------------------------------------------------------
/static/cover/cover_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/cover/cover_2.png
--------------------------------------------------------------------------------
/static/cover/cover_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/cover/cover_3.png
--------------------------------------------------------------------------------
/static/cover/cover_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/cover/cover_4.png
--------------------------------------------------------------------------------
/static/cover/cover_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/cover/cover_5.png
--------------------------------------------------------------------------------
/static/cover/cover_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/cover/cover_6.png
--------------------------------------------------------------------------------
/static/cover/cover_default.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/cover/cover_default.jpg
--------------------------------------------------------------------------------
/static/menuBack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/menuBack.png
--------------------------------------------------------------------------------
/static/music/border-default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/border-default.png
--------------------------------------------------------------------------------
/static/music/border-night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/border-night.png
--------------------------------------------------------------------------------
/static/music/loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/loop.png
--------------------------------------------------------------------------------
/static/music/music-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/music-bg.jpg
--------------------------------------------------------------------------------
/static/music/music-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/music-icon.png
--------------------------------------------------------------------------------
/static/music/music-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/music-list.png
--------------------------------------------------------------------------------
/static/music/music-type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/music-type.png
--------------------------------------------------------------------------------
/static/music/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/next.png
--------------------------------------------------------------------------------
/static/music/once.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/once.png
--------------------------------------------------------------------------------
/static/music/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/pause.png
--------------------------------------------------------------------------------
/static/music/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/play.png
--------------------------------------------------------------------------------
/static/music/prev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/prev.png
--------------------------------------------------------------------------------
/static/music/random.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/music/random.png
--------------------------------------------------------------------------------
/static/no-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yingbing-developer/uni-reader/1b767e77869a344d01401fa41175a70facde4d89/static/no-data.png
--------------------------------------------------------------------------------
/store/config.js:
--------------------------------------------------------------------------------
1 | export const SKIN = 'UNI_READER_SKIN'//皮肤
2 | export const ADULT = 'UNI_READER_ADULT'//青壮年模式
3 | export const ADULTPWD = 'UNI_READER_ADULT_PWD'//青壮年模式密码
4 | export const BOOKS = 'UNI_READER_BOOK_LIST'//书籍列表
5 | export const BOOKPATH = 'UNI_READER_BOOK_PATH'//上次访问小说存放路径
6 | export const BOOKREAD = 'UNI_READER_BOOK_READ'//小说阅读模式
7 | export const BOOKMARK = 'UNI_READER_BOOK_MARK'//小说书签列表
8 | export const COMICPATH = 'UNI_READER_COMIC_PATH'//上次访问漫画存放路径
9 | export const COMICORIEN = 'UNI_READER_COMIC_ORIEN'//漫画阅读方向
10 | export const MUSICPATH = 'UNI_READER_MUSIC_PATH'//上次访问的本地音乐资源路径
11 | export const PLAYLIST = 'UNI_READER_MUSIC_PLAY_LIST'//音乐播放列表
12 | export const PLAYSTATUS = 'UNI_READER_MUSIC_PLAY_STATUS'//音乐播放状态
13 | export const PLAYMODE = 'UNI_READER_MUSIC_PLAY_MODE'//音乐播放模式
14 | export const PLAYRECORD = 'UNI_READER_MUSIC_PLAY_RECORD'//音乐播放记录
15 | export const COMICSOURCES = 'UNI_READER_ONLINE_COMIC_SOURCES'//在线漫画来源控制,放进来的表示关闭获取此来源的漫画
16 | export const MUSICSOURCES = 'UNI_READER_ONLINE_MUSIC_SOURCES'//在线音乐来源控制,放进来的表示关闭获取此来源的音乐
17 | export const BOOKSOURCES = 'UNI_READER_ONLINE_BOOK_SOURCES'//在线小说来源控制,放进来的表示关闭获取此来源的漫画
18 | export const MUSICLYRICSHOW = 'UNI_READER_ONLINE_MUSIC_LYRIC_SHOW'//控制歌词显示
19 | export const IMAGECACHE = 'UNI_READER_IMAGE_CACHE'//图片缓存
--------------------------------------------------------------------------------
/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import book from './modules/book.js'
4 | import bookcertify from './modules/bookcertify.js'
5 | import music from './modules/music.js'
6 | import musiccertify from './modules/musiccertify.js'
7 | import skin from './modules/skin.js'
8 | import app from './modules/app.js'
9 | import cache from './modules/cache.js'
10 | Vue.use(Vuex)
11 | const store = new Vuex.Store({
12 | modules: {
13 | book,
14 | bookcertify,
15 | music,
16 | musiccertify,
17 | skin,
18 | app,
19 | cache
20 | }
21 | })
22 | export default store
--------------------------------------------------------------------------------
/store/modules/app.js:
--------------------------------------------------------------------------------
1 | import { ADULT, ADULTPWD } from '../config.js'
2 |
3 | const state = {
4 | adult: uni.getStorageSync(ADULT) || false, //青壮年模式
5 | adultPwd: uni.getStorageSync(ADULTPWD) || '' //青壮年模式密码
6 | }
7 |
8 | const getters = {
9 | getAdult (state) {
10 | return state.adult
11 | },
12 | getAdultPwd (state) {
13 | return state.adultPwd
14 | }
15 | }
16 |
17 | const mutations = {
18 | setAdult (state, bol) {
19 | state.adult = bol;
20 | uni.setStorageSync(ADULT, bol)
21 | },
22 | setAdultPwd (state, pwd) {
23 | state.adultPwd = pwd;
24 | uni.setStorageSync(ADULTPWD, pwd)
25 | }
26 | }
27 |
28 | export default {
29 | namespaced: true,
30 | state,
31 | getters,
32 | mutations
33 | }
--------------------------------------------------------------------------------
/store/modules/bookcertify.js:
--------------------------------------------------------------------------------
1 | //书籍临时阅读数据
2 | import Utils from '@/assets/js/util.js';
3 | const { indexOf, suffix, dateFormat, removeSuffix, randomString } = Utils;
4 | const state = {
5 | bookInfo: '',//当前阅读书籍信息
6 | bookChapters: [],//当前阅读书籍章节列表
7 | bookPageInfo: ''//当前阅读页面信息
8 | }
9 |
10 | const getters = {
11 | getBookInfo (state) {
12 | return state.bookInfo;
13 | },
14 | getBookChapters (state) {
15 | return state.bookChapters;
16 | },
17 | getBookPageInfo (state) {
18 | return state.bookPageInfo;
19 | }
20 | }
21 |
22 | const mutations = {
23 | setBookInfo (state, bookInfo) {
24 | state.bookInfo = bookInfo
25 | },
26 | setBookChapters (state, chapters) {
27 | state.bookChapters = chapters
28 | },
29 | setBookPageInfo (state, pageInfo) {
30 | state.bookPageInfo = JSON.parse(JSON.stringify(pageInfo))
31 | }
32 | }
33 |
34 | export default {
35 | namespaced: true,
36 | state,
37 | getters,
38 | mutations
39 | }
--------------------------------------------------------------------------------
/store/modules/cache.js:
--------------------------------------------------------------------------------
1 | import { IMAGECACHE } from '../config.js'
2 |
3 | const state = {
4 | imageCache: uni.getStorageSync(IMAGECACHE) || [] //图片临时文件存放
5 | }
6 |
7 | const getters = {
8 | getImageCache (state) {
9 | return state.imageCache
10 | }
11 | }
12 |
13 | const mutations = {
14 | addImageCache (state, obj) {
15 | state.imageCache.push(obj);
16 | uni.setStorageSync(IMAGECACHE, state.imageCache)
17 | },
18 | removeImageCache (state, key) {
19 | const index = state.imageCache.findIndex(item => item.key == key)
20 | if ( index > -1 ) state.imageCache.splice(index, 1);
21 | uni.setStorageSync(IMAGECACHE, state.imageCache)
22 | },
23 | clearImageCache (state) {
24 | uni.removeStorageSync(IMAGECACHE)
25 | }
26 | }
27 |
28 | export default {
29 | namespaced: true,
30 | state,
31 | getters,
32 | mutations
33 | }
--------------------------------------------------------------------------------
/store/modules/music.js:
--------------------------------------------------------------------------------
1 | import Utils from '@/assets/js/util.js';
2 | const { indexOf, suffix, dateFormat, removeSuffix, randomString } = Utils;
3 |
4 | import {
5 | MUSICPATH,
6 | PLAYLIST,
7 | PLAYMODE,
8 | PLAYRECORD,
9 | MUSICSOURCES,
10 | MUSICLYRICSHOW } from '../config.js'
11 |
12 | const state = {
13 | musicPath: uni.getStorageSync(MUSICPATH) || '', //默认访问的本地音乐资源路径
14 | musicPlayList: uni.getStorageSync(PLAYLIST) || [], //音乐播放列表
15 | musicPlayMode: uni.getStorageSync(PLAYMODE) || 'loop', //音乐播放模式 loop => 循环播放 once => 单曲循环 random => 乱序播放
16 | musicPlayRecord: uni.getStorageSync(PLAYRECORD) || '', //音乐播放记录
17 | musicLyricShow: uni.getStorageSync(MUSICLYRICSHOW) || false, //控制歌词显示
18 | musicSourcesController: uni.getStorageSync(MUSICSOURCES) || [] //在线音乐来源控制,放进来的表示关闭获取此来源的音乐
19 | }
20 |
21 | const getters = {
22 | musicPathHistory (state) {
23 | return state.musicPath
24 | },
25 | playList (state) {
26 | return state.musicPlayList
27 | },
28 | getMusicPlayMode (state) {
29 | return state.musicPlayMode
30 | },
31 | getMusicPlayRecord (state) {
32 | return state.musicPlayRecord
33 | },
34 | getMusicSourcesController (state) {
35 | return state.musicSourcesController
36 | },
37 | getMusicLyricShow (state) {
38 | return state.musicLyricShow
39 | }
40 | }
41 |
42 | const mutations = {
43 | //新增歌曲
44 | addMusic (state, music) {
45 | for ( let i in music ) {
46 | state.musicPlayList.push({
47 | name: removeSuffix(music[i].name),
48 | image: music[i].image ? music[i].image : '/static/music/music-bg.jpg',
49 | singer: music[i].singer || '未知歌手' ,
50 | path: music[i].path,
51 | lyric: music[i].lyric || false,
52 | source: music[i].source ? music[i].source : 'local'
53 | })
54 | }
55 | uni.setStorageSync(PLAYLIST, state.musicPlayList);
56 | },
57 | //删除指定歌曲
58 | deleteMusic (state, path) {
59 | let flag = indexOf(state.musicPlayList, 'path', path);
60 | if ( flag > -1 ) {
61 | state.musicPlayList.splice(flag, 1);
62 | uni.setStorageSync(PLAYLIST, state.musicPlayList)
63 | }
64 | },
65 | //清空所有歌曲
66 | clearMusic (state, type) {
67 | state.musicPlayList = [];
68 | uni.setStorageSync(PLAYLIST, state.musicPlayList);
69 | state.musicPlayRecord = '';
70 | uni.setStorageSync(PLAYRECORD, state.musicPlayRecord);
71 | state.musicPlayTime = 0;
72 | state.musicPlayDuration = 0;
73 | },
74 | //更新音乐播放记录
75 | updateMusicPlayRecord (state, record) {
76 | state.musicPlayRecord = record;
77 | uni.setStorageSync(PLAYRECORD, state.musicPlayRecord);
78 | },
79 | //改变音乐播放模式
80 | changeMusicPlayMode (state, mode) {
81 | state.musicPlayMode = mode;
82 | uni.setStorageSync(PLAYMODE, state.musicPlayMode);
83 | },
84 | //更新本地音乐上次访问文件夹位置
85 | updateMusicPath (state, path) {
86 | state.musicPath = path;
87 | uni.setStorageSync(MUSICPATH, state.musicPath);
88 | },
89 | //设置歌词是否展示
90 | setMusicLyricShow (state, bool) {
91 | state.musicLyricShow = bool;
92 | uni.setStorageSync(MUSICLYRICSHOW, state.musicLyricShow);
93 | },
94 | //设置在线音乐来源
95 | setMusicSourcesController (state, sources) {
96 | state.musicSourcesController = sources;
97 | uni.setStorageSync(MUSICSOURCES, state.musicSourcesController);
98 | }
99 | }
100 |
101 | export default {
102 | namespaced: true,
103 | state,
104 | getters,
105 | mutations
106 | }
--------------------------------------------------------------------------------
/store/modules/musiccertify.js:
--------------------------------------------------------------------------------
1 | //音乐播放临时阅读数据
2 | import Utils from '@/assets/js/util.js';
3 | const { indexOf, suffix, dateFormat, removeSuffix, randomString } = Utils;
4 | const state = {
5 | musicInfo: '',//当前播放音乐信息
6 | musicPlayStatus: false,//音乐播放状态
7 | musicPlayTime: 0,//当前音乐播放位置
8 | musicPlayDuration: 0,//当前音乐总时长
9 | musicLyric: [],//当前音乐歌词
10 | }
11 |
12 | const getters = {
13 | getMusicInfo (state) {
14 | return state.musicInfo;
15 | },
16 | getMusicPlayStatus (state) {
17 | return state.musicPlayStatus
18 | },
19 | getMusicPlayTime (state) {
20 | return state.musicPlayTime
21 | },
22 | getMusicPlayDuration (state) {
23 | return state.musicPlayDuration
24 | },
25 | getMusicLyric (state) {
26 | return state.musicLyric
27 | }
28 | }
29 |
30 | const mutations = {
31 | setMusicInfo (state, musicInfo) {
32 | state.musicInfo = musicInfo
33 | },
34 | //设置音乐播放状态
35 | setMusicPlayStatus (state, status) {
36 | state.musicPlayStatus = status;
37 | },
38 | //设置音乐播放时长
39 | setMusicPlayTime (state, time) {
40 | state.musicPlayTime = time;
41 | },
42 | //设置音乐总时长
43 | setMusicPlayDuration (state, duration) {
44 | state.musicPlayDuration = duration;
45 | },
46 | //设置音乐歌词
47 | setMusicLyric (state, lyric) {
48 | state.musicLyric = lyric;
49 | },
50 | }
51 |
52 | export default {
53 | namespaced: true,
54 | state,
55 | getters,
56 | mutations
57 | }
--------------------------------------------------------------------------------
/store/modules/skin.js:
--------------------------------------------------------------------------------
1 | import { SKIN } from '../config.js'
2 |
3 | const state = {
4 | skin: uni.getStorageSync(SKIN) || 'default' //皮肤
5 | }
6 |
7 | const getters = {
8 | //当前皮肤模式
9 | skinMode (state) {
10 | return state.skin
11 | },
12 | skinColor (state) {
13 | // 默认皮肤
14 | if ( state.skin == 'default' ) {
15 | return {
16 | bgColor: '#FAFAFA',
17 | titleColor: '#333333',
18 | textColor: '#666666',
19 | itemColor: '#1776D3',
20 | navColor: '#2196F5',
21 | iconColor: '#FFFFFF',
22 | gapColor: '#E0E0E0',
23 | menuBgColor: '#FAFAFA',
24 | menuIconColor: '#737373',
25 | menuTitleColor: '#727272',
26 | menuActiveColor: '#2397EE',
27 | menuActiveBgColor: '#DDDDDD',
28 | imgMask: 0,
29 | readBackColor: '#BFAD8A',
30 | readTextColor: '#2E2B23',
31 | activeBgColor: '#2397EE',
32 | activeColor: '#FAFAFA',
33 | activedName: 'actived'
34 | }
35 | } else if ( state.skin == 'night' ) {// 夜间模式
36 | return {
37 | bgColor: '#2C2C2C',
38 | titleColor: '#8F8F8F',
39 | textColor: '#5E5E5E',
40 | itemColor: '#3D3D3D',
41 | navColor: '#3C3C3C',
42 | iconColor: '#777777',
43 | gapColor: '#3F3F3F',
44 | menuBgColor: '#373737',
45 | menuIconColor: '#777777',
46 | menuTitleColor: '#8F8F8F',
47 | menuActiveColor: '#FAFAFA',
48 | menuActiveBgColor: '#3F3F3F',
49 | imgMask: 0.3,
50 | readBackColor: '#393E41',
51 | readTextColor: '#95A3A6',
52 | activeBgColor: '#3F3F3F',
53 | activeColor: '#777777',
54 | activedName: 'actived-dark'
55 | }
56 | }
57 | }
58 | }
59 |
60 | const mutations = {
61 | //改变皮肤模式
62 | changeSkin (state, skin) {
63 | state.skin = skin;
64 | uni.setStorageSync(SKIN, skin)
65 | }
66 | }
67 |
68 | export default {
69 | namespaced: true,
70 | state,
71 | getters,
72 | mutations
73 | }
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/changelog.md:
--------------------------------------------------------------------------------
1 | ## 1.2.4(2021-10-18)
2 | * 修复滚动模式定位问题
3 | ## 1.2.3(2021-10-17)
4 | * 添加点击区域配置,具体见下面得介绍
5 | ## 1.2.2(2021-10-17)
6 | * 优化滚动模式
7 | ## 1.2.1(2021-10-15)
8 | * 优化滚动模式逻辑
9 | ## 1.2.0(2021-10-15)
10 | * 修复滚动模式下得问题
11 | ## 1.1.9(2021-10-15)
12 | * 修复一些显示问题
13 | * 优化了一下滚动模式滚动效果
14 | ## 1.1.8(2021-10-14)
15 | * content对象中可以带上章节名称,方便取值
16 | * 增加初始化loading效果
17 | ## 1.1.7(2021-10-14)
18 | * 增加整书模式返回得页面信息
19 | ## 1.1.6(2021-10-14)
20 | * 更改整书模式返回章节集合得参数
21 | ## 1.1.5(2021-10-14)
22 | * 优化翻页得性能,同时最多显示3张页面
23 | ## 1.1.4(2021-10-13)
24 | 修复一些问题
25 | ## 1.1.3(2021-10-13)
26 | * 修复一些问题
27 | ## 1.1.2(2021-10-13)
28 | * 修复一些问题
29 | ## 1.1.1(2021-10-13)
30 | * 修复了一些问题
31 | ## 1.1.0(2021-10-12)
32 | * 此次更新为重构插件
33 | * 首先感谢一下2位插件使用者提供的反馈
34 | * 主要更新如下:
35 | - 1、为请求事件增加了过渡效果,滚动模式下增加上拉和下拉操作
36 | - 2、解决了一些逻辑问题,现在preload和loadmore事件触发更合理
37 | - 3、其它都是些小更新,比如章节模式下currentChange事件增加了返回的页面信息
38 | - 4、更改了参数结构,请注意阅读使用须知
39 | ## 1.0.5(2021-09-22)
40 | * 修复上次更新引起无法翻到上一页的问题
41 | ## 1.0.4(2021-09-22)
42 | * 修复横向翻页部分页面不绘制的bug
43 | ## 1.0.3(2021-09-05)
44 | * 修复整书模式下阅读小说到最后面,下一页会从小说最前面再次排版的bug
45 | ## 1.0.2(2021-09-04)
46 | * 修复预加载章节内容无效的问题
47 | * 添加初始化触发currentChange事件
48 | ## 1.0.1(2021-08-29)
49 | * 减少滚动模式下触底加载更多时的滚动距离
50 | ## 1.0.0(2021-08-28)
51 | * 发布1.0.0版本
52 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/components/page-refresh/page-refresh.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
27 |
28 |
52 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 HuangYi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/README.md:
--------------------------------------------------------------------------------
1 | # @better-scroll/core
2 |
3 | [中文文档](https://github.com/ustbhuangyi/better-scroll/blob/master/packages/core/README_zh-CN.md)
4 |
5 | core scroll from BetterScroll.
6 |
7 | ## Usage
8 |
9 | ```js
10 | import BScroll from '@better-scroll/core'
11 |
12 | const bs = new BScroll('.wrapper', {/* ... */})
13 | ```
14 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/README_zh-CN.md:
--------------------------------------------------------------------------------
1 | # @better-scroll/core
2 |
3 | 核心滚动,实现基础的列表滚动效果。
4 |
5 | ## 使用
6 |
7 | ```js
8 | import BScroll from '@better-scroll/core'
9 |
10 | const bs = new BScroll('.wrapper', {/* ... */})
11 | ```
12 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/BScroll.d.ts:
--------------------------------------------------------------------------------
1 | import { BScrollInstance } from './Instance';
2 | import { Options, DefOptions, OptionsConstructor } from './Options';
3 | import Scroller from './scroller/Scroller';
4 | import { ApplyOrder, EventEmitter } from '@better-scroll/shared-utils';
5 | import { UnionToIntersection } from './utils/typesHelper';
6 | interface PluginCtor {
7 | pluginName: string;
8 | applyOrder?: ApplyOrder;
9 | new (scroll: BScroll): any;
10 | }
11 | interface PluginItem {
12 | name: string;
13 | applyOrder?: ApplyOrder.Pre | ApplyOrder.Post;
14 | ctor: PluginCtor;
15 | }
16 | interface PluginsMap {
17 | [key: string]: boolean;
18 | }
19 | interface PropertyConfig {
20 | key: string;
21 | sourceKey: string;
22 | }
23 | declare type ElementParam = HTMLElement | string;
24 | export interface MountedBScrollHTMLElement extends HTMLElement {
25 | isBScrollContainer?: boolean;
26 | }
27 | export declare class BScrollConstructor extends EventEmitter {
28 | static plugins: PluginItem[];
29 | static pluginsMap: PluginsMap;
30 | scroller: Scroller;
31 | options: OptionsConstructor;
32 | hooks: EventEmitter;
33 | plugins: {
34 | [name: string]: any;
35 | };
36 | wrapper: HTMLElement;
37 | content: HTMLElement;
38 | [key: string]: any;
39 | static use(ctor: PluginCtor): typeof BScrollConstructor;
40 | constructor(el: ElementParam, options?: Options & O);
41 | setContent(wrapper: MountedBScrollHTMLElement): {
42 | valid: boolean;
43 | contentChanged: boolean;
44 | };
45 | private init;
46 | private applyPlugins;
47 | private handleAutoBlur;
48 | private eventBubbling;
49 | private refreshWithoutReset;
50 | proxy(propertiesConfig: PropertyConfig[]): void;
51 | refresh(): void;
52 | enable(): void;
53 | disable(): void;
54 | destroy(): void;
55 | eventRegister(names: string[]): void;
56 | }
57 | export interface BScrollConstructor extends BScrollInstance {
58 | }
59 | export interface CustomAPI {
60 | [key: string]: {};
61 | }
62 | declare type ExtractAPI = {
63 | [K in keyof O]: K extends string ? DefOptions[K] extends undefined ? CustomAPI[K] : never : never;
64 | }[keyof O];
65 | export declare function createBScroll(el: ElementParam, options?: Options & O): BScrollConstructor & UnionToIntersection>;
66 | export declare namespace createBScroll {
67 | var use: typeof BScrollConstructor.use;
68 | var plugins: PluginItem[];
69 | var pluginsMap: PluginsMap;
70 | }
71 | declare type createBScroll = typeof createBScroll;
72 | export interface BScrollFactory extends createBScroll {
73 | new (el: ElementParam, options?: Options & O): BScrollConstructor & UnionToIntersection>;
74 | }
75 | export declare type BScroll = BScrollConstructor & UnionToIntersection>;
76 | export declare const BScroll: BScrollFactory;
77 | export {};
78 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/Instance.d.ts:
--------------------------------------------------------------------------------
1 | import { Behavior } from './scroller/Behavior';
2 | import Actions from './scroller/Actions';
3 | import { ExposedAPI as ExposedAPIByScroller } from './scroller/Scroller';
4 | import { Animater } from './animater';
5 | import { ExposedAPI as ExposedAPIByAnimater } from './animater/Base';
6 | export interface BScrollInstance extends ExposedAPIByScroller, ExposedAPIByAnimater {
7 | [key: string]: any;
8 | x: Behavior['currentPos'];
9 | y: Behavior['currentPos'];
10 | hasHorizontalScroll: Behavior['hasScroll'];
11 | hasVerticalScroll: Behavior['hasScroll'];
12 | scrollerWidth: Behavior['contentSize'];
13 | scrollerHeight: Behavior['contentSize'];
14 | maxScrollX: Behavior['maxScrollPos'];
15 | maxScrollY: Behavior['maxScrollPos'];
16 | minScrollX: Behavior['minScrollPos'];
17 | minScrollY: Behavior['minScrollPos'];
18 | movingDirectionX: Behavior['movingDirection'];
19 | movingDirectionY: Behavior['movingDirection'];
20 | directionX: Behavior['direction'];
21 | directionY: Behavior['direction'];
22 | enabled: Actions['enabled'];
23 | pending: Animater['pending'];
24 | }
25 | export declare const propertiesConfig: {
26 | sourceKey: string;
27 | key: string;
28 | }[];
29 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/Options.d.ts:
--------------------------------------------------------------------------------
1 | import { Quadrant } from '@better-scroll/shared-utils';
2 | export declare type Tap = 'tap' | '';
3 | export declare type BounceOptions = Partial | boolean;
4 | export declare type DblclickOptions = Partial | boolean;
5 | export interface BounceConfig {
6 | top: boolean;
7 | bottom: boolean;
8 | left: boolean;
9 | right: boolean;
10 | }
11 | export interface DblclickConfig {
12 | delay: number;
13 | }
14 | export interface CustomOptions {
15 | }
16 | export interface DefOptions {
17 | [key: string]: any;
18 | startX?: number;
19 | startY?: number;
20 | scrollX?: boolean;
21 | scrollY?: boolean;
22 | freeScroll?: boolean;
23 | directionLockThreshold?: number;
24 | eventPassthrough?: string;
25 | click?: boolean;
26 | tap?: Tap;
27 | bounce?: BounceOptions;
28 | bounceTime?: number;
29 | momentum?: boolean;
30 | momentumLimitTime?: number;
31 | momentumLimitDistance?: number;
32 | swipeTime?: number;
33 | swipeBounceTime?: number;
34 | deceleration?: number;
35 | flickLimitTime?: number;
36 | flickLimitDistance?: number;
37 | resizePolling?: number;
38 | probeType?: number;
39 | stopPropagation?: boolean;
40 | preventDefault?: boolean;
41 | preventDefaultException?: {
42 | tagName?: RegExp;
43 | className?: RegExp;
44 | };
45 | tagException?: {
46 | tagName?: RegExp;
47 | className?: RegExp;
48 | };
49 | HWCompositing?: boolean;
50 | useTransition?: boolean;
51 | bindToWrapper?: boolean;
52 | bindToTarget?: boolean;
53 | disableMouse?: boolean;
54 | disableTouch?: boolean;
55 | autoBlur?: boolean;
56 | translateZ?: string;
57 | dblclick?: DblclickOptions;
58 | autoEndDistance?: number;
59 | outOfBoundaryDampingFactor?: number;
60 | specifiedIndexAsContent?: number;
61 | quadrant?: Quadrant;
62 | }
63 | export interface Options extends DefOptions, CustomOptions {
64 | }
65 | export declare class CustomOptions {
66 | }
67 | export declare class OptionsConstructor extends CustomOptions implements DefOptions {
68 | [key: string]: any;
69 | startX: number;
70 | startY: number;
71 | scrollX: boolean;
72 | scrollY: boolean;
73 | freeScroll: boolean;
74 | directionLockThreshold: number;
75 | eventPassthrough: string;
76 | click: boolean;
77 | tap: Tap;
78 | bounce: BounceConfig;
79 | bounceTime: number;
80 | momentum: boolean;
81 | momentumLimitTime: number;
82 | momentumLimitDistance: number;
83 | swipeTime: number;
84 | swipeBounceTime: number;
85 | deceleration: number;
86 | flickLimitTime: number;
87 | flickLimitDistance: number;
88 | resizePolling: number;
89 | probeType: number;
90 | stopPropagation: boolean;
91 | preventDefault: boolean;
92 | preventDefaultException: {
93 | tagName?: RegExp;
94 | className?: RegExp;
95 | };
96 | tagException: {
97 | tagName?: RegExp;
98 | className?: RegExp;
99 | };
100 | HWCompositing: boolean;
101 | useTransition: boolean;
102 | bindToWrapper: boolean;
103 | bindToTarget: boolean;
104 | disableMouse: boolean;
105 | disableTouch: boolean;
106 | autoBlur: boolean;
107 | translateZ: string;
108 | dblclick: DblclickOptions;
109 | autoEndDistance: number;
110 | outOfBoundaryDampingFactor: number;
111 | specifiedIndexAsContent: number;
112 | quadrant: Quadrant;
113 | constructor();
114 | merge(options?: Options): this;
115 | process(): this;
116 | resolveBounce(bounceOptions: BounceOptions): BounceConfig;
117 | }
118 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/Animation.d.ts:
--------------------------------------------------------------------------------
1 | import Base from './Base';
2 | import { TranslaterPoint } from '../translater';
3 | import { EaseFn } from '@better-scroll/shared-utils';
4 | export default class Animation extends Base {
5 | move(startPoint: TranslaterPoint, endPoint: TranslaterPoint, time: number, easingFn: EaseFn | string): void;
6 | private animate;
7 | doStop(): boolean;
8 | stop(): void;
9 | }
10 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/Base.d.ts:
--------------------------------------------------------------------------------
1 | import { EaseFn, safeCSSStyleDeclaration, EventEmitter } from '@better-scroll/shared-utils';
2 | import Translater, { TranslaterPoint } from '../translater';
3 | export interface ExposedAPI {
4 | stop(): void;
5 | }
6 | export default abstract class Base implements ExposedAPI {
7 | translater: Translater;
8 | options: {
9 | probeType: number;
10 | };
11 | content: HTMLElement;
12 | style: safeCSSStyleDeclaration;
13 | hooks: EventEmitter;
14 | timer: number;
15 | pending: boolean;
16 | callStopWhenPending: boolean;
17 | forceStopped: boolean;
18 | _reflow: number;
19 | [key: string]: any;
20 | constructor(content: HTMLElement, translater: Translater, options: {
21 | probeType: number;
22 | });
23 | translate(endPoint: TranslaterPoint): void;
24 | setPending(pending: boolean): void;
25 | setForceStopped(forceStopped: boolean): void;
26 | setCallStop(called: boolean): void;
27 | setContent(content: HTMLElement): void;
28 | clearTimer(): void;
29 | abstract move(startPoint: TranslaterPoint, endPoint: TranslaterPoint, time: number, easing: string | EaseFn): void;
30 | abstract doStop(): void;
31 | abstract stop(): void;
32 | destroy(): void;
33 | }
34 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/Transition.d.ts:
--------------------------------------------------------------------------------
1 | import { EaseFn } from '@better-scroll/shared-utils';
2 | import Base from './Base';
3 | import { TranslaterPoint } from '../translater';
4 | export default class Transition extends Base {
5 | startProbe(startPoint: TranslaterPoint, endPoint: TranslaterPoint): void;
6 | transitionTime(time?: number): void;
7 | transitionTimingFunction(easing: string): void;
8 | transitionProperty(): void;
9 | move(startPoint: TranslaterPoint, endPoint: TranslaterPoint, time: number, easingFn: string | EaseFn): void;
10 | doStop(): boolean;
11 | stop(): void;
12 | }
13 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/index.d.ts:
--------------------------------------------------------------------------------
1 | import Translater from '../translater';
2 | import { Options as BScrollOptions } from '../Options';
3 | import Animater from './Base';
4 | import Transition from './Transition';
5 | import Animation from './Animation';
6 | export { Animater, Transition, Animation };
7 | export default function createAnimater(element: HTMLElement, translater: Translater, options: BScrollOptions): Transition | Animation;
8 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/base/ActionsHandler.d.ts:
--------------------------------------------------------------------------------
1 | import { EventRegister, EventEmitter } from '@better-scroll/shared-utils';
2 | declare type Exception = {
3 | tagName?: RegExp;
4 | className?: RegExp;
5 | };
6 | export interface Options {
7 | [key: string]: boolean | number | Exception;
8 | click: boolean;
9 | bindToWrapper: boolean;
10 | disableMouse: boolean;
11 | disableTouch: boolean;
12 | preventDefault: boolean;
13 | stopPropagation: boolean;
14 | preventDefaultException: Exception;
15 | tagException: Exception;
16 | autoEndDistance: number;
17 | }
18 | export default class ActionsHandler {
19 | wrapper: HTMLElement;
20 | options: Options;
21 | hooks: EventEmitter;
22 | initiated: number;
23 | pointX: number;
24 | pointY: number;
25 | wrapperEventRegister: EventRegister;
26 | targetEventRegister: EventRegister;
27 | constructor(wrapper: HTMLElement, options: Options);
28 | private handleDOMEvents;
29 | private beforeHandler;
30 | setInitiated(type?: number): void;
31 | private start;
32 | private move;
33 | private end;
34 | private click;
35 | setContent(content: HTMLElement): void;
36 | rebindDOMEvents(): void;
37 | destroy(): void;
38 | }
39 | export {};
40 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { BScroll } from './BScroll';
2 | export { BScrollInstance } from './Instance';
3 | export { Options, CustomOptions } from './Options';
4 | export { TranslaterPoint } from './translater';
5 | export { MountedBScrollHTMLElement } from './BScroll';
6 | export { Behavior, Boundary } from './scroller/Behavior';
7 | export { createBScroll, CustomAPI } from './BScroll';
8 | export default BScroll;
9 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/Actions.d.ts:
--------------------------------------------------------------------------------
1 | import ActionsHandler from '../base/ActionsHandler';
2 | import { Behavior } from './Behavior';
3 | import DirectionLockAction from './DirectionLock';
4 | import { Animater } from '../animater';
5 | import { OptionsConstructor as BScrollOptions } from '../Options';
6 | import { TranslaterPoint } from '../translater';
7 | import { EventEmitter } from '@better-scroll/shared-utils';
8 | export default class ScrollerActions {
9 | hooks: EventEmitter;
10 | scrollBehaviorX: Behavior;
11 | scrollBehaviorY: Behavior;
12 | actionsHandler: ActionsHandler;
13 | animater: Animater;
14 | options: BScrollOptions;
15 | directionLockAction: DirectionLockAction;
16 | fingerMoved: boolean;
17 | contentMoved: boolean;
18 | enabled: boolean;
19 | startTime: number;
20 | endTime: number;
21 | ensuringInteger: boolean;
22 | constructor(scrollBehaviorX: Behavior, scrollBehaviorY: Behavior, actionsHandler: ActionsHandler, animater: Animater, options: BScrollOptions);
23 | private bindActionsHandler;
24 | private handleStart;
25 | private handleMove;
26 | private dispatchScroll;
27 | private checkMomentum;
28 | private handleEnd;
29 | private ensureIntegerPos;
30 | private handleClick;
31 | getCurrentPos(): TranslaterPoint;
32 | refresh(): void;
33 | destroy(): void;
34 | }
35 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/Behavior.d.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils';
2 | export declare type Bounces = [boolean, boolean];
3 | export declare type Rect = {
4 | size: string;
5 | position: string;
6 | };
7 | export interface Options {
8 | scrollable: boolean;
9 | momentum: boolean;
10 | momentumLimitTime: number;
11 | momentumLimitDistance: number;
12 | deceleration: number;
13 | swipeBounceTime: number;
14 | swipeTime: number;
15 | bounces: Bounces;
16 | rect: Rect;
17 | outOfBoundaryDampingFactor: number;
18 | specifiedIndexAsContent: number;
19 | [key: string]: number | boolean | Bounces | Rect;
20 | }
21 | export declare type Boundary = {
22 | minScrollPos: number;
23 | maxScrollPos: number;
24 | };
25 | export declare class Behavior {
26 | wrapper: HTMLElement;
27 | options: Options;
28 | content: HTMLElement;
29 | currentPos: number;
30 | startPos: number;
31 | absStartPos: number;
32 | dist: number;
33 | minScrollPos: number;
34 | maxScrollPos: number;
35 | hasScroll: boolean;
36 | direction: number;
37 | movingDirection: number;
38 | relativeOffset: number;
39 | wrapperSize: number;
40 | contentSize: number;
41 | hooks: EventEmitter;
42 | constructor(wrapper: HTMLElement, content: HTMLElement, options: Options);
43 | start(): void;
44 | move(delta: number): number;
45 | setMovingDirection(delta: number): void;
46 | setDirection(delta: number): void;
47 | performDampingAlgorithm(delta: number, dampingFactor: number): number;
48 | end(duration: number): {
49 | destination?: number | undefined;
50 | duration?: number | undefined;
51 | };
52 | private momentum;
53 | updateDirection(): void;
54 | refresh(content: HTMLElement): void;
55 | private setContent;
56 | private resetState;
57 | computeBoundary(): void;
58 | updatePosition(pos: number): void;
59 | getCurrentPos(): number;
60 | checkInBoundary(): {
61 | position: number;
62 | inBoundary: boolean;
63 | };
64 | adjustPosition(pos: number): number;
65 | updateStartPos(): void;
66 | updateAbsStartPos(): void;
67 | resetStartPos(): void;
68 | getAbsDist(delta: number): number;
69 | destroy(): void;
70 | }
71 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/DirectionLock.d.ts:
--------------------------------------------------------------------------------
1 | import { TouchEvent, DirectionLock } from '@better-scroll/shared-utils';
2 | export default class DirectionLockAction {
3 | directionLockThreshold: number;
4 | freeScroll: boolean;
5 | eventPassthrough: string;
6 | directionLocked: DirectionLock;
7 | constructor(directionLockThreshold: number, freeScroll: boolean, eventPassthrough: string);
8 | reset(): void;
9 | checkMovingDirection(absDistX: number, absDistY: number, e: TouchEvent): boolean;
10 | adjustDelta(deltaX: number, deltaY: number): {
11 | deltaX: number;
12 | deltaY: number;
13 | };
14 | private computeDirectionLock;
15 | private handleEventPassthrough;
16 | }
17 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/Scroller.d.ts:
--------------------------------------------------------------------------------
1 | import ActionsHandler from '../base/ActionsHandler';
2 | import Translater, { TranslaterPoint } from '../translater';
3 | import { Animater } from '../animater';
4 | import { OptionsConstructor as BScrollOptions } from '../Options';
5 | import { Behavior } from './Behavior';
6 | import ScrollerActions from './Actions';
7 | import { EaseItem, EventEmitter, EventRegister } from '@better-scroll/shared-utils';
8 | export interface ExposedAPI {
9 | scrollTo(x: number, y: number, time?: number, easing?: EaseItem, extraTransform?: {
10 | start: object;
11 | end: object;
12 | }): void;
13 | scrollBy(deltaX: number, deltaY: number, time?: number, easing?: EaseItem): void;
14 | scrollToElement(el: HTMLElement | string, time: number, offsetX: number | boolean, offsetY: number | boolean, easing?: EaseItem): void;
15 | resetPosition(time?: number, easing?: EaseItem): boolean;
16 | }
17 | export default class Scroller implements ExposedAPI {
18 | wrapper: HTMLElement;
19 | content: HTMLElement;
20 | actionsHandler: ActionsHandler;
21 | translater: Translater;
22 | animater: Animater;
23 | scrollBehaviorX: Behavior;
24 | scrollBehaviorY: Behavior;
25 | actions: ScrollerActions;
26 | hooks: EventEmitter;
27 | resizeRegister: EventRegister;
28 | transitionEndRegister: EventRegister;
29 | options: BScrollOptions;
30 | wrapperOffset: {
31 | left: number;
32 | top: number;
33 | };
34 | _reflow: number;
35 | resizeTimeout: number;
36 | lastClickTime: number | null;
37 | [key: string]: any;
38 | constructor(wrapper: HTMLElement, content: HTMLElement, options: BScrollOptions);
39 | private init;
40 | private registerTransitionEnd;
41 | private bindTranslater;
42 | private bindAnimater;
43 | private bindActions;
44 | private checkFlick;
45 | private momentum;
46 | private checkClick;
47 | private resize;
48 | private transitionEnd;
49 | togglePointerEvents(enabled?: boolean): void;
50 | refresh(content: HTMLElement): void;
51 | private setContent;
52 | scrollBy(deltaX: number, deltaY: number, time?: number, easing?: EaseItem): void;
53 | scrollTo(x: number, y: number, time?: number, easing?: EaseItem, extraTransform?: {
54 | start: {};
55 | end: {};
56 | }): void;
57 | scrollToElement(el: HTMLElement | string, time: number, offsetX: number | boolean, offsetY: number | boolean, easing?: EaseItem): void;
58 | resetPosition(time?: number, easing?: EaseItem): boolean;
59 | reflow(): void;
60 | updatePositions(pos: TranslaterPoint): void;
61 | getCurrentPos(): TranslaterPoint;
62 | enable(): void;
63 | disable(): void;
64 | destroy(this: Scroller): void;
65 | }
66 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/createOptions.d.ts:
--------------------------------------------------------------------------------
1 | import { Options as BScrollOptions } from '../Options';
2 | import { Options as ActionsHandlerOptions } from '../base/ActionsHandler';
3 | import { Options as BehaviorOptions, Bounces, Rect } from './Behavior';
4 | export declare function createActionsHandlerOptions(bsOptions: BScrollOptions): ActionsHandlerOptions;
5 | export declare function createBehaviorOptions(bsOptions: BScrollOptions, extraProp: 'scrollX' | 'scrollY', bounces: Bounces, rect: Rect): BehaviorOptions;
6 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/translater/index.d.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils';
2 | export interface TranslaterPoint {
3 | x: number;
4 | y: number;
5 | [key: string]: number;
6 | }
7 | export default class Translater {
8 | content: HTMLElement;
9 | style: CSSStyleDeclaration;
10 | hooks: EventEmitter;
11 | constructor(content: HTMLElement);
12 | getComputedPosition(): {
13 | x: number;
14 | y: number;
15 | };
16 | translate(point: TranslaterPoint): void;
17 | setContent(content: HTMLElement): void;
18 | destroy(): void;
19 | }
20 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/bubbling.d.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils';
2 | interface BubblingEventMap {
3 | source: string;
4 | target: string;
5 | }
6 | declare type BubblingEventConfig = BubblingEventMap | string;
7 | export declare function bubbling(source: EventEmitter, target: EventEmitter, events: BubblingEventConfig[]): void;
8 | export {};
9 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/compare.d.ts:
--------------------------------------------------------------------------------
1 | import { TranslaterPoint } from '../translater';
2 | export declare function isSamePoint(startPoint: TranslaterPoint, endPoint: TranslaterPoint): boolean;
3 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/compat.d.ts:
--------------------------------------------------------------------------------
1 | import { TranslaterPoint } from '../translater';
2 | declare type Position = {
3 | x: number;
4 | y: number;
5 | };
6 | export declare const isValidPostion: (startPoint: TranslaterPoint, endPoint: TranslaterPoint, currentPos: Position, prePos: Position) => boolean;
7 | export {};
8 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/typesHelper.d.ts:
--------------------------------------------------------------------------------
1 | export declare type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
2 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_from": "@better-scroll/core",
3 | "_id": "@better-scroll/core@2.4.2",
4 | "_inBundle": false,
5 | "_integrity": "sha512-IqVZLnh04YpaEAy9wJDxtFK/stxVQjB9A9Wcr3Uwkj7Av1TtFpin+t/TObl53diNDG5ZJ+vck/OAthphpuugLA==",
6 | "_location": "/@better-scroll/core",
7 | "_phantomChildren": {},
8 | "_requested": {
9 | "type": "tag",
10 | "registry": true,
11 | "raw": "@better-scroll/core",
12 | "name": "@better-scroll/core",
13 | "escapedName": "@better-scroll%2fcore",
14 | "scope": "@better-scroll",
15 | "rawSpec": "",
16 | "saveSpec": null,
17 | "fetchSpec": "latest"
18 | },
19 | "_requiredBy": [
20 | "#USER",
21 | "/"
22 | ],
23 | "_resolved": "https://registry.npmjs.org/@better-scroll/core/-/core-2.4.2.tgz",
24 | "_shasum": "e69470012d79923a18034c3e4931720fbb06eae5",
25 | "_spec": "@better-scroll/core",
26 | "_where": "G:\\my-project\\uni-readPage\\uni_modules\\yingbing-ReadPage",
27 | "author": {
28 | "name": "jizhi",
29 | "email": "theniceangel@163.com"
30 | },
31 | "bugs": {
32 | "url": "https://github.com/ustbhuangyi/better-scroll/issues"
33 | },
34 | "bundleDependencies": false,
35 | "dependencies": {
36 | "@better-scroll/shared-utils": "^2.4.2"
37 | },
38 | "deprecated": false,
39 | "description": "Minimalistic core scrolling for BetterScroll, it is pure and tiny",
40 | "gitHead": "c97e67ecf15e616d998e67aa4ce15a7c429691c3",
41 | "homepage": "https://github.com/ustbhuangyi/better-scroll",
42 | "keywords": [
43 | "scroll",
44 | "iscroll",
45 | "javascript",
46 | "typescript",
47 | "ios"
48 | ],
49 | "license": "MIT",
50 | "main": "dist/core.js",
51 | "module": "dist/core.esm.js",
52 | "name": "@better-scroll/core",
53 | "publishConfig": {
54 | "access": "public"
55 | },
56 | "repository": {
57 | "type": "git",
58 | "url": "git+ssh://git@github.com/ustbhuangyi/better-scroll.git",
59 | "directory": "packages/core"
60 | },
61 | "scripts": {},
62 | "typings": "dist/types/index.d.ts",
63 | "version": "2.4.2"
64 | }
65 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/Instance.ts:
--------------------------------------------------------------------------------
1 | import { Behavior } from './scroller/Behavior'
2 | import Actions from './scroller/Actions'
3 | import { ExposedAPI as ExposedAPIByScroller } from './scroller/Scroller'
4 | import { Animater } from './animater'
5 | import { ExposedAPI as ExposedAPIByAnimater } from './animater/Base'
6 |
7 | export interface BScrollInstance
8 | extends ExposedAPIByScroller,
9 | ExposedAPIByAnimater {
10 | [key: string]: any
11 | x: Behavior['currentPos']
12 | y: Behavior['currentPos']
13 | hasHorizontalScroll: Behavior['hasScroll']
14 | hasVerticalScroll: Behavior['hasScroll']
15 | scrollerWidth: Behavior['contentSize']
16 | scrollerHeight: Behavior['contentSize']
17 | maxScrollX: Behavior['maxScrollPos']
18 | maxScrollY: Behavior['maxScrollPos']
19 | minScrollX: Behavior['minScrollPos']
20 | minScrollY: Behavior['minScrollPos']
21 | movingDirectionX: Behavior['movingDirection']
22 | movingDirectionY: Behavior['movingDirection']
23 | directionX: Behavior['direction']
24 | directionY: Behavior['direction']
25 | enabled: Actions['enabled']
26 | pending: Animater['pending']
27 | }
28 |
29 | export const propertiesConfig = [
30 | {
31 | sourceKey: 'scroller.scrollBehaviorX.currentPos',
32 | key: 'x'
33 | },
34 | {
35 | sourceKey: 'scroller.scrollBehaviorY.currentPos',
36 | key: 'y'
37 | },
38 | {
39 | sourceKey: 'scroller.scrollBehaviorX.hasScroll',
40 | key: 'hasHorizontalScroll'
41 | },
42 | {
43 | sourceKey: 'scroller.scrollBehaviorY.hasScroll',
44 | key: 'hasVerticalScroll'
45 | },
46 | {
47 | sourceKey: 'scroller.scrollBehaviorX.contentSize',
48 | key: 'scrollerWidth'
49 | },
50 | {
51 | sourceKey: 'scroller.scrollBehaviorY.contentSize',
52 | key: 'scrollerHeight'
53 | },
54 | {
55 | sourceKey: 'scroller.scrollBehaviorX.maxScrollPos',
56 | key: 'maxScrollX'
57 | },
58 | {
59 | sourceKey: 'scroller.scrollBehaviorY.maxScrollPos',
60 | key: 'maxScrollY'
61 | },
62 | {
63 | sourceKey: 'scroller.scrollBehaviorX.minScrollPos',
64 | key: 'minScrollX'
65 | },
66 | {
67 | sourceKey: 'scroller.scrollBehaviorY.minScrollPos',
68 | key: 'minScrollY'
69 | },
70 | {
71 | sourceKey: 'scroller.scrollBehaviorX.movingDirection',
72 | key: 'movingDirectionX'
73 | },
74 | {
75 | sourceKey: 'scroller.scrollBehaviorY.movingDirection',
76 | key: 'movingDirectionY'
77 | },
78 | {
79 | sourceKey: 'scroller.scrollBehaviorX.direction',
80 | key: 'directionX'
81 | },
82 | {
83 | sourceKey: 'scroller.scrollBehaviorY.direction',
84 | key: 'directionY'
85 | },
86 | {
87 | sourceKey: 'scroller.actions.enabled',
88 | key: 'enabled'
89 | },
90 | {
91 | sourceKey: 'scroller.animater.pending',
92 | key: 'pending'
93 | },
94 | {
95 | sourceKey: 'scroller.animater.stop',
96 | key: 'stop'
97 | },
98 | {
99 | sourceKey: 'scroller.scrollTo',
100 | key: 'scrollTo'
101 | },
102 | {
103 | sourceKey: 'scroller.scrollBy',
104 | key: 'scrollBy'
105 | },
106 | {
107 | sourceKey: 'scroller.scrollToElement',
108 | key: 'scrollToElement'
109 | },
110 | {
111 | sourceKey: 'scroller.resetPosition',
112 | key: 'resetPosition'
113 | }
114 | ]
115 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__mocks__/Options.ts:
--------------------------------------------------------------------------------
1 | const mockOptions = jest.fn().mockImplementation(() => {
2 | return {
3 | startX: 0,
4 | startY: 0,
5 | scrollX: false,
6 | scrollY: true,
7 | freeScroll: false,
8 | directionLockThreshold: 0,
9 | eventPassthrough: '',
10 | click: false,
11 | tap: '',
12 | translateZ: ' translateZ(0)',
13 |
14 | bounce: {
15 | top: true,
16 | bottom: true,
17 | left: true,
18 | right: true,
19 | },
20 | bounceTime: 800,
21 |
22 | momentum: true,
23 | momentumLimitTime: 300,
24 | momentumLimitDistance: 15,
25 |
26 | swipeTime: 2500,
27 | swipeBounceTime: 500,
28 |
29 | deceleration: 0.0015,
30 |
31 | flickLimitTime: 200,
32 | flickLimitDistance: 100,
33 |
34 | resizePolling: 60,
35 | probeType: 0,
36 |
37 | stopPropagation: false,
38 | preventDefault: true,
39 | preventDefaultException: {
40 | tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|AUDIO)$/,
41 | },
42 |
43 | HWCompositing: true,
44 |
45 | useTransition: true,
46 | bindToWrapper: false,
47 | disableMouse: true,
48 | observeDOM: true,
49 | autoBlur: true,
50 | mouseWheel: false,
51 | infinity: false,
52 | specifiedIndexAsContent: 0,
53 | quadrant: 0,
54 | outOfBoundaryDampingFactor: 1 / 3,
55 | merge: jest.fn(),
56 | process: jest.fn(),
57 | }
58 | })
59 |
60 | export { mockOptions as OptionsConstructor }
61 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__mocks__/index.ts:
--------------------------------------------------------------------------------
1 | import Scroller from '../scroller/Scroller'
2 | import { OptionsConstructor } from '../Options'
3 | import { EventEmitter } from '@better-scroll/shared-utils'
4 |
5 | jest.mock('../scroller/Scroller')
6 | jest.mock('../Options')
7 |
8 | const BScroll = jest.fn().mockImplementation((wrapper, options) => {
9 | options = Object.assign(new OptionsConstructor(), options)
10 | const eventEmitter = new EventEmitter([
11 | // bscroll
12 | 'refresh',
13 | 'enable',
14 | 'disable',
15 | 'destroy',
16 | // scroller
17 | 'beforeScrollStart',
18 | 'scrollStart',
19 | 'scroll',
20 | 'scrollEnd',
21 | 'touchEnd',
22 | 'flick',
23 | 'alterOptions',
24 | 'mousewheelStart',
25 | 'mousewheelMove',
26 | 'mousewheelEnd',
27 | ])
28 | const res = {
29 | wrapper: wrapper,
30 | options: options,
31 | hooks: new EventEmitter([
32 | 'refresh',
33 | 'enable',
34 | 'disable',
35 | 'destroy',
36 | 'beforeInitialScrollTo',
37 | ]),
38 | scroller: new Scroller(wrapper, wrapper.children[0], options),
39 | // own methods
40 | proxy: jest.fn(),
41 | refresh: jest.fn(),
42 | // proxy methods
43 | scrollTo: jest.fn(),
44 | resetPosition: jest.fn(),
45 | registerType: jest.fn().mockImplementation((names: string[]) => {
46 | names.forEach((name) => {
47 | const eventTypes = eventEmitter.eventTypes
48 | eventTypes[name] = name
49 | })
50 | }),
51 | disable: jest.fn(),
52 | enable: jest.fn(),
53 | stop: jest.fn(),
54 | plugins: {},
55 | x: 0,
56 | y: 0,
57 | maxScrollY: 0,
58 | maxScrollX: 0,
59 | minScrollX: 0,
60 | minScrollY: 0,
61 | hasVerticalScroll: true,
62 | hasHorizontalScroll: false,
63 | enabled: true,
64 | pending: false,
65 | }
66 |
67 | Object.setPrototypeOf(res, eventEmitter)
68 | return res
69 | })
70 |
71 | export default BScroll
72 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__tests__/__utils__/event.ts:
--------------------------------------------------------------------------------
1 | export function createEvent(type: string, name: string): Event {
2 | const e = document.createEvent(type || 'Event')
3 | e.initEvent(name, true, true)
4 | return e
5 | }
6 |
7 | interface CustomClickEvent extends MouseEvent {
8 | pageX: number
9 | pageY: number
10 | }
11 |
12 | export function dispatchClick(target: EventTarget, name = 'click') {
13 | const event = createEvent('', name)
14 | event.pageX = 0
15 | event.pageY = 0
16 | target.dispatchEvent(event)
17 | }
18 |
19 | interface CustomTouch {
20 | pageX: number
21 | pageY: number
22 | }
23 | type CustomTouches = CustomTouch[] | CustomTouch
24 |
25 | export interface CustomTouchEvent extends Event {
26 | touches: CustomTouches
27 | targetTouches: CustomTouches
28 | changedTouches: CustomTouches
29 | }
30 |
31 | interface CustomMouseEvent extends Event {
32 | button: 0 | 1
33 | pageX: number
34 | pageY: number
35 | }
36 |
37 | export function dispatchTouch(
38 | target: EventTarget,
39 | name = 'touchstart',
40 | touches: CustomTouches
41 | ): void {
42 | const event = createEvent('', name)
43 | event.touches = event.targetTouches = event.changedTouches = touches
44 | target.dispatchEvent(event)
45 | }
46 |
47 | export function dispatchMouse(
48 | target: EventTarget,
49 | name = 'mousedown',
50 | useLeftButton = true
51 | ): void {
52 | const event = createEvent('', name)
53 | event.button = useLeftButton ? 0 : 1
54 | event.pageX = 0
55 | event.pageY = 0
56 | target.dispatchEvent(event)
57 | }
58 |
59 | export function dispatchTouchStart(
60 | target: EventTarget,
61 | touches: CustomTouches
62 | ): void {
63 | dispatchTouch(target, 'touchstart', touches)
64 | }
65 |
66 | export function dispatchTouchMove(
67 | target: EventTarget,
68 | touches: CustomTouches
69 | ): void {
70 | dispatchTouch(target, 'touchmove', touches)
71 | }
72 |
73 | export function dispatchTouchEnd(
74 | target: EventTarget,
75 | touches: CustomTouches
76 | ): void {
77 | dispatchTouch(target, 'touchend', touches)
78 | }
79 |
80 | export function dispatchTouchCancel(
81 | target: EventTarget,
82 | touches: CustomTouches
83 | ): void {
84 | dispatchTouch(target, 'touchcancel', touches)
85 | }
86 |
87 | export function dispatchSwipe(
88 | target: EventTarget,
89 | touches: CustomTouches,
90 | duration: number,
91 | cb: () => any
92 | ): void {
93 | // TODO 优化写法
94 | if (!Array.isArray(touches)) {
95 | touches = [touches]
96 | }
97 | if (touches instanceof Array) {
98 | dispatchTouchStart(target, touches[0])
99 | const moveAndEnd = () => {
100 | if (touches instanceof Array) {
101 | dispatchTouchMove(target, touches[1] || touches[0])
102 | dispatchTouchEnd(target, touches[2] || touches[1] || touches[0])
103 | }
104 | cb && cb()
105 | }
106 | if (duration) {
107 | setTimeout(moveAndEnd, duration)
108 | } else {
109 | moveAndEnd()
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__tests__/__utils__/layout.ts:
--------------------------------------------------------------------------------
1 | export interface CustomHTMLDivElement extends HTMLDivElement {
2 | clientWidth: number
3 | clientHeight: number
4 | offsetWidth: number
5 | offsetHeight: number
6 | offsetTop: number
7 | offsetLeft: number
8 | _jsdomMockClientWidth?: number
9 | _jsdomMockClientHeight?: number
10 | _jsdomMockOffsetWidth?: number
11 | _jsdomMockOffsetHeight?: number
12 | _jsdomMockOffsetTop?: number
13 | _jsdomMockOffsetLeft?: number
14 | [key: string]: any
15 | }
16 |
17 | function firstUpper(key: string) {
18 | return key.charAt(0).toUpperCase() + key.slice(1)
19 | }
20 |
21 | function genMockPrototype(mockName: string) {
22 | return {
23 | get: jest.fn().mockImplementation(dom => {
24 | return Number(dom.getAttribute(mockName))
25 | })
26 | }
27 | }
28 |
29 | function mockHTMLPrototype(propName: string, mockGetter: jest.Mock) {
30 | Object.defineProperty(HTMLElement.prototype, propName, {
31 | get: function() {
32 | return mockGetter(this)
33 | },
34 | configurable: true
35 | })
36 | }
37 |
38 | export function mockDomOffset(
39 | dom: CustomHTMLDivElement,
40 | offsetObj: {
41 | width?: number
42 | height?: number
43 | top?: number
44 | left?: number
45 | [key: string]: any
46 | }
47 | ) {
48 | Object.keys(offsetObj).forEach(key => {
49 | const mockName = `_jsdomMockOffset${firstUpper(key)}`
50 | dom.setAttribute(mockName, offsetObj[key])
51 | })
52 | }
53 |
54 | export function mockDomClient(
55 | dom: CustomHTMLDivElement,
56 | clientObj: {
57 | width?: number
58 | height?: number
59 | [key: string]: any
60 | }
61 | ) {
62 | Object.keys(clientObj).forEach(key => {
63 | const mockName = `_jsdomMockClient${firstUpper(key)}`
64 | dom.setAttribute(mockName, clientObj[key])
65 | })
66 | }
67 |
68 | export function createDiv(
69 | width: number = 0,
70 | height: number = 0,
71 | top: number = 0,
72 | left: number = 0
73 | ) {
74 | const dom = document.createElement('div') as CustomHTMLDivElement
75 | mockDomOffset(dom, {
76 | width,
77 | height,
78 | top,
79 | left
80 | })
81 | mockDomClient(dom, {
82 | width,
83 | height
84 | })
85 | return dom
86 | }
87 |
88 | export const mockClientWidth = genMockPrototype('_jsdomMockClientWidth')
89 | mockHTMLPrototype('clientWidth', mockClientWidth.get)
90 |
91 | export const mockClientHeight = genMockPrototype('_jsdomMockClientHeight')
92 | mockHTMLPrototype('clientHeight', mockClientHeight.get)
93 |
94 | export const mockOffsetWidth = genMockPrototype('_jsdomMockOffsetWidth')
95 | mockHTMLPrototype('offsetWidth', mockOffsetWidth.get)
96 |
97 | export const mockOffsetHeight = genMockPrototype('_jsdomMockOffsetHeight')
98 | mockHTMLPrototype('offsetHeight', mockOffsetHeight.get)
99 |
100 | export const mockOffsetTop = genMockPrototype('_jsdomMockOffsetTop')
101 | mockHTMLPrototype('offsetTop', mockOffsetTop.get)
102 |
103 | export const mockOffsetLeft = genMockPrototype('_jsdomMockOffsetLeft')
104 | mockHTMLPrototype('offsetLeft', mockOffsetLeft.get)
105 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__tests__/index.spec.ts:
--------------------------------------------------------------------------------
1 | import BScroll from '../index'
2 |
3 | describe('BetterScroll Core', () => {
4 | let bscroll: BScroll
5 | let wrapper = document.createElement('div')
6 | let content = document.createElement('p')
7 | wrapper.appendChild(content)
8 | beforeEach(() => {
9 | bscroll = new BScroll(wrapper, {})
10 | })
11 | afterEach(() => {
12 | BScroll.plugins = []
13 | BScroll.pluginsMap = {}
14 | })
15 |
16 | it('use()', () => {
17 | const plugin = class MyPlugin {
18 | static pluginName = 'myPlugin'
19 | }
20 | BScroll.use(plugin)
21 | // has installed
22 | BScroll.use(plugin)
23 |
24 | expect(BScroll.plugins.length).toBe(1)
25 |
26 | // Plugin should specify pluginName
27 | const spyFn = jest.spyOn(console, 'error')
28 | const unnamedPlugin = class UnnamedPlugin {}
29 | BScroll.use(unnamedPlugin as any)
30 | expect(spyFn).toBeCalled()
31 | spyFn.mockRestore()
32 | })
33 |
34 | it('should init plugins when set top-level of BScroll options', () => {
35 | let mockFn = jest.fn()
36 | const plugin = class MyPlugin {
37 | static pluginName = 'myPlugin2'
38 | constructor(bscroll: BScroll) {
39 | mockFn(bscroll)
40 | }
41 | }
42 | BScroll.use(plugin)
43 | let wrapper = document.createElement('div')
44 | wrapper.appendChild(document.createElement('p'))
45 |
46 | let bs = new BScroll(wrapper, {
47 | myPlugin2: true
48 | })
49 | expect(mockFn).toBeCalledWith(bs)
50 | })
51 |
52 | it('should throw error when wrapper is not a ElementNode or wrapper has no children ', () => {
53 | let spy = jest.spyOn(console, 'error')
54 | let bs = new BScroll('.div', {})
55 | let bs2 = new BScroll(document.createElement('div'), {})
56 |
57 | expect(spy).toHaveBeenCalled()
58 | expect(spy).toBeCalledTimes(2)
59 | })
60 |
61 | it('disable()', () => {
62 | const mockFn = jest.fn()
63 | bscroll.on(bscroll.eventTypes.disable, mockFn)
64 | bscroll.hooks.on(bscroll.hooks.eventTypes.disable, mockFn)
65 | bscroll.disable()
66 |
67 | expect(mockFn).toBeCalledTimes(2)
68 | })
69 |
70 | it('destroy()', () => {
71 | const mockFn = jest.fn()
72 | bscroll.on(bscroll.eventTypes.destroy, mockFn)
73 | bscroll.hooks.on(bscroll.hooks.eventTypes.destroy, mockFn)
74 | bscroll.destroy()
75 |
76 | expect(mockFn).toBeCalledTimes(2)
77 | })
78 |
79 | it('eventRegister()', () => {
80 | bscroll.eventRegister(['dummy'])
81 | expect(bscroll.eventTypes.dummy).toBeTruthy()
82 | })
83 |
84 | it('should refresh when window resized', () => {
85 | const mockFn = jest.fn()
86 | bscroll.on(bscroll.eventTypes.refresh, mockFn)
87 | bscroll.scroller.hooks.trigger(bscroll.scroller.hooks.eventTypes.resize)
88 | expect(mockFn).toBeCalledTimes(1)
89 | })
90 |
91 | it('plugin wanna control scroll position ', () => {
92 | const mockFn = jest.fn().mockImplementation(() => true)
93 | class DummyPlugin {
94 | static pluginName = 'dummy'
95 | constructor(scroll: BScroll) {
96 | scroll.hooks.on(scroll.hooks.eventTypes.beforeInitialScrollTo, mockFn)
97 | }
98 | }
99 | BScroll.use(DummyPlugin)
100 | bscroll = new BScroll(wrapper, { dummy: true })
101 | expect(mockFn).toBeCalled()
102 | })
103 |
104 | it('should trigger contentChanged hook when content DOM has changed', () => {
105 | const mockFn = jest.fn()
106 | bscroll.on(bscroll.eventTypes.contentChanged, mockFn)
107 |
108 | // content DOM has
109 | wrapper.removeChild(content)
110 | wrapper.appendChild(document.createElement('div'))
111 | bscroll.refresh()
112 | expect(mockFn).toBeCalled()
113 | })
114 | })
115 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/Animation.ts:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import { TranslaterPoint } from '../translater'
3 | import {
4 | getNow,
5 | requestAnimationFrame,
6 | cancelAnimationFrame,
7 | EaseFn,
8 | Probe,
9 | } from '@better-scroll/shared-utils'
10 |
11 | export default class Animation extends Base {
12 | move(
13 | startPoint: TranslaterPoint,
14 | endPoint: TranslaterPoint,
15 | time: number,
16 | easingFn: EaseFn | string
17 | ) {
18 | // time is 0
19 | if (!time) {
20 | this.translate(endPoint)
21 | if (this.options.probeType === Probe.Realtime) {
22 | this.hooks.trigger(this.hooks.eventTypes.move, endPoint)
23 | }
24 | this.hooks.trigger(this.hooks.eventTypes.end, endPoint)
25 | return
26 | }
27 | this.animate(startPoint, endPoint, time, easingFn as EaseFn)
28 | }
29 |
30 | private animate(
31 | startPoint: TranslaterPoint,
32 | endPoint: TranslaterPoint,
33 | duration: number,
34 | easingFn: EaseFn
35 | ) {
36 | let startTime = getNow()
37 | const destTime = startTime + duration
38 | const isRealtimeProbeType = this.options.probeType === Probe.Realtime
39 | const step = () => {
40 | let now = getNow()
41 | // js animation end
42 | if (now >= destTime) {
43 | this.translate(endPoint)
44 | if (isRealtimeProbeType) {
45 | this.hooks.trigger(this.hooks.eventTypes.move, endPoint)
46 | }
47 | this.hooks.trigger(this.hooks.eventTypes.end, endPoint)
48 | return
49 | }
50 |
51 | now = (now - startTime) / duration
52 | let easing = easingFn(now)
53 | const newPoint = {} as TranslaterPoint
54 | Object.keys(endPoint).forEach((key) => {
55 | const startValue = startPoint[key]
56 | const endValue = endPoint[key]
57 | newPoint[key] = (endValue - startValue) * easing + startValue
58 | })
59 | this.translate(newPoint)
60 |
61 | if (isRealtimeProbeType) {
62 | this.hooks.trigger(this.hooks.eventTypes.move, newPoint)
63 | }
64 |
65 | if (this.pending) {
66 | this.timer = requestAnimationFrame(step)
67 | }
68 |
69 | // call bs.stop() should not dispatch end hook again.
70 | // forceStop hook will do this.
71 | /* istanbul ignore if */
72 | if (!this.pending) {
73 | if (this.callStopWhenPending) {
74 | this.callStopWhenPending = false
75 | } else {
76 | // raf ends should dispatch end hook.
77 | this.hooks.trigger(this.hooks.eventTypes.end, endPoint)
78 | }
79 | }
80 | }
81 |
82 | this.setPending(true)
83 | // when manually call bs.stop(), then bs.scrollTo()
84 | // we should reset callStopWhenPending to dispatch end hook
85 | if (this.callStopWhenPending) {
86 | this.setCallStop(false)
87 | }
88 | cancelAnimationFrame(this.timer)
89 | step()
90 | }
91 |
92 | doStop(): boolean {
93 | const pending = this.pending
94 | this.setForceStopped(false)
95 | this.setCallStop(false)
96 | // still in requestFrameAnimation
97 | if (pending) {
98 | this.setPending(false)
99 | cancelAnimationFrame(this.timer)
100 | const pos = this.translater.getComputedPosition()
101 | this.setForceStopped(true)
102 | this.setCallStop(true)
103 |
104 | this.hooks.trigger(this.hooks.eventTypes.forceStop, pos)
105 | }
106 | return pending
107 | }
108 |
109 | stop() {
110 | const stopFromAnimation = this.doStop()
111 | if (stopFromAnimation) {
112 | this.hooks.trigger(this.hooks.eventTypes.callStop)
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/Base.ts:
--------------------------------------------------------------------------------
1 | import {
2 | EaseFn,
3 | safeCSSStyleDeclaration,
4 | cancelAnimationFrame,
5 | EventEmitter,
6 | Probe,
7 | } from '@better-scroll/shared-utils'
8 | import Translater, { TranslaterPoint } from '../translater'
9 |
10 | export interface ExposedAPI {
11 | stop(): void
12 | }
13 |
14 | export default abstract class Base implements ExposedAPI {
15 | content: HTMLElement
16 | style: safeCSSStyleDeclaration
17 | hooks: EventEmitter
18 | timer: number = 0
19 | pending: boolean
20 | callStopWhenPending: boolean
21 | forceStopped: boolean
22 | _reflow: number;
23 | [key: string]: any
24 |
25 | constructor(
26 | content: HTMLElement,
27 | public translater: Translater,
28 | public options: {
29 | probeType: number
30 | }
31 | ) {
32 | this.hooks = new EventEmitter([
33 | 'move',
34 | 'end',
35 | 'beforeForceStop',
36 | 'forceStop',
37 | 'callStop',
38 | 'time',
39 | 'timeFunction',
40 | ])
41 | this.setContent(content)
42 | }
43 |
44 | translate(endPoint: TranslaterPoint) {
45 | this.translater.translate(endPoint)
46 | }
47 |
48 | setPending(pending: boolean) {
49 | this.pending = pending
50 | }
51 |
52 | setForceStopped(forceStopped: boolean) {
53 | this.forceStopped = forceStopped
54 | }
55 |
56 | setCallStop(called: boolean) {
57 | this.callStopWhenPending = called
58 | }
59 |
60 | setContent(content: HTMLElement) {
61 | if (this.content !== content) {
62 | this.content = content
63 | this.style = content.style as safeCSSStyleDeclaration
64 | this.stop()
65 | }
66 | }
67 | clearTimer() {
68 | if (this.timer) {
69 | cancelAnimationFrame(this.timer)
70 | this.timer = 0
71 | }
72 | }
73 |
74 | abstract move(
75 | startPoint: TranslaterPoint,
76 | endPoint: TranslaterPoint,
77 | time: number,
78 | easing: string | EaseFn
79 | ): void
80 |
81 | abstract doStop(): void
82 | abstract stop(): void
83 |
84 | destroy() {
85 | this.hooks.destroy()
86 |
87 | cancelAnimationFrame(this.timer)
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/Transition.ts:
--------------------------------------------------------------------------------
1 | import {
2 | style,
3 | requestAnimationFrame,
4 | cancelAnimationFrame,
5 | EaseFn,
6 | Probe,
7 | } from '@better-scroll/shared-utils'
8 | import Base from './Base'
9 | import { TranslaterPoint } from '../translater'
10 | import { isValidPostion } from '../utils/compat'
11 |
12 | export default class Transition extends Base {
13 | startProbe(startPoint: TranslaterPoint, endPoint: TranslaterPoint) {
14 | let prePos = startPoint
15 | const probe = () => {
16 | let pos = this.translater.getComputedPosition()
17 |
18 | if (isValidPostion(startPoint, endPoint, pos, prePos)) {
19 | this.hooks.trigger(this.hooks.eventTypes.move, pos)
20 | }
21 | // call bs.stop() should not dispatch end hook again.
22 | // forceStop hook will do this.
23 | /* istanbul ignore if */
24 | if (!this.pending) {
25 | if (this.callStopWhenPending) {
26 | this.callStopWhenPending = false
27 | } else {
28 | // transition ends should dispatch end hook.
29 | this.hooks.trigger(this.hooks.eventTypes.end, pos)
30 | }
31 | }
32 | prePos = pos
33 |
34 | if (this.pending) {
35 | this.timer = requestAnimationFrame(probe)
36 | }
37 | }
38 | // when manually call bs.stop(), then bs.scrollTo()
39 | // we should reset callStopWhenPending to dispatch end hook
40 | if (this.callStopWhenPending) {
41 | this.setCallStop(false)
42 | }
43 |
44 | cancelAnimationFrame(this.timer)
45 | probe()
46 | }
47 |
48 | transitionTime(time = 0) {
49 | this.style[style.transitionDuration] = time + 'ms'
50 | this.hooks.trigger(this.hooks.eventTypes.time, time)
51 | }
52 |
53 | transitionTimingFunction(easing: string) {
54 | this.style[style.transitionTimingFunction] = easing
55 | this.hooks.trigger(this.hooks.eventTypes.timeFunction, easing)
56 | }
57 |
58 | transitionProperty() {
59 | this.style[style.transitionProperty] = style.transform
60 | }
61 |
62 | move(
63 | startPoint: TranslaterPoint,
64 | endPoint: TranslaterPoint,
65 | time: number,
66 | easingFn: string | EaseFn
67 | ) {
68 | this.setPending(time > 0)
69 | this.transitionTimingFunction(easingFn as string)
70 | this.transitionProperty()
71 | this.transitionTime(time)
72 | this.translate(endPoint)
73 |
74 | const isRealtimeProbeType = this.options.probeType === Probe.Realtime
75 |
76 | if (time && isRealtimeProbeType) {
77 | this.startProbe(startPoint, endPoint)
78 | }
79 |
80 | // if we change content's transformY in a tick
81 | // such as: 0 -> 50px -> 0
82 | // transitionend will not be triggered
83 | // so we forceupdate by reflow
84 | if (!time) {
85 | this._reflow = this.content.offsetHeight
86 | if (isRealtimeProbeType) {
87 | this.hooks.trigger(this.hooks.eventTypes.move, endPoint)
88 | }
89 | this.hooks.trigger(this.hooks.eventTypes.end, endPoint)
90 | }
91 | }
92 |
93 | doStop(): boolean {
94 | const pending = this.pending
95 | this.setForceStopped(false)
96 | this.setCallStop(false)
97 | // still in transition
98 | if (pending) {
99 | this.setPending(false)
100 | cancelAnimationFrame(this.timer)
101 | const { x, y } = this.translater.getComputedPosition()
102 |
103 | this.transitionTime()
104 | this.translate({ x, y })
105 | this.setForceStopped(true)
106 | this.setCallStop(true)
107 | this.hooks.trigger(this.hooks.eventTypes.forceStop, { x, y })
108 | }
109 | return pending
110 | }
111 |
112 | stop() {
113 | const stopFromTransition = this.doStop()
114 | if (stopFromTransition) {
115 | this.hooks.trigger(this.hooks.eventTypes.callStop)
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__mocks__/Animation.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils'
2 |
3 | const Animation = jest
4 | .fn()
5 | .mockImplementation((content, translater, bscrollOptions) => {
6 | return {
7 | content,
8 | translater,
9 | options: bscrollOptions,
10 | style: content.style,
11 | pending: false,
12 | forceStopped: false,
13 | timer: 0,
14 | hooks: new EventEmitter([
15 | 'move',
16 | 'end',
17 | 'forceStop',
18 | 'beforeForceStop',
19 | 'callStop',
20 | 'time',
21 | 'timeFunction',
22 | ]),
23 | translate: jest.fn(),
24 | stop: jest.fn(),
25 | doStop: jest.fn(),
26 | move: jest.fn(),
27 | destroy: jest.fn(),
28 | setPending: jest.fn(),
29 | setForceStopped: jest.fn(),
30 | setCallStop: jest.fn(),
31 | setContent: jest.fn(),
32 | clearTimer: jest.fn(),
33 | }
34 | })
35 |
36 | export default Animation
37 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__mocks__/Transition.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils'
2 |
3 | const Transition = jest
4 | .fn()
5 | .mockImplementation((content, translater, bscrollOptions) => {
6 | return {
7 | content,
8 | translater,
9 | options: bscrollOptions,
10 | style: content.style,
11 | pending: false,
12 | forceStopped: false,
13 | timer: 0,
14 | hooks: new EventEmitter([
15 | 'move',
16 | 'end',
17 | 'forceStop',
18 | 'beforeForceStop',
19 | 'callStop',
20 | 'time',
21 | 'timeFunction',
22 | ]),
23 | translate: jest.fn(),
24 | stop: jest.fn(),
25 | doStop: jest.fn(),
26 | move: jest.fn(),
27 | startProbe: jest.fn(),
28 | transitionTime: jest.fn(),
29 | transitionTimingFunction: jest.fn(),
30 | destroy: jest.fn(),
31 | setPending: jest.fn(),
32 | setForceStopped: jest.fn(),
33 | setCallStop: jest.fn(),
34 | setContent: jest.fn(),
35 | clearTimer: jest.fn(),
36 | }
37 | })
38 |
39 | export default Transition
40 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__mocks__/index.ts:
--------------------------------------------------------------------------------
1 | import Transition from '../Transition'
2 | import Animation from '../Animation'
3 |
4 | jest.mock('../Transition')
5 | jest.mock('../Animation')
6 |
7 | const createAnimater = jest
8 | .fn()
9 | .mockImplementation((element, translater, bscrollOptions) => {
10 | if (bscrollOptions.useTransition) {
11 | return new Transition(element, translater, bscrollOptions as {
12 | probeType: number
13 | })
14 | } else {
15 | return new Animation(element, translater, bscrollOptions as {
16 | probeType: number
17 | })
18 | }
19 | })
20 |
21 | export default createAnimater
22 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__tests__/index.spec.ts:
--------------------------------------------------------------------------------
1 | import Translater from '../../translater/index'
2 | import Transition from '../Transition'
3 | import Animation from '../Animation'
4 | import { OptionsConstructor } from '../../Options'
5 | jest.mock('../Animation')
6 | jest.mock('../Transition')
7 | jest.mock('../Base')
8 | jest.mock('../../translater/index')
9 | jest.mock('../../Options')
10 |
11 | import createAnimater from '../index'
12 |
13 | describe('animater create test suit', () => {
14 | const dom = document.createElement('div')
15 | const translater = new Translater(dom)
16 | it('should create Transition class when useTransition=true', () => {
17 | const options = new OptionsConstructor()
18 | options.probeType = 0
19 | options.useTransition = true
20 | const animater = createAnimater(dom, translater, options)
21 | expect(Transition).toBeCalledWith(dom, translater, { probeType: 0 })
22 | })
23 | it('should create Animation class when useTransition=false', () => {
24 | const options = new OptionsConstructor()
25 | options.probeType = 0
26 | options.useTransition = false
27 | const animater = createAnimater(dom, translater, options)
28 | expect(Animation).toBeCalledWith(dom, translater, { probeType: 0 })
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/index.ts:
--------------------------------------------------------------------------------
1 | import Translater from '../translater'
2 | import { Options as BScrollOptions } from '../Options'
3 |
4 | import Animater from './Base'
5 | import Transition from './Transition'
6 | import Animation from './Animation'
7 |
8 | export { Animater, Transition, Animation }
9 |
10 | export default function createAnimater(
11 | element: HTMLElement,
12 | translater: Translater,
13 | options: BScrollOptions
14 | ) {
15 | const useTransition = options.useTransition
16 | let animaterOptions = {}
17 | Object.defineProperty(animaterOptions, 'probeType', {
18 | enumerable: true,
19 | configurable: false,
20 | get() {
21 | return options.probeType
22 | },
23 | })
24 | if (useTransition) {
25 | return new Transition(
26 | element,
27 | translater,
28 | animaterOptions as {
29 | probeType: number
30 | }
31 | )
32 | } else {
33 | return new Animation(
34 | element,
35 | translater,
36 | animaterOptions as {
37 | probeType: number
38 | }
39 | )
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/base/__mocks__/ActionsHandler.ts:
--------------------------------------------------------------------------------
1 | import { EventRegister, EventEmitter } from '@better-scroll/shared-utils'
2 |
3 | const ActionsHandler = jest
4 | .fn()
5 | .mockImplementation((wrapper, bscrollOptions) => {
6 | return {
7 | wrapper,
8 | options: bscrollOptions,
9 | initiated: 1,
10 | pointX: 0,
11 | pointY: 0,
12 | startClickRegister: new EventRegister(wrapper, []),
13 | moveEndRegister: new EventRegister(wrapper, []),
14 | hooks: new EventEmitter(['beforeStart', 'start', 'move', 'end', 'click']),
15 | destroy: jest.fn(),
16 | setInitiated: jest.fn(),
17 | setContent: jest.fn(),
18 | rebindDOMEvents: jest.fn(),
19 | }
20 | })
21 |
22 | export default ActionsHandler
23 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/index.ts:
--------------------------------------------------------------------------------
1 | import { BScroll } from './BScroll'
2 |
3 | export { BScrollInstance } from './Instance'
4 | export { Options, CustomOptions } from './Options'
5 | export { TranslaterPoint } from './translater'
6 | export { MountedBScrollHTMLElement } from './BScroll'
7 | export { Behavior, Boundary } from './scroller/Behavior'
8 | export { createBScroll, CustomAPI } from './BScroll'
9 |
10 | export default BScroll
11 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/DirectionLock.ts:
--------------------------------------------------------------------------------
1 | import {
2 | TouchEvent,
3 | DirectionLock,
4 | EventPassthrough
5 | } from '@better-scroll/shared-utils'
6 |
7 | const enum Passthrough {
8 | Yes = 'yes',
9 | No = 'no'
10 | }
11 |
12 | interface DirectionMap {
13 | [key: string]: {
14 | [key: string]: EventPassthrough
15 | }
16 | }
17 |
18 | const PassthroughHandlers = {
19 | [Passthrough.Yes]: (e: TouchEvent) => {
20 | return true
21 | },
22 | [Passthrough.No]: (e: TouchEvent) => {
23 | e.preventDefault()
24 | return false
25 | }
26 | }
27 | const DirectionMap: DirectionMap = {
28 | [DirectionLock.Horizontal]: {
29 | [Passthrough.Yes]: EventPassthrough.Horizontal,
30 | [Passthrough.No]: EventPassthrough.Vertical
31 | },
32 | [DirectionLock.Vertical]: {
33 | [Passthrough.Yes]: EventPassthrough.Vertical,
34 | [Passthrough.No]: EventPassthrough.Horizontal
35 | }
36 | }
37 |
38 | export default class DirectionLockAction {
39 | directionLocked: DirectionLock
40 | constructor(
41 | public directionLockThreshold: number,
42 | public freeScroll: boolean,
43 | public eventPassthrough: string
44 | ) {
45 | this.reset()
46 | }
47 |
48 | reset() {
49 | this.directionLocked = DirectionLock.Default
50 | }
51 |
52 | checkMovingDirection(absDistX: number, absDistY: number, e: TouchEvent) {
53 | this.computeDirectionLock(absDistX, absDistY)
54 |
55 | return this.handleEventPassthrough(e)
56 | }
57 |
58 | adjustDelta(deltaX: number, deltaY: number) {
59 | if (this.directionLocked === DirectionLock.Horizontal) {
60 | deltaY = 0
61 | } else if (this.directionLocked === DirectionLock.Vertical) {
62 | deltaX = 0
63 | }
64 | return {
65 | deltaX,
66 | deltaY
67 | }
68 | }
69 |
70 | private computeDirectionLock(absDistX: number, absDistY: number) {
71 | // If you are scrolling in one direction, lock it
72 | if (this.directionLocked === DirectionLock.Default && !this.freeScroll) {
73 | if (absDistX > absDistY + this.directionLockThreshold) {
74 | this.directionLocked = DirectionLock.Horizontal // lock horizontally
75 | } else if (absDistY >= absDistX + this.directionLockThreshold) {
76 | this.directionLocked = DirectionLock.Vertical // lock vertically
77 | } else {
78 | this.directionLocked = DirectionLock.None // no lock
79 | }
80 | }
81 | }
82 |
83 | private handleEventPassthrough(e: TouchEvent) {
84 | const handleMap = DirectionMap[this.directionLocked]
85 | if (handleMap) {
86 | if (this.eventPassthrough === handleMap[Passthrough.Yes]) {
87 | return PassthroughHandlers[Passthrough.Yes](e)
88 | } else if (this.eventPassthrough === handleMap[Passthrough.No]) {
89 | return PassthroughHandlers[Passthrough.No](e)
90 | }
91 | }
92 | return false
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/Actions.ts:
--------------------------------------------------------------------------------
1 | import DirectionLock from '../DirectionLock'
2 |
3 | jest.mock('../DirectionLock')
4 |
5 | import { EventEmitter } from '@better-scroll/shared-utils'
6 |
7 | const ScrollerActions = jest
8 | .fn()
9 | .mockImplementation(
10 | (
11 | scrollBehaviorX,
12 | scrollBehaviorY,
13 | actionsHandler,
14 | animater,
15 | bscrollOptions
16 | ) => {
17 | const directionLockAction = new DirectionLock(0, false, '')
18 |
19 | return {
20 | options: bscrollOptions,
21 | scrollBehaviorX,
22 | scrollBehaviorY,
23 | actionsHandler,
24 | animater,
25 | directionLockAction,
26 | moved: false,
27 | enabled: true,
28 | startTime: 0,
29 | endTime: 0,
30 | ensuringInteger: false,
31 | getCurrentPos: jest.fn().mockImplementation(() => {
32 | return {
33 | x: 0,
34 | y: 0,
35 | }
36 | }),
37 | refresh: jest.fn(),
38 | destroy: jest.fn(),
39 | hooks: new EventEmitter([
40 | 'start',
41 | 'beforeMove',
42 | 'scrollStart',
43 | 'scroll',
44 | 'beforeEnd',
45 | 'end',
46 | 'scrollEnd',
47 | 'contentNotMoved',
48 | 'detectMovingDirection',
49 | ]),
50 | }
51 | }
52 | )
53 |
54 | export default ScrollerActions
55 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/Behavior.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils'
2 |
3 | const Behavior = jest.fn().mockImplementation((content, bscrollOptions) => {
4 | return {
5 | content,
6 | options: bscrollOptions,
7 | startPos: 0,
8 | currentPos: 0,
9 | absStartPos: 0,
10 | dist: 0,
11 | minScrollPos: 0,
12 | maxScrollPos: 0,
13 | hasScroll: true,
14 | direction: 0,
15 | movingDirection: 0,
16 | relativeOffset: 0,
17 | wrapperSize: 0,
18 | contentSize: 0,
19 | hooks: new EventEmitter([
20 | 'momentum',
21 | 'end',
22 | 'beforeComputeBoundary',
23 | 'computeBoundary',
24 | 'ignoreHasScroll',
25 | ]),
26 | start: jest.fn(),
27 | move: jest.fn(),
28 | end: jest.fn(),
29 | updateDirection: jest.fn(),
30 | refresh: jest.fn(),
31 | updatePosition: jest.fn(),
32 | getCurrentPos: jest.fn().mockImplementation(() => {
33 | return 0
34 | }),
35 | checkInBoundary: jest.fn().mockImplementation(() => {
36 | return {
37 | position: 0,
38 | inBoundary: false,
39 | }
40 | }),
41 | adjustPosition: jest.fn(),
42 | updateStartPos: jest.fn(),
43 | updateAbsStartPos: jest.fn(),
44 | resetStartPos: jest.fn(),
45 | getAbsDist: jest.fn().mockImplementation((delta: number) => {
46 | return Math.abs(delta)
47 | }),
48 | destroy: jest.fn(),
49 | computeBoundary: jest.fn(),
50 | setMovingDirection: jest.fn(),
51 | setDirection: jest.fn(),
52 | performDampingAlgorithm: jest.fn(),
53 | }
54 | })
55 |
56 | export { Behavior }
57 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/DirectionLock.ts:
--------------------------------------------------------------------------------
1 | const DirectionLock = jest
2 | .fn()
3 | .mockImplementation((content, bscrollOptions) => {
4 | return {
5 | directionLocked: '',
6 | directionLockThreshold: '5',
7 | eventPassthrough: '',
8 | freeScroll: false,
9 | reset: jest.fn(),
10 | checkMovingDirection: jest.fn().mockImplementation((ret = true) => {
11 | return ret
12 | }),
13 | adjustDelta: jest
14 | .fn()
15 | .mockImplementation((deltaX: number = 0, deltaY: number = 0) => {
16 | return {
17 | deltaX,
18 | deltaY,
19 | }
20 | }),
21 | }
22 | })
23 |
24 | export default DirectionLock
25 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/Scroller.ts:
--------------------------------------------------------------------------------
1 | import createAnimater from '../../animater'
2 | import Translater from '../../translater'
3 | import { Behavior } from '../Behavior'
4 | import ActionsHandler from '../../base/ActionsHandler'
5 | import Actions from '../Actions'
6 |
7 | jest.mock('../../animater')
8 | jest.mock('../../translater')
9 | jest.mock('../Behavior')
10 | jest.mock('../../base/ActionsHandler')
11 | jest.mock('../Actions')
12 |
13 | import { EventEmitter, EventRegister } from '@better-scroll/shared-utils'
14 |
15 | const Scroller = jest.fn().mockImplementation((wrapper, bscrollOptions) => {
16 | const content = wrapper.children[0]
17 | const translater = new Translater(content)
18 | const animater = createAnimater(content, translater, bscrollOptions)
19 | const actionsHandler = new ActionsHandler(wrapper, bscrollOptions)
20 | const scrollBehaviorX = new Behavior(
21 | wrapper,
22 | content,
23 | Object.assign(bscrollOptions, { scrollable: bscrollOptions.scrollX })
24 | )
25 | const scrollBehaviorY = new Behavior(
26 | wrapper,
27 | content,
28 | Object.assign(bscrollOptions, { scrollable: bscrollOptions.scrollY })
29 | )
30 | const actions = new Actions(
31 | scrollBehaviorX,
32 | scrollBehaviorY,
33 | actionsHandler,
34 | animater,
35 | bscrollOptions
36 | )
37 | return {
38 | wrapper,
39 | content,
40 | options: bscrollOptions,
41 | translater,
42 | animater,
43 | actionsHandler,
44 | actions,
45 | hooks: new EventEmitter([
46 | 'beforeStart',
47 | 'beforeMove',
48 | 'beforeScrollStart',
49 | 'scrollStart',
50 | 'scroll',
51 | 'beforeEnd',
52 | 'scrollEnd',
53 | 'resize',
54 | 'touchEnd',
55 | 'end',
56 | 'flick',
57 | 'scrollCancel',
58 | 'momentum',
59 | 'scrollTo',
60 | 'minDistanceScroll',
61 | 'scrollToElement',
62 | 'transitionEnd',
63 | 'checkClick',
64 | 'beforeRefresh',
65 | ]),
66 | scrollBehaviorX,
67 | scrollBehaviorY,
68 | resizeRegister: new EventRegister(wrapper, []),
69 | transitionEndRegister: new EventRegister(wrapper, []),
70 | scrollTo: jest.fn(),
71 | resetPosition: jest.fn(),
72 | togglePointerEvents: jest.fn(),
73 | reflow: jest.fn(),
74 | }
75 | })
76 |
77 | export default Scroller
78 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__tests__/DirectionLock.spec.ts:
--------------------------------------------------------------------------------
1 | import DirectionLock from '../DirectionLock'
2 | import {
3 | Direction,
4 | DirectionLock as DirectionLockEnum,
5 | } from '@better-scroll/shared-utils'
6 | describe('DirectionLock Class tests', () => {
7 | let directionLock: DirectionLock
8 | let e = new Event('touchstart') as any
9 |
10 | beforeEach(() => {
11 | directionLock = new DirectionLock(5, false, '')
12 | })
13 |
14 | it('should call reset when call constructor function', () => {
15 | expect(directionLock.directionLocked).toBe('')
16 | })
17 |
18 | it('should lock vertically when scrolled in direction Y', () => {
19 | directionLock.checkMovingDirection(0, 20, e)
20 |
21 | expect(directionLock.directionLocked).toBe('vertical')
22 | })
23 |
24 | it('should lock horizontally when scrolled in direction X', () => {
25 | directionLock.checkMovingDirection(20, 0, e)
26 |
27 | expect(directionLock.directionLocked).toBe('horizontal')
28 | })
29 |
30 | it('should no lock when freeScroll is true', () => {
31 | directionLock.freeScroll = true
32 | directionLock.checkMovingDirection(20, 20, e)
33 |
34 | expect(directionLock.directionLocked).toBe('')
35 | })
36 |
37 | it('adjustDelta() ', () => {
38 | directionLock.directionLocked = DirectionLockEnum.Horizontal
39 | const ret1 = directionLock.adjustDelta(20, 20)
40 | expect(ret1).toMatchObject({
41 | deltaX: 20,
42 | deltaY: 0,
43 | })
44 |
45 | directionLock.directionLocked = DirectionLockEnum.Vertical
46 | const ret2 = directionLock.adjustDelta(20, 20)
47 | expect(ret2).toMatchObject({
48 | deltaX: 0,
49 | deltaY: 20,
50 | })
51 | })
52 |
53 | it('reset()', () => {
54 | directionLock.directionLocked = DirectionLockEnum.Vertical
55 | directionLock.reset()
56 | expect(directionLock.directionLocked).toBe(DirectionLockEnum.Default)
57 | })
58 |
59 | it('checkMovingDirection()', () => {
60 | directionLock.directionLocked = DirectionLockEnum.Horizontal
61 | directionLock.eventPassthrough = DirectionLockEnum.Horizontal
62 | const ret1 = directionLock.checkMovingDirection(20, 20, {
63 | preventDefault() {
64 | return true
65 | },
66 | } as any)
67 | expect(ret1).toBe(true)
68 |
69 | directionLock.directionLocked = DirectionLockEnum.Horizontal
70 | directionLock.eventPassthrough = DirectionLockEnum.Vertical
71 | const ret2 = directionLock.checkMovingDirection(20, 20, {
72 | preventDefault() {
73 | return true
74 | },
75 | } as any)
76 | expect(ret2).toBe(false)
77 |
78 | // no locked
79 | directionLock.directionLocked = DirectionLockEnum.Default
80 | const ret3 = directionLock.checkMovingDirection(20, 20, {
81 | preventDefault() {
82 | return true
83 | },
84 | } as any)
85 | expect(ret3).toBe(false)
86 | })
87 | })
88 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__tests__/createOptions.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | createActionsHandlerOptions,
3 | createBehaviorOptions,
4 | } from '../createOptions'
5 | import { OptionsConstructor } from '../../Options'
6 |
7 | jest.mock('../../Options')
8 |
9 | describe('createOptions helper function tests', () => {
10 | let bsOptions: any
11 | beforeEach(() => {
12 | bsOptions = new OptionsConstructor()
13 | })
14 | it('should return correct object when invoking createActionsHandlerOptions function', () => {
15 | let ret = createActionsHandlerOptions(bsOptions)
16 |
17 | expect(ret).toEqual({
18 | click: false,
19 | bindToWrapper: false,
20 | disableMouse: true,
21 | preventDefault: true,
22 | stopPropagation: false,
23 | preventDefaultException: {
24 | tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|AUDIO)$/,
25 | },
26 | })
27 | })
28 |
29 | it('should return correct object when invoking createBehaviorOptions function', () => {
30 | let ret = createBehaviorOptions(bsOptions, 'scrollY', [true, true], {
31 | size: 'width',
32 | position: 'top',
33 | })
34 |
35 | expect(ret).toEqual({
36 | momentum: true,
37 | momentumLimitTime: 300,
38 | momentumLimitDistance: 15,
39 | deceleration: 0.0015,
40 | swipeBounceTime: 500,
41 | swipeTime: 2500,
42 | scrollable: true,
43 | outOfBoundaryDampingFactor: 1 / 3,
44 | specifiedIndexAsContent: 0,
45 | bounces: [true, true],
46 | rect: {
47 | size: 'width',
48 | position: 'top',
49 | },
50 | })
51 | })
52 | })
53 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/createOptions.ts:
--------------------------------------------------------------------------------
1 | import { Options as BScrollOptions } from '../Options'
2 | import { Options as ActionsHandlerOptions } from '../base/ActionsHandler'
3 | import { Options as BehaviorOptions, Bounces, Rect } from './Behavior'
4 |
5 | export function createActionsHandlerOptions(bsOptions: BScrollOptions) {
6 | const options = [
7 | 'click',
8 | 'bindToWrapper',
9 | 'disableMouse',
10 | 'disableTouch',
11 | 'preventDefault',
12 | 'stopPropagation',
13 | 'tagException',
14 | 'preventDefaultException',
15 | 'autoEndDistance',
16 | ].reduce((prev, cur) => {
17 | prev[cur] = bsOptions[cur]
18 | return prev
19 | }, {} as ActionsHandlerOptions)
20 | return options
21 | }
22 |
23 | export function createBehaviorOptions(
24 | bsOptions: BScrollOptions,
25 | extraProp: 'scrollX' | 'scrollY',
26 | bounces: Bounces,
27 | rect: Rect
28 | ) {
29 | const options = [
30 | 'momentum',
31 | 'momentumLimitTime',
32 | 'momentumLimitDistance',
33 | 'deceleration',
34 | 'swipeBounceTime',
35 | 'swipeTime',
36 | 'outOfBoundaryDampingFactor',
37 | 'specifiedIndexAsContent',
38 | ].reduce((prev, cur) => {
39 | prev[cur] = bsOptions[cur]
40 | return prev
41 | }, {} as BehaviorOptions)
42 | // add extra property
43 | options.scrollable = !!bsOptions[extraProp]
44 | options.bounces = bounces
45 | options.rect = rect
46 | return options
47 | }
48 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/translater/__mocks__/index.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils'
2 |
3 | const Translater = jest.fn().mockImplementation((content) => {
4 | return {
5 | style: content.style,
6 | hooks: new EventEmitter(['beforeTranslate', 'translate']),
7 | getComputedPosition: jest
8 | .fn()
9 | .mockImplementation((position = { x: 0, y: 0 }) => {
10 | return position
11 | }),
12 | translate: jest.fn(),
13 | destroy: jest.fn(),
14 | setContent: jest.fn(),
15 | }
16 | })
17 |
18 | export default Translater
19 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/translater/__tests__/index.spec.ts:
--------------------------------------------------------------------------------
1 | import Translater from '../index'
2 |
3 | describe('Translater Class test suit', () => {
4 | let translater: Translater
5 | let contentEl = document.createElement('div')
6 |
7 | beforeEach(() => {
8 | translater = new Translater(contentEl)
9 | })
10 | afterEach(() => {
11 | jest.clearAllMocks()
12 | })
13 |
14 | it('work well when call translate()', () => {
15 | const mockFn1 = jest.fn()
16 | const mockFn2 = jest.fn()
17 | translater.hooks.on(translater.hooks.eventTypes.beforeTranslate, mockFn1)
18 | translater.hooks.on(translater.hooks.eventTypes.translate, mockFn2)
19 |
20 | translater.translate({ x: 0, y: 0, dummy: 0 })
21 |
22 | expect(mockFn1).toBeCalled()
23 | expect(mockFn1).toBeCalledWith(['translateX(0px)', 'translateY(0px)'], {
24 | x: 0,
25 | y: 0,
26 | dummy: 0,
27 | })
28 | expect(mockFn2).toBeCalled()
29 | expect(mockFn2).toBeCalledWith({ x: 0, y: 0, dummy: 0 })
30 | expect(translater.content.style.transform).toBe(
31 | 'translateX(0px) translateY(0px)'
32 | )
33 | })
34 |
35 | it('get correct position when call getComputedPosition()', () => {
36 | // jsDOM library's getComputedStyle is different from browser
37 | window.getComputedStyle = jest.fn().mockImplementation(() => {
38 | return {
39 | transform: 'matrix(1, 0, 0, 1, 0, 0)',
40 | }
41 | })
42 | const { x, y } = translater.getComputedPosition()
43 |
44 | expect(x).toBe(0)
45 | expect(y).toBe(0)
46 | })
47 |
48 | it('should clear hooks when destroyed', () => {
49 | translater.hooks.on(translater.hooks.eventTypes.beforeTranslate, () => {})
50 |
51 | expect(translater.hooks.eventTypes.beforeTranslate).toBe('beforeTranslate')
52 |
53 | translater.destroy()
54 |
55 | expect(translater.hooks.eventTypes.beforeTranslate).toBeFalsy()
56 | })
57 | })
58 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/translater/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | style,
3 | safeCSSStyleDeclaration,
4 | EventEmitter,
5 | } from '@better-scroll/shared-utils'
6 | export interface TranslaterPoint {
7 | x: number
8 | y: number
9 | [key: string]: number
10 | }
11 |
12 | interface TranslaterMetaData {
13 | x: [string, string]
14 | y: [string, string]
15 | [key: string]: any
16 | }
17 | const translaterMetaData: TranslaterMetaData = {
18 | x: ['translateX', 'px'],
19 | y: ['translateY', 'px'],
20 | }
21 |
22 | export default class Translater {
23 | content: HTMLElement
24 | style: CSSStyleDeclaration
25 | hooks: EventEmitter
26 | constructor(content: HTMLElement) {
27 | this.setContent(content)
28 | this.hooks = new EventEmitter(['beforeTranslate', 'translate'])
29 | }
30 |
31 | getComputedPosition() {
32 | let cssStyle = window.getComputedStyle(
33 | this.content,
34 | null
35 | ) as safeCSSStyleDeclaration
36 | let matrix = cssStyle[style.transform].split(')')[0].split(', ')
37 | const x = +(matrix[12] || matrix[4]) || 0
38 | const y = +(matrix[13] || matrix[5]) || 0
39 |
40 | return {
41 | x,
42 | y,
43 | }
44 | }
45 |
46 | translate(point: TranslaterPoint) {
47 | let transformStyle = [] as string[]
48 | Object.keys(point).forEach((key) => {
49 | if (!translaterMetaData[key]) {
50 | return
51 | }
52 | const transformFnName = translaterMetaData[key][0]
53 | if (transformFnName) {
54 | const transformFnArgUnit = translaterMetaData[key][1]
55 | const transformFnArg = point[key]
56 | transformStyle.push(
57 | `${transformFnName}(${transformFnArg}${transformFnArgUnit})`
58 | )
59 | }
60 | })
61 | this.hooks.trigger(
62 | this.hooks.eventTypes.beforeTranslate,
63 | transformStyle,
64 | point
65 | )
66 | this.style[style.transform as any] = transformStyle.join(' ')
67 | this.hooks.trigger(this.hooks.eventTypes.translate, point)
68 | }
69 |
70 | setContent(content: HTMLElement) {
71 | if (this.content !== content) {
72 | this.content = content
73 | this.style = content.style
74 | }
75 | }
76 |
77 | destroy() {
78 | this.hooks.destroy()
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/__tests__/bubbling.spec.ts:
--------------------------------------------------------------------------------
1 | import { bubbling } from '../bubbling'
2 | import { EventEmitter } from '@better-scroll/shared-utils'
3 |
4 | describe('bubbling', () => {
5 | it('bubbling', () => {
6 | const parentHooks = new EventEmitter(['test'])
7 | const childHooks = new EventEmitter(['test'])
8 | bubbling(childHooks, parentHooks, ['test'])
9 | const handler = jest.fn(() => {})
10 | parentHooks.on('test', handler)
11 | childHooks.trigger('test', 'dummy test')
12 | expect(handler).toBeCalledWith('dummy test')
13 | })
14 | })
15 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/bubbling.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@better-scroll/shared-utils'
2 |
3 | interface BubblingEventMap {
4 | source: string
5 | target: string
6 | }
7 | type BubblingEventConfig = BubblingEventMap | string
8 | export function bubbling(
9 | source: EventEmitter,
10 | target: EventEmitter,
11 | events: BubblingEventConfig[]
12 | ) {
13 | events.forEach(event => {
14 | let sourceEvent: string
15 | let targetEvent: string
16 | if (typeof event === 'string') {
17 | sourceEvent = targetEvent = event
18 | } else {
19 | sourceEvent = event.source
20 | targetEvent = event.target
21 | }
22 | source.on(sourceEvent, function(...args: any[]) {
23 | return target.trigger(targetEvent, ...args)
24 | })
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/compare.ts:
--------------------------------------------------------------------------------
1 | import { TranslaterPoint } from '../translater'
2 |
3 | export function isSamePoint(
4 | startPoint: TranslaterPoint,
5 | endPoint: TranslaterPoint
6 | ): boolean {
7 | // keys of startPoint and endPoint should be equal
8 | const keys = Object.keys(startPoint)
9 | for (let key of keys) {
10 | if (startPoint[key] !== endPoint[key]) return false
11 | }
12 | return true
13 | }
14 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/compat.ts:
--------------------------------------------------------------------------------
1 | import { Direction } from '@better-scroll/shared-utils'
2 | import { TranslaterPoint } from '../translater'
3 |
4 | type Position = {
5 | x: number
6 | y: number
7 | }
8 | // iOS 13.6 - 14.x, window.getComputedStyle sometimes will get wrong transform value
9 | // when bs use transition mode
10 | // eg: translateY -100px -> -200px, when the last frame which is about to scroll to -200px
11 | // window.getComputedStyle(this.content) will calculate transformY to be -100px(startPoint)
12 | // it is weird
13 | // so we should validate position caculated by 'window.getComputedStyle'
14 | export const isValidPostion = (
15 | startPoint: TranslaterPoint,
16 | endPoint: TranslaterPoint,
17 | currentPos: Position,
18 | prePos: Position
19 | ) => {
20 | const computeDirection = (endValue: number, startValue: number) => {
21 | const delta = endValue - startValue
22 | const direction =
23 | delta > 0
24 | ? Direction.Negative
25 | : delta < 0
26 | ? Direction.Positive
27 | : Direction.Default
28 | return direction
29 | }
30 | const directionX = computeDirection(endPoint.x, startPoint.x)
31 | const directionY = computeDirection(endPoint.y, startPoint.y)
32 | const deltaX = currentPos.x - prePos.x
33 | const deltaY = currentPos.y - prePos.y
34 |
35 | return directionX * deltaX <= 0 && directionY * deltaY <= 0
36 | }
37 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/typesHelper.ts:
--------------------------------------------------------------------------------
1 | export type UnionToIntersection = (
2 | U extends any ? (k: U) => void : never
3 | ) extends (k: infer I) => void
4 | ? I
5 | : never
6 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 HuangYi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/README.md:
--------------------------------------------------------------------------------
1 | # @better-scroll/pull-down
2 |
3 | [中文文档](https://github.com/ustbhuangyi/better-scroll/blob/master/packages/pull-down/README_zh-CN.md)
4 |
5 | The ability to inject a pull-down refresh for BetterScroll.
6 |
7 | ## Usage
8 |
9 | ```js
10 | import BScroll from '@better-scroll/core'
11 | import Pulldown from '@better-scroll/pull-down'
12 | BScroll.use(Pulldown)
13 |
14 | const bs = new BScroll('.wrapper', {
15 | pullDownRefresh: true
16 | })
17 | ```
18 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/README_zh-CN.md:
--------------------------------------------------------------------------------
1 | # @better-scroll/pull-down
2 |
3 | 为 BetterScroll 注入下拉刷新的能力。
4 |
5 | ## 使用
6 |
7 | ```js
8 | import BScroll from '@better-scroll/core'
9 | import Pulldown from '@better-scroll/pull-down'
10 | BScroll.use(Pulldown)
11 |
12 | const bs = new BScroll('.wrapper', {
13 | pullDownRefresh: true
14 | })
15 | ```
16 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/dist/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import BScroll from '@better-scroll/core';
2 | export declare type PullDownRefreshOptions = Partial | true;
3 | declare const enum PullDownPhase {
4 | DEFAULT = 0,
5 | MOVING = 1,
6 | FETCHING = 2
7 | }
8 | declare const enum ThresholdBoundary {
9 | DEFAULT = 0,
10 | INSIDE = 1,
11 | OUTSIDE = 2
12 | }
13 | export interface PullDownRefreshConfig {
14 | threshold: number;
15 | stop: number;
16 | }
17 | declare module '@better-scroll/core' {
18 | interface CustomOptions {
19 | pullDownRefresh?: PullDownRefreshOptions;
20 | }
21 | interface CustomAPI {
22 | pullDownRefresh: PluginAPI;
23 | }
24 | }
25 | interface PluginAPI {
26 | finishPullDown(): void;
27 | openPullDown(config?: PullDownRefreshOptions): void;
28 | closePullDown(): void;
29 | autoPullDownRefresh(): void;
30 | }
31 | export default class PullDown implements PluginAPI {
32 | scroll: BScroll;
33 | static pluginName: string;
34 | private hooksFn;
35 | pulling: PullDownPhase;
36 | thresholdBoundary: ThresholdBoundary;
37 | watching: boolean;
38 | options: PullDownRefreshConfig;
39 | cachedOriginanMinScrollY: number;
40 | currentMinScrollY: number;
41 | constructor(scroll: BScroll);
42 | private setPulling;
43 | private setThresholdBoundary;
44 | private init;
45 | private handleBScroll;
46 | private handleOptions;
47 | private handleHooks;
48 | private registerHooks;
49 | private hasMouseWheelPlugin;
50 | private watch;
51 | private resetStateBeforeScrollStart;
52 | private checkLocationOfThresholdBoundary;
53 | private locateInsideThresholdBoundary;
54 | private unwatch;
55 | private checkPullDown;
56 | private isFetchingStatus;
57 | private modifyBehaviorYBoundary;
58 | finishPullDown(): void;
59 | openPullDown(config?: PullDownRefreshOptions): void;
60 | closePullDown(): void;
61 | autoPullDownRefresh(): void;
62 | }
63 | export {};
64 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/dist/types/propertiesConfig.d.ts:
--------------------------------------------------------------------------------
1 | declare const _default: {
2 | key: string;
3 | sourceKey: string;
4 | }[];
5 | export default _default;
6 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_from": "@better-scroll/pull-down",
3 | "_id": "@better-scroll/pull-down@2.4.2",
4 | "_inBundle": false,
5 | "_integrity": "sha512-bqMLk33o4oesTXIIOteBKHQgfVKjIVvity39TM/MfzkbY1WDBxD+HFS7ySgoqw7Kl2Wiv/U76Wfqzmm6yDdg7Q==",
6 | "_location": "/@better-scroll/pull-down",
7 | "_phantomChildren": {},
8 | "_requested": {
9 | "type": "tag",
10 | "registry": true,
11 | "raw": "@better-scroll/pull-down",
12 | "name": "@better-scroll/pull-down",
13 | "escapedName": "@better-scroll%2fpull-down",
14 | "scope": "@better-scroll",
15 | "rawSpec": "",
16 | "saveSpec": null,
17 | "fetchSpec": "latest"
18 | },
19 | "_requiredBy": [
20 | "#USER",
21 | "/"
22 | ],
23 | "_resolved": "https://registry.npmjs.org/@better-scroll/pull-down/-/pull-down-2.4.2.tgz",
24 | "_shasum": "6b98b28bd73e9b694b0857a9c73879e70339cb96",
25 | "_spec": "@better-scroll/pull-down",
26 | "_where": "G:\\my-project\\uni-readPage\\uni_modules\\yingbing-ReadPage",
27 | "author": {
28 | "name": "jizhi",
29 | "email": "theniceangel@163.com"
30 | },
31 | "bugs": {
32 | "url": "https://github.com/ustbhuangyi/better-scroll/issues"
33 | },
34 | "bundleDependencies": false,
35 | "dependencies": {
36 | "@better-scroll/core": "^2.4.2"
37 | },
38 | "deprecated": false,
39 | "description": "pull down to refresh, behave likes App list refreshing",
40 | "gitHead": "c97e67ecf15e616d998e67aa4ce15a7c429691c3",
41 | "homepage": "https://github.com/ustbhuangyi/better-scroll",
42 | "keywords": [
43 | "scroll",
44 | "iscroll",
45 | "javascript",
46 | "typescript",
47 | "ios",
48 | "pull-down"
49 | ],
50 | "license": "MIT",
51 | "main": "dist/pull-down.min.js",
52 | "module": "dist/pull-down.esm.js",
53 | "name": "@better-scroll/pull-down",
54 | "publishConfig": {
55 | "access": "public"
56 | },
57 | "repository": {
58 | "type": "git",
59 | "url": "git+ssh://git@github.com/ustbhuangyi/better-scroll.git",
60 | "directory": "packages/pull-down"
61 | },
62 | "typings": "dist/types/index.d.ts",
63 | "version": "2.4.2"
64 | }
65 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/src/propertiesConfig.ts:
--------------------------------------------------------------------------------
1 | const sourcePrefix = 'plugins.pullDownRefresh'
2 |
3 | const propertiesMap = [
4 | {
5 | key: 'finishPullDown',
6 | name: 'finishPullDown'
7 | },
8 | {
9 | key: 'openPullDown',
10 | name: 'openPullDown'
11 | },
12 | {
13 | key: 'closePullDown',
14 | name: 'closePullDown'
15 | },
16 | {
17 | key: 'autoPullDownRefresh',
18 | name: 'autoPullDownRefresh'
19 | }
20 | ]
21 |
22 | export default propertiesMap.map(item => {
23 | return {
24 | key: item.key,
25 | sourceKey: `${sourcePrefix}.${item.name}`
26 | }
27 | })
28 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 HuangYi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/README.md:
--------------------------------------------------------------------------------
1 | # @better-scroll/pull-up
2 |
3 | [中文文档](https://github.com/ustbhuangyi/better-scroll/blob/master/packages/pull-up/README_zh-CN.md)
4 |
5 | The ability to inject a pull-up load for BetterScroll.
6 |
7 | ## Usage
8 |
9 | ```js
10 | import BScroll from '@better-scroll/core'
11 | import PullUp from '@better-scroll/pull-up'
12 | BScroll.use(PullUp)
13 |
14 | const bs = new BScroll('.wrapper', {
15 | pullUpLoad: true
16 | })
17 | ```
18 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/README_zh-CN.md:
--------------------------------------------------------------------------------
1 | # @better-scroll/pull-up
2 |
3 | 为 BetterScroll 注入上拉加载的能力。
4 |
5 | ## 使用
6 |
7 | ```js
8 | import BScroll from '@better-scroll/core'
9 | import Pullup from '@better-scroll/pull-up'
10 | BScroll.use(Pullup)
11 |
12 | const bs = new BScroll('.wrapper', {
13 | pullUpLoad: true
14 | })
15 | ```
16 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/dist/pull-up.min.js:
--------------------------------------------------------------------------------
1 | !function(t,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(t="undefined"!=typeof globalThis?globalThis:t||self).PullUp=o()}(this,function(){"use strict";var n="undefined"!=typeof window,o=n&&navigator.userAgent.toLowerCase();o&&/wechatdevtools/.test(o),o&&o.indexOf("android"),function(){if("string"==typeof o){var t=/os (\d\d?_\d(_\d)?)/.exec(o);if(!t)return;t=t[1].split("_").map(function(t){return parseInt(t,10)});13===t[0]&&t[1]}}();if(n)try{var t={};Object.defineProperty(t,"passive",{get:function(){}}),window.addEventListener("test-passive",function(){},t)}catch(t){}var s=n&&document.createElement("div").style,i=function(){if(!n)return!1;for(var t=0,o=[{key:"standard",value:"transform"},{key:"webkit",value:"webkitTransform"},{key:"Moz",value:"MozTransform"},{key:"O",value:"OTransform"},{key:"ms",value:"msTransform"}];t | true;
3 | export interface PullUpLoadConfig {
4 | threshold: number;
5 | }
6 | declare module '@better-scroll/core' {
7 | interface CustomOptions {
8 | pullUpLoad?: PullUpLoadOptions;
9 | }
10 | interface CustomAPI {
11 | pullUpLoad: PluginAPI;
12 | }
13 | }
14 | interface PluginAPI {
15 | finishPullUp(): void;
16 | openPullUp(config?: PullUpLoadOptions): void;
17 | closePullUp(): void;
18 | autoPullUpLoad(): void;
19 | }
20 | export default class PullUp implements PluginAPI {
21 | scroll: BScroll;
22 | static pluginName: string;
23 | private hooksFn;
24 | pulling: boolean;
25 | watching: boolean;
26 | options: PullUpLoadConfig;
27 | constructor(scroll: BScroll);
28 | private init;
29 | private handleBScroll;
30 | private handleOptions;
31 | private handleHooks;
32 | private registerHooks;
33 | private watch;
34 | private unwatch;
35 | private checkPullUp;
36 | finishPullUp(): void;
37 | openPullUp(config?: PullUpLoadOptions): void;
38 | closePullUp(): void;
39 | autoPullUpLoad(): void;
40 | }
41 | export {};
42 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/dist/types/propertiesConfig.d.ts:
--------------------------------------------------------------------------------
1 | declare const _default: {
2 | key: string;
3 | sourceKey: string;
4 | }[];
5 | export default _default;
6 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_from": "@better-scroll/pull-up",
3 | "_id": "@better-scroll/pull-up@2.4.2",
4 | "_inBundle": false,
5 | "_integrity": "sha512-07Cke3oa96lN9/inxJZ0ixh0nBbbqxOi2IKcBGtD6dP+susiMcdhgd/c7zNRjXkwlw0vzTNfXTgExIOEWzLHYg==",
6 | "_location": "/@better-scroll/pull-up",
7 | "_phantomChildren": {},
8 | "_requested": {
9 | "type": "tag",
10 | "registry": true,
11 | "raw": "@better-scroll/pull-up",
12 | "name": "@better-scroll/pull-up",
13 | "escapedName": "@better-scroll%2fpull-up",
14 | "scope": "@better-scroll",
15 | "rawSpec": "",
16 | "saveSpec": null,
17 | "fetchSpec": "latest"
18 | },
19 | "_requiredBy": [
20 | "#USER",
21 | "/"
22 | ],
23 | "_resolved": "https://registry.npmjs.org/@better-scroll/pull-up/-/pull-up-2.4.2.tgz",
24 | "_shasum": "25357ceef7bac7520930f0631896b63a10f82a6f",
25 | "_spec": "@better-scroll/pull-up",
26 | "_where": "G:\\my-project\\uni-readPage\\uni_modules\\yingbing-ReadPage",
27 | "author": {
28 | "name": "jizhi",
29 | "email": "theniceangel@163.com"
30 | },
31 | "bugs": {
32 | "url": "https://github.com/ustbhuangyi/better-scroll/issues"
33 | },
34 | "bundleDependencies": false,
35 | "dependencies": {
36 | "@better-scroll/core": "^2.4.2"
37 | },
38 | "deprecated": false,
39 | "description": "pull up to load more data",
40 | "gitHead": "c97e67ecf15e616d998e67aa4ce15a7c429691c3",
41 | "homepage": "https://github.com/ustbhuangyi/better-scroll",
42 | "keywords": [
43 | "scroll",
44 | "iscroll",
45 | "javascript",
46 | "typescript",
47 | "ios",
48 | "pull-up"
49 | ],
50 | "main": "dist/pull-up.min.js",
51 | "module": "dist/pull-up.esm.js",
52 | "name": "@better-scroll/pull-up",
53 | "publishConfig": {
54 | "access": "public"
55 | },
56 | "repository": {
57 | "type": "git",
58 | "url": "git+ssh://git@github.com/ustbhuangyi/better-scroll.git",
59 | "directory": "packages/pull-up"
60 | },
61 | "typings": "dist/types/index.d.ts",
62 | "version": "2.4.2"
63 | }
64 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/src/index.ts:
--------------------------------------------------------------------------------
1 | import BScroll, { Boundary } from '@better-scroll/core'
2 | import {
3 | Probe,
4 | Direction,
5 | extend,
6 | EventEmitter,
7 | } from '@better-scroll/shared-utils'
8 | import propertiesConfig from './propertiesConfig'
9 |
10 | export type PullUpLoadOptions = Partial | true
11 | export interface PullUpLoadConfig {
12 | threshold: number
13 | }
14 |
15 | declare module '@better-scroll/core' {
16 | interface CustomOptions {
17 | pullUpLoad?: PullUpLoadOptions
18 | }
19 | interface CustomAPI {
20 | pullUpLoad: PluginAPI
21 | }
22 | }
23 | interface PluginAPI {
24 | finishPullUp(): void
25 | openPullUp(config?: PullUpLoadOptions): void
26 | closePullUp(): void
27 | autoPullUpLoad(): void
28 | }
29 |
30 | const PULL_UP_HOOKS_NAME = 'pullingUp'
31 |
32 | export default class PullUp implements PluginAPI {
33 | static pluginName = 'pullUpLoad'
34 | private hooksFn: Array<[EventEmitter, string, Function]>
35 | pulling: boolean = false
36 | watching: boolean = false
37 | options: PullUpLoadConfig
38 | constructor(public scroll: BScroll) {
39 | this.init()
40 | }
41 |
42 | private init() {
43 | this.handleBScroll()
44 |
45 | this.handleOptions(this.scroll.options.pullUpLoad)
46 |
47 | this.handleHooks()
48 |
49 | this.watch()
50 | }
51 |
52 | private handleBScroll() {
53 | this.scroll.registerType([PULL_UP_HOOKS_NAME])
54 |
55 | this.scroll.proxy(propertiesConfig)
56 | }
57 |
58 | private handleOptions(userOptions: PullUpLoadOptions = {}) {
59 | userOptions = (userOptions === true ? {} : userOptions) as Partial<
60 | PullUpLoadConfig
61 | >
62 | const defaultOptions: PullUpLoadConfig = {
63 | threshold: 0,
64 | }
65 | this.options = extend(defaultOptions, userOptions)
66 |
67 | this.scroll.options.probeType = Probe.Realtime
68 | }
69 |
70 | private handleHooks() {
71 | this.hooksFn = []
72 | const { scrollBehaviorY } = this.scroll.scroller
73 |
74 | this.registerHooks(
75 | this.scroll.hooks,
76 | this.scroll.hooks.eventTypes.contentChanged,
77 | () => {
78 | this.finishPullUp()
79 | }
80 | )
81 |
82 | this.registerHooks(
83 | scrollBehaviorY.hooks,
84 | scrollBehaviorY.hooks.eventTypes.computeBoundary,
85 | (boundary: Boundary) => {
86 | // content is smaller than wrapper
87 | if (boundary.maxScrollPos > 0) {
88 | // allow scrolling when content is not full of wrapper
89 | boundary.maxScrollPos = -1
90 | }
91 | }
92 | )
93 | }
94 |
95 | private registerHooks(hooks: EventEmitter, name: string, handler: Function) {
96 | hooks.on(name, handler, this)
97 | this.hooksFn.push([hooks, name, handler])
98 | }
99 |
100 | private watch() {
101 | if (this.watching) {
102 | return
103 | }
104 | this.watching = true
105 | this.registerHooks(
106 | this.scroll,
107 | this.scroll.eventTypes.scroll,
108 | this.checkPullUp
109 | )
110 | }
111 |
112 | private unwatch() {
113 | this.watching = false
114 | this.scroll.off(this.scroll.eventTypes.scroll, this.checkPullUp)
115 | }
116 |
117 | private checkPullUp(pos: { x: number; y: number }) {
118 | const { threshold } = this.options
119 |
120 | if (
121 | this.scroll.movingDirectionY === Direction.Positive &&
122 | pos.y <= this.scroll.maxScrollY + threshold
123 | ) {
124 | this.pulling = true
125 | // must reset pulling after scrollEnd
126 | this.scroll.once(this.scroll.eventTypes.scrollEnd, () => {
127 | this.pulling = false
128 | })
129 | this.unwatch()
130 | this.scroll.trigger(PULL_UP_HOOKS_NAME)
131 | }
132 | }
133 |
134 | finishPullUp() {
135 | // reset Direction, fix #936
136 | this.scroll.scroller.scrollBehaviorY.setMovingDirection(Direction.Default)
137 | if (this.pulling) {
138 | this.scroll.once(this.scroll.eventTypes.scrollEnd, () => {
139 | this.watch()
140 | })
141 | } else {
142 | this.watch()
143 | }
144 | }
145 |
146 | // allow 'true' type is compat for beta version implements
147 | openPullUp(config: PullUpLoadOptions = {}) {
148 | this.handleOptions(config)
149 | this.watch()
150 | }
151 |
152 | closePullUp() {
153 | this.unwatch()
154 | }
155 |
156 | autoPullUpLoad() {
157 | const { threshold } = this.options
158 | const { scrollBehaviorY } = this.scroll.scroller
159 |
160 | if (this.pulling || !this.watching) {
161 | return
162 | }
163 |
164 | // simulate a pullUp action
165 | const NEGATIVE_VALUE = -1
166 | const outOfBoundaryPos =
167 | scrollBehaviorY.maxScrollPos + threshold + NEGATIVE_VALUE
168 | this.scroll.scroller.scrollBehaviorY.setMovingDirection(NEGATIVE_VALUE)
169 | this.scroll.scrollTo(
170 | this.scroll.x,
171 | outOfBoundaryPos,
172 | this.scroll.options.bounceTime
173 | )
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/src/propertiesConfig.ts:
--------------------------------------------------------------------------------
1 | const sourcePrefix = 'plugins.pullUpLoad'
2 |
3 | const propertiesMap = [
4 | {
5 | key: 'finishPullUp',
6 | name: 'finishPullUp'
7 | },
8 | {
9 | key: 'openPullUp',
10 | name: 'openPullUp'
11 | },
12 | {
13 | key: 'closePullUp',
14 | name: 'closePullUp'
15 | },
16 | {
17 | key: 'autoPullUpLoad',
18 | name: 'autoPullUpLoad'
19 | }
20 | ]
21 |
22 | export default propertiesMap.map(item => {
23 | return {
24 | key: item.key,
25 | sourceKey: `${sourcePrefix}.${item.name}`
26 | }
27 | })
28 |
--------------------------------------------------------------------------------
/uni_modules/yingbing-ReadPage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "yingbing-ReadPage",
3 | "displayName": "小说阅读分页插件",
4 | "version": "1.2.4",
5 | "description": "给小说分页的插件,包含翻页",
6 | "keywords": [
7 | "小说",
8 | "阅读",
9 | "翻页",
10 | "分页"
11 | ],
12 | "repository": "https://github.com/yingbing-developer/uni-readPage.git",
13 | "engines": {
14 | "HBuilderX": "^3.1.0"
15 | },
16 | "dcloudext": {
17 | "category": [
18 | "前端组件",
19 | "通用组件"
20 | ],
21 | "sale": {
22 | "regular": {
23 | "price": "0.00"
24 | },
25 | "sourcecode": {
26 | "price": "0.00"
27 | }
28 | },
29 | "contact": {
30 | "qq": "1014295211"
31 | },
32 | "declaration": {
33 | "ads": "无",
34 | "data": "无",
35 | "permissions": "无"
36 | },
37 | "npmurl": ""
38 | },
39 | "uni_modules": {
40 | "dependencies": [],
41 | "encrypt": [],
42 | "platforms": {
43 | "cloud": {
44 | "tcb": "y",
45 | "aliyun": "y"
46 | },
47 | "client": {
48 | "App": {
49 | "app-vue": "y",
50 | "app-nvue": "n"
51 | },
52 | "H5-mobile": {
53 | "Safari": "u",
54 | "Android Browser": "y",
55 | "微信浏览器(Android)": "y",
56 | "QQ浏览器(Android)": "y"
57 | },
58 | "H5-pc": {
59 | "Chrome": "n",
60 | "IE": "n",
61 | "Edge": "n",
62 | "Firefox": "n",
63 | "Safari": "n"
64 | },
65 | "小程序": {
66 | "微信": "n",
67 | "阿里": "n",
68 | "百度": "n",
69 | "字节跳动": "n",
70 | "QQ": "n"
71 | },
72 | "快应用": {
73 | "华为": "u",
74 | "联盟": "u"
75 | },
76 | "Vue": {
77 | "vue2": "y",
78 | "vue3": "u"
79 | }
80 | }
81 | }
82 | },
83 | "dependencies": {
84 | "@better-scroll/core": "^2.4.2",
85 | "@better-scroll/infinity": "^2.4.2",
86 | "@better-scroll/pull-down": "^2.4.2",
87 | "@better-scroll/pull-up": "^2.4.2"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------