Cat Mouse Translation

划词翻译

  1. // ==UserScript==
  2. // @name Cat Mouse Translation
  3. // @namespace https://github.com/catcat520/CatMouseTranslation/
  4. // @author catcat520
  5. // @include http://*
  6. // @include https://*
  7. // @include file://*
  8. // @include ftp://*
  9. // @exclude http://www.iciba.com*
  10. // @grant GM_xmlhttpRequest
  11. // @grant GM_addStyle
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_registerMenuCommand
  15. // @icon http://tb.himg.baidu.com/sys/portrait/item/d4346e6f65313332ac06
  16. // @version 2017.09.12.36.1
  17. // @supportURL https://github.com/catcat520/
  18. // @contributionURL https://github.com/catcat520/
  19. // @description 划词翻译
  20. // @homepageURL https://greasyfork.org/scripts/27116/
  21. // ==/UserScript==
  22.  
  23.  
  24. /* ------------------ changelog -------------------
  25. 主要功能 : 划词翻译
  26. 取词长度 : 1234 字
  27. 翻译来源 : baidu.com 和 google.cn
  28.  
  29. 其他功能 : 增加 file:// 和 fpt:// 协议,firefox 设置 about:config extensions.greasemonkey.fileIsGreaseable;true
  30. * ------------------------------------------------ */
  31.  
  32. 'use strict';
  33.  
  34. function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
  35.  
  36. var Iciba = function () {
  37. this.init();
  38. };
  39.  
  40. Iciba.prototype.auto_active = 1; //没用~
  41. Iciba.prototype.ctrlKey_actived = null;
  42.  
  43. // init 初始化对象 插入样式 读取设置 绑定事件
  44. Iciba.prototype.init = function () {
  45. var _this = this;
  46. var style = '#icibaCirclePointer{foď-family:"Mārosoft Yahei",sđifįans-İrIJ!importĵt;displaĝblockļľŀłď;z-Ďdex:10Š0ŒĿŁŃ;ovđfŎw:hidśnţŔŦwŰth:20pxŴťŖīightŻŽſĽŤŕńbŀśrŞž ĤlŰ #5ƛƀƍ;ƏrƑ-raņusŞŠžƝŦĄŐgĢund:#ABDƬŖƏxĸhƥoŭ0 ǃ3Ɣ#1ljƺńopaĂtĝ.7Nj;tƤĶitiĕ:.05sǕƼĸizĎg:ƠƢƼNj}ĀĂĄĆĈĊČĎĐƒhŨđ{ǍǏǚĝ1Ǯǰăąćĉċčďđ:ǏǛũ{ǫȌ1ƔƖƘ#35șșǣǏkưoƲƴ#90a2c4ǣoƽsƿdǁ:ǃDžLJ2ȶȃāȅResultCĕłĎǼŘŚŜƩšǕŷdŹȍutoǕƃƅƇaɐɒƋŵŖmaƽɌɎ3żƫɚƁƎƐȌnĕeȝƯƱƳƵEɲȫȭȯȱȳ 8ƔȔxƙ9ɿǕĊtǸĸǎĂnǩŢɥƍǯȹĄȻȽȿɁďaɄr *ȑȬǥǧʈǪɨr-ǭʋŃʍDZa_İaĈh_Ƽ{ņňŊŌŎŐǕɝrgĎȲǕǎűǨʼʤŖɠźş0%ȫơđʢoʃomƓɽȖdƙC˖ǕĔĖsǦeˁœɦ;ʂʄňǿʞʊ˟ƞwƐʅ˥ʉȸʧʐȾɀɂʕnđ Ďpɐ{Ŀ˛ǛǝsłǛcʷʫʺn˞ƌƭʠƣƥiƧ̉ɛɧɵǀŭɪ˶ɴʜˀȒʡʣ˨Ŧʱʼnŋ:ĎƗ˶ʢʵő˂ńũŁāal-̰Ƅ̈ĚűĊ˘ŎaƇ̗ɬ̫ʦȅʩeʫcʭƼ>ȄĄS̓ʬIn˺t˼ƥņ˦ 7ɤ̟˃Ÿźc̰c(ˆ% -ɹ͗x)ˉƑ:̽ɓĬɕŻɺƊ͙ń̦e-ɔƆͰ̊͘ƻȞȠȢ:wůĐǕcoŎƒ#6΋˘ɂʜ˝14ͻ̒ˡeʃˋˤʇˮ̫;˙tėęěĝğġģĥħĩƃĮĹIJĴĶĸıf˯ȅ͋̈́h͎͐Ůǻr,͉aε͍͏ɐ:ĔcƧʚ̔ȰǂDŽ džɽǃ#˖C˸ĶΖ΅·ŀƵȶ2Ǯ.ʎο͌ͅBɐɑn͒ʿ˦ɋ͛Ż9Γˠ͸Ƈ2ͱͩˋƤƦƨ˧ͼƎ;ɯd-ΆΈɱɳΜƮȟϽƣep̼̓oЈЊ̻ϴƒͬЄ̌ĊĦˑƕ·ȗϒϝϟπϢϤǝǺ̭ȑϼȡƳϿϘΉĘЬaНʧПhϣˎ̈ȎiȐЅͿШЀϙ#e5пп̙Ȯ̕Ȳό2LJ8ъϔİtγ͊ϡвСϦйЇĽag˝url("d̻a̤ɝљ/svg+xmlƟaİ64,PHN2ZyBѷXJzaW9uPSIxLjEiIGlk҃JDYXBhXz҉IHƆbG5zҏodHRwOi8vd3ҪLnczLm9yѸ8yMDAwL3ѶѸIљG1sbnM6eGxpbms9Imh0ҢA6Ly9ҫ3φdzMub3JnLҗ5OTkũӊӌӎҊHgӐjBweCӀeT0iMHB4IiѺѿV3QҲ4҃IwIҹgNTYuөY2ԎU2҇k2NҊgc3R5ҜUӐmVuYWJsZS1iԫNrZӣҩW5kOm5ldyҺԎAԐԒԔԒԗDԙԛԝj˛ҙқDpzcGFjZӻāHJlc2VydmUiPgogICՄѴҔdGgKիՄմժCBҎSJNԑUuMTQԚՊ҆jg4N0w0MS41ODgsMՔuNzg2Yӟ֘֓Ԛւրւ0LՊրzԜLӪ֨U4֦տ֖֪TE֥jȩNmMһִy҇Y4Ġ0xMC4ӟTgtMjM׋׍׏֙֫IҰDEһ׍xOC0ҷywמB׈A֨E֯Dה֦שרz֝Q֘׭҆ҹsO֏yө׊֎4֍׭֕TӠցԡ֫ׯցYybזҰjԖ֎wxN׆ҷDh׍׆1֙E֕ؖөM֕֏ӟؚ֩45Ġנ҇E2إטkyҋֻ҇ԡ׵wһזִ֘֯Tפ׌k3תրDc5֫פ֒MԇzՋjIؗSwؗ׆ӨרsԑԓػוU؊AקU1ا0Ԟَ׺4֒d6Iֵמأ֒Qֺٓق׍ҽCس֦Eؽـ֘يքٵٴӜy0ؽ؋y٠؏پڄ؎NѹҰִؽTφNٹ֫ٻڋֵֿ٘ײY֕׍Շg֥DZ٦ԃzҢlԮ՚ZѬӄDթcmņKז։ןgցgؽլךـpOح+PC9wҒRoէo8ҼҾz4K"ͨЄЦȢ-˽ǚǜ̈ceȋrɭІЧϾ˛zΐ5ɻۢͲϺ̀ѐζгϥTǘsŊĐGoթĊХɮ۝řѤњќўѠłѣјeѦѨѪѬѮѰѲPD94bWwgգա՟lvbjӼ׺ԍԃlӍNvZҌuZzӼVVRG֫ʺҙ֊ԫԺԫxܕդԧ5vIj8+CjxڢmcӁӃӅMԧӓӕӗәӛӝ֞ӢӤӦԌҸAvԡZnԂԄWԆԈ܋ԋԍԏ֙ՄݠӰdpZңۄ҄3ׅӀaGVݥ2ӓԋݪӸܺiյլ8ՕFȦAթնހGZӌGwӐӽ֍և1RjQiĆݸޑgZDӼT׿ٝي5ԎQֆޝV׍ySґ3؆ׇ֎AֆYֶQ3ԎӠԑg֟݀N֏2כՂٷҸY׋֏ؤՁ؏֏3׵0֯҈1ԎI־jީٕ֫ՊԐiׇڑ؊ȩԎkٸ޼׌؄רg׵4ԝkM؏ߒӟݷ޷؟޵ׇԞA1My4٣ߩݷzؐأ׺ߵݷ߁߷߀ԞާߒٟՁߵ؟҇ޭ֝ח҇Uڳڷڈ٪լֶEح׬ֿߞ֏0O܎t߾ԝլԚ؋0؆Š҇Aڊް֚tߟࠗS0ࠞc־ִࠞؼߎװI׋׿Ԕґࠋם߶ޮזֆڒIֶ݀׌ֱDMࠋީ߯߱߬ׄ׆։լڂ֏w߯Aڂ׆࠽ًࠣzԎ޲өȟׅީ߶ׄࠫ؊YxԎٻ׍قՆ֒࡟ߒԝiםֿՉׯNזࠚࠀ߬ޙE࠶EٸVsדߋQٯީĬIvۅۇҽѷۊیێͳѮ۶ۑۣ۟ۡϮƞѕ۷ۓ˿ۖۘǸяϠ۩ѓ۬ĵۮ̻eBʕdu۵ۜۑїљ:ћѝџѡۿѥѧѩѫѭĄ܇ѳѵѷѹѻѽѿҁԋ࠿ҊҌպҐҒҔҖҘҚtҜҞҠҢҤҦҨҪҬҮҰҲҴyҶݑһࢌҿ݁ӄӆӈӭӍӏӑ݆HӖӘӚҪ݋Ӡݍӥӧ࡞ӬӋ࣬ӰӲܷӵӷӹ՚ӾԀݗ3ѿRȦޕiөँӸgݭݯZݱ0ԋؤӿԁԃ2ԅԇԉݝՃߞعढAӰ֊eWxlҏܜmFăGUtYमjȧՀӢԩޔ˺ZXࡃլݞkुҥحࣧOnNہWNफջwڬVzऽJѷ҄+DQoJծhհgऑWQӐkJƿWR߈ԃ࣌Nߛؿࠑ֦֖ࠉ٣Gدj٘޵wڀYٝ࠷ڏEײڕ҈ݪپٯIࠜڇؖ֊Mࢅ5ڈ֌כ֐վٓ׆ҥזٓרٸcٝࡆضփ॰ޙࡕࡔժॴ׋֖ؖलࠍԝٍࡥࡣ׃ࡢ֙٬ߟڂލ࠶ࡵڍxQҗ߆փإҷঔٔڙްـק࡙jkߵןࡖ4ࡓTI֕֞ޱ4ĬBսيՇMקࡾ֒c0նࠡޙࢄ֎׃ࠅࡓࠫࡣ׻র֕߰ࠗDk࠶؀׭־זثҷW׎٢өUٓ৫֖ৎܙ׌؝ցশج֦ԓԑڕזޙkؤةৠقصؐ؎׺ٟ׭׋৫֒֔ցৰॻڑ৴ިժEن׺ؤւ״׆ךਥڏ؄ॶוIրߌק؆ԛzכ؎҇ڵNHթޗচ਷ׄiנ߾ؤjޠ֫տ֙਽ҹؿ֛ਝ҇Mٍ֑ޙU߃০ׅ4ҷ࡛׾ߜֈ৞zغ্ٶ޲ԑ֦ٚׯөAڝ९׍ڱ਒׆޷Պ׾ਮ֖ީ֝ੇՔ࠯غ֠ٴט੏כࠢ҈ࡓןࡍ੗֖৷্ٸֵহੌ׍ਭٯ؆٠ҽ߰ਨ৺׌ԓ੧ছ਽ևਿੁߒ੃V٦լਠ0ӟ߰঍ॶ֕তߪࠗԒؚǠԛٍ߮ࠞب֫ߘ৹ঀߕֺؗشڎӪքࡵՊছEસ߯wٯkર਒߰ҽTڏપԕؚૅયׂલؗן૆߮ࡱׄ૊ԑࡇիƸࡶӠөٻґ֣ژֲ֟ࡦ֦A৏ૡԒছB٦ֵߦߠ؜গਮ֙Jj֫؀ڍছশ޼߾ҽو״ࡒցࡼਚװਲזֶڜMةࡸ٪֓ٓ֏ׁ࡛ࠨ޾ԑৎߟ։׉ଗأଙ׾੶ે੝૫ߪؤ׽ࡊ਴଒ցଢુٙҷੀ߻߃Tޠߟةz٬ׅঈ੗ө࠵Ġ4ׄ҈ڙ৚ִॼੲ্x֝ڎيו૫ց૷ਫ਼ٶਮԕਏߊ੎਴ٍߋԜ׵յॴ઎ࠃٳ؉ֿ֑לٯॿ঎૚ߠޱ࠶ࡅ٘֝Aࠚ޾֖c޽୪ଖলө୴ߟ਴ִ࠶ߏ࠮ֶࠡkֶٟࠫMٟࡱ୦਴לڀֈ޵ম߂Ҹାڍؿࡕ৞پ؊ࡁஏֶUҥל࠱ڱ0ঠ٣לઃؤक़ୱো֒hࡆ֩Շ਋॰࠭։ফߪ੬஋ୀڏਁ࡛ٸে੥ߋ࠮ࢇԠԢԤऱԧރҜw٦՜nYƄୠڳଃ߉াk7ܷ4ࢋկձॗख़ࢋۉࡏg==ۍۛк۞˜ɏɑ 1ۤ௤Ї࢜ە:ۗۙࢡ˱ȿTŜtBȬ{ʸ̇̑ˠʾ͔ǩşɻƉόఄۥΔмΉϛǕĐxΟ̳g̈ЖюΜΞΏŞΒఉˠఘĘĚĜ:Aĺ̰,HeܔΖ̯ήķάβۏ࢓ɰ#fbఴఴ̅ƽϰŻ5ƉǕλūǁ-ŝůűۘా̭ీw-ĝɗɑ௴ȼ˲௷ఐ௺ŝȍĦǼΆȋďĞ"Ǖ̡ʳǪ̩௭۝:Ǘࢦǎr࢟ͭƄ͹ఈЯIࢪhح-˶w_˪ơʰŇ̢ĝГͳ}Ϟc౰Ī౳Ŋbన_Ɨ́>LƷEL౺ʲ̣̥Ʉ౏ʑt౒௹Ȭ ņvνϟ௵ಘ௸౔ Ⱦಟ˰౐௶ಣಛƗಧȺ಩ಢ౓ಛpಮʏರಙತĔrmವaಡಸಛ˹ɐಽಿಫɽಆన௼̆ʻϹΔఁˀ್ఝΎӶ౬Ќ಻̰ಖ౑ೆϔ͐ೄಷ೛bѓೞಗೀɽఏł౩aē೓ͮ͹Ďīĺఖ࢑ఘ́yĊ̤n೰ǚ΍˚௧೯ıೲϺΝΎట΢ఢతlదనũ̃aబΰĺయ౿ξ೅ಲɽದഔ೟ഖ Ɨ{ಊΟ೵೷౾ۦങ೤೛Ѣυχȡt͵ͫɫ೙ಪഛĽgʚˊƒ೑ʌഥ೚ഛ́Ģʈ೫Ė೔ͯˆ೼Οഅడ"͋ըe UIĮVđѠnഎLuĂѠ Sࢦ Ȼ޲Ŋμൖ൘a൚൜Unāҡe,ణiథsࢦഐĻ̿ഺറಚɽಁಃ౲I-ņ୴ĄĒ೴௧1шజഹಠച൷ ൹౱౳౩ʺ́đೣ഻ඊඌ಄ർĺɕʮgඓ൶ತඖൻ-u಴൵ಱඕāൺ౳ϊϦీ̻:඙Ɔരඦඟඨඍ඘eඐǸϧం-క఻࢘ʥඥ೥ aච౳೧ʮŊŐඝඳಛෆർൔvಉŇħഽĕഴఋƵ3ෛ඲ස೪ෙ#236fdȪΜ೧ൽeΆƤ࢝ࢳƳđ͵ෝധκФ෠෢෤෦ෳഛාͷĵdwೱ൫ෂ೛෽ƿƳกǚe_λ෌ස෽dĢp_ණ˼ģ۔ǝabƖɐ̾࢑˄Ş6වƂ೭Ƈ1ยආŦφrĤƒĿǷđ෻ටಂබ෾จข{ɑpచรńධฦ3ఽరࢯШ௯ǝǃ-7โഓඈദ෼ඵ඗ึ฀ขฌФฺ฼ษŖ฿Şแ฽࢒ไϾๆ̈-1ͱ๊ͣ฽ۧಾඉತǰඩർൾt_ɝĎර೐ఎ௸̲Ɨఓ:కาපิ๑๱඀಑౼ౡŏ̪࢑೏ϩΜ఺్ə࢑͵ͷลŞ.Ϝ൴ํඔ຀๯-Ǜബeถ˾௰౩ۯзพം຋ఃศ௪ͦఇϳΜ෠ෛ3൅-ൂ͹ƏԿິ࢕ŻఛິേౌഈഏమʁɄຓೕ:ɢ๞౸Ͼb೩kǪ໎๺l๿෎๐ඡ๱_ພ۴ັොగ೬໇ຸd຾Ρడʫ൮ഉ൰ίໃຘನ๎ำຜpാs຅ౠōຈʽ͓๷ຍດຏɋ΃ͶΙ˝ɪ೗໓ໞുດ๊സශນඞ໕ກ໗ā࣓ʫඋ໖౳ū{̭഍̱ఒ̵Űd̸༆ഠඃඅໄ̧఺༃ɝ༅์໭ບ༎ຜ຃༓෽ūʘീ༢۠Ş༤໬ಯ໮ປี൩ʩ۝ู๹ś෬̻௰ണΔ̜മ̘Μ౟ಓnຒ໶ʶΜిŬŮ༞ెΜ௽ೌϪɍ˅ศ౫ൃའใ௥ࢳۻࢶ۾ࢱ܁ࢺ܄ࢽѯeѱࣀҾࣃ॓ѾҀ҂҄ࣉҋҍҏґғҕҗӰқҝҟջҡңҥҧҩӛҭүұҳҵؒҺۈࣂӹӂࣨӇӉࣼӎ݅Ӕࣰ݈ࣳӜuӞࣶӣࣸEӨӪࣻӮՏӱӳएःܘङݗजݙञݜ҄ݞՄ਀ߋE߮Ձ੘େ٘ݗڢHڤՙӼZԹhऴपLԬ࿌2tҮҲ1ӍQ6ӍԆडࡠ࿁֣࿃׬ି؏׿௕ԃ܌܎6ԡҔԖԦ͎BҴXौcnZl௖KCTxݖ࣋ҏQҜFޛjۋCQkݺՖݽग़စl࿅࿇ڦڨbC1բऩlҦBԿԨӡ2RԻѹjҜlһѼ࿖ऱ٦ݮѷԹܟGQ௕ނބ௉ҙӤ்ֈ଺ڳ׿һࡐ׌Aںح࿸ဆJޔޖ্ઁ4ଳؙ࡞ٸI4Tक़ٯֻ঎ߋI঍઩উַ׋ߒݪӪ࠶غ੫דਯԖڑஜҷࠫၓࡰଢ଼આφਚ৲୰؁ؿՋୢيڂڅࠍwী؅ضȩd҈ӨِNॴش୓஭كؿ੉ળॶ੔ڇ߰ၷબၹԑف׮ਯg୍଄ଟTઔ׆ִٟਗ਼ض҅ၠકޮડ؈྾߶৬׎୹֖֨ࠇߋ׀઼֫QુטQ߲মࡹ৭׾פࡶg࡫ႈQࠗV߯ႏـঀၷ઒֙৾ߌߕؤٍӨ޶׌h٦ဃ௘ढ़௚CgဇLȨܺjwݓ3ݕۅ௢࢐ം౦Ǚ෮0ǢΜ༙̯༛๻༝̷ວ̒๪ക໯༾Άཀ΀УǼǾǐǒǔ༺ಶ༼༮ჷoჹɰжȐჽȀǞ9໔൸༕ർමฎฅᄑජ໳ຩຝǍ௿ƞఞ໤ΣlൗŰ൤໩sಥ൨ΆśĮ໦೘ཌྷ౻໵ౢᄁ๫ᄃᄐ༏౳౵౷Ɛē̺Ƈ๾Μᄙ๗༹༫༻༭ᄵຜᄸ໋හ໴̣དྷຉຨ໹ʞώ௪ఆǃɣ๙ńภș๞఺1ͦౣۑ๢:-27ఛDŽϗЁȤʀ༡ີດൄᅬ຿ĞĠcĢĤĦĨĪĬౝᄲჵ༽๑ᅈƐහ෽ᆀơ2ࢮ௥ےท෮ᅣᅥƔ๤ϭᅗჴ๬ᄄ๑ƧṵĜᄔ๏ᄶർ໱ĕ໳෠΋6ິຶฦŠᄏ༔ᆜǥľ۴ཛ̈ۤόᆰ༊ďᆒᄴᆩຜͿณᆞĶ{ȈʫʟŹ̅ʹཛྷᅼᆓᅆีᆹ_ᆻᄦ෽İౙdᄻoථ཈ఀᅐgᄚ฻ᆳtᆵᅅᆷᇈƱᆺ໲ᇞ๑ᇎĕ˔෽ම{఺2ຽᇅᆶ෽ᇉ˽ᆽĊᆿƏᇁཔైབౄŲᅨн఍ᅬົΑ๩คᆛᆸᇠᇊģ༴ං༷ሂᆑሄჶ๑ᇱሉ฻ɪt(๽ѯΟĥຝyЊ)ೊᇃnˌˎː௬ᇮᇝ෽ೈlී́ᇑථᄾຊᇖሣɑːᆐཝɎ87ˈ෨๹༜๽eĦᆨ෽࿳ᇣඡሒᆠЪේໝᅃᄂረᄖቇƕǗ෗ᆽ቉#8d቗቗ቂᄖᆮ໙Ǎ๶ʈᇘ:ལቌᄳ቎ᆪ౨๲ടහᆚሐඡłbሬħƗቬሏᅾඡᆄ˔എቶᆔඡቩ๳˵ h3ᅊ෩ངŀཆǝᇔඇ༬།ᇇ๑ተቲᅋ౽യሧ኎ቅ෇ǚ۴ຩ๜అɻ๞ላΐᇭብᅽች౳ቇ༵ఙልቛᆪቐ༲lበʉ ຫȳᇽΉɿᄎኖ෍኏ቆሇ˽ƕǎϦწ͝ხ̴Ǫ཯ෲΜຒ༧ŀ༩̹ᇒЌཌ࢑ཎĝಔዒᅏϨΛኤᇆኘർsy̗ቔᅩາ༥ͶᇫຯዛᇯᄖȽय़ȼtቭቷ౳ዬљ́ᆆኜɸᅒᇚ;ໜຳΜ໋ີƤ฻ໍ̓kີƐ຺ඃኣംዋດȶሃ༌ኻዝĸuይ́ಥኰኜອǃጊΔጌ໇௫5ሻዩቧຜዳዮജi኱ලቀฦጜˠ࢚ᅠᆊ௰๤3ᅦ-แጮኌᅄኗᇍጔዴħpഞ໅ᇫ఼ጢതጐฏያጾጧ෽໱ᅊᄙ๛ώኬጥፋ጖pፍĒᆮቢፒዊፃᅮየፇኍ጑ጽጕħፘᅊዔ೸དᄱሱዙƣጟ๋፡ጻ፣ᄖĔˍǼዷሷź໽ະቕኸ๸ఐ๺዆฿ገሌᅂጋ፞ጟ፠ჳቼኼ༖۲ǸᅊཊኋŦኆ෫ኈ෮᎔ŖዷύƔኵཤϽཋჲˠ෷෣෥෧࢑᎖ཅ᎙ንೳΎሁᎇጝᎉൃᎋɦᇜጼ፵᎐˷Ѣ჻ĒᎥ෹Ꭸ፲ቍᎸᆪ෈ōuຠᎿᎧፓีቫഝ᎜௫ጏ።ፉᆪƗดዯሩiดᇐ፩ዖᎣƞጞͯᇬᏒ፳ᏔຜᏖɍጪ๛ሦ࢑Ꭵ෢෢Ꮜ๑Ꮸᇐ෠7᏶ȃի౰A_TOO_LOႀጪ๗౮ᄿሲ඾ᐆᎮ೽ᎆ๩';
  47. style = lzw_decode(style);
  48. GM_addStyle(style);
  49. GM_registerMenuCommand('iciba划词翻译设置(ctrl键查词设置)', () => _this.openSetting_ctrl());
  50. GM_registerMenuCommand('iciba划词翻译设置(设置最大查词长度)', () => _this.openSetting_length());
  51. GM_registerMenuCommand('iciba划词翻译设置(默认查词引擎)', () => _this.openSetting_default());
  52. GM_registerMenuCommand('iciba划词翻译设置(小蓝圈查词行为)', () => _this.openSetting_click_or_over());
  53. _this.loadSetting();
  54. _this.eventBinding();
  55. };
  56.  
  57. // loadSetting 读取设置
  58. Iciba.prototype.loadSetting = function () {
  59. // Ctrl键触发
  60. var _this = this;
  61. _this.ctrlKey_actived = parseInt(GM_getValue('ctrlKey_actived') || '0');
  62. _this.maxSelectlength = GM_getValue('maxSelectlength') || '1234';
  63. _this.defaultBehavior = GM_getValue('defaultBehavior') || '1';
  64. _this.mouseoverRatherThanClick = GM_getValue('mouseoverRatherThanClick') || '0';
  65. GM_setValue('ctrlKey_actived', _this.ctrlKey_actived);
  66. GM_setValue('maxSelectlength', _this.maxSelectlength);
  67. GM_setValue('defaultBehavior', _this.defaultBehavior);
  68. GM_setValue('mouseoverRatherThanClick', _this.mouseoverRatherThanClick);
  69. };
  70.  
  71. // eventBinding 绑定事件
  72. Iciba.prototype.eventBinding = function () {
  73. var _this = this;
  74. window.addEventListener('mouseup', function (e) {
  75. setTimeout(() => {
  76. _this._mouseClick(e, _this);
  77. }, 10);
  78. }, false);
  79. window.addEventListener('keydown', function (e) {
  80. _this._keyDown(e, _this);
  81. }, false);
  82. };
  83.  
  84. // openSetting_ctrl ctrl设置对话框
  85. Iciba.prototype.openSetting_ctrl = function () {
  86. var _this = this;
  87. _this.ctrlKey_actived = confirm('按住ctrl键(当且仅当)开启翻译?') ? 1 : 0;
  88. GM_setValue('ctrlKey_actived', _this.ctrlKey_actived);
  89. };
  90.  
  91. // openSetting_length 最大取词长度设置对话框
  92. Iciba.prototype.openSetting_length = function () {
  93. var _this = this;
  94. var len = prompt(`最大划词翻译长度(留空为默认值1234字,当前为 ${_this.maxSelectlength})?`) || '1234';
  95. try {
  96. len = parseInt(Number(len));
  97. } catch (e) {
  98. alert('输入数据无效,操作取消!');
  99. return;
  100. }
  101. var confirm_len = true;
  102. if (len < 10) {
  103. confirm_len = confirm(`你确定要设置一个这么小的数值(${len})?`);
  104. }
  105. if (!confirm_len) {
  106. return;
  107. }
  108. _this.maxSelectlength = len;
  109. GM_setValue('maxSelectlength', _this.maxSelectlength);
  110. };
  111.  
  112. // openSetting_default 默认行为设置对话框
  113. Iciba.prototype.openSetting_default = function () {
  114. var _this = this;
  115. var behavior = prompt(`点击蓝色小圆圈后的默认行为(输入相应的数值,当前为 ${_this.defaultBehavior})?(0:默认iciba划词翻译 , 1:百度翻译 , 2:谷歌翻译)'`) || '1';
  116. if (behavior === '0') {
  117. _this.defaultBehavior = '1';
  118. } else if (behavior === '1') {
  119. _this.defaultBehavior = '1';
  120. } else if (behavior === '2') {
  121. _this.defaultBehavior = '2';
  122. } else {
  123. alert('输入数据无效,操作取消!');
  124. }
  125. GM_setValue('defaultBehavior', _this.defaultBehavior);
  126. };
  127.  
  128. // openSetting_ctrl ctrl设置对话框
  129. Iciba.prototype.openSetting_click_or_over = function () {
  130. var _this = this;
  131. _this.mouseoverRatherThanClick = confirm('是否将「鼠标点击小蓝圈」 打开查词框行为改为「鼠标移至小蓝圈」打开查词框?') ? '1' : '0';
  132. GM_setValue('mouseoverRatherThanClick', _this.mouseoverRatherThanClick);
  133. };
  134.  
  135. // showIcibaCirclePointer 显示并定位小圆点
  136. Iciba.prototype.showIcibaCirclePointer = function (e) {
  137. var _this = this;
  138.  
  139. let de = _this.getPosition(e);
  140. _this.icibaCirclePointer = document.createElement('div');
  141. _this.icibaCirclePointer.id = 'icibaCirclePointer';
  142. _this.icibaCirclePointer.style.position = 'absolute';
  143. _this.icibaCirclePointer.style.top = de.re.offsetTop + 7 + 'px';
  144. _this.icibaCirclePointer.style.left = de.re.offsetLeft + 5 + 'px';
  145. _this.icibaCirclePointer.setAttribute('keyword', window.getSelection().toString().toLowerCase().trim());
  146.  
  147. let mouseoverTimout = 0;
  148. if (_this.mouseoverRatherThanClick === '1') {
  149. _this.icibaCirclePointer.addEventListener('mouseenter', e => {
  150. mouseoverTimout = setTimeout(() => {
  151. _this.showContainer(e, _this);
  152. }, 100); // 100ms delay prevents accident mouseover
  153. }, false);
  154. _this.icibaCirclePointer.addEventListener('mouseleave', () => {
  155. clearTimeout(mouseoverTimout);
  156. }, false);
  157. } else {
  158. _this.icibaCirclePointer.addEventListener('click', e => {
  159. _this.showContainer(e, _this);
  160. }, false);
  161. }
  162.  
  163. document.body.appendChild(_this.icibaCirclePointer);
  164. };
  165.  
  166. // removeCirclePointer 去除小圆点
  167. Iciba.prototype.removeCirclePointer = function () {
  168. var _this = this;
  169. if (_this.icibaCirclePointer) {
  170. document.body.removeChild(_this.icibaCirclePointer);
  171. }
  172. _this.icibaCirclePointer = null;
  173. };
  174.  
  175. // showContainer 显示并定位查词框
  176. Iciba.prototype.showContainer = function (e, _this) {
  177. var word = _this.icibaCirclePointer.getAttribute('keyword');
  178. _this.removeCirclePointer();
  179. _this.createContainer(e);
  180. _this.containerLoadData(word, 'auto');
  181.  
  182. // getData(word,e,bodyClientHeight,bodyClientWidth,windowinnerHeight,windowinnerWidth,htmlClientHeight,htmlClientWidth);
  183. };
  184.  
  185. // createContainer 创建查词框
  186. Iciba.prototype.createContainer = function (e) {
  187. var _this = this;
  188.  
  189. _this.icibaResultContainer = document.createElement('div');
  190. _this.icibaResultContainer.id = 'icibaResultContainer';
  191. _this.icibaResultContainer.style.position = 'absolute';
  192. _this.icibaResultContainer.innerHTML = '\
  193. <div id="iciba_search_box">\
  194. <input id="icibaSearchInput" type="text" />\
  195. <input id="icibaSearchButtonTranslateBaidu" class="icibaSearchButton" type="button" />\
  196. <input id="icibaSearchButtonTranslateGoogle" class="icibaSearchButton" type="button" />\
  197. <input id="icibaSearchButton" class="icibaSearchButton" type="button" />\
  198. </div>\
  199. <div id="icibaResultTextBox"></div>';
  200.  
  201. _this.icibaResultTextBox = _this.icibaResultContainer.querySelector('#icibaResultTextBox');
  202. _this.icibaSearchInput = _this.icibaResultContainer.querySelector('#icibaSearchInput');
  203. _this.icibaSearchButton = _this.icibaResultContainer.querySelector('#icibaSearchButton');
  204. _this.icibaSearchButtonTranslateBaidu = _this.icibaResultContainer.querySelector('#icibaSearchButtonTranslateBaidu');
  205. _this.icibaSearchButtonTranslateGoogle = _this.icibaResultContainer.querySelector('#icibaSearchButtonTranslateGoogle');
  206.  
  207. // bind events
  208. _this.icibaSearchInput.addEventListener('keypress', function (e) {
  209. if (e.target === _this.icibaSearchInput) {
  210. if (e.keyCode != 13) {
  211. return;
  212. }
  213. }
  214. _this.containerLoadData(_this.icibaSearchInput.value, 'auto');
  215. }, false);
  216. _this.icibaSearchButton.addEventListener('click', function () {
  217. _this.containerLoadData(_this.icibaSearchInput.value, 'iciba');
  218. }, false);
  219. _this.icibaSearchButtonTranslateBaidu.addEventListener('click', function () {
  220. _this.containerLoadData(_this.icibaSearchInput.value, 'baidu');
  221. }, false);
  222. _this.icibaSearchButtonTranslateGoogle.addEventListener('click', function () {
  223. _this.containerLoadData(_this.icibaSearchInput.value, 'google');
  224. }, false);
  225.  
  226. _this.containerSetPosition(e);
  227. document.body.appendChild(_this.icibaResultContainer);
  228. };
  229.  
  230. // removeContainer 去除查词框
  231. Iciba.prototype.removeContainer = function () {
  232. var _this = this;
  233. if (_this.icibaResultContainer) {
  234. document.body.removeChild(_this.icibaResultContainer);
  235. _this.icibaResultContainer = null;
  236. _this.icibaResultTextBox = null;
  237. _this.icibaSearchInput = null;
  238. _this.icibaSearchButton = null;
  239. }
  240. };
  241.  
  242. // containerSetPosition 定位查词框
  243. Iciba.prototype.containerSetPosition = function (e) {
  244. var _this = this;
  245. let de = _this.getPosition(e);
  246. if (de.re.detectHeight - de.re.offsetTop < 220 || de.window.innerHeight - e.clientY < 180) {
  247. // TODO using bottom position
  248. _this.icibaResultContainer.style.top = 'auto';
  249. _this.icibaResultContainer.style.bottom = de.re.positionHeight - de.re.offsetTop + 'px';
  250. } else {
  251. _this.icibaResultContainer.style.top = de.re.offsetTop + 'px';
  252. _this.icibaResultContainer.style.bottom = 'auto';
  253. }
  254.  
  255. if (de.re.detectWidth - de.re.offsetLeft < 220 || de.window.innerWidth - e.clientY < 180) {
  256. // using right position
  257. _this.icibaResultContainer.style.left = 'auto';
  258. _this.icibaResultContainer.style.right = de.re.positionWidth - de.re.offsetLeft + 'px';
  259. } else {
  260. _this.icibaResultContainer.style.left = de.re.offsetLeft + 'px';
  261. _this.icibaResultContainer.style.right = 'auto';
  262. }
  263. _this.icibaResultContainer.style.display = '';
  264. };
  265.  
  266. // containerLoadData 获取数据查词
  267. Iciba.prototype.containerLoadData = function (word, engine) {
  268. var _this = this;
  269. _this.icibaResultTextBox.innerHTML = 'Loading......';
  270. _this.icibaSearchInput.value = word;
  271. engine = engine === 'auto' ? { 0: 'iciba', 1: 'baidu', 2: 'google' }[_this.defaultBehavior] : engine;
  272. let get_iciba_result = (() => {
  273. var _ref = _asyncToGenerator(function* (word) {
  274. let result = yield got({
  275. method: 'GET',
  276. referer: 'http://www.iciba.com/',
  277. url: 'http://open.iciba.com/huaci/dict.php?word=' + word,
  278. timeout: 10000
  279. });
  280. var text = result.replace(/\\/g, '');
  281. text = text.match(/dict\.innerHTML=\'(.*)\'/)[1];
  282. text = text.replace(/icIBahyI-'ico_sound'/g, '"icIBahyI-ico_sound"');
  283. return text;
  284. });
  285.  
  286. return function get_iciba_result(_x) {
  287. return _ref.apply(this, arguments);
  288. };
  289. })();
  290. let get_lang_detect = (() => {
  291. var _ref2 = _asyncToGenerator(function* (word) {
  292. let formdata = new FormData();
  293. formdata.append('query', encodeURIComponent(Array.from(word).splice(0, 25).join('')));
  294. let lang_detect = yield got({
  295. method: 'POST',
  296. referer: 'http://fanyi.baidu.com',
  297. url: 'http://fanyi.baidu.com/langdetect',
  298. data: formdata,
  299. timeout: 5000
  300. });
  301. var result = JSON.parse(lang_detect);
  302. if (result.error === 0) {
  303. return result.lan;
  304. } else {
  305. throw new Error('翻译文本语言未知!');
  306. }
  307. });
  308.  
  309. return function get_lang_detect(_x2) {
  310. return _ref2.apply(this, arguments);
  311. };
  312. })();
  313. let get_baidu_translation_result = (() => {
  314. var _ref3 = _asyncToGenerator(function* (lang_detect, target_lang, word) {
  315. let translation_formData = new FormData();
  316. translation_formData.append('from', lang_detect);
  317. translation_formData.append('to', target_lang);
  318. translation_formData.append('query', word);
  319. translation_formData.append('transtype', 'translang');
  320.  
  321. let result = yield got({
  322. method: 'POST',
  323. referer: 'http://fanyi.baidu.com',
  324. url: 'http://fanyi.baidu.com/v2transapi',
  325. data: translation_formData,
  326. timeout: 5000
  327. });
  328.  
  329. result = JSON.parse(result);
  330. if (result.trans_result.type === 2 && result.trans_result.status === 0) {
  331. return result.trans_result.data[0].dst;
  332. } else {
  333. throw new Error('翻译出错!');
  334. }
  335. });
  336.  
  337. return function get_baidu_translation_result(_x3, _x4, _x5) {
  338. return _ref3.apply(this, arguments);
  339. };
  340. })();
  341. let get_google_translation_result = (() => {
  342. var _ref4 = _asyncToGenerator(function* (word, tl = 'zh-CN', override = 0) {
  343. let token = (yield _this.get_google_translate_token(word)).value;
  344. let url = 'https://translate.google.cn/translate_a/single?';
  345. let query_string = `client=t&sl=auto&tl=${tl}&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&source=btn&tk=${token}`;
  346. let result = yield got({
  347. method: 'POST',
  348. headers: {
  349. 'Referer': 'https://translate.google.cn/',
  350. 'Cache-Control': 'max-age=0',
  351. 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
  352. // 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
  353. },
  354. url: url + query_string,
  355. data: `q=${word}`,
  356. timeout: 5000
  357. });
  358. result = JSON.parse(result);
  359. // detected language
  360. if (result[8][0][0] === 'zh-CN' && override === 0) {
  361. return get_google_translation_result(word, tl = 'en', 1);
  362. } else {
  363. return result[0].map(function (v) {
  364. return v[0] ? v[0] : '';
  365. }).join('');
  366. }
  367. });
  368.  
  369. return function get_google_translation_result(_x6) {
  370. return _ref4.apply(this, arguments);
  371. };
  372. })();
  373.  
  374. let get_translation = (() => {
  375. var _ref5 = _asyncToGenerator(function* (word, engine) {
  376. if (engine === 'iciba') {
  377. let iciba_result = yield get_iciba_result(word);
  378. _this.icibaResultTextBox.innerHTML = iciba_result;
  379. let playbtn = document.querySelectorAll('.icIBahyI-ico_sound');
  380. if (playbtn.length != 0) {
  381. for (let i = 0; i < playbtn.length; i++) {
  382. playbtn[i].setAttribute('mp3', playbtn[i].getAttribute('onclick').match(/asplay_hanci\('(.*)'\)/)[1]);
  383. playbtn[i].removeAttribute('onclick');
  384. playbtn[i].addEventListener('click', _this.playSound, false);
  385. }
  386. }
  387. } else if (engine === 'baidu') {
  388. let lang_detect = yield get_lang_detect(word);
  389. let target_lang = lang_detect === 'zh' ? 'en' : 'zh';
  390. let baidu_translation_result = yield get_baidu_translation_result(lang_detect, target_lang, word);
  391. _this.icibaResultTextBox.innerHTML = baidu_translation_result;
  392. } else if (engine === 'google') {
  393. let google_translation_result = yield get_google_translation_result(word);
  394. _this.icibaResultTextBox.innerHTML = google_translation_result;
  395. }
  396. });
  397.  
  398. return function get_translation(_x7, _x8) {
  399. return _ref5.apply(this, arguments);
  400. };
  401. })();
  402.  
  403. get_translation(word, engine).catch(err => {
  404. _this.icibaResultTextBox.innerHTML = err.message;
  405. });
  406. };
  407.  
  408. // https://github.com/matheuss/google-translate-token
  409. // get_google_translate_token 获取google translate token
  410. Iciba.prototype.get_google_translate_token = function (word) {
  411. window.TKK = GM_getValue('TKK') || '0';
  412. /* eslint-disable */
  413. // BEGIN
  414. function sM(a) {
  415. var b;
  416. if (null !== yr) b = yr;else {
  417. b = wr(String.fromCharCode(84));
  418. var c = wr(String.fromCharCode(75));
  419. b = [b(), b()];
  420. b[1] = c();
  421. b = (yr = window[b.join(c())] || "") || "";
  422. }
  423. var d = wr(String.fromCharCode(116)),
  424. c = wr(String.fromCharCode(107)),
  425. d = [d(), d()];
  426. d[1] = c();
  427. c = "&" + d.join("") + "=";
  428. d = b.split(".");
  429. b = Number(d[0]) || 0;
  430. for (var e = [], f = 0, g = 0; g < a.length; g++) {
  431. var l = a.charCodeAt(g);
  432. 128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023), e[f++] = l >> 18 | 240, e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224, e[f++] = l >> 6 & 63 | 128), e[f++] = l & 63 | 128);
  433. }
  434. a = b;
  435. for (f = 0; f < e.length; f++) a += e[f], a = xr(a, "+-a^+6");
  436. a = xr(a, "+-3^+b+-f");
  437. a ^= Number(d[1]) || 0;
  438. 0 > a && (a = (a & 2147483647) + 2147483648);
  439. a %= 1E6;
  440. return c + (a.toString() + "." + (a ^ b));
  441. }
  442.  
  443. var yr = null;
  444. var wr = function (a) {
  445. return function () {
  446. return a;
  447. };
  448. },
  449. xr = function (a, b) {
  450. for (var c = 0; c < b.length - 2; c += 3) {
  451. var d = b.charAt(c + 2),
  452. d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d),
  453. d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
  454. a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d;
  455. }
  456. return a;
  457. };
  458.  
  459. // END
  460. /* eslint-enable */
  461.  
  462. function updateTKK() {
  463. return new Promise(function (resolve, reject) {
  464. var now = Math.floor(Date.now() / 3600000);
  465. if (Number(window.TKK.split('.')[0]) === now) {
  466. resolve();
  467. } else {
  468. got({
  469. method: 'GET',
  470. url: 'https://translate.google.cn/',
  471. timeout: 5000
  472. }).then(result => {
  473. var code = result.match(/TKK=(.*?)\(\)\)'\);/g);
  474. if (code) {
  475. eval(code[0]);
  476. /* eslint-disable no-undef */
  477. if (typeof TKK !== 'undefined') {
  478. window.TKK = TKK;
  479. GM_setValue('TKK', TKK);
  480. }
  481. /* eslint-enable no-undef */
  482. }
  483. resolve();
  484. }).catch(() => {
  485. reject();
  486. });
  487. }
  488. });
  489. }
  490.  
  491. function get(text) {
  492. return updateTKK().then(function () {
  493. var tk = sM(text);
  494. tk = tk.replace('&tk=', '');
  495. return { name: 'tk', value: tk };
  496. }).catch(function (err) {
  497. throw err;
  498. });
  499. }
  500. return get(word);
  501. };
  502.  
  503. // conflictsResolve 不同网站的冲突解决
  504. Iciba.prototype.conflictsResolve = function () {
  505. if (window.location.href.indexOf('http://tieba.baidu.com/photo/p?kw=') === 1) {
  506. GM_addStyle('.af_container{position:relative;}');
  507. }
  508. };
  509.  
  510. // playSound 发声
  511. Iciba.prototype.playSound = function (e) {
  512. var audio = document.createElement('audio');
  513. var source = document.createElement('source');
  514. source.type = 'audio/mpeg';
  515. source.src = e.target.getAttribute('mp3');
  516. source.autoplay = 'autoplay';
  517. source.controls = 'controls';
  518. audio.appendChild(source);
  519. audio.play();
  520. };
  521.  
  522. // getPosition 计算鼠标事件对于元素应去的top left值
  523. Iciba.prototype.getPosition = function (e) {
  524. // e.clienX e.clientY 是相对于浏览器viewport的位置(当前窗口)
  525. // e.pageX e.pageY 是相对于当前页面的位置(页面最左上角,不考虑 margin)
  526. // position:absolute 以父元素content-box的左上角定位
  527. // html 和 body 都为 static 时用 以当前 viewport 的大小的隐形元素 最上面定位 (不考虑 html body margin)
  528. // html 不为 static 时用 html 的 content-box 定位
  529. // body 不为 static 时用 body 的 content-box 定位
  530. // html 和 body 似乎不会发生margin-collapse
  531. // margin collapse 只发生在 margin-top 和 margin-bottom
  532. var de = {
  533. page: {
  534. offsetTop: e.pageY,
  535. offsetLeft: e.pageX
  536. },
  537. body: {
  538. rect: document.body.getBoundingClientRect(),
  539. scrollHeight: document.body.scrollHeight, // inner height of an element in pixels, including padding but not the horizontal scrollbar
  540. scrollWidth: document.body.scrollWidth, // inner width of an element in pixels. It includes padding but not the vertical scrollbar
  541. clientTop: document.body.clientTop, // top border width
  542. clientLeft: document.body.clientLeft, // left border width
  543. position: document.defaultView.getComputedStyle(document.body)['position']
  544.  
  545. },
  546. html: {
  547. rect: document.documentElement.getBoundingClientRect(), // coordinates relative to the viewport origin, of the top of the rectangle box
  548. scrollHeight: document.documentElement.scrollHeight, // inner height of an element in pixels, including padding but not the horizontal scrollbar
  549. scrollWidth: document.documentElement.scrollWidth, // inner width of an element in pixels. It includes padding but not the vertical scrollbar
  550. clientTop: document.documentElement.clientTop, // top border width
  551. clientLeft: document.documentElement.clientLeft, // left border width
  552. position: document.defaultView.getComputedStyle(document.documentElement)['position']
  553. },
  554. window: {
  555. scrollY: window.scrollY, // number of pixels that the document has already been scrolled vertically.
  556. scrollX: window.scrollX, // number of pixels that the document has already been scrolled horizontally.
  557. innerHeight: window.innerHeight, // viewport height
  558. innerWidth: window.innerWidth },
  559. e: e,
  560. base: 'page',
  561. get re() {
  562. return this[this.base];
  563. }
  564. };
  565.  
  566. de.page.positionHeight = de.window.innerHeight;
  567. de.page.positionWidth = de.window.innerWidth;
  568. de.page.detectHeight = de.html.scrollHeight;
  569. de.page.detectWidth = de.html.scrollHeight;
  570.  
  571. de.body.positionHeight = de.body.scrollHeight;
  572. de.body.positionWidth = de.body.scrollWidth;
  573. de.body.detectHeight = de.body.scrollHeight;
  574. de.body.detectWidth = de.body.scrollWidth;
  575.  
  576. de.html.positionHeight = de.html.scrollHeight;
  577. de.html.positionWidth = de.html.scrollWidth;
  578. de.html.detectHeight = de.html.scrollHeight;
  579. de.html.detectWidth = de.html.scrollWidth;
  580.  
  581. // formula from jquery.offset
  582. de.body.offsetTop = e.pageY - (de.body.rect.top + de.window.scrollY + de.body.clientTop);
  583. de.body.offsetLeft = e.pageX - (de.body.rect.left + de.window.scrollX + de.body.clientLeft);
  584. de.html.offsetTop = e.pageY - (de.html.rect.top + de.window.scrollY + de.html.clientTop);
  585. de.html.offsetLeft = e.pageX - (de.html.rect.left + de.window.scrollX + de.html.clientLeft);
  586.  
  587. if (de.html.position !== 'static') {
  588. de.base = 'html';
  589. } else if (de.body.position !== 'static') {
  590. de.base = 'body';
  591. }
  592. return de;
  593. };
  594.  
  595. // _keyDown keydown 事件处理函数
  596. Iciba.prototype._keyDown = function (e, _this) {
  597. if (e.key === 'Control' && e.keyCode === 17) {
  598. if (!_this.ctrlKey_actived) {
  599. _this.removeCirclePointer();
  600. }
  601. }
  602. };
  603.  
  604. // _isInsideOf 判断是否在内部
  605. Iciba.prototype._isInsideOf = function (e, target) {
  606. // when target is not exist
  607. if (!target) {
  608. return false;
  609. }
  610. var e_target = e.target;
  611. while (e_target != target && e_target) {
  612. e_target = e_target.parentNode;
  613. }
  614. if (e_target === target) {
  615. return true;
  616. } else {
  617. return false;
  618. }
  619. };
  620.  
  621. // _mouseClick mousedown 事件处理函数
  622. Iciba.prototype._mouseClick = function (e, _this) {
  623. // console.log('pageX:' + e.pageX + ',pageY:' + e.pageY + ',clientX:' + e.clientX + ',clientY:' + e.clientY)
  624. // ignore when click on icibaCirclePointer
  625.  
  626. if (e.target.id === 'icibaCirclePointer') {
  627. return;
  628. }
  629.  
  630. if (e.button != 0) {
  631. return;
  632. }
  633.  
  634. // ignore when click insideof icibaResultContainer
  635. if (_this._isInsideOf(e, _this.icibaResultContainer)) {
  636. return;
  637. }
  638.  
  639. // Ctrl键触发
  640. if (_this.ctrlKey_actived) {
  641. if (!(e.ctrlKey === true && e.shiftKey === false && e.altKey === false)) {
  642. _this.removeCirclePointer();
  643. _this.removeContainer();
  644. return;
  645. }
  646. }
  647.  
  648. // remove all things
  649. if (_this.icibaResultContainer) {
  650. _this.removeContainer();
  651. }
  652. if (_this.icibaCirclePointer) {
  653. _this.removeCirclePointer();
  654. }
  655.  
  656. // 显示iciba_icon
  657. if (window.getSelection().toString().length >= _this.maxSelectlength) {
  658. return; // ignore when selection is too loing
  659. }
  660.  
  661. if (window.getSelection().toString().length !== 0) {
  662. _this.showIcibaCirclePointer(e);
  663. return;
  664. }
  665.  
  666. // 去除iciba_icon
  667. if (window.getSelection().toString().length === 0) {
  668. _this.removeCirclePointer();
  669. }
  670.  
  671. return;
  672. };
  673.  
  674. // https://gist.github.com/revolunet/843889
  675. // Decompress an LZW-encoded string
  676. function lzw_decode(s) {
  677. let dict = {};
  678. let data = (s + '').split('');
  679. let currChar = data[0];
  680. let oldPhrase = currChar;
  681. let out = [currChar];
  682. let code = 256;
  683. let phrase;
  684. for (let i = 1; i < data.length; i++) {
  685. let currCode = data[i].charCodeAt(0);
  686. if (currCode < 256) {
  687. phrase = data[i];
  688. } else {
  689. phrase = dict[currCode] ? dict[currCode] : oldPhrase + currChar;
  690. }
  691. out.push(phrase);
  692. currChar = phrase.charAt(0);
  693. dict[code] = oldPhrase + currChar;
  694. code++;
  695. oldPhrase = phrase;
  696. }
  697. return out.join('');
  698. }
  699.  
  700. function got(param) {
  701. return new Promise((rs, rj) => {
  702. var obj = {
  703. method: 'GET',
  704. referer: '',
  705. url: '',
  706. timeout: 10000,
  707. ontimeout() {
  708. rj(new Error('网络超时!'));
  709. },
  710. onerror() {
  711. rj(new Error('网络错误!'));
  712. },
  713. onload(response) {
  714. if (response.status != 200) {
  715. rj(new Error('网络错误!'));
  716. }
  717. rs(response.responseText);
  718. }
  719. };
  720. for (let x in param) {
  721. obj[x] = param[x];
  722. }
  723. GM_xmlhttpRequest(obj);
  724. });
  725. }
  726.  
  727. {
  728. new Iciba();
  729. }