- // ==UserScript==
- // @name 仓库用度盘投稿助手
- // @namespace moe.jixun.dupan.galacg
- // @version 1.2.1
- // @description 简易功能增强, 方便仓库投稿用
- // @author Jixun<https://jixun.moe/>
- // @include http://pan.baidu.com/disk/home*
- // @include http://yun.baidu.com/disk/home*
- // @include https://pan.baidu.com/disk/home*
- // @include https://yun.baidu.com/disk/home*
-
- // @compatible firefox GreaseMonkey (有限)
- // @compatible firefox Violentmonkey
- // @compatible chrome Violentmonkey
-
- // @grant none
- // @run-at document-start
-
- // ==/UserScript==
-
- const isGm = (typeof unsafeWindow !== 'undefined') && (unsafeWindow !== window);
- if (isGm) {
- const INFO = '[仓库助手]';
-
- console.info("%s 以 GreaseMonkey 兼容模式执行。该脚本管理器所遇到的问题不能保证能够修复。", INFO);
- unsafeWindow.eval(`;(${entry})();`);
- } else {
- entry();
- }
-
- function entry () {
- const INFO = '[仓库助手]';
-
- var oRequire;
- if (window.require) {
- console.warn("%s 覆盖方式安装,若无效请强制刷新。", INFO);
- oRequire = window.require;
- window.require = fakeRequire;
- Object.assign(fakeRequire, oRequire);
- } else {
- console.info("%s 钩子方式安装,若失效请报告。", INFO);
- Object.defineProperty(window, 'require', {
- set: function (require) {
- oRequire = require;
- },
- get: function () {
- return fakeRequire;
- }
- });
- }
-
- const __AppId = 250528;
- const pluginBlacklist = ['右上角广告位', '网盘APP下载', '满减活动', '会员提醒'];
- var _G = {};
- // window.__debug_G = _G;
-
- function fakeRequire(module) {
- // console.info('%s Load module: %s', INFO, module);
- if (module == 'disk-system:widget/system/uiRender/menu/listMenu.js') {
- if (!_G.injected) {
- initScript();
- _G.injected = true;
- }
- } else if (module == 'system-core:pluginHub/register/register.js') {
- if (!_G.btnInjected) {
- registerPlugin();
- _G.btnInjected = true;
- }
- }
- return oRequire.apply(this, arguments);
- }
-
- function menuInsertAfter(list, name, item, noPush) {
- for (var i = 0; i < list.length; i++) {
- if (list[i] instanceof Array) {
- if (menuInsertAfter(list[i], name, item, true)) {
- return;
- }
- } else if (list[i].title === name) {
- i++;
- list.splice(i, i, item);
- return true;
- }
- }
-
- if (!noPush) list.push(item);
- }
-
- function initScript() {
- // Load module
- _G.FaceData = oRequire('system-core:data/faceData.js');
- _G.ListInit = oRequire("disk-system:widget/pageModule/list/listInit.js");
-
- var fileCtxMenu = _G.FaceData.getData().contextMenu.file;
- menuInsertAfter(fileCtxMenu, '分享', {
- index: 8,
- keyboard: 'u',
- title: '自定义分享',
- display: isFileChecked,
- action: lazyDialog('loadCustomShareDialog')
- });
-
- fileCtxMenu.forEach(m => {
- if (m.index >= 2) {
- m.index++;
- }
- });
-
- fileCtxMenu.push({
- index: 2, // '删除' 的 index。
- keyboard: 'r',
- position: 'bottom',
- title: '批量重命名',
- display: isFileChecked,
- action: lazyDialog('loadBatchRenameDialog')
- });
-
- setTimeout(delayLoad, 200);
- delayLoadDuCode();
-
- // ESC 将关闭所有漂浮窗口
- document.addEventListener('keyup', function(e) {
- if (e.keyCode == 0x1b) {
- $('.dialog-close').click();
- }
- }, false);
- }
-
- function registerPlugin() {
- window.define('function-widget:jixun/standard-code.js', function(require, exports, module) {
- exports.start = lazyDialog('loadStandardCodeDialog');
- });
-
- window.manifest = window.manifest.filter(plugin => pluginBlacklist.indexOf(plugin.name) === -1);
-
- window.manifest.push({
- "name": "标准提取码插件",
- "group": "moe.jixun.code",
- "version": '1.0',
- "type": "1",
- "description": "类似于 115 的标准提取码",
- "filesType": "*",
- "buttons": [{
- "index": 2,
- "disabled": "none",
- "title": "标准提取码",
- "buttonStyle": "normal",
- "pluginId": "JIXUNSTDCODE",
- "position": 'tools'
- }],
- "preload": false,
- "depsFiles": [],
- "entranceFile": "function-widget:jixun/standard-code.js",
- "pluginId": "JIXUNSTDCODE"
- });
- }
-
- function isFileChecked() {
- return _G.ListInit.getCheckedItems().length > 0;
- }
-
- function lazyDialog(name) {
- return function() {
- if (_G[name]) {
- _G[name]();
- } else {
- loadDependencies();
- _G.Tip.show({
- mode: 'loading',
- msg: '正在努力加载中 ...'
- });
- }
- };
- }
-
- function nextId() {
- if (!nextId.id) nextId.id = 0;
- return nextId.id++;
- }
-
- function confirmDialog(data) {
- loadDependencies();
-
- var dialog;
- var dialogData = {
- id: "confirm-" + nextId(),
- show: true,
- title: data.title,
- body: $('<div style="text-align:center; padding:22px;">').append(data.body),
- buttons: [{
- name: "confirm",
- title: data.sureText || "确定",
- type: "big",
- color: "blue",
- padding: ["50px", "50px"],
- click: function() {
- if ($.isFunction(data.onSure)) {
- data.onSure.apply(this, arguments);
- } else {
- dialog.hide();
- }
- }
- }, {
- name: "cancel",
- title: data.cancelText || "取消",
- type: "big",
- padding: ["50px", "50px"],
- click: function() {
- if ($.isFunction(data.onCancel)) {
- data.onCancel.apply(this, arguments);
- } else {
- dialog.hide();
- }
- }
- }]
- };
- if (data.cancel === false) {
- dialogData.buttons.pop();
- }
- dialog = new _G.Dialog(dialogData);
- return dialog;
- }
-
- function delayLoad() {
- _G.loadCustomShareDialog = (function() {
- var _tplCustomShare = `
- <div>
- <p>请输入提取码: <input id="jx_shareKey" class="jx-input" style="width: 6em" /></p>
- <p id="jx_errmsg" class="jx_c_warn jx_hide">无效的提取码, 脚本将随机生成一个分享代码 :<</p>
- </div>
- <div class="jx_hide">
- <p>分享地址: <input id="jx_shortUrl" class="jx-input" style="width: 20em" readonly /></p>
- <p>提取码: <input id="jx_shareCode" class="jx-input" style="width: 5em; text-align: center" readonly /></p>
-
- <p style="text-align: left">投稿代码:<br /><textarea readonly id="jx_dlboxCode" class="jx jx-input"></textarea></p>
- </div>
- `;
-
- var dialog, $footer, $key, $tplCustomShare;
-
- function showDialog() {
- $tplCustomShare = $(_tplCustomShare);
- dialog = confirmDialog({
- title: '自定义分享',
- body: $tplCustomShare,
- onSure: function() {
- handleConfirm();
- dialog.hide();
- },
- onCancel: function() {
- dialog.hide();
- },
- });
-
- $footer = dialog.$dialog.find(_G.Dialog.QUERY.dialogFooter);
-
- $key = $('#jx_shareKey', $tplCustomShare)
- .blur(function() {
- if (!isCodeValid(this.value = this.value.trim())) {
- $('#jx_errmsg', $tplCustomShare)
- .removeClass('jx_hide');
- }
- })
- .focus(function() {
- $('#jx_errmsg', $tplCustomShare)
- .addClass('jx_hide');
- })
- .val(genKey(4));
- }
-
- function handleConfirm() {
- var key = $key.val();
- if (!isCodeValid(key)) {
- key = genKey(4);
- $key.val(key);
- }
-
- _G.Tip.show({
- mode: 'loading',
- msg: '正在分享,请稍后 ...',
- autoClose: false
- });
-
- var sharedItems = _G.ListInit.getCheckedItems();
- $.ajax({
- url: '/share/set?' + $.param({
- channel: 'chunlei',
- bdstoken: yunData.MYBDSTOKEN,
- app_id: __AppId
- }),
- type: 'POST',
- data: {
- fid_list: JSON.stringify(sharedItems.map(getFileId)),
- schannel: 4,
- channel_list: '[]',
- pwd: key
- },
- dataType: 'json'
- }).success(function(r) {
- _G.Tip.hide();
-
- _G.Tip.show({
- mode: 'success',
- msg: '分享成功!'
- });
-
- $footer.children('.g-button-blue-large').hide();
- $footer.children('.g-button-large').find('.text').text('关闭');
-
- let url = r.shorturl ? `${r.shorturl}#${key}` : '很抱歉, 分享失败 :<';
- $('#jx_shortUrl', $tplCustomShare).val(url);
- $('#jx_shareCode', $tplCustomShare).val(key);
-
- $tplCustomShare.toggleClass('jx_hide');
-
- var title = fixCode(sharedItems[0].server_filename) + (sharedItems.length == 1 ? '' : ' 等文件');
-
- $('#jx_dlboxCode', $tplCustomShare).val(
- `[dlbox title="${escapeHtml(title)}" from="浩瀚的宇宙" time="${makeDate(new Date())}" info="提取:${escapeHtml(key)}" link1="度娘|${url}"][/dlbox]]`
- );
-
- dialog.show();
- }).fail(function() {
- _G.Tip.hide();
-
- _G.Tip.show({
- mode: 'failure',
- msg: '网络错误,请稍后重试。'
- });
- });
- }
-
- /* 依赖函数表 */
- function isCodeValid(code) {
- return encodeURIComponent(code).replace(/%[A-F\d]{2}/g, '-').length == 4;
- }
-
- function fixCode(code) {
- return code.replace(/"/g, '"').replace(/\]/g, ']');
- }
-
- function fixWidthDigits(d) {
- return ('0' + d.toString()).slice(-2);
- }
-
- function makeDate(d) {
- return `${d.getFullYear()}.${fixWidthDigits(d.getMonth() + 1)}.${fixWidthDigits(d.getDate())}`;
- }
-
- function genKey(size) {
- // length => 26 + 10, 36
- var keySet = 'abcdefghijklmnopqrstuvwxyz0123456789';
- for (var i = (size || 4) | 0, r = ''; i--;)
- r += keySet[0 | (Math.random() * 36)];
-
- return r;
- }
-
- function getFileId(item) {
- return item.fs_id;
- }
-
- /* 收尾 */
- return showDialog;
- })();
-
- _G.loadBatchRenameDialog = (function() {
- var _tplConfirmRename = `
- <p>请输入新的命名规则 (自动储存): <input id="jx_nameRule" class="jx-input" style="width:20em" /></p>
- <p style="line-height: 1; padding-top: 1em;">
- <code>:n</code> 表示不带扩展名的文件名; <code>:e</code> 表示扩展名; <code>:E</code> 表示 .扩展名;
- <br><code>:d</code> 表示一位随机数字; <code>:c</code> 表示一位随机字符; <code>:t</code> 表示当前时间戳</p>
- `;
-
- var dialog, $tplConfirmRename;
-
- function showDialog() {
- $tplConfirmRename = $(_tplConfirmRename);
- $('#jx_nameRule', $tplConfirmRename).val(localStorage.jxRenameRule || '[GalACG] :d:d:d:d:d:d:d:d:d:d:E');
-
- dialog = confirmDialog({
- title: '确认批量重命名',
- body: $tplConfirmRename,
- onSure: function() {
- handleConfirm();
- dialog.hide();
- },
- onCancel: function() {
- dialog.hide();
- },
- });
- }
-
- function handleConfirm() {
- // 储存批量重命名记录
- var _nameRule = $('#jx_nameRule', $tplConfirmRename).val();
- localStorage.jxRenameRule = _nameRule;
-
- var _flist = _G.ListInit.getCheckedItems().map(toReplacePayload);
-
- _G.Tip.show({
- mode: 'loading',
- msg: '正在批量重命名,请稍后 ...',
- autoClose: false
- });
-
- $.ajax({
- url: '/api/filemanager?' + $.param({
- channel: 'chunlei',
- bdstoken: yunData.MYBDSTOKEN,
- app_id: __AppId,
- opera: 'rename'
- }),
- type: 'POST',
- data: {
- filelist: JSON.stringify(_flist)
- }
- }).success(function() {
- _G.Tip.hide();
- _G.Message.trigger('system-refresh');
- }).fail(function() {
- _G.Tip.hide();
-
- _G.Tip.show({
- mode: 'failure',
- msg: '批量重命名失败, 请稍后重试!'
- });
- });
-
- function toReplacePayload(item) {
- return {
- path: item.path,
- newname: _nameRule.replace(/:([cdeEn])/g, fixName.bind(item.server_filename))
- };
- }
- }
-
- /* 依赖函数表 */
- function fixName(z, code) {
- switch (code) {
- case 'n':
- var name = this.match(/^(.+)\./);
- return name ? name[1] : this;
- case 'c':
- return String.fromCharCode(97 + Math.random() * 26);
- case 'd':
- return Math.random().toString().slice(3, 4);
- case 't':
- return +new Date();
- case 'e':
- var ext = this.match(/\.([^.]+)$/);
- return ext ? ext[1] : '';
- case 'E':
- return this.match(/\.[^.]+$/) || '';
- }
- }
-
- /* 收尾 */
- return showDialog;
- })();
- }
-
- let div = document.createElement('a');
- let escapeDict = {
- '"': 'quot',
- "'": 'apos',
- };
- function escapeHtml(text) {
- div.textContent = text;
- const result = div.innerHTML.replace(/["']/g, x => `&${escapeDict[x]};`);
- div.textContent = '';
- return result;
- }
-
- function parseSize(size) {
- // 超过 GB
- if (size.length > 9) {
- size = size.slice(0, -7);
- return size.slice(0, -2) + '.' + size.slice(-2) + ' GB';
- }
-
- return (parseInt(size) / 1024 / 1024).toFixed(2) + ' MB';
- }
-
- function itemInfo(item) {
- const name = escapeHtml(item.name);
- return `
- <span class="name" title="${name}">${name}</span>
- <span class="size">(${escapeHtml(parseSize(item.size))})</span>
- `;
- }
-
- function delayLoadDuCode() {
- _G.loadStandardCodeDialog = delayLoadDuStdCode();
-
- function delayLoadDuStdCode() {
- var _tplStandardCode = `
- <div>
- <p><textarea class="jx jx_code jx-input" rows="7" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea></p>
- <p style="line-height: 1; padding: .5em 0;">
- 扩展阅读:
- <a href="http://game.ali213.net/thread-5465798-1-1.html" target="_blank">肚娘代码说明 [游侠]</a>
- | <a href="https://jixun.moe/2017/06/13/du-code-gen/" target="_blank">标准度娘提取码 [梦姬]</a>
- </p>
- <p style="text-align:left">
- <b>文件列表</b> (版本: <span class="jx_version" style="color:black">--</span>):
- </p>
- <ul class="jx_list"></ul>
- <p class="jx_c_warn jx_hide jx_errmsg">无效的提取码! 请确保您输入的提取码无误。</p>
- </div>
- `;
-
- var dialog, $tplStandardCode, codeInfo, jx_list, jx_code, jx_errmsg, jx_version;
- var failed = 0;
-
- function showDialog() {
- $tplStandardCode = $(_tplStandardCode);
-
- dialog = confirmDialog({
- title: '通用提取码',
- body: $tplStandardCode,
- onSure: function() {
- handleConfirm();
- dialog.hide();
- },
- onCancel: function() {
- dialog.hide();
- },
- });
-
- jx_list = $('.jx_list', $tplStandardCode);
- jx_code = $('.jx_code', $tplStandardCode);
- jx_errmsg = $('.jx_errmsg', $tplStandardCode);
- jx_version = $('.jx_version', $tplStandardCode);
-
- function updatePreview () {
- var code = jx_code.val();
- codeInfo = DuParser.parse(code);
- jx_errmsg.toggleClass('jx_hide', Boolean(!code || codeInfo.length));
- if (codeInfo.length) {
- jx_version.text(codeInfo.ver);
- jx_list.html(codeInfo.map(itemInfo).map(x => `<li>${x}</li>`).join(''));
- } else {
- jx_version.text('--');
- jx_list.text('');
- }
- }
-
- const debounce = fn => {
- let timer;
- return () => {
- cancelAnimationFrame(timer);
- timer = requestAnimationFrame(fn);
- };
- };
-
- jx_code.on('blur input', debounce(updatePreview)).focus(function() {
- jx_errmsg.addClass('jx_hide');
- });
- }
-
- var _curDir;
-
- function handleConfirm() {
- _curDir = _G.ListInit.currentKey;
- if (_curDir.slice(-1) != '/')
- _curDir += '/';
-
- failed = 0;
- saveFile(0);
- }
-
- function statusHtml(success) {
- const text = success ? '成功' : '失败';
- const className = success ? 'success' : 'fail';
- return `<span class="jx-status jx-status-${className}">${text}</span>`;
- }
-
- function saveFile(i) {
- if (i >= codeInfo.length) {
- _G.Message.trigger('system-refresh');
- const dialog = confirmDialog({
- title: `转存完毕 (失败 ${failed} 个, 共 ${i} 个)!`,
- body: `
- <ul class="save-complete-details jx_list">
- ${codeInfo.map(info => `<li>${itemInfo(info)}${statusHtml(info.success)}</li>`).join('')}
- </ul>
- `,
- onSure: function() {
- dialog.hide();
- },
- cancel: false,
- });
- return;
- }
-
- _G.Tip.show({
- mode: 'loading',
- msg: `正在转存文件 (${ i + 1 }/${ codeInfo.length }), 请稍后 ..`,
- autoClose: false
- });
-
- var file = codeInfo[i];
-
- $.ajax({
- url: '/api/rapidupload?rtype=1',
- type: 'POST',
- data: {
- path: _curDir + file.name,
- 'content-md5': file.md5,
- 'slice-md5': file.md5s,
- 'content-length': file.size,
- 'local_mtime': ''
- }
- }).success(function(r) {
- _G.Tip.hide();
- if (r.errno) {
- failed++;
- } else {
- codeInfo[i].success = true;
- }
- }).fail(function(r) {
- failed++;
- }).always(function() {
- saveFile(i + 1);
- });
- }
-
- /**
- * 一个简单的类似于 NodeJS Buffer 的实现.
- * 用于解析游侠度娘提取码。
- * @param {SimpleBuffer}
- */
- function SimpleBuffer(str) {
- this.fromString(str);
- }
-
- SimpleBuffer.toStdHex = function toStdHex(n) {
- return ('0' + n.toString(16)).slice(-2);
- };
-
- SimpleBuffer.prototype.fromString = function fromString(str) {
- var len = str.length;
-
- this.buf = new Uint8Array(len);
- for (var i = 0; i < len; i++) {
- this.buf[i] = str.charCodeAt(i);
- }
- };
-
- SimpleBuffer.prototype.readUnicode = function readUnicode(index, size) {
- if (size & 1)
- size++;
-
- var bufText = Array.prototype.slice.call(this.buf, index, index + size).map(SimpleBuffer.toStdHex);
-
- var buf = [''];
- for (var i = 0; i < size; i += 2)
- buf.push(bufText[i + 1] + bufText[i]);
-
- return JSON.parse('"' + buf.join('\\u') + '"');
- };
-
- SimpleBuffer.prototype.readNumber = function readNumber(index, size) {
- var ret = 0;
-
- for (var i = index + size; i > index;)
- ret = this.buf[--i] + (ret * 256);
-
- return ret;
- };
-
- SimpleBuffer.prototype.readUInt = function readUInt(index) {
- return this.readNumber(index, 4);
- };
-
- SimpleBuffer.prototype.readULong = function readULong(index) {
- return this.readNumber(index, 8);
- };
-
- SimpleBuffer.prototype.readHex = function readHex(index, size) {
- return Array.prototype.slice.call(this.buf, index, index + size).map(SimpleBuffer.toStdHex).join('');
- };
-
- function DuParser() {}
- DuParser.parse = function generalDuCodeParse(szUrl) {
- var r;
- if (szUrl.indexOf('BDLINK') === 0) {
- r = DuParser.parseDu_v1(szUrl);
- r.ver = '游侠 v1';
- } else if (szUrl.indexOf('bdpan://') === 0) {
- r = DuParser.parseDu_bdpan(szUrl);
- r.ver = 'PanDownload';
- } else {
- r = DuParser.parseDu_v2(szUrl);
- r.ver = '梦姬标准';
- }
- return r;
- };
-
- DuParser.parseDu_v1 = function parseDu_v1(szUrl) {
- var raw = atob(szUrl.slice(6).replace(/\s/g, ''));
- if (raw.slice(0, 5) !== 'BDFS\x00')
- return null;
-
- var buf = new SimpleBuffer(raw);
-
- var ptr = 9;
- var arrFiles = [];
- var fileInfo, nameSize;
- var total = buf.readUInt(5);
-
- for (i = 0; i < total; i++) {
- // 大小 (8 bytes)
- // MD5 + MD5S (0x20)
- // nameSize (4 bytes)
- // Name (unicode)
- fileInfo = {};
- fileInfo.size = buf.readULong(ptr + 0);
- fileInfo.md5 = buf.readHex(ptr + 8, 0x10);
- fileInfo.md5s = buf.readHex(ptr + 0x18, 0x10);
- nameSize = buf.readUInt(ptr + 0x28) << 1;
- fileInfo.nameSize = nameSize;
- ptr += 0x2C;
-
- fileInfo.name = buf.readUnicode(ptr, nameSize);
- arrFiles.push(fileInfo);
- ptr += nameSize;
- }
-
- return arrFiles;
- };
-
- DuParser.parseDu_v2 = function parseDu_v2(szUrl) {
- return szUrl.split('\n').map(function(z) {
- // unsigned long long: 0~18446744073709551615
- return z.trim().match(/([\dA-F]{32})#([\dA-F]{32})#([\d]{1,20})#([\s\S]+)/);
- }).filter(function(z) {
- return z;
- }).map(function(info) {
- return {
- md5: info[1],
- md5s: info[2],
- size: info[3],
- name: info[4]
- };
- });
- };
-
- DuParser.parseDu_bdpan = function parseDu_bdpan(szUrl) {
- return szUrl.split('\n').map(z => z.trim()).filter(url => szUrl.indexOf('bdpan://') === 0).map(z => {
- return atob(z.slice('bdpan://'.length)).trim().match(/^([\s\S]+)\|([\d]{1,20})\|([\dA-F]{32})\|([\dA-F]{32})$/i);
- }).filter(function(z) {
- return z;
- }).map(function([, name, size, md5, md5s]) {
- name = decodeURIComponent(name.split('').map(z => `%${('0' + z.charCodeAt(0).toString(16)).slice(-2)}`).join(''));
- return { name, size, md5, md5s };
- });
- };
-
- /* 收尾 */
- return showDialog;
- }
- }
-
- function loadDependencies() {
- _G.Message = oRequire("system-core:system/baseService/message/message.js");
- _G.Tip = oRequire("system-core:system/uiService/tip/tip.js");
- _G.Dialog = oRequire("system-core:system/uiService/dialog/dialog.js");
- _G.Context = oRequire("system-core:context/context.js").instanceForSystem;
- _G.ui = _G.Context.ui;
- }
- };
-
- // Inject style
- var style = document.createElement('style');
- style.textContent = `
- .jx_btn {
- background: #fefefe;
- background: linear-gradient(to bottom, #fefefe 0%,#f2f2f2 88%);
-
- display: inline-block;
- line-height: 25px;
- vertical-align: middle;
- margin: 0 0 0 10px;
- text-decoration: none;
- border: 1px solid #AAA;
- padding: 0px 20px;
- height: 26px;
- border-radius: 2px;
-
- min-width: 3em;
- text-align: center;
- }
- .jx_btn, .jx_btn:hover, .jx_btn:focus {
- color: #666;
- }
- .jx_btn:active {
- color: #06C;
- background: #e3e3e3;
- background: -moz-linear-gradient(top, #e3e3e3 0%, #f7f7f7 12%);
- background: -webkit-linear-gradient(top, #e3e3e3 0%,#f7f7f7 12%);
- background: linear-gradient(to bottom, #e3e3e3 0%,#f7f7f7 12%);
- }
- .jx-input {
- margin: 9px 0;
- _margin: 7px 0;
- padding: 0 0 0 5px;
- width: 200px;
- height: 24px;
- vertical-align: middle;
- border: 1px solid #3b8cff;
- border: 1px solid rgba(58,140,255,.3);
- background: #fff;
- border-radius: 2px;
- }
-
- .jx_hide { display: none }
- .jx_c_warn { color: red }
-
- .jx_list {
- text-align: left;
- max-height: 5.5em;
- overflow-y: scroll;
- overflow-x: hidden;
- line-height: 1;
- padding: .2em;
- margin-bottom: .5em;
- }
-
- /*
- .jx_list:not(:empty) {
- border: 1px solid #ddd;
- }
- */
-
- .jx_list > li {
- display: flex;
- white-space: nowrap;
- line-height: 1.3;
- }
-
- .jx_list .name {
- color: black;
-
- overflow: hidden;
- text-overflow: ellipsis;
- }
-
- .jx_list .size {
- color: #777;
-
- flex-grow: 1;
- }
-
- .save-complete-details {
- max-height: 30em;
- }
-
- .jx-status {
- padding-left: 0.25em;
- }
-
- .jx-status-success {
- color: green;
- }
-
- .jx-status-fail {
- color: red;
- }
-
- textarea.jx{
- width: 100%;
- min-height: 5em;
- line-height: 1;
- }
- `;
-
- document.head.appendChild(style);