Block_Obj

BLOCK_OBJ

当前为 2020-07-25 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/407543/830439/Block_Obj.js

  1. // ==UserScript==
  2. // @name Block_Obj
  3. // @namespace https://greasyfork.org/zh-CN/users/193133-pana
  4. // @homepage https://www.sailboatweb.com
  5. // @version 2.6.0
  6. // @description BLOCK_OBJ
  7. // @author pana
  8. // @license GNU General Public License v3.0 or later
  9. // ==/UserScript==
  10.  
  11. const BLOCK_STYLE = `
  12. .block_obj_wrap_div {
  13. background-color: #222222;
  14. border-radius: 3px;
  15. border: 1px solid #282A36;
  16. bottom: 6vh;
  17. box-shadow: 0 0 5px #282A36;
  18. color: #D3D3D3;
  19. font-size: 13px;
  20. margin: 0px;
  21. padding: 0px;
  22. position: fixed;
  23. text-align: left;
  24. transition: 0.8s;
  25. width: 520px;
  26. z-index: 99999;
  27. }
  28. .block_obj_show_wrap {
  29. display: block;
  30. right: 0;
  31. }
  32. .block_obj_hidden_wrap {
  33. right: -530px;
  34. }
  35. .block_obj_main_fieldset {
  36. border-radius: 3px;
  37. border: 3px groove #00A1D6;
  38. height: auto;
  39. margin: 8px;
  40. min-width: 300px;
  41. padding: 4px 9px 6px 9px;
  42. width: auto;
  43. }
  44. .block_obj_ul_node {
  45. list-style: none;
  46. padding-left: 0;
  47. margin: 0;
  48. }
  49. .block_obj_checkbox_li {
  50. display: inline-block;
  51. margin-top: 5px;
  52. }
  53. .block_obj_checkbox_input {
  54. clip: rect(0, 0, 0, 0);
  55. position: absolute;
  56. }
  57. .block_obj_checkbox_label {
  58. cursor: pointer;
  59. vertical-align: middle;
  60. }
  61. .block_obj_checkbox_input + label::before {
  62. background-color: silver;
  63. border-radius: 0.1em;
  64. color: #FFF;
  65. content: "\\a0";
  66. display: inline-block;
  67. height: 1em;
  68. line-height: 85%;
  69. margin-right: 0.5em;
  70. text-align: center;
  71. vertical-align: 0.2em;
  72. width: 1em;
  73. }
  74. .block_obj_checkbox_input:checked + label::before {
  75. background-color: #00A1D6;
  76. content: "\\2713";
  77. }
  78. .block_obj_separator_text {
  79. color: #FFB86C;
  80. margin-bottom: 2px;
  81. margin-top: 2px;
  82. }
  83. .block_obj_separator_symbol {
  84. background-color: #303030;
  85. height: 2px;
  86. margin-bottom: 5px;
  87. margin-top: 5px;
  88. min-width: 400px;
  89. }
  90. .block_obj_input_div {
  91. margin-top: 5px;
  92. }
  93. .block_obj_input {
  94. background-color: #C0C0C0;
  95. border: 1px solid #C0C0C0;
  96. color: #000;
  97. font-size: 13px;
  98. min-height: 15px;
  99. margin-left: 5px;
  100. margin-right: 5px;
  101. padding-left: 4px;
  102. }
  103. .block_obj_keyword_input {
  104. width: 150px;
  105. }
  106. .block_obj_input_btn {
  107. background-color: #3da9cc;
  108. border-radius: 3px;
  109. border: 1px solid #73C9E5;
  110. box-shadow: 0 0 4px #73C9E5;
  111. color: #FFF;
  112. cursor: pointer;
  113. display: inline-block;
  114. min-height: 15px;
  115. line-height: normal;
  116. margin-left: 5px;
  117. text-align: center;
  118. vertical-align: bottom;
  119. white-space: nowrap;
  120. width: 30px;
  121. }
  122. .block_obj_list_div {
  123. margin-top: 5px;
  124. }
  125. .block_obj_list_textarea_div {
  126. border: 1px dotted #00A1D6;
  127. margin-top: 3px;
  128. max-height: 60px;
  129. min-height: 3px;
  130. overflow: auto;
  131. }
  132. .block_obj_list_textarea_div::-webkit-scrollbar {
  133. background-color: #979797;
  134. border-radius: 5px;
  135. width: 10px;
  136. }
  137. .block_obj_list_textarea_div::-webkit-scrollbar-thumb {
  138. background-color: #404040;
  139. border-radius: 5px;
  140. }
  141. .block_obj_button_clicked {
  142. color: #000;
  143. }
  144. .block_obj_child_span {
  145. background-color: #3D3D3D;
  146. border-radius: 5px;
  147. border: 1px solid #3D3D3D;
  148. display: inline-block;
  149. margin: 3px;
  150. padding: 2px;
  151. min-height: 18px;
  152. line-height: normal;
  153. }
  154. .block_obj_child_text {
  155. border-right: 1px solid #A9181C;
  156. margin-right: 4px;
  157. padding-right: 4px;
  158. }
  159. .block_obj_child_del {
  160. color: #A9181C;
  161. cursor: pointer;
  162. }
  163. .block_obj_list_textarea_expand {
  164. max-height: 720px;
  165. }
  166. .block_obj_li_hide {
  167. display: none;
  168. }
  169. .block_obj_reg_input {
  170. width: 100px;
  171. }
  172. .block_obj_modifier_input {
  173. width: 50px;
  174. }
  175. .block_obj_button {
  176. background-color: #FB7299;
  177. border-radius: 4px;
  178. border: 1px solid #FB7299;
  179. color: #FFF;
  180. cursor: pointer;
  181. margin-top: 5px;
  182. padding: 2px 4px;
  183. position: relative;
  184. min-height: 17px;
  185. line-height: normal;
  186. }
  187. .block_obj_save_button {
  188. float: right;
  189. margin-right: 5px;
  190. }
  191. .block_obj_cancel_button {
  192. float: left;
  193. margin-left: 5px;
  194. }
  195. .block_obj_expand_box {
  196. bottom: 0px;
  197. height: 6vh;
  198. position: fixed;
  199. right: -6vw;
  200. transition: 0.5s;
  201. width: 12vw;
  202. z-index: 99999;
  203. }
  204. .block_obj_show_expand_box {
  205. right: 0;
  206. width: 6vw;
  207. }
  208. .block_obj_expand_span {
  209. background-color: #00A1D6;
  210. border-radius: 19px;
  211. border: 1px solid #00A1D6;
  212. bottom: 1vh;
  213. color: #FFF;
  214. cursor: pointer;
  215. display: block;
  216. font-size: 13px;
  217. height: 38px;
  218. line-height: 38px;
  219. position: absolute;
  220. right: 1vw;
  221. text-align: center;
  222. width: 38px;
  223. z-index: 99999;
  224. }
  225. .block_obj_expand_span:hover {
  226. box-shadow: 0 0 5px 1px green;
  227. }
  228. .block_obj_move_right {
  229. margin-left: 15px;
  230. }
  231. .block_obj_none {
  232. display: none !important;
  233. }
  234. .block_obj_hidden {
  235. visibility: hidden !important;
  236. }
  237. `;
  238. class Block_Obj {
  239. constructor(config_key, reg_key_array = []) {
  240. this.wrapDiv = null;
  241. this.mainFieldset = null;
  242. this.ulNode = null;
  243. this.style = null;
  244. this.saveField = [];
  245. this.onSave = null;
  246. this.onChange = null;
  247. this.field = [];
  248. this.configKey = config_key;
  249. this.regKeyArray = reg_key_array;
  250. this.config = this.readConfig();
  251. }
  252. init(initialization) {
  253. if (! this.id) {
  254. this.id = initialization.id ? 'blockObj_' + initialization.id : 'blockObj_' + Block_Obj.count;
  255. ! initialization.id && Block_Obj.count ++;
  256. }
  257. this.display = initialization.display ? true : false;
  258. if (initialization.events) {
  259. if (typeof(initialization.events['save']) === 'function') {
  260. this.onSave = initialization.events['save'];
  261. }
  262. if (typeof(initialization.events['change']) === 'function') {
  263. this.onChange = initialization.events['change'];
  264. }
  265. }
  266. this.style = document.createElement('style');
  267. this.style.type = 'text/css';
  268. this.style.innerHTML = BLOCK_STYLE;
  269. document.body.appendChild(this.style);
  270. if (initialization.style && typeof(initialization.style) === 'string') {
  271. let external_style = document.createElement('style');
  272. external_style.type = 'text/css';
  273. external_style.innerHTML = initialization.style;
  274. document.body.appendChild(external_style);
  275. }
  276. ! this.wrapDiv && this.createSettingsPanel();
  277. this.field = initialization.field;
  278. this.settingsPanel();
  279. initialization.menu && typeof(GM_registerMenuCommand) === 'function' && GM_registerMenuCommand(initialization.menu, () => this.expandWrap());
  280. typeof(GM_addValueChangeListener) === 'function' && GM_addValueChangeListener(this.configKey, (_name, _old_value, new_value, remote) => {
  281. if (remote) {
  282. this.destroyAndRebuild(new_value);
  283. typeof(this.onChange) === 'function' && this.onChange(this.getConfig());
  284. }
  285. });
  286. let expand_box = document.createElement('div');
  287. expand_box.className = 'block_obj_expand_box';
  288. expand_box.onmouseenter = function() {
  289. this.classList.add('block_obj_show_expand_box');
  290. };
  291. expand_box.onmouseleave = function() {
  292. this.classList.remove('block_obj_show_expand_box');
  293. };
  294. let expand_span = document.createElement('span');
  295. expand_span.id = this.id + '_expandSpan';
  296. expand_span.className = 'block_obj_expand_span';
  297. expand_span.textContent = '屏蔽';
  298. expand_span.title = '显示屏蔽设置';
  299. expand_span.addEventListener('click', () => this.expandWrap());
  300. expand_box.appendChild(expand_span);
  301. document.body.appendChild(expand_box);
  302. }
  303. settingsPanel() {
  304. if (Array.isArray(this.field)) {
  305. this.field.forEach(ele => {
  306. if (! this.wrapDiv.querySelector('#' + this.id + '_' + (ele.id ? ele.id : ''))) {
  307. switch (ele.type.toLowerCase()) {
  308. case 'separator':
  309. case 's':
  310. this.insertSeparator(ele.id, ele.label, ele.title, ele.classname);
  311. break;
  312. case 'br':
  313. case 'b':
  314. this.insertBr(ele.classname);
  315. break;
  316. case 'input':
  317. case 'i':
  318. this.insertInput(ele.id, ele.list_id, false, ele.label, ele.title, ele.placeholder, ele.classname, ele.campare);
  319. break;
  320. case 'reg_input':
  321. case 'ri':
  322. this.insertInput(ele.id, ele.list_id, true, ele.label, ele.title, ele.placeholder, ele.classname, ele.campare, ele.modifier_label, ele.modifier_placeholder);
  323. break;
  324. case 'list':
  325. case 'l':
  326. this.insertList(ele.id, (this.config[ele.id] == null ? ele.default : this.config[ele.id]), ele.label, ele.title, ele.classname);
  327. break;
  328. case 'checkbox':
  329. case 'c':
  330. default:
  331. this.insertCheckbox(ele.id, ele.label, ele.title, (this.config[ele.id] == null ? ele.default : this.config[ele.id]), ele.classname, ele.move_right);
  332. break;
  333. }
  334. }
  335. });
  336. }
  337. let save_button = this.createSpanBtn('block_obj_button block_obj_save_button', '保存并关闭', '保存设置并关闭设置窗口', e => {
  338. this.expandWrap();
  339. this.saveConfig();
  340. });
  341. let only_save_button = this.createSpanBtn('block_obj_button block_obj_save_button', '仅保存', '仅保存设置', e => {
  342. only_save_button.textContent = '已保存';
  343. save_timer && window.clearTimeout(save_timer);
  344. var save_timer = window.setTimeout(() => {
  345. only_save_button.textContent = '仅保存';
  346. }, 1000);
  347. this.saveConfig();
  348. });
  349. let cancel_button = this.createSpanBtn('block_obj_button block_obj_cancel_button', '取消', '关闭设置窗口', e => {
  350. this.expandWrap();
  351. cancel_timer && window.clearTimeout(cancel_timer);
  352. var cancel_timer = window.setTimeout(() => {
  353. this.display = false;
  354. this.destroyAndRebuild();
  355. }, 800);
  356. e.stopPropagation();
  357. });
  358. this.ulNode.appendChild(save_button);
  359. this.ulNode.appendChild(only_save_button);
  360. this.ulNode.appendChild(cancel_button);
  361. document.body.appendChild(this.wrapDiv);
  362. }
  363. getConfig() {
  364. let real_config = {};
  365. Object.assign(real_config, this.config);
  366. this.regKeyArray.forEach(key => {
  367. real_config[key] = this.convertArray(real_config[key]);
  368. });
  369. return real_config;
  370. }
  371. readConfig() {
  372. let config = {};
  373. if (typeof(GM_getValue) === 'function' && this.configKey) {
  374. config = GM_getValue(this.configKey, {});
  375. }
  376. return config;
  377. }
  378. saveConfig() {
  379. this.saveField.forEach(item => {
  380. if (item.type == 'checkbox') {
  381. this.config[item.key] = document.getElementById(this.id + '_' + item.key).checked;
  382. } else if (item.type == 'list') {
  383. this.config[item.key] = this.extractList(this.id + '_' + item.key);
  384. }
  385. typeof(GM_setValue) && GM_setValue(this.configKey, this.config);
  386. typeof(this.onSave) === 'function' && this.onSave(this.getConfig());
  387. });
  388. }
  389. createSettingsPanel() {
  390. this.wrapDiv = document.createElement('div');
  391. this.wrapDiv.id = this.id + '_wrapDiv';
  392. this.wrapDiv.className = 'block_obj_wrap_div ' + (this.display ? 'block_obj_show_wrap' : 'block_obj_hidden_wrap');
  393. this.mainFieldset = document.createElement('fieldset');
  394. this.mainFieldset.id = this.id + '_mainFieldset';
  395. this.mainFieldset.className = 'block_obj_main_fieldset';
  396. this.wrapDiv.appendChild(this.mainFieldset);
  397. this.ulNode = document.createElement('ul');
  398. this.ulNode.id = this.id + '_ulNode';
  399. this.ulNode.className = 'block_obj_ul_node';
  400. this.mainFieldset.appendChild(this.ulNode);
  401. document.body.appendChild(this.wrapDiv);
  402. }
  403. destroyAndRebuild(new_config = null) {
  404. this.config = new_config || this.config;
  405. document.body.removeChild(this.wrapDiv);
  406. this.createSettingsPanel();
  407. this.settingsPanel();
  408. }
  409. expandWrap() {
  410. let panel = document.getElementById(this.id + '_wrapDiv');
  411. let button = document.getElementById(this.id + '_expandSpan');
  412. if (panel) {
  413. if (panel.classList.contains('block_obj_show_wrap')) {
  414. this.display = false;
  415. panel.classList.remove('block_obj_show_wrap');
  416. panel.classList.add('block_obj_hidden_wrap');
  417. if (button) {
  418. button.title = '显示屏蔽设置';
  419. }
  420. } else {
  421. this.display = true;
  422. panel.classList.remove('block_obj_hidden_wrap');
  423. panel.classList.add('block_obj_show_wrap');
  424. if (button) {
  425. button.title = '隐藏屏蔽设置';
  426. }
  427. }
  428. }
  429. }
  430. insertCheckbox(id, label = '', title = '', checked = false, classname = null, move_right = false) {
  431. let checkbox_li = document.createElement('li');
  432. checkbox_li.className = 'block_obj_checkbox_li';
  433. classname && checkbox_li.classList.add(classname);
  434. move_right && checkbox_li.classList.add('block_obj_move_right');
  435. let checkbox_input = document.createElement('input');
  436. checkbox_input.type = 'checkbox';
  437. checkbox_input.className = 'block_obj_checkbox_input';
  438. checkbox_input.id = this.id + '_' + id;
  439. checkbox_input.checked = checked ? true : false;
  440. let checkbox_label = document.createElement('label');
  441. checkbox_label.className = 'block_obj_checkbox_label';
  442. checkbox_label.setAttribute('for', this.id + '_' + id);
  443. checkbox_label.textContent = label;
  444. checkbox_label.title = title;
  445. checkbox_li.appendChild(checkbox_input);
  446. checkbox_li.appendChild(checkbox_label);
  447. this.ulNode.appendChild(checkbox_li);
  448. this.saveField.push({
  449. 'key': id,
  450. 'type': 'checkbox'
  451. });
  452. }
  453. insertSeparator(id = null, label = null, title = null, li_classname = null) {
  454. let separator_li = document.createElement('li');
  455. separator_li.className = 'block_obj_separator_li';
  456. li_classname && separator_li.classList.add('block_obj_' + li_classname);
  457. let separator_div = document.createElement('div');
  458. if (id) {
  459. separator_div.id = this.id + '_' + id;
  460. }
  461. if (label) {
  462. separator_div.className = 'block_obj_separator_text';
  463. separator_div.textContent = label;
  464. } else {
  465. separator_div.className = 'block_obj_separator_symbol';
  466. }
  467. separator_div.title = title ? title : '';
  468. separator_li.appendChild(separator_div);
  469. this.ulNode.appendChild(separator_li);
  470. }
  471. insertBr(classname = null) {
  472. let br = document.createElement('br');
  473. br.className = classname ? classname : '';
  474. this.ulNode.appendChild(br);
  475. }
  476. insertInput(id, list_id, is_reg = false, label = '', title = '', placeholder = '', li_classname = null, campare = null, modifier_label = '', modifier_placeholder = '') {
  477. let input_li = document.createElement('li');
  478. input_li.className = li_classname ? 'block_obj_' + li_classname : '';
  479. let input_div = document.createElement('div');
  480. input_div.className = 'block_obj_input_div';
  481. let input_span = document.createElement('span');
  482. input_span.className = 'block_obj_input_span';
  483. input_span.textContent = label;
  484. input_div.appendChild(input_span);
  485. let input = document.createElement('input');
  486. input.id = this.id + '_' + id;
  487. input.title = title;
  488. input.placeholder = placeholder;
  489. input.type = 'text';
  490. input.className = is_reg ? 'block_obj_input block_obj_reg_input' : 'block_obj_input block_obj_keyword_input';
  491. input_span.appendChild(input);
  492. let modifier_span = document.createElement('span');
  493. modifier_span.textContent = modifier_label;
  494. is_reg && input_div.appendChild(modifier_span);
  495. let modifier_input = document.createElement('input');
  496. modifier_input.placeholder = modifier_placeholder;
  497. modifier_input.type = 'text';
  498. modifier_input.className = 'block_obj_input block_obj_modifier_input';
  499. modifier_span.appendChild(modifier_input);
  500. list_id = this.id + '_' + list_id;
  501. input.addEventListener('keyup', e => {
  502. if (e.keyCode === 13) {
  503. is_reg ? this.addRegListItem(input, modifier_input, list_id) : this.addListItem(input, list_id, campare);
  504. }
  505. });
  506. modifier_input.addEventListener('keyup', e => {
  507. e.keyCode === 13 && this.addRegListItem(input, modifier_input, list_id);
  508. });
  509. let add_btn = this.createSpanBtn('block_obj_input_btn', '添加', '添加内容到列表中', e => {
  510. if (is_reg ? this.addRegListItem(input, modifier_input, list_id) : this.addListItem(input, list_id, campare))
  511. this.buttonClicked(add_btn, '添加成功', 'block_obj_button_clicked');
  512. });
  513. let delete_btn = this.createSpanBtn('block_obj_input_btn', '删除', '从列表中删除符合的项目', e => {
  514. if (is_reg ? this.delRegListItem(input, modifier_input, list_id) : this.delListItem(input, list_id))
  515. this.buttonClicked(delete_btn, '删除成功', 'block_obj_button_clicked');
  516. });
  517. let clear_btn = this.createSpanBtn('block_obj_input_btn', '清空', '清空列表', e => {
  518. document.getElementById(list_id).innerHTML = '';
  519. this.buttonClicked(clear_btn, '清除成功', 'block_obj_button_clicked');
  520. });
  521. let copy_btn = this.createSpanBtn('block_obj_input_btn', '复制', '复制列表', e => {
  522. if (typeof(GM_setClipboard) == 'function') {
  523. GM_setClipboard(this.extractList(list_id).toString(), 'text');
  524. this.buttonClicked(copy_btn, '复制成功', 'block_obj_button_clicked');
  525. } else {
  526. alert('GM_setClipboard is not an interface.');
  527. }
  528. });
  529. let expand_btn = this.createSpanBtn('block_obj_input_btn', '展开', '展开列表', e => {
  530. li_classname && this.toggleList('block_obj_' + li_classname);
  531. if (expand_btn.textContent == '展开') {
  532. expand_btn.textContent = '恢复';
  533. expand_btn.title = '收缩列表';
  534. } else {
  535. expand_btn.textContent = '展开';
  536. expand_btn.title = '展开列表';
  537. }
  538. });
  539. input_div.appendChild(add_btn);
  540. input_div.appendChild(delete_btn);
  541. input_div.appendChild(clear_btn);
  542. input_div.appendChild(copy_btn);
  543. input_div.appendChild(expand_btn);
  544. input_li.appendChild(input_div);
  545. this.ulNode.appendChild(input_li);
  546. }
  547. insertList(id, save_array = [], label = '', title = '', li_classname = '') {
  548. let list_li = document.createElement('li');
  549. list_li.className = li_classname ? 'block_obj_' + li_classname : '';
  550. let list_div = document.createElement('div');
  551. list_div.className = 'block_obj_list_div';
  552. list_div.textContent = label;
  553. list_div.title = title;
  554. let list_textarea_div = document.createElement('div');
  555. list_textarea_div.id = this.id + '_' + id;
  556. list_textarea_div.className = 'block_obj_list_textarea_div';
  557. for (let item of save_array) {
  558. item && list_textarea_div.insertAdjacentElement('afterbegin', this.createListItem(item));
  559. }
  560. list_div.appendChild(list_textarea_div);
  561. list_li.appendChild(list_div);
  562. this.ulNode.appendChild(list_li);
  563. this.saveField.push({
  564. 'key': id,
  565. 'type': 'list'
  566. });
  567. }
  568. addListItem(input, list_id, campare = null) {
  569. let text_value = input.value;
  570. if (text_value) {
  571. let status = true;
  572. if (typeof(campare) === 'function') {
  573. let temp_status = campare(text_value);
  574. if (typeof(temp_status) === 'boolean') {
  575. status = temp_status;
  576. }
  577. }
  578. if (status) {
  579. let text_arr = this.stringToArray(text_value);
  580. let save_arr = this.extractList(list_id);
  581. text_arr.forEach(item => {
  582. ! save_arr.includes(item) && document.getElementById(list_id).insertAdjacentElement('afterbegin', this.createListItem(item));
  583. });
  584. input.value = '';
  585. return true;
  586. }
  587. }
  588. return false;
  589. }
  590. delListItem(input, list_id) {
  591. let text_value = input.value;
  592. if (text_value) {
  593. let del_status = false;
  594. let text_arr = this.stringToArray(text_value);
  595. let save_arr = this.extractList(list_id);
  596. text_arr.forEach(item => {
  597. if (save_arr.includes(item)) {
  598. let total_child = document.getElementById(list_id).getElementsByClassName('block_obj_child_span');
  599. try {
  600. document.getElementById(list_id).removeChild(total_child[total_child.length - 1 - save_arr.indexOf(item)]);
  601. del_status = true;
  602. } catch(e) {
  603. del_status = false;
  604. console.error('Block_Obj: Error deleting element.');
  605. console.error(e);
  606. }
  607. }
  608. });
  609. if (del_status) {
  610. input.value = '';
  611. return true;
  612. }
  613. }
  614. return false;
  615. }
  616. addRegListItem(reg_input, modifier_input, list_id) {
  617. let reg_value = reg_input.value;
  618. let modifier_value = modifier_input.value;
  619. if (reg_value) {
  620. try {
  621. let reg_obj = new RegExp(reg_value, modifier_value);
  622. let save_arr = this.extractList(list_id);
  623. ! save_arr.includes(reg_obj.toString()) && document.getElementById(list_id).insertAdjacentElement('afterbegin', this.createListItem(reg_obj.toString()));
  624. reg_input.value = '';
  625. modifier_input.value = '';
  626. return true;
  627. } catch(e) {
  628. console.error('Block_Obj: Invalid regular expression.');
  629. console.error(e);
  630. }
  631. }
  632. return false;
  633. }
  634. delRegListItem(reg_input, modifier_input, list_id) {
  635. let reg_value = reg_input.value;
  636. let modifier_value = modifier_input.value;
  637. if (reg_value) {
  638. let del_status = false;
  639. try {
  640. let reg_obj = new RegExp(reg_value, modifier_value);
  641. let save_arr = this.extractList(list_id);
  642. if (save_arr.includes(reg_obj.toString())) {
  643. let total_child = document.getElementById(list_id).getElementsByClassName('block_obj_child_span');
  644. document.getElementById(list_id).removeChild(total_child[total_child.length - 1 - save_arr.indexOf(reg_obj.toString())]);
  645. del_status = true;
  646. }
  647. } catch(e) {
  648. del_status = false;
  649. console.error('Block_Obj: Invalid regular expression or error deleting element.');
  650. console.error(e);
  651. }
  652. if (del_status) {
  653. reg_input.value = '';
  654. modifier_input.value = '';
  655. return true;
  656. }
  657. return false;
  658. }
  659. }
  660. createSpanBtn(classname, label, title, callback) {
  661. let btn_span = document.createElement('span');
  662. btn_span.className = classname;
  663. btn_span.textContent = label;
  664. btn_span.title = title;
  665. btn_span.addEventListener('click', e => typeof(callback) === 'function' && callback(e));
  666. return btn_span;
  667. }
  668. createListItem(text_value) {
  669. let child_span = document.createElement('span');
  670. child_span.className = 'block_obj_child_span';
  671. let text_span = document.createElement('span');
  672. text_span.className = 'block_obj_child_text';
  673. text_span.textContent = text_value.length > 9 ? text_value.slice(0, 3) + '...' + text_value.slice(-3) : text_value;
  674. if (text_value.length > 9) {
  675. text_span.title = text_value;
  676. }
  677. let del_span = document.createElement('span');
  678. del_span.textContent = 'X';
  679. del_span.title = '移除';
  680. del_span.className = 'block_obj_child_del';
  681. del_span.addEventListener('click', e => child_span.remove());
  682. child_span.appendChild(text_span);
  683. child_span.appendChild(del_span);
  684. return child_span;
  685. }
  686. createBlockBtn(value, list_id, classname, type = 'span', text = '', title = '') {
  687. let btn_type = 'span';
  688. if (typeof(type) === 'string') {
  689. switch (type.toLowerCase()) {
  690. case 'div':
  691. case 'd':
  692. btn_type = 'div';
  693. break;
  694. case 'a':
  695. btn_type = 'a';
  696. break;
  697. case 'button':
  698. btn_type = 'button';
  699. break;
  700. case 'input':
  701. btn_type = 'input';
  702. break;
  703. case 'i':
  704. btn_type = 'i';
  705. break;
  706. case 'b':
  707. btn_type = 'b';
  708. break;
  709. case 'span':
  710. case 's':
  711. default:
  712. btn_type = 'span';
  713. break;
  714. }
  715. }
  716. let block_btn = document.createElement(btn_type);
  717. block_btn.textContent = text ? text : '';
  718. block_btn.title = title ? title : '';
  719. block_btn.className = classname ? classname : '';
  720. block_btn.addEventListener('click', e => {
  721. e.stopPropagation();
  722. if (value && list_id) {
  723. list_id = this.id + '_' + list_id;
  724. let save_arr = this.extractList(list_id);
  725. ! save_arr.includes(value) && document.getElementById(list_id) && document.getElementById(list_id).insertAdjacentElement('afterbegin', this.createListItem(value));
  726. }
  727. this.saveConfig();
  728. });
  729. return block_btn;
  730. }
  731. buttonClicked(button, click_title, click_class) {
  732. let original_title = button.title;
  733. button.title = click_title;
  734. click_class && button.classList.add(click_class);
  735. timer && window.clearTimeout(timer);
  736. var timer = window.setTimeout(() => {
  737. button.title = original_title;
  738. button.classList.remove(click_class);
  739. }, 1000);
  740. }
  741. extractList(list_id) {
  742. let re_arr = [];
  743. let list_dom = document.getElementById(list_id);
  744. let list_arr = list_dom.getElementsByClassName('block_obj_child_text');
  745. for (let i = list_arr.length - 1; i >= 0; i --) {
  746. list_arr[i].title ? re_arr.push(list_arr[i].title) : re_arr.push(list_arr[i].textContent);
  747. }
  748. return re_arr;
  749. }
  750. stringToArray(text_string) {
  751. let temp_array = text_string.split(',');
  752. let return_array = [];
  753. for (let i = 0, l = temp_array.length; i < l; i ++) {
  754. for (let j = i + 1; j < l; j ++) {
  755. if (temp_array[i] === temp_array[j]) {
  756. ++ i;
  757. j = i;
  758. }
  759. }
  760. return_array.push(temp_array[i]);
  761. }
  762. return return_array;
  763. }
  764. toggleList(li_classname) {
  765. for (let li of this.ulNode.querySelectorAll('li')) {
  766. if (li.classList.contains(li_classname)) {
  767. let list_textarea_div = li.querySelector('.block_obj_list_textarea_div');
  768. if (list_textarea_div) {
  769. list_textarea_div.classList.contains('block_obj_list_textarea_expand') ? list_textarea_div.classList.remove('block_obj_list_textarea_expand') : list_textarea_div.classList.add('block_obj_list_textarea_expand');
  770. }
  771. } else {
  772. li.classList.contains('block_obj_li_hide') ? li.classList.remove('block_obj_li_hide') : li.classList.add('block_obj_li_hide');
  773. }
  774. }
  775. for (let br of this.ulNode.querySelectorAll('br')) {
  776. br.classList.contains('block_obj_li_hide') ? br.classList.remove('block_obj_li_hide') : br.classList.add('block_obj_li_hide');
  777. }
  778. }
  779. convertArray(string_array) {
  780. let re_arr = [];
  781. if (Array.isArray(string_array)) {
  782. for (let i in string_array) {
  783. try {
  784. let new_reg = new RegExp(string_array[i].replace(/^\/|\/[a-z]*$/gi, ''), string_array[i].replace(/^\/.*\/[^a-z]*/i, ''));
  785. re_arr.push(new_reg);
  786. } catch(e) {
  787. console.error('Block_Obj: The transformation contains invalid regular expressions.');
  788. console.error(e);
  789. }
  790. }
  791. }
  792. return re_arr;
  793. }
  794. }
  795. Block_Obj.count = 0;
  796. Block_Obj.fn = {
  797. 'hideOperation': (node, hide_status, method) => {
  798. if (node && node instanceof HTMLElement) {
  799. if (hide_status) {
  800. if (method === 0) {
  801. node.classList.add('block_obj_none');
  802. } else if (method === 1) {
  803. node.classList.add('block_obj_hidden');
  804. } else if (method === 2) {
  805. node.style.display = 'none';
  806. } else if (method === 3) {
  807. node.style.visibility = 'hidden';
  808. }
  809. } else {
  810. if (method === 0) {
  811. node.classList.remove('block_obj_none');
  812. } else if (method === 1) {
  813. node.classList.remove('block_obj_hidden');
  814. } else if (method === 2) {
  815. node.style.display = '';
  816. } else if (method === 3) {
  817. node.style.visibility = '';
  818. }
  819. }
  820. }
  821. }
  822. };