Commit 3072c1583c49a513943513bfc098098c80d54d50

Authored by David Guilherme
0 parents
Exists in v2

Release 2.0

Showing 66 changed files with 1525 additions and 0 deletions   Show diff stats
.editorconfig 0 → 100644
  1 +++ a/.editorconfig
... ... @@ -0,0 +1,10 @@
  1 +root = true
  2 +
  3 +# Unix-style newlines with a newline ending every file
  4 +[*]
  5 +end_of_line = lf
  6 +insert_final_newline = true
  7 +
  8 +[{*.js, *.html, *.json}]
  9 +indent_style = space
  10 +indent_size = 2
0 11 \ No newline at end of file
... ...
.gitignore 0 → 100644
  1 +++ a/.gitignore
... ... @@ -0,0 +1,5 @@
  1 +node_modules
  2 +
  3 +chrome/app/player
  4 +firefox/data/player
  5 +safari.safariextension/app/player
... ...
chrome/app/middleware.js 0 → 100644
  1 +++ a/chrome/app/middleware.js
... ... @@ -0,0 +1,11 @@
  1 +window.addEventListener('load', function() {
  2 + chrome.runtime.onMessage.addListener(
  3 + function(request, sender, sendResponse) {
  4 + if (request.selectedText === undefined) return;
  5 +
  6 + window.plugin = (window.plugin || new VLibras.Plugin());
  7 + window.plugin.translate(request.selectedText);
  8 + });
  9 +
  10 + chrome.runtime.sendMessage({ready: true});
  11 +});
... ...
chrome/background.js 0 → 100644
  1 +++ a/chrome/background.js
... ... @@ -0,0 +1,51 @@
  1 +var popup = undefined;
  2 +var selectedText = undefined;
  3 +
  4 +// Creates the context menu to translate texts
  5 +chrome.contextMenus.create({
  6 + id: 'translate_contextmenu',
  7 + title: 'Traduzir \'%s\' para LIBRAS',
  8 + contexts: ['selection']
  9 +}, function () {
  10 + if ( chrome.runtime.lastError ) console.log(chrome.runtime.lastError.message);
  11 +});
  12 +
  13 +// Listening the event click
  14 +chrome.contextMenus.onClicked.addListener( function (info) {
  15 + selectedText = info.selectionText;
  16 +
  17 + // Creates the window if it exists
  18 + if ( popup === undefined ) {
  19 + chrome.windows.create({
  20 + url: "app/player/index.html",
  21 + top: 10,
  22 + left: 10,
  23 + width: 540,
  24 + height: 450,
  25 + type: "popup"
  26 + }, function (w) {
  27 + popup = w;
  28 + });
  29 + } else {
  30 + chrome.windows.update(popup.id, {focused: true}, function () {
  31 + chrome.runtime.sendMessage({selectedText: selectedText});
  32 + selectedText = undefined;
  33 + });
  34 + }
  35 +});
  36 +
  37 +// Frees variable if the popup doesn't to exist anymore
  38 +chrome.windows.onRemoved.addListener( function (windowId) {
  39 + if (windowId == popup.id) {
  40 + popup = undefined;
  41 + }
  42 +});
  43 +
  44 +// Listening the ready event of the popup
  45 +chrome.runtime.onMessage.addListener(
  46 + function(request, sender, sendResponse) {
  47 + if (request.ready === true && selectedText !== undefined) {
  48 + chrome.runtime.sendMessage({selectedText: selectedText});
  49 + selectedText = undefined;
  50 + }
  51 + });
... ...
chrome/icons/vlibras128.png 0 → 100644

19.8 KB

chrome/icons/vlibras16.png 0 → 100644

18 KB

chrome/icons/vlibras48.png 0 → 100644

18.4 KB

chrome/manifest.json 0 → 100644
  1 +++ a/chrome/manifest.json
... ... @@ -0,0 +1,20 @@
  1 +{
  2 + "manifest_version": 2,
  3 + "name": "VLibras",
  4 + "description": "Um tradutor de Português para LIBRAS.",
  5 + "version": "2.0.0",
  6 + "background": {
  7 + "scripts": ["background.js"],
  8 + "persistent": false
  9 + },
  10 + "permissions": [
  11 + "contextMenus",
  12 + "http://vlibras.lavid.ufpb.br/"
  13 + ],
  14 + "icons": {
  15 + "16": "icons/vlibras16.png",
  16 + "48": "icons/vlibras48.png",
  17 + "128": "icons/vlibras128.png"
  18 + },
  19 + "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
  20 +}
... ...
firefox/README.md 0 → 100644
  1 +++ a/firefox/README.md
... ... @@ -0,0 +1,2 @@
  1 +#VLibras Plugin
  2 +Um tradutor de Português para LIBRAS
0 3 \ No newline at end of file
... ...
firefox/data/delegator.js 0 → 100644
  1 +++ a/firefox/data/delegator.js
... ... @@ -0,0 +1,7 @@
  1 +'use strict';
  2 +
  3 +self.port.on('selectedText', function(selectedText) {
  4 + var event = new CustomEvent('plugin:selectedText', { 'detail': selectedText });
  5 +
  6 + document.dispatchEvent(event);
  7 +});
... ...
firefox/data/middleware.js 0 → 100644
  1 +++ a/firefox/data/middleware.js
... ... @@ -0,0 +1,6 @@
  1 +document.addEventListener('plugin:selectedText', function(e) {
  2 + if (e.detail === undefined) return;
  3 +
  4 + window.plugin = (window.plugin || new VLibras.Plugin());
  5 + window.plugin.translate(e.detail);
  6 +});
... ...
firefox/index.js 0 → 100644
  1 +++ a/firefox/index.js
... ... @@ -0,0 +1,62 @@
  1 +'use strict';
  2 +
  3 +// Imports
  4 +let self = require('sdk/self');
  5 +let { Ci } = require('chrome');
  6 +
  7 +let cm = require("sdk/context-menu");
  8 +let pm = require('sdk/page-mod');
  9 +
  10 +let browser = require('sdk/window/utils').getMostRecentBrowserWindow();
  11 +
  12 +//Globals
  13 +let app = {
  14 + window: null,
  15 + worker: null,
  16 + selectedText: ""
  17 +};
  18 +
  19 +// Context menu
  20 +cm.Item({
  21 + label: "Traduzir para LIBRAS",
  22 + context: cm.SelectionContext(),
  23 + contentScript: 'self.on("context", function () {' +
  24 + ' var text = window.getSelection().toString();' +
  25 + ' if (text.length > 20)' +
  26 + ' text = text.substr(0, 20) + "...";' +
  27 + ' return "Traduzir \'" + text + "\' para LIBRAS";' +
  28 + '});' +
  29 + 'self.on("click", function (node, data) {' +
  30 + ' self.postMessage( window.getSelection().toString() );' +
  31 + '});',
  32 + onMessage: function(selectedText) {
  33 + app.selectedText = selectedText;
  34 +
  35 + if ( !(app.window instanceof Ci.nsIDOMWindow) ) {
  36 + app.window = browser.open(
  37 + self.data.url('player/index.html'),
  38 + 'VLibras Plugin',
  39 + 'width=540,height=450,menubar=no,resizable=yes'
  40 + );
  41 + } else {
  42 + app.worker.port.emit('selectedText', app.selectedText);
  43 + app.window.focus();
  44 + }
  45 + }
  46 +});
  47 +
  48 +// Page mod
  49 +pm.PageMod({
  50 + include: self.data.url('player/index.html'),
  51 + contentScriptWhen: 'end',
  52 + contentScriptFile: self.data.url('delegator.js'),
  53 + onAttach: function(worker) {
  54 + app.worker = worker;
  55 +
  56 + app.worker.port.emit('selectedText', app.selectedText);
  57 +
  58 + app.worker.on('detach', function () {
  59 + app.worker = undefined;
  60 + });
  61 + }
  62 +});
... ...
firefox/package.json 0 → 100644
  1 +++ a/firefox/package.json
