6.3.1 - 新增发布通知权限 / WS 实例创建; 修复 floaty 模块异常 / 安卓 7.x 异常; UI 模式增强; 迁移至 View Binding
This commit is contained in:
@@ -4,6 +4,42 @@
|
||||
|
||||
******
|
||||
|
||||
# v6.3.1
|
||||
|
||||
###### 2023/05/26
|
||||
|
||||
* `新增` 发布通知权限及主页抽屉开关 _[`issue #55`](http://issues.autojs6.com/55)_
|
||||
* `新增` UI 模式支持简单的 Android 布局解析 (参阅 示例代码 > 布局 > 简单安卓布局)
|
||||
* `新增` UI 模式增加 console / imagebutton / ratingbar / switch / textclock / togglebutton 等控件
|
||||
* `新增` UI 模式控件的颜色色值支持 [OmniColor](https://docs.autojs6.com/#/omniTypes?id=omnicolor) 类型 (如 color="orange")
|
||||
* `新增` UI 模式的控件完全支持 attr 方法设置控件属性 (如 ui.text.attr('color', 'blue'))
|
||||
* `新增` UI 模式控件支持布尔类型属性值的缺省形式 (如 clickable="true" 可简写为 clickable 或 isClickable)
|
||||
* `新增` button 控件支持 isColored 及 isBorderless 布尔类型属性
|
||||
* `新增` console.resetGlobalLogConfig 方法用于重置全局日志配置
|
||||
* `新增` web.newWebSocket 方法用于创建 Web Socket 实例 (参阅 项目文档 > [万维网](https://docs.autojs6.com/#/web?id=m-newwebsocket))
|
||||
* `修复` 文件管理器的文件夹排序异常
|
||||
* `修复` floaty 模块构建的浮动窗口无法调节样式及位置的问题 _[`issue #60`](http://issues.autojs6.com/60)_
|
||||
* `修复` floaty 模块构建的浮动窗口与系统状态栏重叠的问题
|
||||
* `修复` http.postMultipart 方法功能异常 _[`issue #56`](http://issues.autojs6.com/56)_
|
||||
* `修复` Android 7.x 无法运行任何脚本的问题 _[`issue #61`](http://issues.autojs6.com/61)_
|
||||
* `修复` sign.property 文件不存在时无法构建项目的问题
|
||||
* `修复` 高版本系统 AutoJs6 置于后台时可能因无前台通知权限而崩溃的问题 (API >= 33)
|
||||
* `修复` 调用 console.show 方法后日志窗口点击 FAB 按钮无法清空日志的问题
|
||||
* `修复` 脚本编辑器调试时出现的 prototype 空指针异常
|
||||
* `修复` 脚本编辑器运行脚本时在缓存文件夹运行临时脚本而非先保存再在原始位置运行以避免可能的脚本内容丢失问题
|
||||
* `修复` 调整布局层次分析的层级色条宽度避免层级过多时控件名称无法显示的问题 _[`issue #46`](http://issues.autojs6.com/46)_
|
||||
* `优化` 布局分析浮动窗口增加退出按钮以关闭窗口 _[`issue #63`](http://issues.autojs6.com/63)_
|
||||
* `优化` 脚本绝对路径使用简称形式以缩减文本长度并增加可读性
|
||||
* `优化` 将 Error 替换为 Exception 避免出现异常时 AutoJs6 应用崩溃
|
||||
* `优化` 视图 (View) 绑定方式由 ButterKnife 迁移至 View Binding _[`issue #48`](http://issues.autojs6.com/48)_
|
||||
* `优化` 服务端模式非正常关闭时将于 AutoJs6 启动时自动开启 _[`issue #64`](http://issues.autojs6.com/64)_
|
||||
* `优化` 客户端模式非正常关闭时将于 AutoJs6 启动时按最近一次的历史地址自动连接
|
||||
* `优化` 升级 Leakcanary 版本 2.10 -> 2.11
|
||||
* `优化` 升级 Android Material 版本 1.8.0 -> 1.9.0
|
||||
* `优化` 升级 Androidx WebKit 版本 1.6.1 -> 1.7.0
|
||||
* `优化` 升级 Okhttp3 版本 3.10.0 -> 5.0.0-alpha.9 -> 5.0.0-alpha.11
|
||||
* `优化` 升级 MLKit Text Recognition Chinese 版本 16.0.0-beta6 -> 16.0.0
|
||||
|
||||
# v6.3.0
|
||||
|
||||
###### 2023/04/29
|
||||
@@ -347,7 +383,7 @@
|
||||
* `新增` 主页抽屉底部增加重启应用按钮
|
||||
* `新增` 主页抽屉增加忽略电池优化/显示在其他应用上层等开关
|
||||
* `修复` 应用初始安装后部分区域主题颜色渲染异常的问题
|
||||
* `修复` sign.property 不存在时无法 build 的问题
|
||||
* `修复` sign.property 文件不存在时无法构建项目的问题
|
||||
* `修复` 定时任务面板一次性任务的月份存取错误
|
||||
* `修复` 应用设置页面开关颜色不随主题变更的问题
|
||||
* `修复` 无法识别打包插件及打包插件下载地址无效的问题
|
||||
|
||||
@@ -1532,6 +1532,10 @@
|
||||
<li><span class="stability_undefined"><a href="#console_setgloballogconfig_config">setGlobalLogConfig(config)</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><span class="stability_undefined"><a href="#console_m_resetgloballogconfig">[m] resetGlobalLogConfig</a></span><ul>
|
||||
<li><span class="stability_undefined"><a href="#console_resetgloballogconfig">resetGlobalLogConfig()</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><span class="stability_undefined"><a href="#console_m_input">[m] input</a></span><ul>
|
||||
<li><span class="stability_undefined"><a href="#console_input_data_args">input(data, ...args)</a></span></li>
|
||||
</ul>
|
||||
@@ -2017,6 +2021,10 @@
|
||||
<li><span class="stability_undefined"><a href="#web_newinjectablewebclient">newInjectableWebClient()</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><span class="stability_undefined"><a href="#web_m_newwebsocket">[m] newWebSocket</a></span><ul>
|
||||
<li><span class="stability_undefined"><a href="#web_newwebsocket_url">newWebSocket(url)</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><span class="stability_undefined"><a href="#http_http">HTTP</a></span><ul>
|
||||
@@ -2541,7 +2549,7 @@ console.log(UiObject.bounds()); /* 访问的是类 UiObject 的静态方法 boun
|
||||
<h3>OCR 特性<span><a class="mark" href="#qa_ocr" id="qa_ocr">#</a></span></h3>
|
||||
<p>AutoJs6 的 OCR 特性是基于 <a href="https://developers.google.com/ml-kit?hl=zh-cn">Google ML Kit</a> 的 <a href="https://developers.google.com/ml-kit/vision/text-recognition/android?hl=zh-cn">文字识别 API</a> 实现的.</p>
|
||||
<blockquote>
|
||||
<p>注: AutoJs6 的 <a href="http://project.autojs6.com/blob/master/app/src/main/java/org/autojs/autojs/runtime/api/MlKitOCR.kt">OCR 实现源码</a> 参考自 <a href="https://github.com/TonyJiangWJ">TonyJiangWJ</a> 的开源项目.</p>
|
||||
<p>注: AutoJs6 的 <a href="http://project.autojs6.com/blob/master/app/src/main/java/org/autojs/autojs/runtime/api/MlKitOCR.kt">OCR 实现源码</a> 参考自 <a href="https://github.com/TonyJiangWJ">TonyJiangWJ</a> 的 <a href="https://github.com/TonyJiangWJ/Auto.js">开源项目</a>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>参阅: <a href="ocr.html">光学字符识别 (OCR)</a> 模块</p>
|
||||
@@ -7615,7 +7623,7 @@ ocr.recognizeText(img, [ 0, 0, 100, 150 ]).filter(text => text.includes('
|
||||
<pre><code class="lang-js">ocr.recognizeText('./picture.jpg'); /* 获取本地图像文件中的所有文本. */
|
||||
</code></pre>
|
||||
<h3>recognizeText(imgPath, region)<span><a class="mark" href="#ocr_recognizetext_imgpath_region" id="ocr_recognizetext_imgpath_region">#</a></span></h3>
|
||||
<p><strong><code>6.3.0</code></strong> <strong><code>Overload [4-5]/6</code></strong></p>
|
||||
<p><strong><code>6.3.0</code></strong> <strong><code>Overload 6/6</code></strong></p>
|
||||
<ul>
|
||||
<li><strong>imgPath</strong> { <span class="type"><a href="dataTypes.html#datatypes_string">string</a></span> } - 图像路径</li>
|
||||
<li><strong>region</strong> { <span class="type"><a href="omniTypes.html#omnitypes_omniregion">OmniRegion</a></span> } - OCR 识别区域</li>
|
||||
@@ -10278,6 +10286,14 @@ console.timeEnd('fruit');
|
||||
maxFileSize: 384 << 10, /* 384 KB. */
|
||||
});
|
||||
</code></pre>
|
||||
<h2>[m] resetGlobalLogConfig<span><a class="mark" href="#console_m_resetgloballogconfig" id="console_m_resetgloballogconfig">#</a></span></h2>
|
||||
<h3>resetGlobalLogConfig()<span><a class="mark" href="#console_resetgloballogconfig" id="console_resetgloballogconfig">#</a></span></h3>
|
||||
<p><strong><code>6.3.1</code></strong></p>
|
||||
<ul>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="dataTypes.html#datatypes_void">void</a></span> }</li>
|
||||
</ul>
|
||||
<p>重置全局日志写入配置.</p>
|
||||
<p>此方法可重置 <a href="#all_m_setgloballogconfig">setGlobalLogConfig</a> 的全部选项配置.</p>
|
||||
<h2>[m] input<span><a class="mark" href="#console_m_input" id="console_m_input">#</a></span></h2>
|
||||
<h3>input(data, ...args)<span><a class="mark" href="#console_input_data_args" id="console_input_data_args">#</a></span></h3>
|
||||
<p><strong><code>ABANDONED</code></strong></p>
|
||||
@@ -10286,7 +10302,7 @@ console.timeEnd('fruit');
|
||||
<li><strong>args</strong> { <span class="type"><a href="documentation.html#documentation_可变参数">...</a><a href="dataTypes.html#datatypes_any">any</a><a href="documentation.html#documentation_可变参数">[]</a></span> } - <a href="glossaries.html#glossaries_占位符替换参数">占位符替换参数</a></li>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="dataTypes.html#datatypes_void">void</a></span> }</li>
|
||||
</ul>
|
||||
<p>此方法已于 <code>6.3.0</code> 版本被废弃, 使用后将无任何效果.</p>
|
||||
<p>此方法已于 <code>6.3.1</code> 版本被废弃, 使用后将无任何效果.</p>
|
||||
<h2>[m] rawInput<span><a class="mark" href="#console_m_rawinput" id="console_m_rawinput">#</a></span></h2>
|
||||
<h3>rawInput(data, ...args)<span><a class="mark" href="#console_rawinput_data_args" id="console_rawinput_data_args">#</a></span></h3>
|
||||
<p><strong><code>ABANDONED</code></strong></p>
|
||||
@@ -10295,7 +10311,7 @@ console.timeEnd('fruit');
|
||||
<li><strong>args</strong> { <span class="type"><a href="documentation.html#documentation_可变参数">...</a><a href="dataTypes.html#datatypes_any">any</a><a href="documentation.html#documentation_可变参数">[]</a></span> } - <a href="glossaries.html#glossaries_占位符替换参数">占位符替换参数</a></li>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="dataTypes.html#datatypes_void">void</a></span> }</li>
|
||||
</ul>
|
||||
<p>此方法已于 <code>6.3.0</code> 版本被废弃, 使用后将无任何效果.
|
||||
<p>此方法已于 <code>6.3.1</code> 版本被废弃, 使用后将无任何效果.
|
||||
<!-- [end-include:console.md] --></p>
|
||||
<!-- [start-include:shell.md] -->
|
||||
<h1>Shell<span><a class="mark" href="#shell_shell" id="shell_shell">#</a></span></h1>
|
||||
@@ -13433,6 +13449,73 @@ settings.setDisplayZoomControls(false);
|
||||
<pre><code class="lang-js">/* 为 webView 对象重新设置一个新的客户端. */
|
||||
webView.setWebViewClient(newInjectableWebClient());
|
||||
</code></pre>
|
||||
<h2>[m] newWebSocket<span><a class="mark" href="#web_m_newwebsocket" id="web_m_newwebsocket">#</a></span></h2>
|
||||
<h3>newWebSocket(url)<span><a class="mark" href="#web_newwebsocket_url" id="web_newwebsocket_url">#</a></span></h3>
|
||||
<p><strong><code>6.3.1</code></strong> <strong><code>Global</code></strong></p>
|
||||
<ul>
|
||||
<li><strong>url</strong> { <span class="type"><a href="dataTypes.html#datatypes_string">string</a></span> }</li>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="webSocketType.html">WebSocket</a></span> }</li>
|
||||
</ul>
|
||||
<p>新建并返回一个 <a href="webSocketType.html">WebSocket</a> 实例.</p>
|
||||
<pre><code class="lang-js">console.setExitOnClose(7e3).show();
|
||||
|
||||
let ws = web.newWebSocket('wss://echo.websocket.events');
|
||||
|
||||
ws
|
||||
.on('open', (res, ws) => {
|
||||
console.log('WebSocket 已连接');
|
||||
})
|
||||
.on('message', (message, ws) => {
|
||||
console.log('接收到消息');
|
||||
// if (message instanceof okio.ByteString) {
|
||||
// console.log(`消息类型: ByteString`);
|
||||
// } else if (typeof message === 'string') {
|
||||
// console.log(`消息类型: String`);
|
||||
// } else {
|
||||
// throw TypeError('Should never happen');
|
||||
// }
|
||||
})
|
||||
.on('text', (text, ws) => {
|
||||
console.info('接收到文本消息:');
|
||||
console.info(`text: ${text}`);
|
||||
})
|
||||
.on('bytes', (bytes, ws) => {
|
||||
console.info('接收到字节数组消息:');
|
||||
console.info(`utf8: ${bytes.utf8()}`);
|
||||
console.info(`base64: ${bytes.base64()}`);
|
||||
console.info(`md5: ${bytes.md5()}`);
|
||||
console.info(`hex: ${bytes.hex()}`);
|
||||
})
|
||||
.on('closing', (code, reason, ws) => {
|
||||
console.log('WebSocket 关闭中');
|
||||
})
|
||||
.on('closed', (code, reason, ws) => {
|
||||
console.log('WebSocket 已关闭');
|
||||
console.log(`code: ${code}`);
|
||||
if (reason) console.log(`reason: ${reason}`);
|
||||
})
|
||||
.on('failure', (err, res, ws) => {
|
||||
console.error('WebSocket 连接失败');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
/* 发送文本消息. */
|
||||
ws.send('Hello WebSocket');
|
||||
|
||||
/* 发送字节数组消息. */
|
||||
ws.send(new okio.ByteString(new java.lang.String('Hello WebSocket').getBytes()));
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('断开 WebSocket');
|
||||
|
||||
/* code 支持的范围 [1000,5000). */
|
||||
/* 1000 表示成功操作或常规的 Socket 关闭操作. */
|
||||
/* 参阅 https://github.com/Luka967/websocket-close-codes */
|
||||
ws.close(1000, 'Closed by user');
|
||||
}, 8e3);
|
||||
|
||||
setTimeout(() => console.log('Exit'), 9e3);
|
||||
</code></pre>
|
||||
<!-- [end-include:web.md] -->
|
||||
<!-- [start-include:http.md] -->
|
||||
<h1>HTTP<span><a class="mark" href="#http_http" id="http_http">#</a></span></h1>
|
||||
@@ -13441,7 +13524,7 @@ webView.setWebViewClient(newInjectableWebClient());
|
||||
<p style="font: italic 1em sans-serif; color: #78909C">Marked by SuperMonster003 on Mar 21, 2023.</p>
|
||||
|
||||
<hr>
|
||||
<p>http模块提供一些进行http请求的函数.</p>
|
||||
<p>http 模块主要用于发送 HTTP 请求, 获取并解析 HTTP 响应.</p>
|
||||
<blockquote>
|
||||
<p>注: 与 <a href="web.html">web</a> 模块不同, web 模块主要用于 WebView 网页的注入及客户端构建.</p>
|
||||
</blockquote>
|
||||
@@ -13578,11 +13661,11 @@ log(res.body.string());
|
||||
<p>选项options可以包含以下属性:</p>
|
||||
<ul>
|
||||
<li><code>headers</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type">Object</a> } 键值对形式的HTTP头部信息. 有关HTTP头部信息, 参见<a href="http://www.runoob.com/http/http-header-fields.html">菜鸟教程:HTTP响应头信息</a>.</li>
|
||||
<li><code>method</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } HTTP请求方法. 包括"GET", "POST", "PUT", "DELET", "PATCH".</li>
|
||||
<li><code>method</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } HTTP请求方法. 包括"GET", "POST", "PUT", "DELETE", "PATCH".</li>
|
||||
<li><code>contentType</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } HTTP头部信息中的"Content-Type", 表示HTTP请求的内容类型. 例如"text/plain", "application/json". 更多信息参见<a href="http://www.runoob.com/http/http-content-type.html">菜鸟教程:HTTP contentType</a>.</li>
|
||||
<li><code>body</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } | { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" class="type">Array</a> } | { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">Function</a> } HTTP请求的内容. 可以是一个字符串, 也可以是一个字节数组;或者是一个以<a href="https://github.com/square/okio/blob/master/okio/src/main/java/okio/BufferedSink.java/">BufferedSink</a>为参数的函数.</li>
|
||||
</ul>
|
||||
<p>该函数是get, post, postJson等函数的基础函数. 因此除非是PUT, DELET等请求, 或者需要更高定制的HTTP请求, 否则直接使用get, post, postJson等函数会更加方便.</p>
|
||||
<p>该函数是get, post, postJson等函数的基础函数. 因此除非是PUT, DELETE等请求, 或者需要更高定制的HTTP请求, 否则直接使用get, post, postJson等函数会更加方便.</p>
|
||||
<h2>[m] buildRequest<span><a class="mark" href="#http_m_buildrequest" id="http_m_buildrequest">#</a></span></h2>
|
||||
<h3>buildRequest(url, options)<span><a class="mark" href="#http_buildrequest_url_options" id="http_buildrequest_url_options">#</a></span></h3>
|
||||
<p>... ...
|
||||
|
||||
@@ -189,12 +189,20 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:left">35 (?)</td>
|
||||
<td style="text-align:left">Android 15</td>
|
||||
<td style="text-align:left">VANILLA_ICE_CREAM</td>
|
||||
<td style="text-align:left">15</td>
|
||||
<td style="text-align:left">Vanilla Ice Cream</td>
|
||||
<td style="text-align:left">Q3, 2024 (?)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:left">34</td>
|
||||
<td style="text-align:left">Android 14</td>
|
||||
<td style="text-align:left">?</td>
|
||||
<td style="text-align:left">UPSIDE_DOWN_CAKE</td>
|
||||
<td style="text-align:left">14</td>
|
||||
<td style="text-align:left">Upside Down Cake</td>
|
||||
<td style="text-align:left">Feb 8, 2023</td>
|
||||
<td style="text-align:left">Q3, 2023 (?)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:left">33</td>
|
||||
@@ -475,6 +483,7 @@
|
||||
<p>要求设备 API 级别不低于指定值:</p>
|
||||
<pre><code class="lang-js">/* 在 API 级别低于 30 的设备上将抛出异常. */
|
||||
runtime.requiresApi(30);
|
||||
runtime.requiresApi(util.versionCodes.R); /* 效果同上. */
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>注: AutoJs6 安装及使用需满足的最低 API 级别为 24 (7.0) [N].</p>
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
<h2>目录</h2>
|
||||
<ul>
|
||||
<li><span class="stability_undefined"><a href="#changelog_changelog">文档更新日志 (Changelog)</a></span><ul>
|
||||
<li><span class="stability_undefined"><a href="#changelog_v1_1_4">v1.1.4</a></span></li>
|
||||
<li><span class="stability_undefined"><a href="#changelog_v1_1_3">v1.1.3</a></span></li>
|
||||
<li><span class="stability_undefined"><a href="#changelog_v1_1_2">v1.1.2</a></span></li>
|
||||
<li><span class="stability_undefined"><a href="#changelog_v1_1_1">v1.1.1</a></span></li>
|
||||
@@ -183,6 +184,15 @@
|
||||
|
||||
<div id="apicontent">
|
||||
<h1>文档更新日志 (Changelog)<span><a class="mark" href="#changelog_changelog" id="changelog_changelog">#</a></span></h1>
|
||||
<h2>v1.1.4<span><a class="mark" href="#changelog_v1_1_4" id="changelog_v1_1_4">#</a></span></h2>
|
||||
<p style="font: bold 0.8em sans-serif; color: #888888">2023/05/26</p>
|
||||
|
||||
<ul>
|
||||
<li><code>新增</code> <a href="https://docs.autojs6.com/#/console?id=m-resetgloballogconfig">console.resetGlobalLogConfig</a> 文档</li>
|
||||
<li><code>新增</code> <a href="https://docs.autojs6.com/#/web?id=m-newwebsocket">web.newWebSocket</a> 文档</li>
|
||||
<li><code>优化</code> 完善 <a href="https://docs.autojs6.com/#/omniTypes">全能类型 (Omnipotent Types)</a> 章节</li>
|
||||
<li><code>优化</code> 完善 <a href="https://docs.autojs6.com/#/apiLevel">安卓 API 级别 (Android API Level)</a> 章节</li>
|
||||
</ul>
|
||||
<h2>v1.1.3<span><a class="mark" href="#changelog_v1_1_3" id="changelog_v1_1_3">#</a></span></h2>
|
||||
<p style="font: bold 0.8em sans-serif; color: #888888">2023/04/29</p>
|
||||
|
||||
@@ -211,7 +221,7 @@
|
||||
<li><code>新增</code> <a href="https://docs.autojs6.com/#/notice">消息通知 (Notice)</a> 文档</li>
|
||||
<li><code>新增</code> <a href="https://docs.autojs6.com/#/httpRequestHeadersType">HttpRequestHeaders</a> / <a href="https://docs.autojs6.com/#/httpResponseHeadersType">HttpResponseHeaders</a> / <a href="https://docs.autojs6.com/#/opencvRectType">OpencvRect</a> 等类型</li>
|
||||
<li><code>新增</code> <a href="https://docs.autojs6.com/#/glossaries?id=通知渠道">通知渠道</a> / <a href="https://docs.autojs6.com/#/glossaries?id=HTTP-标头">HTTP 标头</a> / <a href="https://docs.autojs6.com/#/glossaries?id=MIME-类型">MIME 类型</a> / <a href="https://docs.autojs6.com/#/glossaries?id=HTTP-请求方法">HTTP 请求方法</a> 等术语</li>
|
||||
<li><code>新增</code> <a href="https://docs.autojs6.com/#/color">颜色 (Color)</a> 章节增加 <a href="https://docs.autojs6.com/#/color?id=m-toColorStateList">toColorStateList</a> 及 <a href="https://docs.autojs6.com/#/color?id=m-setPaintColor">setPaintColor</a> 条目</li>
|
||||
<li><code>新增</code> <a href="https://docs.autojs6.com/#/color">颜色 (Color)</a> 章节增加 <a href="https://docs.autojs6.com/#/color?id=m-tocolorstatelist">toColorStateList</a> 及 <a href="https://docs.autojs6.com/#/color?id=m-setpaintcolor">setPaintColor</a> 条目</li>
|
||||
<li><code>修复</code> 文档更新日志条目中的链接无效的问题</li>
|
||||
<li><code>优化</code> 完善 <a href="https://docs.autojs6.com/#/qa">疑难解答 (Q & A)</a> 章节</li>
|
||||
</ul>
|
||||
|
||||
@@ -404,7 +404,7 @@ c.getRed(); // 255
|
||||
c.getRedDouble(); // 1
|
||||
</code></pre>
|
||||
<p>Color 类是对 <a href="color.html">colors</a> 模块的一种变式封装, 用于解决 colors 模块冗余嵌套的难题.</p>
|
||||
<p>如需对颜色 <code>hsv(174,100,59)</code> 设置 <code>80%</code> 透明度然后返回其 Hex 代码:</p>
|
||||
<p>例如需要对颜色 <code>hsv(174,100,59)</code> 设置 <code>80%</code> 透明度然后返回其 Hex 代码:</p>
|
||||
<pre><code class="lang-js">colors.toHex(colors.setAlpha(colors.hsv(174, 100, 59), 0.8));
|
||||
</code></pre>
|
||||
<p>或使用变量拆写形式以增加可读性:</p>
|
||||
@@ -422,7 +422,7 @@ colors.toHex(colorWithAlpha);
|
||||
.toHex();
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>注: 上述示例仅用于演示, 否则可使用 colors.hsva 或 Color#setHsva 同时设置 HSV 分量与 A 分量.</p>
|
||||
<p>注: 上述示例仅用于演示, 实际可使用 colors.hsva 或 Color#setHsva 同时设置 HSV 分量与 A 分量.</p>
|
||||
</blockquote>
|
||||
<p>Color 实例方法的使用方式与 colors 模块对应方法多数情况是类似的, 因此某些情况下可用于替代 colors 模块.</p>
|
||||
<p>以 <code>set</code> 或 <code>remove</code> 为前缀的方法, 通常都会返回 Color 自身类型, 从而支持链式调用, 如 <a href="#colortype_m_setalpha">setAlpha</a>, <a href="#colortype_m_removealpha">removeAlpha</a>, <a href="#colortype_m_setred">setRed</a>, <a href="#colortype_m_removered">removeRed</a>, <a href="#colortype_m_sethsv">setHsv</a>, <a href="#colortype_m_setrgba">setRgba</a> 等.</p>
|
||||
|
||||
@@ -324,6 +324,10 @@
|
||||
<li><span class="stability_undefined"><a href="#console_setgloballogconfig_config">setGlobalLogConfig(config)</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><span class="stability_undefined"><a href="#console_m_resetgloballogconfig">[m] resetGlobalLogConfig</a></span><ul>
|
||||
<li><span class="stability_undefined"><a href="#console_resetgloballogconfig">resetGlobalLogConfig()</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><span class="stability_undefined"><a href="#console_m_input">[m] input</a></span><ul>
|
||||
<li><span class="stability_undefined"><a href="#console_input_data_args">input(data, ...args)</a></span></li>
|
||||
</ul>
|
||||
@@ -1174,6 +1178,14 @@ console.timeEnd('fruit');
|
||||
maxFileSize: 384 << 10, /* 384 KB. */
|
||||
});
|
||||
</code></pre>
|
||||
<h2>[m] resetGlobalLogConfig<span><a class="mark" href="#console_m_resetgloballogconfig" id="console_m_resetgloballogconfig">#</a></span></h2>
|
||||
<h3>resetGlobalLogConfig()<span><a class="mark" href="#console_resetgloballogconfig" id="console_resetgloballogconfig">#</a></span></h3>
|
||||
<p><strong><code>6.3.1</code></strong></p>
|
||||
<ul>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="dataTypes.html#datatypes_void">void</a></span> }</li>
|
||||
</ul>
|
||||
<p>重置全局日志写入配置.</p>
|
||||
<p>此方法可重置 <a href="#console_m_setgloballogconfig">setGlobalLogConfig</a> 的全部选项配置.</p>
|
||||
<h2>[m] input<span><a class="mark" href="#console_m_input" id="console_m_input">#</a></span></h2>
|
||||
<h3>input(data, ...args)<span><a class="mark" href="#console_input_data_args" id="console_input_data_args">#</a></span></h3>
|
||||
<p><strong><code>ABANDONED</code></strong></p>
|
||||
@@ -1182,7 +1194,7 @@ console.timeEnd('fruit');
|
||||
<li><strong>args</strong> { <span class="type"><a href="documentation.html#documentation_可变参数">...</a><a href="dataTypes.html#datatypes_any">any</a><a href="documentation.html#documentation_可变参数">[]</a></span> } - <a href="glossaries.html#glossaries_占位符替换参数">占位符替换参数</a></li>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="dataTypes.html#datatypes_void">void</a></span> }</li>
|
||||
</ul>
|
||||
<p>此方法已于 <code>6.3.0</code> 版本被废弃, 使用后将无任何效果.</p>
|
||||
<p>此方法已于 <code>6.3.1</code> 版本被废弃, 使用后将无任何效果.</p>
|
||||
<h2>[m] rawInput<span><a class="mark" href="#console_m_rawinput" id="console_m_rawinput">#</a></span></h2>
|
||||
<h3>rawInput(data, ...args)<span><a class="mark" href="#console_rawinput_data_args" id="console_rawinput_data_args">#</a></span></h3>
|
||||
<p><strong><code>ABANDONED</code></strong></p>
|
||||
@@ -1191,7 +1203,7 @@ console.timeEnd('fruit');
|
||||
<li><strong>args</strong> { <span class="type"><a href="documentation.html#documentation_可变参数">...</a><a href="dataTypes.html#datatypes_any">any</a><a href="documentation.html#documentation_可变参数">[]</a></span> } - <a href="glossaries.html#glossaries_占位符替换参数">占位符替换参数</a></li>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="dataTypes.html#datatypes_void">void</a></span> }</li>
|
||||
</ul>
|
||||
<p>此方法已于 <code>6.3.0</code> 版本被废弃, 使用后将无任何效果.</p>
|
||||
<p>此方法已于 <code>6.3.1</code> 版本被废弃, 使用后将无任何效果.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -309,7 +309,8 @@ console.build({ titleIconsTint: 'green' }).show();
|
||||
console.build({ contentTextSize: 18 }).show();
|
||||
</code></pre>
|
||||
<h2>[p?] contentTextColor<span><a class="mark" href="#consolebuildoptionstype_p_contenttextcolor" id="consolebuildoptionstype_p_contenttextcolor">#</a></span></h2>
|
||||
<div class="signature"><ul>
|
||||
<p><strong><code>Overload 1/2</code></strong></p>
|
||||
<ul>
|
||||
<li>{{<ul>
|
||||
<li>verbose?: <a href="omniTypes.html#omnitypes_omnicolor">OmniColor</a>;</li>
|
||||
<li>log?: <a href="omniTypes.html#omnitypes_omnicolor">OmniColor</a>;</li>
|
||||
@@ -319,9 +320,9 @@ console.build({ contentTextSize: 18 }).show();
|
||||
<li>assert?: <a href="omniTypes.html#omnitypes_omnicolor">OmniColor</a>;</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>} | <a href="omniTypes.html#omnitypes_omnicolor">OmniColor</a> } - 浮动窗口日志文本字体颜色</li>
|
||||
<li>}} - 浮动窗口日志文本字体颜色</li>
|
||||
</ul>
|
||||
</div><p>设置控制台浮动窗口的日志文本字体颜色, 按日志等级设置一个或多个不同的字体颜色.</p>
|
||||
<p>设置控制台浮动窗口的日志文本字体颜色, 按日志等级设置一个或多个不同的字体颜色.</p>
|
||||
<pre><code class="lang-js">/* 设置 LOG 等级日志字体颜色为深橙色. */
|
||||
console.build({ contentTextColor: { log: 'dark-orange' } }).show();
|
||||
console.log('content text color test for console.log');
|
||||
@@ -344,7 +345,11 @@ console.build({
|
||||
console[fName].call(console, `content text color test for console.${fName}`);
|
||||
});
|
||||
</code></pre>
|
||||
<p>如果希望不区分日志等级, 统一设置所有日志的文本颜色, 可参考下述示例:</p>
|
||||
<p><strong><code>Overload 2/2</code></strong></p>
|
||||
<ul>
|
||||
<li>{ <span class="type"><a href="omniTypes.html#omnitypes_omnicolor">OmniColor</a></span> } - 浮动窗口日志文本统一字体颜色</li>
|
||||
</ul>
|
||||
<p>使用 <code>{ contentTextColor: OmniColor }</code> 时, 不区分日志等级, 统一设置所有日志的文本颜色:</p>
|
||||
<pre><code class="lang-js">/* 所有日志本文的颜色统一设置为深绿色. */
|
||||
console.build({
|
||||
contentTextColor: 'dark-green',
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
<p style="font: italic 1em sans-serif; color: #78909C">Marked by SuperMonster003 on Mar 21, 2023.</p>
|
||||
|
||||
<hr>
|
||||
<p>http模块提供一些进行http请求的函数.</p>
|
||||
<p>http 模块主要用于发送 HTTP 请求, 获取并解析 HTTP 响应.</p>
|
||||
<blockquote>
|
||||
<p>注: 与 <a href="web.html">web</a> 模块不同, web 模块主要用于 WebView 网页的注入及客户端构建.</p>
|
||||
</blockquote>
|
||||
@@ -340,11 +340,11 @@ log(res.body.string());
|
||||
<p>选项options可以包含以下属性:</p>
|
||||
<ul>
|
||||
<li><code>headers</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type">Object</a> } 键值对形式的HTTP头部信息. 有关HTTP头部信息, 参见<a href="http://www.runoob.com/http/http-header-fields.html">菜鸟教程:HTTP响应头信息</a>.</li>
|
||||
<li><code>method</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } HTTP请求方法. 包括"GET", "POST", "PUT", "DELET", "PATCH".</li>
|
||||
<li><code>method</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } HTTP请求方法. 包括"GET", "POST", "PUT", "DELETE", "PATCH".</li>
|
||||
<li><code>contentType</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } HTTP头部信息中的"Content-Type", 表示HTTP请求的内容类型. 例如"text/plain", "application/json". 更多信息参见<a href="http://www.runoob.com/http/http-content-type.html">菜鸟教程:HTTP contentType</a>.</li>
|
||||
<li><code>body</code> { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type">string</a> } | { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" class="type">Array</a> } | { <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">Function</a> } HTTP请求的内容. 可以是一个字符串, 也可以是一个字节数组;或者是一个以<a href="https://github.com/square/okio/blob/master/okio/src/main/java/okio/BufferedSink.java/">BufferedSink</a>为参数的函数.</li>
|
||||
</ul>
|
||||
<p>该函数是get, post, postJson等函数的基础函数. 因此除非是PUT, DELET等请求, 或者需要更高定制的HTTP请求, 否则直接使用get, post, postJson等函数会更加方便.</p>
|
||||
<p>该函数是get, post, postJson等函数的基础函数. 因此除非是PUT, DELETE等请求, 或者需要更高定制的HTTP请求, 否则直接使用get, post, postJson等函数会更加方便.</p>
|
||||
<h2>[m] buildRequest<span><a class="mark" href="#http_m_buildrequest" id="http_m_buildrequest">#</a></span></h2>
|
||||
<h3>buildRequest(url, options)<span><a class="mark" href="#http_buildrequest_url_options" id="http_buildrequest_url_options">#</a></span></h3>
|
||||
<p>... ...</p>
|
||||
|
||||
@@ -316,7 +316,7 @@ ocr.recognizeText(img, [ 0, 0, 100, 150 ]).filter(text => text.includes('
|
||||
<pre><code class="lang-js">ocr.recognizeText('./picture.jpg'); /* 获取本地图像文件中的所有文本. */
|
||||
</code></pre>
|
||||
<h3>recognizeText(imgPath, region)<span><a class="mark" href="#ocr_recognizetext_imgpath_region" id="ocr_recognizetext_imgpath_region">#</a></span></h3>
|
||||
<p><strong><code>6.3.0</code></strong> <strong><code>Overload [4-5]/6</code></strong></p>
|
||||
<p><strong><code>6.3.0</code></strong> <strong><code>Overload 6/6</code></strong></p>
|
||||
<ul>
|
||||
<li><strong>imgPath</strong> { <span class="type"><a href="dataTypes.html#datatypes_string">string</a></span> } - 图像路径</li>
|
||||
<li><strong>region</strong> { <span class="type"><a href="omniTypes.html#omnitypes_omniregion">OmniRegion</a></span> } - OCR 识别区域</li>
|
||||
|
||||
@@ -240,6 +240,35 @@ console.show(); /* 显示控制台悬浮窗. */
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><code>OmniColor</code> 不仅可用于参数传入方法中, 还可以作为 XML 元素的属性值:</p>
|
||||
<pre><code class="lang-js">'ui';
|
||||
|
||||
ui.layout(<vertical>
|
||||
<button text="click to start" color="#006400"/>
|
||||
</vertical>);
|
||||
</code></pre>
|
||||
<p>上述示例设置按钮布局的文字颜色为深绿色, 使用了 <a href="dataTypes.html#datatypes_colorhex">ColorHex</a> 作为颜色值.</p>
|
||||
<p>使用 <a href="dataTypes.html#datatypes_colorname">ColorName</a> 作为颜色值也可达到相同的效果:</p>
|
||||
<pre><code class="lang-js">'ui';
|
||||
|
||||
ui.layout(<vertical>
|
||||
<button text="click to start" color="dark-green"/>
|
||||
</vertical>);
|
||||
</code></pre>
|
||||
<p>使用 <a href="dataTypes.html#datatypes_colorint">ColorInt</a> 作为颜色值同样可以达到相同的效果:</p>
|
||||
<pre><code class="lang-js">'ui';
|
||||
|
||||
ui.layout(<vertical>
|
||||
<button text="click to start" color="-16751616"/>
|
||||
</vertical>);
|
||||
</code></pre>
|
||||
<p>如需使用主题色作为颜色值, 需要使用一对花括号以及绑定全局作用域的表达式:</p>
|
||||
<pre><code class="lang-js">'ui';
|
||||
|
||||
ui.layout(<vertical>
|
||||
<button text="click to start" color="{{autojs.themeColor}}"/>
|
||||
</vertical>);
|
||||
</code></pre>
|
||||
<h2>OmniIntent<span><a class="mark" href="#omnitypes_omniintent" id="omnitypes_omniintent">#</a></span></h2>
|
||||
<p>Intent 聚合类型.</p>
|
||||
<table>
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
<h3>OCR 特性<span><a class="mark" href="#qa_ocr" id="qa_ocr">#</a></span></h3>
|
||||
<p>AutoJs6 的 OCR 特性是基于 <a href="https://developers.google.com/ml-kit?hl=zh-cn">Google ML Kit</a> 的 <a href="https://developers.google.com/ml-kit/vision/text-recognition/android?hl=zh-cn">文字识别 API</a> 实现的.</p>
|
||||
<blockquote>
|
||||
<p>注: AutoJs6 的 <a href="http://project.autojs6.com/blob/master/app/src/main/java/org/autojs/autojs/runtime/api/MlKitOCR.kt">OCR 实现源码</a> 参考自 <a href="https://github.com/TonyJiangWJ">TonyJiangWJ</a> 的开源项目.</p>
|
||||
<p>注: AutoJs6 的 <a href="http://project.autojs6.com/blob/master/app/src/main/java/org/autojs/autojs/runtime/api/MlKitOCR.kt">OCR 实现源码</a> 参考自 <a href="https://github.com/TonyJiangWJ">TonyJiangWJ</a> 的 <a href="https://github.com/TonyJiangWJ/Auto.js">开源项目</a>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>参阅: <a href="ocr.html">光学字符识别 (OCR)</a> 模块</p>
|
||||
|
||||
@@ -175,6 +175,10 @@
|
||||
<li><span class="stability_undefined"><a href="#web_newinjectablewebclient">newInjectableWebClient()</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><span class="stability_undefined"><a href="#web_m_newwebsocket">[m] newWebSocket</a></span><ul>
|
||||
<li><span class="stability_undefined"><a href="#web_newwebsocket_url">newWebSocket(url)</a></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -287,6 +291,73 @@ settings.setDisplayZoomControls(false);
|
||||
<p>新建并返回一个 <a href="injectableWebClientType.html">InjectableWebClient</a> (可 <a href="glossaries.html#glossaries_注入">注入</a> 的 <a href="https://developer.android.com/reference/android/webkit/WebViewClient">WebViewClient</a>) 实例.</p>
|
||||
<pre><code class="lang-js">/* 为 webView 对象重新设置一个新的客户端. */
|
||||
webView.setWebViewClient(newInjectableWebClient());
|
||||
</code></pre>
|
||||
<h2>[m] newWebSocket<span><a class="mark" href="#web_m_newwebsocket" id="web_m_newwebsocket">#</a></span></h2>
|
||||
<h3>newWebSocket(url)<span><a class="mark" href="#web_newwebsocket_url" id="web_newwebsocket_url">#</a></span></h3>
|
||||
<p><strong><code>6.3.1</code></strong> <strong><code>Global</code></strong></p>
|
||||
<ul>
|
||||
<li><strong>url</strong> { <span class="type"><a href="dataTypes.html#datatypes_string">string</a></span> }</li>
|
||||
<li><ins><strong>returns</strong></ins> { <span class="type"><a href="webSocketType.html">WebSocket</a></span> }</li>
|
||||
</ul>
|
||||
<p>新建并返回一个 <a href="webSocketType.html">WebSocket</a> 实例.</p>
|
||||
<pre><code class="lang-js">console.setExitOnClose(7e3).show();
|
||||
|
||||
let ws = web.newWebSocket('wss://echo.websocket.events');
|
||||
|
||||
ws
|
||||
.on('open', (res, ws) => {
|
||||
console.log('WebSocket 已连接');
|
||||
})
|
||||
.on('message', (message, ws) => {
|
||||
console.log('接收到消息');
|
||||
// if (message instanceof okio.ByteString) {
|
||||
// console.log(`消息类型: ByteString`);
|
||||
// } else if (typeof message === 'string') {
|
||||
// console.log(`消息类型: String`);
|
||||
// } else {
|
||||
// throw TypeError('Should never happen');
|
||||
// }
|
||||
})
|
||||
.on('text', (text, ws) => {
|
||||
console.info('接收到文本消息:');
|
||||
console.info(`text: ${text}`);
|
||||
})
|
||||
.on('bytes', (bytes, ws) => {
|
||||
console.info('接收到字节数组消息:');
|
||||
console.info(`utf8: ${bytes.utf8()}`);
|
||||
console.info(`base64: ${bytes.base64()}`);
|
||||
console.info(`md5: ${bytes.md5()}`);
|
||||
console.info(`hex: ${bytes.hex()}`);
|
||||
})
|
||||
.on('closing', (code, reason, ws) => {
|
||||
console.log('WebSocket 关闭中');
|
||||
})
|
||||
.on('closed', (code, reason, ws) => {
|
||||
console.log('WebSocket 已关闭');
|
||||
console.log(`code: ${code}`);
|
||||
if (reason) console.log(`reason: ${reason}`);
|
||||
})
|
||||
.on('failure', (err, res, ws) => {
|
||||
console.error('WebSocket 连接失败');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
/* 发送文本消息. */
|
||||
ws.send('Hello WebSocket');
|
||||
|
||||
/* 发送字节数组消息. */
|
||||
ws.send(new okio.ByteString(new java.lang.String('Hello WebSocket').getBytes()));
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('断开 WebSocket');
|
||||
|
||||
/* code 支持的范围 [1000,5000). */
|
||||
/* 1000 表示成功操作或常规的 Socket 关闭操作. */
|
||||
/* 参阅 https://github.com/Luka967/websocket-close-codes */
|
||||
ws.close(1000, 'Closed by user');
|
||||
}, 8e3);
|
||||
|
||||
setTimeout(() => console.log('Exit'), 9e3);
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// noinspection JSUnusedGlobalSymbols,NpmUsedModulesInstalled,JSUnusedLocalSymbols
|
||||
|
||||
'use strict';
|
||||
|
||||
// @Caution by SuperMonster003 on Apr 19, 2022.
|
||||
// ! Do not declare with const because variable has already
|
||||
// ! declared globally in RhinoJavaScriptEngine.kt.
|
||||
@@ -15,9 +13,11 @@ let RootMode = org.autojs.autojs.util.RootUtils.RootMode;
|
||||
let Pref = org.autojs.autojs.pref.Pref;
|
||||
let Shell = org.autojs.autojs.runtime.api.Shell;
|
||||
let Intent = global.Intent = android.content.Intent;
|
||||
let Context = global.Context = android.content.Context;
|
||||
let PendingIntent = android.app.PendingIntent;
|
||||
let Toast = android.widget.Toast;
|
||||
let KeyEvent = android.view.KeyEvent;
|
||||
let MotionEvent = android.view.MotionEvent;
|
||||
let Version = Packages.io.github.g00fy2.versioncompare.Version;
|
||||
let Image = org.autojs.autojs.core.image.ImageWrapper;
|
||||
let ColorTable = org.autojs.autojs.core.image.ColorTable;
|
||||
@@ -40,17 +40,59 @@ let GlobalAppContext = org.autojs.autojs.app.GlobalAppContext;
|
||||
let DisplayUtils = org.autojs.autojs.util.DisplayUtils;
|
||||
let StringUtils = org.autojs.autojs.util.StringUtils;
|
||||
let ColorUtils = org.autojs.autojs.util.ColorUtils;
|
||||
let TextUtils = org.autojs.autojs.util.TextUtils;
|
||||
let ProxyObject = org.autojs.autojs.rhino.ProxyObject;
|
||||
let ProxyJavaObject = org.autojs.autojs.rhino.ProxyJavaObject;
|
||||
let NotificationManager = android.app.NotificationManager;
|
||||
let NotificationCompat = Packages.androidx.core.app.NotificationCompat;
|
||||
let SecurityException = java.lang.SecurityException;
|
||||
let Locale = java.util.Locale;
|
||||
let URI = java.net.URI;
|
||||
let File = java.io.File;
|
||||
|
||||
/* Global View classes. */
|
||||
|
||||
let JsAppBarLayout = org.autojs.autojs.core.ui.widget.JsAppBarLayout;
|
||||
let JsButton = org.autojs.autojs.core.ui.widget.JsButton;
|
||||
let JsCanvasView = org.autojs.autojs.core.ui.widget.JsCanvasView;
|
||||
let JsCardView = org.autojs.autojs.core.ui.widget.JsCardView;
|
||||
let JsCheckBox = org.autojs.autojs.core.ui.widget.JsCheckBox;
|
||||
let JsConsoleView = org.autojs.autojs.core.ui.widget.JsConsoleView;
|
||||
let JsDatePicker = org.autojs.autojs.core.ui.widget.JsDatePicker;
|
||||
let JsDrawerLayout = org.autojs.autojs.core.ui.widget.JsDrawerLayout;
|
||||
let JsEditText = org.autojs.autojs.core.ui.widget.JsEditText;
|
||||
let JsFloatingActionButton = org.autojs.autojs.core.ui.widget.JsFloatingActionButton;
|
||||
let JsFrameLayout = org.autojs.autojs.core.ui.widget.JsFrameLayout;
|
||||
let JsGridView = org.autojs.autojs.core.ui.widget.JsGridView;
|
||||
let JsImageButton = org.autojs.autojs.core.ui.widget.JsImageButton;
|
||||
let JsImageView = org.autojs.autojs.core.ui.widget.JsImageView;
|
||||
let JsLinearLayout = org.autojs.autojs.core.ui.widget.JsLinearLayout;
|
||||
let JsListView = org.autojs.autojs.core.ui.widget.JsListView;
|
||||
let JsProgressBar = org.autojs.autojs.core.ui.widget.JsProgressBar;
|
||||
let JsRadioButton = org.autojs.autojs.core.ui.widget.JsRadioButton;
|
||||
let JsRadioGroup = org.autojs.autojs.core.ui.widget.JsRadioGroup;
|
||||
let JsRatingBar = org.autojs.autojs.core.ui.widget.JsRatingBar;
|
||||
let JsRelativeLayout = org.autojs.autojs.core.ui.widget.JsRelativeLayout;
|
||||
let JsScrollView = org.autojs.autojs.core.ui.widget.JsScrollView;
|
||||
let JsSeekBar = org.autojs.autojs.core.ui.widget.JsSeekBar;
|
||||
let JsSpinner = org.autojs.autojs.core.ui.widget.JsSpinner;
|
||||
let JsSwitch = org.autojs.autojs.core.ui.widget.JsSwitch;
|
||||
let JsTabLayout = org.autojs.autojs.core.ui.widget.JsTabLayout;
|
||||
let JsTextClock = org.autojs.autojs.core.ui.widget.JsTextClock;
|
||||
let JsTextView = android.os.Build.VERSION.SDK_INT < 26 /* Android API 26 (8.0) [O] */
|
||||
? org.autojs.autojs.core.ui.widget.JsTextViewLegacy
|
||||
: org.autojs.autojs.core.ui.widget.JsTextView;
|
||||
let JsTimePicker = org.autojs.autojs.core.ui.widget.JsTimePicker;
|
||||
let JsToggleButton = org.autojs.autojs.core.ui.widget.JsToggleButton;
|
||||
let JsToolbar = org.autojs.autojs.core.ui.widget.JsToolbar;
|
||||
let JsViewPager = org.autojs.autojs.core.ui.widget.JsViewPager;
|
||||
let JsWebView = org.autojs.autojs.core.ui.widget.JsWebView;
|
||||
|
||||
/* Global assignment. */
|
||||
|
||||
Object.assign(this, {
|
||||
io: Packages.io,
|
||||
okio: Packages.okio,
|
||||
de: Packages.de,
|
||||
ezy: Packages.ezy,
|
||||
kotlin: Packages.kotlin,
|
||||
@@ -264,8 +306,11 @@ Object.assign(this, {
|
||||
if (typeof global[module] === 'object') {
|
||||
if (!(Object.hasOwn(global[module], 'toString'))) {
|
||||
// noinspection JSPotentiallyInvalidConstructorUsage
|
||||
if (typeof global[module].constructor.prototype.toString !== 'function') {
|
||||
global[module].toString = () => module;
|
||||
let prototype = global[module].constructor.prototype;
|
||||
if (prototype !== undefined) /* For AutoJs6 debugger. */ {
|
||||
if (typeof prototype.toString !== 'function') {
|
||||
global[module].toString = () => module;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -415,6 +460,9 @@ Object.assign(this, {
|
||||
[ 'engines', 'continuation', 'http' ],
|
||||
[ 'images', 'colors', 'dialogs' ],
|
||||
|
||||
/* ! http < web */
|
||||
[ 'web' ],
|
||||
|
||||
/* ! files < i18n */
|
||||
/* ! i18n < selector */
|
||||
[ 'i18n', 'selector' ],
|
||||
@@ -438,7 +486,7 @@ Object.assign(this, {
|
||||
|
||||
/* Safe to put last regardless of the order, no guarantee ;). */
|
||||
[ 'floaty', 'storages', 'device', 'recorder', 'toast' ],
|
||||
[ 'media', 'sensors', 'web', 'events', 'base64', 'notice' ],
|
||||
[ 'media', 'sensors', 'events', 'base64', 'notice' ],
|
||||
|
||||
/* Last but not the least */
|
||||
[ 'globals' ],
|
||||
|
||||
@@ -350,7 +350,6 @@ var MODE = {
|
||||
};
|
||||
|
||||
function Beautifier(js_source_text, options) {
|
||||
"use strict";
|
||||
var output;
|
||||
var tokens = [],
|
||||
token_pos;
|
||||
|
||||
@@ -62,6 +62,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
|
||||
Color.prototype = {
|
||||
constructor: Color,
|
||||
toString() {
|
||||
return this.digest();
|
||||
},
|
||||
digest() {
|
||||
return colors.digest.apply(colors, [ this.color ].concat(Array.from(arguments)));
|
||||
},
|
||||
@@ -78,6 +81,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
this.color = colors.setAlpha(this.color, alpha);
|
||||
return this;
|
||||
},
|
||||
setAlphaRelative(percentage) {
|
||||
return this.setAlpha(this.getAlpha() * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
getAlpha() {
|
||||
return colors.alpha(this.color);
|
||||
},
|
||||
@@ -98,6 +104,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
this.color = colors.setRed(this.color, red);
|
||||
return this;
|
||||
},
|
||||
setRedRelative(percentage) {
|
||||
return this.setRed(this.getRed() * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
getRed() {
|
||||
return colors.red(this.color);
|
||||
},
|
||||
@@ -118,6 +127,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
this.color = colors.setGreen(this.color, green);
|
||||
return this;
|
||||
},
|
||||
setGreenRelative(percentage) {
|
||||
return this.setGreen(this.getGreen() * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
getGreen() {
|
||||
return colors.green(this.color);
|
||||
},
|
||||
@@ -138,6 +150,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
this.color = colors.setBlue(this.color, blue);
|
||||
return this;
|
||||
},
|
||||
setBlueRelative(percentage) {
|
||||
return this.setBlue(this.getBlue() * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
getBlue() {
|
||||
return colors.blue(this.color);
|
||||
},
|
||||
@@ -267,6 +282,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
let [ r, g, b ] = this.toRgb(color);
|
||||
return this.toInt(this.argb(alpha, r, g, b));
|
||||
},
|
||||
setAlphaRelative(color, percentage) {
|
||||
return this.setAlpha(color, this.getAlpha(color) * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
removeAlpha(color) {
|
||||
return this.setAlpha(color, 0);
|
||||
},
|
||||
@@ -293,6 +311,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
let [ a, , g, b ] = this.toArgb(color);
|
||||
return this.toInt(this.argb(a, red, g, b));
|
||||
},
|
||||
setRedRelative(color, percentage) {
|
||||
return this.setRed(color, this.getRed(color) * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
removeRed(color) {
|
||||
return this.setRed(color, 0);
|
||||
},
|
||||
@@ -319,6 +340,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
let [ a, r, , b ] = this.toArgb(color);
|
||||
return this.toInt(this.argb(a, r, green, b));
|
||||
},
|
||||
setGreenRelative(color, percentage) {
|
||||
return this.getGreen(color, this.getGreen(color) * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
removeGreen(color) {
|
||||
return this.setGreen(color, 0);
|
||||
},
|
||||
@@ -345,75 +369,27 @@ module.exports = function (scriptRuntime, scope) {
|
||||
let [ a, r, g ] = this.toArgb(color);
|
||||
return this.toInt(this.argb(a, r, g, blue));
|
||||
},
|
||||
setBlueRelative(color, percentage) {
|
||||
return this.setBlue(color, this.getBlue(color) * _.parseRelativePercentage(percentage));
|
||||
},
|
||||
removeBlue(color) {
|
||||
return this.setBlue(color, 0);
|
||||
},
|
||||
toInt(color) {
|
||||
try {
|
||||
return _.parseColor(typeof color === 'number' ? _.toJavaIntegerRange(color) : this.toFullHex(color));
|
||||
} catch (e) {
|
||||
scriptRuntime.console.error(`Passed color: ${color}`);
|
||||
throw Error(e + '\n' + e.stack);
|
||||
if (color instanceof _.Color) {
|
||||
color = color.color;
|
||||
}
|
||||
return ColorUtils.toInt.apply(ColorUtils, [ color ]);
|
||||
},
|
||||
toHex(color, alphaOrLength) {
|
||||
let [ _ignoredArg0, arg1 /* alpha | length */ ] = arguments;
|
||||
|
||||
if (color instanceof _.Color) {
|
||||
return this.toHex.apply(this, [ color.color ].concat(Array.from(arguments).slice(1)));
|
||||
}
|
||||
if (color instanceof ThemeColor) {
|
||||
return this.toHex.apply(this, [ color.getColorPrimary() ].concat(Array.from(arguments).slice(1)));
|
||||
}
|
||||
if (typeof color === 'number') {
|
||||
color = rtColors.toString(_.toJavaIntegerRange(color));
|
||||
if (isNullish(alphaOrLength)) {
|
||||
return ColorUtils.toHex.apply(ColorUtils, [ color ]);
|
||||
} else {
|
||||
color = String(color);
|
||||
return ColorUtils.toHex.apply(ColorUtils, [ color, alphaOrLength ]);
|
||||
}
|
||||
if (color.startsWith('#')) {
|
||||
if (color.length === 4) {
|
||||
color = color.replace(/(#)(\w)(\w)(\w)/, '$1$2$2$3$3$4$4');
|
||||
}
|
||||
} else {
|
||||
if (color === parseInt(color).toString()) {
|
||||
return this.toHex.apply(this, [ parseInt(color) ].concat(Array.from(arguments).slice(1)));
|
||||
}
|
||||
let colorByName = ColorTable.getColorByName(color, true);
|
||||
if (colorByName !== null) {
|
||||
return this.toHex.apply(this, [ colorByName.intValue() ].concat(Array.from(arguments).slice(1)));
|
||||
}
|
||||
}
|
||||
if (!/^#[A-F\d]{3}([A-F\d]{3}([A-F\d]{2})?)?$/i.test(color)) {
|
||||
throw TypeError(`Invalid color string format: ${color}`);
|
||||
}
|
||||
return ( /* @IIFE(toColorHex) */ () => {
|
||||
if (arg1 /* alpha */ === true || arg1 /* alpha */ === 'keep' || arg1 /* length */ === 8) {
|
||||
if (color.length === 7) {
|
||||
color = `#FF${color.slice(1)}`;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
if (arg1 /* alpha */ === false || arg1 /* alpha */ === 'none' || arg1 /* length */ === 6) {
|
||||
return `#${color.slice(-6)}`;
|
||||
}
|
||||
if (arg1 /* length */ === 3) {
|
||||
if (!/^#(?:([A-F\d]){2})?([A-F\d])\2([A-F\d])\3([A-F\d])\4$/i.test(color)) {
|
||||
throw TypeError(`Can't convert color ${color} to #RGB with unexpected color format.`);
|
||||
}
|
||||
let [ r, g, b ] = [ color.slice(-6, -5), color.slice(-4, -3), color.slice(-2, -1) ];
|
||||
return `#${r}${g}${b}`;
|
||||
}
|
||||
if (arg1 /* alpha */ === undefined || arg1 /* alpha */ === 'auto') {
|
||||
return /^#FF([A-F\d]){6}$/i.test(color) ? `#${color.slice(3)}` : color;
|
||||
}
|
||||
throw TypeError('Unknown type of alpha for colors.toString()');
|
||||
})().toUpperCase();
|
||||
},
|
||||
/**
|
||||
* Color to full hex like '#BF110523'.
|
||||
*/
|
||||
toFullHex(color) {
|
||||
return this.toHex(color, 8);
|
||||
return ColorUtils.toFullHex.apply(ColorUtils, [ color ]);
|
||||
},
|
||||
/**
|
||||
* Get hex code string of a color.
|
||||
@@ -870,15 +846,12 @@ module.exports = function (scriptRuntime, scope) {
|
||||
parseNumber(num, def) {
|
||||
return typeof num === 'number' ? num : typeof def === 'function' ? def() : def || 0;
|
||||
},
|
||||
/**
|
||||
* @param {number|string} color
|
||||
* @returns {number}
|
||||
*/
|
||||
parseColor(color) {
|
||||
if (typeof color === 'string') {
|
||||
return rtColors.parseColor(color);
|
||||
parseRelativePercentage(percentage) {
|
||||
let p = Numberx.parseAny(percentage);
|
||||
if (isNaN(p) || p < 0) {
|
||||
throw TypeError(`Relative percentage must be in range 0..255, instead of ${percentage}`)
|
||||
}
|
||||
return color;
|
||||
return p;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ let { files, util, s13n } = global;
|
||||
module.exports = function (scriptRuntime, scope) {
|
||||
const Log = android.util.Log;
|
||||
const Level = org.apache.log4j.Level;
|
||||
const ConsoleUtils = org.autojs.autojs.util.ConsoleUtils;
|
||||
const LogManager = org.apache.log4j.LogManager;
|
||||
const LogConfigurator = de.mindpipe.android.logging.log4j.LogConfigurator;
|
||||
const ConsoleUtils = org.autojs.autojs.util.ConsoleUtils;
|
||||
|
||||
// noinspection JSValidateTypes
|
||||
/** @type {org.autojs.autojs.core.console.GlobalConsole} */
|
||||
@@ -92,8 +93,14 @@ module.exports = function (scriptRuntime, scope) {
|
||||
Boolean(typeof value === 'function' ? value() : value),
|
||||
message || util.getClassName(java.lang.AssertionError));
|
||||
},
|
||||
input(data, param) {
|
||||
return eval(String(this.rawInput(data, param)));
|
||||
input() {
|
||||
// @Abandoned by SuperMonster003 as of May 3, 2023.
|
||||
// return eval(String(this.rawInput(data, param)));
|
||||
throw Error(context.getString(R.strings.error_abandoned_method, 'console.input'));
|
||||
},
|
||||
rawInput() {
|
||||
// @Abandoned by SuperMonster003 as of May 3, 2023.
|
||||
throw Error(context.getString(R.strings.error_abandoned_method, 'console.rawInput'));
|
||||
},
|
||||
log() {
|
||||
rtConsole.log(util.format.apply(util, arguments));
|
||||
@@ -247,6 +254,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
configurator.setResetConfiguration(_.parseOption(config.resetConfiguration, true));
|
||||
configurator.configure();
|
||||
},
|
||||
resetGlobalLogConfig() {
|
||||
LogManager.getLoggerRepository().resetConfiguration();
|
||||
},
|
||||
launch() {
|
||||
ConsoleUtils.launch();
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@ module.exports = function (runtime, scope) {
|
||||
delete this.$appropriateProtect;
|
||||
},
|
||||
},
|
||||
legacies: {
|
||||
isObjectSpecies(o) {
|
||||
return species.isObject(o);
|
||||
},
|
||||
},
|
||||
ensureNonUiThread() {
|
||||
if (ui.isUiThread()) {
|
||||
throw Error('不能在ui线程执行阻塞操作,请在子线程或子脚本执行,或者使用setInterval循环检测当前activity和package.');
|
||||
@@ -533,7 +538,7 @@ module.exports = function (runtime, scope) {
|
||||
},
|
||||
};
|
||||
|
||||
Object.assign(scope, _.extensions);
|
||||
Object.assign(scope, _.extensions, _.legacies);
|
||||
|
||||
// Object.keys(_.extensions)
|
||||
// .filter(key => !key.startsWith('$'))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// noinspection JSUnusedGlobalSymbols,JSUnusedLocalSymbols,UnnecessaryLocalVariableJS
|
||||
|
||||
/* Overwritten protection. */
|
||||
|
||||
@@ -10,7 +10,8 @@ let { ui } = global;
|
||||
* @return {Internal.Http}
|
||||
*/
|
||||
module.exports = function (scriptRuntime, scope) {
|
||||
const PFile = org.autojs.pio.PFile;
|
||||
|
||||
const PFile = org.autojs.autojs.pio.PFile;
|
||||
const Request = okhttp3.Request;
|
||||
const RequestBody = okhttp3.RequestBody;
|
||||
const MultipartBody = okhttp3.MultipartBody;
|
||||
@@ -31,6 +32,13 @@ module.exports = function (scriptRuntime, scope) {
|
||||
Http.prototype = {
|
||||
constructor: Http,
|
||||
__okhttp__: new MutableOkHttp(),
|
||||
/**
|
||||
* @example
|
||||
* http.client() === http.client(); // true
|
||||
*/
|
||||
client() {
|
||||
return this.__okhttp__.client();
|
||||
},
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {Http.RequestBuilderOptions} [options]
|
||||
@@ -83,6 +91,7 @@ module.exports = function (scriptRuntime, scope) {
|
||||
return body;
|
||||
}
|
||||
if (typeof body === 'string') {
|
||||
// noinspection JSDeprecatedSymbols
|
||||
return RequestBody.create(MediaType.parse(this.options.contentType), body);
|
||||
}
|
||||
if (typeof body === 'function') {
|
||||
@@ -119,6 +128,7 @@ module.exports = function (scriptRuntime, scope) {
|
||||
let file = new PFile(path);
|
||||
fileName = fileName || file.getName();
|
||||
mimeType = mimeType || this.parseMimeType(file.getExtension());
|
||||
// noinspection JSDeprecatedSymbols
|
||||
let requestBody = RequestBody.create(MediaType.parse(mimeType), file);
|
||||
builder.addFormDataPart(key, fileName, requestBody);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,13 @@ module.exports = function (scriptRuntime, scope) {
|
||||
const BigTextStyle = androidx.core.app.NotificationCompat.BigTextStyle;
|
||||
const Notification = android.app.Notification;
|
||||
const NotificationManager = android.app.NotificationManager;
|
||||
const NotificationManagerCompat = androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
// @Caution by SuperMonster003 on May 6, 2023.
|
||||
// ! On device running with Android 7.x,
|
||||
// ! importing NotificationManagerCompat will cause java.lang.ClassNotFoundException:
|
||||
// ! Didn't find class "android.app.NotificationChannel" on path: DexPathList ...
|
||||
|
||||
// const NotificationManagerCompat = androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
const configDefaults = {
|
||||
/**
|
||||
@@ -511,7 +517,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
if (!isNullish(id)) {
|
||||
let niceId = Number(id);
|
||||
if (!isNaN(niceId)) {
|
||||
NotificationManagerCompat.from(context).cancel(niceId);
|
||||
if (util.version.sdkInt >= util.versionCodes.O) {
|
||||
androidx.core.app.NotificationManagerCompat.from(context).cancel(niceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -65,11 +65,11 @@ module.exports = function (scriptRuntime, scope) {
|
||||
__asGlobal__(scriptRuntime.timers, methods, scope);
|
||||
|
||||
Object.assign(scope, {
|
||||
/**
|
||||
* @global
|
||||
*/
|
||||
/** @global */
|
||||
loop() {
|
||||
return scriptRuntime.console.warn('Method loop() is deprecated and has no effect.');
|
||||
// @Abandoned by SuperMonster003 as of May 3, 2023.
|
||||
// scriptRuntime.console.warn('Method loop() is deprecated and has no effect.');
|
||||
throw Error(context.getString(R.strings.error_abandoned_method, 'global.loop'));
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -12,17 +12,20 @@ let { files } = global;
|
||||
module.exports = function (scriptRuntime, scope) {
|
||||
const Looper = android.os.Looper;
|
||||
const Runnable = java.lang.Runnable;
|
||||
const Color = android.graphics.Color;
|
||||
const ContextThemeWrapper = android.view.ContextThemeWrapper;
|
||||
const ViewExtras = org.autojs.autojs.core.ui.ViewExtras;
|
||||
const JsListView = org.autojs.autojs.core.ui.widget.JsListView;
|
||||
const JsGridView = org.autojs.autojs.core.ui.widget.JsGridView;
|
||||
const JsViewHelper = org.autojs.autojs.core.ui.JsViewHelper;
|
||||
const ThemeColor = org.autojs.autojs.theme.ThemeColor;
|
||||
const DynamicLayoutInflater = org.autojs.autojs.core.ui.inflater.DynamicLayoutInflater;
|
||||
const ColorDrawable = android.graphics.drawable.ColorDrawable;
|
||||
|
||||
require('object-observe-lite.min').call(scope);
|
||||
require('array-observe.min').call(scope);
|
||||
|
||||
let isAndroidLayout = null;
|
||||
|
||||
// noinspection JSValidateTypes
|
||||
let _ = {
|
||||
// @Coerce by SuperMonster003 on Nov 9, 2022.
|
||||
@@ -142,6 +145,15 @@ module.exports = function (scriptRuntime, scope) {
|
||||
: activity);
|
||||
return layoutInflater.inflate(_.toXMLString(xml), parent || null, Boolean(isAttachedToParent));
|
||||
},
|
||||
useAndroidLayout(b) {
|
||||
if (typeof b === 'boolean') {
|
||||
isAndroidLayout = b;
|
||||
} else if (b === undefined) {
|
||||
isAndroidLayout = true;
|
||||
} else {
|
||||
isAndroidLayout = null;
|
||||
}
|
||||
},
|
||||
run(action) {
|
||||
if (this.isUiThread()) {
|
||||
return action();
|
||||
@@ -175,11 +187,16 @@ module.exports = function (scriptRuntime, scope) {
|
||||
scriptRuntime.getUiHandler().postDelayed(_.wrapUiAction(action), delay);
|
||||
}
|
||||
},
|
||||
layout(layout) {
|
||||
layout(xml) {
|
||||
_.ensureActivity();
|
||||
layoutInflater.setContext(activity);
|
||||
// noinspection JSCheckFunctionSignatures
|
||||
this.setContentView(layoutInflater.inflate(layout, activity.window.decorView, false));
|
||||
layoutInflater.setContext(activity);
|
||||
// noinspection JSCheckFunctionSignatures,JSTypeOfValues
|
||||
this.setContentView(layoutInflater.inflate(
|
||||
typeof xml === 'xml' ? xml.toXMLString() : String(xml),
|
||||
activity.window.decorView,
|
||||
false,
|
||||
));
|
||||
},
|
||||
layoutFile(path) {
|
||||
this.layout(files.read(path));
|
||||
@@ -200,18 +217,13 @@ module.exports = function (scriptRuntime, scope) {
|
||||
},
|
||||
statusBarColor(color) {
|
||||
_.ensureActivity();
|
||||
let colorInt = (/* @IIFE */ () => {
|
||||
if (typeof color === 'string') {
|
||||
if (Number(color).toString() === color) {
|
||||
color = Number(color);
|
||||
}
|
||||
}
|
||||
if (typeof color === 'number') {
|
||||
return color;
|
||||
}
|
||||
return scriptRuntime.colors.parseColor(String(color));
|
||||
})();
|
||||
this.run(() => activity.window.setStatusBarColor(colorInt));
|
||||
this.run(() => activity.window.setStatusBarColor(colors.toInt(color)));
|
||||
},
|
||||
backgroundColor(color) {
|
||||
_.ensureActivity();
|
||||
this.run(() => activity.window.setBackgroundDrawable(new ColorDrawable(
|
||||
Color(color).setAlpha(1.0).toInt(),
|
||||
)));
|
||||
},
|
||||
findById(id) {
|
||||
return this.view ? this.findByStringId(this.view, id) : null;
|
||||
@@ -235,28 +247,19 @@ module.exports = function (scriptRuntime, scope) {
|
||||
*/
|
||||
layoutInflaterDelegate: {
|
||||
beforeConvertXml(context, xml) {
|
||||
if (isAndroidLayout === true || isAndroidLayout === null && /\bxmlns:\w+="\w+:\/\/|\b(android|app):\w+=".+"/.test(xml)) {
|
||||
// noinspection JSTypeOfValues
|
||||
return typeof xml === 'xml' ? xml.toXMLString() : String(xml);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
afterConvertXml(context, xml) {
|
||||
return xml;
|
||||
},
|
||||
beforeInflation(context, xml, parent) {
|
||||
return null;
|
||||
},
|
||||
afterInflation(context, result, xml, parent) {
|
||||
return result;
|
||||
},
|
||||
beforeInflateView(context, node, parent, attachToParent) {
|
||||
return null;
|
||||
},
|
||||
afterInflateView(context, view, node, parent, attachToParent) {
|
||||
let { widget } = view;
|
||||
if (widget && context.get('root') !== widget) {
|
||||
widget.notifyAfterInflation(view);
|
||||
}
|
||||
return view;
|
||||
},
|
||||
beforeCreateView(context, node, viewName, parent, attrs) {
|
||||
beforeCreateView(context, node, viewName, parent) {
|
||||
if (uiProxy.__widgets__.hasOwnProperty(viewName)) {
|
||||
let Widget = uiProxy.__widgets__[viewName];
|
||||
let widget = new Widget();
|
||||
@@ -267,7 +270,13 @@ module.exports = function (scriptRuntime, scope) {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
afterCreateView(context, view, node, viewName, parent, attrs) {
|
||||
beforeInflation(context, xml, parent) {
|
||||
return null;
|
||||
},
|
||||
afterInflation(context, result, xml, parent) {
|
||||
return result;
|
||||
},
|
||||
afterCreateView(context, view, node, viewName, parent) {
|
||||
if (view instanceof JsListView || view instanceof JsGridView) {
|
||||
_.initListView(view);
|
||||
}
|
||||
@@ -275,11 +284,13 @@ module.exports = function (scriptRuntime, scope) {
|
||||
if (widget !== null) {
|
||||
widget.view = view;
|
||||
view.widget = widget;
|
||||
ViewExtras.getViewAttributes(view, layoutInflater.getResourceParser()).setViewAttributeDelegate({
|
||||
has: name => widget.hasAttr(name),
|
||||
get: (view, name, getter) => widget.getAttr(view, name, getter),
|
||||
set: (view, name, value, setter) => widget.setAttr(view, name, value, setter),
|
||||
});
|
||||
ViewExtras
|
||||
.getViewAttributes(view, layoutInflater.getResourceParser())
|
||||
.setViewAttributeDelegate({
|
||||
has: name => widget.hasAttr(name),
|
||||
get: (view, name, getter) => widget.getAttr(view, name, getter),
|
||||
set: (view, name, value, setter) => widget.setAttr(view, name, value, setter),
|
||||
});
|
||||
widget.notifyViewCreated(view);
|
||||
}
|
||||
return view;
|
||||
@@ -287,6 +298,27 @@ module.exports = function (scriptRuntime, scope) {
|
||||
beforeApplyAttributes(context, view, inflater, attrs, parent) {
|
||||
return false;
|
||||
},
|
||||
beforeApplyAttribute(context, inflater, view, ns, attrName, value, parent) {
|
||||
let isDynamic = layoutInflater.isDynamicValue(value);
|
||||
return isDynamic && layoutInflater.getInflateFlags() === DynamicLayoutInflater.FLAG_IGNORES_DYNAMIC_ATTRS
|
||||
|| !isDynamic && layoutInflater.getInflateFlags() === DynamicLayoutInflater.FLAG_JUST_DYNAMIC_ATTRS
|
||||
|| (/* @IIFE */ () => {
|
||||
value = _.bind(value);
|
||||
let widget = context.get('widget');
|
||||
if (widget !== null && widget.hasAttr(attrName)) {
|
||||
widget.setAttr(view, attrName, value, (view, attrName, value) => {
|
||||
inflater.setAttr(view, ns, attrName, value, parent);
|
||||
});
|
||||
} else {
|
||||
inflater.setAttr(view, ns, attrName, value, parent);
|
||||
}
|
||||
this.afterApplyAttribute(context, inflater, view, ns, attrName, value, parent);
|
||||
return true;
|
||||
})();
|
||||
},
|
||||
afterApplyAttribute(context, inflater, view, ns, attrName, value, parent) {
|
||||
// Empty method body
|
||||
},
|
||||
afterApplyAttributes(context, view, inflater, attrs, parent) {
|
||||
context.remove('widget');
|
||||
},
|
||||
@@ -302,26 +334,12 @@ module.exports = function (scriptRuntime, scope) {
|
||||
afterApplyPendingAttributesOfChildren(context, inflater, view) {
|
||||
// Empty method body
|
||||
},
|
||||
beforeApplyAttribute(context, inflater, view, ns, attrName, value, parent, attrs) {
|
||||
let isDynamic = layoutInflater.isDynamicValue(value);
|
||||
return isDynamic && layoutInflater.getInflateFlags() === DynamicLayoutInflater.FLAG_IGNORES_DYNAMIC_ATTRS
|
||||
|| !isDynamic && layoutInflater.getInflateFlags() === DynamicLayoutInflater.FLAG_JUST_DYNAMIC_ATTRS
|
||||
|| (/* @IIFE */ () => {
|
||||
value = _.bind(value);
|
||||
let widget = context.get('widget');
|
||||
if (widget !== null && widget.hasAttr(attrName)) {
|
||||
widget.setAttr(view, attrName, value, (view, attrName, value) => {
|
||||
inflater.setAttr(view, ns, attrName, value, parent, attrs);
|
||||
});
|
||||
} else {
|
||||
inflater.setAttr(view, ns, attrName, value, parent, attrs);
|
||||
}
|
||||
this.afterApplyAttribute(context, inflater, view, ns, attrName, value, parent, attrs);
|
||||
return true;
|
||||
})();
|
||||
},
|
||||
afterApplyAttribute(context, inflater, view, ns, attrName, value, parent, attrs) {
|
||||
// Empty method body
|
||||
afterInflateView(context, view, node, parent, attachToParent) {
|
||||
let { widget } = view;
|
||||
if (widget && context.get('root') !== widget) {
|
||||
widget.notifyAfterInflation(view);
|
||||
}
|
||||
return view;
|
||||
},
|
||||
},
|
||||
bind(value) {
|
||||
@@ -333,7 +351,8 @@ module.exports = function (scriptRuntime, scope) {
|
||||
if (j < 0) {
|
||||
return value;
|
||||
}
|
||||
value = value.slice(0, i) + _.evalInContext(value.slice(i + 2, j), ctx) + value.slice(j + 2);
|
||||
let evaluated = _.evalInContext(value.slice(i + 2, j), ctx);
|
||||
value = value.slice(0, i) + _.attrValueConvert(evaluated) + value.slice(j + 2);
|
||||
i = j + 1;
|
||||
}
|
||||
return value;
|
||||
@@ -401,6 +420,18 @@ module.exports = function (scriptRuntime, scope) {
|
||||
setLayoutInflaterDelegate() {
|
||||
layoutInflater.setLayoutInflaterDelegate(this.layoutInflaterDelegate);
|
||||
},
|
||||
attrValueConvert(o) {
|
||||
if (typeof o === 'string') {
|
||||
return o;
|
||||
}
|
||||
if (o instanceof scope.Color) {
|
||||
return o.toHex();
|
||||
}
|
||||
if (o instanceof ThemeColor) {
|
||||
return o.getColorPrimary();
|
||||
}
|
||||
return o;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
|
||||
/* Overwritten protection. */
|
||||
|
||||
let { http } = global;
|
||||
|
||||
/**
|
||||
* @param {org.autojs.autojs.runtime.ScriptRuntime} scriptRuntime
|
||||
* @param {org.mozilla.javascript.Scriptable | global} scope
|
||||
@@ -38,6 +42,9 @@ module.exports = function (scriptRuntime, scope) {
|
||||
newInjectableWebClient() {
|
||||
return new InjectableWebClient(Context.getCurrentContext(), scope);
|
||||
},
|
||||
newWebSocket(url) {
|
||||
return new org.autojs.autojs.core.web.WebSocket(http.__okhttp__, url);
|
||||
},
|
||||
};
|
||||
|
||||
return Web;
|
||||
@@ -46,7 +53,7 @@ module.exports = function (scriptRuntime, scope) {
|
||||
/**
|
||||
* @type {(keyof Internal.Web)[]}
|
||||
*/
|
||||
let methods = [ 'newInjectableWebView', 'newInjectableWebClient' ];
|
||||
let methods = [ 'newInjectableWebView', 'newInjectableWebClient', 'newWebSocket' ];
|
||||
__asGlobal__(web, methods, scope);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module.exports = function(){
|
||||
Object.observe&&!Array.observe&&function(t,e){"use strict";var n=t.getNotifier,r="performChange",i="_original",o="splice";var u={push:function h(t){var e=arguments,u=h[i].apply(this,e);n(this)[r](o,function(){return{index:u-e.length,addedCount:e.length,removed:[]}});return u},unshift:function d(t){var e=arguments,u=d[i].apply(this,e);n(this)[r](o,function(){return{index:0,addedCount:e.length,removed:[]}});return u},pop:function a(){var t=this.length,e=a[i].call(this);if(this.length!==t)n(this)[r](o,function(){return{index:this.length,addedCount:0,removed:[e]}},this);return e},shift:function l(){var t=this.length,e=l[i].call(this);if(this.length!==t)n(this)[r](o,function(){return{index:0,addedCount:0,removed:[e]}},this);return e},splice:function f(t,e){var u=arguments,s=f[i].apply(this,u);if(s.length||u.length>2)n(this)[r](o,function(){return{index:t,addedCount:u.length-2,removed:s}},this);return s}};for(var s in u){u[s][i]=e.prototype[s];e.prototype[s]=u[s]}e.observe=function(e,n){return t.observe(e,n,["add","update","delete",o])};e.unobserve=t.unobserve}(Object,Array);
|
||||
Object.observe&&!Array.observe&&function(t,e){var n=t.getNotifier,r="performChange",i="_original",o="splice";var u={push:function h(t){var e=arguments,u=h[i].apply(this,e);n(this)[r](o,function(){return{index:u-e.length,addedCount:e.length,removed:[]}});return u},unshift:function d(t){var e=arguments,u=d[i].apply(this,e);n(this)[r](o,function(){return{index:0,addedCount:e.length,removed:[]}});return u},pop:function a(){var t=this.length,e=a[i].call(this);if(this.length!==t)n(this)[r](o,function(){return{index:this.length,addedCount:0,removed:[e]}},this);return e},shift:function l(){var t=this.length,e=l[i].call(this);if(this.length!==t)n(this)[r](o,function(){return{index:0,addedCount:0,removed:[e]}},this);return e},splice:function f(t,e){var u=arguments,s=f[i].apply(this,u);if(s.length||u.length>2)n(this)[r](o,function(){return{index:t,addedCount:u.length-2,removed:s}},this);return s}};for(var s in u){u[s][i]=e.prototype[s];e.prototype[s]=u[s]}e.observe=function(e,n){return t.observe(e,n,["add","update","delete",o])};e.unobserve=t.unobserve}(Object,Array);
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
( /* @ModuleIIFE */ () => {
|
||||
|
||||
"use strict";
|
||||
|
||||
var _createClass = function () {
|
||||
function defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
* @see https://raw.githubusercontent.com/taylorhakes/promise-polyfill/master/dist/polyfill.js
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @type {PromiseConstructorLike}
|
||||
*/
|
||||
|
||||
142
app/src/main/assets/sample/布局/待办事项 [v6.3.1+].js
Normal file
142
app/src/main/assets/sample/布局/待办事项 [v6.3.1+].js
Normal file
@@ -0,0 +1,142 @@
|
||||
'ui';
|
||||
|
||||
let themeColor = 'orange-800';
|
||||
|
||||
let materialColors = [
|
||||
'amber-500',
|
||||
'blue-500',
|
||||
'blue-grey-500',
|
||||
'brown-500',
|
||||
'cyan-500',
|
||||
'deep-orange-500',
|
||||
'deep-purple-500',
|
||||
'green-500',
|
||||
'grey-500',
|
||||
'indigo-500',
|
||||
'light-blue-500',
|
||||
'light-green-500',
|
||||
'lime-500',
|
||||
'orange-500',
|
||||
'pink-500',
|
||||
'purple-500',
|
||||
'red-500',
|
||||
'teal-500',
|
||||
'yellow-500',
|
||||
];
|
||||
|
||||
let storage = storages.create('todoList');
|
||||
|
||||
storage.clear();
|
||||
|
||||
ui.layout(
|
||||
<frame>
|
||||
<vertical>
|
||||
<appbar>
|
||||
<toolbar id="toolbar" title="TODO" />
|
||||
</appbar>
|
||||
<button id="selectAll" text="全部完成" isColored margin="6 4" />
|
||||
<list id="todoList">
|
||||
<card w="*" h="70" margin="10 5" cardCornerRadius="2dp"
|
||||
cardElevation="1dp" foreground="?selectableItemBackground">
|
||||
<horizontal gravity="center_vertical">
|
||||
<view bg="{{this.color}}" h="*" w="10" />
|
||||
<vertical padding="10 8" h="auto" w="0" layout_weight="1">
|
||||
<text id="title" text="{{this.title}}" textColor="blue-grey-900" textSize="16sp" maxLines="1" paddingBottom="4dp" />
|
||||
<text text="{{this.summary}}" textColor="blue-grey-300" textSize="14sp" maxLines="1" />
|
||||
</vertical>
|
||||
<checkbox id="done" marginLeft="4" marginRight="6" checked="{{this.done}}" tint="blue-grey-500,pink-300" />
|
||||
</horizontal>
|
||||
</card>
|
||||
</list>
|
||||
</vertical>
|
||||
<fab id="add" w="auto" h="auto" src="@drawable/ic_add_black_48dp"
|
||||
margin="16" layout_gravity="bottom|right" tint="white" backgroundTint="orange-800" />
|
||||
</frame>,
|
||||
);
|
||||
|
||||
// 从 storage 获取待办事项列表
|
||||
let todoList = storage.get('items', [{
|
||||
title: '写操作系统作业',
|
||||
summary: '明天第 1 - 2 节',
|
||||
color: 'red-500',
|
||||
done: false,
|
||||
}, {
|
||||
title: '给 ui 模式增加若干 bug',
|
||||
summary: '无限期',
|
||||
color: 'orange-500',
|
||||
done: false,
|
||||
}, {
|
||||
title: '发布 AutoJs6 v6.6.6',
|
||||
summary: '2066 年 6 月',
|
||||
color: 'teal-500',
|
||||
done: false,
|
||||
}, {
|
||||
title: '完成 AutoJs6 文档撰写',
|
||||
summary: '2031 年 5 月',
|
||||
color: '#2196f3',
|
||||
done: false,
|
||||
}]);
|
||||
|
||||
ui.statusBarColor(themeColor);
|
||||
ui['toolbar'].attr('bg', themeColor);
|
||||
ui['selectAll'].attr('backgroundTint', 'pink-300');
|
||||
|
||||
ui['todoList'].setDataSource(todoList);
|
||||
|
||||
ui['selectAll'].on('click', function () {
|
||||
todoList.forEach(item => {
|
||||
item.done = true;
|
||||
});
|
||||
// 通知数据全部更新
|
||||
ui['todoList'].adapter.notifyDataSetChanged();
|
||||
});
|
||||
|
||||
ui['todoList'].on('item_bind', function (itemView, itemHolder) {
|
||||
// 绑定勾选框事件
|
||||
itemView.done.on('check', function (checked) {
|
||||
let item = itemHolder.item;
|
||||
item.done = checked;
|
||||
let paint = itemView.title.paint;
|
||||
// 设置或取消中划线效果
|
||||
if (checked) {
|
||||
paint.flags |= Paint.STRIKE_THRU_TEXT_FLAG;
|
||||
} else {
|
||||
paint.flags &= ~Paint.STRIKE_THRU_TEXT_FLAG;
|
||||
}
|
||||
itemView.title.invalidate();
|
||||
});
|
||||
});
|
||||
|
||||
ui['todoList'].on('item_click', function (item, i, itemView) {
|
||||
itemView.done.checked = !itemView.done.checked;
|
||||
});
|
||||
|
||||
ui['todoList'].on('item_long_click', function (e, item, i) {
|
||||
confirm(`确定要删除 "${item.title}" 吗?`)
|
||||
.then(ok => {
|
||||
if (ok) {
|
||||
todoList.splice(i, 1);
|
||||
}
|
||||
});
|
||||
e.consumed = true;
|
||||
});
|
||||
|
||||
// 当离开本界面时保存 todoList
|
||||
ui.emitter.on('pause', () => storage.put('items', todoList));
|
||||
|
||||
ui['add'].on('click', () => {
|
||||
dialogs.rawInput('请输入标题')
|
||||
.then((title) => {
|
||||
if (!title) {
|
||||
return;
|
||||
}
|
||||
dialogs.rawInput('请输入期限', '明天')
|
||||
.then(summary => {
|
||||
todoList.push({
|
||||
title: title,
|
||||
summary: summary,
|
||||
color: materialColors[random(0, materialColors.length - 1)],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
34
app/src/main/assets/sample/布局/简单安卓布局.js
Normal file
34
app/src/main/assets/sample/布局/简单安卓布局.js
Normal file
@@ -0,0 +1,34 @@
|
||||
'ui';
|
||||
|
||||
const themeColor = Color(autojs.themeColor);
|
||||
const colorRelativeRate = 1.8;
|
||||
|
||||
ui.layout(
|
||||
<org.autojs.autojs.core.ui.widget.JsTextClock
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/text_clock"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:format24Hour="HH:mm"
|
||||
android:textSize="36sp"/>,
|
||||
);
|
||||
|
||||
/* 1 秒钟后应用自定义样式. */
|
||||
setTimeout(() => {
|
||||
ui.statusBarColor(themeColor);
|
||||
ui.backgroundColor(
|
||||
Color(themeColor)
|
||||
.setRedRelative(colorRelativeRate)
|
||||
.setGreenRelative(colorRelativeRate)
|
||||
.setBlueRelative(colorRelativeRate)
|
||||
.toInt(),
|
||||
);
|
||||
|
||||
/** @type {JsTextClock} */
|
||||
let textClockView = ui.text_clock;
|
||||
|
||||
textClockView.attr('color', themeColor.toInt());
|
||||
textClockView.attr('size', '56');
|
||||
textClockView.attr('layout_gravity', 'center');
|
||||
textClockView.attr('format24Hour', 'HH:mm:ss');
|
||||
}, 1e3);
|
||||
@@ -4,12 +4,12 @@ ui.layout(
|
||||
<vertical padding="16">
|
||||
<checkbox id="cb1" text="复选框"/>
|
||||
<checkbox id="cb2" checked="true" text="勾选的复选框"/>
|
||||
<radiogroup>
|
||||
<radiogroup marginTop="16">
|
||||
<radio text="单选框1"/>
|
||||
<radio text="单选框2"/>
|
||||
<radio text="单选框3"/>
|
||||
</radiogroup>
|
||||
<radiogroup mariginTop="16">
|
||||
<radiogroup marginTop="16">
|
||||
<radio text="单选框1"/>
|
||||
<radio text="单选框2"/>
|
||||
<radio text="勾选的单选框3" checked="true"/>
|
||||
24
app/src/main/assets/sample/控件/开关控件 [v6.3.1+].js
Normal file
24
app/src/main/assets/sample/控件/开关控件 [v6.3.1+].js
Normal file
@@ -0,0 +1,24 @@
|
||||
'ui';
|
||||
|
||||
ui.layout(<vertical gravity="center">
|
||||
<horizontal width="-1" gravity="center" margin="16">
|
||||
<text text="滑块单色/轨道单色" size="16" marginEnd="32"/>
|
||||
<switch checked="false" thumbTint="orange-800" trackTint="orange-200" marginEnd="16"></switch>
|
||||
<switch checked="true" thumbTint="orange-800" trackTint="orange-200"></switch>
|
||||
</horizontal>
|
||||
<horizontal width="-1" gravity="center" margin="16">
|
||||
<text text="滑块单色/轨道双色" size="16" marginEnd="32"/>
|
||||
<switch checked="false" thumbTint="orange-800" trackTint="light-gray/orange-200" marginEnd="16"></switch>
|
||||
<switch checked="true" thumbTint="orange-800" trackTint="light-gray/orange-200"></switch>
|
||||
</horizontal>
|
||||
<horizontal width="-1" gravity="center" margin="16">
|
||||
<text text="滑块双色/轨道单色" size="16" marginEnd="32"/>
|
||||
<switch checked="false" thumbTint="gray/orange-800" trackTint="light-gray" marginEnd="16"></switch>
|
||||
<switch checked="true" thumbTint="gray/orange-800" trackTint="light-gray"></switch>
|
||||
</horizontal>
|
||||
<horizontal width="-1" gravity="center" margin="16">
|
||||
<text text="滑块双色/轨道双色" size="16" marginEnd="32"/>
|
||||
<switch checked="false" thumbTint="gray/orange-800" trackTint="light-gray/orange-200" marginEnd="16"></switch>
|
||||
<switch checked="true" thumbTint="gray/orange-800" trackTint="light-gray/orange-200"></switch>
|
||||
</horizontal>
|
||||
</vertical>);
|
||||
@@ -13,10 +13,8 @@ const assert = (value, message) => {
|
||||
message && console.verbose(`${message} passed`);
|
||||
};
|
||||
|
||||
const SecurityException = java.lang.SecurityException;
|
||||
const AtomicLong = java.util.concurrent.atomic.AtomicLong;
|
||||
const JavaScriptEngine = org.autojs.autojs.engine.JavaScriptEngine;
|
||||
const JsLinearLayout = org.autojs.autojs.core.ui.widget.JsLinearLayout;
|
||||
|
||||
// @Test Rhino basic
|
||||
|
||||
@@ -16,7 +16,6 @@ const assert = (value, message) => {
|
||||
};
|
||||
|
||||
const JavaScriptEngine = org.autojs.autojs.engine.JavaScriptEngine;
|
||||
const JsLinearLayout = org.autojs.autojs.core.ui.widget.JsLinearLayout;
|
||||
|
||||
// @Test auto
|
||||
|
||||
46
app/src/main/assets/sample/浮动窗口/浮动窗口输入框 [v6.3.1+].js
Normal file
46
app/src/main/assets/sample/浮动窗口/浮动窗口输入框 [v6.3.1+].js
Normal file
@@ -0,0 +1,46 @@
|
||||
// noinspection HtmlUnknownAttribute
|
||||
|
||||
let win = floaty.window(
|
||||
<vertical bg="white" padding="24">
|
||||
<input id="input" hint="请输入任意内容" textSize="16sp" margin="0 12"/>
|
||||
<view h="1" w="180" layout_weight="1"/>
|
||||
<button id="ok" text="确定" bgTint="light-blue-600" color="white" layout_gravity="bottom"/>
|
||||
</vertical>,
|
||||
);
|
||||
|
||||
win.exitOnClose();
|
||||
|
||||
/** @type {JsButton} */
|
||||
let buttonView = win['ok'];
|
||||
|
||||
/** @type {JsEditText} */
|
||||
let inputView = win['input'];
|
||||
|
||||
toast(`长按 "${buttonView.attr('text')}" 键可调整浮动窗口样式`, 'long');
|
||||
|
||||
inputView.on('click', () => {
|
||||
win.requestFocus();
|
||||
});
|
||||
|
||||
inputView.on('key_up', function (keyCode, event) {
|
||||
if (keyCode === keys.back) {
|
||||
win.disableFocus();
|
||||
event.consumed = true;
|
||||
}
|
||||
});
|
||||
|
||||
buttonView.on('click', () => {
|
||||
let text = inputView.text();
|
||||
text
|
||||
? toast('输入内容: ' + text)
|
||||
: toast('未输入任何内容');
|
||||
win.disableFocus();
|
||||
});
|
||||
|
||||
buttonView.on('long_click', (event) => {
|
||||
toast.dismissAll();
|
||||
win.setAdjustEnabled(!win.isAdjustEnabled());
|
||||
event.consumed = true;
|
||||
});
|
||||
|
||||
setInterval(() => null, 1000);
|
||||
Reference in New Issue
Block a user