// ==UserScript== // @name iciba划词翻译 // @namespace noe132.com // @author noe132 // @include http://* // @include https://* // @exclude http://www.iciba.com* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @icon http://tb.himg.baidu.com/sys/portrait/item/d4346e6f65313332ac06 // @version 3.2.4 // @supportURL http://tieba.baidu.com/f?kw=firefox // @contributionURL nnnnoe132@gmail.com|alipay.com // @description iciba翻译 // @downloadURL none // ==/UserScript== /* ------------------ changelog ------------------- * update INFO: * update 2017/04/12 : 添加了百度翻译谷歌翻译按钮 * update 2017/04/12 : 搞了个字符串压缩~解压字符串速度还可以 * update 2017/04/11 : bug fix,重写鼠标事件定位方法 * update 2017/03/24 : 添加鼠标事件10ms延迟 * update 2017/03/24 : 用babel翻译async function,可以支持到chrome33 * update 2017/03/23 : 使用百度翻译API,iciba的程序员不更新api * update 2016/12/23 : trim查询字符串,更新版本号到3 * update 2016/09/23 : mouseClick只能左键触发 * update 2016/08/19 : 不知为何connect属性未加上 * update 2016/05/30 : 样式修改 * update 2016/05/03 : 解释处理修改 * update 2016/05/02 : 样式修改 * update 2016/05/01 : 样式修改 * update 2016/04/22 : 老版本浏览器兼容性修复 * update 2016/04/17 : 样式修改 * update 2016/04/17 : 重写 * update 2016/04/09 : 样式小改 * update 2016/03/27 : 紧急修复。。。 * update 2016/03/16 : 样式修正 * update 2016/03/05 : 样式小改 * update 2015/07/31 : 貌似之前的wordpress判断不太给力,干脆带wp-admin的都干掉 * update 2015/07/12 : 去除wp-admin/post.php页面,防止wordpress编辑文章自动添加div * update 2015/05/19 : 设置查词默认为小写 * update 2015/05/09 : 按Ctrl可以使小蓝圈隐藏起来(暂时) * update 2015/01/03 : 样式全加了 !important 提高优先级 * update 2014/12/24 : 添加设置选项(可当且仅当按住ctrl键显示翻译按钮) * update 2014/12/20 : 修正语法错误。。。 * update 2014/12/19 : 搜词BUG修复,修正点击定位~ * update 2014/12/10 : 严格模式'use strict',提高性能 * update 2014/12/04 : 贴吧图册预览修正 * update 2014/11/16 : 更换mouseClick的触发条件为mouseup * update 2014/11/14 : 添加输入框查词,修正定位不正确。 * ------------------------------------------------ */ 'use strict'; 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"); }); }; } var Iciba = function () { this.init(); }; Iciba.prototype.auto_active = 1; //没用~ Iciba.prototype.ctrlKey_actived = null; // init 初始化对象 插入样式 读取设置 绑定事件 Iciba.prototype.init = function () { var _this = this; 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రరЯIࢪhح-˶w_˪ơʰŇ̢ĝГͳ}ϞcవĪసŊbత_Ɨ́>LƷELిʲ̣̥Ʉ௴ȼ˲௷ఌ௺ɽņvνϟ௵t౞௹Ȭ Ⱦ౤˰౜௶௸ౠ Ɨ౭Ⱥ౯౧౱౪p౵ʏ౷౨౲Ĕrm౼a౦౿౪˹ɐ಄ಆ౹ɽోత௼̆ʻϹΔఁˀಔˠఔӶƄ͹ɪಂ̰౛ʑ౸౟ಈςtಋ౾಍ bѓನಢಇɽఋłr̓ēΎಛͯĎīĺఒ࢑ఔ́yĊ̤n಻ǚ΍˚௧಺ıಽϺΝΎఛ΢ఞఠlఢతũ̃aనΰĺఫౄξಌತɽ౬೟಩ೡ౳i{౏Οೀೂృۦ೤ಯಪѢυχȡt͵ͫɫಡౝಪĽgʚˊƒಘʌ೰೼೦́ĢʈಶĖಸ͹ˆೇΟ೐ఝ"͋ըe UIĮVđѠn೙LuĂѠ Sࢦ Ȼ޲ŊμഡണaഥധUnāҡe,టiడsࢦ೛Ļ̿അ౰೦ెైషI-ņ୴ĄĒಿ௧1шఘɦۧಅ೥౩ɽൃశస಴ʺ́đಮആൕ ൗ౉െĺɕʮg൞ുൠൢ൅-u౻ീಣ൫āൄసϊϦūo̻:൥Ɔ೻൪౲൬൙e൛Ǹϧం-఑Ż௬ി౥ൔ౲aංെಲʮŊŐ൩൲ඁ൴൘െടv౎Ňħഈĕ೿ఇƵ3ඨൿ඙౪a{ඦ#236fdȪΜಲേeΆƤ࢝ࢳƳđ͵ඪರ ѢУǼදනඳඵෂಪඒͷĵdw಼ശ൱ස෎ƿƳිǚe_λ඘ූඛൣേĢp_൷˼ģ۔ǝabƖɐ̾࢑˄Ş6అƂͮഎ෴൐ƞφrĤƒĿǷđ෌ൂ෡൭ෘෑී{ɑpఖ෵ńൽƇ13Ɖ௭࢛෩ලǃ-7ดඍ౮ೱคేගාෙීෝФซญ෺ŦฐŞณฎ࢒ࢯШ௯ǝ-1ͱͣปฎ൒ೠൠǰ൵െൈt_ɝĎඇಗఊ௸̲Ɨఏ:఑ฃ൳ม෢แൊౖుǪ̩ʽ͓็Μϰ௨ə࢑͵ͷ෷ฑ.Ϝฝ౶ฟ๐฿-Ǜ೷e෨˾௰಴ۯз෰್ಖʞ1෹௪ͦόึฯදඨ3ഐ-഍ƇƏԿຄ࢕Żగຄഒĝʫഹ೔഻ίపʁɄ๢ಜƇɢฯఽϾb಴akǪມk๊l๏ක๑൭แ_๭۴ກඩఓಷ๣ʟຉຳĖຏȍ೓೚ຖ๧౽๩ສ๫pഉs๕ʳ๗ŏ̪࢑๸Λ࢑๝ɗɑɋ΃ͶΙ˝ಞɝຨຸΟຆ:ปഃʥ෕෍ฅ൶ā࣓ʫൡ໤െū{̭೘̱ఎ̵Űd̸໛కൎฯ๡๝໘ಠ຿൓ແ౪෎๓໨෎ūʘഋ೫്൏ຩ༁໪řΆʩ۝ช้śර̻௰೮Δ̜೹̘Μ່̡ౙ̧ō໊Ǖλ൹ŭůűۘ̅ʹಓϪɍ˅෹ͭບෳฯ࢚΀ࢴۼࢷࢱ܁ࢺ܄ࢽѯ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ǢΜ໮̯໰๋໲̷๶̒฻ඏ།ຫసഴ༑΀ෆĒǾǐǒǔ໾฼ໂย჌Ĥ΀жȐბȀǞ9༌ൖ༎඄ෟ໣჊െχໍ๬Ǎ௿ƞచΡഓlഢŰയດs౫ളΆśĮຑ໽࢑༟̣༣ʶვ჈უშహe఻ພē̺Ƈ๎Μძศ་ᄅༀᄇ๫఺఼Ɛහ໇ᄂ๘ᄑ๚ʞώ௪Ɖчผ෱ϫșฯ๝1ͦตۑำ̈-27గDŽϗЁȤʀ໶ໝഏ໶຺ΤcĢĤĦĨĪĬ"ტ໩ᄈᄙພහ෎ᅍƐ2ࢮ௥ےท௰ᄳᄵƔีϭสďჇᄖᅋ๫ƧṵĜღภໃ໅ථЪƵ΋6ຄᄽŠᅊ෎˛ľ۴௽ʻۤόᅻ໠ᅟ໢ᅩยͿ෥ໄĕໆȈʫʟŹ༬௾ᅾtᅠൟთ෢ᆃ_ᆅĶᅢยİΆƳᄍൺЌ༝໌ᄡgწฌᆎᆐ඀჉๫ᆔᆖჸᅵයĕ˔෎඄{๝2ຍᄕᆑᆩᆂƱᆄģථĊᆉƏᆋΜ༦ŬŮ໳༫Μ෈ȷ໶຋Αฺᆀ๪ᆻȡᆽჸʙൌ۠ษᅴ༎ᆫģ ฌɪt(ํѯΟĥ๬yЊ)಑༭nˌˎːඌೞඎᅡ෎ಏlච́ᆝൻᄐᆡϨᆣᇂɑːᅝ༯Ɏ87ˈභ้໱ํeĦᇛᄈ࿅ᆘᆓᆼᆕᆾັ຃ᆸᆨᄗᇓ൯ሖჸඣഊද8dሤሤሐ๫ᅹnຮǍๆʈᆤ:༲ሚණሜ෢ǎŁᇹħ೙ᇑᆒ൭łbሹ೧හᅨᇒ෢ᅑơቃሼᆺሶʫโไn h3ᄜම༕ŀ༗ǝ༙൑ቊስሾ෬ሹᄝూ೺ሳ෠ᄈຯ๯ໍอɻᄥɼຊ്ᆷᇳพᆹቝసᇝໆᇘΐተ೯ᇴታሓ൭ቶቾస໬ቩǃ๻ȳᄸнɿსቤყᆪሕ˽ƕǎϦႿ͝Ⴡ̴ǪཁශΜ໺ີ໼໚ಾᄎ༜Ⴥˠᄁĝ༡ኣƞኄረᆙy̗ᅬᄹຂທ̧ᆵϳኌᆁ෢Ƚय़ȼಧቜኁെኹљ́ᅓኄόᄣᆎ;መɋ˫ිaฌຠ̓຦ພቮᇙᇏᅞʹຘᆵᄔቱ๨ችᅵuኺ́౫lሮǩ๽ǃቺΔኜ༴௫5ሉዛເዝ༎ዀኻ೧ዤඉሎฑየˠ༷าᅗิฒᄶ-ณዺഄቼማኾĸዟ዁ħp೩ዘີ25ˇካኸጊዴ෎ໄᄜძฬώጔ൭ዳዡpጘĒሪሰጝኛጏያኵዯ໿ዱᄈጠħጣᄜእೃ๡ᄃ໋๷ᆢƣያᄧቻቲጇ༅۲ආኪΜෲ໑๟್දኊ่ఌ๊ኗฐዓΐዚ್ዪͯ๿ዖᆧሴገĔˍ˷ත༛ቚƞቕᆯ඼༘ባᇾంц዆ᄷబัƴ፡ఆᅭධ඲පබ࢑፣༖ල፰ŖቸŞፓዩጩፖጫጾዜፀ༎፜ǸහκФ෈፴෋኶ቅሾ௸ඕu๯ᎍ්፶ᎄደᎆᄈ೪ድዄ௫ᇐጆፚᇶi෦ಧᎥ෦dቡጵౚጨኳጐጄ໡Ꭳብ๫ƗᎧዶฬᇲፉ፲නᎾሙጬზቋ൭Ꮇűኯн7ᏉȃիవA_TOO_LOၒዶศఄዖ;ძඊᏙፑ፾ฺ'; style = lzw_decode(style); GM_addStyle(style); GM_registerMenuCommand('iciba翻译设置', this.openSetting); _this.loadSetting(); _this.eventBinding(); }; // loadSetting 读取设置 Iciba.prototype.loadSetting = function () { // Ctrl键触发 var _this = this; if (GM_getValue('ctrlKey_actived') === undefined) { _this.ctrlKey_actived = 0; } else { _this.ctrlKey_actived = parseInt(GM_getValue('ctrlKey_actived')); } GM_setValue('ctrlKey_actived', _this.ctrlKey_actived); }; // eventBinding 绑定事件 Iciba.prototype.eventBinding = function () { var _this = this; window.addEventListener('mouseup', function (e) { setTimeout(() => { _this._mouseClick(e, _this); }, 10); }, false); window.addEventListener('keydown', function (e) { _this._keyDown(e, _this); }, false); }; // openSetting 设置对话框 Iciba.prototype.openSetting = function () { var _this = this; _this.ctrlKey_actived = confirm('按住ctrl键(当且仅当)开启翻译?') ? 1 : 0; GM_setValue('ctrlKey_actived', _this.ctrlKey_actived); }; // showIcibaCirclePointer 显示并定位小圆点 Iciba.prototype.showIcibaCirclePointer = function (e) { var _this = this; let { top, left } = _this.getPosition(e); _this.icibaCirclePointer = document.createElement('div'); _this.icibaCirclePointer.id = 'icibaCirclePointer'; _this.icibaCirclePointer.style.position = 'absolute'; _this.icibaCirclePointer.style.top = top + 7 + 'px'; _this.icibaCirclePointer.style.left = left + 5 + 'px'; _this.icibaCirclePointer.setAttribute('keyword', window.getSelection().toString().toLowerCase().trim()); _this.icibaCirclePointer.addEventListener('click', function (e) { _this.showContainer(e, _this); }, false); document.body.appendChild(_this.icibaCirclePointer); }; // removeCirclePointer 去除小圆点 Iciba.prototype.removeCirclePointer = function () { var _this = this; if (_this.icibaCirclePointer) { document.body.removeChild(_this.icibaCirclePointer); } _this.icibaCirclePointer = null; }; // showContainer 显示并定位查词框 Iciba.prototype.showContainer = function (e, _this) { var word = _this.icibaCirclePointer.getAttribute('keyword'); _this.removeCirclePointer(); _this.createContainer(); _this.containerSetPosition(e); _this.containerLoadData(word, 'iciba'); // getData(word,e,bodyClientHeight,bodyClientWidth,windowInnerHeight,windowInnerWidth,htmlClientHeight,htmlClientWidth); }; // createContainer 创建查词框 Iciba.prototype.createContainer = function () { var _this = this; _this.icibaResultContainer = document.createElement('div'); _this.icibaResultContainer.id = 'icibaResultContainer'; _this.icibaResultContainer.style.position = 'absolute'; _this.icibaResultContainer.innerHTML = '\ \
'; document.body.appendChild(_this.icibaResultContainer); _this.icibaResultTextBox = document.getElementById('icibaResultTextBox'); _this.icibaSearchInput = document.getElementById('icibaSearchInput'); _this.icibaSearchButton = document.getElementById('icibaSearchButton'); _this.icibaSearchButtonTranslateBaidu = document.getElementById('icibaSearchButtonTranslateBaidu'); _this.icibaSearchButtonTranslateGoogle = document.getElementById('icibaSearchButtonTranslateGoogle'); _this.icibaSearchInput.addEventListener('keypress', function (e) { if (e.target === _this.icibaSearchInput) { if (e.keyCode != 13) { return; } } _this.containerLoadData(_this.icibaSearchInput.value, 'iciba'); }, false); _this.icibaSearchButton.addEventListener('click', function () { _this.containerLoadData(_this.icibaSearchInput.value, 'iciba'); }, false); _this.icibaSearchButtonTranslateBaidu.addEventListener('click', function () { _this.containerLoadData(_this.icibaSearchInput.value, 'baidu'); }, false); _this.icibaSearchButtonTranslateGoogle.addEventListener('click', function () { _this.containerLoadData(_this.icibaSearchInput.value, 'google'); }, false); }; // removeContainer 去除查词框 Iciba.prototype.removeContainer = function () { var _this = this; if (_this.icibaResultContainer) { document.body.removeChild(_this.icibaResultContainer); _this.icibaResultContainer = null; _this.icibaResultTextBox = null; _this.icibaSearchInput = null; _this.icibaSearchButton = null; } }; // containerSetPosition 定位查词框 Iciba.prototype.containerSetPosition = function (e) { var _this = this; let { de, top, left } = _this.getPosition(e); if (de[de.base].clientHeight - top < 200) { // TODO using bottom position _this.icibaResultContainer.style.top = 'auto'; _this.icibaResultContainer.style.bottom = de[de.base].clientHeight - top + 'px'; } else { _this.icibaResultContainer.style.top = top + 'px'; _this.icibaResultContainer.style.bottom = 'auto'; } if (de[de.base].clientWidth - left < 300) { // using right position _this.icibaResultContainer.style.left = 'auto'; _this.icibaResultContainer.style.right = de[de.base].clientWidth - left + 'px'; } else { _this.icibaResultContainer.style.left = left + 'px'; _this.icibaResultContainer.style.right = 'auto'; } }; // containerLoadData 获取数据查词 Iciba.prototype.containerLoadData = function (word, engine) { var _this = this; _this.icibaResultTextBox.innerHTML = 'Loading......'; _this.icibaSearchInput.value = word; var get_iciba_result = function (word) { return new Promise(function (rs, rj) { GM_xmlhttpRequest({ method: 'GET', referer: 'http://www.iciba.com/', url: 'http://open.iciba.com/huaci/dict.php?word=' + word, timeout: 10000, ontimeout() { rj({ status: 1, message: '网络超时!' }); }, onerror() { rj({ status: 1, message: '网络错误!' }); }, onload(response) { if (response.status != 200) { rj({ status: 1, message: '网络错误!' }); } var text = response.responseText.replace(/\\/g, ''); text = text.match(/dict\.innerHTML=\'(.*)\'/)[1]; text = text.replace(/icIBahyI-'ico_sound'/g, '"icIBahyI-ico_sound"'); rs({ status: 0, data: text }); } }); }); }; var get_lang_detect = function (word) { var lang_detect_formData = new FormData(); lang_detect_formData.append('query', word); return new Promise(function (rs, rj) { GM_xmlhttpRequest({ method: 'POST', referer: 'http://fanyi.baidu.com', url: 'http://fanyi.baidu.com/langdetect', data: lang_detect_formData, timeout: 5000, ontimeout() { rj({ status: 1, message: '网络超时!' }); }, onerror() { rj({ status: 1, message: '网络错误!' }); }, onload(response) { if (response.status != 200) { rj({ status: 1, message: '网络错误!' }); } var result = JSON.parse(response.responseText); if (result.error === 0) { rs({ status: 0, lang: result.lan }); } else { rj({ status: 1, message: '翻译文本语言未知!' }); } } }); }); }; var get_baidu_translation_result = function (lang_detect, target_lang, word) { var translation_formData = new FormData(); translation_formData.append('from', lang_detect); translation_formData.append('to', target_lang); translation_formData.append('query', word); translation_formData.append('transtype', 'translang'); return new Promise(function (rs, rj) { GM_xmlhttpRequest({ method: 'POST', referer: 'http://fanyi.baidu.com', url: 'http://fanyi.baidu.com/v2transapi', data: translation_formData, timeout: 5000, ontimeout() { rj({ status: 1, message: '网络超时!' }); }, onerror() { rj({ status: 1, message: '网络错误!' }); }, onload(response) { if (response.status != 200) { rj({ status: 1, message: '网络错误!' }); } var result = JSON.parse(response.responseText); if (result.trans_result.type === 2 && result.trans_result.status === 0) { rs(result.trans_result.data[0].dst); } else { rj({ status: 1, message: '翻译出错!' }); } } }); }); }; var get_google_translation_result = (() => { var _ref = _asyncToGenerator(function* (word, tl = 'zh-CN', override = 0) { let token = (yield _this.get_google_translate_token(word)).value; let url = 'https://translate.google.cn/translate_a/single?'; 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}&q=${word}`; console.log(token); let result = yield new Promise((() => { var _ref2 = _asyncToGenerator(function* (rs, rj) { GM_xmlhttpRequest({ method: 'GET', headers: { 'Referer': 'https://translate.google.cn/', 'Cache-Control': 'max-age=0' }, url: url + query_string, timeout: 5000, ontimeout() { rj({ status: 1, message: '网络超时!' }); }, onerror() { rj({ status: 1, message: '网络错误!' }); }, onload(response) { if (response.status != 200) { rj({ status: 1, message: '网络错误!' }); } var result = JSON.parse(response.responseText); console.log(result); // detected language if (result[8][0][0] === 'zh-CN' && override === 0) { rs(get_google_translation_result(word, tl = 'en', 1)); } else { rs(result[0][0][0]); } } }); }); return function (_x2, _x3) { return _ref2.apply(this, arguments); }; })()); return result; }); return function get_google_translation_result(_x) { return _ref.apply(this, arguments); }; })(); let get_translation = (() => { var _ref3 = _asyncToGenerator(function* (word, engine) { if (engine === 'iciba') { let iciba_result = yield get_iciba_result(word); _this.icibaResultTextBox.innerHTML = iciba_result.data; let playbtn = document.querySelectorAll('.icIBahyI-ico_sound'); if (playbtn.length != 0) { for (let i = 0; i < playbtn.length; i++) { playbtn[i].setAttribute('mp3', playbtn[i].getAttribute('onclick').match(/asplay_hanci\('(.*)'\)/)[1]); playbtn[i].removeAttribute('onclick'); playbtn[i].addEventListener('click', _this.playSound, false); } } } else if (engine === 'baidu') { let lang_detect = (yield get_lang_detect(word)).lang; let target_lang = lang_detect === 'zh' ? 'en' : 'zh'; let baidu_translation_result = yield get_baidu_translation_result(lang_detect, target_lang, word); _this.icibaResultTextBox.innerHTML = baidu_translation_result; } else if (engine === 'google') { let google_translation_result = yield get_google_translation_result(word); _this.icibaResultTextBox.innerHTML = google_translation_result; } }); return function get_translation(_x4, _x5) { return _ref3.apply(this, arguments); }; })(); get_translation(word, engine).catch(err => { _this.icibaResultTextBox.innerHTML = err.message; }); }; // https://github.com/matheuss/google-translate-token // get_google_translate_token 获取google translate token Iciba.prototype.get_google_translate_token = function (word) { window.TKK = GM_getValue('TKK', '0'); /* eslint-disable */ // BEGIN function sM(a) { var b; if (null !== yr) b = yr;else { b = wr(String.fromCharCode(84)); var c = wr(String.fromCharCode(75)); b = [b(), b()]; b[1] = c(); b = (yr = window[b.join(c())] || "") || ""; } var d = wr(String.fromCharCode(116)), c = wr(String.fromCharCode(107)), d = [d(), d()]; d[1] = c(); c = "&" + d.join("") + "="; d = b.split("."); b = Number(d[0]) || 0; for (var e = [], f = 0, g = 0; g < a.length; g++) { var l = a.charCodeAt(g); 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); } a = b; for (f = 0; f < e.length; f++) a += e[f], a = xr(a, "+-a^+6"); a = xr(a, "+-3^+b+-f"); a ^= Number(d[1]) || 0; 0 > a && (a = (a & 2147483647) + 2147483648); a %= 1E6; return c + (a.toString() + "." + (a ^ b)); } var yr = null; var wr = function (a) { return function () { return a; }; }, xr = function (a, b) { for (var c = 0; c < b.length - 2; c += 3) { var d = b.charAt(c + 2), d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d), d = "+" == b.charAt(c + 1) ? a >>> d : a << d; a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d; } return a; }; // END /* eslint-enable */ function updateTKK() { return new Promise(function (resolve, reject) { var now = Math.floor(Date.now() / 3600000); if (Number(window.TKK.split('.')[0]) === now) { resolve(); } else { GM_xmlhttpRequest({ method: 'GET', url: 'https://translate.google.cn/', timeout: 5000, ontimeout() { var e = new Error(); e.code = 'BAD_NETWORK'; e.message = 'BAD_NETWORK'; reject(e); }, onerror() { var e = new Error(); e.code = 'BAD_NETWORK'; e.message = 'BAD_NETWORK'; reject(e); }, onload(response) { var code = response.responseText.match(/TKK=(.*?)\(\)\)'\);/g); if (code) { eval(code[0]); /* eslint-disable no-undef */ if (typeof TKK !== 'undefined') { window.TKK = TKK; GM_setValue('TKK', TKK); } /* eslint-enable no-undef */ } resolve(); } }); } }); } function get(text) { return updateTKK().then(function () { var tk = sM(text); tk = tk.replace('&tk=', ''); return { name: 'tk', value: tk }; }).catch(function (err) { throw err; }); } return get(word); }; // conflictsResolve 不同网站的冲突解决 Iciba.prototype.conflictsResolve = function () { if (window.location.href.indexOf('http://tieba.baidu.com/photo/p?kw=') === 1) { GM_addStyle('.af_container{position:relative;}'); } }; // playSound 发声 Iciba.prototype.playSound = function (e) { var audio = document.createElement('audio'); var source = document.createElement('source'); source.type = 'audio/mpeg'; source.src = e.target.getAttribute('mp3'); source.autoplay = 'autoplay'; source.controls = 'controls'; audio.appendChild(source); audio.play(); }; // getPosition 计算鼠标事件对于元素应去的top left值 Iciba.prototype.getPosition = function (e) { // e.clienX e.clientY 是相对于浏览器view port的位置(当前窗口) // e.pageX e.pageY 是相对于当前页面的位置(页面最左上角) // position:absolute 以父元素content-box的左上角定位 // html 和 body 都为 static 时用 页面最左上角定位(需要考虑html的margin-top) // html 和 body 似乎不会发生margin-collapse // margin collapse 只发生在 margin-top 和 margin-bottom var de = { page: { clientHeight: document.documentElement.scrollHeight, clientWidth: document.documentElement.scrollWidght, offsetTop: e.pageY, offsetLeft: e.pageX }, body: { rect: document.body.getBoundingClientRect(), clientHeight: document.body.clientHeight, clientWidth: document.body.clientWidth, clientTop: document.body.clientTop, // top border width clientLeft: document.body.clientLeft, // left border width position: document.defaultView.getComputedStyle(document.body)['position'] }, html: { rect: document.documentElement.getBoundingClientRect(), // coordinates relative to the viewport origin, of the top of the rectangle box clientHeight: document.documentElement.clientHeight, // inner height of an element in pixels, including padding but not the horizontal scrollbar clientWidth: document.documentElement.clientWidth, // inner width of an element in pixels. It includes padding but not the vertical scrollbar clientTop: document.documentElement.clientTop, // top border width clientLeft: document.documentElement.clientLeft, // left border width position: document.defaultView.getComputedStyle(document.documentElement)['position'] }, window: { scrollY: window.scrollY, // number of pixels that the document has already been scrolled vertically. scrollX: window.scrollX, // number of pixels that the document has already been scrolled horizontally. InnerHeight: window.innerHeight, // viewport height InnerWidth: window.innerWidth }, base: 'page' }; // formula from jquery.offset de.body.offsetTop = e.pageY - (de.body.rect.top + de.window.scrollY + de.body.clientTop); de.body.offsetLeft = e.pageX - (de.body.rect.left + de.window.scrollX + de.body.clientLeft); de.html.offsetTop = e.pageY - (de.html.rect.top + de.window.scrollY + de.html.clientTop); de.html.offsetLeft = e.pageX - (de.html.rect.left + de.window.scrollX + de.html.clientLeft); if (de.html.position !== 'static') { de.base = 'html'; } else if (de.body.position !== 'static') { de.base = 'body'; } return { top: de[de.base].offsetTop, left: de[de.base].offsetLeft, de: de }; }; // _keyDown keydown 事件处理函数 Iciba.prototype._keyDown = function (e, _this) { if (e.key === 'Control' && e.keyCode === 17) { if (!_this.ctrlKey_actived) { _this.removeCirclePointer(); } } }; // _isInsideOf 判断是否在内部 Iciba.prototype._isInsideOf = function (e, target) { // when target is not exist if (!target) { return false; } var e_target = e.target; while (e_target != target && e_target) { e_target = e_target.parentNode; } if (e_target === target) { return true; } else { return false; } }; // _mouseClick mousedown 事件处理函数 Iciba.prototype._mouseClick = function (e, _this) { // console.log('pageX:' + e.pageX + ',pageY:' + e.pageY + ',clientX:' + e.clientX + ',clientY:' + e.clientY) // ignore when click on icibaCirclePointer if (e.target.id === 'icibaCirclePointer') { return; } if (e.button != 0) { return; } // ignore when click insideof icibaResultContainer if (_this._isInsideOf(e, _this.icibaResultContainer)) { return; } // Ctrl键触发 if (_this.ctrlKey_actived) { if (!(e.ctrlKey === true && e.shiftKey === false && e.altKey === false)) { _this.removeCirclePointer(); _this.removeContainer(); return; } } // remove all things if (_this.icibaResultContainer) { _this.removeContainer(); } if (_this.icibaCirclePointer) { _this.removeCirclePointer(); } // 显示iciba_icon if (window.getSelection().toString().length >= 150) { return; // ignore when selection is too loing } if (window.getSelection().toString().length !== 0) { _this.showIcibaCirclePointer(e); return; } // 去除iciba_icon if (window.getSelection().toString().length === 0) { _this.removeCirclePointer(); } return; }; // https://gist.github.com/revolunet/843889 // Decompress an LZW-encoded string function lzw_decode(s) { let dict = {}; let data = (s + '').split(''); let currChar = data[0]; let oldPhrase = currChar; let out = [currChar]; let code = 256; let phrase; for (let i = 1; i < data.length; i++) { let currCode = data[i].charCodeAt(0); if (currCode < 256) { phrase = data[i]; } else { phrase = dict[currCode] ? dict[currCode] : oldPhrase + currChar; } out.push(phrase); currChar = phrase.charAt(0); dict[code] = oldPhrase + currChar; code++; oldPhrase = phrase; } return out.join(''); } { new Iciba(); }