... ... @@ -0,0 +1,11 @@
  1 +{
  2 + "title": "VLibras Plugin",
  3 + "name": "vlibras-plugin",
  4 + "version": "2.0.0",
  5 + "description": "Um tradutor de Português para LIBRAS",
  6 + "main": "index.js",
  7 + "author": "LAViD",
  8 + "engines": {
  9 + "firefox": ">=38.0a1"
  10 + }
  11 +}
... ...
gulpfile.js 0 → 100644
  1 +++ a/gulpfile.js
... ... @@ -0,0 +1,40 @@
  1 +var gulp = require('gulp');
  2 +var webpack = require('webpack-stream');
  3 +
  4 +var webpackConfig = require('./webpack.config.js');
  5 +
  6 +var options = {
  7 + dest: {
  8 + chrome: 'chrome/app/player',
  9 + firefox: 'firefox/data/player',
  10 + safari: 'safari.safariextension/app/player'
  11 + }
  12 +};
  13 +
  14 +function build(target) {
  15 + var destPath = options.dest[target];
  16 +
  17 + gulp.src('node_modules/vlibras/src/target/**/*')
  18 + .pipe(gulp.dest(destPath + '/target'));
  19 +
  20 + gulp.src('plugin/index.js')
  21 + .pipe(webpack(webpackConfig))
  22 + .pipe(gulp.dest(destPath));
  23 +
  24 + gulp.src(['index.html', 'assets/*'], {cwd: 'plugin', base: 'plugin'})
  25 + .pipe(gulp.dest(destPath));
  26 +}
  27 +
  28 +gulp.task('build:chrome', function () {
  29 + build('chrome');
  30 +});
  31 +
  32 +gulp.task('build:firefox', function () {
  33 + build('firefox');
  34 +});
  35 +
  36 +gulp.task('build:safari', function () {
  37 + build('safari');
  38 +});
  39 +
  40 +gulp.task('build', ['build:chrome', 'build:firefox', 'build:safari']);
... ...
keys/vlibrasplugin-chrome.pem 0 → 100644
  1 +++ a/keys/vlibrasplugin-chrome.pem
... ... @@ -0,0 +1,28 @@
  1 +-----BEGIN PRIVATE KEY-----
  2 +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8UI+z9pRhF8Kv
  3 +WC3Y2eI41b4AJeROjrO3rVeBG+FYjMuOB0r1byFUlebGP/Nep7nZ9eEUZ4E71lkp
  4 +WDyYLfZTb+gum6MQAeh8Wd7aBh9qSa4ru08ieu/8HxmHdfUFpWph3yPMV0TdAXVh
  5 +sbMLWcvzu+AmEkPM09KtXENyAOkR63ncll7HtmGFdxicTzNWuIhrvrhsd1xtuS1c
  6 +g4vk1XEJ5mcSnVLVGojAI8uwY4QEAGC2bUMzmD6mtZxySHu5XxNnk1xFdTxebd1K
  7 +4u0HyDgpY7epRsnkYHQq9HZ7Smet2JW4tHmd/5nPMZXFztZ/bUSuOqAmXvmLXvmw
  8 +JSpVnEENAgMBAAECggEAVCmFMB8iDYq6/fbg9qvaSSBt/E7zDJEGjS6xjwhQ3GyA
  9 +hQeJXsu+D7m3HB90u3cmvtz/LUldHssbqji/TBwunPfEwx/X7s2LhBf+W16lJ7Gq
  10 +X+0k3vomy31ywXHcght9wiQiMa9HHacLORBcPtRxLItpEFrVZnO9ErHLiuYRRGo+
  11 +EKP79o1dVZ5kldJ7toB4ok+KIDu2PJJShj4nXj7mKNlGZPH2hYn+NG7ZLFOjUp09
  12 +AKjTIE5WADt5bOKN9Wo2HiCG63zLZsaJmeYh2v3TxnpAj+W/TMxV/y0kIe7gzqw1
  13 +2qxdBmLBILNM8AkwadpbJRuC6aynd41sqejix3uemQKBgQDzONGl0Yf8fg5EyX3r
  14 +w/OldzZv/Comy6Ka/aq8I88clFBlEoD2os+lF6IDAgMj102awjiI+fxOe81C7Pza
  15 +a5eGHeq3qaE0E7v7ggcW7YXlFs9YC6RikKEkGCFnnaxeBf+/iXICcf32GzZkSow2
  16 +JTedIJIbu/oca2UFpVsK4inkHwKBgQDGNUZMmJ1ca4WdpmP6mUCwqEgOZ+UcG/3K
  17 +4Sy0BtJOB1wVoQOzM1q2FUurCqps81cghUbtJyeRk4y4eI1rOEbz8m0UB0hWyEq1
  18 +pJJiz0nei7ficAIHO5e2elDV2lJ7KNxYeb3YN2NXbGmwmsI/IoudPp+wghnl4Xns
  19 +2JcBFZdVUwKBgQCBDcb/6xvyt5gum5M7BDBFvemepfhfuXFAOBTd20pL6c52ssjH
  20 +FUCEYvPOEMVFwTomQaPp2msr4bjaKBFKfAhcW4dtiI5Gqan3G9lTKxj+o4nFN/gz
  21 +bHZ0RnGDH0CUay52nSFndsDAU1QbBws6t6i4sM2V9boSVlG2GzUhozuDFQKBgG2P
  22 +kTZRvdoSTR9hlC43fDyqKHpeD5TEHDuC0HUKuEENbGdAQ41Qu7med98p3B6xO93s
  23 +DdKVLBgaGVT2viUgTIgX3xeNFv1xZWqWd5xKvKhZTuHJzDU3SZtCbWBod+NAKNx3
  24 +HutfYng2ow1N3kWL0OSwcxDcOXiKdBzpdD7TMn2lAoGAH3xcQ9pI1aCeNxrnyvsJ
  25 +1EFlSX+3HQvjd9JOVemiVd6jP5SbrM6DplzimYPVmJhlAcq+wi8/dHyOGMRCb7ZV
  26 +Yv44hSheny/RhfMcePwubLBhVULRrdg2LWOEnSgrLIWNe2CCJ+xzgr2mEM+vGazI
  27 +zVWbI5s+shUi96/ZSZMjxGo=
  28 +-----END PRIVATE KEY-----
... ...
package.json 0 → 100644
  1 +++ a/package.json
... ... @@ -0,0 +1,20 @@
  1 +{
  2 + "name": "vlibras-plugin",
  3 + "version": "0.0.1",
  4 + "dependencies": {
  5 + "inherits": "^2.0.1",
  6 + "nouislider": "^8.3.0",
  7 + "vlibras": "~0.0.1"
  8 + },
  9 + "devDependencies": {
  10 + "css-loader": "^0.23.1",
  11 + "es6-promise": "^3.1.2",
  12 + "gulp": "^3.9.1",
  13 + "node-sass": "^3.4.2",
  14 + "raw-loader": "^0.5.1",
  15 + "sass-loader": "^3.1.2",
  16 + "style-loader": "^0.13.0",
  17 + "webpack": "^1.12.14",
  18 + "webpack-stream": "^3.1.0"
  19 + }
  20 +}
... ...
plugin/Plugin.js 0 → 100644
  1 +++ a/plugin/Plugin.js
