diff --git a/src/Info.plist b/src/Info.plist index fcdfd66..e914556 100644 --- a/src/Info.plist +++ b/src/Info.plist @@ -5,7 +5,7 @@ Author Andy Portmen Builder Version - 10600.7.12 + 11601.1.56 CFBundleDisplayName igTranslator for Google CFBundleIdentifier @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleShortVersionString - 0.3.6 + 0.3.9 CFBundleVersion 2 Chrome diff --git a/src/data/content_script/inject.js b/src/data/content_script/inject.js index 979c46b..ce17e5c 100644 --- a/src/data/content_script/inject.js +++ b/src/data/content_script/inject.js @@ -88,45 +88,58 @@ function init() { if (text_direction == 'ltr') e.style.textAlign = "left"; } } - + function getSelectedRect(w) { try { - var range = w.getRangeAt(0).cloneRange(); - if (range.startOffset != range.endOffset) { - var rect = range.getBoundingClientRect(); - return rect; - } - else { - var arr = range.startContainer.childNodes; - for (var i = 0; i < arr.length; i++) { - var target = arr[i].nodeName.toLowerCase(); - if (target == 'textarea' || target == 'input') { - var rect = getTextBoundingRect(arr[i], arr[i].selectionStart, arr[i].selectionEnd); - if (rect.top && rect.left && rect.height && rect.width) return rect; + if (w.rangeCount) { + var range = w.getRangeAt(0).cloneRange(); + if (range.startOffset !== range.endOffset) { + var rect = range.getBoundingClientRect(); + return rect; + } + else if (range.startOffset == 0 && range.endOffset == 0) { + return null; + } + else { + var arr = range.startContainer.childNodes; + for (var i = 0; i < arr.length; i++) { + var target = arr[i].nodeName.toLowerCase(); + if (target.indexOf('text') !== -1 || target.indexOf('input') !== -1) { + var rect = getTextBoundingRect(arr[i], arr[i].selectionStart, arr[i].selectionEnd); + if (rect.top && rect.left && rect.height && rect.width) { + return rect; + } + else { + return null; + } + } } + range.collapse(false); + var dummy = document.createElement("span"); + range.insertNode(dummy); + var rect = dummy.getBoundingClientRect(); + dummy.parentNode.removeChild(dummy); + return rect; } - range.collapse(false); - var dummy = document.createElement("span"); - range.insertNode(dummy); - var rect = dummy.getBoundingClientRect(); - dummy.parentNode.removeChild(dummy); - return rect; + } + else { + return null; } } catch (e) { return null; } } - + function requestBubbleTranslation(e) { header.textContent = ''; content.textContent = ''; translateIcon.style.display = 'none'; var rect = requestBubbleTranslation.rect; - //iFrame.style.top = (rect.top + window.scrollY + rect.height) + 'px'; - iFrame.style.top = (e.clientY + window.scrollY + 40) + 'px'; - //iFrame.style.left = (rect.left + window.scrollX - 23 + rect.width / 2) + 'px'; - iFrame.style.left = (e.clientX + window.scrollX - 40) + 'px'; + if (rect && rect.top) iFrame.style.top = (rect.top + window.scrollY + rect.height) + 'px'; + else iFrame.style.top = (e.clientY + window.scrollY + 40) + 'px'; + if (rect && rect.left) iFrame.style.left = (rect.left + window.scrollX - 23 + rect.width / 2) + 'px'; + else iFrame.style.left = (e.clientX + window.scrollX - 40) + 'px'; iFrame.style.width = (170) + "px"; iFrame.style.height = (70) + "px"; iFrame.style.display = 'block'; @@ -136,14 +149,14 @@ function init() { allowMouseOverTranslation = false; background.send("translation-request", requestBubbleTranslation.text); } - + var timeoutIconShow, timeoutIconHide; function showTranslateIcon(e) { var rect = requestBubbleTranslation.rect; - //translateIcon.style.top = (rect.top + window.scrollY - 18) + 'px'; - translateIcon.style.top = (e.clientY + window.scrollY - 35) + 'px'; - //translateIcon.style.left = (rect.left + window.scrollX + rect.width - 2) + 'px'; - translateIcon.style.left = (e.clientX + window.scrollX + 10) + 'px'; + if (rect && rect.top) translateIcon.style.top = (rect.top + window.scrollY - 18) + 'px'; + else translateIcon.style.top = (e.clientY + window.scrollY - 30) + 'px'; + if (rect && rect.left) translateIcon.style.left = (rect.left + window.scrollX + rect.width - 2) + 'px'; + else translateIcon.style.left = (e.clientX + window.scrollX + 10) + 'px'; if (timeoutIconShow) window.clearTimeout(timeoutIconShow); if (timeoutIconHide) window.clearTimeout(timeoutIconHide); timeoutIconShow = window.setTimeout(function () { @@ -153,7 +166,7 @@ function init() { translateIcon.style.display = "none"; }, translateIconTime * 1000); /* hide TranslateIcon automatically */ } - + /* iFrame */ var iFrame = html("iframe", { src: "about:blank", @@ -572,7 +585,6 @@ function init() { } else { /* dblclick or mouseup translations */ var selectedText = getSelectedText(target); - console.error(selectedText) if (selectedText && selectedText.length >= minimumNumberOfCharacters) { requestBubbleTranslation.text = selectedText; requestBubbleTranslation.rect = getSelectedRect(window.getSelection()); @@ -756,4 +768,4 @@ function getTextBoundingRect(input, selectionStart, selectionEnd, debug) { } return ''; } -} +} \ No newline at end of file diff --git a/src/data/firefox/sound.html b/src/data/firefox/sound.html index ae99087..692a0d6 100644 --- a/src/data/firefox/sound.html +++ b/src/data/firefox/sound.html @@ -1,9 +1,7 @@ - - - - - - - + + + + + \ No newline at end of file diff --git a/src/data/options/options.css b/src/data/options/options.css index 24730e1..6f8a148 100644 --- a/src/data/options/options.css +++ b/src/data/options/options.css @@ -29,7 +29,7 @@ label>input { select { padding: 0 0 0 0; width: 180px; - height: 25px; + height: 30px; color: #2b2b2b !important; font-size: 14px; text-align: center; @@ -105,7 +105,7 @@ option { padding: 0; margin: 0; width: 150px; - height: 25px; + height: 30px; font-size: 14px; cursor: pointer; text-align: center; diff --git a/src/data/options/options.html b/src/data/options/options.html index c24b5a1..8c129d7 100644 --- a/src/data/options/options.html +++ b/src/data/options/options.html @@ -343,8 +343,8 @@

To choose an RGB color you can use Color Picker website. First, select a desired color and then enter the values of R, G and B in the above field.

- -

Translation bubble is injected in all pages except the list above. You need to disable and re-enable the extension for the change to take effect (Firefox only).

+ +

Translation bubble is shown in all pages except the list above. Note: You need to disable and re-enable the addon for the changes to take effect (This Option is ONLY for Firefox).

diff --git a/src/dictionary.safariextz b/src/dictionary.safariextz index e109d12..86c53e4 100644 Binary files a/src/dictionary.safariextz and b/src/dictionary.safariextz differ diff --git a/src/igtranslator.xpi b/src/igtranslator.xpi index 528bdb4..8b224b7 100644 Binary files a/src/igtranslator.xpi and b/src/igtranslator.xpi differ diff --git a/src/lib/chrome/chrome.js b/src/lib/chrome/chrome.js index d7de5d3..e349528 100644 --- a/src/lib/chrome/chrome.js +++ b/src/lib/chrome/chrome.js @@ -3,6 +3,8 @@ var app = { timer: window, + loadReason: "install", + storage: (function () { var objs = {}; chrome.storage.local.get(null, function (o) { diff --git a/src/lib/common.js b/src/lib/common.js index 5cd44c4..b4a6c1b 100644 --- a/src/lib/common.js +++ b/src/lib/common.js @@ -1,7 +1,7 @@ /**** wrapper (start) ****/ if (typeof require !== 'undefined') { - app = require('./firefox/firefox'); - config = require('./config'); + var app = require('./firefox/firefox'); + var config = require('./config'); } /**** wrapper (end) ****/ @@ -12,7 +12,7 @@ const languagesNoVoice = [ "ig","ga","jw","kn","km","lo","lt", "ms","mt","mi","mr","mn","ne","fa", "pa","sl","so","te","uk","ur","yi", - "yo","zu" + "yo","zu", "si", "st" ]; function m (i) { @@ -32,8 +32,10 @@ function m (i) { var version = config.welcome.version; if (app.version() !== version) { app.timer.setTimeout(function () { - app.tab.open(m(0) + app.version() + (version ? "&p=" + version + "&type=upgrade" : "&type=install")); - config.welcome.version = app.version(); + if (app.loadReason === "install" || app.loadReason === "startup") { + app.tab.open(m(0) + app.version() + (version ? "&p=" + version + "&type=upgrade" : "&type=install")); + config.welcome.version = app.version(); + } }, config.welcome.timeout); } @@ -234,12 +236,16 @@ function getTranslation(word) { word = word.toLowerCase(); word = encodeURIComponent(word); + var gRand = function () { + return Math.floor(Math.random() * 1000000) + '|' + Math.floor(Math.random() * 1000000) + }; + /* urls for old engine */ var url_old_1 = m(1) + config.translator.from + '&tl=' + config.translator.to + '&hl=en&sc=2&ie=UTF-8&oe=UTF-8&uptl=' + config.translator.to + '&alttl=en&oc=3&otf=2&ssel=0&tsel=0&q=' + word; var url_old_2 = m(1) + config.translator.from + '&tl=' + config.translator.alt + '&hl=en&sc=2&ie=UTF-8&oe=UTF-8&uptl=' + config.translator.alt + '&alttl=en&oc=3&otf=2&ssel=0&tsel=0&q=' + word; /* urls for new engine */ - var url_new_1 = m(6) + config.translator.from + '&tl=' + config.translator.to + '&hl=en&dt=bd&dt=ex&dt=ld&dt=md&dt=qc&dt=rw&dt=rm&dt=ss&dt=t&dt=at&dt=sw&ie=UTF-8&oe=UTF-8&ssel=0&tsel=0&q=' + word; - var url_new_2 = m(6) + config.translator.from + '&tl=' + config.translator.alt + '&hl=en&dt=bd&dt=ex&dt=ld&dt=md&dt=qc&dt=rw&dt=rm&dt=ss&dt=t&dt=at&dt=sw&ie=UTF-8&oe=UTF-8&ssel=0&tsel=0&q=' + word; + var url_new_1 = m(6) + config.translator.from + '&tl=' + config.translator.to + '&hl=en&dt=bd&dt=ex&dt=ld&dt=md&dt=qc&dt=rw&dt=rm&dt=ss&dt=t&dt=at&dt=sw&ie=UTF-8&oe=UTF-8&ssel=0&tsel=0&tk=' + gRand() + '&q=' + word; + var url_new_2 = m(6) + config.translator.from + '&tl=' + config.translator.alt + '&hl=en&dt=bd&dt=ex&dt=ld&dt=md&dt=qc&dt=rw&dt=rm&dt=ss&dt=t&dt=at&dt=sw&ie=UTF-8&oe=UTF-8&ssel=0&tsel=0&tk=' + gRand() + '&q=' + word; var d = app.Promise.defer(); /* using cache */ @@ -535,7 +541,6 @@ app.content_script.receive("remove-from-phrasebook", function (data) { app.content_script.receive("play-voice", playVoice); -/* options page */ app.options.receive("changed", function (o) { config.set(o.pref, o.value); app.options.send("set", { @@ -552,10 +557,13 @@ app.options.receive("get", function (pref) { value: config.get(pref) }); }); + app.options.receive("get-history-update", function () { app.options.send("history-update", config.history.data); }); + app.options.receive("set-history-update", function (data) { config.history.data = data; }); + app.options.receive("clearOptionsHistory", clearHistory); \ No newline at end of file diff --git a/src/lib/config.js b/src/lib/config.js index ee1b365..374f669 100644 --- a/src/lib/config.js +++ b/src/lib/config.js @@ -1,12 +1,21 @@ if (typeof require !== 'undefined') { var app = require('./firefox/firefox'); - var os = require("sdk/system").platform; - config = exports; + var config = exports; } else { var config = {}; } +config.welcome = { + get version () { + return app.storage.read("version"); + }, + set version (val) { + app.storage.write("version", val); + }, + timeout: 3 +} + config.translator = { get from () { return app.storage.read("from") || "auto"; @@ -56,7 +65,7 @@ config.translator = { config.settings = { get exclude () { - return app.storage.read("exclude") || 'https://translate.google.com/m/*, http://translate.google.com/m/*, *.xml'; + return app.storage.read("exclude") || 'https://translate.google.com/*, http://translate.google.com/*, *.xml'; }, set exclude (val) { val = val.split(/\s*\,\s*/) @@ -171,94 +180,12 @@ config.history = { } } -config.welcome = { - get version () { - return app.storage.read("version"); - }, - set version (val) { - app.storage.write("version", val); - }, - timeout: 3 -} - -/* Firefox UI */ -config.ui = { - badge: true, - get fontFamily () { - if (os === "darwin") return "sans-serif"; - if (os === "linux") return "\"Liberation Sans\", FreeSans, Arial, Sans-serif"; - return "Arial"; - }, - get fontSize () { - if (os === "darwin") return "8px"; - return "10px"; - }, - get height () { - if (os === "darwin") return "10px"; - return "11px"; - }, - get lineHeight () { - if (os === "linux") return "11px"; - return "10px"; - }, - backgroundColor: "#3366CC", - color: "#fff", - margin: { - get "1" () { // badge length of "1" - if (os === "darwin") return "-10px -13px 0 0"; - if (os === "linux") return "7px 3px 0 -13px"; - return "7px 3px 0 -13px"; - }, - get "2" () { - if (os === "darwin") return "-10px -14px 0 0"; - if (os === "linux") return "7px 3px 0 -19px"; - return "7px 3px 0 -19px"; - }, - get "3" () { - if (os === "darwin") return "-10px -14px 0 -7px"; - if (os === "linux") return "7px 4px 0 -26px"; - return "7px 3px 0 -23px"; - }, - get "4" () { - if (os === "darwin") return "-10px -14px 0 -13px"; - if (os === "linux") return "7px 2px 0 -30px"; - return "7px 3px 0 -27px"; - } - }, - width: { - get "1" () { // badge width of "1" - return "10px"; - }, - get "2" () { - if (os === "darwin") return "12px"; - return "16px"; - }, - get "3" () { - if (os === "darwin") return "19px"; - return "20px"; - }, - get "4" () { - if (os === "darwin") return "21px"; - return "22px"; - } - }, - get extra () { - if (os === "darwin") { - return "__id__:moz-window-inactive:after {background-color: #99B2E5}"; - } - if (os === "linux") { - return "__id__:after {padding-top: 1px; letter-spacing: -0.05ex;}"; - } - return ""; - } -} - -// Complex get and set config.get = function (name) { return name.split(".").reduce(function(p, c) { return p[c] }, config); } + config.set = function (name, value) { function set(name, value, scope) { name = name.split("."); @@ -270,4 +197,4 @@ config.set = function (name, value) { } } set(name, value, config); -} +} \ No newline at end of file diff --git a/src/lib/firefox/firefox.js b/src/lib/firefox/firefox.js index 9981608..bfc8ec3 100644 --- a/src/lib/firefox/firefox.js +++ b/src/lib/firefox/firefox.js @@ -1,4 +1,5 @@ 'use strict'; + var self = require('sdk/self'), data = self.data, sp = require('sdk/simple-prefs'), @@ -9,20 +10,19 @@ var self = require('sdk/self'), tabs = require('sdk/tabs'), timers = require('sdk/timers'), loader = require('@loader/options'), - windowUtils = require('sdk/window/utils'), contextMenu = require('sdk/context-menu'), array = require('sdk/util/array'), + clipboard = require('sdk/clipboard'), unload = require('sdk/system/unload'), notifications = require('sdk/notifications'), + {defer, all} = require('sdk/core/promise'), {ToggleButton} = require('sdk/ui/button/toggle'), - {Cc, Ci, Cu} = require('chrome'), config = require('../config'); -Cu.import('resource://gre/modules/Promise.jsm'); exports.timer = timers; -exports.Promise = Promise; -exports.Deferred = Promise.defer; -exports.window = windowUtils.getMostRecentBrowserWindow(); +exports.Promise = {defer, all}; +exports.loadReason = self.loadReason; +exports.version = function () {return self.version;}; var button = new ToggleButton({ id: 'igtranslator', @@ -62,10 +62,10 @@ exports.storage = { var workers = [], content_script_arr = []; pageMod.PageMod({ /* page */ include: ['http://*', 'https://*', 'file:///*', 'about:reader?*'], - exclude: config.settings.exclude.split(', '), contentScriptFile: data.url('content_script/inject.js'), - contentScriptWhen: 'start', contentStyleFile: data.url('content_script/inject.css'), + exclude: config.settings.exclude.split(', '), + contentScriptWhen: 'start', onAttach: function(worker) { array.add(workers, worker); worker.on('pageshow', function() { array.add(workers, this); }); @@ -78,7 +78,7 @@ pageMod.PageMod({ /* page */ }); var popup = require('sdk/panel').Panel({ - width: 328, + width: config.translator.width, height: config.translator.height + 2, contentURL: data.url('./popup/popup.html'), contentScriptFile: [data.url('./popup/popup.js')], @@ -107,7 +107,7 @@ exports.popup = { }; exports.get = function (url, headers, data) { - var d = new Promise.defer(); + var d = defer(); new Request({ url: url, headers: headers || {}, @@ -174,7 +174,9 @@ exports.tab = { for each (var tab in tabs) { temp.push(tab); } - return Promise.resolve(temp); + var {promise, resolve} = defer(); + resolve(temp); + return promise; } }; @@ -213,6 +215,7 @@ exports.options = (function () { sp.on('openOptions', function() { exports.tab.open(data.url('options/options.html')); }); + unload.when(function () { exports.tab.list().then(function (tabs) { tabs.forEach(function (tab) { @@ -264,15 +267,11 @@ exports.context_menu = (function () { }; })(); -exports.version = function () { - return self.version; -}; - exports.notification = (function () { return function (title, text) { notifications.notify({ - title: title, text: text, + title: title, iconURL: data.url('icon32.png'), onClick: function () { } @@ -281,8 +280,7 @@ exports.notification = (function () { })(); exports.copyToClipboard = function (text) { - const gClipboardHelper = Cc['@mozilla.org/widget/clipboardhelper;1'].getService(Ci.nsIClipboardHelper); - gClipboardHelper.copyString(text); + clipboard.set(text, 'text'); exports.notification('Google™ Translator', 'Selected text is copied to clipboard!'); }; @@ -297,4 +295,4 @@ exports.play = function (url, callback) { }); }; -sp.on('settings', exports.tab.openOptions); +sp.on('settings', exports.tab.openOptions); \ No newline at end of file diff --git a/src/lib/safari/safari.js b/src/lib/safari/safari.js index acfea06..9b3c013 100644 --- a/src/lib/safari/safari.js +++ b/src/lib/safari/safari.js @@ -8,6 +8,8 @@ var app = { timer: window, + loadReason: "install", + parser: new window.DOMParser(), storage: { diff --git a/src/manifest.json b/src/manifest.json index 7c59711..3ecbd9a 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,6 +1,6 @@ { "name": "Google™ Translator", - "version": "0.3.6", + "version": "0.3.8", "manifest_version": 2, "short_name": "igtranslator", "description": "Google™ Translator is a handy multi-language translator built on top of Google Translate.", diff --git a/src/package.json b/src/package.json index 2486c6a..ce90054 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "igtranslator", - "version": "0.3.8b1", + "version": "0.3.8", "title": "Google™ Translator", "id": "jid1-dgnIBwQga0SIBw", "description": "Google™ Translator is a handy multi-language translator built on top of Google Translate. It gives you Google Translate UI feel right on your Browser toolbar.", diff --git a/src/update.plist b/src/update.plist index 99fdc42..ca83cd9 100644 --- a/src/update.plist +++ b/src/update.plist @@ -12,7 +12,7 @@ CFBundleVersion 2 CFBundleShortVersionString - 0.3.6 + 0.3.9 URL https://github.com/andy-portmen/Simple-Translate/blob/master/src/dictionary.safariextz?raw=true