Stylish 轻捷

像Stylish一样:安装和管理用户样式

当前为 2017-12-27 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Stylish Lite
  3. // @name:zh-CN Stylish 轻捷
  4. // @namespace https://greasyfork.org/zh-CN/users/104201
  5. // @icon data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAFVBMVEUAAAA0mNsuzHHnTDw0mNvznBL////Mp1gEAAAAAnRSTlMAQABPjKgAAAABYktHRAZhZrh9AAAAB3RJTUUH4QwXBjotfQkeHgAAAElJREFUWMPtyzERgEAQBLBjwAAOGCy8BQTQ4N8KBvYovyHpU2d2VK0jK0VRFEWZW1pKU5Y9+yjblSmK8tPSU3J5sltRFEVR5pYXL1PRF3j4eAwAAAAASUVORK5CYII=
  6. // @version 0.1
  7. // @description Install and Manage user styles,Just like Stylish.
  8. // @description:zh-CN 像Stylish一样:安装和管理用户样式
  9. // @author 黄盐(Foowon)
  10. // @include *
  11. // @noframes
  12. // @require https://cdn.bootcss.com/zepto/1.2.0/zepto.min.js
  13. // @grant unsafeWindow
  14. // @run-at document-start
  15. // @grant GM_setValue
  16. // @grant GM_getValue
  17. // @grant GM_openInTab
  18. // @grant GM_registerMenuCommand
  19. // @grant GM_unregisterMenuCommand
  20. // @grant GM_xmlhttpRequest
  21. // ==/UserScript==
  22. /* jshint esversion: 6 */
  23. ;
  24. 'use strict';
  25. //========如果你一定要用 Greasymonkey 可以把 28 行注释打开,然后把 第 29 行注释掉.
  26. //然后 把脚本所有的 GM_getValue 替换为 await GM.getValue, 所有的 GM_setValue 替换为 await.setValue 或许可用...
  27. //推荐 安装Tampermonkey 使用脚本.
  28. // (async () => {
  29. (function () {
  30.  
  31. //===============PART ① Add Styles To Tabs======================================//
  32. const applyCssId = 'stylishLite';const SLSpliter = '\n<<<===SL===>>>\n';
  33. const ruleReg = /(url|url-prefix|domain|regexp)\(['"]?.*\)/;
  34. const blockBeginReg = /@\s*(-moz-document|media).+/g;
  35. const blockEndReg = /\}[^{]*\}/g;
  36. // parser: use to process rawText form userstyles.org/styles/*
  37. // use to save styles in manage panel
  38. let parser={
  39. css:'',
  40. partEndReg: /\}[^{]*\}/,
  41. partBeginReg: /@-moz-document.+\n\{\n/,
  42. ruleBeginReg: /@-moz-document /,
  43. ruleLineReg: /@-moz-document.+/,
  44. matchReg: /(url-prefix|regexp|domain)\((\S)+\)/g,
  45. ruleReg: /(url|url-prefix|regexp|domain)\((\S)+\)/g,
  46. ruleTextPreReg: /(url|url-prefix|regexp|domain)\(('|")?/,
  47. ruleTextEndReg: /('|")?\)/,
  48. //convert userstyles.org mozilla document format to SL format(my script format)
  49. moz2SL: function(mozString){
  50. let string = mozString,
  51. begins = parser.getIndexs(string,blockBeginReg),
  52. ends = parser.getIndexs(string,blockEndReg);
  53. if(!begins.indexs.length) return [string];
  54.  
  55. let bidxs = begins.indexs,
  56. bmches = begins.matches,
  57. eidxs = ends.indexs,
  58. emches = ends.matches;
  59. if(bidxs.length !== eidxs.length){
  60. //这里只是修补了 [一重嵌套] 问题,更多层的嵌套情况就可能会出错
  61. if(bidxs.length - eidxs.length > 1) {
  62. console.info('[Stylish Lite Error]:Parse Mozilla Format Document Error');
  63. return [string];
  64. }
  65. for(let i in emches){
  66. if(emches[i].match(/\}/g).length>2){
  67. let p1 = emches[i].indexOf('}',1);
  68. let n1 = emches[i].slice(0,p1+1);
  69. emches.splice(i,1,n1,emches[i].slice(p1));
  70. eidxs.splice(i,1,eidxs[i],eidxs[i]+n1.length);
  71. }
  72. }
  73. }
  74. let tmp = [];
  75. for(let i in eidxs){
  76. tmp[i] = eidxs[i] + ends.matches[i].length;
  77. }
  78. eidxs = tmp;
  79. let blocks = [];
  80. blocks.push(string.slice(0,bidxs[0]).trim());
  81. let start = bidxs[0],
  82. end = eidxs[0];
  83. for(let i in bmches){
  84. if(bidxs[parseInt(i)+1]){
  85. if(bmches[parseInt(i)+1].match(ruleReg)){
  86. blocks.push(string.slice(start, end).trim());
  87. blocks.push(string.slice(end,bidxs[parseInt(i)+1]).trim());
  88. start = bidxs[parseInt(i)+1];
  89. end = eidxs[parseInt(i)+1];
  90. }else{
  91. end = eidxs[parseInt(i)+1];
  92. }
  93. }else{
  94. if(bmches[i].match(ruleReg)){
  95. blocks.push(string.slice(start, end).trim());
  96. blocks.push(string.slice(end).trim());
  97. }else{
  98. blocks.push(string.slice(start).trim());
  99. }
  100. }
  101. }
  102. // delete blank block
  103. tmp = [];
  104. for(let i in blocks){
  105. if(/\S/.test(blocks[i])) tmp.push(blocks[i]);
  106. }
  107. return tmp.join(SLSpliter);
  108. },
  109. //delete repeat value
  110. unique: function(arr){
  111. let a = {},
  112. b = [];
  113. for(let i in arr){
  114. if(!a[arr[i]]) {
  115. a[arr[i]] = true;
  116. b.push(arr[i]);
  117. }
  118. }
  119. return b;
  120. },
  121. //concat all matched css
  122. concat: function(cssArr){
  123. this.css = '';
  124. for(let i = 0; i < cssArr.length; i++){
  125. this.css += getCss(cssArr[i]);
  126. }
  127. return this.css;
  128. },
  129. //SLString from moz2SL or form GM_getValue
  130. split: function(SLString){
  131. return SLString.split(SLSpliter);
  132. },
  133. getIndexs: function(raw, searchRegexp/*global regexp*/){
  134. if(!raw || !/\S/.test(raw)) return{indexs:[],matches:[]}; //blank string
  135. let matches = raw.match(searchRegexp);
  136. if(!matches) return {indexs:[],matches:[]}; //string widthout rule
  137. let idx, indexs =[], lastIndex = 0;
  138. for(let i in matches){
  139. idx = raw.indexOf(matches[i],lastIndex);
  140. indexs.push(idx);
  141. lastIndex = idx+matches[i].length;
  142. }
  143. return {
  144. indexs:indexs,
  145. matches: matches
  146. };
  147. },
  148. // str: striing block form split(rawStr)
  149. // @-moz-document rul(....) \n xxxxx....
  150. getCss: function(str, edit){
  151. let string = $.trim(str),
  152. ruleLine = string.match(/@-moz-document.+/);
  153. if(ruleLine === null) return string;
  154. let css='',
  155. rules = ruleLine[0].match(/(url|url-prefix|regexp|domain)\((\S)+\)/g);
  156. if(edit || parser.checkMatch(rules)) css = string.slice(ruleLine[0].length +2, -2).replace(/\n /g,'\n');
  157. return $.trim(css);
  158. },
  159. getRule: function(ruleStr){
  160. return ruleStr.slice(0, ruleStr.indexOf('('));
  161. },
  162. getRuleText:function(ruleStr){
  163. return ruleStr.replace(parser.ruleTextPreReg,'').replace(parser.ruleTextEndReg,'');
  164. },
  165. checkMatch: function(rulesArr){
  166. if(rulesArr === null || rulesArr.length === 0) return true;
  167. let rule = '',
  168. ruleText = '',
  169. isMatch = false;
  170. LbMatch:{
  171. for(let i in rulesArr){
  172. rule = parser.getRule(rulesArr[i]);
  173. ruleText = parser.getRuleText(rulesArr[i]);
  174. switch (rule) {
  175. case 'url':
  176. if(document.location.href == ruleText){
  177. isMatch = true;
  178. break LbMatch;
  179. }
  180. break;
  181. case 'url-prefix':
  182. if(document.location.href.indexOf(ruleText) == 0){
  183. isMatch = true;
  184. break LbMatch;
  185. }
  186. break;
  187. case 'domain':
  188. if(document.domain == ruleText || document.domain.substring(document.domain.indexOf(ruleText) + 1) == ruleText){
  189. isMatch = true;
  190. break LbMatch;
  191. }
  192. break;
  193. default://regexp
  194. if(new RegExp(ruleText).test(document.location.href)){
  195. isMatch = true;
  196. break LbMatch;
  197. }
  198. break;
  199. }
  200. }
  201. }
  202. return isMatch;
  203. }
  204. };
  205. function apply(){
  206. let tmp,doc,
  207. cssText = '',
  208. matchedStyles = [],
  209. styles = GM_getValue('styles', {}),
  210. css = GM_getValue('css', {});
  211. for(let i in styles){
  212. if(!styles[i].enable) continue;
  213. if(parser.checkMatch(styles[i].rule)){
  214. cssText += `\n/*-------------${i}----------------*/\n`;
  215. tmp = parser.split(css[i]);
  216. for(let j in tmp){
  217. cssText += parser.getCss(tmp[j]);
  218. }
  219. }
  220. }
  221. addStyle(cssText, applyCssId);
  222. }
  223. // this addStyle function is better than GM_addStyle
  224. function addStyle(cssStr,id='styishLite'){
  225. try {
  226. let doc = document.body || document.documentElement;
  227. $(doc).after($(`<style id="${id}" type="text/css"><!--\n${cssStr}\n--></style>`));
  228. } catch(e) {
  229. let head = document.head || document.documentElement;
  230. $(head).after($(`<style id="${id}" type="text/css"><!--\n${cssStr}\n--></style>`));
  231. }
  232. }
  233. function checkList(key){
  234. let isApply = true,
  235. list = GM_getValue('nameList',{}),
  236. // default name list mode: black
  237. nameListMode = GM_getValue('nameListMode','black');
  238. if(list[key]){
  239. if(nameListMode === 'black') isApply = false;
  240. }else{
  241. if(nameListMode === 'white') isApply = false;
  242. }
  243. return isApply;
  244. }
  245. //(onlist && white list) || (not on list && black list)=> apply()
  246. if(checkList(location.origin)) apply();
  247.  
  248. //===============PART ② Action on userstyles.org/styles/**id**/**name** ========//
  249. const LogoSVG = `<svg width="100%" height="100%" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><g><rect x="0" y="0" width="30" height="30" fill="none"/></g><g><rect fill="#2ecc71" stroke="#000" stroke-width="0" width="47" height="70" y="0" x="0"/><rect fill="#3498db" stroke="#000" stroke-width="0" x="53" y="30" width="47" height="70"/><rect fill="#e74c3c" stroke="#000" stroke-width="0" x="53" y="0" width="47" height="25"/><rect fill="#f39c12" stroke="#000" stroke-width="0" x="0" y="75" width="47" height="25"/><text fill="#ffffff" stroke-width="0" x="20" y="57" font-size="50" font-family="'Courier New', Courier, monospace" text-anchor="start" xml:space="preserve" font-weight="bold" transform="matrix(1.67,0,0,1.9,-35,-45) " stroke="#000">S</text><text fill="#ffffff" stroke-width="0" x="53" y="71" font-size="48" font-family="'Courier New', Courier, monospace" text-anchor="start" xml:space="preserve" font-weight="bold" transform="matrix(1.65,0,0,1.9,-35,-45) " stroke="#000">L</text></g></svg>`;
  250.  
  251. //works on https://userstyles.org/styles/*
  252. let utorg = {
  253. locationReg: /https:\/\/userstyles.org\/styles\/\d+\/.*/,
  254. siteMatched: function(){
  255. return this.locationReg.test(location.href);
  256. },
  257. createButton: function(){
  258. if( !$ && ($('div#install_style_button').length<1 || $('div#buttons').length < 1)) {
  259. setTimeout(utorg.createButton, 500);
  260. return;
  261. }else{
  262. let tar = $('div#buttons'),
  263. styles = GM_getValue('styles',{}),
  264. name = $('h1[id=stylish-description]').text(),
  265. version = $('div#infomation_value_left').last().text(),
  266. buttonClass = '',
  267. buttonText = '';
  268. if(styles[name]){
  269. if(styles[name].version === version){
  270. buttonClass = 'slCheck';
  271. buttonText = 'Installed';
  272. }else{
  273. buttonClass = 'slRefresh';
  274. buttonText = 'Update Style';
  275. }
  276. }else{
  277. buttonClass = 'slDownload';
  278. buttonText = 'Install Style';
  279. }
  280.  
  281. if(tar.length ===0){
  282. setTimeout(utorg.createButton, 500);
  283. return;
  284. }
  285. let a = $('div#buttons').children().first().before(`<div id="SLInstall" style="display:flex;flex-direction:row;align-items:center;justify-content:center;border-radius:4px;background-color:#2ECC71;box-shadow:0 6px 16px 0 rgba(80, 178, 243, 0.35);color:white;font-size:16px;cursor:pointer;font-weight:bold;width:173px;height:48px;margin-left:9px;"><div id="SLBtnIcon" class="${buttonClass}" style="font:30px;margin-right:10px;"></div><div>${buttonText}</div></div>`);
  286.  
  287. $('#SLInstall').off();
  288. $('#SLInstall').on('click', utorg.install);
  289. }
  290. },
  291. // get raw text from userstyles.org
  292. getRawCss: function(){
  293. return $('#stylish-code').val();
  294. },
  295. install: function(){
  296. let rawCss = utorg.getRawCss();
  297. if(!rawCss){
  298. setTimeout(utorg.install, 500);
  299. return;
  300. }
  301. let ruleLines = rawCss.match(parser.ruleLineReg),
  302. name = $('h1[id=stylish-description]').text(),
  303. styles = GM_getValue('styles', {}),
  304. css = GM_getValue('css', {});
  305. if(name.length < 1) return false;
  306. GM_setValue('styles',styles);
  307. css[name] = $.trim(parser.moz2SL(rawCss));
  308. GM_setValue('css',css);
  309. stylesObj = {
  310. name: name,
  311. rule: parser.unique(ruleLines.join('\n').match(parser.ruleReg)),
  312. enable: true,
  313. version: $('div#infomation_value_left').last().text(),
  314. stylesOrgId: location.href.split('/')[4]
  315. };
  316. styles[name] = stylesObj;
  317. $('#SLInstall').text('Installed');
  318. $('#SLBtnIcon').attr('class','slCheck');
  319. }
  320. };
  321. //https://userstyles.org/styles
  322. $(()=>{
  323. if(utorg.siteMatched()){
  324. addStyle(SLFontCSS,'SLFontCSS');
  325. utorg.createButton();
  326. }
  327. });
  328.  
  329. //===============PART ③ Manage Styles ==========================================//
  330. const SLFontCSS = `
  331. /* =================== SLClass ==================== */
  332. @font-face {font-family: 'SL';src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff');}
  333. .slSpace::before {content:' ';font-family:SL;display:inline-block;width:30px;}
  334. .slAdd::before {content:'A';font-family:SL;}
  335. .slMinus::before {content:'B';font-family:SL;}
  336. .slCheck::before {content:'C';font-family:SL;}
  337. .slClose::before {content:'D';font-family:SL;}
  338. .slCopy::before {content:'E';font-family:SL;}
  339. .slDeleteNormal::before{content:'F';font-family:SL;}
  340. .slEdit::before {content:'G';font-family:SL;}
  341. .slSave::before {content:'H';font-family:SL;}
  342. .slOn::before {content:'I';font-family:SL;color:#2ACD71;}
  343. .slOff::before {content:'J';font-family:SL;color:#E84A39;}
  344. .slCube::before {content:'K';font-family:SL;}
  345. .slCubes::before {content:'M';font-family:SL;}
  346. .slDownload::before {content:'N';font-family:SL;}
  347. .slRefresh::before {content:'O';font-family:SL;}
  348. .slLink::before {content:'P';font-family:SL;}
  349. .slList::before {content:'Q';font-family:SL;}
  350. .slReturn::before {content:'R';font-family:SL;}
  351. .slTag::before {content:'T';font-family:SL;padding-right:10px;}
  352. .slMagic::before {content:'U';font-family:SL;}
  353. .slCode::before {content:'V';font-family:SL;}
  354. .slPin::before {content:'W';font-family:SL;}
  355. .slApp::before {content:'X';font-family:SL;}
  356. .slVerDots::before {content:'Y';font-family:SL;}
  357. .slDeleteBold::before {content:'Z';font-family:SL;}
  358. .slVisible::before {content:'a';font-family:SL;}
  359. .slHidden::before {content:'b';font-family:SL;}
  360. .slMidThinger::before {content:'c';font-family:SL;}
  361. /* ===================SLClass End==================== */
  362. `;
  363. //======== prism === css_beautfy =========
  364. /* PrismJS 1.9.0 http://prismjs.com/download.html?themes=prism-solarizedlight&languages=css */
  365. var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,disableWorkerMessageHandler:_self.Prism&&_self.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof r?new r(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case"Object":var r={};for(var a in e)e.hasOwnProperty(a)&&(r[a]=n.util.clone(e[a]));return r;case"Array":return e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var r=n.util.clone(n.languages[e]);for(var a in t)r[a]=t[a];return r},insertBefore:function(e,t,r,a){a=a||n.languages;var l=a[e];if(2==arguments.length){r=arguments[1];for(var i in r)r.hasOwnProperty(i)&&(l[i]=r[i]);return l}var o={};for(var s in l)if(l.hasOwnProperty(s)){if(s==t)for(var i in r)r.hasOwnProperty(i)&&(o[i]=r[i]);o[s]=l[s]}return n.languages.DFS(n.languages,function(t,n){n===a[e]&&t!=e&&(this[t]=o)}),a[e]=o},DFS:function(e,t,r,a){a=a||{};for(var l in e)e.hasOwnProperty(l)&&(t.call(e,l,e[l],r||l),"Object"!==n.util.type(e[l])||a[n.util.objId(e[l])]?"Array"!==n.util.type(e[l])||a[n.util.objId(e[l])]||(a[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,l,a)):(a[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,null,a)))}},plugins:{},highlightAll:function(e,t){n.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,r){var a={callback:r,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var l,i=a.elements||e.querySelectorAll(a.selector),o=0;l=i[o++];)n.highlightElement(l,t===!0,a.callback)},highlightElement:function(t,r,a){for(var l,i,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(l=(o.className.match(e)||[,""])[1].toLowerCase(),i=n.languages[l]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,t.parentNode&&(o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l));var s=t.textContent,g={element:t,language:l,grammar:i,code:s};if(n.hooks.run("before-sanity-check",g),!g.code||!g.grammar)return g.code&&(n.hooks.run("before-highlight",g),g.element.textContent=g.code,n.hooks.run("after-highlight",g)),n.hooks.run("complete",g),void 0;if(n.hooks.run("before-highlight",g),r&&_self.Worker){var u=new Worker(n.filename);u.onmessage=function(e){g.highlightedCode=e.data,n.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,a&&a.call(g.element),n.hooks.run("after-highlight",g),n.hooks.run("complete",g)},u.postMessage(JSON.stringify({language:g.language,code:g.code,immediateClose:!0}))}else g.highlightedCode=n.highlight(g.code,g.grammar,g.language),n.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,a&&a.call(t),n.hooks.run("after-highlight",g),n.hooks.run("complete",g)},highlight:function(e,t,a){var l=n.tokenize(e,t);return r.stringify(n.util.encode(l),a)},matchGrammar:function(e,t,r,a,l,i,o){var s=n.Token;for(var g in r)if(r.hasOwnProperty(g)&&r[g]){if(g==o)return;var u=r[g];u="Array"===n.util.type(u)?u:[u];for(var c=0;c<u.length;++c){var h=u[c],f=h.inside,d=!!h.lookbehind,m=!!h.greedy,p=0,y=h.alias;if(m&&!h.pattern.global){var v=h.pattern.toString().match(/[imuy]*$/)[0];h.pattern=RegExp(h.pattern.source,v+"g")}h=h.pattern||h;for(var b=a,k=l;b<t.length;k+=t[b].length,++b){var w=t[b];if(t.length>e.length)return;if(!(w instanceof s)){h.lastIndex=0;var _=h.exec(w),P=1;if(!_&&m&&b!=t.length-1){if(h.lastIndex=k,_=h.exec(e),!_)break;for(var A=_.index+(d?_[1].length:0),j=_.index+_[0].length,x=b,O=k,N=t.length;N>x&&(j>O||!t[x].type&&!t[x-1].greedy);++x)O+=t[x].length,A>=O&&(++b,k=O);if(t[b]instanceof s||t[x-1].greedy)continue;P=x-b,w=e.slice(k,O),_.index-=k}if(_){d&&(p=_[1].length);var A=_.index+p,_=_[0].slice(p),j=A+_.length,S=w.slice(0,A),C=w.slice(j),M=[b,P];S&&(++b,k+=S.length,M.push(S));var E=new s(g,f?n.tokenize(_,f):_,y,_,m);if(M.push(E),C&&M.push(C),Array.prototype.splice.apply(t,M),1!=P&&n.matchGrammar(e,t,r,b,k,!0,g),i)break}else if(i)break}}}}},tokenize:function(e,t){var r=[e],a=t.rest;if(a){for(var l in a)t[l]=a[l];delete t.rest}return n.matchGrammar(e,r,t,0,0,!1),r},hooks:{all:{},add:function(e,t){var r=n.hooks.all;r[e]=r[e]||[],r[e].push(t)},run:function(e,t){var r=n.hooks.all[e];if(r&&r.length)for(var a,l=0;a=r[l++];)a(t)}}},r=n.Token=function(e,t,n,r,a){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length,this.greedy=!!a};if(r.stringify=function(e,t,a){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return r.stringify(n,t,e)}).join("");var l={type:e.type,content:r.stringify(e.content,t,a),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:a};if(e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o=Object.keys(l.attributes).map(function(e){return e+'="'+(l.attributes[e]||"").replace(/"/g,"&quot;")+'"'}).join(" ");return"<"+l.tag+' class="'+l.classes.join(" ")+'"'+(o?" "+o:"")+">"+l.content+"</"+l.tag+">"},!_self.document)return _self.addEventListener?(n.disableWorkerMessageHandler||_self.addEventListener("message",function(e){var t=JSON.parse(e.data),r=t.language,a=t.code,l=t.immediateClose;_self.postMessage(n.highlight(a,n.languages[r],r)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return a&&(n.filename=a.src,n.manual||a.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
  366. Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css",greedy:!0}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
  367. //======== css_beautfy min.js=======
  368. (function(){function a(R,v){function S(U,T){return U===undefined?T:U}v=v||{};var M=v.indent_size||4;var r=v.indent_char||" ";var K=S(v.selector_separator_newline,true);var H=S(v.end_with_newline,false);var F=S(v.newline_between_rules,true);var k=S(v.newline_between_properties,true);var L=S(v.newline_before_open_brace,false);var B=S(v.newline_after_open_brace,true);var s=S(v.newline_before_close_brace,true);if(typeof M==="string"){M=parseInt(M,10)}var q=/^\s+$/;var u=/[\w$\-_]/;var A=-1,z;var t=0;function e(){z=R.charAt(++A);return z||""}function i(T){var U=A;if(T){C()}result=R.charAt(A+1)||"";A=U-1;e();return result}function D(U){var T=A;while(e()){if(z==="\\"){e()}else{if(U.indexOf(z)!==-1){break}else{if(z==="\n"){break}}}}return R.substring(T,A+1)}function j(V){var U=A;var T=D(V);A=U-1;e();return T}function C(){var T="";while(q.test(i())){e();T+=z}return T}function n(){var T="";if(z&&q.test(z)){T=z}while(q.test(e())){T+=z}return T}function Q(T){var U=A;T=i()==="/";e();while(e()){if(!T&&z==="*"&&i()==="/"){e();break}else{if(T&&z==="\n"){return R.substring(U,A)}}}return R.substring(U,A)+z}function h(T){return R.substring(A-T.length,A).toLowerCase()===T}function I(){for(var T=A+1;T<R.length;T++){var U=R.charAt(T);if(U==="{"){return true}else{if(U===";"||U==="}"||U===")"){return false}}}return false}var b=R.match(/^[\t ]*/)[0];var c=new Array(M+1).join(r);var l=0;var N=0;function p(){l++;b+=c}function g(){l--;b=b.slice(0,-M)}var O={};O["{"]=function(T){L?w.push("\n"):O.singleSpace();w.push(T);B?O.newLine():O.singleSpace()};O["}"]=function(T){s?O.newLine():O.singleSpace();w.push(T);O.newLine()};O._lastCharWhitespace=function(){return q.test(w[w.length-1])};O.newLine=function(T){if(!T){O.trim()}if(w.length){w.push("\n")}if(b){w.push(b)}};O.singleSpace=function(){if(w.length&&!O._lastCharWhitespace()){w.push(" ")}};O.trim=function(){while(O._lastCharWhitespace()){w.pop()}};var w=[];if(b){w.push(b)}var G=false;var m=false;var d="";var E="";while(true){var y=n();var x=y!=="";var J=y.indexOf("\n")!==-1;E=d;d=z;if(!z){break}else{if(z==="/"&&i()==="*"){var f=h("");O.newLine();w.push(Q());O.newLine();if(f){O.newLine(true)}}else{if(z==="/"&&i()==="/"){if(!J&&E!=="{"){O.trim()}O.singleSpace();w.push(Q());O.newLine()}else{if(z==="@"){if(x){O.singleSpace()}w.push(z);var o=j(": ,;{}()[]/='\"");if(o.match(/[ :]$/)){e();o=D(": ").replace(/\s$/,"");w.push(o);O.singleSpace()}o=o.replace(/\s$/,"");if(o in a.NESTED_AT_RULE){N+=1;if(o in a.CONDITIONAL_GROUP_RULE){m=true}}}else{if(z==="{"){if(i(true)==="}"){C();e();O.singleSpace();w.push("{}");O.newLine();if(F&&l===0){O.newLine(true)}}else{p();O["{"](z);if(m){m=false;G=(l>N)}else{G=(l>=N)}}}else{if(z==="}"){g();O["}"](z);G=false;if(N){N--}if(F&&l===0){O.newLine(true)}}else{if(z===":"){C();if((G||m)&&!(h("&")||I())){w.push(":");O.singleSpace()}else{if(i()===":"){e();w.push("::")}else{w.push(":")}}}else{if(z==='"'||z==="'"){if(x){O.singleSpace()}w.push(D(z))}else{if(z===";"){w.push(z);k?O.newLine():O.singleSpace()}else{if(z==="("){if(h("url")){w.push(z);C();if(e()){if(z!==")"&&z!=='"'&&z!=="'"){w.push(D(")"))}else{A--}}}else{t++;if(x){O.singleSpace()}w.push(z);C()}}else{if(z===")"){w.push(z);t--}else{if(z===","){w.push(z);C();if(!G&&K&&t<1){O.newLine()}else{O.singleSpace()}}else{if(z==="]"){w.push(z)}else{if(z==="["){if(x){O.singleSpace()}w.push(z)}else{if(z==="="){C();z="=";w.push(z)}else{if(x){O.singleSpace()}w.push(z)}}}}}}}}}}}}}}}}var P=w.join("").replace(/[\r\n\t ]+$/,"");if(H){P+="\n"}return P}a.NESTED_AT_RULE={"@page":true,"@font-face":true,"@keyframes":true,"@media":true,"@supports":true,"@document":true};a.CONDITIONAL_GROUP_RULE={"@media":true,"@supports":true,"@document":true};if(typeof define==="function"&&define.amd){define([],function(){return{css_beautify:a}})}else{if(typeof exports!=="undefined"){exports.css_beautify=a}else{if(typeof window!=="undefined"){window.css_beautify=a}else{if(typeof global!=="undefined"){global.css_beautify=a}}}}}());
  369. let cmdOnOff=null,
  370. //manage styles panel
  371. ui = {
  372. ruleLiHTML: `
  373. <li>
  374. <select name="ruletype" id="">
  375. <option value="url">URL</option>
  376. <option value="url-prefix">URL Prefix</option>
  377. <option value="domain">domain</option>
  378. <option value="regexp">Regular Expresion</option>
  379. </select>
  380. <input type="text" value="">
  381. <i class="slDeleteNormal" name="deleteRule" title="Delete Rule"></i>
  382. <i class="slAdd" name="addRule" title = "Add Rule"></i>
  383. </li>
  384. `,
  385. codeBlockDivHTML: `
  386. <div>
  387. <li name="number">Block %%BLOCKNUMBER%%</li>
  388. <pre><code name="applyTo" contenteditable="true" class="language-css">%%CSSCODE%%</code></pre>
  389. <div name="rules">
  390. <div name="applyto">
  391. <div><b>Apply To:</b></div>
  392. <div>
  393. %%ruleLiHTML%%
  394. </div>
  395. </div>
  396. </div>
  397. <i name="deletePart" title="Delete Code Block"><b class="slDeleteBold"> </b><b class="slCode"> </b></i>
  398. <i name="addPart" title="Add Code Block"><b class="slAdd"> </b><b class="slCode"> </b></i>
  399. <i name="beautify" title="Beautify Code"><b class="slMagic"> </b><b class="slCode"> </b></i>
  400. </div>
  401. `,
  402. SLMenuDivHTML:`
  403. <div id="SLMenu">
  404. <span id="SLLogo" title="Go To Userstyles.org"><a href="https://userstyles.org/" target="_blank">%%LOGOSVG%%</a></span>
  405. <span id="SLAbout" class="slAdd" name="addStyle" title="Add New Style"></span>
  406. <span id="SLReturn" class="slReturn" name="return" title="Return"></span>
  407. <span id="SLClose" class="slClose" name="close" title="Close"></span>
  408. </div>
  409. `,
  410. SLEditDivHTML:`
  411. <div id="SLEdit">
  412. <div name="setting">
  413. <h1>Edit Style</h1>
  414. <li contenteditable="true" name="editingStyleName" data-name="" data-version="" data-stylesOrgId=""></li>
  415. <input type="checkbox" id="enableStyle"><label for="enableStyle" class="slOn" title="Enable/Disabled This Style"> </label><i name="saveStyle" class="slSave" title="Save Changes"> </i>
  416. </div>
  417. <div name="codeblocks">
  418. </div>
  419. </div>
  420. `,
  421. makeList: function(){
  422. let styles = GM_getValue('styles',{}),
  423. k = 0,
  424. text = `
  425. <div id="SLList">
  426. <div name="tool">
  427. <input type="text" id="slFilter" placeholder="Search Styles By Name">
  428. <span id="slHideOn" name="filterbtn" title="Hide Enabled Styles"><b class="slHidden"></b><b class="slSpace"></b><b class="slOn"></b></span>
  429. <span id="slHideOff" name="filterbtn" title="Hide Disabled Styles"><b class="slHidden"></b><b class="slSpace"></b><b class="slOff"></b></span>
  430. <span id="slShowAll" name="filterbtn" title="Show All Styles"><b class="slVisible"></b> <b class="slOn"></b><b class="slOff"></b></span>
  431. </div>
  432. <div name="list">`;
  433. for(let i in styles){
  434. text += `
  435. <div>
  436. <li name="styleName" data-version="${styles[i].version}" data-stylesOrgId="${styles[i].stylesOrgId}" class="slTag">${i}</li>
  437. <li name="applyTo"><span><b>Apply To:</b></span>${styles[i].rule.length ? ui.concatRules(styles[i].rule) : '<span>All</span>'}</li>
  438. <li>
  439. <i name="edit" class="slEdit"title="Edit" title="Edit"></i>
  440. <input type="checkbox" name="enableThis" id="chbx${k}" ${styles[i].enable ? "checked" : ''}><label for="chbx${k++}" class="${styles[i].enable ? 'slOn' : 'slOff'}" title="Enable/Disable"></label>
  441. <i name="delete" class="slDeleteNormal" title="Delete"></i>
  442. <i name="update" data-usoid="${styles[i].stylesOrgId ? styles[i].stylesOrgId : ''}" style="visibility:${styles[i].stylesOrgId ? 'visible' : 'hidden'};" class="slLink" title="Open This Style's Home Page"></i>
  443. </li>
  444. </div>
  445. `;
  446. }
  447. return text +`
  448. </div>
  449. </div>`;
  450. },
  451. makePanel: function(){
  452. if($('#SLManage,#SLManageCss')) $('#SLManage,#SLManageCss').remove();
  453. let text = `
  454. <style id="SLManageCss" type="text/css">
  455. ${SLFontCSS}
  456. html,body{margin:0;padding:0;}
  457. #SLManage{z-index:999999;position:fixed;top:0;left:0;width:100%;height:100%;font-size:14px;}
  458. #SLManage li{list-style-type:none;}
  459. #SLManage li:hover,#SLManage li[name="styleName"]:hover{font-style:italic;}
  460. #SLManage h1{color:#268BD2;}
  461. #SLManage input[type=checkbox]{display:none;}
  462. #SLMenu span{display:inline-block;float:left;}
  463. #SLLogo svg{border-radius:10px;width:60px;height:60px;margin:10px;}
  464. #SLMenu span:not(#SLLogo){width:40px;height:40px;padding:10px;margin:10px 0;color:#3199DC;font-size:40px;}
  465. #SLMenu span:hover{cursor:pointer;color:#2ACD71!important;}
  466. #SLManage #SLMenu{position:absolute;top:0;left:0;width:25%;min-width:200px;height:80px;padding:0 10px;background:#001f3f;color:white!important;}
  467. #SLList,#SLEdit{width:100%;height:100%;}
  468. /*SLList*/
  469. #SLManage div[name="list"]>div{border-bottom:2px dashed #839594;padding-bottom:10px;}
  470. #SLManage li[name="styleName"]{font:25px bolder;color:#3199DC;}
  471. #SLManage li[name="applyTo"]{margin:3px 3px 3px 10px;}
  472. #SLManage li[name="applyTo"] span{color:#657B83;margin:2px 3px;font-size:14px;background-color:#657b8333;border-radius:5px;}
  473. #SLManage li[name="applyTo"] span:first-child{background-color:transparent;}
  474. #slFilter{width:80%;font-size:20px;padding:4px 5px;}
  475. /*SLEdit*/
  476. #SLList>div,#SLEdit>div{height:100%;position:fixed;top:0;padding:10px;margin:0;display:inline-block;background:#EEE8D5;}
  477. #SLManage div[name="tool"],#SLManage div[name="setting"]{width:25%;left:0;margin-top:80px!important;}
  478. #SLManage div[name="tool"]>span{display:block;width:80%;font-size:23px;text-align:center;padding:0 5px;margin:6px 0;}
  479. #SLManage div[name="list"],#SLManage div[name="codeblocks"]{width:75%;right:0;border-left:2px dashed #839594;overflow-y:auto;}
  480. #SLManage li[name="editingStyleName"]{padding:2px 5px;width:80%;}
  481. #SLManage li[name="number"]{padding:2px 10px;display:inline-block;}
  482. #SLManage i,#SLManage label{padding:0 15px;margin:2px 5px;font-size:20px;font-style:normal;}
  483. #SLManage i:hover,#SLManage label:hover,#SLManage div[name="tool"]>span:hover{background:#3199DC;cursor:pointer;}
  484. #SLManage i,#SLManage label,#SLManage select,#SLManage input[type=text],#SLManage li[name="editingStyleName"],#SLManage li[name="number"],#SLManage div[name="tool"]>span{border:1px solid #839594;border-radius:5px;}
  485. #SLEdit pre{width:90%;margin-left:50px;overflow:auto;height:300px;resize:vertical;border:1px solid #839594;}
  486. #SLEdit code{display:block;width:100%;height:100%;}
  487. #SLManage div[name="applyto"]{white-space:nowrap;}
  488. #SLManage div[name=applyto] div:first-child{display:inline-block;width:15%;vertical-align:top;text-align:center;padding-right:15px;padding:3px}
  489. #SLManage div[name=applyto] div:nth-child(2){display:inline-block;width:80%;}
  490. #SLManage div[name=applyto] li{white-space:nowrap;width:100%;}
  491. #SLManage div[name=applyto] select{width:20%;padding:4px 0;}
  492. #SLManage div[name=applyto] input{width:60%;padding:4px 5px;}
  493. #SLManage div[name=codeblocks]>div{border-bottom:2px dashed #839594;padding-bottom:5px;}
  494.  
  495. #SLEdit,span#SLReturn{display: none;}
  496.  
  497. /* ===================== PrismJS Solarized Color Schemes START ========================= */
  498. code[class*="language-"],pre[class*="language-"]{color:#657b83; /* base00 */font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}
  499. pre[class*="language-"]::-moz-selection,pre[class*="language-"]::-moz-selection,code[class*="language-"]::-moz-selection,code[class*="language-"]::-moz-selection{background:#073642; /* base02 */}
  500. pre[class*="language-"]::selection,pre[class*="language-"]::selection,code[class*="language-"]::selection,code[class*="language-"]::selection{background:#073642; /* base02 */}
  501. /* Code blocks */
  502. pre[class*="language-"]{padding:1em;margin:.5em 0;overflow:auto;border-radius:0.3em;}
  503. :not(pre) > code[class*="language-"],pre[class*="language-"]{background-color:#fdf6e3; /* base3 */}
  504. /* Inline code */
  505. :not(pre) > code[class*="language-"]{padding:.1em;border-radius:.3em;}
  506. .token.comment,.token.prolog,.token.doctype,.token.cdata{color:#93a1a1; /* base1 */}
  507. .token.punctuation{color:#586e75; /* base01 */}
  508. .namespace{opacity:.7;}
  509. .token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#268bd2; /* blue */}
  510. .token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.url,.token.inserted{color:#2aa198; /* cyan */}
  511. .token.entity{color:#657b83; /* base00 */background:#eee8d5; /* base2 */}
  512. .token.atrule,.token.attr-value,.token.keyword{color:#859900; /* green */}
  513. .token.function{color:#b58900; /* yellow */}
  514. .token.regex,.token.important,.token.variable{color:#cb4b16; /* orange */}
  515. .token.important,.token.bold{font-weight:bold;}
  516. .token.italic{font-style:italic;}
  517. .token.entity{cursor:help;}
  518. /* ======================== PrismJS Solarized Color Schemes END ============================ */
  519. </style>
  520. `;
  521. text += `
  522. <div id="SLManage">
  523. ${ui.SLMenuDivHTML.replace('%%LOGOSVG%%',LogoSVG.replace('WIDTH','width="60px"').replace('HIGHT','height="60px"'))}
  524. ${ui.makeList()}
  525. ${ui.SLEditDivHTML}
  526. </div>`;
  527. $('body').append(text);
  528. $('#SLManage').on('click',ui.click);
  529. $('input[name=enableThis],input#enableStyle').on('change',ui.enableButton);
  530. //styles filter
  531. $('#slFilter').bind('input propertychange',()=>{
  532. $('div[name=list]>div').show();
  533. $('li[name=styleName]').each((idx,item)=>{
  534. if(!$(item).text().match(new RegExp($('#slFilter').val(), "i"))) $(item).parent().hide();
  535. });
  536. });
  537. },
  538. editButton: function(evt,mark = ''){
  539. let a = $(evt.target).parent().parent(),
  540. tarLi = a.find('li[name=styleName]');
  541. if(mark === 'menuAdd') tarLi = $('null');
  542. let name = tarLi.text() || null,
  543. version = tarLi.data('version') || null,
  544. stylesOrgId = tarLi.data('stylesOrgId') || null,
  545. enable = a.find('input[name=enableThis]').prop('checked') || true,
  546. cssRaw = GM_getValue('css',{})[name] || '',
  547. blocks = parser.split(cssRaw),
  548. k = 1,tmp = null,tmp1 = null,
  549. html = '';
  550. for(let i in blocks){
  551. html +=`
  552. <div>
  553. <li name="number">Block ${k++}</li>
  554. <pre><code name="applyTo" contenteditable="true" class="language-css">${parser.getCss(blocks[i],1)}</code></pre>
  555. <div name="rules">
  556. <div name="applyto">
  557. <div><b>Apply To:</b></div>
  558. <div>
  559. `;
  560. tmp = blocks[i].match(parser.ruleLineReg);
  561. if(tmp){
  562. tmp = tmp[0].match(parser.ruleReg);
  563. }else{
  564. tmp = [''];
  565. }
  566. for(let j in tmp){
  567. tmp1 = parser.getRule(tmp[j]);
  568. html += ui.ruleLiHTML.replace(`value="${tmp1}"`,`value="${tmp1}" selected="selected"`).replace('<input type="text" value="">',`<input type="text" value="${parser.getRuleText(tmp[j])}">`);
  569. }
  570. html +=` </div>
  571. </div>
  572. </div>
  573. <i name="deletePart" title="Delete Code Block"><b class="slDeleteBold"> </b><b class="slCode"> </b></i>
  574. <i name="addPart" title="Add Code Block"><b class="slAdd"> </b><b class="slCode"> </b></i>
  575. <i name="beautify" title="Beautify Code"><b class="slMagic"> </b><b class="slCode"> </b></i>
  576. </div>`;
  577. }
  578. $('#SLList,#SLAbout').hide();
  579. $('#SLEdit,#SLReturn').show();
  580. $('li[name=editingStyleName]').data('name',name).data('version',version).data('stylesOrgId',stylesOrgId).text(name);
  581. $('li[name=editingStyleName]').data('name',name);
  582. $('#enableStyle').prop('checked',enable);
  583. $('#enableStyle').next().attr('class',(enable ? 'slOn' : 'slOff'));
  584. $('div[name=codeblocks]').html(html);
  585. Prism.highlightAll();
  586. },
  587. enableButton: function(evt){
  588. let name,enable;
  589. let a = $(evt.target);
  590. if($(evt.target).attr('id') === 'enableStyle'){
  591. name = $('li[name=editingStyleName]').text();
  592. }else{
  593. name = a.parent().parent().find('li[name=styleName]').text();
  594. }
  595. enable = a.prop('checked');
  596. let styles = GM_getValue('styles',{});
  597. styles[name].enable = enable;
  598. GM_setValue('styles', styles);
  599. if(enable){
  600. a.next().attr('class','slOn');
  601. }else{
  602. a.next().attr('class','slOff');
  603. }
  604. },
  605. deleteButton: function(evt){
  606. let a = $(evt.target).parent().parent(),
  607. name = a.find('li[name=styleName]').text(),
  608. styles = GM_getValue('styles',{}),
  609. css = GM_getValue('css',{});
  610. delete styles[name];
  611. delete css[name];
  612. GM_setValue('styles', styles);
  613. GM_setValue('css', css);
  614. a.remove();
  615. },
  616. updateButton: function(evt){
  617. let link = 'https://userstyles.org/styles/' + $(evt.target).data('usoid');
  618. GM_openInTab(link,{active:true,insert:true,setParent:true});
  619. },
  620. concatRules: function(ruleArr){
  621. let arr = ruleArr;
  622. for(let i in arr){
  623. arr[i] = parser.getRuleText(arr[i]);
  624. }
  625. return '<span>'+arr.join(' ,</span><span>')+'</span>';
  626. },
  627. saveButton: function(){
  628. let txt = '',
  629. blocks = [],
  630. ruleLine ='',
  631. ruleLines =[],
  632. stylesObj = {},
  633. tarLi = $('li[name=editingStyleName]'),
  634. name = tarLi.text();
  635. if(!name.trim()){
  636. alert('Style Name Can not be Empty !!!');
  637. return true;
  638. }
  639. $('div[name=codeblocks]>div').each((idx,item)=>{
  640. ruleLine = '';
  641. $(item).find('input').each((idx1,item1)=>{
  642. if(/\S/.test($(item1).val())) ruleLine += ' '+$(item1).prev().val()+'("'+($(item1).val())+'")';
  643. });
  644. if(/\S/.test(ruleLine)){
  645. ruleLine = '@-moz-document' + ruleLine;
  646. txt = $.trim($(item).find('code').html().replace(/<div>|<\/?span[^>]*>/g,'').replace(/<\/div>|<br>/g,'\n'));
  647.  
  648. blocks.push(ruleLine +'\n{\n ' + txt + '\n}');
  649. ruleLines.push(ruleLine);
  650. }else{
  651. blocks.push($.trim($(item).find('code').html().replace(/<div>|<\/?span[^>]*>/g,'').replace(/<\/div>|<br>/g,'\n')));
  652. }
  653. });
  654. let css = GM_getValue('css',{});
  655. let styles = GM_getValue('styles',{});
  656. css[name] = blocks.join(SLSpliter);
  657. GM_setValue('css',css);
  658. stylesObj = {
  659. name: name,
  660. rule: parser.unique(ruleLines.join('\n').match(parser.ruleReg)),
  661. enable: $('#enableStyle').prop('checked'),
  662. version: tarLi.data('version'),
  663. stylesOrgId: tarLi.data('stylesOrgId')
  664. };
  665. styles[name] = stylesObj;
  666. GM_setValue('styles',styles);
  667.  
  668. ui.updateULList();
  669. $('#SLList,#SLAbout').show();
  670. $('#SLEdit,#SLReturn').hide();
  671. },
  672. updateULList: function(){
  673. let txt = ui.makeList();
  674. $('#SLList').remove();
  675. $('#SLEdit').before(txt);
  676. },
  677. addRule: function(ele,ruleType = null){
  678. let a = $(ui.ruleLiHTML);
  679. ele.parent().after(a);
  680. if(ruleType) a.find(`option[value="${ruleType}"]`).prop('selected','selected');
  681. },
  682. deleteRule: function(ele){
  683. if(ele.parent().parent().find('li').length > 1) ele.parent().remove();
  684. },
  685. deleteCodeBlock: function(ele){
  686. if($('div[name=codeblocks]>div').length > 1) $(ele).parent().remove();
  687. },
  688. addCodeBlock: function(ele){
  689. $(ele).parent().after(ui.codeBlockDivHTML.replace('%%BLOCKNUMBER%%','new').replace('%%CSSCODE%%','').replace('%%ruleLiHTML%%',ui.ruleLiHTML));
  690. Prism.highlightAll();
  691. },
  692. beautifyCodeBlock: function(ele){
  693. ele.parent().find('code').html(css_beautify(ele.parent().find('code').text()));
  694. Prism.highlightAll();
  695. },
  696. click: function(evt){
  697. function getName(zeptoCol){
  698. if(zeptoCol.attr('name')){
  699. return zeptoCol;
  700. }else{
  701. return zeptoCol.parent();
  702. }
  703. }
  704. let ele = getName($(evt.target));
  705. switch (ele.attr('name')) {
  706. case 'addStyle':
  707. ui.editButton(evt, 'menuAdd');
  708. break;
  709. case 'return':
  710. $('#SLList,#SLAbout').show();
  711. $('#SLEdit,#SLReturn').hide();
  712. break;
  713. case 'close':
  714. $('#SLManage').remove();
  715. break;
  716. case 'filterbtn':
  717. $('div[name=list]>div').show();
  718. $('#SLList input[id*=chbx]').each((idx,it)=>{
  719. if(evt.target.id === 'slHideOn' || evt.target.parentElement.id === 'slHideOn'){
  720. if($(it).prop('checked')) $(it).parent().parent().hide();
  721. }
  722. if(evt.target.id === 'slHideOff' || evt.target.parentElement.id === 'slHideOff'){
  723. if(!$(it).prop('checked')) $(it).parent().parent().hide();
  724. }
  725. });
  726. break;
  727. case 'edit':
  728. ui.editButton(evt);
  729. break;
  730. case 'delete':
  731. ui.deleteButton(evt);
  732. break;
  733. case 'update':
  734. ui.updateButton(evt);
  735. break;
  736. case 'saveStyle':
  737. ui.saveButton();
  738. break;
  739. case 'deletePart':
  740. ui.deleteCodeBlock(ele);
  741. break;
  742. case 'addPart':
  743. ui.addCodeBlock(ele);
  744. break;
  745. case 'beautify':
  746. ui.beautifyCodeBlock(ele);
  747. break;
  748. case 'deleteRule':
  749. ui.deleteRule(ele);
  750. break;
  751. case 'addRule':
  752. ui.addRule(ele);
  753. break;
  754. default:
  755. break;
  756. }
  757. }
  758. };
  759. function stylesOnOff(){
  760. GM_unregisterMenuCommand(cmdOnOff);
  761. if($('#'+applyCssId).length > 0){
  762. $('#'+applyCssId).remove();
  763. updateList('add',location.origin);
  764. cmdOnOff = GM_registerMenuCommand('SL On',stylesOnOff);
  765. }else{
  766. apply();
  767. updateList('delete',location.origin);
  768. cmdOnOff = GM_registerMenuCommand('SL Off',stylesOnOff);
  769. }
  770. }
  771. function updateList(op, name){
  772. let key = name || location.origin,
  773. list = GM_getValue('nameList',{});
  774. if(op === 'delete'){
  775. delete list[key];
  776. }else{
  777. list[key] = 1;
  778. }
  779. GM_setValue('nameList',list);
  780. }
  781.  
  782. $(()=>{
  783. //register menu
  784. GM_registerMenuCommand('SL Manage',ui.makePanel);
  785. if(checkList(location.origin)){
  786. cmdOnOff = GM_registerMenuCommand('SL Off',stylesOnOff);
  787. }else{
  788. cmdOnOff = GM_registerMenuCommand('SL On',stylesOnOff);
  789. }
  790. });
  791.  
  792.  
  793.  
  794. })();