... ... @@ -0,0 +1,72 @@
  1 +var VLibras = require('vlibras');
  2 +
  3 +var InfoScreen = require('components/InfoScreen');
  4 +var InfoScreenBtn = require('components/InfoScreenBtn');
  5 +var Controls = require('components/Controls');
  6 +var Progress = require('components/Progress');
  7 +var MessageBox = require('components/MessageBox');
  8 +
  9 +function Plugin() {
  10 + this.player = new VLibras.Player({
  11 + progress: Progress
  12 + });
  13 +
  14 + this.element = document.querySelector('[vp]');
  15 + this.controls = new Controls(this.player);
  16 + this.info = new InfoScreen();
  17 + this.infoBtn = new InfoScreenBtn(this.info);
  18 + this.messageBox = new MessageBox();
  19 + this.loadingRef = null;
  20 +
  21 + this.messageBox.load(this.element.querySelector('[vp-message-box]'));
  22 + this.player.load(this.element);
  23 +
  24 + this.player.on('load', function () {
  25 + // Loading components
  26 + this.controls.load(this.element.querySelector('[vp-controls]'));
  27 + this.info.load(this.element.querySelector('[vp-info-screen]'));
  28 + this.infoBtn.load(this.element.querySelector('[vp-info-screen-btn]'));
  29 + }.bind(this));
  30 +
  31 + this.info.on('show', function () {
  32 + this.player.pause();
  33 + }.bind(this));
  34 +
  35 + this.player.on('translate:start', function () {
  36 + this.loadingRef = this.messageBox.show('info', 'Traduzindo...');
  37 + }.bind(this));
  38 +
  39 + this.player.on('translate:end', function () {
  40 + this.messageBox.hide(this.loadingRef);
  41 + }.bind(this));
  42 +
  43 + this.player.on('error', function (err) {
  44 + switch(err) {
  45 + case 'compatibility_error':
  46 + this.messageBox.show(
  47 + 'warning',
  48 + 'O seu computador não suporta o WebGL. Por favor, atualize os drivers de vídeo.'
  49 + );
  50 + break;
  51 + case 'translation_error':
  52 + this.messageBox.show(
  53 + 'warning',
  54 + 'Não foi possivel traduzir. Por favor, verifique sua internet.',
  55 + 3000
  56 + );
  57 + break;
  58 + case 'internal_error':
  59 + this.messageBox.show(
  60 + 'warning',
  61 + 'Ops! Ocorreu um problema, por favor entre em contato com a gente.'
  62 + );
  63 + break;
  64 + }
  65 + }.bind(this));
  66 +};
  67 +
  68 +Plugin.prototype.translate = function (text) {
  69 + this.player.translate(text);
  70 +};
  71 +
  72 +module.exports = Plugin;
... ...
plugin/assets/About.png 0 → 100644

1.63 KB

plugin/assets/Base.png 0 → 100644

14.9 KB

plugin/assets/CamaraDosDps.png 0 → 100644

9.5 KB

plugin/assets/Close.png 0 → 100644

1.16 KB

plugin/assets/CounterOff.png 0 → 100644

414 Bytes

plugin/assets/CounterOn.png 0 → 100644

359 Bytes

plugin/assets/Fast.png 0 → 100644

23.8 KB

plugin/assets/Gov.png 0 → 100644

33.8 KB

plugin/assets/LSD.png 0 → 100644

15.3 KB

plugin/assets/Lavid.png 0 → 100644

14.6 KB

plugin/assets/Pause.png 0 → 100644

269 Bytes

plugin/assets/Play.png 0 → 100644

23.3 KB

plugin/assets/RNP.png 0 → 100644

10.2 KB

plugin/assets/Repeat.png 0 → 100644

1.35 KB

plugin/assets/Slow.png 0 → 100644

23.6 KB

plugin/assets/Stop.png 0 → 100644

22.8 KB

plugin/assets/Subtitles.png 0 → 100644

873 Bytes

plugin/assets/SubtitlesDisabled.png 0 → 100644

1.07 KB

plugin/assets/ToLeft.png 0 → 100644

648 Bytes

plugin/assets/ToRight.png 0 → 100644

661 Bytes

plugin/assets/UF.png 0 → 100644

19.1 KB

plugin/assets/UFCG.png 0 → 100644

17.9 KB

plugin/assets/favicon.png 0 → 100644

18.4 KB

plugin/assets/logo.png 0 → 100644

4.3 KB

plugin/assets/progresslogo.png 0 → 100644

20.7 KB

plugin/components/Controls/controls.html 0 → 100644
  1 +++ a/plugin/components/Controls/controls.html
... ... @@ -0,0 +1,6 @@
  1 +<span class="controls-play"></span>
  2 +<span class="controls-stop"></span>
  3 +<div class="controls-slider">
  4 + <div class="slider"></div>
  5 +</div>
  6 +<span class="controls-subtitles"></span>
... ...
plugin/components/Controls/controls.scss 0 → 100644
  1 +++ a/plugin/components/Controls/controls.scss
