diff --git a/.gitignore b/.gitignore index ca6f01c..7db56de 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,13 @@ chrome/app/player firefox/data/player safari.safariextension/app/player -webgl/Release -webgl/vendors -webplayer/vendors +player/webgl/Release +player/vendors node_modules -**/.DS_Store \ No newline at end of file +**/.DS_Store +**/Thumbs.db + +**/*.crx +**/*.xpi \ No newline at end of file diff --git a/Gulpfile.js b/Gulpfile.js index 2fdfa30..d8223d1 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -6,45 +6,55 @@ var playersPath = { safari: 'safari.safariextension/app/player' }; -var webglOptions = { - base: 'webgl', - cwd: 'webgl' -}; - var webglFiles = [ 'connect.js', 'load.js', + 'verify-compatibility.js', 'window.html', 'TemplateData/*', - 'Release/*', - 'vendors/**/*', - 'js/*' + 'Release/*' ]; -var webplayerOptions = { - base: 'webplayer', - cwd: 'webplayer' -}; - var webplayerFiles = [ 'window.html', 'player.js', - 'WEBPLAYER.unity3d', - 'vendors/**/*', - 'TemplateData/*' + 'WEBPLAYER.unity3d' ]; +var playerFiles = [ + 'TemplateData/*', + 'js/*', + 'vendors/qdclient/qdclient.js', + 'vendors/offline/offline.js' +]; + +var webglTask = function(dest) { + gulp.src(webglFiles, {base: 'player/webgl', cwd: 'player/webgl'}) + .pipe(gulp.dest(dest)); + + playerTask(dest); +}; + +var webplayerTask = function(dest) { + gulp.src(webplayerFiles, {base: 'player/webplayer', cwd: 'player/webplayer'}) + .pipe(gulp.dest(dest)); + + playerTask(dest); +}; + +var playerTask = function(dest) { + gulp.src(playerFiles, {base: 'player', cwd: 'player'}) + .pipe(gulp.dest(dest)); +}; + gulp.task('chrome', function() { - gulp.src(webglFiles, webglOptions) - .pipe(gulp.dest(playersPath.chrome)); + webglTask(playersPath.chrome); }); gulp.task('firefox', function() { - gulp.src(webglFiles, webglOptions) - .pipe(gulp.dest(playersPath.firefox)); + webglTask(playersPath.firefox); }); gulp.task('safari', function() { - gulp.src(webplayerFiles, webplayerOptions) - .pipe(gulp.dest(playersPath.safari)); + webplayerTask(playersPath.safari); }); \ No newline at end of file diff --git a/chrome/app/main.js b/chrome/app/main.js deleted file mode 100644 index bde11cc..0000000 --- a/chrome/app/main.js +++ /dev/null @@ -1,50 +0,0 @@ -var app = { - chooser: null, - glosa: undefined, - loaded: false, - lastReq: { - url: null, - millis: null, - response: null - } -}; - -function onLoadPlayer() { - if ( app.glosa !== undefined ) - SendMessage('PlayerManager', 'catchGlosa', app.glosa); - - app.loaded = true; -} - -chrome.runtime.onMessage.addListener( - function(request, sender, sendResponse) { - if (request.selectedText === undefined) return; - - request.selectedText = encodeURI(request.selectedText); - - app.chooser = app.chooser || new qdClient.Chooser(); - - document.getElementById('loading-screen').style.display = 'block'; - app.chooser.choose( - app.lastReq.url, - app.lastReq.millis, - app.lastReq.response, - function (url) { - var start = new Date().getTime(); - qdClient.request(url + '?texto=' + request.selectedText, "GET", {}, - function(status, response) { - app.lastReq.response = status === 404 ? -1 : status; - app.lastReq.millis = (new Date().getTime() - start); - app.lastReq.url = url; - - app.glosa = response; - - if (app.loaded == true) - SendMessage('PlayerManager', 'catchGlosa', app.glosa); - - document.getElementById('loading-screen').style.display = 'none'; - }); - }); - }); - -chrome.runtime.sendMessage({ready: true}); diff --git a/chrome/app/middleware.js b/chrome/app/middleware.js new file mode 100644 index 0000000..ed63b7f --- /dev/null +++ b/chrome/app/middleware.js @@ -0,0 +1,10 @@ +window.addEventListener('load', function() { + chrome.runtime.onMessage.addListener( + function(request, sender, sendResponse) { + if (request.selectedText === undefined) return; + + VLibrasPlugin.translate(encodeURI(request.selectedText)); + }); + + chrome.runtime.sendMessage({ready: true}); +}); diff --git a/firefox/data/main.js b/firefox/data/main.js deleted file mode 100644 index 90b9fad..0000000 --- a/firefox/data/main.js +++ /dev/null @@ -1,47 +0,0 @@ -var app = { - chooser: null, - glosa: undefined, - loaded: false, - lastReq: { - url: null, - millis: null, - response: null - } -}; - -function onLoadPlayer() { - if ( app.glosa !== undefined ) - SendMessage('PlayerManager', 'catchGlosa', app.glosa); - - app.loaded = true; -} - -document.addEventListener('plugin:selectedText', function(e) { - if (e.detail === undefined) return; - - e.detail = encodeURI(e.detail); - - app.chooser = app.chooser || new qdClient.Chooser(); - - document.getElementById('loading-screen').style.display = 'block'; - app.chooser.choose( - app.lastReq.url, - app.lastReq.millis, - app.lastReq.response, - function (url) { - var start = new Date().getTime(); - - qdClient.request(url + '?texto=' + e.detail, "GET", {}, - function(status, response) { - app.lastReq.response = status === 404 ? -1 : status; - app.lastReq.millis = (new Date().getTime() - start); - app.lastReq.url = url; - - app.glosa = response; - - document.getElementById('loading-screen').style.display = 'none'; - if (app.loaded == true) - SendMessage('PlayerManager', 'catchGlosa', app.glosa); - }); - }); -}); diff --git a/firefox/data/middleware.js b/firefox/data/middleware.js new file mode 100644 index 0000000..bb774cb --- /dev/null +++ b/firefox/data/middleware.js @@ -0,0 +1,5 @@ +document.addEventListener('plugin:selectedText', function(e) { + if (e.detail === undefined) return; + + VLibrasPlugin.translate(encodeURI(e.detail)); +}); diff --git a/firefox/index.js b/firefox/index.js index 16b4bfd..93b1e0d 100644 --- a/firefox/index.js +++ b/firefox/index.js @@ -48,7 +48,7 @@ cm.Item({ // Page mod pm.PageMod({ include: self.data.url('player/window.html'), - contentScriptWhen: 'ready', + contentScriptWhen: 'end', contentScriptFile: self.data.url('delegator.js'), onAttach: function(worker) { app.worker = worker; diff --git a/player/.bowerrc b/player/.bowerrc new file mode 100644 index 0000000..b4eb29f --- /dev/null +++ b/player/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "vendors" +} diff --git a/player/TemplateData/default-cover.jpg b/player/TemplateData/default-cover.jpg new file mode 100644 index 0000000..86f23ce Binary files /dev/null and b/player/TemplateData/default-cover.jpg differ diff --git a/player/TemplateData/favicon.png b/player/TemplateData/favicon.png new file mode 100644 index 0000000..f6c7194 Binary files /dev/null and b/player/TemplateData/favicon.png differ diff --git a/player/TemplateData/fullbar.png b/player/TemplateData/fullbar.png new file mode 100644 index 0000000..4ee0a14 Binary files /dev/null and b/player/TemplateData/fullbar.png differ diff --git a/player/TemplateData/loadingbar.png b/player/TemplateData/loadingbar.png new file mode 100644 index 0000000..98e0d96 Binary files /dev/null and b/player/TemplateData/loadingbar.png differ diff --git a/player/TemplateData/progresslogo.png b/player/TemplateData/progresslogo.png new file mode 100644 index 0000000..a568710 Binary files /dev/null and b/player/TemplateData/progresslogo.png differ diff --git a/player/TemplateData/style.css b/player/TemplateData/style.css new file mode 100644 index 0000000..01513e4 --- /dev/null +++ b/player/TemplateData/style.css @@ -0,0 +1,69 @@ +html { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + +html, body, #canvas { + width: 100%; + height: 100%; + margin: 0; + overflow: hidden; + font-size: 70%; + line-height: 110%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; +} + +#loading-screen { + position: absolute; + top: 0; + left: 0; + display: none; + width: 100%; + height: 100%; + z-index: 9999; +} + +.message-box { + position: fixed; + top: -5em; + left: 0; + width: 100%; + padding: 1em; + font-size: 2em; + word-wrap: break-word; + color: #000; + opacity: 0; + -moz-transition: all .15s ease .15s; + -webkit-transition: all .15s ease .15s; + transition: all .15s ease .15s; + -moz-box-shadow: 0px 2px 5px #888888; + -webkit-box-shadow: 0px 2px 5px #888888; + box-shadow: 0px 2px 5px #888888; + z-index: 9998; +} + +.message-box.info { + background-color: #3b8bba; + color: #ffffff; +} + +.message-box.warning { + background-color: #f8ecad; + color: #7c6d1f; +} + +.message-box.success { + background-color: #d6e9c6; + color: #468847; +} + +.message-box.default { + background-color: #e6e6e6; + color: #8c8c8c; +} + +.message-box.active { + top: 0; + opacity: 1; +} \ No newline at end of file diff --git a/player/bower.json b/player/bower.json new file mode 100644 index 0000000..1bfaeed --- /dev/null +++ b/player/bower.json @@ -0,0 +1,15 @@ +{ + "name": "vlibras-player", + "version": "0.0.1", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "devDependencies": { + "qdclient": "git@git.lavid.ufpb.br:qdclient.git" + }, + "dependencies": {} +} diff --git a/player/js/loading.js b/player/js/loading.js new file mode 100644 index 0000000..0272c09 --- /dev/null +++ b/player/js/loading.js @@ -0,0 +1,19 @@ +(function (window, document, Message) { + + function Loading(selector, messageSelector) { + this.element = document.querySelector(selector); + this.message = new Message(messageSelector); + } + + Loading.prototype.show = function(message) { + this.element.style.display = 'block'; + this.message.show('info', message); + }; + + Loading.prototype.hide = function() { + this.element.style.display = 'none'; + this.message.hide(); + }; + + window.Loading = Loading; +})(window, document, window.Message); \ No newline at end of file diff --git a/player/js/message.js b/player/js/message.js new file mode 100644 index 0000000..8b2c12e --- /dev/null +++ b/player/js/message.js @@ -0,0 +1,50 @@ +(function(window, document) { + + function Message(selectors) { + this.element = document.querySelector(selectors); + + this.element.classList.add('message-box'); + + var self = this; + var closeElement = this.element.querySelector('.close'); + + if (closeElement) { + closeElement.addEventListener('click', function (e) { + self.hide(); + }); + } + + this.hide(); + } + + Message.LEVELS = ['info', 'warning', 'success', 'default']; + + Message.prototype.hide = function() { + this.element.classList.remove('active'); + + Message.LEVELS.forEach(function(level) { + this.element.classList.remove(level); + }, this); + }; + + Message.prototype.show = function(level, message, time) { + var self = this; + + level = Message.LEVELS.indexOf(level) == -1 ? 'info' : level; + + this.hide(); + + self.element.classList.add('active'); + self.element.classList.add(level); + self.element.querySelector('.message').innerHTML = message; + + if (time) { + setTimeout(function () { + self.hide(); + }, time + 1); + } + }; + + // Expose + window.Message = Message; +})(window, document); \ No newline at end of file diff --git a/player/js/vlibras-plugin.js b/player/js/vlibras-plugin.js new file mode 100644 index 0000000..80ba6d9 --- /dev/null +++ b/player/js/vlibras-plugin.js @@ -0,0 +1,73 @@ +(function(window, document, Loading, Message) { + function VLibrasPlugin() { + this.loaded = false; + this.chooser = new qdClient.Chooser(); + this.glosa = undefined; + this.loading = new Loading('#loading-screen', '#message-box'); + this.message = new Message('#message-box'); + this.lastReq = { + url: null, + millis: null, + response: null + }; + } + + VLibrasPlugin.prototype.sendGlosa = function(glosa) { + var glosa = glosa || this.glosa; + + if (glosa !== undefined && this.loaded === true) { + window.SendMessage('PlayerManager', 'catchGlosa', glosa); + } + }; + + VLibrasPlugin.prototype.translate = function(text) { + var self = this; + self.loading.show('Traduzindo...'); + self.chooser.choose(self.lastReq.url, self.lastReq.millis, self.lastReq.response, + function (url) { + var start = new Date().getTime(); + + if (!url) { + self.loading.hide(); + self.message.show('warning', 'Não foi possível se conectar ao servidor. Irei soletrar!', 3000); + + self.glosa = decodeURI(text).toUpperCase(); + self.sendGlosa(); + return; + } + + qdClient.request(url + '?texto=' + text, "GET", {}, + function(status, response) { + self.lastReq.response = status !== 200 ? -1 : status; + self.lastReq.millis = (new Date().getTime() - start); + self.lastReq.url = url; + + self.loading.hide(); + if (status !== 200) + self.message.show('warning', 'Não foi possível se conectar ao servidor. Irei soletrar!', 3000); + + self.glosa = response || decodeURI(text).toUpperCase(); + self.sendGlosa(); + }); + }); + }; + + VLibrasPlugin.prototype.showMessage = function(level, message, time) { + this.message.show(level, message, time); + }; + + VLibrasPlugin.prototype.hideMessage = function() { + this.message.hide(); + }; + + VLibrasPlugin.prototype.load = function() { + this.loaded = true; + this.sendGlosa(); + }; + + // Expose + window.VLibrasPlugin = new VLibrasPlugin(); + window.onLoadPlayer = function() { + this.VLibrasPlugin.load(); + }; +})(window, document, Loading, Message); diff --git a/player/webgl/TemplateData/UnityProgress.js b/player/webgl/TemplateData/UnityProgress.js new file mode 100644 index 0000000..0ed2beb --- /dev/null +++ b/player/webgl/TemplateData/UnityProgress.js @@ -0,0 +1,97 @@ +function UnityProgress (dom) { + this.progress = 0.0; + this.message = ""; + this.dom = dom; + + var parent = dom.parentNode; + + var background = document.createElement("div"); + background.style.background = "#FFFFFF"; + background.style.position = "absolute"; + parent.appendChild(background); + this.background = background; + + var logoImage = document.createElement("img"); + logoImage.src = "TemplateData/progresslogo.png"; + logoImage.style.position = "absolute"; + parent.appendChild(logoImage); + this.logoImage = logoImage; + + var progressFrame = document.createElement("img"); + progressFrame.src = "TemplateData/loadingbar.png"; + progressFrame.style.position = "absolute"; + parent.appendChild(progressFrame); + this.progressFrame = progressFrame; + + var progressBar = document.createElement("img"); + progressBar.src = "TemplateData/fullbar.png"; + progressBar.style.position = "absolute"; + parent.appendChild(progressBar); + this.progressBar = progressBar; + + var messageArea = document.createElement("p"); + messageArea.style.position = "absolute"; + parent.appendChild(messageArea); + this.messageArea = messageArea; + + + this.SetProgress = function (progress) { + if (this.progress < progress) + this.progress = progress; + this.messageArea.style.display = "none"; + this.progressFrame.style.display = "inline"; + this.progressBar.style.display = "inline"; + this.Update(); + } + + this.SetMessage = function (message) { + this.message = message; + this.background.style.display = "inline"; + this.logoImage.style.display = "inline"; + this.progressFrame.style.display = "none"; + this.progressBar.style.display = "none"; + this.Update(); + } + + this.Clear = function() { + this.background.style.display = "none"; + this.logoImage.style.display = "none"; + this.progressFrame.style.display = "none"; + this.progressBar.style.display = "none"; + } + + this.Update = function() { + this.background.style.top = this.dom.offsetTop + 'px'; + this.background.style.left = this.dom.offsetLeft + 'px'; + this.background.style.width = this.dom.offsetWidth + 'px'; + this.background.style.height = this.dom.offsetHeight + 'px'; + + var logoImg = new Image(); + logoImg.src = this.logoImage.src; + var progressFrameImg = new Image(); + progressFrameImg.src = this.progressFrame.src; + + this.logoImage.style.top = this.dom.offsetTop + (this.dom.offsetHeight * 0.5 - logoImg.height * 0.5) + 'px'; + this.logoImage.style.left = this.dom.offsetLeft + (this.dom.offsetWidth * 0.5 - logoImg.width * 0.5) + 'px'; + this.logoImage.style.width = logoImg.width+'px'; + this.logoImage.style.height = logoImg.height+'px'; + + this.progressFrame.style.top = this.dom.offsetTop + (this.dom.offsetHeight * 0.5 + logoImg.height * 0.5 + 10) + 'px'; + this.progressFrame.style.left = this.dom.offsetLeft + (this.dom.offsetWidth * 0.5 - progressFrameImg.width * 0.5) + 'px'; + this.progressFrame.width = progressFrameImg.width; + this.progressFrame.height = progressFrameImg.height; + + this.progressBar.style.top = this.progressFrame.style.top; + this.progressBar.style.left = this.progressFrame.style.left; + this.progressBar.width = progressFrameImg.width * Math.min(this.progress, 1); + this.progressBar.height = progressFrameImg.height; + + this.messageArea.style.top = this.progressFrame.style.top; + this.messageArea.style.left = 0; + this.messageArea.style.width = '100%'; + this.messageArea.style.textAlign = 'center'; + this.messageArea.innerHTML = this.message; + } + + this.Update (); +} \ No newline at end of file diff --git a/player/webgl/connect.js b/player/webgl/connect.js new file mode 100644 index 0000000..e332844 --- /dev/null +++ b/player/webgl/connect.js @@ -0,0 +1,40 @@ +// connect to canvas + var Module = { + TOTAL_MEMORY: 268435456, + filePackagePrefixURL: "Release/", + memoryInitializerPrefixURL: "Release/", + preRun: [], + postRun: [], + print: (function() { + return function(text) { + console.log (text); + }; + })(), + printErr: function(text) { + console.error (text); + }, + canvas: document.getElementById('canvas'), + progress: null, + setStatus: function(text) { + if (this.progress == null) + { + if (typeof UnityProgress != 'function') + return; + this.progress = new UnityProgress (canvas); + } + if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' }; + if (text === Module.setStatus.text) return; + this.progress.SetMessage (text); + var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); + if (m) + this.progress.SetProgress (parseInt(m[2])/parseInt(m[4])); + if (text === "") + this.progress.Clear() + }, + totalDependencies: 0, + monitorRunDependencies: function(left) { + this.totalDependencies = Math.max(this.totalDependencies, left); + Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); + } + }; + Module.setStatus('Downloading (0.0/1)'); diff --git a/player/webgl/load.js b/player/webgl/load.js new file mode 100644 index 0000000..53ce991 --- /dev/null +++ b/player/webgl/load.js @@ -0,0 +1,39 @@ +if (!(!Math.fround)) { + var script = document.createElement('script'); + script.src = "Release/WEBGL.js"; + document.body.appendChild(script); +} else { + var codeXHR = new XMLHttpRequest(); + codeXHR.open('GET', 'Release/WEBGL.js', true); + codeXHR.onload = function() { + var code = codeXHR.responseText; + if (!Math.fround) { +try { + console.log('optimizing out Math.fround calls'); + var m = /var ([^=]+)=global\.Math\.fround;/.exec(code); + var minified = m[1]; + if (!minified) throw 'fail'; + var startAsm = code.indexOf('// EMSCRIPTEN_START_FUNCS'); + var endAsm = code.indexOf('// EMSCRIPTEN_END_FUNCS'); + var asm = code.substring(startAsm, endAsm); + do { + var moar = false; // we need to re-do, as x(x( will not be fixed + asm = asm.replace(new RegExp('[^a-zA-Z0-9\\$\\_]' + minified + '\\(', 'g'), function(s) { moar = true; return s[0] + '(' }); + } while (moar); + code = code.substring(0, startAsm) + asm + code.substring(endAsm); + code = code.replace("'use asm'", "'almost asm'"); +} catch(e) { console.log('failed to optimize out Math.fround calls ' + e) } + } + + var blob = new Blob([code], { type: 'text/javascript' }); + codeXHR = null; + var src = URL.createObjectURL(blob); + var script = document.createElement('script'); + script.src = URL.createObjectURL(blob); + script.onload = function() { + URL.revokeObjectURL(script.src); + }; + document.body.appendChild(script); + }; + codeXHR.send(null); +} diff --git a/player/webgl/verify-compatibility.js b/player/webgl/verify-compatibility.js new file mode 100644 index 0000000..52e4d93 --- /dev/null +++ b/player/webgl/verify-compatibility.js @@ -0,0 +1,17 @@ +(function() { + var checkWebGLCompability = function() { + var canvas = document.createElement('canvas'); + var gl = canvas.getContext("webgl"); + if (!gl) { + gl = canvas.getContext("experimental-webgl"); + if (!gl) return false; + } + + return true; + }; + + if (!checkWebGLCompability()) { + VLibrasPlugin.showMessage('warning', 'O seu computador não suporta o WebGL. Porfavor atualizar os drivers de vídeo.'); + window.stop(); + }; +})(); \ No newline at end of file diff --git a/player/webgl/window.html b/player/webgl/window.html new file mode 100644 index 0000000..0bd6e68 --- /dev/null +++ b/player/webgl/window.html @@ -0,0 +1,36 @@ + + +
+ + +