Showing
32 changed files
with
4731 additions
and
0 deletions
Too many changes to show.
To preserve performance only 32 of 737 files are displayed.
.gitignore
0 → 100644
app/AppSignature.jks
0 → 100644
No preview for this file type
app/build.gradle
0 → 100644
1 | +apply plugin: 'com.android.application' | |
2 | +apply plugin: 'android-aspectjx' | |
3 | +apply from: '../common.gradle' | |
4 | + | |
5 | +// Android 代码规范文档:https://github.com/getActivity/AndroidCodeStandard | |
6 | +android { | |
7 | + sourceSets { | |
8 | + main { | |
9 | + // res 资源目录配置 | |
10 | + jniLibs.srcDirs = ['src/main/libs'] | |
11 | + res.srcDirs( | |
12 | + 'src/main/res', | |
13 | + 'src/main/res-sw', | |
14 | + ) | |
15 | + } | |
16 | + } | |
17 | + // 资源目录存放指引:https://developer.android.google.cn/guide/topics/resources/providing-resources | |
18 | + defaultConfig { | |
19 | + | |
20 | + // 无痛修改包名:https://www.jianshu.com/p/17327e191d2e | |
21 | + applicationId 'com.studymachine.www' | |
22 | + | |
23 | + // 仅保留中文语种的资源 | |
24 | + resConfigs 'zh' | |
25 | + | |
26 | + // 仅保留 xxhdpi 图片资源(目前主流分辨率 1920 * 1080) | |
27 | + resConfigs 'xxhdpi' | |
28 | + | |
29 | + // 混淆配置 | |
30 | + proguardFiles 'proguard-sdk.pro', 'proguard-app.pro' | |
31 | + | |
32 | + // 日志打印开关 | |
33 | + buildConfigField('boolean', 'LOG_ENABLE', '' + LOG_ENABLE + '') | |
34 | + // 测试包下的 BuglyId | |
35 | + buildConfigField('String', 'BUGLY_ID', '"' + BUGLY_ID + '"') | |
36 | + // 测试服务器的主机地址 | |
37 | + buildConfigField('String', 'HOST_URL', '"' + HOST_URL + '"') | |
38 | + // 测试oss服务器的主机地址 | |
39 | + buildConfigField('String', 'IMAGER_HOST_URL', '"' + IMAGER_HOST_URL + '"') | |
40 | + // 测试web的主机地址 | |
41 | + buildConfigField('String', 'WEB_HOST_URL', '"' + WEB_HOST_URL + '"') | |
42 | + | |
43 | + | |
44 | + javaCompileOptions { | |
45 | + annotationProcessorOptions { | |
46 | + // EventBus Apt 索引类生成位置 | |
47 | + arguments = [eventBusIndex: applicationId + '.MyEventBusIndex'] | |
48 | + } | |
49 | + } | |
50 | + } | |
51 | + | |
52 | + // Apk 签名的那些事:https://www.jianshu.com/p/a1f8e5896aa2 | |
53 | + signingConfigs { | |
54 | + config { | |
55 | + storeFile file(StoreFile) | |
56 | + storePassword StorePassword | |
57 | + keyAlias KeyAlias | |
58 | + keyPassword KeyPassword | |
59 | + v1SigningEnabled true | |
60 | + v2SigningEnabled true | |
61 | + } | |
62 | + release { | |
63 | + storeFile file(StoreFile) | |
64 | + storePassword StorePassword | |
65 | + keyAlias KeyAlias | |
66 | + keyPassword KeyPassword | |
67 | + v1SigningEnabled true | |
68 | + v2SigningEnabled false | |
69 | + } | |
70 | + } | |
71 | + | |
72 | + // 构建配置:https://developer.android.google.cn/studio/build/build-variants | |
73 | + buildTypes { | |
74 | + | |
75 | + debug { | |
76 | + // 给包名添加后缀 | |
77 | + applicationIdSuffix '.debug' | |
78 | + // 调试模式开关 | |
79 | + debuggable true | |
80 | + jniDebuggable true | |
81 | + // 压缩对齐开关 | |
82 | + zipAlignEnabled false | |
83 | + // 移除无用的资源 | |
84 | + shrinkResources false | |
85 | + // 代码混淆开关 | |
86 | + minifyEnabled false | |
87 | + // 签名信息配置 | |
88 | + signingConfig signingConfigs.config | |
89 | + // 添加清单占位符 | |
90 | + addManifestPlaceholders([ | |
91 | + 'app_name': '未来猫 Debug 版' | |
92 | + ]) | |
93 | + // 调试模式下只保留一种架构的 so 库,提升打包速度 | |
94 | + ndk { | |
95 | + abiFilters 'armeabi-v7a' | |
96 | + } | |
97 | + } | |
98 | + | |
99 | + preview.initWith(debug) | |
100 | + preview { | |
101 | + applicationIdSuffix '' | |
102 | + // 添加清单占位符 | |
103 | + addManifestPlaceholders([ | |
104 | + 'app_name': '@string/app_name' | |
105 | + ]) | |
106 | + } | |
107 | + | |
108 | + release { | |
109 | + // 调试模式开关 | |
110 | + debuggable false | |
111 | + jniDebuggable false | |
112 | + // 压缩对齐开关 | |
113 | + zipAlignEnabled true | |
114 | + // 移除无用的资源 | |
115 | + shrinkResources true | |
116 | + // 代码混淆开关 | |
117 | + minifyEnabled true | |
118 | + // 签名信息配置 | |
119 | + signingConfig signingConfigs.release | |
120 | + // 添加清单占位符 | |
121 | + addManifestPlaceholders([ | |
122 | + 'app_name': '@string/app_name' | |
123 | + ]) | |
124 | + // 仅保留两种架构的 so 库,根据 Bugly 统计得出 | |
125 | + ndk { | |
126 | + // armeabi:万金油架构平台(占用率:0%) | |
127 | + // armeabi-v7a:曾经主流的架构平台(占用率:10%) | |
128 | + // arm64-v8a:目前主流架构平台(占用率:95%) | |
129 | + abiFilters 'armeabi-v7a' | |
130 | +// , 'arm64-v8a' 因为swf的原因 不能保留 | |
131 | + } | |
132 | + } | |
133 | + } | |
134 | + | |
135 | + packagingOptions { | |
136 | + // 剔除这个包下的所有文件(不会移除签名信息) | |
137 | + exclude 'META-INF/*******' | |
138 | + } | |
139 | + | |
140 | + // AOP 配置(exclude 和 include 二选一) | |
141 | + // 需要进行配置,否则就会引发冲突,具体表现为: | |
142 | + // 第一种:编译不过去,报错:java.util.zip.ZipException:Cause: zip file is empty | |
143 | + // 第二种:编译能过去,但运行时报错:ClassNotFoundException: Didn't find class on path: DexPathList | |
144 | + aspectjx { | |
145 | + // 排除一些第三方库的包名(Gson、 LeakCanary 和 AOP 有冲突) | |
146 | + // exclude 'androidx', 'com.google', 'com.squareup', 'org.apache', 'com.alipay', 'com.taobao', 'versions.9' | |
147 | + // 只对以下包名做 AOP 处理 | |
148 | + include android.defaultConfig.applicationId | |
149 | + } | |
150 | + | |
151 | + applicationVariants.all { variant -> | |
152 | + // apk 输出文件名配置 | |
153 | + variant.outputs.all { output -> | |
154 | + outputFileName = rootProject.getName() + '_v' + variant.versionName + '_' + variant.buildType.name | |
155 | + if (variant.buildType.name == buildTypes.release.getName()) { | |
156 | + outputFileName += '_' + new Date().format('MMdd') | |
157 | + } | |
158 | + outputFileName += '.apk' | |
159 | + } | |
160 | + } | |
161 | +} | |
162 | + | |
163 | +// 添加构建依赖项:https://developer.android.google.cn/studio/build/dependencies | |
164 | +// api 与 implementation 的区别:https://www.jianshu.com/p/8962d6ba936e | |
165 | +dependencies { | |
166 | + // 基类封装 | |
167 | + implementation project(':library:base') | |
168 | + // 控件封装 | |
169 | + implementation project(':library:widget') | |
170 | + // 友盟封装 | |
171 | + implementation project(':library:umeng') | |
172 | + | |
173 | + // 依赖 libs 目录下所有的 jar 和 aar 包 | |
174 | + implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') | |
175 | + | |
176 | + | |
177 | + //ZXing的精简极速版 https://github.com/jenly1314/ZXingLite | |
178 | + implementation 'com.github.jenly1314:zxing-lite:2.1.1' | |
179 | + | |
180 | + // 快速实现新手引导层的库 https://github.com/huburt-Hu/NewbieGuide | |
181 | + implementation 'com.github.huburt-Hu:NewbieGuide:v2.4.0' | |
182 | + | |
183 | + //日历 https://github.com/huanghaibin-dev/CalendarView | |
184 | + implementation 'com.haibin:calendarview:3.7.1' | |
185 | + | |
186 | + //XPopup:https://github.com/li-xiaojun/XPopup | |
187 | + implementation 'com.github.li-xiaojun:XPopup:2.7.6' | |
188 | + | |
189 | + //官方的flex布局控件 | |
190 | + implementation 'com.google.android:flexbox:1.0.0' | |
191 | + | |
192 | + // 权限请求框架:https://github.com/getActivity/XXPermissions | |
193 | + implementation 'com.github.getActivity:XXPermissions:12.3' | |
194 | + | |
195 | + // 标题栏框架:https://github.com/getActivity/TitleBar | |
196 | + implementation 'com.github.getActivity:TitleBar:9.2' | |
197 | + | |
198 | + // 吐司框架:https://github.com/getActivity/ToastUtils | |
199 | + implementation 'com.github.getActivity:ToastUtils:9.5' | |
200 | + | |
201 | + // 网络请求框架:https://github.com/getActivity/EasyHttp | |
202 | + implementation 'com.github.getActivity:EasyHttp:10.2' | |
203 | + // OkHttp 框架:https://github.com/square/okhttp | |
204 | + // noinspection GradleDependency | |
205 | + implementation 'com.squareup.okhttp3:okhttp:3.12.13' | |
206 | + | |
207 | + // Json 解析框架:https://github.com/google/gson | |
208 | + implementation 'com.google.code.gson:gson:2.8.8' | |
209 | + // Gson 解析容错:https://github.com/getActivity/GsonFactory | |
210 | + implementation 'com.github.getActivity:GsonFactory:5.2' | |
211 | + | |
212 | + // Shape 框架:https://github.com/getActivity/ShapeView | |
213 | + implementation 'com.github.getActivity:ShapeView:6.0' | |
214 | + | |
215 | + // AOP 插件库:https://mvnrepository.com/artifact/org.aspectj/aspectjrt | |
216 | + implementation 'org.aspectj:aspectjrt:1.9.6' | |
217 | + | |
218 | + // 图片加载框架:https://github.com/bumptech/glide | |
219 | + // 官方使用文档:https://github.com/Muyangmin/glide-docs-cn | |
220 | + implementation 'com.github.bumptech.glide:glide:4.12.0' | |
221 | + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' | |
222 | + | |
223 | + // 沉浸式框架:https://github.com/gyf-dev/ImmersionBar | |
224 | + implementation 'com.gyf.immersionbar:immersionbar:3.0.0' | |
225 | + | |
226 | + // 手势 ImageView:https://github.com/Baseflow/PhotoView | |
227 | + implementation 'com.github.Baseflow:PhotoView:2.3.0' | |
228 | + | |
229 | + // Bugly 异常捕捉:https://bugly.qq.com/docs/user-guide/instruction-manual-android/?v=20190418140644 | |
230 | + implementation 'com.tencent.bugly:crashreport:3.4.4' | |
231 | + implementation 'com.tencent.bugly:nativecrashreport:3.9.2' | |
232 | + | |
233 | + // 动画解析库:https://github.com/airbnb/lottie-android | |
234 | + // 动画资源:https://lottiefiles.com、https://icons8.com/animated-icons | |
235 | + implementation 'com.airbnb.android:lottie:4.1.0' | |
236 | + | |
237 | + // 上拉刷新下拉加载框架:https://github.com/scwang90/SmartRefreshLayout | |
238 | + implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' | |
239 | + implementation 'com.scwang.smart:refresh-header-material:2.0.3' | |
240 | + | |
241 | + // 日志打印框架:https://github.com/JakeWharton/timber | |
242 | + implementation 'com.jakewharton.timber:timber:4.7.1' | |
243 | + | |
244 | + // 指示器框架:https://github.com/ongakuer/CircleIndicator | |
245 | + implementation 'me.relex:circleindicator:2.1.6' | |
246 | + | |
247 | + // 腾讯 MMKV:https://github.com/Tencent/MMKV | |
248 | + implementation 'com.tencent:mmkv-static:1.2.10' | |
249 | + | |
250 | + // 内存泄漏监测框架:https://github.com/square/leakcanary | |
251 | + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7' | |
252 | + previewImplementation 'com.squareup.leakcanary:leakcanary-android:2.7' | |
253 | + // 工具类:https://github.com/Blankj/AndroidUtilCode | |
254 | + implementation 'com.blankj:utilcodex:1.31.0' | |
255 | + //eventbus:https://github.com/greenrobot/EventBus | |
256 | + implementation 'org.greenrobot:eventbus:3.1.1' | |
257 | + annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1' | |
258 | + //轮播图:https://github.com/youth5201314/banner | |
259 | + implementation 'io.github.youth5201314:banner:2.2.1' | |
260 | + // 轮播图:https://github.com/bingoogolapple/BGABanner-Android | |
261 | + // 多语种:https://github.com/getActivity/MultiLanguages | |
262 | + // 悬浮窗:https://github.com/getActivity/XToast | |
263 | + // 日志输出:https://github.com/getActivity/Logcat | |
264 | + // 工具类:https://github.com/Blankj/AndroidUtilCode | |
265 | + // 二维码:https://github.com/bingoogolapple/BGAQRCode-Android | |
266 | + // 跑马灯:https://github.com/sunfusheng/MarqueeView | |
267 | + // 对象注解:https://www.jianshu.com/p/f1f888e4a35f | |
268 | + // 对象存储:https://github.com/leavesC/DoKV | |
269 | + // 多渠道打包:https://github.com/Meituan-Dianping/walle | |
270 | + // 设备唯一标识:http://msa-alliance.cn/col.jsp?id=120 | |
271 | + // 嵌套滚动容器:https://github.com/donkingliang/ConsecutiveScroller | |
272 | + // 隐私调用监控:https://github.com/huage2580/PermissionMonitor | |
273 | + //RKGlassDevice Glass 设备管理模块 | |
274 | + implementation 'com.rokid.axr:glassdevice-phone:1.0.4' | |
275 | +} | |
\ No newline at end of file | ... | ... |
app/gradle.properties
0 → 100644
app/libs/classes.jar
0 → 100644
No preview for this file type
No preview for this file type
app/proguard-app.pro
0 → 100644
1 | +# 忽略警告 | |
2 | +#-ignorewarning | |
3 | + | |
4 | +# 混淆保护自己项目的部分代码以及引用的第三方jar包 | |
5 | +#-libraryjars libs/xxxxxxxxx.jar | |
6 | + | |
7 | +#swf播放器 | |
8 | +-libraryjars libs/classes.jar | |
9 | +-keep public class softboy.swfplayer.FileUtils {*;} | |
10 | +-keep public class air.com.adobe.appentry.AppEntry {*;} | |
11 | +-keep class a.a.a.a** {*;} | |
12 | +-keep class air.com.** {*;} | |
13 | +-keep class android.arch.** {*;} | |
14 | +-keep class b.** {*;} | |
15 | +-keep class c.** {*;} | |
16 | +-keep class com.a.** {*;} | |
17 | +-keep class com.adobe.** {*;} | |
18 | +-keep class com.adobe.air** {*;} | |
19 | +-keep class com.android.** {*;} | |
20 | +-keep class b.a.** {*;} | |
21 | + | |
22 | +# 不混淆这个包下的类 | |
23 | +-keep class com.studymachine.www.http.api.** { | |
24 | + <fields>; | |
25 | +} | |
26 | +-keep class com.studymachine.www.http.response.** { | |
27 | + <fields>; | |
28 | +} | |
29 | +-keep class com.studymachine.www.http.model.** { | |
30 | + <fields>; | |
31 | +} | |
32 | +-keep class com.studymachine.www.domain.** { | |
33 | + <fields>; | |
34 | +} | |
35 | + | |
36 | +# 不混淆被 Log 注解的方法信息 | |
37 | +-keepclassmembernames class ** { | |
38 | + @com.studymachine.www.aop.Log <methods>; | |
39 | +} | |
\ No newline at end of file | ... | ... |
app/proguard-sdk.pro
0 → 100644
1 | +# Glide | |
2 | +-keep public class * implements com.bumptech.glide.module.GlideModule | |
3 | +-keep class * extends com.bumptech.glide.module.AppGlideModule { | |
4 | + <init>(...); | |
5 | +} | |
6 | +-keep public enum com.bumptech.glide.load.ImageHeaderParser$** { | |
7 | + **[] $VALUES; | |
8 | + public *; | |
9 | +} | |
10 | +-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder { | |
11 | + *** rewind(); | |
12 | +} | |
13 | + | |
14 | +# for DexGuard only | |
15 | +#-keepresourcexmlelements manifest/application/meta-data@value=GlideModule | |
16 | + | |
17 | +# Bugly | |
18 | +-dontwarn com.tencent.bugly.** | |
19 | +-keep public class com.tencent.bugly.**{*;} | |
20 | + | |
21 | +# AOP | |
22 | +-adaptclassstrings | |
23 | +-keepattributes InnerClasses, EnclosingMethod, Signature, *Annotation* | |
24 | + | |
25 | +-keepnames @org.aspectj.lang.annotation.Aspect class * { | |
26 | + public <methods>; | |
27 | +} | |
28 | + | |
29 | +# EventBus | |
30 | +-keepattributes *Annotation* | |
31 | +-keepclassmembers class ** { | |
32 | + @org.greenrobot.eventbus.Subscribe <methods>; | |
33 | +} | |
34 | +-keep enum org.greenrobot.eventbus.ThreadMode { *; } | |
35 | + | |
36 | +# OkHttp3 | |
37 | +-keepattributes Signature | |
38 | +-keepattributes *Annotation* | |
39 | +-keep class okhttp3.** { *; } | |
40 | +-keep interface okhttp3.** { *; } | |
41 | +-dontwarn okhttp3.** | |
42 | +-dontwarn okio.** | |
43 | +-dontwarn org.conscrypt.** | |
44 | + | |
45 | +#腾讯x5 | |
46 | +-dontwarn dalvik.** | |
47 | +-dontwarn com.tencent.smtt.** | |
48 | + | |
49 | +-keep class com.tencent.smtt.** { | |
50 | + *; | |
51 | +} | |
52 | + | |
53 | +-keep class com.tencent.tbs.** { | |
54 | + *; | |
55 | +} | |
56 | + | |
57 | +#日历 | |
58 | +-keepclasseswithmembers class * { | |
59 | + public <init>(android.content.Context); | |
60 | +} | |
61 | + | |
62 | +#swf播放器 | |
63 | +-libraryjars libs/classes.jar | |
64 | +-keep public class softboy.swfplayer.FileUtils {*;} | |
65 | +-keep public class air.com.adobe.appentry.AppEntry {*;} | |
66 | +-keep class a.a.a.a** {*;} | |
67 | +-keep class air.com.** {*;} | |
68 | +-keep class android.arch.** {*;} | |
69 | +-keep class b.** {*;} | |
70 | +-keep class c.** {*;} | |
71 | +-keep class com.a.** {*;} | |
72 | +-keep class com.adobe.** {*;} | |
73 | +-keep class com.android.** {*;} | |
74 | +-keep class b.a.** {*;} | |
\ No newline at end of file | ... | ... |
app/release/output-metadata.json
0 → 100644
1 | +{ | |
2 | + "version": 2, | |
3 | + "artifactType": { | |
4 | + "type": "APK", | |
5 | + "kind": "Directory" | |
6 | + }, | |
7 | + "applicationId": "com.studymachine.www", | |
8 | + "variantName": "processReleaseResources", | |
9 | + "elements": [ | |
10 | + { | |
11 | + "type": "SINGLE", | |
12 | + "filters": [], | |
13 | + "versionCode": 204, | |
14 | + "versionName": "2.0.4", | |
15 | + "outputFile": "StudyMachine_v2.0.4_release_0901.apk" | |
16 | + } | |
17 | + ] | |
18 | +} | |
\ No newline at end of file | ... | ... |
app/src/main/AndroidManifest.xml
0 → 100644
1 | +<?xml version="1.0" encoding="utf-8"?><!-- 清单文件合并指引:https://developer.android.google.cn/studio/build/manifest-merge?hl=zh-cn --> | |
2 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
3 | + xmlns:tools="http://schemas.android.com/tools" | |
4 | + package="com.studymachine.www"> | |
5 | + | |
6 | + <!-- 网络相关 --> | |
7 | + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | |
8 | + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> | |
9 | + <uses-permission android:name="android.permission.INTERNET" /> | |
10 | + | |
11 | + <!-- 外部存储 --> | |
12 | + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | |
13 | + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |
14 | + | |
15 | + <!-- 拍照权限 --> | |
16 | + <uses-permission android:name="android.permission.CAMERA" /> | |
17 | + | |
18 | + <!-- 安装权限 --> | |
19 | + <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> | |
20 | + | |
21 | + <!-- 定位权限(用于 WebView 定位)--> | |
22 | + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> | |
23 | + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> | |
24 | + <uses-permission android:name= "android.permission.SYSTEM_ALERT_WINDOW" /> | |
25 | + <uses-permission android:name= "android.permission.SYSTEM_OVERLAY_WINDOW" /> | |
26 | + | |
27 | + <uses-permission android:name="android.permission.READ_PHONE_STATE" /> | |
28 | + <uses-feature android:name="android.hardware.usb.host" /> | |
29 | + | |
30 | + <!-- Application 节点详解:https://developer.android.google.cn/guide/topics/manifest/application-element --> | |
31 | + <!-- Activity 节点详解:https://developer.android.google.cn/guide/topics/manifest/activity-element --> | |
32 | + <application | |
33 | + android:name="com.studymachine.www.app.AppApplication" | |
34 | + android:allowBackup="false" | |
35 | + android:icon="@mipmap/launcher_ic" | |
36 | + android:label="${app_name}" | |
37 | + android:largeHeap="true" | |
38 | + android:networkSecurityConfig="@xml/network_security_config" | |
39 | + android:requestLegacyExternalStorage="true" | |
40 | + android:resizeableActivity="true" | |
41 | + android:roundIcon="@mipmap/launcher_ic" | |
42 | + android:supportsRtl="false" | |
43 | + android:theme="@style/AppTheme" | |
44 | + android:usesCleartextTraffic="true" | |
45 | + tools:ignore="AllowBackup,LockedOrientationActivity" | |
46 | + tools:replace="android:allowBackup,android:supportsRtl" | |
47 | + android:extractNativeLibs="true" | |
48 | + > | |
49 | + | |
50 | + <service | |
51 | + android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService" | |
52 | + android:label="dexopt" | |
53 | + android:process=":dexopt" /> | |
54 | + | |
55 | + <!-- 表示当前已经适配了分区存储 --> | |
56 | + <meta-data | |
57 | + android:name="ScopedStorage" | |
58 | + android:value="true" /> | |
59 | + | |
60 | + <!-- 适配 Android 7.0 文件意图 --> | |
61 | + <provider | |
62 | + android:name="androidx.core.content.FileProvider" | |
63 | + android:authorities="${applicationId}.provider" | |
64 | + android:exported="false" | |
65 | + android:grantUriPermissions="true"> | |
66 | + <meta-data | |
67 | + android:name="android.support.FILE_PROVIDER_PATHS" | |
68 | + android:resource="@xml/file_paths" /> | |
69 | + </provider> | |
70 | + | |
71 | + | |
72 | + <activity | |
73 | + android:name=".ui.activity.SwfActivity" | |
74 | + android:process=":flash" | |
75 | + android:screenOrientation="landscape" | |
76 | + android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> | |
77 | + <meta-data | |
78 | + android:name="namespaceVersion" | |
79 | + android:value="32" /> | |
80 | + <meta-data | |
81 | + android:name="autoOrients" | |
82 | + android:value="true" /> | |
83 | + <meta-data | |
84 | + android:name="fullScreen" | |
85 | + android:value="true" /> | |
86 | + <meta-data | |
87 | + android:name="initialcontent" | |
88 | + android:value="cached.swf" /> | |
89 | + <meta-data | |
90 | + android:name="containsVideo" | |
91 | + android:value="false" /> | |
92 | + <meta-data | |
93 | + android:name="embeddedFonts" | |
94 | + android:value="false" /> | |
95 | + <meta-data | |
96 | + android:name="webContentsDebuggingEnabled" | |
97 | + android:value="false" /> | |
98 | + <meta-data | |
99 | + android:name="disableMediaCodec" | |
100 | + android:value="false" /> | |
101 | + | |
102 | + <intent-filter> | |
103 | + <action android:name="android.intent.action.VIEW" /> | |
104 | + | |
105 | + <category android:name="android.intent.category.BROWSABLE" /> | |
106 | + <category android:name="android.intent.category.DEFAULT" /> | |
107 | + | |
108 | + <data android:scheme="com.softboy.flashairtest" /> | |
109 | + </intent-filter> | |
110 | + | |
111 | + </activity> | |
112 | + | |
113 | + | |
114 | + <!-- 闪屏页 --> | |
115 | + <activity | |
116 | + android:name="com.studymachine.www.ui.activity.SplashActivity" | |
117 | + android:launchMode="singleTop" | |
118 | + android:screenOrientation="landscape" | |
119 | + android:theme="@style/SplashTheme"> | |
120 | + <!-- 程序入口 --> | |
121 | + <intent-filter> | |
122 | + <action android:name="android.intent.action.MAIN" /> | |
123 | + <action android:name="android.intent.action.VIEW" /> | |
124 | + | |
125 | + <category android:name="android.intent.category.LAUNCHER" /> | |
126 | + </intent-filter> | |
127 | + </activity> | |
128 | + | |
129 | + <!-- 无网络页 --> | |
130 | + <activity | |
131 | + android:name="com.studymachine.www.ui.activity.NoNetworkActivity" | |
132 | + android:launchMode="singleTop" | |
133 | + android:screenOrientation="landscape" | |
134 | + android:theme="@style/TransparentTheme" /> | |
135 | + | |
136 | + <!-- 外置浏览器界面 --> | |
137 | + <activity | |
138 | + android:name="com.studymachine.www.ui.activity.ExternalBrowserActivity" | |
139 | + android:launchMode="singleTop" | |
140 | + android:screenOrientation="landscape" | |
141 | + android:theme="@style/TransparentTheme" /> | |
142 | + | |
143 | + <!-- 首页 --> | |
144 | + <activity | |
145 | + android:name="com.studymachine.www.ui.activity.HomeActivity" | |
146 | + android:launchMode="singleTask" | |
147 | + android:screenOrientation="landscape" | |
148 | + android:windowSoftInputMode="adjustPan" /> | |
149 | + | |
150 | + <!-- 学情档案详情 --> | |
151 | + <activity | |
152 | + android:name="com.studymachine.www.ui.activity.RecordDetailActivity" | |
153 | + android:launchMode="singleTask" | |
154 | + android:screenOrientation="landscape" | |
155 | + android:windowSoftInputMode="adjustPan" /> | |
156 | + <!-- 学情档案 --> | |
157 | + <activity | |
158 | + android:name="com.studymachine.www.ui.activity.RecordActivity" | |
159 | + android:launchMode="singleTask" | |
160 | + android:screenOrientation="landscape" | |
161 | + android:windowSoftInputMode="adjustPan" /> | |
162 | + | |
163 | + <!-- 知识竞技列表 --> | |
164 | + <activity | |
165 | + android:name="com.studymachine.www.ui.activity.ArenaListActivity" | |
166 | + android:launchMode="singleTask" | |
167 | + android:screenOrientation="landscape" | |
168 | + android:windowSoftInputMode="adjustPan" /> | |
169 | + | |
170 | + <!-- ai列表 --> | |
171 | + <activity | |
172 | + android:name="com.studymachine.www.ui.activity.AiListActivity" | |
173 | + android:launchMode="singleTask" | |
174 | + android:screenOrientation="landscape" | |
175 | + android:windowSoftInputMode="adjustPan" /> | |
176 | + | |
177 | + <!-- ai详情 --> | |
178 | + <activity | |
179 | + android:name="com.studymachine.www.ui.activity.AiDetailActivity" | |
180 | + android:configChanges="orientation|screenSize|keyboardHidden" | |
181 | + android:launchMode="singleTask" | |
182 | + android:screenOrientation="landscape" | |
183 | + android:windowSoftInputMode="adjustPan" /> | |
184 | + | |
185 | + <!-- 精准强化列表 --> | |
186 | + <activity | |
187 | + android:name="com.studymachine.www.ui.activity.AccurateListActivity" | |
188 | + android:launchMode="singleTask" | |
189 | + android:screenOrientation="landscape" | |
190 | + android:windowSoftInputMode="adjustPan" /> | |
191 | + | |
192 | + <!-- 精准强化详情 --> | |
193 | + <activity | |
194 | + android:name="com.studymachine.www.ui.activity.AccurateDetailActivity" | |
195 | + android:launchMode="singleTask" | |
196 | + android:screenOrientation="landscape" | |
197 | + android:windowSoftInputMode="adjustPan" /> | |
198 | + | |
199 | + <!-- 登录页 --> | |
200 | + <activity | |
201 | + android:name="com.studymachine.www.ui.activity.LoginActivity" | |
202 | + android:launchMode="singleTask" | |
203 | + android:screenOrientation="landscape" | |
204 | + android:windowSoftInputMode="stateHidden" /> | |
205 | + | |
206 | + <!-- 注册页 --> | |
207 | + <activity | |
208 | + android:name="com.studymachine.www.ui.activity.RegisterActivity" | |
209 | + android:launchMode="singleTop" | |
210 | + android:screenOrientation="landscape" | |
211 | + android:windowSoftInputMode="stateHidden" /> | |
212 | + <!-- 协议--> | |
213 | + <activity | |
214 | + android:name="com.studymachine.www.ui.activity.AgreementActivity" | |
215 | + android:launchMode="singleTop" | |
216 | + android:screenOrientation="landscape" | |
217 | + android:windowSoftInputMode="stateHidden" /> | |
218 | + <!-- 注册页 选择年级--> | |
219 | + <activity | |
220 | + android:name="com.studymachine.www.ui.activity.RegisterGradeActivity" | |
221 | + android:launchMode="singleTop" | |
222 | + android:screenOrientation="landscape" | |
223 | + android:windowSoftInputMode="stateHidden" /> | |
224 | + <!-- 注册页 选择教材--> | |
225 | + <activity | |
226 | + android:name="com.studymachine.www.ui.activity.RegisterTextbookActivity" | |
227 | + android:launchMode="singleTop" | |
228 | + android:screenOrientation="landscape" | |
229 | + android:windowSoftInputMode="stateHidden" /> | |
230 | + <!-- 注册页 公众号二维码--> | |
231 | + <activity | |
232 | + android:name="com.studymachine.www.ui.activity.RegisterWechatActivity" | |
233 | + android:launchMode="singleTop" | |
234 | + android:screenOrientation="landscape" | |
235 | + android:windowSoftInputMode="stateHidden" /> | |
236 | + <!-- 注册页 选择虚拟形象--> | |
237 | + <activity | |
238 | + android:name="com.studymachine.www.ui.activity.RegisterPersonActivity" | |
239 | + android:launchMode="singleTop" | |
240 | + android:screenOrientation="landscape" | |
241 | + android:windowSoftInputMode="stateHidden"> | |
242 | + | |
243 | + </activity> | |
244 | + <!-- 忘记密码 --> | |
245 | + <activity | |
246 | + android:name="com.studymachine.www.ui.activity.PasswordForgetActivity" | |
247 | + android:label="@string/password_forget_title" | |
248 | + android:launchMode="singleTop" | |
249 | + android:screenOrientation="landscape" | |
250 | + android:windowSoftInputMode="stateHidden" /> | |
251 | + <!-- 崩溃展示(必须在独立进程) --> | |
252 | + <activity | |
253 | + android:name="com.studymachine.www.ui.activity.CrashActivity" | |
254 | + android:launchMode="singleTop" | |
255 | + android:process=":crash" | |
256 | + android:screenOrientation="landscape" /> | |
257 | + | |
258 | + <!-- 重启应用(必须在独立进程) --> | |
259 | + <activity | |
260 | + android:name="com.studymachine.www.ui.activity.RestartActivity" | |
261 | + android:launchMode="singleTop" | |
262 | + android:process=":restart" /> | |
263 | + | |
264 | + <!-- 个人资料 --> | |
265 | + <activity | |
266 | + android:name="com.studymachine.www.ui.activity.PersonalCenterActivity" | |
267 | + android:launchMode="singleTop" | |
268 | + android:screenOrientation="landscape" /> | |
269 | + | |
270 | + <!-- 常见问题 --> | |
271 | + <activity | |
272 | + android:name="com.studymachine.www.ui.activity.CommonProblemActivity" | |
273 | + android:launchMode="singleTop" | |
274 | + android:screenOrientation="landscape" | |
275 | + android:theme="@style/TransparentTheme" /> | |
276 | + | |
277 | + <activity | |
278 | + android:name="com.studymachine.www.ui.activity.BrowserActivity" | |
279 | + android:launchMode="singleTop" | |
280 | + android:screenOrientation="landscape" /> | |
281 | + | |
282 | + <!-- 拍照选择 --> | |
283 | + <activity | |
284 | + android:name="com.studymachine.www.ui.activity.CameraActivity" | |
285 | + android:launchMode="singleTop" | |
286 | + android:screenOrientation="portrait" /> | |
287 | + | |
288 | + <!-- 图片裁剪 --> | |
289 | + <activity | |
290 | + android:name="com.studymachine.www.ui.activity.ImageCropActivity" | |
291 | + android:launchMode="singleTop" | |
292 | + android:screenOrientation="portrait" /> | |
293 | + | |
294 | + <!-- 图片选择 --> | |
295 | + <activity | |
296 | + android:name="com.studymachine.www.ui.activity.ImageSelectActivity" | |
297 | + android:label="@string/image_select_title" | |
298 | + android:launchMode="singleTop" | |
299 | + android:screenOrientation="portrait" /> | |
300 | + | |
301 | + <!-- 查看大图 --> | |
302 | + <activity | |
303 | + android:name="com.studymachine.www.ui.activity.ImagePreviewActivity" | |
304 | + android:launchMode="singleTop" | |
305 | + android:screenOrientation="portrait" /> | |
306 | + | |
307 | + <!-- 播放视频(自适应方向) --> | |
308 | + <activity | |
309 | + android:name="com.studymachine.www.ui.activity.VideoPlayActivity" | |
310 | + android:launchMode="singleTop" | |
311 | + android:theme="@style/FullScreenTheme" /> | |
312 | + | |
313 | + <!-- 播放视频(竖屏方向) --> | |
314 | + <activity | |
315 | + android:name="com.studymachine.www.ui.activity.VideoPlayActivity$Portrait" | |
316 | + android:launchMode="singleTop" | |
317 | + android:screenOrientation="portrait" | |
318 | + android:theme="@style/FullScreenTheme" /> | |
319 | + | |
320 | + <!-- 播放视频(横屏方向) --> | |
321 | + <activity | |
322 | + android:name="com.studymachine.www.ui.activity.VideoPlayActivity$Landscape" | |
323 | + android:launchMode="singleTop" | |
324 | + android:screenOrientation="landscape" | |
325 | + android:theme="@style/FullScreenTheme" /> | |
326 | + | |
327 | + <!-- 选择视频 --> | |
328 | + <activity | |
329 | + android:name="com.studymachine.www.ui.activity.VideoSelectActivity" | |
330 | + android:launchMode="singleTop" | |
331 | + android:screenOrientation="portrait" /> | |
332 | + | |
333 | + | |
334 | + <!-- 微信回调(请注意这个 Activity 放置的包名要和当前项目的包名保持一致,否则将不能正常回调) --> | |
335 | + <activity | |
336 | + android:name="com.studymachine.www.wxapi.WXEntryActivity" | |
337 | + android:configChanges="keyboardHidden|orientation|screenSize" | |
338 | + android:exported="true" | |
339 | + android:theme="@android:style/Theme.Translucent.NoTitleBar" /> | |
340 | + | |
341 | + </application> | |
342 | + | |
343 | + <!-- Android 11 软件包可见性适配:https://www.jianshu.com/p/d1ccd425c4ce --> | |
344 | + <queries> | |
345 | + <!-- 拍照意图:MediaStore.ACTION_IMAGE_CAPTURE --> | |
346 | + <intent> | |
347 | + <action android:name="android.media.action.IMAGE_CAPTURE" /> | |
348 | + </intent> | |
349 | + | |
350 | + <!-- 拍摄意图:MediaStore.ACTION_VIDEO_CAPTURE --> | |
351 | + <intent> | |
352 | + <action android:name="android.media.action.VIDEO_CAPTURE" /> | |
353 | + </intent> | |
354 | + | |
355 | + <!-- 图片裁剪意图 --> | |
356 | + <intent> | |
357 | + <action android:name="com.android.camera.action.CROP" /> | |
358 | + </intent> | |
359 | + | |
360 | + <!-- 打电话意图:Intent.ACTION_DIAL --> | |
361 | + <intent> | |
362 | + <action android:name="android.intent.action.DIAL" /> | |
363 | + </intent> | |
364 | + | |
365 | + <!-- 调起分享意图:Intent.ACTION_SEND --> | |
366 | + <intent> | |
367 | + <action android:name="android.intent.action.SEND" /> | |
368 | + </intent> | |
369 | + | |
370 | + <!-- 调起其他页面意图:Intent.ACTION_VIEW --> | |
371 | + <intent> | |
372 | + <action android:name="android.intent.action.VIEW" /> | |
373 | + </intent> | |
374 | + | |
375 | + <!-- 调起系统文件选择器:Intent.ACTION_GET_CONTENT --> | |
376 | + <intent> | |
377 | + <action android:name="android.intent.action.GET_CONTENT" /> | |
378 | + </intent> | |
379 | + </queries> | |
380 | + | |
381 | +</manifest> | |
\ No newline at end of file | ... | ... |
1 | +<?xml version="1.0" encoding="utf-8" standalone="no" ?> | |
2 | +<!-- | |
3 | + Usage: | |
4 | + | |
5 | + To localize the description, use the following format for the description element. | |
6 | + <description> | |
7 | + <text xml:lang="en">English App description goes here</text> | |
8 | + <text xml:lang="fr">French App description goes here</text> | |
9 | + <text xml:lang="ja">Japanese App description goes here</text> | |
10 | + </description> | |
11 | + | |
12 | + To localize the name, use the following format for the name element. | |
13 | + <name> | |
14 | + <text xml:lang="en">English App name goes here</text> | |
15 | + <text xml:lang="fr">French App name goes here</text> | |
16 | + <text xml:lang="ja">Japanese App name goes here</text> | |
17 | + </name> | |
18 | +--> | |
19 | +<application xmlns="http://ns.adobe.com/air/application/3.8"> | |
20 | + <id>issess</id> | |
21 | + <versionNumber>1.0.0</versionNumber> | |
22 | + <versionLabel>1.0.0</versionLabel> | |
23 | + <filename>cached</filename> | |
24 | + <description/> | |
25 | + <name>cached</name> | |
26 | + <copyright/> | |
27 | + <initialWindow> | |
28 | + <content>cached.swf</content> | |
29 | + <systemChrome>standard</systemChrome> | |
30 | + <transparent>false</transparent> | |
31 | + <visible>true</visible> | |
32 | + <fullScreen>true</fullScreen> | |
33 | + | |
34 | + <renderMode>gpu</renderMode> | |
35 | + <autoOrients>true</autoOrients></initialWindow> | |
36 | + <icon/> | |
37 | + <customUpdateUI>false</customUpdateUI> | |
38 | + <allowBrowserInvocation>false</allowBrowserInvocation> | |
39 | + <android> | |
40 | + <manifestAdditions><![CDATA[<manifest> | |
41 | +</manifest>]]></manifestAdditions> | |
42 | + </android> | |
43 | +</application> | |
\ No newline at end of file | ... | ... |
app/src/main/assets/cached.swf
0 → 100644
No preview for this file type
app/src/main/assets/index.html
0 → 100644
1 | +<!DOCTYPE html> | |
2 | +<html lang="en"> | |
3 | +<head> | |
4 | + <meta charset="UTF-8"/> | |
5 | + <title></title> | |
6 | +</head> | |
7 | +<link rel="stylesheet" href="./quill.bubble.css"> | |
8 | +<link rel="stylesheet" href="./quill.core.css"> | |
9 | +<link rel="stylesheet" href="./quill.snow.css"> | |
10 | +<body> | |
11 | +<div class="ql-editor" id="ql-editor" style="color:#FFF;"> | |
12 | +</div> | |
13 | +<script> | |
14 | + const data = studyMachine.getSingPageData() | |
15 | + const content = document.getElementById("ql-editor") | |
16 | + content.innerHTML = data | |
17 | +</script> | |
18 | +</body> | |
19 | +</html> | ... | ... |
app/src/main/assets/quill.bubble.css
0 → 100644
1 | +/*! | |
2 | + * Quill Editor v1.3.7 | |
3 | + * https://quilljs.com/ | |
4 | + * Copyright (c) 2014, Jason Chen | |
5 | + * Copyright (c) 2013, salesforce.com | |
6 | + */ | |
7 | +.ql-container { | |
8 | + box-sizing: border-box; | |
9 | + font-family: Helvetica, Arial, sans-serif; | |
10 | + font-size: 13px; | |
11 | + height: 100%; | |
12 | + margin: 0px; | |
13 | + position: relative; | |
14 | +} | |
15 | +.ql-container.ql-disabled .ql-tooltip { | |
16 | + visibility: hidden; | |
17 | +} | |
18 | +.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before { | |
19 | + pointer-events: none; | |
20 | +} | |
21 | +.ql-clipboard { | |
22 | + left: -100000px; | |
23 | + height: 1px; | |
24 | + overflow-y: hidden; | |
25 | + position: absolute; | |
26 | + top: 50%; | |
27 | +} | |
28 | +.ql-clipboard p { | |
29 | + margin: 0; | |
30 | + padding: 0; | |
31 | +} | |
32 | +.ql-editor { | |
33 | + box-sizing: border-box; | |
34 | + line-height: 1.42; | |
35 | + height: 100%; | |
36 | + outline: none; | |
37 | + overflow-y: auto; | |
38 | + padding: 12px 15px; | |
39 | + tab-size: 4; | |
40 | + -moz-tab-size: 4; | |
41 | + text-align: left; | |
42 | + white-space: pre-wrap; | |
43 | + word-wrap: break-word; | |
44 | +} | |
45 | +.ql-editor > * { | |
46 | + cursor: text; | |
47 | +} | |
48 | +.ql-editor p, | |
49 | +.ql-editor ol, | |
50 | +.ql-editor ul, | |
51 | +.ql-editor pre, | |
52 | +.ql-editor blockquote, | |
53 | +.ql-editor h1, | |
54 | +.ql-editor h2, | |
55 | +.ql-editor h3, | |
56 | +.ql-editor h4, | |
57 | +.ql-editor h5, | |
58 | +.ql-editor h6 { | |
59 | + margin: 0; | |
60 | + padding: 0; | |
61 | + counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
62 | +} | |
63 | +.ql-editor ol, | |
64 | +.ql-editor ul { | |
65 | + padding-left: 1.5em; | |
66 | +} | |
67 | +.ql-editor ol > li, | |
68 | +.ql-editor ul > li { | |
69 | + list-style-type: none; | |
70 | +} | |
71 | +.ql-editor ul > li::before { | |
72 | + content: '\2022'; | |
73 | +} | |
74 | +.ql-editor ul[data-checked=true], | |
75 | +.ql-editor ul[data-checked=false] { | |
76 | + pointer-events: none; | |
77 | +} | |
78 | +.ql-editor ul[data-checked=true] > li *, | |
79 | +.ql-editor ul[data-checked=false] > li * { | |
80 | + pointer-events: all; | |
81 | +} | |
82 | +.ql-editor ul[data-checked=true] > li::before, | |
83 | +.ql-editor ul[data-checked=false] > li::before { | |
84 | + color: #777; | |
85 | + cursor: pointer; | |
86 | + pointer-events: all; | |
87 | +} | |
88 | +.ql-editor ul[data-checked=true] > li::before { | |
89 | + content: '\2611'; | |
90 | +} | |
91 | +.ql-editor ul[data-checked=false] > li::before { | |
92 | + content: '\2610'; | |
93 | +} | |
94 | +.ql-editor li::before { | |
95 | + display: inline-block; | |
96 | + white-space: nowrap; | |
97 | + width: 1.2em; | |
98 | +} | |
99 | +.ql-editor li:not(.ql-direction-rtl)::before { | |
100 | + margin-left: -1.5em; | |
101 | + margin-right: 0.3em; | |
102 | + text-align: right; | |
103 | +} | |
104 | +.ql-editor li.ql-direction-rtl::before { | |
105 | + margin-left: 0.3em; | |
106 | + margin-right: -1.5em; | |
107 | +} | |
108 | +.ql-editor ol li:not(.ql-direction-rtl), | |
109 | +.ql-editor ul li:not(.ql-direction-rtl) { | |
110 | + padding-left: 1.5em; | |
111 | +} | |
112 | +.ql-editor ol li.ql-direction-rtl, | |
113 | +.ql-editor ul li.ql-direction-rtl { | |
114 | + padding-right: 1.5em; | |
115 | +} | |
116 | +.ql-editor ol li { | |
117 | + counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
118 | + counter-increment: list-0; | |
119 | +} | |
120 | +.ql-editor ol li:before { | |
121 | + content: counter(list-0, decimal) '. '; | |
122 | +} | |
123 | +.ql-editor ol li.ql-indent-1 { | |
124 | + counter-increment: list-1; | |
125 | +} | |
126 | +.ql-editor ol li.ql-indent-1:before { | |
127 | + content: counter(list-1, lower-alpha) '. '; | |
128 | +} | |
129 | +.ql-editor ol li.ql-indent-1 { | |
130 | + counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
131 | +} | |
132 | +.ql-editor ol li.ql-indent-2 { | |
133 | + counter-increment: list-2; | |
134 | +} | |
135 | +.ql-editor ol li.ql-indent-2:before { | |
136 | + content: counter(list-2, lower-roman) '. '; | |
137 | +} | |
138 | +.ql-editor ol li.ql-indent-2 { | |
139 | + counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
140 | +} | |
141 | +.ql-editor ol li.ql-indent-3 { | |
142 | + counter-increment: list-3; | |
143 | +} | |
144 | +.ql-editor ol li.ql-indent-3:before { | |
145 | + content: counter(list-3, decimal) '. '; | |
146 | +} | |
147 | +.ql-editor ol li.ql-indent-3 { | |
148 | + counter-reset: list-4 list-5 list-6 list-7 list-8 list-9; | |
149 | +} | |
150 | +.ql-editor ol li.ql-indent-4 { | |
151 | + counter-increment: list-4; | |
152 | +} | |
153 | +.ql-editor ol li.ql-indent-4:before { | |
154 | + content: counter(list-4, lower-alpha) '. '; | |
155 | +} | |
156 | +.ql-editor ol li.ql-indent-4 { | |
157 | + counter-reset: list-5 list-6 list-7 list-8 list-9; | |
158 | +} | |
159 | +.ql-editor ol li.ql-indent-5 { | |
160 | + counter-increment: list-5; | |
161 | +} | |
162 | +.ql-editor ol li.ql-indent-5:before { | |
163 | + content: counter(list-5, lower-roman) '. '; | |
164 | +} | |
165 | +.ql-editor ol li.ql-indent-5 { | |
166 | + counter-reset: list-6 list-7 list-8 list-9; | |
167 | +} | |
168 | +.ql-editor ol li.ql-indent-6 { | |
169 | + counter-increment: list-6; | |
170 | +} | |
171 | +.ql-editor ol li.ql-indent-6:before { | |
172 | + content: counter(list-6, decimal) '. '; | |
173 | +} | |
174 | +.ql-editor ol li.ql-indent-6 { | |
175 | + counter-reset: list-7 list-8 list-9; | |
176 | +} | |
177 | +.ql-editor ol li.ql-indent-7 { | |
178 | + counter-increment: list-7; | |
179 | +} | |
180 | +.ql-editor ol li.ql-indent-7:before { | |
181 | + content: counter(list-7, lower-alpha) '. '; | |
182 | +} | |
183 | +.ql-editor ol li.ql-indent-7 { | |
184 | + counter-reset: list-8 list-9; | |
185 | +} | |
186 | +.ql-editor ol li.ql-indent-8 { | |
187 | + counter-increment: list-8; | |
188 | +} | |
189 | +.ql-editor ol li.ql-indent-8:before { | |
190 | + content: counter(list-8, lower-roman) '. '; | |
191 | +} | |
192 | +.ql-editor ol li.ql-indent-8 { | |
193 | + counter-reset: list-9; | |
194 | +} | |
195 | +.ql-editor ol li.ql-indent-9 { | |
196 | + counter-increment: list-9; | |
197 | +} | |
198 | +.ql-editor ol li.ql-indent-9:before { | |
199 | + content: counter(list-9, decimal) '. '; | |
200 | +} | |
201 | +.ql-editor .ql-indent-1:not(.ql-direction-rtl) { | |
202 | + padding-left: 3em; | |
203 | +} | |
204 | +.ql-editor li.ql-indent-1:not(.ql-direction-rtl) { | |
205 | + padding-left: 4.5em; | |
206 | +} | |
207 | +.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right { | |
208 | + padding-right: 3em; | |
209 | +} | |
210 | +.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right { | |
211 | + padding-right: 4.5em; | |
212 | +} | |
213 | +.ql-editor .ql-indent-2:not(.ql-direction-rtl) { | |
214 | + padding-left: 6em; | |
215 | +} | |
216 | +.ql-editor li.ql-indent-2:not(.ql-direction-rtl) { | |
217 | + padding-left: 7.5em; | |
218 | +} | |
219 | +.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right { | |
220 | + padding-right: 6em; | |
221 | +} | |
222 | +.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right { | |
223 | + padding-right: 7.5em; | |
224 | +} | |
225 | +.ql-editor .ql-indent-3:not(.ql-direction-rtl) { | |
226 | + padding-left: 9em; | |
227 | +} | |
228 | +.ql-editor li.ql-indent-3:not(.ql-direction-rtl) { | |
229 | + padding-left: 10.5em; | |
230 | +} | |
231 | +.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right { | |
232 | + padding-right: 9em; | |
233 | +} | |
234 | +.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right { | |
235 | + padding-right: 10.5em; | |
236 | +} | |
237 | +.ql-editor .ql-indent-4:not(.ql-direction-rtl) { | |
238 | + padding-left: 12em; | |
239 | +} | |
240 | +.ql-editor li.ql-indent-4:not(.ql-direction-rtl) { | |
241 | + padding-left: 13.5em; | |
242 | +} | |
243 | +.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right { | |
244 | + padding-right: 12em; | |
245 | +} | |
246 | +.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right { | |
247 | + padding-right: 13.5em; | |
248 | +} | |
249 | +.ql-editor .ql-indent-5:not(.ql-direction-rtl) { | |
250 | + padding-left: 15em; | |
251 | +} | |
252 | +.ql-editor li.ql-indent-5:not(.ql-direction-rtl) { | |
253 | + padding-left: 16.5em; | |
254 | +} | |
255 | +.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right { | |
256 | + padding-right: 15em; | |
257 | +} | |
258 | +.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right { | |
259 | + padding-right: 16.5em; | |
260 | +} | |
261 | +.ql-editor .ql-indent-6:not(.ql-direction-rtl) { | |
262 | + padding-left: 18em; | |
263 | +} | |
264 | +.ql-editor li.ql-indent-6:not(.ql-direction-rtl) { | |
265 | + padding-left: 19.5em; | |
266 | +} | |
267 | +.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right { | |
268 | + padding-right: 18em; | |
269 | +} | |
270 | +.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right { | |
271 | + padding-right: 19.5em; | |
272 | +} | |
273 | +.ql-editor .ql-indent-7:not(.ql-direction-rtl) { | |
274 | + padding-left: 21em; | |
275 | +} | |
276 | +.ql-editor li.ql-indent-7:not(.ql-direction-rtl) { | |
277 | + padding-left: 22.5em; | |
278 | +} | |
279 | +.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right { | |
280 | + padding-right: 21em; | |
281 | +} | |
282 | +.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right { | |
283 | + padding-right: 22.5em; | |
284 | +} | |
285 | +.ql-editor .ql-indent-8:not(.ql-direction-rtl) { | |
286 | + padding-left: 24em; | |
287 | +} | |
288 | +.ql-editor li.ql-indent-8:not(.ql-direction-rtl) { | |
289 | + padding-left: 25.5em; | |
290 | +} | |
291 | +.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right { | |
292 | + padding-right: 24em; | |
293 | +} | |
294 | +.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right { | |
295 | + padding-right: 25.5em; | |
296 | +} | |
297 | +.ql-editor .ql-indent-9:not(.ql-direction-rtl) { | |
298 | + padding-left: 27em; | |
299 | +} | |
300 | +.ql-editor li.ql-indent-9:not(.ql-direction-rtl) { | |
301 | + padding-left: 28.5em; | |
302 | +} | |
303 | +.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right { | |
304 | + padding-right: 27em; | |
305 | +} | |
306 | +.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right { | |
307 | + padding-right: 28.5em; | |
308 | +} | |
309 | +.ql-editor .ql-video { | |
310 | + display: block; | |
311 | + max-width: 100%; | |
312 | +} | |
313 | +.ql-editor .ql-video.ql-align-center { | |
314 | + margin: 0 auto; | |
315 | +} | |
316 | +.ql-editor .ql-video.ql-align-right { | |
317 | + margin: 0 0 0 auto; | |
318 | +} | |
319 | +.ql-editor .ql-bg-black { | |
320 | + background-color: #000; | |
321 | +} | |
322 | +.ql-editor .ql-bg-red { | |
323 | + background-color: #e60000; | |
324 | +} | |
325 | +.ql-editor .ql-bg-orange { | |
326 | + background-color: #f90; | |
327 | +} | |
328 | +.ql-editor .ql-bg-yellow { | |
329 | + background-color: #ff0; | |
330 | +} | |
331 | +.ql-editor .ql-bg-green { | |
332 | + background-color: #008a00; | |
333 | +} | |
334 | +.ql-editor .ql-bg-blue { | |
335 | + background-color: #06c; | |
336 | +} | |
337 | +.ql-editor .ql-bg-purple { | |
338 | + background-color: #93f; | |
339 | +} | |
340 | +.ql-editor .ql-color-white { | |
341 | + color: #fff; | |
342 | +} | |
343 | +.ql-editor .ql-color-red { | |
344 | + color: #e60000; | |
345 | +} | |
346 | +.ql-editor .ql-color-orange { | |
347 | + color: #f90; | |
348 | +} | |
349 | +.ql-editor .ql-color-yellow { | |
350 | + color: #ff0; | |
351 | +} | |
352 | +.ql-editor .ql-color-green { | |
353 | + color: #008a00; | |
354 | +} | |
355 | +.ql-editor .ql-color-blue { | |
356 | + color: #06c; | |
357 | +} | |
358 | +.ql-editor .ql-color-purple { | |
359 | + color: #93f; | |
360 | +} | |
361 | +.ql-editor .ql-font-serif { | |
362 | + font-family: Georgia, Times New Roman, serif; | |
363 | +} | |
364 | +.ql-editor .ql-font-monospace { | |
365 | + font-family: Monaco, Courier New, monospace; | |
366 | +} | |
367 | +.ql-editor .ql-size-small { | |
368 | + font-size: 0.75em; | |
369 | +} | |
370 | +.ql-editor .ql-size-large { | |
371 | + font-size: 1.5em; | |
372 | +} | |
373 | +.ql-editor .ql-size-huge { | |
374 | + font-size: 2.5em; | |
375 | +} | |
376 | +.ql-editor .ql-direction-rtl { | |
377 | + direction: rtl; | |
378 | + text-align: inherit; | |
379 | +} | |
380 | +.ql-editor .ql-align-center { | |
381 | + text-align: center; | |
382 | +} | |
383 | +.ql-editor .ql-align-justify { | |
384 | + text-align: justify; | |
385 | +} | |
386 | +.ql-editor .ql-align-right { | |
387 | + text-align: right; | |
388 | +} | |
389 | +.ql-editor.ql-blank::before { | |
390 | + color: rgba(0,0,0,0.6); | |
391 | + content: attr(data-placeholder); | |
392 | + font-style: italic; | |
393 | + left: 15px; | |
394 | + pointer-events: none; | |
395 | + position: absolute; | |
396 | + right: 15px; | |
397 | +} | |
398 | +.ql-bubble.ql-toolbar:after, | |
399 | +.ql-bubble .ql-toolbar:after { | |
400 | + clear: both; | |
401 | + content: ''; | |
402 | + display: table; | |
403 | +} | |
404 | +.ql-bubble.ql-toolbar button, | |
405 | +.ql-bubble .ql-toolbar button { | |
406 | + background: none; | |
407 | + border: none; | |
408 | + cursor: pointer; | |
409 | + display: inline-block; | |
410 | + float: left; | |
411 | + height: 24px; | |
412 | + padding: 3px 5px; | |
413 | + width: 28px; | |
414 | +} | |
415 | +.ql-bubble.ql-toolbar button svg, | |
416 | +.ql-bubble .ql-toolbar button svg { | |
417 | + float: left; | |
418 | + height: 100%; | |
419 | +} | |
420 | +.ql-bubble.ql-toolbar button:active:hover, | |
421 | +.ql-bubble .ql-toolbar button:active:hover { | |
422 | + outline: none; | |
423 | +} | |
424 | +.ql-bubble.ql-toolbar input.ql-image[type=file], | |
425 | +.ql-bubble .ql-toolbar input.ql-image[type=file] { | |
426 | + display: none; | |
427 | +} | |
428 | +.ql-bubble.ql-toolbar button:hover, | |
429 | +.ql-bubble .ql-toolbar button:hover, | |
430 | +.ql-bubble.ql-toolbar button:focus, | |
431 | +.ql-bubble .ql-toolbar button:focus, | |
432 | +.ql-bubble.ql-toolbar button.ql-active, | |
433 | +.ql-bubble .ql-toolbar button.ql-active, | |
434 | +.ql-bubble.ql-toolbar .ql-picker-label:hover, | |
435 | +.ql-bubble .ql-toolbar .ql-picker-label:hover, | |
436 | +.ql-bubble.ql-toolbar .ql-picker-label.ql-active, | |
437 | +.ql-bubble .ql-toolbar .ql-picker-label.ql-active, | |
438 | +.ql-bubble.ql-toolbar .ql-picker-item:hover, | |
439 | +.ql-bubble .ql-toolbar .ql-picker-item:hover, | |
440 | +.ql-bubble.ql-toolbar .ql-picker-item.ql-selected, | |
441 | +.ql-bubble .ql-toolbar .ql-picker-item.ql-selected { | |
442 | + color: #fff; | |
443 | +} | |
444 | +.ql-bubble.ql-toolbar button:hover .ql-fill, | |
445 | +.ql-bubble .ql-toolbar button:hover .ql-fill, | |
446 | +.ql-bubble.ql-toolbar button:focus .ql-fill, | |
447 | +.ql-bubble .ql-toolbar button:focus .ql-fill, | |
448 | +.ql-bubble.ql-toolbar button.ql-active .ql-fill, | |
449 | +.ql-bubble .ql-toolbar button.ql-active .ql-fill, | |
450 | +.ql-bubble.ql-toolbar .ql-picker-label:hover .ql-fill, | |
451 | +.ql-bubble .ql-toolbar .ql-picker-label:hover .ql-fill, | |
452 | +.ql-bubble.ql-toolbar .ql-picker-label.ql-active .ql-fill, | |
453 | +.ql-bubble .ql-toolbar .ql-picker-label.ql-active .ql-fill, | |
454 | +.ql-bubble.ql-toolbar .ql-picker-item:hover .ql-fill, | |
455 | +.ql-bubble .ql-toolbar .ql-picker-item:hover .ql-fill, | |
456 | +.ql-bubble.ql-toolbar .ql-picker-item.ql-selected .ql-fill, | |
457 | +.ql-bubble .ql-toolbar .ql-picker-item.ql-selected .ql-fill, | |
458 | +.ql-bubble.ql-toolbar button:hover .ql-stroke.ql-fill, | |
459 | +.ql-bubble .ql-toolbar button:hover .ql-stroke.ql-fill, | |
460 | +.ql-bubble.ql-toolbar button:focus .ql-stroke.ql-fill, | |
461 | +.ql-bubble .ql-toolbar button:focus .ql-stroke.ql-fill, | |
462 | +.ql-bubble.ql-toolbar button.ql-active .ql-stroke.ql-fill, | |
463 | +.ql-bubble .ql-toolbar button.ql-active .ql-stroke.ql-fill, | |
464 | +.ql-bubble.ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill, | |
465 | +.ql-bubble .ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill, | |
466 | +.ql-bubble.ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill, | |
467 | +.ql-bubble .ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill, | |
468 | +.ql-bubble.ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill, | |
469 | +.ql-bubble .ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill, | |
470 | +.ql-bubble.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill, | |
471 | +.ql-bubble .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill { | |
472 | + fill: #fff; | |
473 | +} | |
474 | +.ql-bubble.ql-toolbar button:hover .ql-stroke, | |
475 | +.ql-bubble .ql-toolbar button:hover .ql-stroke, | |
476 | +.ql-bubble.ql-toolbar button:focus .ql-stroke, | |
477 | +.ql-bubble .ql-toolbar button:focus .ql-stroke, | |
478 | +.ql-bubble.ql-toolbar button.ql-active .ql-stroke, | |
479 | +.ql-bubble .ql-toolbar button.ql-active .ql-stroke, | |
480 | +.ql-bubble.ql-toolbar .ql-picker-label:hover .ql-stroke, | |
481 | +.ql-bubble .ql-toolbar .ql-picker-label:hover .ql-stroke, | |
482 | +.ql-bubble.ql-toolbar .ql-picker-label.ql-active .ql-stroke, | |
483 | +.ql-bubble .ql-toolbar .ql-picker-label.ql-active .ql-stroke, | |
484 | +.ql-bubble.ql-toolbar .ql-picker-item:hover .ql-stroke, | |
485 | +.ql-bubble .ql-toolbar .ql-picker-item:hover .ql-stroke, | |
486 | +.ql-bubble.ql-toolbar .ql-picker-item.ql-selected .ql-stroke, | |
487 | +.ql-bubble .ql-toolbar .ql-picker-item.ql-selected .ql-stroke, | |
488 | +.ql-bubble.ql-toolbar button:hover .ql-stroke-miter, | |
489 | +.ql-bubble .ql-toolbar button:hover .ql-stroke-miter, | |
490 | +.ql-bubble.ql-toolbar button:focus .ql-stroke-miter, | |
491 | +.ql-bubble .ql-toolbar button:focus .ql-stroke-miter, | |
492 | +.ql-bubble.ql-toolbar button.ql-active .ql-stroke-miter, | |
493 | +.ql-bubble .ql-toolbar button.ql-active .ql-stroke-miter, | |
494 | +.ql-bubble.ql-toolbar .ql-picker-label:hover .ql-stroke-miter, | |
495 | +.ql-bubble .ql-toolbar .ql-picker-label:hover .ql-stroke-miter, | |
496 | +.ql-bubble.ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter, | |
497 | +.ql-bubble .ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter, | |
498 | +.ql-bubble.ql-toolbar .ql-picker-item:hover .ql-stroke-miter, | |
499 | +.ql-bubble .ql-toolbar .ql-picker-item:hover .ql-stroke-miter, | |
500 | +.ql-bubble.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter, | |
501 | +.ql-bubble .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter { | |
502 | + stroke: #fff; | |
503 | +} | |
504 | +@media (pointer: coarse) { | |
505 | + .ql-bubble.ql-toolbar button:hover:not(.ql-active), | |
506 | + .ql-bubble .ql-toolbar button:hover:not(.ql-active) { | |
507 | + color: #ccc; | |
508 | + } | |
509 | + .ql-bubble.ql-toolbar button:hover:not(.ql-active) .ql-fill, | |
510 | + .ql-bubble .ql-toolbar button:hover:not(.ql-active) .ql-fill, | |
511 | + .ql-bubble.ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill, | |
512 | + .ql-bubble .ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill { | |
513 | + fill: #ccc; | |
514 | + } | |
515 | + .ql-bubble.ql-toolbar button:hover:not(.ql-active) .ql-stroke, | |
516 | + .ql-bubble .ql-toolbar button:hover:not(.ql-active) .ql-stroke, | |
517 | + .ql-bubble.ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter, | |
518 | + .ql-bubble .ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter { | |
519 | + stroke: #ccc; | |
520 | + } | |
521 | +} | |
522 | +.ql-bubble { | |
523 | + box-sizing: border-box; | |
524 | +} | |
525 | +.ql-bubble * { | |
526 | + box-sizing: border-box; | |
527 | +} | |
528 | +.ql-bubble .ql-hidden { | |
529 | + display: none; | |
530 | +} | |
531 | +.ql-bubble .ql-out-bottom, | |
532 | +.ql-bubble .ql-out-top { | |
533 | + visibility: hidden; | |
534 | +} | |
535 | +.ql-bubble .ql-tooltip { | |
536 | + position: absolute; | |
537 | + transform: translateY(10px); | |
538 | +} | |
539 | +.ql-bubble .ql-tooltip a { | |
540 | + cursor: pointer; | |
541 | + text-decoration: none; | |
542 | +} | |
543 | +.ql-bubble .ql-tooltip.ql-flip { | |
544 | + transform: translateY(-10px); | |
545 | +} | |
546 | +.ql-bubble .ql-formats { | |
547 | + display: inline-block; | |
548 | + vertical-align: middle; | |
549 | +} | |
550 | +.ql-bubble .ql-formats:after { | |
551 | + clear: both; | |
552 | + content: ''; | |
553 | + display: table; | |
554 | +} | |
555 | +.ql-bubble .ql-stroke { | |
556 | + fill: none; | |
557 | + stroke: #ccc; | |
558 | + stroke-linecap: round; | |
559 | + stroke-linejoin: round; | |
560 | + stroke-width: 2; | |
561 | +} | |
562 | +.ql-bubble .ql-stroke-miter { | |
563 | + fill: none; | |
564 | + stroke: #ccc; | |
565 | + stroke-miterlimit: 10; | |
566 | + stroke-width: 2; | |
567 | +} | |
568 | +.ql-bubble .ql-fill, | |
569 | +.ql-bubble .ql-stroke.ql-fill { | |
570 | + fill: #ccc; | |
571 | +} | |
572 | +.ql-bubble .ql-empty { | |
573 | + fill: none; | |
574 | +} | |
575 | +.ql-bubble .ql-even { | |
576 | + fill-rule: evenodd; | |
577 | +} | |
578 | +.ql-bubble .ql-thin, | |
579 | +.ql-bubble .ql-stroke.ql-thin { | |
580 | + stroke-width: 1; | |
581 | +} | |
582 | +.ql-bubble .ql-transparent { | |
583 | + opacity: 0.4; | |
584 | +} | |
585 | +.ql-bubble .ql-direction svg:last-child { | |
586 | + display: none; | |
587 | +} | |
588 | +.ql-bubble .ql-direction.ql-active svg:last-child { | |
589 | + display: inline; | |
590 | +} | |
591 | +.ql-bubble .ql-direction.ql-active svg:first-child { | |
592 | + display: none; | |
593 | +} | |
594 | +.ql-bubble .ql-editor h1 { | |
595 | + font-size: 2em; | |
596 | +} | |
597 | +.ql-bubble .ql-editor h2 { | |
598 | + font-size: 1.5em; | |
599 | +} | |
600 | +.ql-bubble .ql-editor h3 { | |
601 | + font-size: 1.17em; | |
602 | +} | |
603 | +.ql-bubble .ql-editor h4 { | |
604 | + font-size: 1em; | |
605 | +} | |
606 | +.ql-bubble .ql-editor h5 { | |
607 | + font-size: 0.83em; | |
608 | +} | |
609 | +.ql-bubble .ql-editor h6 { | |
610 | + font-size: 0.67em; | |
611 | +} | |
612 | +.ql-bubble .ql-editor a { | |
613 | + text-decoration: underline; | |
614 | +} | |
615 | +.ql-bubble .ql-editor blockquote { | |
616 | + border-left: 4px solid #ccc; | |
617 | + margin-bottom: 5px; | |
618 | + margin-top: 5px; | |
619 | + padding-left: 16px; | |
620 | +} | |
621 | +.ql-bubble .ql-editor code, | |
622 | +.ql-bubble .ql-editor pre { | |
623 | + background-color: #f0f0f0; | |
624 | + border-radius: 3px; | |
625 | +} | |
626 | +.ql-bubble .ql-editor pre { | |
627 | + white-space: pre-wrap; | |
628 | + margin-bottom: 5px; | |
629 | + margin-top: 5px; | |
630 | + padding: 5px 10px; | |
631 | +} | |
632 | +.ql-bubble .ql-editor code { | |
633 | + font-size: 85%; | |
634 | + padding: 2px 4px; | |
635 | +} | |
636 | +.ql-bubble .ql-editor pre.ql-syntax { | |
637 | + background-color: #23241f; | |
638 | + color: #f8f8f2; | |
639 | + overflow: visible; | |
640 | +} | |
641 | +.ql-bubble .ql-editor img { | |
642 | + max-width: 100%; | |
643 | +} | |
644 | +.ql-bubble .ql-picker { | |
645 | + color: #ccc; | |
646 | + display: inline-block; | |
647 | + float: left; | |
648 | + font-size: 14px; | |
649 | + font-weight: 500; | |
650 | + height: 24px; | |
651 | + position: relative; | |
652 | + vertical-align: middle; | |
653 | +} | |
654 | +.ql-bubble .ql-picker-label { | |
655 | + cursor: pointer; | |
656 | + display: inline-block; | |
657 | + height: 100%; | |
658 | + padding-left: 8px; | |
659 | + padding-right: 2px; | |
660 | + position: relative; | |
661 | + width: 100%; | |
662 | +} | |
663 | +.ql-bubble .ql-picker-label::before { | |
664 | + display: inline-block; | |
665 | + line-height: 22px; | |
666 | +} | |
667 | +.ql-bubble .ql-picker-options { | |
668 | + background-color: #444; | |
669 | + display: none; | |
670 | + min-width: 100%; | |
671 | + padding: 4px 8px; | |
672 | + position: absolute; | |
673 | + white-space: nowrap; | |
674 | +} | |
675 | +.ql-bubble .ql-picker-options .ql-picker-item { | |
676 | + cursor: pointer; | |
677 | + display: block; | |
678 | + padding-bottom: 5px; | |
679 | + padding-top: 5px; | |
680 | +} | |
681 | +.ql-bubble .ql-picker.ql-expanded .ql-picker-label { | |
682 | + color: #777; | |
683 | + z-index: 2; | |
684 | +} | |
685 | +.ql-bubble .ql-picker.ql-expanded .ql-picker-label .ql-fill { | |
686 | + fill: #777; | |
687 | +} | |
688 | +.ql-bubble .ql-picker.ql-expanded .ql-picker-label .ql-stroke { | |
689 | + stroke: #777; | |
690 | +} | |
691 | +.ql-bubble .ql-picker.ql-expanded .ql-picker-options { | |
692 | + display: block; | |
693 | + margin-top: -1px; | |
694 | + top: 100%; | |
695 | + z-index: 1; | |
696 | +} | |
697 | +.ql-bubble .ql-color-picker, | |
698 | +.ql-bubble .ql-icon-picker { | |
699 | + width: 28px; | |
700 | +} | |
701 | +.ql-bubble .ql-color-picker .ql-picker-label, | |
702 | +.ql-bubble .ql-icon-picker .ql-picker-label { | |
703 | + padding: 2px 4px; | |
704 | +} | |
705 | +.ql-bubble .ql-color-picker .ql-picker-label svg, | |
706 | +.ql-bubble .ql-icon-picker .ql-picker-label svg { | |
707 | + right: 4px; | |
708 | +} | |
709 | +.ql-bubble .ql-icon-picker .ql-picker-options { | |
710 | + padding: 4px 0px; | |
711 | +} | |
712 | +.ql-bubble .ql-icon-picker .ql-picker-item { | |
713 | + height: 24px; | |
714 | + width: 24px; | |
715 | + padding: 2px 4px; | |
716 | +} | |
717 | +.ql-bubble .ql-color-picker .ql-picker-options { | |
718 | + padding: 3px 5px; | |
719 | + width: 152px; | |
720 | +} | |
721 | +.ql-bubble .ql-color-picker .ql-picker-item { | |
722 | + border: 1px solid transparent; | |
723 | + float: left; | |
724 | + height: 16px; | |
725 | + margin: 2px; | |
726 | + padding: 0px; | |
727 | + width: 16px; | |
728 | +} | |
729 | +.ql-bubble .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg { | |
730 | + position: absolute; | |
731 | + margin-top: -9px; | |
732 | + right: 0; | |
733 | + top: 50%; | |
734 | + width: 18px; | |
735 | +} | |
736 | +.ql-bubble .ql-picker.ql-header .ql-picker-label[data-label]:not([data-label=''])::before, | |
737 | +.ql-bubble .ql-picker.ql-font .ql-picker-label[data-label]:not([data-label=''])::before, | |
738 | +.ql-bubble .ql-picker.ql-size .ql-picker-label[data-label]:not([data-label=''])::before, | |
739 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-label]:not([data-label=''])::before, | |
740 | +.ql-bubble .ql-picker.ql-font .ql-picker-item[data-label]:not([data-label=''])::before, | |
741 | +.ql-bubble .ql-picker.ql-size .ql-picker-item[data-label]:not([data-label=''])::before { | |
742 | + content: attr(data-label); | |
743 | +} | |
744 | +.ql-bubble .ql-picker.ql-header { | |
745 | + width: 98px; | |
746 | +} | |
747 | +.ql-bubble .ql-picker.ql-header .ql-picker-label::before, | |
748 | +.ql-bubble .ql-picker.ql-header .ql-picker-item::before { | |
749 | + content: 'Normal'; | |
750 | +} | |
751 | +.ql-bubble .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, | |
752 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { | |
753 | + content: 'Heading 1'; | |
754 | +} | |
755 | +.ql-bubble .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, | |
756 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { | |
757 | + content: 'Heading 2'; | |
758 | +} | |
759 | +.ql-bubble .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, | |
760 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { | |
761 | + content: 'Heading 3'; | |
762 | +} | |
763 | +.ql-bubble .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, | |
764 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { | |
765 | + content: 'Heading 4'; | |
766 | +} | |
767 | +.ql-bubble .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, | |
768 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { | |
769 | + content: 'Heading 5'; | |
770 | +} | |
771 | +.ql-bubble .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, | |
772 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { | |
773 | + content: 'Heading 6'; | |
774 | +} | |
775 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { | |
776 | + font-size: 2em; | |
777 | +} | |
778 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { | |
779 | + font-size: 1.5em; | |
780 | +} | |
781 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { | |
782 | + font-size: 1.17em; | |
783 | +} | |
784 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { | |
785 | + font-size: 1em; | |
786 | +} | |
787 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { | |
788 | + font-size: 0.83em; | |
789 | +} | |
790 | +.ql-bubble .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { | |
791 | + font-size: 0.67em; | |
792 | +} | |
793 | +.ql-bubble .ql-picker.ql-font { | |
794 | + width: 108px; | |
795 | +} | |
796 | +.ql-bubble .ql-picker.ql-font .ql-picker-label::before, | |
797 | +.ql-bubble .ql-picker.ql-font .ql-picker-item::before { | |
798 | + content: 'Sans Serif'; | |
799 | +} | |
800 | +.ql-bubble .ql-picker.ql-font .ql-picker-label[data-value=serif]::before, | |
801 | +.ql-bubble .ql-picker.ql-font .ql-picker-item[data-value=serif]::before { | |
802 | + content: 'Serif'; | |
803 | +} | |
804 | +.ql-bubble .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before, | |
805 | +.ql-bubble .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before { | |
806 | + content: 'Monospace'; | |
807 | +} | |
808 | +.ql-bubble .ql-picker.ql-font .ql-picker-item[data-value=serif]::before { | |
809 | + font-family: Georgia, Times New Roman, serif; | |
810 | +} | |
811 | +.ql-bubble .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before { | |
812 | + font-family: Monaco, Courier New, monospace; | |
813 | +} | |
814 | +.ql-bubble .ql-picker.ql-size { | |
815 | + width: 98px; | |
816 | +} | |
817 | +.ql-bubble .ql-picker.ql-size .ql-picker-label::before, | |
818 | +.ql-bubble .ql-picker.ql-size .ql-picker-item::before { | |
819 | + content: 'Normal'; | |
820 | +} | |
821 | +.ql-bubble .ql-picker.ql-size .ql-picker-label[data-value=small]::before, | |
822 | +.ql-bubble .ql-picker.ql-size .ql-picker-item[data-value=small]::before { | |
823 | + content: 'Small'; | |
824 | +} | |
825 | +.ql-bubble .ql-picker.ql-size .ql-picker-label[data-value=large]::before, | |
826 | +.ql-bubble .ql-picker.ql-size .ql-picker-item[data-value=large]::before { | |
827 | + content: 'Large'; | |
828 | +} | |
829 | +.ql-bubble .ql-picker.ql-size .ql-picker-label[data-value=huge]::before, | |
830 | +.ql-bubble .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { | |
831 | + content: 'Huge'; | |
832 | +} | |
833 | +.ql-bubble .ql-picker.ql-size .ql-picker-item[data-value=small]::before { | |
834 | + font-size: 10px; | |
835 | +} | |
836 | +.ql-bubble .ql-picker.ql-size .ql-picker-item[data-value=large]::before { | |
837 | + font-size: 18px; | |
838 | +} | |
839 | +.ql-bubble .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { | |
840 | + font-size: 32px; | |
841 | +} | |
842 | +.ql-bubble .ql-color-picker.ql-background .ql-picker-item { | |
843 | + background-color: #fff; | |
844 | +} | |
845 | +.ql-bubble .ql-color-picker.ql-color .ql-picker-item { | |
846 | + background-color: #000; | |
847 | +} | |
848 | +.ql-bubble .ql-toolbar .ql-formats { | |
849 | + margin: 8px 12px 8px 0px; | |
850 | +} | |
851 | +.ql-bubble .ql-toolbar .ql-formats:first-child { | |
852 | + margin-left: 12px; | |
853 | +} | |
854 | +.ql-bubble .ql-color-picker svg { | |
855 | + margin: 1px; | |
856 | +} | |
857 | +.ql-bubble .ql-color-picker .ql-picker-item.ql-selected, | |
858 | +.ql-bubble .ql-color-picker .ql-picker-item:hover { | |
859 | + border-color: #fff; | |
860 | +} | |
861 | +.ql-bubble .ql-tooltip { | |
862 | + background-color: #444; | |
863 | + border-radius: 25px; | |
864 | + color: #fff; | |
865 | +} | |
866 | +.ql-bubble .ql-tooltip-arrow { | |
867 | + border-left: 6px solid transparent; | |
868 | + border-right: 6px solid transparent; | |
869 | + content: " "; | |
870 | + display: block; | |
871 | + left: 50%; | |
872 | + margin-left: -6px; | |
873 | + position: absolute; | |
874 | +} | |
875 | +.ql-bubble .ql-tooltip:not(.ql-flip) .ql-tooltip-arrow { | |
876 | + border-bottom: 6px solid #444; | |
877 | + top: -6px; | |
878 | +} | |
879 | +.ql-bubble .ql-tooltip.ql-flip .ql-tooltip-arrow { | |
880 | + border-top: 6px solid #444; | |
881 | + bottom: -6px; | |
882 | +} | |
883 | +.ql-bubble .ql-tooltip.ql-editing .ql-tooltip-editor { | |
884 | + display: block; | |
885 | +} | |
886 | +.ql-bubble .ql-tooltip.ql-editing .ql-formats { | |
887 | + visibility: hidden; | |
888 | +} | |
889 | +.ql-bubble .ql-tooltip-editor { | |
890 | + display: none; | |
891 | +} | |
892 | +.ql-bubble .ql-tooltip-editor input[type=text] { | |
893 | + background: transparent; | |
894 | + border: none; | |
895 | + color: #fff; | |
896 | + font-size: 13px; | |
897 | + height: 100%; | |
898 | + outline: none; | |
899 | + padding: 10px 20px; | |
900 | + position: absolute; | |
901 | + width: 100%; | |
902 | +} | |
903 | +.ql-bubble .ql-tooltip-editor a { | |
904 | + top: 10px; | |
905 | + position: absolute; | |
906 | + right: 20px; | |
907 | +} | |
908 | +.ql-bubble .ql-tooltip-editor a:before { | |
909 | + color: #ccc; | |
910 | + content: "\D7"; | |
911 | + font-size: 16px; | |
912 | + font-weight: bold; | |
913 | +} | |
914 | +.ql-container.ql-bubble:not(.ql-disabled) a { | |
915 | + position: relative; | |
916 | + white-space: nowrap; | |
917 | +} | |
918 | +.ql-container.ql-bubble:not(.ql-disabled) a::before { | |
919 | + background-color: #444; | |
920 | + border-radius: 15px; | |
921 | + top: -5px; | |
922 | + font-size: 12px; | |
923 | + color: #fff; | |
924 | + content: attr(href); | |
925 | + font-weight: normal; | |
926 | + overflow: hidden; | |
927 | + padding: 5px 15px; | |
928 | + text-decoration: none; | |
929 | + z-index: 1; | |
930 | +} | |
931 | +.ql-container.ql-bubble:not(.ql-disabled) a::after { | |
932 | + border-top: 6px solid #444; | |
933 | + border-left: 6px solid transparent; | |
934 | + border-right: 6px solid transparent; | |
935 | + top: 0; | |
936 | + content: " "; | |
937 | + height: 0; | |
938 | + width: 0; | |
939 | +} | |
940 | +.ql-container.ql-bubble:not(.ql-disabled) a::before, | |
941 | +.ql-container.ql-bubble:not(.ql-disabled) a::after { | |
942 | + left: 0; | |
943 | + margin-left: 50%; | |
944 | + position: absolute; | |
945 | + transform: translate(-50%, -100%); | |
946 | + transition: visibility 0s ease 200ms; | |
947 | + visibility: hidden; | |
948 | +} | |
949 | +.ql-container.ql-bubble:not(.ql-disabled) a:hover::before, | |
950 | +.ql-container.ql-bubble:not(.ql-disabled) a:hover::after { | |
951 | + visibility: visible; | |
952 | +} | ... | ... |
app/src/main/assets/quill.core.css
0 → 100644
1 | +/*! | |
2 | + * Quill Editor v1.3.7 | |
3 | + * https://quilljs.com/ | |
4 | + * Copyright (c) 2014, Jason Chen | |
5 | + * Copyright (c) 2013, salesforce.com | |
6 | + */ | |
7 | +.ql-container { | |
8 | + box-sizing: border-box; | |
9 | + font-family: Helvetica, Arial, sans-serif; | |
10 | + font-size: 13px; | |
11 | + height: 100%; | |
12 | + margin: 0px; | |
13 | + position: relative; | |
14 | +} | |
15 | +.ql-container.ql-disabled .ql-tooltip { | |
16 | + visibility: hidden; | |
17 | +} | |
18 | +.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before { | |
19 | + pointer-events: none; | |
20 | +} | |
21 | +.ql-clipboard { | |
22 | + left: -100000px; | |
23 | + height: 1px; | |
24 | + overflow-y: hidden; | |
25 | + position: absolute; | |
26 | + top: 50%; | |
27 | +} | |
28 | +.ql-clipboard p { | |
29 | + margin: 0; | |
30 | + padding: 0; | |
31 | +} | |
32 | +.ql-editor { | |
33 | + box-sizing: border-box; | |
34 | + line-height: 1.42; | |
35 | + height: 100%; | |
36 | + outline: none; | |
37 | + overflow-y: auto; | |
38 | + padding: 12px 15px; | |
39 | + tab-size: 4; | |
40 | + -moz-tab-size: 4; | |
41 | + text-align: left; | |
42 | + white-space: pre-wrap; | |
43 | + word-wrap: break-word; | |
44 | +} | |
45 | +.ql-editor > * { | |
46 | + cursor: text; | |
47 | +} | |
48 | +.ql-editor p, | |
49 | +.ql-editor ol, | |
50 | +.ql-editor ul, | |
51 | +.ql-editor pre, | |
52 | +.ql-editor blockquote, | |
53 | +.ql-editor h1, | |
54 | +.ql-editor h2, | |
55 | +.ql-editor h3, | |
56 | +.ql-editor h4, | |
57 | +.ql-editor h5, | |
58 | +.ql-editor h6 { | |
59 | + margin: 0; | |
60 | + padding: 0; | |
61 | + counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
62 | +} | |
63 | +.ql-editor ol, | |
64 | +.ql-editor ul { | |
65 | + padding-left: 1.5em; | |
66 | +} | |
67 | +.ql-editor ol > li, | |
68 | +.ql-editor ul > li { | |
69 | + list-style-type: none; | |
70 | +} | |
71 | +.ql-editor ul > li::before { | |
72 | + content: '\2022'; | |
73 | +} | |
74 | +.ql-editor ul[data-checked=true], | |
75 | +.ql-editor ul[data-checked=false] { | |
76 | + pointer-events: none; | |
77 | +} | |
78 | +.ql-editor ul[data-checked=true] > li *, | |
79 | +.ql-editor ul[data-checked=false] > li * { | |
80 | + pointer-events: all; | |
81 | +} | |
82 | +.ql-editor ul[data-checked=true] > li::before, | |
83 | +.ql-editor ul[data-checked=false] > li::before { | |
84 | + color: #777; | |
85 | + cursor: pointer; | |
86 | + pointer-events: all; | |
87 | +} | |
88 | +.ql-editor ul[data-checked=true] > li::before { | |
89 | + content: '\2611'; | |
90 | +} | |
91 | +.ql-editor ul[data-checked=false] > li::before { | |
92 | + content: '\2610'; | |
93 | +} | |
94 | +.ql-editor li::before { | |
95 | + display: inline-block; | |
96 | + white-space: nowrap; | |
97 | + width: 1.2em; | |
98 | +} | |
99 | +.ql-editor li:not(.ql-direction-rtl)::before { | |
100 | + margin-left: -1.5em; | |
101 | + margin-right: 0.3em; | |
102 | + text-align: right; | |
103 | +} | |
104 | +.ql-editor li.ql-direction-rtl::before { | |
105 | + margin-left: 0.3em; | |
106 | + margin-right: -1.5em; | |
107 | +} | |
108 | +.ql-editor ol li:not(.ql-direction-rtl), | |
109 | +.ql-editor ul li:not(.ql-direction-rtl) { | |
110 | + padding-left: 1.5em; | |
111 | +} | |
112 | +.ql-editor ol li.ql-direction-rtl, | |
113 | +.ql-editor ul li.ql-direction-rtl { | |
114 | + padding-right: 1.5em; | |
115 | +} | |
116 | +.ql-editor ol li { | |
117 | + counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
118 | + counter-increment: list-0; | |
119 | +} | |
120 | +.ql-editor ol li:before { | |
121 | + content: counter(list-0, decimal) '. '; | |
122 | +} | |
123 | +.ql-editor ol li.ql-indent-1 { | |
124 | + counter-increment: list-1; | |
125 | +} | |
126 | +.ql-editor ol li.ql-indent-1:before { | |
127 | + content: counter(list-1, lower-alpha) '. '; | |
128 | +} | |
129 | +.ql-editor ol li.ql-indent-1 { | |
130 | + counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
131 | +} | |
132 | +.ql-editor ol li.ql-indent-2 { | |
133 | + counter-increment: list-2; | |
134 | +} | |
135 | +.ql-editor ol li.ql-indent-2:before { | |
136 | + content: counter(list-2, lower-roman) '. '; | |
137 | +} | |
138 | +.ql-editor ol li.ql-indent-2 { | |
139 | + counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
140 | +} | |
141 | +.ql-editor ol li.ql-indent-3 { | |
142 | + counter-increment: list-3; | |
143 | +} | |
144 | +.ql-editor ol li.ql-indent-3:before { | |
145 | + content: counter(list-3, decimal) '. '; | |
146 | +} | |
147 | +.ql-editor ol li.ql-indent-3 { | |
148 | + counter-reset: list-4 list-5 list-6 list-7 list-8 list-9; | |
149 | +} | |
150 | +.ql-editor ol li.ql-indent-4 { | |
151 | + counter-increment: list-4; | |
152 | +} | |
153 | +.ql-editor ol li.ql-indent-4:before { | |
154 | + content: counter(list-4, lower-alpha) '. '; | |
155 | +} | |
156 | +.ql-editor ol li.ql-indent-4 { | |
157 | + counter-reset: list-5 list-6 list-7 list-8 list-9; | |
158 | +} | |
159 | +.ql-editor ol li.ql-indent-5 { | |
160 | + counter-increment: list-5; | |
161 | +} | |
162 | +.ql-editor ol li.ql-indent-5:before { | |
163 | + content: counter(list-5, lower-roman) '. '; | |
164 | +} | |
165 | +.ql-editor ol li.ql-indent-5 { | |
166 | + counter-reset: list-6 list-7 list-8 list-9; | |
167 | +} | |
168 | +.ql-editor ol li.ql-indent-6 { | |
169 | + counter-increment: list-6; | |
170 | +} | |
171 | +.ql-editor ol li.ql-indent-6:before { | |
172 | + content: counter(list-6, decimal) '. '; | |
173 | +} | |
174 | +.ql-editor ol li.ql-indent-6 { | |
175 | + counter-reset: list-7 list-8 list-9; | |
176 | +} | |
177 | +.ql-editor ol li.ql-indent-7 { | |
178 | + counter-increment: list-7; | |
179 | +} | |
180 | +.ql-editor ol li.ql-indent-7:before { | |
181 | + content: counter(list-7, lower-alpha) '. '; | |
182 | +} | |
183 | +.ql-editor ol li.ql-indent-7 { | |
184 | + counter-reset: list-8 list-9; | |
185 | +} | |
186 | +.ql-editor ol li.ql-indent-8 { | |
187 | + counter-increment: list-8; | |
188 | +} | |
189 | +.ql-editor ol li.ql-indent-8:before { | |
190 | + content: counter(list-8, lower-roman) '. '; | |
191 | +} | |
192 | +.ql-editor ol li.ql-indent-8 { | |
193 | + counter-reset: list-9; | |
194 | +} | |
195 | +.ql-editor ol li.ql-indent-9 { | |
196 | + counter-increment: list-9; | |
197 | +} | |
198 | +.ql-editor ol li.ql-indent-9:before { | |
199 | + content: counter(list-9, decimal) '. '; | |
200 | +} | |
201 | +.ql-editor .ql-indent-1:not(.ql-direction-rtl) { | |
202 | + padding-left: 3em; | |
203 | +} | |
204 | +.ql-editor li.ql-indent-1:not(.ql-direction-rtl) { | |
205 | + padding-left: 4.5em; | |
206 | +} | |
207 | +.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right { | |
208 | + padding-right: 3em; | |
209 | +} | |
210 | +.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right { | |
211 | + padding-right: 4.5em; | |
212 | +} | |
213 | +.ql-editor .ql-indent-2:not(.ql-direction-rtl) { | |
214 | + padding-left: 6em; | |
215 | +} | |
216 | +.ql-editor li.ql-indent-2:not(.ql-direction-rtl) { | |
217 | + padding-left: 7.5em; | |
218 | +} | |
219 | +.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right { | |
220 | + padding-right: 6em; | |
221 | +} | |
222 | +.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right { | |
223 | + padding-right: 7.5em; | |
224 | +} | |
225 | +.ql-editor .ql-indent-3:not(.ql-direction-rtl) { | |
226 | + padding-left: 9em; | |
227 | +} | |
228 | +.ql-editor li.ql-indent-3:not(.ql-direction-rtl) { | |
229 | + padding-left: 10.5em; | |
230 | +} | |
231 | +.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right { | |
232 | + padding-right: 9em; | |
233 | +} | |
234 | +.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right { | |
235 | + padding-right: 10.5em; | |
236 | +} | |
237 | +.ql-editor .ql-indent-4:not(.ql-direction-rtl) { | |
238 | + padding-left: 12em; | |
239 | +} | |
240 | +.ql-editor li.ql-indent-4:not(.ql-direction-rtl) { | |
241 | + padding-left: 13.5em; | |
242 | +} | |
243 | +.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right { | |
244 | + padding-right: 12em; | |
245 | +} | |
246 | +.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right { | |
247 | + padding-right: 13.5em; | |
248 | +} | |
249 | +.ql-editor .ql-indent-5:not(.ql-direction-rtl) { | |
250 | + padding-left: 15em; | |
251 | +} | |
252 | +.ql-editor li.ql-indent-5:not(.ql-direction-rtl) { | |
253 | + padding-left: 16.5em; | |
254 | +} | |
255 | +.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right { | |
256 | + padding-right: 15em; | |
257 | +} | |
258 | +.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right { | |
259 | + padding-right: 16.5em; | |
260 | +} | |
261 | +.ql-editor .ql-indent-6:not(.ql-direction-rtl) { | |
262 | + padding-left: 18em; | |
263 | +} | |
264 | +.ql-editor li.ql-indent-6:not(.ql-direction-rtl) { | |
265 | + padding-left: 19.5em; | |
266 | +} | |
267 | +.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right { | |
268 | + padding-right: 18em; | |
269 | +} | |
270 | +.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right { | |
271 | + padding-right: 19.5em; | |
272 | +} | |
273 | +.ql-editor .ql-indent-7:not(.ql-direction-rtl) { | |
274 | + padding-left: 21em; | |
275 | +} | |
276 | +.ql-editor li.ql-indent-7:not(.ql-direction-rtl) { | |
277 | + padding-left: 22.5em; | |
278 | +} | |
279 | +.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right { | |
280 | + padding-right: 21em; | |
281 | +} | |
282 | +.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right { | |
283 | + padding-right: 22.5em; | |
284 | +} | |
285 | +.ql-editor .ql-indent-8:not(.ql-direction-rtl) { | |
286 | + padding-left: 24em; | |
287 | +} | |
288 | +.ql-editor li.ql-indent-8:not(.ql-direction-rtl) { | |
289 | + padding-left: 25.5em; | |
290 | +} | |
291 | +.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right { | |
292 | + padding-right: 24em; | |
293 | +} | |
294 | +.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right { | |
295 | + padding-right: 25.5em; | |
296 | +} | |
297 | +.ql-editor .ql-indent-9:not(.ql-direction-rtl) { | |
298 | + padding-left: 27em; | |
299 | +} | |
300 | +.ql-editor li.ql-indent-9:not(.ql-direction-rtl) { | |
301 | + padding-left: 28.5em; | |
302 | +} | |
303 | +.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right { | |
304 | + padding-right: 27em; | |
305 | +} | |
306 | +.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right { | |
307 | + padding-right: 28.5em; | |
308 | +} | |
309 | +.ql-editor .ql-video { | |
310 | + display: block; | |
311 | + max-width: 100%; | |
312 | +} | |
313 | +.ql-editor .ql-video.ql-align-center { | |
314 | + margin: 0 auto; | |
315 | +} | |
316 | +.ql-editor .ql-video.ql-align-right { | |
317 | + margin: 0 0 0 auto; | |
318 | +} | |
319 | +.ql-editor .ql-bg-black { | |
320 | + background-color: #000; | |
321 | +} | |
322 | +.ql-editor .ql-bg-red { | |
323 | + background-color: #e60000; | |
324 | +} | |
325 | +.ql-editor .ql-bg-orange { | |
326 | + background-color: #f90; | |
327 | +} | |
328 | +.ql-editor .ql-bg-yellow { | |
329 | + background-color: #ff0; | |
330 | +} | |
331 | +.ql-editor .ql-bg-green { | |
332 | + background-color: #008a00; | |
333 | +} | |
334 | +.ql-editor .ql-bg-blue { | |
335 | + background-color: #06c; | |
336 | +} | |
337 | +.ql-editor .ql-bg-purple { | |
338 | + background-color: #93f; | |
339 | +} | |
340 | +.ql-editor .ql-color-white { | |
341 | + color: #fff; | |
342 | +} | |
343 | +.ql-editor .ql-color-red { | |
344 | + color: #e60000; | |
345 | +} | |
346 | +.ql-editor .ql-color-orange { | |
347 | + color: #f90; | |
348 | +} | |
349 | +.ql-editor .ql-color-yellow { | |
350 | + color: #ff0; | |
351 | +} | |
352 | +.ql-editor .ql-color-green { | |
353 | + color: #008a00; | |
354 | +} | |
355 | +.ql-editor .ql-color-blue { | |
356 | + color: #06c; | |
357 | +} | |
358 | +.ql-editor .ql-color-purple { | |
359 | + color: #93f; | |
360 | +} | |
361 | +.ql-editor .ql-font-serif { | |
362 | + font-family: Georgia, Times New Roman, serif; | |
363 | +} | |
364 | +.ql-editor .ql-font-monospace { | |
365 | + font-family: Monaco, Courier New, monospace; | |
366 | +} | |
367 | +.ql-editor .ql-size-small { | |
368 | + font-size: 0.75em; | |
369 | +} | |
370 | +.ql-editor .ql-size-large { | |
371 | + font-size: 1.5em; | |
372 | +} | |
373 | +.ql-editor .ql-size-huge { | |
374 | + font-size: 2.5em; | |
375 | +} | |
376 | +.ql-editor .ql-direction-rtl { | |
377 | + direction: rtl; | |
378 | + text-align: inherit; | |
379 | +} | |
380 | +.ql-editor .ql-align-center { | |
381 | + text-align: center; | |
382 | +} | |
383 | +.ql-editor .ql-align-justify { | |
384 | + text-align: justify; | |
385 | +} | |
386 | +.ql-editor .ql-align-right { | |
387 | + text-align: right; | |
388 | +} | |
389 | +.ql-editor.ql-blank::before { | |
390 | + color: rgba(0,0,0,0.6); | |
391 | + content: attr(data-placeholder); | |
392 | + font-style: italic; | |
393 | + left: 15px; | |
394 | + pointer-events: none; | |
395 | + position: absolute; | |
396 | + right: 15px; | |
397 | +} | ... | ... |
app/src/main/assets/quill.snow.css
0 → 100644
1 | +/*! | |
2 | + * Quill Editor v1.3.7 | |
3 | + * https://quilljs.com/ | |
4 | + * Copyright (c) 2014, Jason Chen | |
5 | + * Copyright (c) 2013, salesforce.com | |
6 | + */ | |
7 | +.ql-container { | |
8 | + box-sizing: border-box; | |
9 | + font-family: Helvetica, Arial, sans-serif; | |
10 | + font-size: 13px; | |
11 | + height: 100%; | |
12 | + margin: 0px; | |
13 | + position: relative; | |
14 | +} | |
15 | +.ql-container.ql-disabled .ql-tooltip { | |
16 | + visibility: hidden; | |
17 | +} | |
18 | +.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before { | |
19 | + pointer-events: none; | |
20 | +} | |
21 | +.ql-clipboard { | |
22 | + left: -100000px; | |
23 | + height: 1px; | |
24 | + overflow-y: hidden; | |
25 | + position: absolute; | |
26 | + top: 50%; | |
27 | +} | |
28 | +.ql-clipboard p { | |
29 | + margin: 0; | |
30 | + padding: 0; | |
31 | +} | |
32 | +.ql-editor { | |
33 | + box-sizing: border-box; | |
34 | + line-height: 1.42; | |
35 | + height: 100%; | |
36 | + outline: none; | |
37 | + overflow-y: auto; | |
38 | + padding: 12px 15px; | |
39 | + tab-size: 4; | |
40 | + -moz-tab-size: 4; | |
41 | + text-align: left; | |
42 | + white-space: pre-wrap; | |
43 | + word-wrap: break-word; | |
44 | +} | |
45 | +.ql-editor > * { | |
46 | + cursor: text; | |
47 | +} | |
48 | +.ql-editor p, | |
49 | +.ql-editor ol, | |
50 | +.ql-editor ul, | |
51 | +.ql-editor pre, | |
52 | +.ql-editor blockquote, | |
53 | +.ql-editor h1, | |
54 | +.ql-editor h2, | |
55 | +.ql-editor h3, | |
56 | +.ql-editor h4, | |
57 | +.ql-editor h5, | |
58 | +.ql-editor h6 { | |
59 | + margin: 0; | |
60 | + padding: 0; | |
61 | + counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
62 | +} | |
63 | +.ql-editor ol, | |
64 | +.ql-editor ul { | |
65 | + padding-left: 1.5em; | |
66 | +} | |
67 | +.ql-editor ol > li, | |
68 | +.ql-editor ul > li { | |
69 | + list-style-type: none; | |
70 | +} | |
71 | +.ql-editor ul > li::before { | |
72 | + content: '\2022'; | |
73 | +} | |
74 | +.ql-editor ul[data-checked=true], | |
75 | +.ql-editor ul[data-checked=false] { | |
76 | + pointer-events: none; | |
77 | +} | |
78 | +.ql-editor ul[data-checked=true] > li *, | |
79 | +.ql-editor ul[data-checked=false] > li * { | |
80 | + pointer-events: all; | |
81 | +} | |
82 | +.ql-editor ul[data-checked=true] > li::before, | |
83 | +.ql-editor ul[data-checked=false] > li::before { | |
84 | + color: #777; | |
85 | + cursor: pointer; | |
86 | + pointer-events: all; | |
87 | +} | |
88 | +.ql-editor ul[data-checked=true] > li::before { | |
89 | + content: '\2611'; | |
90 | +} | |
91 | +.ql-editor ul[data-checked=false] > li::before { | |
92 | + content: '\2610'; | |
93 | +} | |
94 | +.ql-editor li::before { | |
95 | + display: inline-block; | |
96 | + white-space: nowrap; | |
97 | + width: 1.2em; | |
98 | +} | |
99 | +.ql-editor li:not(.ql-direction-rtl)::before { | |
100 | + margin-left: -1.5em; | |
101 | + margin-right: 0.3em; | |
102 | + text-align: right; | |
103 | +} | |
104 | +.ql-editor li.ql-direction-rtl::before { | |
105 | + margin-left: 0.3em; | |
106 | + margin-right: -1.5em; | |
107 | +} | |
108 | +.ql-editor ol li:not(.ql-direction-rtl), | |
109 | +.ql-editor ul li:not(.ql-direction-rtl) { | |
110 | + padding-left: 1.5em; | |
111 | +} | |
112 | +.ql-editor ol li.ql-direction-rtl, | |
113 | +.ql-editor ul li.ql-direction-rtl { | |
114 | + padding-right: 1.5em; | |
115 | +} | |
116 | +.ql-editor ol li { | |
117 | + counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
118 | + counter-increment: list-0; | |
119 | +} | |
120 | +.ql-editor ol li:before { | |
121 | + content: counter(list-0, decimal) '. '; | |
122 | +} | |
123 | +.ql-editor ol li.ql-indent-1 { | |
124 | + counter-increment: list-1; | |
125 | +} | |
126 | +.ql-editor ol li.ql-indent-1:before { | |
127 | + content: counter(list-1, lower-alpha) '. '; | |
128 | +} | |
129 | +.ql-editor ol li.ql-indent-1 { | |
130 | + counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
131 | +} | |
132 | +.ql-editor ol li.ql-indent-2 { | |
133 | + counter-increment: list-2; | |
134 | +} | |
135 | +.ql-editor ol li.ql-indent-2:before { | |
136 | + content: counter(list-2, lower-roman) '. '; | |
137 | +} | |
138 | +.ql-editor ol li.ql-indent-2 { | |
139 | + counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |
140 | +} | |
141 | +.ql-editor ol li.ql-indent-3 { | |
142 | + counter-increment: list-3; | |
143 | +} | |
144 | +.ql-editor ol li.ql-indent-3:before { | |
145 | + content: counter(list-3, decimal) '. '; | |
146 | +} | |
147 | +.ql-editor ol li.ql-indent-3 { | |
148 | + counter-reset: list-4 list-5 list-6 list-7 list-8 list-9; | |
149 | +} | |
150 | +.ql-editor ol li.ql-indent-4 { | |
151 | + counter-increment: list-4; | |
152 | +} | |
153 | +.ql-editor ol li.ql-indent-4:before { | |
154 | + content: counter(list-4, lower-alpha) '. '; | |
155 | +} | |
156 | +.ql-editor ol li.ql-indent-4 { | |
157 | + counter-reset: list-5 list-6 list-7 list-8 list-9; | |
158 | +} | |
159 | +.ql-editor ol li.ql-indent-5 { | |
160 | + counter-increment: list-5; | |
161 | +} | |
162 | +.ql-editor ol li.ql-indent-5:before { | |
163 | + content: counter(list-5, lower-roman) '. '; | |
164 | +} | |
165 | +.ql-editor ol li.ql-indent-5 { | |
166 | + counter-reset: list-6 list-7 list-8 list-9; | |
167 | +} | |
168 | +.ql-editor ol li.ql-indent-6 { | |
169 | + counter-increment: list-6; | |
170 | +} | |
171 | +.ql-editor ol li.ql-indent-6:before { | |
172 | + content: counter(list-6, decimal) '. '; | |
173 | +} | |
174 | +.ql-editor ol li.ql-indent-6 { | |
175 | + counter-reset: list-7 list-8 list-9; | |
176 | +} | |
177 | +.ql-editor ol li.ql-indent-7 { | |
178 | + counter-increment: list-7; | |
179 | +} | |
180 | +.ql-editor ol li.ql-indent-7:before { | |
181 | + content: counter(list-7, lower-alpha) '. '; | |
182 | +} | |
183 | +.ql-editor ol li.ql-indent-7 { | |
184 | + counter-reset: list-8 list-9; | |
185 | +} | |
186 | +.ql-editor ol li.ql-indent-8 { | |
187 | + counter-increment: list-8; | |
188 | +} | |
189 | +.ql-editor ol li.ql-indent-8:before { | |
190 | + content: counter(list-8, lower-roman) '. '; | |
191 | +} | |
192 | +.ql-editor ol li.ql-indent-8 { | |
193 | + counter-reset: list-9; | |
194 | +} | |
195 | +.ql-editor ol li.ql-indent-9 { | |
196 | + counter-increment: list-9; | |
197 | +} | |
198 | +.ql-editor ol li.ql-indent-9:before { | |
199 | + content: counter(list-9, decimal) '. '; | |
200 | +} | |
201 | +.ql-editor .ql-indent-1:not(.ql-direction-rtl) { | |
202 | + padding-left: 3em; | |
203 | +} | |
204 | +.ql-editor li.ql-indent-1:not(.ql-direction-rtl) { | |
205 | + padding-left: 4.5em; | |
206 | +} | |
207 | +.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right { | |
208 | + padding-right: 3em; | |
209 | +} | |
210 | +.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right { | |
211 | + padding-right: 4.5em; | |
212 | +} | |
213 | +.ql-editor .ql-indent-2:not(.ql-direction-rtl) { | |
214 | + padding-left: 6em; | |
215 | +} | |
216 | +.ql-editor li.ql-indent-2:not(.ql-direction-rtl) { | |
217 | + padding-left: 7.5em; | |
218 | +} | |
219 | +.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right { | |
220 | + padding-right: 6em; | |
221 | +} | |
222 | +.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right { | |
223 | + padding-right: 7.5em; | |
224 | +} | |
225 | +.ql-editor .ql-indent-3:not(.ql-direction-rtl) { | |
226 | + padding-left: 9em; | |
227 | +} | |
228 | +.ql-editor li.ql-indent-3:not(.ql-direction-rtl) { | |
229 | + padding-left: 10.5em; | |
230 | +} | |
231 | +.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right { | |
232 | + padding-right: 9em; | |
233 | +} | |
234 | +.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right { | |
235 | + padding-right: 10.5em; | |
236 | +} | |
237 | +.ql-editor .ql-indent-4:not(.ql-direction-rtl) { | |
238 | + padding-left: 12em; | |
239 | +} | |
240 | +.ql-editor li.ql-indent-4:not(.ql-direction-rtl) { | |
241 | + padding-left: 13.5em; | |
242 | +} | |
243 | +.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right { | |
244 | + padding-right: 12em; | |
245 | +} | |
246 | +.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right { | |
247 | + padding-right: 13.5em; | |
248 | +} | |
249 | +.ql-editor .ql-indent-5:not(.ql-direction-rtl) { | |
250 | + padding-left: 15em; | |
251 | +} | |
252 | +.ql-editor li.ql-indent-5:not(.ql-direction-rtl) { | |
253 | + padding-left: 16.5em; | |
254 | +} | |
255 | +.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right { | |
256 | + padding-right: 15em; | |
257 | +} | |
258 | +.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right { | |
259 | + padding-right: 16.5em; | |
260 | +} | |
261 | +.ql-editor .ql-indent-6:not(.ql-direction-rtl) { | |
262 | + padding-left: 18em; | |
263 | +} | |
264 | +.ql-editor li.ql-indent-6:not(.ql-direction-rtl) { | |
265 | + padding-left: 19.5em; | |
266 | +} | |
267 | +.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right { | |
268 | + padding-right: 18em; | |
269 | +} | |
270 | +.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right { | |
271 | + padding-right: 19.5em; | |
272 | +} | |
273 | +.ql-editor .ql-indent-7:not(.ql-direction-rtl) { | |
274 | + padding-left: 21em; | |
275 | +} | |
276 | +.ql-editor li.ql-indent-7:not(.ql-direction-rtl) { | |
277 | + padding-left: 22.5em; | |
278 | +} | |
279 | +.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right { | |
280 | + padding-right: 21em; | |
281 | +} | |
282 | +.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right { | |
283 | + padding-right: 22.5em; | |
284 | +} | |
285 | +.ql-editor .ql-indent-8:not(.ql-direction-rtl) { | |
286 | + padding-left: 24em; | |
287 | +} | |
288 | +.ql-editor li.ql-indent-8:not(.ql-direction-rtl) { | |
289 | + padding-left: 25.5em; | |
290 | +} | |
291 | +.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right { | |
292 | + padding-right: 24em; | |
293 | +} | |
294 | +.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right { | |
295 | + padding-right: 25.5em; | |
296 | +} | |
297 | +.ql-editor .ql-indent-9:not(.ql-direction-rtl) { | |
298 | + padding-left: 27em; | |
299 | +} | |
300 | +.ql-editor li.ql-indent-9:not(.ql-direction-rtl) { | |
301 | + padding-left: 28.5em; | |
302 | +} | |
303 | +.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right { | |
304 | + padding-right: 27em; | |
305 | +} | |
306 | +.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right { | |
307 | + padding-right: 28.5em; | |
308 | +} | |
309 | +.ql-editor .ql-video { | |
310 | + display: block; | |
311 | + max-width: 100%; | |
312 | +} | |
313 | +.ql-editor .ql-video.ql-align-center { | |
314 | + margin: 0 auto; | |
315 | +} | |
316 | +.ql-editor .ql-video.ql-align-right { | |
317 | + margin: 0 0 0 auto; | |
318 | +} | |
319 | +.ql-editor .ql-bg-black { | |
320 | + background-color: #000; | |
321 | +} | |
322 | +.ql-editor .ql-bg-red { | |
323 | + background-color: #e60000; | |
324 | +} | |
325 | +.ql-editor .ql-bg-orange { | |
326 | + background-color: #f90; | |
327 | +} | |
328 | +.ql-editor .ql-bg-yellow { | |
329 | + background-color: #ff0; | |
330 | +} | |
331 | +.ql-editor .ql-bg-green { | |
332 | + background-color: #008a00; | |
333 | +} | |
334 | +.ql-editor .ql-bg-blue { | |
335 | + background-color: #06c; | |
336 | +} | |
337 | +.ql-editor .ql-bg-purple { | |
338 | + background-color: #93f; | |
339 | +} | |
340 | +.ql-editor .ql-color-white { | |
341 | + color: #fff; | |
342 | +} | |
343 | +.ql-editor .ql-color-red { | |
344 | + color: #e60000; | |
345 | +} | |
346 | +.ql-editor .ql-color-orange { | |
347 | + color: #f90; | |
348 | +} | |
349 | +.ql-editor .ql-color-yellow { | |
350 | + color: #ff0; | |
351 | +} | |
352 | +.ql-editor .ql-color-green { | |
353 | + color: #008a00; | |
354 | +} | |
355 | +.ql-editor .ql-color-blue { | |
356 | + color: #06c; | |
357 | +} | |
358 | +.ql-editor .ql-color-purple { | |
359 | + color: #93f; | |
360 | +} | |
361 | +.ql-editor .ql-font-serif { | |
362 | + font-family: Georgia, Times New Roman, serif; | |
363 | +} | |
364 | +.ql-editor .ql-font-monospace { | |
365 | + font-family: Monaco, Courier New, monospace; | |
366 | +} | |
367 | +.ql-editor .ql-size-small { | |
368 | + font-size: 0.75em; | |
369 | +} | |
370 | +.ql-editor .ql-size-large { | |
371 | + font-size: 1.5em; | |
372 | +} | |
373 | +.ql-editor .ql-size-huge { | |
374 | + font-size: 2.5em; | |
375 | +} | |
376 | +.ql-editor .ql-direction-rtl { | |
377 | + direction: rtl; | |
378 | + text-align: inherit; | |
379 | +} | |
380 | +.ql-editor .ql-align-center { | |
381 | + text-align: center; | |
382 | +} | |
383 | +.ql-editor .ql-align-justify { | |
384 | + text-align: justify; | |
385 | +} | |
386 | +.ql-editor .ql-align-right { | |
387 | + text-align: right; | |
388 | +} | |
389 | +.ql-editor.ql-blank::before { | |
390 | + color: rgba(0,0,0,0.6); | |
391 | + content: attr(data-placeholder); | |
392 | + font-style: italic; | |
393 | + left: 15px; | |
394 | + pointer-events: none; | |
395 | + position: absolute; | |
396 | + right: 15px; | |
397 | +} | |
398 | +.ql-snow.ql-toolbar:after, | |
399 | +.ql-snow .ql-toolbar:after { | |
400 | + clear: both; | |
401 | + content: ''; | |
402 | + display: table; | |
403 | +} | |
404 | +.ql-snow.ql-toolbar button, | |
405 | +.ql-snow .ql-toolbar button { | |
406 | + background: none; | |
407 | + border: none; | |
408 | + cursor: pointer; | |
409 | + display: inline-block; | |
410 | + float: left; | |
411 | + height: 24px; | |
412 | + padding: 3px 5px; | |
413 | + width: 28px; | |
414 | +} | |
415 | +.ql-snow.ql-toolbar button svg, | |
416 | +.ql-snow .ql-toolbar button svg { | |
417 | + float: left; | |
418 | + height: 100%; | |
419 | +} | |
420 | +.ql-snow.ql-toolbar button:active:hover, | |
421 | +.ql-snow .ql-toolbar button:active:hover { | |
422 | + outline: none; | |
423 | +} | |
424 | +.ql-snow.ql-toolbar input.ql-image[type=file], | |
425 | +.ql-snow .ql-toolbar input.ql-image[type=file] { | |
426 | + display: none; | |
427 | +} | |
428 | +.ql-snow.ql-toolbar button:hover, | |
429 | +.ql-snow .ql-toolbar button:hover, | |
430 | +.ql-snow.ql-toolbar button:focus, | |
431 | +.ql-snow .ql-toolbar button:focus, | |
432 | +.ql-snow.ql-toolbar button.ql-active, | |
433 | +.ql-snow .ql-toolbar button.ql-active, | |
434 | +.ql-snow.ql-toolbar .ql-picker-label:hover, | |
435 | +.ql-snow .ql-toolbar .ql-picker-label:hover, | |
436 | +.ql-snow.ql-toolbar .ql-picker-label.ql-active, | |
437 | +.ql-snow .ql-toolbar .ql-picker-label.ql-active, | |
438 | +.ql-snow.ql-toolbar .ql-picker-item:hover, | |
439 | +.ql-snow .ql-toolbar .ql-picker-item:hover, | |
440 | +.ql-snow.ql-toolbar .ql-picker-item.ql-selected, | |
441 | +.ql-snow .ql-toolbar .ql-picker-item.ql-selected { | |
442 | + color: #06c; | |
443 | +} | |
444 | +.ql-snow.ql-toolbar button:hover .ql-fill, | |
445 | +.ql-snow .ql-toolbar button:hover .ql-fill, | |
446 | +.ql-snow.ql-toolbar button:focus .ql-fill, | |
447 | +.ql-snow .ql-toolbar button:focus .ql-fill, | |
448 | +.ql-snow.ql-toolbar button.ql-active .ql-fill, | |
449 | +.ql-snow .ql-toolbar button.ql-active .ql-fill, | |
450 | +.ql-snow.ql-toolbar .ql-picker-label:hover .ql-fill, | |
451 | +.ql-snow .ql-toolbar .ql-picker-label:hover .ql-fill, | |
452 | +.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-fill, | |
453 | +.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-fill, | |
454 | +.ql-snow.ql-toolbar .ql-picker-item:hover .ql-fill, | |
455 | +.ql-snow .ql-toolbar .ql-picker-item:hover .ql-fill, | |
456 | +.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-fill, | |
457 | +.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-fill, | |
458 | +.ql-snow.ql-toolbar button:hover .ql-stroke.ql-fill, | |
459 | +.ql-snow .ql-toolbar button:hover .ql-stroke.ql-fill, | |
460 | +.ql-snow.ql-toolbar button:focus .ql-stroke.ql-fill, | |
461 | +.ql-snow .ql-toolbar button:focus .ql-stroke.ql-fill, | |
462 | +.ql-snow.ql-toolbar button.ql-active .ql-stroke.ql-fill, | |
463 | +.ql-snow .ql-toolbar button.ql-active .ql-stroke.ql-fill, | |
464 | +.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill, | |
465 | +.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill, | |
466 | +.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill, | |
467 | +.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill, | |
468 | +.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill, | |
469 | +.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill, | |
470 | +.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill, | |
471 | +.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill { | |
472 | + fill: #06c; | |
473 | +} | |
474 | +.ql-snow.ql-toolbar button:hover .ql-stroke, | |
475 | +.ql-snow .ql-toolbar button:hover .ql-stroke, | |
476 | +.ql-snow.ql-toolbar button:focus .ql-stroke, | |
477 | +.ql-snow .ql-toolbar button:focus .ql-stroke, | |
478 | +.ql-snow.ql-toolbar button.ql-active .ql-stroke, | |
479 | +.ql-snow .ql-toolbar button.ql-active .ql-stroke, | |
480 | +.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke, | |
481 | +.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke, | |
482 | +.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke, | |
483 | +.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke, | |
484 | +.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke, | |
485 | +.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke, | |
486 | +.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke, | |
487 | +.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke, | |
488 | +.ql-snow.ql-toolbar button:hover .ql-stroke-miter, | |
489 | +.ql-snow .ql-toolbar button:hover .ql-stroke-miter, | |
490 | +.ql-snow.ql-toolbar button:focus .ql-stroke-miter, | |
491 | +.ql-snow .ql-toolbar button:focus .ql-stroke-miter, | |
492 | +.ql-snow.ql-toolbar button.ql-active .ql-stroke-miter, | |
493 | +.ql-snow .ql-toolbar button.ql-active .ql-stroke-miter, | |
494 | +.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke-miter, | |
495 | +.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke-miter, | |
496 | +.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter, | |
497 | +.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter, | |
498 | +.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke-miter, | |
499 | +.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke-miter, | |
500 | +.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter, | |
501 | +.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter { | |
502 | + stroke: #06c; | |
503 | +} | |
504 | +@media (pointer: coarse) { | |
505 | + .ql-snow.ql-toolbar button:hover:not(.ql-active), | |
506 | + .ql-snow .ql-toolbar button:hover:not(.ql-active) { | |
507 | + color: #444; | |
508 | + } | |
509 | + .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-fill, | |
510 | + .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-fill, | |
511 | + .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill, | |
512 | + .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill { | |
513 | + fill: #444; | |
514 | + } | |
515 | + .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke, | |
516 | + .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke, | |
517 | + .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter, | |
518 | + .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter { | |
519 | + stroke: #444; | |
520 | + } | |
521 | +} | |
522 | +.ql-snow { | |
523 | + box-sizing: border-box; | |
524 | +} | |
525 | +.ql-snow * { | |
526 | + box-sizing: border-box; | |
527 | +} | |
528 | +.ql-snow .ql-hidden { | |
529 | + display: none; | |
530 | +} | |
531 | +.ql-snow .ql-out-bottom, | |
532 | +.ql-snow .ql-out-top { | |
533 | + visibility: hidden; | |
534 | +} | |
535 | +.ql-snow .ql-tooltip { | |
536 | + position: absolute; | |
537 | + transform: translateY(10px); | |
538 | +} | |
539 | +.ql-snow .ql-tooltip a { | |
540 | + cursor: pointer; | |
541 | + text-decoration: none; | |
542 | +} | |
543 | +.ql-snow .ql-tooltip.ql-flip { | |
544 | + transform: translateY(-10px); | |
545 | +} | |
546 | +.ql-snow .ql-formats { | |
547 | + display: inline-block; | |
548 | + vertical-align: middle; | |
549 | +} | |
550 | +.ql-snow .ql-formats:after { | |
551 | + clear: both; | |
552 | + content: ''; | |
553 | + display: table; | |
554 | +} | |
555 | +.ql-snow .ql-stroke { | |
556 | + fill: none; | |
557 | + stroke: #444; | |
558 | + stroke-linecap: round; | |
559 | + stroke-linejoin: round; | |
560 | + stroke-width: 2; | |
561 | +} | |
562 | +.ql-snow .ql-stroke-miter { | |
563 | + fill: none; | |
564 | + stroke: #444; | |
565 | + stroke-miterlimit: 10; | |
566 | + stroke-width: 2; | |
567 | +} | |
568 | +.ql-snow .ql-fill, | |
569 | +.ql-snow .ql-stroke.ql-fill { | |
570 | + fill: #444; | |
571 | +} | |
572 | +.ql-snow .ql-empty { | |
573 | + fill: none; | |
574 | +} | |
575 | +.ql-snow .ql-even { | |
576 | + fill-rule: evenodd; | |
577 | +} | |
578 | +.ql-snow .ql-thin, | |
579 | +.ql-snow .ql-stroke.ql-thin { | |
580 | + stroke-width: 1; | |
581 | +} | |
582 | +.ql-snow .ql-transparent { | |
583 | + opacity: 0.4; | |
584 | +} | |
585 | +.ql-snow .ql-direction svg:last-child { | |
586 | + display: none; | |
587 | +} | |
588 | +.ql-snow .ql-direction.ql-active svg:last-child { | |
589 | + display: inline; | |
590 | +} | |
591 | +.ql-snow .ql-direction.ql-active svg:first-child { | |
592 | + display: none; | |
593 | +} | |
594 | +.ql-snow .ql-editor h1 { | |
595 | + font-size: 2em; | |
596 | +} | |
597 | +.ql-snow .ql-editor h2 { | |
598 | + font-size: 1.5em; | |
599 | +} | |
600 | +.ql-snow .ql-editor h3 { | |
601 | + font-size: 1.17em; | |
602 | +} | |
603 | +.ql-snow .ql-editor h4 { | |
604 | + font-size: 1em; | |
605 | +} | |
606 | +.ql-snow .ql-editor h5 { | |
607 | + font-size: 0.83em; | |
608 | +} | |
609 | +.ql-snow .ql-editor h6 { | |
610 | + font-size: 0.67em; | |
611 | +} | |
612 | +.ql-snow .ql-editor a { | |
613 | + text-decoration: underline; | |
614 | +} | |
615 | +.ql-snow .ql-editor blockquote { | |
616 | + border-left: 4px solid #ccc; | |
617 | + margin-bottom: 5px; | |
618 | + margin-top: 5px; | |
619 | + padding-left: 16px; | |
620 | +} | |
621 | +.ql-snow .ql-editor code, | |
622 | +.ql-snow .ql-editor pre { | |
623 | + background-color: #f0f0f0; | |
624 | + border-radius: 3px; | |
625 | +} | |
626 | +.ql-snow .ql-editor pre { | |
627 | + white-space: pre-wrap; | |
628 | + margin-bottom: 5px; | |
629 | + margin-top: 5px; | |
630 | + padding: 5px 10px; | |
631 | +} | |
632 | +.ql-snow .ql-editor code { | |
633 | + font-size: 85%; | |
634 | + padding: 2px 4px; | |
635 | +} | |
636 | +.ql-snow .ql-editor pre.ql-syntax { | |
637 | + background-color: #23241f; | |
638 | + color: #f8f8f2; | |
639 | + overflow: visible; | |
640 | +} | |
641 | +.ql-snow .ql-editor img { | |
642 | + max-width: 100%; | |
643 | +} | |
644 | +.ql-snow .ql-picker { | |
645 | + color: #444; | |
646 | + display: inline-block; | |
647 | + float: left; | |
648 | + font-size: 14px; | |
649 | + font-weight: 500; | |
650 | + height: 24px; | |
651 | + position: relative; | |
652 | + vertical-align: middle; | |
653 | +} | |
654 | +.ql-snow .ql-picker-label { | |
655 | + cursor: pointer; | |
656 | + display: inline-block; | |
657 | + height: 100%; | |
658 | + padding-left: 8px; | |
659 | + padding-right: 2px; | |
660 | + position: relative; | |
661 | + width: 100%; | |
662 | +} | |
663 | +.ql-snow .ql-picker-label::before { | |
664 | + display: inline-block; | |
665 | + line-height: 22px; | |
666 | +} | |
667 | +.ql-snow .ql-picker-options { | |
668 | + background-color: #fff; | |
669 | + display: none; | |
670 | + min-width: 100%; | |
671 | + padding: 4px 8px; | |
672 | + position: absolute; | |
673 | + white-space: nowrap; | |
674 | +} | |
675 | +.ql-snow .ql-picker-options .ql-picker-item { | |
676 | + cursor: pointer; | |
677 | + display: block; | |
678 | + padding-bottom: 5px; | |
679 | + padding-top: 5px; | |
680 | +} | |
681 | +.ql-snow .ql-picker.ql-expanded .ql-picker-label { | |
682 | + color: #ccc; | |
683 | + z-index: 2; | |
684 | +} | |
685 | +.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-fill { | |
686 | + fill: #ccc; | |
687 | +} | |
688 | +.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-stroke { | |
689 | + stroke: #ccc; | |
690 | +} | |
691 | +.ql-snow .ql-picker.ql-expanded .ql-picker-options { | |
692 | + display: block; | |
693 | + margin-top: -1px; | |
694 | + top: 100%; | |
695 | + z-index: 1; | |
696 | +} | |
697 | +.ql-snow .ql-color-picker, | |
698 | +.ql-snow .ql-icon-picker { | |
699 | + width: 28px; | |
700 | +} | |
701 | +.ql-snow .ql-color-picker .ql-picker-label, | |
702 | +.ql-snow .ql-icon-picker .ql-picker-label { | |
703 | + padding: 2px 4px; | |
704 | +} | |
705 | +.ql-snow .ql-color-picker .ql-picker-label svg, | |
706 | +.ql-snow .ql-icon-picker .ql-picker-label svg { | |
707 | + right: 4px; | |
708 | +} | |
709 | +.ql-snow .ql-icon-picker .ql-picker-options { | |
710 | + padding: 4px 0px; | |
711 | +} | |
712 | +.ql-snow .ql-icon-picker .ql-picker-item { | |
713 | + height: 24px; | |
714 | + width: 24px; | |
715 | + padding: 2px 4px; | |
716 | +} | |
717 | +.ql-snow .ql-color-picker .ql-picker-options { | |
718 | + padding: 3px 5px; | |
719 | + width: 152px; | |
720 | +} | |
721 | +.ql-snow .ql-color-picker .ql-picker-item { | |
722 | + border: 1px solid transparent; | |
723 | + float: left; | |
724 | + height: 16px; | |
725 | + margin: 2px; | |
726 | + padding: 0px; | |
727 | + width: 16px; | |
728 | +} | |
729 | +.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg { | |
730 | + position: absolute; | |
731 | + margin-top: -9px; | |
732 | + right: 0; | |
733 | + top: 50%; | |
734 | + width: 18px; | |
735 | +} | |
736 | +.ql-snow .ql-picker.ql-header .ql-picker-label[data-label]:not([data-label=''])::before, | |
737 | +.ql-snow .ql-picker.ql-font .ql-picker-label[data-label]:not([data-label=''])::before, | |
738 | +.ql-snow .ql-picker.ql-size .ql-picker-label[data-label]:not([data-label=''])::before, | |
739 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-label]:not([data-label=''])::before, | |
740 | +.ql-snow .ql-picker.ql-font .ql-picker-item[data-label]:not([data-label=''])::before, | |
741 | +.ql-snow .ql-picker.ql-size .ql-picker-item[data-label]:not([data-label=''])::before { | |
742 | + content: attr(data-label); | |
743 | +} | |
744 | +.ql-snow .ql-picker.ql-header { | |
745 | + width: 98px; | |
746 | +} | |
747 | +.ql-snow .ql-picker.ql-header .ql-picker-label::before, | |
748 | +.ql-snow .ql-picker.ql-header .ql-picker-item::before { | |
749 | + content: 'Normal'; | |
750 | +} | |
751 | +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, | |
752 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { | |
753 | + content: 'Heading 1'; | |
754 | +} | |
755 | +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, | |
756 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { | |
757 | + content: 'Heading 2'; | |
758 | +} | |
759 | +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, | |
760 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { | |
761 | + content: 'Heading 3'; | |
762 | +} | |
763 | +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, | |
764 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { | |
765 | + content: 'Heading 4'; | |
766 | +} | |
767 | +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, | |
768 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { | |
769 | + content: 'Heading 5'; | |
770 | +} | |
771 | +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, | |
772 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { | |
773 | + content: 'Heading 6'; | |
774 | +} | |
775 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { | |
776 | + font-size: 2em; | |
777 | +} | |
778 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { | |
779 | + font-size: 1.5em; | |
780 | +} | |
781 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { | |
782 | + font-size: 1.17em; | |
783 | +} | |
784 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { | |
785 | + font-size: 1em; | |
786 | +} | |
787 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { | |
788 | + font-size: 0.83em; | |
789 | +} | |
790 | +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { | |
791 | + font-size: 0.67em; | |
792 | +} | |
793 | +.ql-snow .ql-picker.ql-font { | |
794 | + width: 108px; | |
795 | +} | |
796 | +.ql-snow .ql-picker.ql-font .ql-picker-label::before, | |
797 | +.ql-snow .ql-picker.ql-font .ql-picker-item::before { | |
798 | + content: 'Sans Serif'; | |
799 | +} | |
800 | +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before, | |
801 | +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before { | |
802 | + content: 'Serif'; | |
803 | +} | |
804 | +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before, | |
805 | +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before { | |
806 | + content: 'Monospace'; | |
807 | +} | |
808 | +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before { | |
809 | + font-family: Georgia, Times New Roman, serif; | |
810 | +} | |
811 | +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before { | |
812 | + font-family: Monaco, Courier New, monospace; | |
813 | +} | |
814 | +.ql-snow .ql-picker.ql-size { | |
815 | + width: 98px; | |
816 | +} | |
817 | +.ql-snow .ql-picker.ql-size .ql-picker-label::before, | |
818 | +.ql-snow .ql-picker.ql-size .ql-picker-item::before { | |
819 | + content: 'Normal'; | |
820 | +} | |
821 | +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before, | |
822 | +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before { | |
823 | + content: 'Small'; | |
824 | +} | |
825 | +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before, | |
826 | +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before { | |
827 | + content: 'Large'; | |
828 | +} | |
829 | +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before, | |
830 | +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { | |
831 | + content: 'Huge'; | |
832 | +} | |
833 | +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before { | |
834 | + font-size: 10px; | |
835 | +} | |
836 | +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before { | |
837 | + font-size: 18px; | |
838 | +} | |
839 | +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { | |
840 | + font-size: 32px; | |
841 | +} | |
842 | +.ql-snow .ql-color-picker.ql-background .ql-picker-item { | |
843 | + background-color: #fff; | |
844 | +} | |
845 | +.ql-snow .ql-color-picker.ql-color .ql-picker-item { | |
846 | + background-color: #000; | |
847 | +} | |
848 | +.ql-toolbar.ql-snow { | |
849 | + border: 1px solid #ccc; | |
850 | + box-sizing: border-box; | |
851 | + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; | |
852 | + padding: 8px; | |
853 | +} | |
854 | +.ql-toolbar.ql-snow .ql-formats { | |
855 | + margin-right: 15px; | |
856 | +} | |
857 | +.ql-toolbar.ql-snow .ql-picker-label { | |
858 | + border: 1px solid transparent; | |
859 | +} | |
860 | +.ql-toolbar.ql-snow .ql-picker-options { | |
861 | + border: 1px solid transparent; | |
862 | + box-shadow: rgba(0,0,0,0.2) 0 2px 8px; | |
863 | +} | |
864 | +.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label { | |
865 | + border-color: #ccc; | |
866 | +} | |
867 | +.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options { | |
868 | + border-color: #ccc; | |
869 | +} | |
870 | +.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item.ql-selected, | |
871 | +.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item:hover { | |
872 | + border-color: #000; | |
873 | +} | |
874 | +.ql-toolbar.ql-snow + .ql-container.ql-snow { | |
875 | + border-top: 0px; | |
876 | +} | |
877 | +.ql-snow .ql-tooltip { | |
878 | + background-color: #fff; | |
879 | + border: 1px solid #ccc; | |
880 | + box-shadow: 0px 0px 5px #ddd; | |
881 | + color: #444; | |
882 | + padding: 5px 12px; | |
883 | + white-space: nowrap; | |
884 | +} | |
885 | +.ql-snow .ql-tooltip::before { | |
886 | + content: "Visit URL:"; | |
887 | + line-height: 26px; | |
888 | + margin-right: 8px; | |
889 | +} | |
890 | +.ql-snow .ql-tooltip input[type=text] { | |
891 | + display: none; | |
892 | + border: 1px solid #ccc; | |
893 | + font-size: 13px; | |
894 | + height: 26px; | |
895 | + margin: 0px; | |
896 | + padding: 3px 5px; | |
897 | + width: 170px; | |
898 | +} | |
899 | +.ql-snow .ql-tooltip a.ql-preview { | |
900 | + display: inline-block; | |
901 | + max-width: 200px; | |
902 | + overflow-x: hidden; | |
903 | + text-overflow: ellipsis; | |
904 | + vertical-align: top; | |
905 | +} | |
906 | +.ql-snow .ql-tooltip a.ql-action::after { | |
907 | + border-right: 1px solid #ccc; | |
908 | + content: 'Edit'; | |
909 | + margin-left: 16px; | |
910 | + padding-right: 8px; | |
911 | +} | |
912 | +.ql-snow .ql-tooltip a.ql-remove::before { | |
913 | + content: 'Remove'; | |
914 | + margin-left: 8px; | |
915 | +} | |
916 | +.ql-snow .ql-tooltip a { | |
917 | + line-height: 26px; | |
918 | +} | |
919 | +.ql-snow .ql-tooltip.ql-editing a.ql-preview, | |
920 | +.ql-snow .ql-tooltip.ql-editing a.ql-remove { | |
921 | + display: none; | |
922 | +} | |
923 | +.ql-snow .ql-tooltip.ql-editing input[type=text] { | |
924 | + display: inline-block; | |
925 | +} | |
926 | +.ql-snow .ql-tooltip.ql-editing a.ql-action::after { | |
927 | + border-right: 0px; | |
928 | + content: 'Save'; | |
929 | + padding-right: 0px; | |
930 | +} | |
931 | +.ql-snow .ql-tooltip[data-mode=link]::before { | |
932 | + content: "Enter link:"; | |
933 | +} | |
934 | +.ql-snow .ql-tooltip[data-mode=formula]::before { | |
935 | + content: "Enter formula:"; | |
936 | +} | |
937 | +.ql-snow .ql-tooltip[data-mode=video]::before { | |
938 | + content: "Enter video:"; | |
939 | +} | |
940 | +.ql-snow a { | |
941 | + color: #06c; | |
942 | +} | |
943 | +.ql-container.ql-snow { | |
944 | + border: 1px solid #ccc; | |
945 | +} | ... | ... |
1 | +package com.studymachine.www.action; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.graphics.drawable.Drawable; | |
5 | +import android.net.ConnectivityManager; | |
6 | +import android.net.NetworkInfo; | |
7 | + | |
8 | +import androidx.annotation.DrawableRes; | |
9 | +import androidx.annotation.RawRes; | |
10 | +import androidx.annotation.StringRes; | |
11 | +import androidx.core.content.ContextCompat; | |
12 | + | |
13 | +import com.studymachine.www.R; | |
14 | +import com.studymachine.www.widget.StatusLayout; | |
15 | + | |
16 | +/** | |
17 | + * time : 2019/12/08 | |
18 | + * desc : 状态布局意图 | |
19 | + */ | |
20 | +public interface StatusAction { | |
21 | + | |
22 | + /** | |
23 | + * 获取状态布局 | |
24 | + */ | |
25 | + StatusLayout getStatusLayout(); | |
26 | + | |
27 | + /** | |
28 | + * 显示加载中 | |
29 | + */ | |
30 | + default void showLoading() { | |
31 | + showLoading(R.raw.loading); | |
32 | + } | |
33 | + | |
34 | + default void showLoading(@RawRes int id) { | |
35 | + StatusLayout layout = getStatusLayout(); | |
36 | + layout.show(); | |
37 | + layout.setAnimResource(id); | |
38 | + layout.setHint(""); | |
39 | + layout.setOnRetryListener(null); | |
40 | + } | |
41 | + | |
42 | + /** | |
43 | + * 显示加载完成 | |
44 | + */ | |
45 | + default void showComplete() { | |
46 | + StatusLayout layout = getStatusLayout(); | |
47 | + if (layout == null || !layout.isShow()) { | |
48 | + return; | |
49 | + } | |
50 | + layout.hide(); | |
51 | + } | |
52 | + | |
53 | + /** | |
54 | + * 显示空提示 | |
55 | + */ | |
56 | + default void showEmpty() { | |
57 | + showLayout(R.drawable.common_status_empty, R.string.status_layout_no_data, null); | |
58 | + } | |
59 | + | |
60 | + /** | |
61 | + * 显示错误提示 | |
62 | + */ | |
63 | + default void showError(StatusLayout.OnRetryListener listener) { | |
64 | + StatusLayout layout = getStatusLayout(); | |
65 | + Context context = layout.getContext(); | |
66 | + ConnectivityManager manager = ContextCompat.getSystemService(context, ConnectivityManager.class); | |
67 | + if (manager != null) { | |
68 | + NetworkInfo info = manager.getActiveNetworkInfo(); | |
69 | + // 判断网络是否连接 | |
70 | + if (info == null || !info.isConnected()) { | |
71 | + showLayout(R.drawable.status_network_ic, R.string.status_layout_error_network, listener); | |
72 | + return; | |
73 | + } | |
74 | + } | |
75 | + showLayout(R.drawable.status_error_ic, R.string.status_layout_error_request, listener); | |
76 | + } | |
77 | + | |
78 | + /** | |
79 | + * 显示自定义提示 | |
80 | + */ | |
81 | + default void showLayout(@DrawableRes int drawableId, @StringRes int stringId, StatusLayout.OnRetryListener listener) { | |
82 | + StatusLayout layout = getStatusLayout(); | |
83 | + Context context = layout.getContext(); | |
84 | + showLayout(ContextCompat.getDrawable(context, drawableId), context.getString(stringId), listener); | |
85 | + } | |
86 | + | |
87 | + default void showLayout(Drawable drawable, CharSequence hint, StatusLayout.OnRetryListener listener) { | |
88 | + StatusLayout layout = getStatusLayout(); | |
89 | + layout.show(); | |
90 | + layout.setIcon(drawable); | |
91 | + layout.setHint(hint); | |
92 | + layout.setOnRetryListener(listener); | |
93 | + } | |
94 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.action; | |
2 | + | |
3 | +import android.graphics.drawable.Drawable; | |
4 | +import android.view.View; | |
5 | +import android.view.ViewGroup; | |
6 | + | |
7 | +import androidx.annotation.Nullable; | |
8 | +import androidx.annotation.StringRes; | |
9 | + | |
10 | +import com.hjq.bar.OnTitleBarListener; | |
11 | +import com.hjq.bar.TitleBar; | |
12 | + | |
13 | +/** | |
14 | + * time : 2019/12/08 | |
15 | + * desc : 标题栏意图 | |
16 | + */ | |
17 | +public interface TitleBarAction extends OnTitleBarListener { | |
18 | + | |
19 | + @Nullable | |
20 | + TitleBar getTitleBar(); | |
21 | + | |
22 | + /** | |
23 | + * 左项被点击 | |
24 | + * | |
25 | + * @param view 被点击的左项View | |
26 | + */ | |
27 | + @Override | |
28 | + default void onLeftClick(View view) {} | |
29 | + | |
30 | + /** | |
31 | + * 标题被点击 | |
32 | + * | |
33 | + * @param view 被点击的标题View | |
34 | + */ | |
35 | + @Override | |
36 | + default void onTitleClick(View view) {} | |
37 | + | |
38 | + /** | |
39 | + * 右项被点击 | |
40 | + * | |
41 | + * @param view 被点击的右项View | |
42 | + */ | |
43 | + @Override | |
44 | + default void onRightClick(View view) {} | |
45 | + | |
46 | + /** | |
47 | + * 设置标题栏的标题 | |
48 | + */ | |
49 | + default void setTitle(@StringRes int id) { | |
50 | + if (getTitleBar() != null) { | |
51 | + setTitle(getTitleBar().getResources().getString(id)); | |
52 | + } | |
53 | + } | |
54 | + | |
55 | + /** | |
56 | + * 设置标题栏的标题 | |
57 | + */ | |
58 | + default void setTitle(CharSequence title) { | |
59 | + if (getTitleBar() != null) { | |
60 | + getTitleBar().setTitle(title); | |
61 | + } | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * 设置标题栏的左标题 | |
66 | + */ | |
67 | + default void setLeftTitle(int id) { | |
68 | + if (getTitleBar() != null) { | |
69 | + getTitleBar().setLeftTitle(id); | |
70 | + } | |
71 | + } | |
72 | + | |
73 | + default void setLeftTitle(CharSequence text) { | |
74 | + if (getTitleBar() != null) { | |
75 | + getTitleBar().setLeftTitle(text); | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + default CharSequence getLeftTitle() { | |
80 | + if (getTitleBar() != null) { | |
81 | + return getTitleBar().getLeftTitle(); | |
82 | + } | |
83 | + return ""; | |
84 | + } | |
85 | + | |
86 | + /** | |
87 | + * 设置标题栏的右标题 | |
88 | + */ | |
89 | + default void setRightTitle(int id) { | |
90 | + if (getTitleBar() != null) { | |
91 | + getTitleBar().setRightTitle(id); | |
92 | + } | |
93 | + } | |
94 | + | |
95 | + default void setRightTitle(CharSequence text) { | |
96 | + if (getTitleBar() != null) { | |
97 | + getTitleBar().setRightTitle(text); | |
98 | + } | |
99 | + } | |
100 | + | |
101 | + default CharSequence getRightTitle() { | |
102 | + if (getTitleBar() != null) { | |
103 | + return getTitleBar().getRightTitle(); | |
104 | + } | |
105 | + return ""; | |
106 | + } | |
107 | + | |
108 | + /** | |
109 | + * 设置标题栏的左图标 | |
110 | + */ | |
111 | + default void setLeftIcon(int id) { | |
112 | + if (getTitleBar() != null) { | |
113 | + getTitleBar().setLeftIcon(id); | |
114 | + } | |
115 | + } | |
116 | + | |
117 | + default void setLeftIcon(Drawable drawable) { | |
118 | + if (getTitleBar() != null) { | |
119 | + getTitleBar().setLeftIcon(drawable); | |
120 | + } | |
121 | + } | |
122 | + | |
123 | + @Nullable | |
124 | + default Drawable getLeftIcon() { | |
125 | + if (getTitleBar() != null) { | |
126 | + return getTitleBar().getLeftIcon(); | |
127 | + } | |
128 | + return null; | |
129 | + } | |
130 | + | |
131 | + /** | |
132 | + * 设置标题栏的右图标 | |
133 | + */ | |
134 | + default void setRightIcon(int id) { | |
135 | + if (getTitleBar() != null) { | |
136 | + getTitleBar().setRightIcon(id); | |
137 | + } | |
138 | + } | |
139 | + | |
140 | + default void setRightIcon(Drawable drawable) { | |
141 | + if (getTitleBar() != null) { | |
142 | + getTitleBar().setRightIcon(drawable); | |
143 | + } | |
144 | + } | |
145 | + | |
146 | + @Nullable | |
147 | + default Drawable getRightIcon() { | |
148 | + if (getTitleBar() != null) { | |
149 | + return getTitleBar().getRightIcon(); | |
150 | + } | |
151 | + return null; | |
152 | + } | |
153 | + | |
154 | + /** | |
155 | + * 递归获取 ViewGroup 中的 TitleBar 对象 | |
156 | + */ | |
157 | + default TitleBar obtainTitleBar(ViewGroup group) { | |
158 | + if (group == null) { | |
159 | + return null; | |
160 | + } | |
161 | + for (int i = 0; i < group.getChildCount(); i++) { | |
162 | + View view = group.getChildAt(i); | |
163 | + if ((view instanceof TitleBar)) { | |
164 | + return (TitleBar) view; | |
165 | + } | |
166 | + | |
167 | + if (view instanceof ViewGroup) { | |
168 | + TitleBar titleBar = obtainTitleBar((ViewGroup) view); | |
169 | + if (titleBar != null) { | |
170 | + return titleBar; | |
171 | + } | |
172 | + } | |
173 | + } | |
174 | + return null; | |
175 | + } | |
176 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.action; | |
2 | + | |
3 | +import androidx.annotation.StringRes; | |
4 | + | |
5 | +import com.hjq.toast.ToastUtils; | |
6 | + | |
7 | +/** | |
8 | + * time : 2019/12/08 | |
9 | + * desc : 吐司意图 | |
10 | + */ | |
11 | +public interface ToastAction { | |
12 | + | |
13 | + default void toast(CharSequence text) { | |
14 | + ToastUtils.show(text); | |
15 | + } | |
16 | + | |
17 | + default void toast(@StringRes int id) { | |
18 | + ToastUtils.show(id); | |
19 | + } | |
20 | + | |
21 | + default void toast(Object object) { | |
22 | + ToastUtils.show(object); | |
23 | + } | |
24 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import java.lang.annotation.ElementType; | |
4 | +import java.lang.annotation.Retention; | |
5 | +import java.lang.annotation.RetentionPolicy; | |
6 | +import java.lang.annotation.Target; | |
7 | + | |
8 | +/** | |
9 | + * time : 2020/01/11 | |
10 | + * desc : 网络检测注解 | |
11 | + */ | |
12 | +@Retention(RetentionPolicy.RUNTIME) | |
13 | +@Target(ElementType.METHOD) | |
14 | +public @interface CheckNet {} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.app.Application; | |
5 | +import android.net.ConnectivityManager; | |
6 | +import android.net.NetworkInfo; | |
7 | + | |
8 | +import androidx.core.content.ContextCompat; | |
9 | +import androidx.lifecycle.Lifecycle; | |
10 | +import androidx.lifecycle.LifecycleOwner; | |
11 | + | |
12 | +import com.studymachine.www.R; | |
13 | +import com.studymachine.www.manager.ActivityManager; | |
14 | +import com.hjq.toast.ToastUtils; | |
15 | +import com.studymachine.www.ui.activity.NoNetworkActivity; | |
16 | + | |
17 | +import org.aspectj.lang.ProceedingJoinPoint; | |
18 | +import org.aspectj.lang.annotation.Around; | |
19 | +import org.aspectj.lang.annotation.Aspect; | |
20 | +import org.aspectj.lang.annotation.Pointcut; | |
21 | + | |
22 | +/** | |
23 | + * time : 2020/01/11 | |
24 | + * desc : 网络检测切面 | |
25 | + */ | |
26 | +@Aspect | |
27 | +public class CheckNetAspect { | |
28 | + | |
29 | + /** | |
30 | + * 方法切入点 | |
31 | + */ | |
32 | + @Pointcut("execution(@com.studymachine.www.aop.CheckNet * *(..))") | |
33 | + public void method() {} | |
34 | + | |
35 | + /** | |
36 | + * 在连接点进行方法替换 | |
37 | + */ | |
38 | + @Around("method() && @annotation(checkNet)") | |
39 | + public void aroundJoinPoint(ProceedingJoinPoint joinPoint, CheckNet checkNet) throws Throwable { | |
40 | + Application application = ActivityManager.getInstance().getApplication(); | |
41 | + if (application != null) { | |
42 | + ConnectivityManager manager = ContextCompat.getSystemService(application, ConnectivityManager.class); | |
43 | + if (manager != null) { | |
44 | + NetworkInfo info = manager.getActiveNetworkInfo(); | |
45 | + // 判断网络是否连接 | |
46 | + if (info == null || !info.isConnected()) { | |
47 | + ToastUtils.show(R.string.common_network_hint); | |
48 | + Activity topActivity = ActivityManager.getInstance().getTopActivity(); | |
49 | + NoNetworkActivity.start(topActivity); | |
50 | + return; | |
51 | + } | |
52 | + } | |
53 | + } | |
54 | + //执行原方法 | |
55 | + joinPoint.proceed(); | |
56 | + } | |
57 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import java.lang.annotation.ElementType; | |
4 | +import java.lang.annotation.Retention; | |
5 | +import java.lang.annotation.RetentionPolicy; | |
6 | +import java.lang.annotation.Target; | |
7 | + | |
8 | +/** | |
9 | + * time : 2019/12/06 | |
10 | + * desc : Debug 日志注解 | |
11 | + */ | |
12 | +@Retention(RetentionPolicy.RUNTIME) | |
13 | +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) | |
14 | +public @interface Log { | |
15 | + | |
16 | + String value() default "AppLog"; | |
17 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import android.os.Looper; | |
4 | +import android.os.Trace; | |
5 | + | |
6 | +import androidx.annotation.NonNull; | |
7 | + | |
8 | +import org.aspectj.lang.ProceedingJoinPoint; | |
9 | +import org.aspectj.lang.Signature; | |
10 | +import org.aspectj.lang.annotation.Around; | |
11 | +import org.aspectj.lang.annotation.Aspect; | |
12 | +import org.aspectj.lang.annotation.Pointcut; | |
13 | +import org.aspectj.lang.reflect.CodeSignature; | |
14 | +import org.aspectj.lang.reflect.MethodSignature; | |
15 | + | |
16 | +import java.util.concurrent.TimeUnit; | |
17 | + | |
18 | +import timber.log.Timber; | |
19 | + | |
20 | +/** | |
21 | + * time : 2019/12/06 | |
22 | + * desc : Debug 日志切面 | |
23 | + */ | |
24 | +@Aspect | |
25 | +public class LogAspect { | |
26 | + | |
27 | + /** | |
28 | + * 构造方法切入点 | |
29 | + */ | |
30 | + @Pointcut("execution(@com.studymachine.www.aop.Log *.new(..))") | |
31 | + public void constructor() {} | |
32 | + | |
33 | + /** | |
34 | + * 方法切入点 | |
35 | + */ | |
36 | + @Pointcut("execution(@com.studymachine.www.aop.Log * *(..))") | |
37 | + public void method() {} | |
38 | + | |
39 | + /** | |
40 | + * 在连接点进行方法替换 | |
41 | + */ | |
42 | + @Around("(method() || constructor()) && @annotation(log)") | |
43 | + public Object aroundJoinPoint(ProceedingJoinPoint joinPoint, Log log) throws Throwable { | |
44 | + enterMethod(joinPoint, log); | |
45 | + | |
46 | + long startNanos = System.nanoTime(); | |
47 | + Object result = joinPoint.proceed(); | |
48 | + long stopNanos = System.nanoTime(); | |
49 | + | |
50 | + exitMethod(joinPoint, log, result, TimeUnit.NANOSECONDS.toMillis(stopNanos - startNanos)); | |
51 | + | |
52 | + return result; | |
53 | + } | |
54 | + | |
55 | + /** | |
56 | + * 方法执行前切入 | |
57 | + */ | |
58 | + private void enterMethod(ProceedingJoinPoint joinPoint, Log log) { | |
59 | + CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature(); | |
60 | + | |
61 | + // 方法所在类 | |
62 | + String className = codeSignature.getDeclaringType().getName(); | |
63 | + // 方法名 | |
64 | + String methodName = codeSignature.getName(); | |
65 | + // 方法参数名集合 | |
66 | + String[] parameterNames = codeSignature.getParameterNames(); | |
67 | + // 方法参数值集合 | |
68 | + Object[] parameterValues = joinPoint.getArgs(); | |
69 | + | |
70 | + //记录并打印方法的信息 | |
71 | + StringBuilder builder = getMethodLogInfo(className, methodName, parameterNames, parameterValues); | |
72 | + | |
73 | + log(log.value(), builder.toString()); | |
74 | + | |
75 | + final String section = builder.substring(2); | |
76 | + Trace.beginSection(section); | |
77 | + } | |
78 | + | |
79 | + /** | |
80 | + * 获取方法的日志信息 | |
81 | + * | |
82 | + * @param className 类名 | |
83 | + * @param methodName 方法名 | |
84 | + * @param parameterNames 方法参数名集合 | |
85 | + * @param parameterValues 方法参数值集合 | |
86 | + */ | |
87 | + @NonNull | |
88 | + private StringBuilder getMethodLogInfo(String className, String methodName, String[] parameterNames, Object[] parameterValues) { | |
89 | + StringBuilder builder = new StringBuilder("\u21E2 "); | |
90 | + builder.append(className) | |
91 | + .append(".") | |
92 | + .append(methodName) | |
93 | + .append('('); | |
94 | + for (int i = 0; i < parameterValues.length; i++) { | |
95 | + if (i > 0) { | |
96 | + builder.append(", "); | |
97 | + } | |
98 | + builder.append(parameterNames[i]).append('='); | |
99 | + builder.append(parameterValues[i].toString()); | |
100 | + } | |
101 | + builder.append(')'); | |
102 | + | |
103 | + if (Looper.myLooper() != Looper.getMainLooper()) { | |
104 | + builder.append(" [Thread:\"").append(Thread.currentThread().getName()).append("\"]"); | |
105 | + } | |
106 | + return builder; | |
107 | + } | |
108 | + | |
109 | + | |
110 | + /** | |
111 | + * 方法执行完毕,切出 | |
112 | + * | |
113 | + * @param result 方法执行后的结果 | |
114 | + * @param lengthMillis 执行方法所需要的时间 | |
115 | + */ | |
116 | + private void exitMethod(ProceedingJoinPoint joinPoint, Log log, Object result, long lengthMillis) { | |
117 | + Trace.endSection(); | |
118 | + | |
119 | + Signature signature = joinPoint.getSignature(); | |
120 | + | |
121 | + String className = signature.getDeclaringType().getName(); | |
122 | + String methodName = signature.getName(); | |
123 | + | |
124 | + StringBuilder builder = new StringBuilder("\u21E0 ") | |
125 | + .append(className) | |
126 | + .append(".") | |
127 | + .append(methodName) | |
128 | + .append(" [") | |
129 | + .append(lengthMillis) | |
130 | + .append("ms]"); | |
131 | + | |
132 | + // 判断方法是否有返回值 | |
133 | + if (signature instanceof MethodSignature && ((MethodSignature) signature).getReturnType() != void.class) { | |
134 | + builder.append(" = "); | |
135 | + builder.append(result.toString()); | |
136 | + } | |
137 | + | |
138 | + log(log.value(), builder.toString()); | |
139 | + } | |
140 | + | |
141 | + private void log(String tag, String msg) { | |
142 | + Timber.tag(tag); | |
143 | + Timber.d(msg); | |
144 | + } | |
145 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import java.lang.annotation.ElementType; | |
4 | +import java.lang.annotation.Retention; | |
5 | +import java.lang.annotation.RetentionPolicy; | |
6 | +import java.lang.annotation.Target; | |
7 | + | |
8 | +/** | |
9 | + * time : 2019/12/06 | |
10 | + * desc : 权限申请注解 | |
11 | + */ | |
12 | +@Retention(RetentionPolicy.RUNTIME) | |
13 | +@Target({ElementType.METHOD}) | |
14 | +public @interface Permissions { | |
15 | + | |
16 | + /** | |
17 | + * 需要申请权限的集合 | |
18 | + */ | |
19 | + String[] value(); | |
20 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | + | |
5 | +import com.studymachine.www.manager.ActivityManager; | |
6 | +import com.studymachine.www.other.PermissionCallback; | |
7 | +import com.hjq.permissions.XXPermissions; | |
8 | +import com.tencent.bugly.crashreport.CrashReport; | |
9 | + | |
10 | +import org.aspectj.lang.ProceedingJoinPoint; | |
11 | +import org.aspectj.lang.annotation.Around; | |
12 | +import org.aspectj.lang.annotation.Aspect; | |
13 | +import org.aspectj.lang.annotation.Pointcut; | |
14 | + | |
15 | +import java.util.List; | |
16 | + | |
17 | +import timber.log.Timber; | |
18 | + | |
19 | +/** | |
20 | + * time : 2019/12/06 | |
21 | + * desc : 权限申请切面 | |
22 | + */ | |
23 | +@Aspect | |
24 | +public class PermissionsAspect { | |
25 | + | |
26 | + /** | |
27 | + * 方法切入点 | |
28 | + */ | |
29 | + @Pointcut("execution(@com.studymachine.www.aop.Permissions * *(..))") | |
30 | + public void method() {} | |
31 | + | |
32 | + /** | |
33 | + * 在连接点进行方法替换 | |
34 | + */ | |
35 | + @Around("method() && @annotation(permissions)") | |
36 | + public void aroundJoinPoint(ProceedingJoinPoint joinPoint, Permissions permissions) { | |
37 | + Activity activity = null; | |
38 | + | |
39 | + // 方法参数值集合 | |
40 | + Object[] parameterValues = joinPoint.getArgs(); | |
41 | + for (Object arg : parameterValues) { | |
42 | + if (!(arg instanceof Activity)) { | |
43 | + continue; | |
44 | + } | |
45 | + activity = (Activity) arg; | |
46 | + break; | |
47 | + } | |
48 | + | |
49 | + if (activity == null || activity.isFinishing() || activity.isDestroyed()) { | |
50 | + activity = ActivityManager.getInstance().getTopActivity(); | |
51 | + } | |
52 | + | |
53 | + if (activity == null || activity.isFinishing() || activity.isDestroyed()) { | |
54 | + Timber.e("The activity has been destroyed and permission requests cannot be made"); | |
55 | + return; | |
56 | + } | |
57 | + | |
58 | + requestPermissions(joinPoint, activity, permissions.value()); | |
59 | + } | |
60 | + | |
61 | + private void requestPermissions(ProceedingJoinPoint joinPoint, Activity activity, String[] permissions) { | |
62 | + XXPermissions.with(activity) | |
63 | + .permission(permissions) | |
64 | + .request(new PermissionCallback() { | |
65 | + | |
66 | + @Override | |
67 | + public void onGranted(List<String> permissions, boolean all) { | |
68 | + if (all) { | |
69 | + try { | |
70 | + // 获得权限,执行原方法 | |
71 | + joinPoint.proceed(); | |
72 | + } catch (Throwable e) { | |
73 | + CrashReport.postCatchedException(e); | |
74 | + } | |
75 | + } | |
76 | + } | |
77 | + }); | |
78 | + } | |
79 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import java.lang.annotation.ElementType; | |
4 | +import java.lang.annotation.Retention; | |
5 | +import java.lang.annotation.RetentionPolicy; | |
6 | +import java.lang.annotation.Target; | |
7 | + | |
8 | +/** | |
9 | + * time : 2019/12/06 | |
10 | + * desc : 防重复点击注解 | |
11 | + */ | |
12 | +@Retention(RetentionPolicy.RUNTIME) | |
13 | +@Target(ElementType.METHOD) | |
14 | +public @interface SingleClick { | |
15 | + | |
16 | + /** | |
17 | + * 快速点击的间隔 | |
18 | + */ | |
19 | + long value() default 1000; | |
20 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.aop; | |
2 | + | |
3 | +import org.aspectj.lang.ProceedingJoinPoint; | |
4 | +import org.aspectj.lang.annotation.Around; | |
5 | +import org.aspectj.lang.annotation.Aspect; | |
6 | +import org.aspectj.lang.annotation.Pointcut; | |
7 | +import org.aspectj.lang.reflect.CodeSignature; | |
8 | + | |
9 | +import timber.log.Timber; | |
10 | + | |
11 | +/** | |
12 | + * time : 2019/12/06 | |
13 | + * desc : 防重复点击切面 | |
14 | + */ | |
15 | +@Aspect | |
16 | +public class SingleClickAspect { | |
17 | + | |
18 | + /** 最近一次点击的时间 */ | |
19 | + private long mLastTime; | |
20 | + | |
21 | + /** 最近一次点击的标记 */ | |
22 | + private String mLastTag; | |
23 | + | |
24 | + /** | |
25 | + * 方法切入点 | |
26 | + */ | |
27 | + @Pointcut("execution(@com.studymachine.www.aop.SingleClick * *(..))") | |
28 | + public void method() {} | |
29 | + | |
30 | + /** | |
31 | + * 在连接点进行方法替换 | |
32 | + */ | |
33 | + @Around("method() && @annotation(singleClick)") | |
34 | + public void aroundJoinPoint(ProceedingJoinPoint joinPoint, SingleClick singleClick) throws Throwable { | |
35 | + CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature(); | |
36 | + // 方法所在类 | |
37 | + String className = codeSignature.getDeclaringType().getName(); | |
38 | + // 方法名 | |
39 | + String methodName = codeSignature.getName(); | |
40 | + // 构建方法 TAG | |
41 | + StringBuilder builder = new StringBuilder(className + "." + methodName); | |
42 | + builder.append("("); | |
43 | + Object[] parameterValues = joinPoint.getArgs(); | |
44 | + for (int i = 0; i < parameterValues.length; i++) { | |
45 | + Object arg = parameterValues[i]; | |
46 | + if (i == 0) { | |
47 | + builder.append(arg); | |
48 | + } else { | |
49 | + builder.append(", ") | |
50 | + .append(arg); | |
51 | + } | |
52 | + } | |
53 | + builder.append(")"); | |
54 | + | |
55 | + String tag = builder.toString(); | |
56 | + long currentTimeMillis = System.currentTimeMillis(); | |
57 | + if (currentTimeMillis - mLastTime < singleClick.value() && tag.equals(mLastTag)) { | |
58 | + Timber.tag("SingleClick"); | |
59 | + Timber.i("%s 毫秒内发生快速点击:%s", singleClick.value(), tag); | |
60 | + return; | |
61 | + } | |
62 | + mLastTime = currentTimeMillis; | |
63 | + mLastTag = tag; | |
64 | + // 执行原方法 | |
65 | + joinPoint.proceed(); | |
66 | + } | |
67 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.app; | |
2 | + | |
3 | +import android.content.Intent; | |
4 | +import android.os.Bundle; | |
5 | +import android.view.View; | |
6 | +import android.view.WindowManager; | |
7 | + | |
8 | +import androidx.annotation.NonNull; | |
9 | +import androidx.annotation.Nullable; | |
10 | +import androidx.annotation.StringRes; | |
11 | + | |
12 | +import com.gyf.immersionbar.BarHide; | |
13 | +import com.gyf.immersionbar.ImmersionBar; | |
14 | +import com.hjq.bar.TitleBar; | |
15 | +import com.hjq.base.BaseActivity; | |
16 | +import com.hjq.base.BaseDialog; | |
17 | +import com.studymachine.www.R; | |
18 | +import com.studymachine.www.action.TitleBarAction; | |
19 | +import com.studymachine.www.action.ToastAction; | |
20 | +import com.studymachine.www.http.model.HttpData; | |
21 | +import com.studymachine.www.manager.EventBusManager; | |
22 | +import com.studymachine.www.other.Tool; | |
23 | +import com.studymachine.www.ui.activity.HomeActivity; | |
24 | +import com.studymachine.www.ui.dialog.WaitDialog; | |
25 | +import com.hjq.http.listener.OnHttpListener; | |
26 | + | |
27 | +import org.greenrobot.eventbus.EventBus; | |
28 | + | |
29 | +import okhttp3.Call; | |
30 | + | |
31 | +/** | |
32 | + * time : 2018/10/18 | |
33 | + * desc : Activity 业务基类 | |
34 | + */ | |
35 | +public abstract class AppActivity extends BaseActivity | |
36 | + implements ToastAction, TitleBarAction, OnHttpListener<Object> { | |
37 | + | |
38 | + /** | |
39 | + * 标题栏对象 | |
40 | + */ | |
41 | + private TitleBar mTitleBar; | |
42 | + /** | |
43 | + * 状态栏沉浸 | |
44 | + */ | |
45 | + private ImmersionBar mImmersionBar; | |
46 | + | |
47 | + /** | |
48 | + * 加载对话框 | |
49 | + */ | |
50 | + private BaseDialog mDialog; | |
51 | + /** | |
52 | + * 对话框数量 | |
53 | + */ | |
54 | + private int mDialogCount; | |
55 | + | |
56 | + /** | |
57 | + * 当前加载对话框是否在显示中 | |
58 | + */ | |
59 | + public boolean isShowDialog() { | |
60 | + return mDialog != null && mDialog.isShowing(); | |
61 | + } | |
62 | + | |
63 | + /** | |
64 | + * 显示加载对话框 | |
65 | + */ | |
66 | + public void showDialog() { | |
67 | + if (isFinishing() || isDestroyed()) { | |
68 | + return; | |
69 | + } | |
70 | + mDialogCount++; | |
71 | + postDelayed(() -> { | |
72 | + if (mDialogCount <= 0 || isFinishing() || isDestroyed()) { | |
73 | + return; | |
74 | + } | |
75 | + | |
76 | + if (mDialog == null) { | |
77 | + mDialog = new WaitDialog.Builder(this) | |
78 | + .setCancelable(false) | |
79 | + .create(); | |
80 | + } | |
81 | + if (!mDialog.isShowing()) { | |
82 | + mDialog.show(); | |
83 | + } | |
84 | + }, 300); | |
85 | + } | |
86 | + | |
87 | + /** | |
88 | + * 隐藏加载对话框 | |
89 | + */ | |
90 | + public void hideDialog() { | |
91 | + if (isFinishing() || isDestroyed()) { | |
92 | + return; | |
93 | + } | |
94 | + | |
95 | + if (mDialogCount > 0) { | |
96 | + mDialogCount--; | |
97 | + } | |
98 | + | |
99 | + if (mDialogCount != 0 || mDialog == null || !mDialog.isShowing()) { | |
100 | + return; | |
101 | + } | |
102 | + | |
103 | + mDialog.dismiss(); | |
104 | + } | |
105 | + | |
106 | + @Override | |
107 | + protected void initLayout() { | |
108 | + super.initLayout(); | |
109 | + | |
110 | + if (getTitleBar() != null) { | |
111 | + getTitleBar().setOnTitleBarListener(this); | |
112 | + } | |
113 | + | |
114 | + // 初始化沉浸式状态栏 | |
115 | + if (isStatusBarEnabled()) { | |
116 | + getStatusBarConfig().init(); | |
117 | + | |
118 | + // 设置标题栏沉浸 | |
119 | + if (getTitleBar() != null) { | |
120 | + ImmersionBar.setTitleBar(this, getTitleBar()); | |
121 | + } | |
122 | + } | |
123 | + //保持常亮 | |
124 | + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | |
125 | + EventBusManager.register(this); | |
126 | + } | |
127 | + | |
128 | + /** | |
129 | + * 是否使用沉浸式状态栏 | |
130 | + */ | |
131 | + protected boolean isStatusBarEnabled() { | |
132 | + return true; | |
133 | + } | |
134 | + | |
135 | + /** | |
136 | + * 状态栏字体深色模式 | |
137 | + */ | |
138 | + protected boolean isStatusBarDarkFont() { | |
139 | + return true; | |
140 | + } | |
141 | + | |
142 | + /** | |
143 | + * 获取状态栏沉浸的配置对象 | |
144 | + */ | |
145 | + @NonNull | |
146 | + public ImmersionBar getStatusBarConfig() { | |
147 | + if (mImmersionBar == null) { | |
148 | + mImmersionBar = createStatusBarConfig(); | |
149 | + } | |
150 | + return mImmersionBar; | |
151 | + } | |
152 | + | |
153 | + /** | |
154 | + * 初始化沉浸式状态栏 | |
155 | + */ | |
156 | + @NonNull | |
157 | + protected ImmersionBar createStatusBarConfig() { | |
158 | + | |
159 | + return ImmersionBar.with(this) | |
160 | + // 隐藏状态栏和导航栏 | |
161 | + .hideBar(BarHide.FLAG_HIDE_BAR); | |
162 | +// return ImmersionBar.with(this) | |
163 | +// // 默认状态栏字体颜色为黑色 | |
164 | +// .statusBarDarkFont(isStatusBarDarkFont()) | |
165 | +// // 指定导航栏背景颜色 | |
166 | +// .navigationBarColor(R.color.white) | |
167 | +// // 状态栏字体和导航栏内容自动变色,必须指定状态栏颜色和导航栏颜色才可以自动变色 | |
168 | +// .autoDarkModeEnable(true, 0.2f); | |
169 | + } | |
170 | + | |
171 | + /** | |
172 | + * 设置标题栏的标题 | |
173 | + */ | |
174 | + @Override | |
175 | + public void setTitle(@StringRes int id) { | |
176 | + setTitle(getString(id)); | |
177 | + } | |
178 | + | |
179 | + /** | |
180 | + * 设置标题栏的标题 | |
181 | + */ | |
182 | + @Override | |
183 | + public void setTitle(CharSequence title) { | |
184 | + super.setTitle(title); | |
185 | + if (getTitleBar() != null) { | |
186 | + getTitleBar().setTitle(title); | |
187 | + } | |
188 | + } | |
189 | + | |
190 | + @Override | |
191 | + @Nullable | |
192 | + public TitleBar getTitleBar() { | |
193 | + if (mTitleBar == null) { | |
194 | + mTitleBar = obtainTitleBar(getContentView()); | |
195 | + } | |
196 | + return mTitleBar; | |
197 | + } | |
198 | + | |
199 | + @Override | |
200 | + public void onLeftClick(View view) { | |
201 | + onBackPressed(); | |
202 | + } | |
203 | + | |
204 | + @Override | |
205 | + public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { | |
206 | + super.startActivityForResult(intent, requestCode, options); | |
207 | + overridePendingTransition(R.anim.right_in_activity, R.anim.right_out_activity); | |
208 | + } | |
209 | + | |
210 | + @Override | |
211 | + public void finish() { | |
212 | + super.finish(); | |
213 | + overridePendingTransition(R.anim.left_in_activity, R.anim.left_out_activity); | |
214 | + } | |
215 | + | |
216 | + /** | |
217 | + * {@link OnHttpListener} | |
218 | + */ | |
219 | + | |
220 | + @Override | |
221 | + public void onStart(Call call) { | |
222 | + showDialog(); | |
223 | + } | |
224 | + | |
225 | + @Override | |
226 | + public void onSucceed(Object result) { | |
227 | + if (result instanceof HttpData) { | |
228 | + toast(((HttpData<?>) result).getMessage()); | |
229 | + } | |
230 | + } | |
231 | + | |
232 | + @Override | |
233 | + public void onFail(Exception e) { | |
234 | + toast(e.getMessage()); | |
235 | + } | |
236 | + | |
237 | + @Override | |
238 | + public void onEnd(Call call) { | |
239 | + hideDialog(); | |
240 | + } | |
241 | + | |
242 | + @Override | |
243 | + protected void onDestroy() { | |
244 | + super.onDestroy(); | |
245 | + if (isShowDialog()) { | |
246 | + hideDialog(); | |
247 | + } | |
248 | + mDialog = null; | |
249 | + EventBusManager.unregister(this); | |
250 | + } | |
251 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.app; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.view.View; | |
5 | + | |
6 | +import androidx.annotation.IntRange; | |
7 | +import androidx.annotation.LayoutRes; | |
8 | +import androidx.annotation.NonNull; | |
9 | +import androidx.annotation.Nullable; | |
10 | + | |
11 | +import com.hjq.base.BaseAdapter; | |
12 | + | |
13 | +import java.util.ArrayList; | |
14 | +import java.util.List; | |
15 | + | |
16 | + | |
17 | +/** | |
18 | + * time : 2018/12/19 | |
19 | + * desc : RecyclerView 适配器业务基类 | |
20 | + */ | |
21 | +public abstract class AppAdapter<T> extends BaseAdapter<BaseAdapter<?>.ViewHolder> { | |
22 | + | |
23 | + /** 列表数据 */ | |
24 | + private List<T> mDataSet; | |
25 | + /** 当前列表的页码,默认为第一页,用于分页加载功能 */ | |
26 | + private int mPageNumber = 1; | |
27 | + /** 是否是最后一页,默认为false,用于分页加载功能 */ | |
28 | + private boolean mLastPage; | |
29 | + /** 标记对象 */ | |
30 | + private Object mTag; | |
31 | + | |
32 | + public AppAdapter(@NonNull Context context) { | |
33 | + super(context); | |
34 | + } | |
35 | + | |
36 | + @Override | |
37 | + public int getItemCount() { | |
38 | + return getCount(); | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * 获取数据总数 | |
43 | + */ | |
44 | + public int getCount() { | |
45 | + if (mDataSet == null) { | |
46 | + return 0; | |
47 | + } | |
48 | + return mDataSet.size(); | |
49 | + } | |
50 | + | |
51 | + /** | |
52 | + * 设置新的数据 | |
53 | + */ | |
54 | + public void setData(@Nullable List<T> data) { | |
55 | + mDataSet = data; | |
56 | + notifyDataSetChanged(); | |
57 | + } | |
58 | + | |
59 | + /** | |
60 | + * 获取当前数据 | |
61 | + */ | |
62 | + @Nullable | |
63 | + public List<T> getData() { | |
64 | + return mDataSet; | |
65 | + } | |
66 | + | |
67 | + /** | |
68 | + * 追加一些数据 | |
69 | + */ | |
70 | + public void addData(List<T> data) { | |
71 | + if (data == null || data.size() == 0) { | |
72 | + return; | |
73 | + } | |
74 | + | |
75 | + if (mDataSet == null || mDataSet.size() == 0) { | |
76 | + setData(data); | |
77 | + return; | |
78 | + } | |
79 | + | |
80 | + mDataSet.addAll(data); | |
81 | + notifyItemRangeInserted(mDataSet.size() - data.size(), data.size()); | |
82 | + } | |
83 | + | |
84 | + /** | |
85 | + * 清空当前数据 | |
86 | + */ | |
87 | + public void clearData() { | |
88 | + if (mDataSet == null || mDataSet.size() == 0) { | |
89 | + return; | |
90 | + } | |
91 | + | |
92 | + mDataSet.clear(); | |
93 | + notifyDataSetChanged(); | |
94 | + } | |
95 | + | |
96 | + /** | |
97 | + * 是否包含了某个位置上的条目数据 | |
98 | + */ | |
99 | + public boolean containsItem(@IntRange(from = 0) int position) { | |
100 | + return containsItem(getItem(position)); | |
101 | + } | |
102 | + | |
103 | + /** | |
104 | + * 是否包含某个条目数据 | |
105 | + */ | |
106 | + public boolean containsItem(T item) { | |
107 | + if (mDataSet == null || item == null) { | |
108 | + return false; | |
109 | + } | |
110 | + return mDataSet.contains(item); | |
111 | + } | |
112 | + | |
113 | + /** | |
114 | + * 获取某个位置上的数据 | |
115 | + */ | |
116 | + public T getItem(@IntRange(from = 0) int position) { | |
117 | + if (mDataSet == null) { | |
118 | + return null; | |
119 | + } | |
120 | + return mDataSet.get(position); | |
121 | + } | |
122 | + | |
123 | + /** | |
124 | + * 更新某个位置上的数据 | |
125 | + */ | |
126 | + public void setItem(@IntRange(from = 0) int position, @NonNull T item) { | |
127 | + if (mDataSet == null) { | |
128 | + mDataSet = new ArrayList<>(); | |
129 | + } | |
130 | + mDataSet.set(position, item); | |
131 | + notifyItemChanged(position); | |
132 | + } | |
133 | + | |
134 | + /** | |
135 | + * 添加单条数据 | |
136 | + */ | |
137 | + public void addItem(@NonNull T item) { | |
138 | + if (mDataSet == null) { | |
139 | + mDataSet = new ArrayList<>(); | |
140 | + } | |
141 | + addItem(mDataSet.size(), item); | |
142 | + } | |
143 | + | |
144 | + public void addItem(@IntRange(from = 0) int position, @NonNull T item) { | |
145 | + if (mDataSet == null) { | |
146 | + mDataSet = new ArrayList<>(); | |
147 | + } | |
148 | + | |
149 | + if (position < mDataSet.size()) { | |
150 | + mDataSet.add(position, item); | |
151 | + } else { | |
152 | + mDataSet.add(item); | |
153 | + position = mDataSet.size() - 1; | |
154 | + } | |
155 | + notifyItemInserted(position); | |
156 | + } | |
157 | + | |
158 | + /** | |
159 | + * 删除单条数据 | |
160 | + */ | |
161 | + public void removeItem(@NonNull T item) { | |
162 | + int index = mDataSet.indexOf(item); | |
163 | + if (index != -1) { | |
164 | + removeItem(index); | |
165 | + } | |
166 | + } | |
167 | + | |
168 | + public void removeItem(@IntRange(from = 0) int position) { | |
169 | + mDataSet.remove(position); | |
170 | + notifyItemRemoved(position); | |
171 | + } | |
172 | + | |
173 | + /** | |
174 | + * 获取当前的页码 | |
175 | + */ | |
176 | + public int getPageNumber() { | |
177 | + return mPageNumber; | |
178 | + } | |
179 | + | |
180 | + /** | |
181 | + * 设置当前的页码 | |
182 | + */ | |
183 | + public void setPageNumber(@IntRange(from = 0) int number) { | |
184 | + mPageNumber = number; | |
185 | + } | |
186 | + | |
187 | + /** | |
188 | + * 当前是否为最后一页 | |
189 | + */ | |
190 | + public boolean isLastPage() { | |
191 | + return mLastPage; | |
192 | + } | |
193 | + | |
194 | + /** | |
195 | + * 设置是否为最后一页 | |
196 | + */ | |
197 | + public void setLastPage(boolean last) { | |
198 | + mLastPage = last; | |
199 | + } | |
200 | + | |
201 | + /** | |
202 | + * 获取标记 | |
203 | + */ | |
204 | + @Nullable | |
205 | + public Object getTag() { | |
206 | + return mTag; | |
207 | + } | |
208 | + | |
209 | + /** | |
210 | + * 设置标记 | |
211 | + */ | |
212 | + public void setTag(@NonNull Object tag) { | |
213 | + mTag = tag; | |
214 | + } | |
215 | + | |
216 | + public final class SimpleHolder extends ViewHolder { | |
217 | + | |
218 | + public SimpleHolder(@LayoutRes int id) { | |
219 | + super(id); | |
220 | + } | |
221 | + | |
222 | + public SimpleHolder(View itemView) { | |
223 | + super(itemView); | |
224 | + } | |
225 | + | |
226 | + @Override | |
227 | + public void onBindView(int position) {} | |
228 | + } | |
229 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.app; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.app.Application; | |
5 | +import android.content.Context; | |
6 | +import android.hardware.usb.UsbDevice; | |
7 | +import android.net.ConnectivityManager; | |
8 | +import android.net.Network; | |
9 | +import android.os.Build; | |
10 | + | |
11 | +import androidx.annotation.NonNull; | |
12 | +import androidx.core.content.ContextCompat; | |
13 | +import androidx.lifecycle.Lifecycle; | |
14 | +import androidx.lifecycle.LifecycleOwner; | |
15 | +import androidx.lifecycle.MutableLiveData; | |
16 | + | |
17 | +import com.rokid.axr.phone.glassdevice.RKGlassDevice; | |
18 | +import com.rokid.axr.phone.glassdevice.callback.OnGlassDeviceConnectListener; | |
19 | +import com.rokid.axr.phone.glassdevice.hw.GlassSensorListener; | |
20 | + | |
21 | +import com.blankj.utilcode.util.NetworkUtils; | |
22 | +import com.hjq.bar.TitleBar; | |
23 | +import com.hjq.http.EasyHttp; | |
24 | +import com.hjq.http.lifecycle.ApplicationLifecycle; | |
25 | +import com.hjq.http.listener.OnHttpListener; | |
26 | +import com.studymachine.www.R; | |
27 | +import com.studymachine.www.aop.Log; | |
28 | +import com.studymachine.www.http.api.UpdateVersionApi; | |
29 | +import com.studymachine.www.http.glide.GlideApp; | |
30 | +import com.studymachine.www.http.model.HttpData; | |
31 | +import com.studymachine.www.http.model.RequestHandler; | |
32 | +import com.studymachine.www.http.model.RequestServer; | |
33 | +import com.studymachine.www.manager.ActivityManager; | |
34 | +import com.studymachine.www.manager.DictionariesManager; | |
35 | +import com.studymachine.www.manager.EventBusManager; | |
36 | +import com.studymachine.www.manager.UserManager; | |
37 | +import com.studymachine.www.other.AppConfig; | |
38 | +import com.studymachine.www.other.CrashHandler; | |
39 | +import com.studymachine.www.other.DebugLoggerTree; | |
40 | +import com.studymachine.www.other.MaterialHeader; | |
41 | +import com.studymachine.www.other.SmartBallPulseFooter; | |
42 | +import com.studymachine.www.other.TitleBarStyle; | |
43 | +import com.studymachine.www.other.ToastLogInterceptor; | |
44 | +import com.studymachine.www.other.ToastStyle; | |
45 | +import com.hjq.gson.factory.GsonFactory; | |
46 | +import com.hjq.http.EasyConfig; | |
47 | +import com.hjq.toast.ToastUtils; | |
48 | +import com.hjq.umeng.UmengClient; | |
49 | +import com.scwang.smart.refresh.layout.SmartRefreshLayout; | |
50 | +import com.studymachine.www.ui.activity.NoNetworkActivity; | |
51 | +import com.studymachine.www.ui.dialog.NoNetworkDialog; | |
52 | +import com.studymachine.www.ui.dialog.UpdateDialog; | |
53 | +import com.tencent.bugly.crashreport.CrashReport; | |
54 | +import com.tencent.mmkv.MMKV; | |
55 | +import com.tencent.smtt.export.external.TbsCoreSettings; | |
56 | +import com.tencent.smtt.sdk.QbSdk; | |
57 | + | |
58 | +import java.util.HashMap; | |
59 | + | |
60 | +import okhttp3.OkHttpClient; | |
61 | +import timber.log.Timber; | |
62 | + | |
63 | +/** | |
64 | + * desc : 应用入口 | |
65 | + */ | |
66 | +public final class AppApplication extends Application { | |
67 | + | |
68 | + @Log("启动耗时") | |
69 | + @Override | |
70 | + public void onCreate() { | |
71 | + super.onCreate(); | |
72 | + initSdk(this); | |
73 | + initApp(); | |
74 | + } | |
75 | + | |
76 | + private void initApp() { | |
77 | + } | |
78 | + | |
79 | + @Override | |
80 | + protected void attachBaseContext(Context base) { | |
81 | + super.attachBaseContext(base); | |
82 | + } | |
83 | + | |
84 | + @Override | |
85 | + public void onLowMemory() { | |
86 | + super.onLowMemory(); | |
87 | + // 清理所有图片内存缓存 | |
88 | + GlideApp.get(this).onLowMemory(); | |
89 | + } | |
90 | + | |
91 | + @Override | |
92 | + public void onTrimMemory(int level) { | |
93 | + super.onTrimMemory(level); | |
94 | + // 根据手机内存剩余情况清理图片内存缓存 | |
95 | + GlideApp.get(this).onTrimMemory(level); | |
96 | + } | |
97 | + | |
98 | + | |
99 | + /** | |
100 | + * 初始化一些第三方框架 | |
101 | + */ | |
102 | + public static void initSdk(Application application) { | |
103 | + | |
104 | + //初始化x5内核 | |
105 | + initX5app(application); | |
106 | + | |
107 | + // 设置标题栏初始化器 | |
108 | + TitleBar.setDefaultStyle(new TitleBarStyle()); | |
109 | + | |
110 | + // 设置全局的 Header 构建器 | |
111 | + SmartRefreshLayout.setDefaultRefreshHeaderCreator((cx, layout) -> | |
112 | + new MaterialHeader(application).setColorSchemeColors(ContextCompat.getColor(application, R.color.common_accent_color))); | |
113 | + // 设置全局的 Footer 构建器 | |
114 | + SmartRefreshLayout.setDefaultRefreshFooterCreator((cx, layout) -> new SmartBallPulseFooter(application)); | |
115 | + // 设置全局初始化器 | |
116 | + SmartRefreshLayout.setDefaultRefreshInitializer((cx, layout) -> { | |
117 | + // 刷新头部是否跟随内容偏移 | |
118 | + layout.setEnableHeaderTranslationContent(true) | |
119 | + // 刷新尾部是否跟随内容偏移 | |
120 | + .setEnableFooterTranslationContent(true) | |
121 | + // 加载更多是否跟随内容偏移 | |
122 | + .setEnableFooterFollowWhenNoMoreData(true) | |
123 | + // 内容不满一页时是否可以上拉加载更多 | |
124 | + .setEnableLoadMoreWhenContentNotFull(false) | |
125 | + // 仿苹果越界效果开关 | |
126 | + .setEnableOverScrollDrag(false); | |
127 | + }); | |
128 | + | |
129 | + // 初始化吐司 | |
130 | + ToastUtils.init(application, new ToastStyle()); | |
131 | + // 设置调试模式 | |
132 | + ToastUtils.setDebugMode(AppConfig.isDebug()); | |
133 | + // 设置 Toast 拦截器 | |
134 | + ToastUtils.setInterceptor(new ToastLogInterceptor()); | |
135 | + | |
136 | + // EventBus 事件总线 | |
137 | + EventBusManager.init(); | |
138 | + | |
139 | + // 本地异常捕捉 | |
140 | + CrashHandler.register(application); | |
141 | + | |
142 | + // 友盟统计、登录、分享 SDK | |
143 | + UmengClient.init(application, AppConfig.isLogEnable()); | |
144 | + | |
145 | + // Bugly 异常捕捉 | |
146 | + CrashReport.initCrashReport(application, AppConfig.getBuglyId(), AppConfig.isDebug()); | |
147 | + | |
148 | + // Activity 栈管理初始化 | |
149 | + ActivityManager.getInstance().init(application); | |
150 | + | |
151 | + // MMKV 初始化 | |
152 | + MMKV.initialize(application); | |
153 | + RKGlassDevice.getInstance().init(new OnGlassDeviceConnectListener() { | |
154 | + @Override | |
155 | + public void onGlassDeviceConnected(UsbDevice usbDevice) { | |
156 | + //Glass 设备连接成功 | |
157 | + MutableLiveData<Boolean> connectStatus = new MutableLiveData(); | |
158 | + connectStatus.setValue(true); | |
159 | + } | |
160 | + | |
161 | + @Override | |
162 | + public void onGlassDeviceDisconnected() { | |
163 | + //Glass 设备断开连接 | |
164 | + } | |
165 | + }); | |
166 | + // 网络请求框架初始化 | |
167 | + OkHttpClient okHttpClient = new OkHttpClient.Builder() | |
168 | + .build(); | |
169 | + | |
170 | + EasyConfig.with(okHttpClient) | |
171 | + // 是否打印日志 | |
172 | + .setLogEnabled(AppConfig.isLogEnable()) | |
173 | + // 设置服务器配置 | |
174 | + .setServer(new RequestServer()) | |
175 | + // 设置请求处理策略 | |
176 | + .setHandler(new RequestHandler(application)) | |
177 | + // 设置请求重试次数 | |
178 | + .setRetryCount(1) | |
179 | + .setInterceptor((api, params, headers) -> { | |
180 | + // 添加全局请求头 | |
181 | + headers.put("deviceOaid", UmengClient.getDeviceOaid()); | |
182 | + headers.put("versionName", AppConfig.getVersionName()); | |
183 | + headers.put("versionCode", String.valueOf(AppConfig.getVersionCode())); | |
184 | + headers.put("version", String.valueOf(AppConfig.getVersionCode())); | |
185 | + headers.put("client", "android"); | |
186 | + headers.put("clienttype", "1"); | |
187 | + headers.put("Authorization", UserManager.getInstance().getToken()); | |
188 | + // 添加全局请求参数 | |
189 | + }) | |
190 | + .into(); | |
191 | + | |
192 | + // 设置 Json 解析容错监听 | |
193 | + GsonFactory.setJsonCallback((typeToken, fieldName, jsonToken) -> { | |
194 | + // 上报到 Bugly 错误列表 | |
195 | + CrashReport.postCatchedException(new IllegalArgumentException( | |
196 | + "类型解析异常:" + typeToken + "#" + fieldName + ",后台返回的类型为:" + jsonToken)); | |
197 | + }); | |
198 | + | |
199 | + // 初始化日志打印 | |
200 | + if (AppConfig.isLogEnable()) { | |
201 | + Timber.plant(new DebugLoggerTree()); | |
202 | + } | |
203 | + | |
204 | + // 注册网络状态变化监听 | |
205 | + ConnectivityManager connectivityManager = ContextCompat.getSystemService(application, ConnectivityManager.class); | |
206 | + if (connectivityManager != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | |
207 | + connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() { | |
208 | + @Override | |
209 | + public void onLost(@NonNull Network network) { | |
210 | + Timber.tag("网络状态").d("网络已断开连接"); | |
211 | + toNoNetworkActivity(); | |
212 | + } | |
213 | + | |
214 | + @Override | |
215 | + public void onUnavailable() { | |
216 | + Timber.tag("网络状态").d("网络连接超时或者网络连接不可达"); | |
217 | + super.onUnavailable(); | |
218 | + } | |
219 | + | |
220 | + @Override | |
221 | + public void onAvailable(@NonNull Network network) { | |
222 | + super.onAvailable(network); | |
223 | + Timber.tag("网络状态").d("网络连接成功"); | |
224 | + boolean isConnected = NetworkUtils.isAvailableByPing(); | |
225 | + Timber.tag("网络状态").d("网络连接:" + (isConnected ? "成功" : "失败")); | |
226 | + if (!isConnected) { | |
227 | + toNoNetworkActivity(); | |
228 | + } | |
229 | + } | |
230 | + }); | |
231 | + } | |
232 | + } | |
233 | + | |
234 | + private static void toNoNetworkActivity() { | |
235 | + Timber.tag("网络状态").d("跳转无网络"); | |
236 | + Activity topActivity = ActivityManager.getInstance().getTopActivity(); | |
237 | + if (!(topActivity instanceof LifecycleOwner)) { | |
238 | + return; | |
239 | + } | |
240 | + LifecycleOwner lifecycleOwner = ((LifecycleOwner) topActivity); | |
241 | + if (lifecycleOwner.getLifecycle().getCurrentState() != Lifecycle.State.RESUMED) { | |
242 | + return; | |
243 | + } | |
244 | + NoNetworkActivity.start(topActivity); | |
245 | + } | |
246 | + | |
247 | + | |
248 | + public static void initX5app(Context context) { | |
249 | + //设置非wifi条件下允许下载X5内核 | |
250 | + QbSdk.setDownloadWithoutWifi(true); | |
251 | + HashMap map = new HashMap(); | |
252 | + map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true); | |
253 | + map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true); | |
254 | + QbSdk.initTbsSettings(map); | |
255 | + //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。 | |
256 | + QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() { | |
257 | + @Override | |
258 | + public void onCoreInitFinished() { | |
259 | + | |
260 | + } | |
261 | + | |
262 | + /** | |
263 | + * 预初始化结束 | |
264 | + * 由于X5内核体积较大,需要依赖网络动态下发,所以当内核不存在的时候,默认会回调false,此时将会使用系统内核代替 | |
265 | + * @param isX5 是否使用X5内核 | |
266 | + */ | |
267 | + @Override | |
268 | + public void onViewInitFinished(boolean isX5) { | |
269 | + Timber.d("x5内核%s", (isX5 ? "yes" : "no")); | |
270 | + } | |
271 | + }; | |
272 | + | |
273 | + //x5内核初始化接口 | |
274 | + QbSdk.initX5Environment(context, cb); | |
275 | + } | |
276 | +} | |
\ No newline at end of file | ... | ... |
1 | +package com.studymachine.www.app; | |
2 | + | |
3 | + | |
4 | +import com.hjq.base.BaseFragment; | |
5 | +import com.studymachine.www.action.ToastAction; | |
6 | +import com.studymachine.www.http.model.HttpData; | |
7 | +import com.hjq.http.listener.OnHttpListener; | |
8 | +import com.studymachine.www.manager.EventBusManager; | |
9 | + | |
10 | +import okhttp3.Call; | |
11 | + | |
12 | +/** | |
13 | + * time : 2018/10/18 | |
14 | + * desc : Fragment 业务基类 | |
15 | + */ | |
16 | +public abstract class AppFragment<A extends AppActivity> extends BaseFragment<A> | |
17 | + implements ToastAction, OnHttpListener<Object> { | |
18 | + | |
19 | + | |
20 | + @Override | |
21 | + protected void onFragmentResume(boolean first) { | |
22 | + super.onFragmentResume(first); | |
23 | + if(first){ | |
24 | + EventBusManager.register(this); | |
25 | + } | |
26 | + } | |
27 | + | |
28 | + /** | |
29 | + * 当前加载对话框是否在显示中 | |
30 | + */ | |
31 | + public boolean isShowDialog() { | |
32 | + A activity = getAttachActivity(); | |
33 | + if (activity == null) { | |
34 | + return false; | |
35 | + } | |
36 | + return activity.isShowDialog(); | |
37 | + } | |
38 | + | |
39 | + /** | |
40 | + * 显示加载对话框 | |
41 | + */ | |
42 | + public void showDialog() { | |
43 | + A activity = getAttachActivity(); | |
44 | + if (activity == null) { | |
45 | + return; | |
46 | + } | |
47 | + activity.showDialog(); | |
48 | + } | |
49 | + | |
50 | + /** | |
51 | + * 隐藏加载对话框 | |
52 | + */ | |
53 | + public void hideDialog() { | |
54 | + A activity = getAttachActivity(); | |
55 | + if (activity == null) { | |
56 | + return; | |
57 | + } | |
58 | + activity.hideDialog(); | |
59 | + } | |
60 | + | |
61 | + /** | |
62 | + * {@link OnHttpListener} | |
63 | + */ | |
64 | + | |
65 | + @Override | |
66 | + public void onStart(Call call) { | |
67 | + showDialog(); | |
68 | + } | |
69 | + | |
70 | + @Override | |
71 | + public void onSucceed(Object result) { | |
72 | + if (!(result instanceof HttpData)) { | |
73 | + return; | |
74 | + } | |
75 | + toast(((HttpData<?>) result).getMessage()); | |
76 | + } | |
77 | + | |
78 | + @Override | |
79 | + public void onFail(Exception e) { | |
80 | + toast(e.getMessage()); | |
81 | + } | |
82 | + | |
83 | + @Override | |
84 | + public void onEnd(Call call) { | |
85 | + hideDialog(); | |
86 | + } | |
87 | + | |
88 | + @Override | |
89 | + public void onDestroy() { | |
90 | + super.onDestroy(); | |
91 | + EventBusManager.unregister(this); | |
92 | + } | |
93 | +} | |
\ No newline at end of file | ... | ... |