... ... @@ -0,0 +1,57 @@
  1 +@import '~scss/flexbox';
  2 +
  3 +.controls {
  4 + @include flexbox;
  5 + @include align-items(center);
  6 +
  7 + padding: 10px;
  8 + width: calc(100% - 10px);
  9 + height: 60px;
  10 + margin: 0 5px;
  11 +
  12 + background: url(assets/Base.png) no-repeat center center;
  13 + background-size: 100% 100%;
  14 +
  15 + .controls-play, .controls-slider, .controls-subtitles {
  16 + margin: 0 10px;
  17 + }
  18 +
  19 + .controls-play:before { content: url(assets/Play.png); }
  20 + &.playing .controls-play:before { content: url(assets/Pause.png); }
  21 + &.stopped .controls-play:before { content: url(assets/Repeat.png); }
  22 + .controls-stop:before { content: url(assets/Stop.png); }
  23 + &.subtitles .controls-subtitles:before { content: url(assets/Subtitles.png) }
  24 + .controls-subtitles:before { content: url(assets/SubtitlesDisabled.png) }
  25 +
  26 + .controls-slider {
  27 + @include flexbox;
  28 + @include align-items(center);
  29 +
  30 + -webkit-appearance: none;
  31 + width: 100%;
  32 + margin: 2.5px 0;
  33 + height: 7px;
  34 + background-color: transparent;
  35 +
  36 + &:before { content: url(assets/Slow.png); }
  37 + &:after { padding-left: 5px; content: url(assets/Fast.png); }
  38 +
  39 + .slider {
  40 + width: 100%;
  41 + height: 7px;
  42 +
  43 + &.noUi-target { box-shadow: none; border: 0; }
  44 + &.noUi-connect { background-color: #fff; }
  45 + .noUi-background { background-color: #333; box-shadow: none; }
  46 + .noUi-handle {
  47 + width: 20px;
  48 + height: 20px;
  49 + left: -8px;
  50 + top: -8px;
  51 + border-radius: 50%;
  52 + }
  53 +
  54 + .noUi-handle:after, .noUi-handle:before { display: none; }
  55 + }
  56 + }
  57 +}
... ...
plugin/components/Controls/index.js 0 → 100644
  1 +++ a/plugin/components/Controls/index.js
... ... @@ -0,0 +1,74 @@
  1 +var noUiSlider = require('nouislider');
  2 +require('nouislider/distribute/nouislider.min.css');
  3 +
  4 +var controlsTpl = require('./controls.html');
  5 +require('./controls.scss');
  6 +
  7 +function Controls(player) {
  8 + this.player = player;
  9 +
  10 + this.player.on('animation:play', function () {
  11 + console.log('animation:play');
  12 + this.element.classList.remove('stopped');
  13 + this.element.classList.add('playing');
  14 + }.bind(this));
  15 +
  16 + this.player.on('animation:pause', function () {
  17 + console.log('animation:pause');
  18 + this.element.classList.remove('playing');
  19 + this.element.classList.remove('stopped');
  20 + }.bind(this));
  21 +
  22 + this.player.on('animation:end', function () {
  23 + console.log('animation:end');
  24 + this.element.classList.remove('playing');
  25 + this.element.classList.add('stopped');
  26 + }.bind(this));
  27 +}
  28 +
  29 +Controls.prototype.load = function (element) {
  30 + this.element = element;
  31 + this.element.innerHTML = controlsTpl;
  32 + this.element.classList.add('controls');
  33 + this.element.classList.add('subtitles');
  34 +
  35 + var play = this.element.querySelector('.controls-play');
  36 + var stop = this.element.querySelector('.controls-stop');
  37 + var slider = this.element.querySelector('.controls-slider .slider');
  38 + var subtitles = this.element.querySelector('.controls-subtitles');
  39 +
  40 + play.addEventListener('click', function () {
  41 + if (this.element.classList.contains('playing')) {
  42 + this.player.pause();
  43 + } else if(this.element.classList.contains('stopped')) {
  44 + this.player.repeat();
  45 + } else {
  46 + this.player.continue();
  47 + }
  48 + }.bind(this));
  49 +
  50 + stop.addEventListener('click', function () {
  51 + this.player.stop();
  52 + }.bind(this));
  53 +
  54 + noUiSlider.create(slider, {
  55 + start: 1.1,
  56 + step: 0.05,
  57 + connect: 'lower',
  58 + range: {
  59 + min: 0,
  60 + max: 2
  61 + }
  62 + });
  63 +
  64 + slider.noUiSlider.on('update', function (value) {
  65 + this.player.setSpeed(Number(value[0]));
  66 + }.bind(this));
  67 +
  68 + subtitles.addEventListener('click', function () {
  69 + this.element.classList.toggle('subtitles');
  70 + this.player.toggleSubtitle();
  71 + }.bind(this));
  72 +};
  73 +
  74 +module.exports = Controls;
... ...
plugin/components/InfoScreen/index.js 0 → 100644
  1 +++ a/plugin/components/InfoScreen/index.js
... ... @@ -0,0 +1,66 @@
  1 +var inherits = require('inherits');
  2 +var EventEmitter = require('events').EventEmitter;
  3 +
  4 +var infoScreenTpl = require('./info-screen.html');
  5 +require('./info-screen.scss');
  6 +
  7 +function InfoScreen() {
  8 + this.visible = false;
  9 +}
  10 +
  11 +inherits(InfoScreen, EventEmitter);
  12 +
  13 +InfoScreen.prototype.load = function (element) {
  14 + this.element = element;
  15 + this.element.innerHTML = infoScreenTpl;
  16 + this.element.classList.add('info-screen');
  17 +
  18 + var main = this.element.querySelector('#info-main');
  19 + var realizadores = this.element.querySelector('#info-realizadores');
  20 + var left = this.element.querySelector('.arrow-left');
  21 + var right = this.element.querySelector('.arrow-right');
  22 + var bullets = this.element.querySelectorAll('.info-bullet');
  23 +
  24 + left.addEventListener('click', function() {
  25 + realizadores.classList.remove('active');
  26 + main.classList.add('active');
  27 +
  28 + this.classList.remove('active');
  29 + right.classList.add('active');
  30 +
  31 + bullets[1].classList.remove('active');
  32 + bullets[0].classList.add('active');
  33 + });
  34 +
  35 + right.addEventListener('click', function() {
  36 + main.classList.remove('active');
  37 + realizadores.classList.add('active');
  38 +
  39 + this.classList.remove('active');
  40 + left.classList.add('active');
  41 +
  42 + bullets[0].classList.remove('active');
  43 + bullets[1].classList.add('active');
  44 + });
  45 +
  46 + this.hide();
  47 +};
  48 +
  49 +InfoScreen.prototype.toggle = function () {
  50 + if (this.visible) this.hide();
  51 + else this.show();
  52 +};
  53 +
  54 +InfoScreen.prototype.hide = function () {
  55 + this.visible = false;
  56 + this.element.classList.remove('active');
  57 + this.emit('hide');
  58 +};
  59 +
  60 +InfoScreen.prototype.show = function () {
  61 + this.visible = true;
  62 + this.element.classList.add('active');
  63 + this.emit('show');
  64 +};
  65 +
  66 +module.exports = InfoScreen;
... ...
plugin/components/InfoScreen/info-screen.html 0 → 100644
  1 +++ a/plugin/components/InfoScreen/info-screen.html
... ... @@ -0,0 +1,35 @@
  1 +<div class="arrow arrow-left">
  2 + <img src="assets/ToLeft.png" />
  3 +</div>
  4 +<div id="info-tabset">
  5 + <div id="info-main" class="info-tab active">
  6 + <div id="info-logo">
  7 + <img src="assets/logo.png"/>
  8 + </div>
  9 + <div id="info-meta">
  10 + <p>Versão 2.0.0</p>
  11 + <a href="http://vlibras.gov.br" target="_blank">vlibras.gov.br</a>
  12 + </div>
  13 + <div id="info-text">
  14 + <p>O VLibras é uma ferramenta aberta de distribuição livre, desenvolvida para melhorar o acesso à informação das pessoas surdas brasileiras.</p>
  15 + <p>Qualquer dúvida ou questionamento, envie uma mensagem para o Núcleo de Pesquisa e Extensão LAViD - Centro de Informática - UFPB através do e-mail. contato@lavid.ufpb.br</p>
  16 + </div>
  17 + </div>
  18 + <div id="info-realizadores" class="info-tab">
  19 + <h2>Realizadores</h2>
  20 + <img id="gov-logo" class="logo" src="assets/Gov.png" /><br /><br />
  21 + <img class="logo" src="assets/Lavid.png" />
  22 + <img id="ufpb-logo" class="logo" src="assets/UF.png" />
  23 + <img class="logo" src="assets/RNP.png" /><br /><br />
  24 + <img class="logo" src="assets/UFCG.png" />
  25 + <img class="logo" src="assets/LSD.png" />
  26 + <img class="logo" src="assets/CamaraDosDps.png" />
  27 + </div>
  28 + <div id="info-tab-bullets">
  29 + <span class="info-bullet active"></span>
  30 + <span class="info-bullet"></span>
  31 + </div>
  32 +</div>
  33 +<div class="arrow arrow-right active">
  34 + <img src="assets/ToRight.png" />
  35 +</div>
... ...
plugin/components/InfoScreen/info-screen.scss 0 → 100644
  1 +++ a/plugin/components/InfoScreen/info-screen.scss
... ... @@ -0,0 +1,116 @@
  1 +.info-screen {
  2 + position: absolute;
  3 + left: 0;
  4 + top: 0;
  5 +
  6 + padding: 1em;
  7 +
  8 + width: 100%;
  9 + height: 100%;
  10 +
  11 + background-color: white;
  12 + color: black;
  13 + font-family: Arial, sans-serif;
  14 + text-align: center;
  15 +
  16 + align-items: center;
  17 + -webkit-align-items: center;
  18 + font-size: 16px;
  19 +
  20 + display: none;
  21 +
  22 + -webkit-box-sizing: border-box;
  23 + -moz-box-sizing: border-box;
  24 + box-sizing: border-box;
  25 +
  26 + &.active {
  27 + display: -webkit-flex;
  28 + display: flex;
  29 + }
  30 +
  31 + .arrow {
  32 + flex-grow: 1;
  33 + -webkit-flex-grow: 1;
  34 + visibility: hidden;
  35 + }
  36 +
  37 + .arrow.active {
  38 + visibility: visible;
  39 + }
  40 +
  41 + #info-tabset {
  42 + flex-grow: 4;
  43 + display: -webkit-flex;
  44 + display: flex;
  45 + flex-direction: column;
  46 + -webkit-flex-direction: column;
  47 + padding: 0 1em;
  48 + }
  49 +
  50 + #info-main {
  51 + flex-direction: column;
  52 + -webkit-flex-direction: column;
  53 + }
  54 +
  55 + #info-realizadores {
  56 + flex-direction: row;
  57 + -webkit-flex-direction: row;
  58 + flex-wrap: wrap;
  59 + -webkit-flex-wrap: wrap;
  60 + justify-content: center;
  61 + -webkit-justify-content: center;
  62 + }
  63 +
  64 + #info-realizadores .logo {
  65 + margin-left: 2em;
  66 + width: 20%;
  67 + min-width: 60px;
  68 + max-width: 80px;
  69 + }
  70 +
  71 + #gov-logo.logo {
  72 + width: 100%;
  73 + margin-left: 0;
  74 + min-width: 200px;
  75 + max-width: 500px;
  76 + }
  77 +
  78 + #ufpb-logo {
  79 + width: 10%;
  80 + }
  81 +
  82 + .info-tab {
  83 + flex-grow: 3;
  84 + -webkit-flex-grow: 3;
  85 + display: none;
  86 + }
  87 +
  88 + .info-tab.active {
  89 + display: block;
  90 + }
  91 +
  92 + #info-meta p {
  93 + margin: .5em 0 0;
  94 + }
  95 +
  96 + #info-meta a {
  97 + text-decoration: none;
  98 + }
  99 +
  100 + .info-bullet:before {
  101 + content: url(assets/CounterOff.png);
  102 + }
  103 +
  104 + .info-bullet.active:before {
  105 + content: url(assets/CounterOn.png);
  106 + }
  107 +
  108 + #info-tab-bullets {
  109 + width: 100%;
  110 + height: 16px;
  111 + text-align: center;
  112 + flex-grow: 1;
  113 + -webkit-flex-grow: 1;
  114 + margin-top: 10%;
  115 + }
  116 +}
... ...
plugin/components/InfoScreenBtn/index.js 0 → 100644
  1 +++ a/plugin/components/InfoScreenBtn/index.js
... ... @@ -0,0 +1,17 @@
  1 +require('./info-screen-btn.scss');
  2 +
  3 +function InfoScreenBtn(screen) {
  4 + this.screen = screen;
  5 +}
  6 +
  7 +InfoScreenBtn.prototype.load = function (element) {
  8 + this.element = element;
  9 + this.element.classList.add('info-screen-btn');
  10 +
  11 + this.element.addEventListener('click', function () {
  12 + this.element.classList.toggle('active');
  13 + this.screen.toggle();
  14 + }.bind(this));
  15 +};
  16 +
  17 +module.exports = InfoScreenBtn;
... ...
plugin/components/InfoScreenBtn/info-screen-btn.scss 0 → 100644
  1 +++ a/plugin/components/InfoScreenBtn/info-screen-btn.scss
... ... @@ -0,0 +1,7 @@
  1 +.info-screen-btn:before {
  2 + content: url(assets/About.png);
  3 +}
  4 +
  5 +.info-screen-btn.active:before {
  6 + content: url(assets/Close.png);
  7 +}
... ...
plugin/components/MessageBox/index.js 0 → 100644
  1 +++ a/plugin/components/MessageBox/index.js
... ... @@ -0,0 +1,56 @@
  1 +require('./message-box.scss');
  2 +
  3 +var messageBoxTlp = '<span class="message"></span>';
  4 +
  5 +function MessageBox() {
  6 + this.element = null;
  7 + this.message = null;
  8 +}
  9 +
  10 +MessageBox.LEVELS = ['info', 'warning', 'success', 'default'];
  11 +
  12 +MessageBox.prototype.load = function (element) {
  13 + this.element = element;
  14 + this.element.classList.add('message-box');
  15 + this.element.innerHTML = messageBoxTlp;
  16 +
  17 + this.hide();
  18 +};
  19 +
  20 +MessageBox.prototype.hide = function(message) {
  21 + if (message !== this.message) return;
  22 +
  23 + this.message = null;
  24 + this.element.classList.remove('active');
  25 +
  26 + MessageBox.LEVELS.forEach(function(level) {
  27 + this.element.classList.remove(level);
  28 + }, this);
  29 +};
  30 +
  31 +MessageBox.prototype.show = function(level, message, time) {
  32 + var self = this;
  33 +
  34 + level = MessageBox.LEVELS.indexOf(level) == -1 ? 'info' : level;
  35 +
  36 + this.hide();
  37 +
  38 + self.element.classList.add('active');
  39 + self.element.classList.add(level);
  40 + self.element.querySelector('.message').innerHTML = message;
  41 +
  42 + self.message = {
  43 + text: message
  44 + };
  45 +
  46 + var ref = self.message;
  47 + if (time) {
  48 + setTimeout(function () {
  49 + self.hide(ref);
  50 + }, time + 1);
  51 + }
  52 +
  53 + return this.message;
  54 +};
  55 +
  56 +module.exports = MessageBox;
... ...
plugin/components/MessageBox/message-box.scss 0 → 100644
  1 +++ a/plugin/components/MessageBox/message-box.scss
... ... @@ -0,0 +1,46 @@
  1 +.message-box {
  2 + position: fixed;
  3 + top: -5em;
  4 + left: 0;
  5 + width: 100%;
  6 + padding: 1em;
  7 + font-size: 1em;
  8 + word-wrap: break-word;
  9 + color: #000;
  10 + opacity: 0;
  11 + -moz-transition: all .15s ease .15s;
  12 + -webkit-transition: all .15s ease .15s;
  13 + transition: all .15s ease .15s;
  14 + -moz-box-shadow: 0px 2px 5px #888888;
  15 + -webkit-box-shadow: 0px 2px 5px #888888;
  16 + box-shadow: 0px 2px 5px #888888;
  17 +
  18 + &.active {
  19 + top: 0;
  20 + opacity: 1;
  21 + }
  22 +
  23 + &.info {
  24 + background-color: #3b8bba;
  25 + color: #ffffff;
  26 + }
  27 +
  28 + &.warning {
  29 + background-color: #f8ecad;
  30 + color: #7c6d1f;
  31 + }
  32 +
  33 + &.success {
  34 + background-color: #d6e9c6;
  35 + color: #468847;
  36 + }
  37 +
  38 + &.default {
  39 + background-color: #e6e6e6;
  40 + color: #8c8c8c;
  41 + }
  42 +
  43 + a {
  44 + color: inherit;
  45 + }
  46 +}
... ...
plugin/components/Progress/index.js 0 → 100644
  1 +++ a/plugin/components/Progress/index.js
... ... @@ -0,0 +1,40 @@
  1 +require('./progress.scss');
  2 +var progressTpl = require('./progress.html');
  3 +
  4 +function Progress(wrapper) {
  5 + this.progress = 0.0;
  6 + this.message = '';
  7 +
  8 + this.element = document.createElement('div');
  9 + this.element.classList.add('progress');
  10 + this.element.innerHTML = progressTpl;
  11 +
  12 + wrapper.appendChild(this.element);
  13 +
  14 + this.Update();
  15 +}
  16 +
  17 +Progress.prototype.SetProgress = function (progress) {
  18 + if (this.progress < progress) {
  19 + this.progress = progress;
  20 + }
  21 +
  22 + this.Update();
  23 +};
  24 +
  25 +Progress.prototype.SetMessage = function (message) {
  26 + this.message = message;
  27 + this.Update();
  28 +};
  29 +
  30 +Progress.prototype.Clear = function() {
  31 + var parent = this.element.parentNode;
  32 + parent.removeChild(this.element);
  33 +};
  34 +
  35 +Progress.prototype.Update = function() {
  36 + var progress = this.element.querySelector('.progressbar > .bar');
  37 + progress.style.width = (this.progress * 100) + '%';
  38 +};
  39 +
  40 +module.exports = Progress;
... ...
plugin/components/Progress/progress.html 0 → 100644
  1 +++ a/plugin/components/Progress/progress.html
... ... @@ -0,0 +1,4 @@
  1 +<img class="brand" src="assets/progresslogo.png"></img>
  2 +<div class="progressbar">
  3 + <div class="bar"></div>
  4 +</div>
... ...
plugin/components/Progress/progress.scss 0 → 100644
  1 +++ a/plugin/components/Progress/progress.scss
... ... @@ -0,0 +1,33 @@
  1 +.progress {
  2 + $loading-brand-height: 150px;
  3 + $loading-progress-height: 15px;
  4 + $loading-width: 150px;
  5 + $loading-height: $loading-brand-height + $loading-progress-height;
  6 +
  7 + position: absolute;
  8 + top: 50%;
  9 + left: 50%;
  10 + margin-left: -$loading-width / 2;
  11 + margin-top: -($loading-height / 2 + 10);
  12 + width: $loading-width;
  13 + text-align: center;
  14 +
  15 + .brand {
  16 + height: $loading-brand-height;
  17 + }
  18 +
  19 + .progressbar {
  20 + margin: 10px;
  21 + background-color: #444444;
  22 + width: 100%;
  23 + height: $loading-progress-height;
  24 + padding: 0;
  25 + margin: 0;
  26 +
  27 + .bar {
  28 + width: 0;
  29 + background-color: #003366;
  30 + height: $loading-progress-height;
  31 + }
  32 + }
  33 +}
... ...
plugin/index.html 0 → 100644
  1 +++ a/plugin/index.html
... ... @@ -0,0 +1,18 @@
  1 +<!doctype html>
  2 +<html lang="en-us">
  3 +<head>
  4 + <meta charset="utf-8">
  5 + <title>VLibras Plugin</title>
  6 +</head>
  7 +<body>
  8 + <div vp>
  9 + <div vp-message-box></div>
  10 + <div vp-info-screen></div>
  11 + <div vp-info-screen-btn></div>
  12 + <div vp-controls></div>
  13 + </div>
  14 +
  15 + <script src="vlibras-plugin.js"></script>
  16 + <script src="../middleware.js"></script>
  17 +</body>
  18 +</html>
... ...
plugin/index.js 0 → 100644
  1 +++ a/plugin/index.js
... ... @@ -0,0 +1,6 @@
  1 +var Plugin = require('./Plugin.js');
  2 +var window = require('window');
  3 +
  4 +require('scss/vlibras-plugin.scss');
  5 +
  6 +window.VLibras.Plugin = Plugin;
... ...
plugin/scss/_flexbox.scss 0 → 100644
  1 +++ a/plugin/scss/_flexbox.scss
... ... @@ -0,0 +1,394 @@
  1 +// Flexbox Mixins
  2 +// http://philipwalton.github.io/solved-by-flexbox/
  3 +// https://github.com/philipwalton/solved-by-flexbox
  4 +//
  5 +// Copyright (c) 2013 Brian Franco
  6 +//
  7 +// Permission is hereby granted, free of charge, to any person obtaining a
  8 +// copy of this software and associated documentation files (the
  9 +// "Software"), to deal in the Software without restriction, including
  10 +// without limitation the rights to use, copy, modify, merge, publish,
  11 +// distribute, sublicense, and/or sell copies of the Software, and to
  12 +// permit persons to whom the Software is furnished to do so, subject to
  13 +// the following conditions:
  14 +// The above copyright notice and this permission notice shall be included
  15 +// in all copies or substantial portions of the Software.
  16 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17 +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18 +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  19 +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  20 +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21 +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22 +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23 +//
  24 +// This is a set of mixins for those who want to mess around with flexbox
  25 +// using the native support of current browsers. For full support table
  26 +// check: http://caniuse.com/flexbox
  27 +//
  28 +// Basically this will use:
  29 +//
  30 +// * Fallback, old syntax (IE10, mobile webkit browsers - no wrapping)
  31 +// * Final standards syntax (FF, Safari, Chrome, IE11, Opera)
  32 +//
  33 +// This was inspired by:
  34 +//
  35 +// * http://dev.opera.com/articles/view/advanced-cross-browser-flexbox/
  36 +//
  37 +// With help from:
  38 +//
  39 +// * http://w3.org/tr/css3-flexbox/
  40 +// * http://the-echoplex.net/flexyboxes/
  41 +// * http://msdn.microsoft.com/en-us/library/ie/hh772069(v=vs.85).aspx
  42 +// * http://css-tricks.com/using-flexbox/
  43 +// * http://dev.opera.com/articles/view/advanced-cross-browser-flexbox/
  44 +// * https://developer.mozilla.org/en-us/docs/web/guide/css/flexible_boxes
  45 +
  46 +//----------------------------------------------------------------------
  47 +
  48 +// Flexbox Containers
  49 +//
  50 +// The 'flex' value causes an element to generate a block-level flex
  51 +// container box.
  52 +//
  53 +// The 'inline-flex' value causes an element to generate a inline-level
  54 +// flex container box.
  55 +//
  56 +// display: flex | inline-flex
  57 +//
  58 +// http://w3.org/tr/css3-flexbox/#flex-containers
  59 +//
  60 +// (Placeholder selectors for each type, for those who rather @extend)
  61 +
  62 +@mixin flexbox {
  63 + display: -webkit-box;
  64 + display: -webkit-flex;
  65 + display: -moz-flex;
  66 + display: -ms-flexbox;
  67 + display: flex;
  68 +}
  69 +
  70 +%flexbox { @include flexbox; }
  71 +
  72 +//----------------------------------
  73 +
  74 +@mixin inline-flex {
  75 + display: -webkit-inline-box;
  76 + display: -webkit-inline-flex;
  77 + display: -moz-inline-flex;
  78 + display: -ms-inline-flexbox;
  79 + display: inline-flex;
  80 +}
  81 +
  82 +%inline-flex { @include inline-flex; }
  83 +
  84 +//----------------------------------------------------------------------
  85 +
  86 +// Flexbox Direction
  87 +//
  88 +// The 'flex-direction' property specifies how flex items are placed in
  89 +// the flex container, by setting the direction of the flex container's
  90 +// main axis. This determines the direction that flex items are laid out in.
  91 +//
  92 +// Values: row | row-reverse | column | column-reverse
  93 +// Default: row
  94 +//
  95 +// http://w3.org/tr/css3-flexbox/#flex-direction-property
  96 +
  97 +@mixin flex-direction($value: row) {
  98 + @if $value == row-reverse {
  99 + -webkit-box-direction: reverse;
  100 + -webkit-box-orient: horizontal;
  101 + } @else if $value == column {
  102 + -webkit-box-direction: normal;
  103 + -webkit-box-orient: vertical;
  104 + } @else if $value == column-reverse {
  105 + -webkit-box-direction: reverse;
  106 + -webkit-box-orient: vertical;
  107 + } @else {
  108 + -webkit-box-direction: normal;
  109 + -webkit-box-orient: horizontal;
  110 + }
  111 + -webkit-flex-direction: $value;
  112 + -moz-flex-direction: $value;
  113 + -ms-flex-direction: $value;
  114 + flex-direction: $value;
  115 +}
  116 +// Shorter version:
  117 +@mixin flex-dir($args...) { @include flex-direction($args...); }
  118 +
  119 +//----------------------------------------------------------------------
  120 +
  121 +// Flexbox Wrap
  122 +//
  123 +// The 'flex-wrap' property controls whether the flex container is single-line
  124 +// or multi-line, and the direction of the cross-axis, which determines
  125 +// the direction new lines are stacked in.
  126 +//
  127 +// Values: nowrap | wrap | wrap-reverse
  128 +// Default: nowrap
  129 +//
  130 +// http://w3.org/tr/css3-flexbox/#flex-wrap-property
  131 +
  132 +@mixin flex-wrap($value: nowrap) {
  133 + // No Webkit Box fallback.
  134 + -webkit-flex-wrap: $value;
  135 + -moz-flex-wrap: $value;
  136 + @if $value == nowrap {
  137 + -ms-flex-wrap: none;
  138 + } @else {
  139 + -ms-flex-wrap: $value;
  140 + }
  141 + flex-wrap: $value;
  142 +}
  143 +
  144 +//----------------------------------------------------------------------
  145 +
  146 +// Flexbox Flow (shorthand)
  147 +//
  148 +// The 'flex-flow' property is a shorthand for setting the 'flex-direction'
  149 +// and 'flex-wrap' properties, which together define the flex container's
  150 +// main and cross axes.
  151 +//
  152 +// Values: <flex-direction> | <flex-wrap>
  153 +// Default: row nowrap
  154 +//
  155 +// http://w3.org/tr/css3-flexbox/#flex-flow-property
  156 +
  157 +@mixin flex-flow($values: (row nowrap)) {
  158 + // No Webkit Box fallback.
  159 + -webkit-flex-flow: $values;
  160 + -moz-flex-flow: $values;
  161 + -ms-flex-flow: $values;
  162 + flex-flow: $values;
  163 +}
  164 +
  165 +//----------------------------------------------------------------------
  166 +
  167 +// Flexbox Order
  168 +//
  169 +// The 'order' property controls the order in which flex items appear within
  170 +// their flex container, by assigning them to ordinal groups.
  171 +//
  172 +// Default: 0
  173 +//
  174 +// http://w3.org/tr/css3-flexbox/#order-property
  175 +
  176 +@mixin order($int: 0) {
  177 + -webkit-box-ordinal-group: $int + 1;
  178 + -webkit-order: $int;
  179 + -moz-order: $int;
  180 + -ms-flex-order: $int;
  181 + order: $int;
  182 +}
  183 +
  184 +//----------------------------------------------------------------------
  185 +
  186 +// Flexbox Grow
  187 +//
  188 +// The 'flex-grow' property sets the flex grow factor. Negative numbers
  189 +// are invalid.
  190 +//
  191 +// Default: 0
  192 +//
  193 +// http://w3.org/tr/css3-flexbox/#flex-grow-property
  194 +
  195 +@mixin flex-grow($int: 0) {
  196 + -webkit-box-flex: $int;
  197 + -webkit-flex-grow: $int;
  198 + -moz-flex-grow: $int;
  199 + -ms-flex-positive: $int;
  200 + flex-grow: $int;
  201 +}
  202 +
  203 +//----------------------------------------------------------------------
  204 +
  205 +// Flexbox Shrink
  206 +//
  207 +// The 'flex-shrink' property sets the flex shrink factor. Negative numbers
  208 +// are invalid.
  209 +//
  210 +// Default: 1
  211 +//
  212 +// http://w3.org/tr/css3-flexbox/#flex-shrink-property
  213 +
  214 +@mixin flex-shrink($int: 1) {
  215 + -webkit-flex-shrink: $int;
  216 + -moz-flex-shrink: $int;
  217 + -ms-flex-negative: $int;
  218 + flex-shrink: $int;
  219 +}
  220 +
  221 +//----------------------------------------------------------------------
  222 +
  223 +// Flexbox Basis
  224 +//
  225 +// The 'flex-basis' property sets the flex basis. Negative lengths are invalid.
  226 +//
  227 +// Values: Like "width"
  228 +// Default: auto
  229 +//
  230 +// http://www.w3.org/TR/css3-flexbox/#flex-basis-property
  231 +
  232 +@mixin flex-basis($value: auto) {
  233 + -webkit-flex-basis: $value;
  234 + -moz-flex-basis: $value;
  235 + -ms-flex-preferred-size: $value;
  236 + flex-basis: $value;
  237 +}
  238 +
  239 +//----------------------------------------------------------------------
  240 +
  241 +// Flexbox "Flex" (shorthand)
  242 +//
  243 +// The 'flex' property specifies the components of a flexible length: the
  244 +// flex grow factor and flex shrink factor, and the flex basis. When an
  245 +// element is a flex item, 'flex' is consulted instead of the main size
  246 +// property to determine the main size of the element. If an element is
  247 +// not a flex item, 'flex' has no effect.
  248 +//
  249 +// Values: none | <flex-grow> <flex-shrink> || <flex-basis>
  250 +// Default: See individual properties (1 1 0).
  251 +//
  252 +// http://w3.org/tr/css3-flexbox/#flex-property
  253 +
  254 +@mixin flex($fg: 1, $fs: null, $fb: null) {
  255 +
  256 + // Set a variable to be used by box-flex properties
  257 + $fg-boxflex: $fg;
  258 +
  259 + // Box-Flex only supports a flex-grow value so let's grab the
  260 + // first item in the list and just return that.
  261 + @if type-of($fg) == 'list' {
  262 + $fg-boxflex: nth($fg, 1);
  263 + }
  264 +
  265 + -webkit-box-flex: $fg-boxflex;
  266 + -webkit-flex: $fg $fs $fb;
  267 + -moz-box-flex: $fg-boxflex;
  268 + -moz-flex: $fg $fs $fb;
  269 + -ms-flex: $fg $fs $fb;
  270 + flex: $fg $fs $fb;
  271 +}
  272 +
  273 +//----------------------------------------------------------------------
  274 +
  275 +// Flexbox Justify Content
  276 +//
  277 +// The 'justify-content' property aligns flex items along the main axis
  278 +// of the current line of the flex container. This is done after any flexible
  279 +// lengths and any auto margins have been resolved. Typically it helps distribute
  280 +// extra free space leftover when either all the flex items on a line are
  281 +// inflexible, or are flexible but have reached their maximum size. It also
  282 +// exerts some control over the alignment of items when they overflow the line.
  283 +//
  284 +// Note: 'space-*' values not supported in older syntaxes.
  285 +//
  286 +// Values: flex-start | flex-end | center | space-between | space-around
  287 +// Default: flex-start
  288 +//
  289 +// http://w3.org/tr/css3-flexbox/#justify-content-property
  290 +
  291 +@mixin justify-content($value: flex-start) {
  292 + @if $value == flex-start {
  293 + -webkit-box-pack: start;
  294 + -ms-flex-pack: start;
  295 + } @else if $value == flex-end {
  296 + -webkit-box-pack: end;
  297 + -ms-flex-pack: end;
  298 + } @else if $value == space-between {
  299 + -webkit-box-pack: justify;
  300 + -ms-flex-pack: justify;
  301 + } @else if $value == space-around {
  302 + -ms-flex-pack: distribute;
  303 + } @else {
  304 + -webkit-box-pack: $value;
  305 + -ms-flex-pack: $value;
  306 + }
  307 + -webkit-justify-content: $value;
  308 + -moz-justify-content: $value;
  309 + justify-content: $value;
  310 +}
  311 +// Shorter version:
  312 +@mixin flex-just($args...) { @include justify-content($args...); }
  313 +
  314 +//----------------------------------------------------------------------
  315 +
  316 +// Flexbox Align Items
  317 +//
  318 +// Flex items can be aligned in the cross axis of the current line of the
  319 +// flex container, similar to 'justify-content' but in the perpendicular
  320 +// direction. 'align-items' sets the default alignment for all of the flex
  321 +// container's items, including anonymous flex items. 'align-self' allows
  322 +// this default alignment to be overridden for individual flex items. (For
  323 +// anonymous flex items, 'align-self' always matches the value of 'align-items'
  324 +// on their associated flex container.)
  325 +//
  326 +// Values: flex-start | flex-end | center | baseline | stretch
  327 +// Default: stretch
  328 +//
  329 +// http://w3.org/tr/css3-flexbox/#align-items-property
  330 +
  331 +@mixin align-items($value: stretch) {
  332 + @if $value == flex-start {
  333 + -webkit-box-align: start;
  334 + -ms-flex-align: start;
  335 + } @else if $value == flex-end {
  336 + -webkit-box-align: end;
  337 + -ms-flex-align: end;
  338 + } @else {
  339 + -webkit-box-align: $value;
  340 + -ms-flex-align: $value;
  341 + }
  342 + -webkit-align-items: $value;
  343 + -moz-align-items: $value;
  344 + align-items: $value;
  345 +}
  346 +
  347 +//----------------------------------
  348 +
  349 +// Flexbox Align Self
  350 +//
  351 +// Values: auto | flex-start | flex-end | center | baseline | stretch
  352 +// Default: auto
  353 +
  354 +@mixin align-self($value: auto) {
  355 + // No Webkit Box Fallback.
  356 + -webkit-align-self: $value;
  357 + -moz-align-self: $value;
  358 + @if $value == flex-start {
  359 + -ms-flex-item-align: start;
  360 + } @else if $value == flex-end {
  361 + -ms-flex-item-align: end;
  362 + } @else {
  363 + -ms-flex-item-align: $value;
  364 + }
  365 + align-self: $value;
  366 +}
  367 +
  368 +//----------------------------------------------------------------------
  369 +
  370 +// Flexbox Align Content
  371 +//
  372 +// The 'align-content' property aligns a flex container's lines within the
  373 +// flex container when there is extra space in the cross-axis, similar to
  374 +// how 'justify-content' aligns individual items within the main-axis. Note,
  375 +// this property has no effect when the flexbox has only a single line.
  376 +//
  377 +// Values: flex-start | flex-end | center | space-between | space-around | stretch
  378 +// Default: stretch
  379 +//
  380 +// http://w3.org/tr/css3-flexbox/#align-content-property
  381 +
  382 +@mixin align-content($value: stretch) {
  383 + // No Webkit Box Fallback.
  384 + -webkit-align-content: $value;
  385 + -moz-align-content: $value;
  386 + @if $value == flex-start {
  387 + -ms-flex-line-pack: start;
  388 + } @else if $value == flex-end {
  389 + -ms-flex-line-pack: end;
  390 + } @else {
  391 + -ms-flex-line-pack: $value;
  392 + }
  393 + align-content: $value;
  394 +}
... ...
plugin/scss/vlibras-plugin.scss 0 → 100644
  1 +++ a/plugin/scss/vlibras-plugin.scss
... ... @@ -0,0 +1,59 @@
  1 +html {
  2 + -webkit-box-sizing: border-box;
  3 + -moz-box-sizing: border-box;
  4 + box-sizing: border-box;
  5 +}
  6 +
  7 +*, *:before, *:after {
  8 + -webkit-box-sizing: inherit;
  9 + -moz-box-sizing: inherit;
  10 + box-sizing: inherit;
  11 +}
  12 +
  13 +html, body {
  14 + width: 100%;
  15 + height: 100%;
  16 +}
  17 +
  18 +body {
  19 + margin: 0;
  20 + overflow: hidden;
  21 + font-size: 16px;
  22 +}
  23 +
  24 +[vp] {
  25 + height: 100%;
  26 + width: 100%;
  27 + z-index: 1;
  28 +
  29 + canvas { width: 100%; height: 100% }
  30 +
  31 + [vp-info-screen-btn] {
  32 + position: fixed;
  33 + top: 7px;
  34 + right: 5px;
  35 + z-index: 4;
  36 + }
  37 +
  38 + [vp-message-box] {
  39 + z-index: 5;
  40 + }
  41 +
  42 + [vp-info-screen] {
  43 + z-index: 3;
  44 + }
  45 +
  46 + [vp-controls] {
  47 + position: fixed;
  48 + bottom: 7px;
  49 + max-width: 560px;
  50 + z-index: 2;
  51 + }
  52 +}
  53 +
  54 +@media (min-width: 560px) {
  55 + [vp] [vp-controls] {
  56 + left: 50%;
  57 + margin-left: -275px;
  58 + }
  59 +}
... ...
safari.safariextension/Info.plist 0 → 100644
  1 +++ a/safari.safariextension/Info.plist
... ... @@ -0,0 +1,53 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>Author</key>
  6 + <string>LAViD</string>
  7 + <key>Builder Version</key>
  8 + <string>10600.6.3</string>
  9 + <key>CFBundleDisplayName</key>
  10 + <string>VLibras Plugin</string>
  11 + <key>CFBundleIdentifier</key>
  12 + <string>br.ufpb.lavid.vlibras</string>
  13 + <key>CFBundleInfoDictionaryVersion</key>
  14 + <string>6.0</string>
  15 + <key>CFBundleShortVersionString</key>
  16 + <string>0.2.0</string>
  17 + <key>CFBundleVersion</key>
  18 + <string>2</string>
  19 + <key>Chrome</key>
  20 + <dict>
  21 + <key>Database Quota</key>
  22 + <real>52428800</real>
  23 + <key>Global Page</key>
  24 + <string>global.html</string>
  25 + </dict>
  26 + <key>Content</key>
  27 + <dict>
  28 + <key>Scripts</key>
  29 + <dict>
  30 + <key>Start</key>
  31 + <array>
  32 + <string>scripts/contextmenu.js</string>
  33 + </array>
  34 + </dict>
  35 + </dict>
  36 + <key>Description</key>
  37 + <string>Um tradutor de portugues para LIBRAS</string>
  38 + <key>DeveloperIdentifier</key>
  39 + <string>3PTX2S8KDQ</string>
  40 + <key>ExtensionInfoDictionaryVersion</key>
  41 + <string>1.0</string>
  42 + <key>Permissions</key>
  43 + <dict>
  44 + <key>Website Access</key>
  45 + <dict>
  46 + <key>Include Secure Pages</key>
  47 + <true/>
  48 + <key>Level</key>
  49 + <string>All</string>
  50 + </dict>
  51 + </dict>
  52 +</dict>
  53 +</plist>
... ...
safari.safariextension/app/middleware.js 0 → 100644
  1 +++ a/safari.safariextension/app/middleware.js
... ... @@ -0,0 +1,12 @@
  1 +window.resizeTo(540, 470);
  2 +
  3 +document.addEventListener('player:verified', function() {
  4 + safari.self.addEventListener('message', function (request) {
  5 + if (request.name !== 'plugin:selectedText' && request.message === undefined) return;
  6 +
  7 + window.plugin = (window.plugin || new VLibras.Plugin());
  8 + window.plugin.translate(request.message);
  9 + });
  10 +
  11 + safari.self.tab.dispatchMessage('page:ready', true);
  12 +});
... ...
safari.safariextension/background.js 0 → 100644
  1 +++ a/safari.safariextension/background.js
... ... @@ -0,0 +1,49 @@
  1 +var popup = null;
  2 +var selectedText = undefined;
  3 +var appURL = safari.extension.baseURI + 'app/player/index.html';
  4 +
  5 +safari.application.addEventListener('contextmenu', function (event){
  6 + var selectedText = event.userInfo;
  7 +
  8 + if (!selectedText) return;
  9 +
  10 + if (selectedText.length > 20) {
  11 + selectedText = selectedText.substr(0, 20) + '...';
  12 + }
  13 +
  14 + if (selectedText !== '') {
  15 + event.contextMenu.appendContextMenuItem('translateLibras', 'Traduzir ' + selectedText + ' para LIBRAS');
  16 + }
  17 +}, false);
  18 +
  19 +safari.application.addEventListener('command', function (event){
  20 + if (event.command === 'translateLibras') {
  21 + selectedText = event.userInfo;
  22 +
  23 + if (popup === null) {
  24 + popup = safari.application.openBrowserWindow().activeTab;
  25 + popup.url = appURL;
  26 +
  27 + popup.addEventListener('close', function () {
  28 + popup = null;
  29 + });
  30 +
  31 + popup.addEventListener('navigate', function (event) {
  32 + if (event.target.url !== appURL) {
  33 + popup = null;
  34 + }
  35 + });
  36 +
  37 + popup.addEventListener('message', function (request) {
  38 + if (selectedText !== undefined && request.name === 'page:ready' && request.message == true) {
  39 + popup.page.dispatchMessage('plugin:selectedText', selectedText);
  40 + selectedText = undefined;
  41 + };
  42 + });
  43 + } else {
  44 + popup.browserWindow.activate();
  45 + popup.page.dispatchMessage('plugin:selectedText', selectedText);
  46 + selectedText = undefined;
  47 + }
  48 + }
  49 +}, false);
... ...
safari.safariextension/global.html 0 → 100644
  1 +++ a/safari.safariextension/global.html
... ... @@ -0,0 +1,8 @@
  1 +<html>
  2 + <head>
  3 + <title>VLibras Plugin</title>
  4 + <script src="background.js"></script>
  5 + </head>
  6 + <body>
  7 + </body>
  8 +</html>
0 9 \ No newline at end of file
... ...
safari.safariextension/scripts/contextmenu.js 0 → 100644
  1 +++ a/safari.safariextension/scripts/contextmenu.js
... ... @@ -0,0 +1,3 @@
  1 +document.addEventListener('contextmenu', function (event){
  2 + safari.self.tab.setContextMenuEventUserInfo(event, window.getSelection().toString());
  3 +}, false);
0 4 \ No newline at end of file
... ...
safari.safariextension/vlibras48.png 0 → 100644

18.4 KB

webpack.config.js 0 → 100644
  1 +++ a/webpack.config.js
... ... @@ -0,0 +1,21 @@
  1 +var path = require('path');
  2 +
  3 +require('es6-promise').polyfill();
  4 +
  5 +module.exports = {
  6 + output: {
  7 + filename: 'vlibras-plugin.js'
  8 + },
  9 + resolve: {
  10 + root: path.join(__dirname, 'plugin')
  11 + },
  12 + externals: {
  13 + 'window': 'window'
  14 + },
  15 + module: {
  16 + loaders: [
  17 + { test: /\.s?css/, loaders: ['style', 'css?-url', 'sass'] },
  18 + { test: /\.html/, loaders: ['raw'] }
  19 + ]
  20 + }
  21 +}
... ...