From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../abra_uma_p\303\241gina_web/index.html" | 51 +++ .../adding_a_button_to_the_toolbar/index.html | 83 +++++ .../index.html | 115 +++++++ .../index.html | 120 +++++++ .../captura_de_carregamento_da_pagina/index.html | 28 ++ .../sdk/tutorials/chrome_authority/index.html | 65 ++++ .../sdk/tutorials/come\303\247ando/index.html" | 206 +++++++++++ .../tutorials/creating_event_targets/index.html | 245 +++++++++++++ .../tutorials/creating_reusable_modules/index.html | 253 ++++++++++++++ .../sdk/tutorials/getting_started_(jpm)/index.html | 155 +++++++++ .../pt-br/mozilla/add-ons/sdk/tutorials/index.html | 144 ++++++++ .../mozilla/add-ons/sdk/tutorials/l10n/index.html | 380 +++++++++++++++++++++ .../sdk/tutorials/lista_de_tabs_abertas/index.html | 67 ++++ .../listening_for_load_and_unload/index.html | 60 ++++ .../add-ons/sdk/tutorials/logging/index.html | 55 +++ .../modifying_the_page_hosted_by_a_tab/index.html | 137 ++++++++ .../modifying_web_pages_based_on_url/index.html | 228 +++++++++++++ .../sdk/tutorials/mostrar_um_popup/index.html | 165 +++++++++ .../add-ons/sdk/tutorials/unit_testing/index.html | 127 +++++++ 19 files changed, 2684 insertions(+) create mode 100644 "files/pt-br/mozilla/add-ons/sdk/tutorials/abra_uma_p\303\241gina_web/index.html" create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/adicionar_uma_item_de_menu_ao_firefox/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/adicione_um_item_ao_menu_de_contexto/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/captura_de_carregamento_da_pagina/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/chrome_authority/index.html create mode 100644 "files/pt-br/mozilla/add-ons/sdk/tutorials/come\303\247ando/index.html" create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/creating_event_targets/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/creating_reusable_modules/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/l10n/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/lista_de_tabs_abertas/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/listening_for_load_and_unload/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/logging/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/mostrar_um_popup/index.html create mode 100644 files/pt-br/mozilla/add-ons/sdk/tutorials/unit_testing/index.html (limited to 'files/pt-br/mozilla/add-ons/sdk/tutorials') diff --git "a/files/pt-br/mozilla/add-ons/sdk/tutorials/abra_uma_p\303\241gina_web/index.html" "b/files/pt-br/mozilla/add-ons/sdk/tutorials/abra_uma_p\303\241gina_web/index.html" new file mode 100644 index 0000000000..defcedcee2 --- /dev/null +++ "b/files/pt-br/mozilla/add-ons/sdk/tutorials/abra_uma_p\303\241gina_web/index.html" @@ -0,0 +1,51 @@ +--- +title: Abra uma Página Web +slug: Mozilla/Add-ons/SDK/Tutorials/Abra_uma_Página_Web +tags: + - Add-on SDK + - Tab + - runScript + - tab.attach +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Open_a_Web_Page +--- +
Para seguir este tutorial você precisará ter instalado o SDK e ter conhecimento básico sobre cfx.
+ +

Para abrir uma página web, você pode usar o módulo tabs:

+ +
var tabs = require("sdk/tabs");
+tabs.open("http://www.example.com");
+
+ +

Esta função é assíncrona, então você não recebe imediatamente um objeto tab que você possa examinar. Faça isto, passe uma função de retorno para open(). A função de retorno é atribuída a propriedade onReady, e será passada a tab como argumento:

+ +
var tabs = require("sdk/tabs");
+tabs.open({
+  url: "http://www.example.com",
+  onReady: function onReady(tab) {
+    console.log(tab.title);
+  }
+});
+
+ +

Mesmo assim, você não consegue acesso direto a qualquer conteúdo hospedado na tab.

+ +

Para acessar conteúdo da tab você precisa anexar um script à tab usando o tab.attach(). Este add-on carrega uma página, então anexa um script à página que adiciona uma borda vermelha nela:

+ +
var tabs = require("sdk/tabs");
+tabs.open({
+  url: "http://www.example.com",
+  onReady: runScript
+});
+
+function runScript(tab) {
+  tab.attach({
+    contentScript: "document.body.style.border = '5px solid red';"
+  });
+}
+
+ +

Aprendendo Mais

+ +

Para aprender mais sobre uso de tabs no SDK, veja a referência da API tabs.

+ +

Para aprender mais sobre execução de scripts em tabs, veja o tutorial sobre uso de tab.attach().

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html new file mode 100644 index 0000000000..83b2f61907 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html @@ -0,0 +1,83 @@ +--- +title: Adicionando um botão à barra de ferramentas +slug: Mozilla/Add-ons/SDK/Tutorials/Adding_a_Button_to_the_Toolbar +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Adding_a_Button_to_the_Toolbar +--- +
+

Para seguir este tutorial você precisará ter instalado o SDK e ter conhecimento básico do cfx.

+ +

Este tutorial usa a API action button, que está disponível somente do Firefox 29 em diante.

+
+ +

Para adicionar um botão à barra de ferramentas, use os módulos action button ou toggle button.

+ +

Crie um novo diretório, navegue até ele, e execute cfx init.

+ +

Então salve estes três ícones no diretório "data":

+ + + + + + + + + + + + + + + + +
icon-16.png
icon-32.png
icon-64.png
+ +

Então abra o arquivo chamado "main.js" no diretório "lib" e adicione o seguinte código a ele:

+ +
var buttons = require('sdk/ui/button/action');
+var tabs = require("sdk/tabs");
+
+var button = buttons.ActionButton({
+  id: "mozilla-link",
+  label: "Visit Mozilla",
+  icon: {
+    "16": "./icon-16.png",
+    "32": "./icon-32.png",
+    "64": "./icon-64.png"
+  },
+  onClick: handleClick
+});
+
+function handleClick(state) {
+  tabs.open("https://www.mozilla.org/");
+}
+ +

Agora execute o add-on com cfx run. O botão é adicionado à barra de ferramentas no topo da janela do navegador:

+ +

Você não pode configurar a localização inicial para o botão, mas o usuário pode mover ele usando as características de personalização do navegador. O id é obrigatório, e é usado para lembrar a posição do botão, então você não deve mudá-lo em versões subsequentes do add-on.

+ +

Clicando no botão carrega https://www.mozilla.org/ em uma nova tab.

+ +

Especificando o ícone

+ +

A propriedade ícone pode especificar um único ícone ou uma coleção de ícones em diferentes tamanhos, como o exemplo acima. Se você especificar uma coleção de ícones em diferentes tamanhos o navegador automaticamente escolherá o melhor para a resolução de tela em uso e coloca na interface de usuário do navegador que hospeda o botão. Leia mais sobre especificar múltiplos ícones.

+ +

O arquivo de ícone deve ser empacotado com seu add-on: ele não pode referenciar um arquivo remoto.

+ +

Você pode mudar o ícone a qualquer hora configurando a propriedade icon do botão. Você pode mudar o ícone, e os outros atributos de estado, ou globalmente, para uma janela específica, ou para uma tab específica. Leia mais sobre atualização de estado.

+ +

Anexando um painel

+ +

Se você precisar anexar um panel a um botão, use a API toggle button. É como a API do action button exceto que ele adiciona uma propriedade boleana checked que é alternada sempre que o botão é checado. Para anexar o painel, passe o método show() do painel. Para mais detalhes sobre isso, veja a documentação do toggle button.

+ +

Mostrando conteúdo mais rico

+ +

Para criar conteúdo mais complexo para a interface do usuário do que é possível com apenas um botão, use a API toolbar. Com a API toolbar você consegue uma faixa horizontal da interface do usuário. Você pode adicionar botões à barra de ferramentas e também frames, que podem ter HTML, CSS, e JavaScript.

+ +

Aprendendo mais

+ + diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/adicionar_uma_item_de_menu_ao_firefox/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/adicionar_uma_item_de_menu_ao_firefox/index.html new file mode 100644 index 0000000000..ebc4e41846 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/adicionar_uma_item_de_menu_ao_firefox/index.html @@ -0,0 +1,115 @@ +--- +title: Adicionar um item de menu ao Firefox +slug: Mozilla/Add-ons/SDK/Tutorials/Adicionar_uma_item_de_menu_ao_Firefox +tags: + - Add-on SDK + - Menu Item +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Add_a_Menu_Item_to_Firefox +--- +
+

Para seguir este tutorial você precisará ter instalado o SDK e aprendido o básico do cfx.

+
+ +
+

Se vocé estiver usando jpm ao invés de cfx, o método para usar módulos de terceiros é diferente, e você deve ler a versão jpm ao invés deste guia.

+
+ +

O SDK não tem ainda uma API para adicionar novos itens de menu ao Firefox. Mas é extensível por design, então qualquer um pode construir e publicar módulos para desenvolvedores de add-on usar. Felizmente, Erik Vold escreveu um módulo menuitems que nos permite adicionar itens de menu.

+ +

Este tutorial tem dupla função. Ele descreve o método geral para usar um externo, módulo de terceiro em seu add-on, e ele descreve como adicionar um item de menu usando o módulo menuitems em especial.

+ +

Primeiro, crie um novo add-on. Crie um diretório chamado "clickme" onde você quiser, navegue para ele e execute cfx init.

+ +
mkdir clickme
+cd clickme
+cfx init
+
+ +

A estrutura de diretório de costume será criada:

+ + + +
 
+ +

Inslatando menuitems

+ +

Crie um diretório em "clickme" chamado "packages". Baixe o pacote menuitems de https://github.com/mykmelez/menuitems-jplib e extrai ele dentro do diretório "packages" que você criou:

+ +
mkdir packages
+cd packages
+tar -xf ../erikvold-menuitems-jplib-d80630c.zip
+
+ +

Dependências de Módulo

+ +

Se os módulos de terceiros dependem de módulos SDK, você pode usá-los imediatamente, mas se eles dependem de módulos de terceiros, você terá de instalar essas dependências também.

+ +

No diretório principal do pacote (menuitems) você encontrará um arquivo chamado "package.json". Abra ele e procure por uma entrada chamada "dependencies". A entrada para o pacote menuitems é:

+ +
"dependencies": ["api-utils", "vold-utils"]
+
+ +

Isso nos diz que nós precisamos instalar o pacote vold-utils, que nós podemos fazer baixando ele de https://github.com/mykmelez/vold-utils-jplib e adicionando ele ao diretório packages com menuitems. Veja também api-utils Docs(UtilsAPI).

+ +

Usando menuitems

+ +

A documentação para o módulo menuitems nos diz para criar um item de menu usando MenuItem(). Das opções aceitas pelo MenuItem(), nós usaremos este conjunto mínimo:

+ + + +
+
+
var menuitem = require("menuitems").Menuitem({
+  id: "clickme",
+  menuid: "menu_ToolsPopup",
+  label: "Click Me!",
+  onCommand: function() {
+    console.log("clicked");
+  },
+  insertbefore: "menu_pageInfo"
+});
+ +
 
+
+
+ +

Próximo, nós temos que declarar nossa dependência do pacote menuitems. No package.json de nosso add-on adicionamos a linha:

+ +
"dependencies": "menuitems"
+
+ +

Observe que devido ao bug 663480, se você adicionar uma linha dependencies ao package.json, e você usar qualquer módulo do SDK, então você deve também declarar sua dependência naquele pacote embutido, como isto:

+ +
"dependencies": ["menuitems", "addon-sdk"]
+
+ +

Agora terminamos. Execute o add-on e você verá o novo item aparecer no menu de Ferramentas: selecione ele e você verá a info: clicked aparecer no console.

+ +

Cuidados

+ +

Módulos de terceiros são uma ótima forma de usar características não suportadas diretamente pelo SDK, mas porque módulos de terceiros usam APIs de nível baixo, eles podem quebrar quando forem lançadas novas versões do Firefox.

+ +

 

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/adicione_um_item_ao_menu_de_contexto/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/adicione_um_item_ao_menu_de_contexto/index.html new file mode 100644 index 0000000000..d864cd3029 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/adicione_um_item_ao_menu_de_contexto/index.html @@ -0,0 +1,120 @@ +--- +title: Adicione um Item ao Menu de Contexto +slug: Mozilla/Add-ons/SDK/Tutorials/Adicione_um_Item_ao_Menu_de_Contexto +tags: + - Add-on SDK + - Firefox + - Guide + - context-menu +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Add_a_Context_Menu_Item +--- +
+

Para seguir este tutorial você precisará ter instalado o SDK e ter conhecimento básico sobre cfx.

+
+ +

Para adicionar itens e submenus ao menu de contexto do Firetox, use o módulo  context-menu.

+ +

Aqui está um add-on que adiciona um novo item ao menu de contexto. O item é mostrado sempre que alguma coisa na página é selecionada. Quando é clicado, a seleção é enviada para o código principal do add-on, que apenas registra ele:

+ +
var contextMenu = require("sdk/context-menu");
+ var menuItem = contextMenu.Item({
+  label: "Log Selection",
+  context: contextMenu.SelectionContext(),
+  contentScript: 'self.on("click", function () {' +
+                 '  var text = window.getSelection().toString();' +
+                 '  self.postMessage(text);' +
+                 '});',
+  onMessage: function (selectionText) {
+    console.log(selectionText);
+  }
+});
+ +

Teste: execute o add-on, carregue uma página web, selecione algum texto e clique com o botão direito. Você verá o novo item aparecer:

+ +

+ +

Clique nele, e a seleção é registrada no console (ou na shell, se você estiver executando uma instância do Firefox na linha de comando):

+ +
info: elephantine lizard
+
+ +

Detalhes

+ +

Tudo que este add-on faz é criar um item no menu de contexto. Você não precisa adicioná-lo: uma vez que você criou o item, ele é automaticamente adicionado no contexto correto. O construtor nesse caso possui quatro opções: label, context, contentScript, e onMessage.

+ +

label

+ +

O label é tão somente a string que será mostrada.

+ +

context

+ +

O context descreve a circunstância em que o item será mostrado. O módulo context-menu oferece uma série de contextos embutidos, incluindo este SelectionContext(), que significa: mostrar o item quando alguma coisa na página for selecionada.

+ +

Se estes simples contextos não forem suficiente, você pode definir contextos mais sofisticados usando scripts.

+ +

contentScript

+ +

Este anexa um script ao item. Nesse caso o script espera pelo clique do usuário no item, então envia uma mensagem para o add-on contendo do texto selecionado.

+ +

onMessage

+ +

A propriedade onMessage oferece um modo para o código do add-on responder mensagens do script anexado ao item do menu de contexto. Nesse caso é apenas registrado o texto selecionado.

+ +

Então:

+ +
    +
  1. O usuário clica no item
  2. +
  3. o conteúdo do script do evento click dispara, e o conteúdo do script recupera o texto selecionado e envia a mensagem para o add-on
  4. +
  5. o evento message do add-on dispara, e ao código manipulador da função é passado o texto selecionado, que é registrado
  6. +
+ +

Mais opções

+ +

Adicionando uma imagem

+ +

Você pode adicionar uma imagem ao menu de contexto por meio da opção image. Isto é uma URL apontando para um ícone 16x16 que é mostrado do lado esquerdo do item do menu de contexto. Geralmente você armazenaria sua imagem no diretório "data" do seu add-on, e construiria a URL usando self.data.url():

+ +
var self = require("sdk/self");
+
+var contextMenu = require("sdk/context-menu");
+var menuItem = contextMenu.Item({
+  label: "Log Selection",
+  context: contextMenu.SelectionContext(),
+  contentScript: 'self.on("click", function () {' +
+                 '  var text = window.getSelection().toString();' +
+                 '  self.postMessage(text);' +
+                 '});',
+  image: self.data.url("icon-16.png"),
+  onMessage: function (selectionText) {
+    console.log(selectionText);
+  }
+});
+ +

Adicione uma tecla de atalho

+ +
+

Novo no Firefox 35.

+
+ +

A partir do Firefox 35 você pode especificar uma tecla de atalho usando a opção  accessKey. Deve ser somente um caracter. Pressione a tecla selecionada na opção quando o menu de contexto estiver aberto:

+ +
var contextMenu = require("sdk/context-menu");
+var menuItem = contextMenu.Item({
+  label: "Log Selection",
+  context: contextMenu.SelectionContext(),
+  contentScript: 'self.on("click", function () {' +
+                 '  var text = window.getSelection().toString();' +
+                 '  self.postMessage(text);' +
+                 '});',
+  accessKey: "l",
+  onMessage: function (selectionText) {
+    console.log(selectionText);
+  }
+});
+
+ +

 

+ +

Aprendendo mais

+ +

Aprendendo mais sobre o módulo context-menu, veja a referência da API context-menu.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/captura_de_carregamento_da_pagina/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/captura_de_carregamento_da_pagina/index.html new file mode 100644 index 0000000000..1fa1ae81d6 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/captura_de_carregamento_da_pagina/index.html @@ -0,0 +1,28 @@ +--- +title: Captura de carregamento da página +slug: Mozilla/Add-ons/SDK/Tutorials/captura_de_carregamento_da_pagina +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Listen_for_Page_Load +--- +
+ Para seguir esse tutorial você necessita ter instalado o SDK e aprendido o básico do cfx.
+

Você pode capturar notificações sobre novas páginas em carregamento usando o módulo tabs. O seguinte complemento captura o evento ready da aba e mostra no console a URL da mesma, carregada pelo usuário:

+
require("sdk/tabs").on("ready", logURL);
+
+function logURL(tab) {
+  console.log(tab.url);
+}
+
+

Você não tem acesso direto a qualquer conteúdo hospedado na guia.

+

Para acessar o conteúdo da aba você precisa anexar um script usando tab.attach(). Este add-on atribui um script para todas as abas abertas. O script adiciona uma borda vermelha ao documento da aba:

+
require("sdk/tabs").on("ready", runScript);
+
+function runScript(tab) {
+  tab.attach({
+    contentScript: "if (document.body) document.body.style.border = '5px solid red';"
+  });
+}
+
+

(Este exemplo é apenas para mostrar a idéia: para implementar algo como isso, você deve usar page-mod, e especificar "*" como o match-pattern.)

+

Aprendendo Mais

+

Para aprender mais sobre o trabalho com abas no SDK, veja a referência de tab da API. Você pode capturar uma série de outros eventos da aba, incluindo open, close e activate.

+

Para ler mais sobre rodar scripts nas abas, veja o tutorial sobre como usar tab.attach().

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/chrome_authority/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/chrome_authority/index.html new file mode 100644 index 0000000000..0e09ecdc02 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/chrome_authority/index.html @@ -0,0 +1,65 @@ +--- +title: Autoridade Chrome +slug: Mozilla/Add-ons/SDK/Tutorials/Chrome_Authority +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Chrome_Authority +--- +
+

A API usada para ganhar acesso ao Chrome atualmente é uma característica experimental do SDK, e deve mudar em lançamentos futuros.

+
+ +

Usando Autoridade Chrome

+ +

Os módulos de baixo-nível mais poderosos são executados com "chrome privileges", que nos dão acesso ao infame Objeto Components, que concede acesso irrestrito ao host. A partir daí, o módulo pode fazer praticamente qualquer coisa que o navegador é capaz. Para obter estes privilégios, o módulo deve declarar sua intenção com uma declaração como a seguinte:

+ +
var {Cc, Ci} = require("chrome");
+ +

O objeto retornado pelo require("chrome"), quando desempacotado com a característica destructuring assignment disponível no ambiente JS do Mozilla, fornecerá os redutores comuns dos Components.*:

+ +

Cc

+ +

Um redutor para Components.classes.

+ +

Ci

+ +

Um redutor para Components.interfaces.

+ +

Cu

+ +

Um redutor para Components.utils.

+ +

Cr

+ +

Um redutor para Components.results.

+ +

Cm

+ +

Um redutor para Components.manager.

+ +

components

+ +

Uma outra forma de chamar Components por si mesmo (note as letras minúsculas). A partir daí você pode acessar propriedade de uso menos frequente como Components.stack e Components.isSuccessCode.

+ +

Nota: a declaração require("chrome") é o único modo para acessar as funcionalidades do chrome e da API Components. O objeto Components não deve ser acessado de módulos. A ferramenta SDK emitira um aviso se ela vir código em móduo que referencie o Components diretamente.

+ +

Seu módulo deve evitar usar privilégios do chrome a menos que seja absolutamente necessário. Uso da Autoridade do Chrome deve receber revisão extra de segurança, e a maioria dos bugs nestes módulos são críticos a segurança.

+ +

Geração do Manifesto

+ +

O manifesto é uma lista, incluída no XPI gerado, que especifica quais módulos requisitação accesso require() para quais outros módulos. Ele também grava quais módulos requisitam acesso chrome. Esta lista é gerada pelo mapeamento de todos os módulos incluído pela declaração require(XYZ) e grava a string "XYZ" que eles referênciam.

+ +

Quando a implementação do manifesto estiver completa o carregador do programa  vai impedir os módulos de usar require()  para solicitar módulos que não estão listados no manifesto. Também, evitará que os módulos consiga autoridade chrome a menos que o manifesto indique que eles pediram para ele. Isto irá assegurar que os revisores enxerguem as mesmas restrições de autoridade que são aplicadas sobre o código em execução, aumentando efetivamente o tempo gasto revendo o add-on. (até que este trabalho seja concluído, os módulos podem ser capazes de burlar essas restrições).

+ +

O manifesto é construído com um mapeador baseado em expressão regular, não um análisador Javascript. Os desenvolvedores devem manter as declarações require simples, com uma única string estática, uma por linha de código. Se o mapeador falhar para enxergar a entrada require, o manifesto não incluirá aquela entrada, e (uma vez que a implementação esteja completa) o código em execução lança uma exceção.

+ +

Por exemplo, nenhum dos códigos a seguir serão encontrados pelo mapeamento do manifesto, levando a uma exceção em tempo de execução, quando a chamada require() é proibida de importar os módulos chamados:

+ +
// todos estes falharão
+var xhr = require("x"+"hr");
+var modname = "xpcom";
+var xpcom = require(modname);
+var one = require("one"); var two = require("two");
+
+ +

A intenção é que os desenvolvedores usem a declaração require() para dois propósitos: declarar (ao revisores de segurança) qual a classificação dos poderes que os modulos querem usar, e controlar como estes poderes serão mapeados dentro do namespace do módulo local. Suas declarações devem então ser claras e fáceis de analisar. Um formato de manifesto futuro deve mover a porção de declaração para um arquivo separado, para permitir expressões mais granuladas de autorização.

+ +

Comandos que constroem um manifesto, como "jpm xpi" ou "jpm run", mapearão todos os módulos incluídos pelo uso dos atalhos Cc/Ci (ou a forma expandida Components.classes). Emitirá um aviso se ele visualizar a forma expandida ou ver o uso e.g. "Cc" sem a entrada correspondente na declaração require("chrome"). Estes avisos servem para guiar os desenvolvedores para o usar o padrão correto. Todos os desenvolvedores de módulos devem reparar os avisos e corrigir seus códigos até que os avisos tenham desaparecido.

diff --git "a/files/pt-br/mozilla/add-ons/sdk/tutorials/come\303\247ando/index.html" "b/files/pt-br/mozilla/add-ons/sdk/tutorials/come\303\247ando/index.html" new file mode 100644 index 0000000000..1294a58ffd --- /dev/null +++ "b/files/pt-br/mozilla/add-ons/sdk/tutorials/come\303\247ando/index.html" @@ -0,0 +1,206 @@ +--- +title: Começando +slug: Mozilla/Add-ons/SDK/Tutorials/Começando +tags: + - Add-on SDK + - Tutorial +translation_of: Mozilla/Add-ons/SDK/Tutorials/Getting_Started_%28jpm%29 +--- +

Este tutorial percorre a criação de um add-on simples usando o SDK.

+ +

Pré-requisitos

+ +

Para criar add-ons para Firefox usando SDK, você primeiro precisará seguir as instruções para instalar e ativar o SDK. Uma vez que você fez isso, você estará olhando para um prompt de comando.

+ +

Inicializando um add-on vazio

+ +

No prompt de comando, crie um novo diretório. O diretório não precisa estar no diretório principal do SDK: você pode criar ele em qualquer lugar que você quiser. Navegue para ele, digite cfx init, e tecle enter:

+ +
mkdir my-addon
+cd my-addon
+cfx init
+
+ +

Você verá uma saída como esta:

+ +
* lib directory created
+* data directory created
+* test directory created
+* doc directory created
+* README.md written
+* package.json written
+* test/test-main.js written
+* lib/main.js written
+* doc/main.md written
+Your sample add-on is now ready for testing:
+try "cfx test" and then "cfx run". Have fun!"
+
+ +

Implementando o add-on

+ +

Agora você pode escrever o código do add-on, que vai no arquivo "main.js" em diretório "lib". Esse arquivo foi criado para você no passo anterior. Abra ele e adicione o seguinte código:

+ +
var buttons = require('sdk/ui/button/action');
+var tabs = require("sdk/tabs");
+
+var button = buttons.ActionButton({
+  id: "mozilla-link",
+  label: "Visite Mozilla",
+  icon: {
+    "16": "./icon-16.png",
+    "32": "./icon-32.png",
+    "64": "./icon-64.png"
+  },
+  onClick: handleClick
+});
+
+function handleClick(state) {
+  tabs.open("https://www.mozilla.org/");
+}
+
+ +

Salve o arquivo.

+ +

Próximo, salve estes ícones no diretório "data" de seu add-on:

+ + + + + + + + + + + + + + + + +
icon-16.png
icon-32.png
icon-64.png
+ +

Volte ao prompt de comando, digite:

+ +
cfx run
+
+ +

Este é o comando SDK para executar uma nova instância do Firefox com seu add-on instalado. Quando o Firefox inicia, no canto de cima do lado direito do navegador você verá um ícone com o logotipo do Firefox. Clique nele, e uma nova tab abrirá com o site https://www.mozilla.org/ carregado nela.

+ +

Isso é tudo que esse add-on faz. Ele usa dois módulos SDK: o módulo action button, que permite a você adicionar botões ao navegador, e o módulo tabs, que permite a você realizar operações básicas com tabs. Nesse caso, nós criamos uma botão cujo ícone é o íncone do Firefox, e adicionamos um manipulador de clique que carrega a home page da Mozilla na nova tab.

+ +

Tente editar esse arquivo. Por exemplo, nós poderíamos mudar a página que é carregada:

+ +
var buttons = require('sdk/ui/button/action');
+var tabs = require("sdk/tabs");
+
+var button = buttons.ActionButton({
+  id: "mozilla-link",
+  label: "Visit Mozilla",
+  icon: {
+    "16": "./icon-16.png",
+    "32": "./icon-32.png",
+    "64": "./icon-64.png"
+  },
+  onClick: handleClick
+});
+
+function handleClick(state) {
+  tabs.open("https://developer.mozilla.org/");
+}
+ +

No promp de comando, execute novamente cfx run. Desta vez clicando levará você para https://developer.mozilla.org/.

+ +

Empacotando o add-on

+ +

Quando você termina o add-on e está preparado para distribui-lo, você precisa empacotá-lo como um arquivo XPI. Esse é um formato de arquivo instalável para add-ons de Firefox.  Você pode distribuir arquivos XPI ou publicá-los em https://addons.mozilla.org assim outros usuários podem baixar e instalá-los.

+ +

Para construir um XPI, apenas execute o comando cfx xpi do diretório do add-on:

+ +
cfx xpi
+
+ +

Você deve ver uma mensagem como:

+ +
Exporting extension to my-addon.xpi.
+
+ +

Para testar que funcionou, tente instalar o arquivo XPI em sua própria instalação do Firefox. Você pode fazer isso pressionando Ctrl+O (Cmd+O no Mac) de dentro do Firefox, ou selecionando o item "Abrir arquivo" do menu "Arquivo" do Firefox. Isso trará uma caixa de seleção; navegue até o arquivo "my-addon.xpi", abra-o e siga o prompt para instalar o add-on.

+ +

Resumo

+ +

Neste tutorial nós construímos e empacotamos um add-on usando três comandos:

+ + + +

Esses são os três principais comandos que você usará quando desenvolver add-ons no SDK. Há uma abrangente documentação de referência cobrindo todos os comandos que você pode usar e todas as opções que eles possuem.

+ +

O próprio código do add-on usa dois módulos do SDK, action button e tabs. Há documentação de referência para toda a API do SDK, de alto e baixo nível.

+ +

O que vem a seguir?

+ +

Para sentir algumas das coisas que você pode fazer com a API do SDK, tente trabalhar através de alguns dos tutorials.

+ +

Técnicas avançadas

+ +

Sobreescrevendo os módulos embutidos

+ +

Os módulos do SDK que você usa para implementar seu add-on estão embutidas no Firefox. Quando você executa ou empacota um add-on usando cfx run ou cfx xpi, o add-on usará as versões dos módulos na versão do Firefox que hospeda elas.

+ +

Como um desenvolvedor de add-on, isso é normalmente o que você quer. Mas se você está desenvolvendo os módulos SDK por si mesmo, claro, não será. Nesse caso assumimos que você pegou o SDK de seu repositório GitHub e executará o script bin/activate desse diretório raiz de trabalho.

+ +

Então quando você invoca cfx run ou cfx xpi, você passa a opçao "-o":

+ +
cfx run -o
+
+ +

Isso instrui o cfx a usar a cópia local dos módulos do SDK, não aqueles existentes no Firefox.

+ +

Desenvolvendo sem cfx run

+ +

Porque cfx run reinicia o navegador cada vez que você invoca ele, ele pode ser um pouco pesado se você está fazendo mudanças frequentes em um add-on. Um modelo de desenvolvimento alternativo é usar o add-on Extension Auto-Installer: este escuta para novos arquivos XPI em uma porta específica e instala-os automaticamente. Dessa maneira você pode testar novas mudanças sem precisar reiniciar o navegador:

+ + + +

Você poderia até mesmo automatizar esse fluxo com um script simples. Por exemplo:

+ +
while true ; do cfx xpi ; wget --post-file=codesy.xpi http://localhost:8888/ ; sleep 5 ; done
+
+ +

Note que o nível de registro definido para o console é diferente quando você usa esse método, comparado com o nível de registro usado quando um add-on está executando usando cfx run. Isso significa que se você quiser ver a saída de mensagens do console.log(), você terá que ajustar uma configuração. Veja a documentação no nível de registros para mais detalhes sobre isso.

+ +

Um outro exemplo usando grunt e grunt-shell:

+ +
module.exports = function(grunt) {
+  'use strict';
+  require('matchdep').filterDev('grunt-!(cli)').forEach(grunt.loadNpmTasks);
+  grunt.initConfig({
+    shell: {
+      xpi: {
+        command: [
+          'cd pluginpath',
+          'cfx xpi',
+          'wget --post-file=pluginname.xpi http://localhost:8888/ || echo>/dev/null'
+        ].join('&&')
+      }
+    },
+    watch: {
+      xpi: {
+        files: ['pluginpath/**'],
+        tasks: ['shell:xpi']
+      }
+    }
+  });
+
+  grunt.loadNpmTasks('grunt-contrib-watch');
+  grunt.loadNpmTasks('grunt-shell');
+  grunt.registerTask('default', ['watch']);
+};
diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/creating_event_targets/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/creating_event_targets/index.html new file mode 100644 index 0000000000..d8fd6a7318 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/creating_event_targets/index.html @@ -0,0 +1,245 @@ +--- +title: Criando Alvos de Eventos +slug: Mozilla/Add-ons/SDK/Tutorials/Creating_event_targets +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Creating_event_targets +--- +

Este tutorial descreve o uso de APIS de baixo nível. Estas APIs estão ainda em desenvolvimento, e nós esperamos fazer mudanças incompatíveis nela em lançamentos futuros.

+ +

O guia de programação de eventos dirigidos com SDK descreve como consumir eventos: isto é, como escutar eventos gerados pelo alvos de evento. Por exemplo, você pode escutar ao evento evento ready do módulo tab ou o event show do objeto Panel.

+ +

Com o SDK, também é simples implementar seus próprios alvos de eventos. Isto é especialmente útil se você quiser construir seus próprios módulos, ou organizar seu add-on melhor ou permitir a outros desenvolvedores reusar seu código. Se você usa o framework de eventos do SDK para seus alvos de eventos, os usuários de seus módulos podem escutar pelos eventos usando a API de evento padrão do SDK.

+ +

Neste tutorial nów criaremos parte de um módulo para acessar a API Local do navegador. Ele emitirá eventos quando o usuário adicionar e visitar um favorito, permitindo aos usuários escutar estes eventos usando a API de evento padrão do SDK.

+ +

Usando a API Local

+ +

Primeiro, vamos escrever algun código usando a API Local que registra as URIs do favorito que o usuário adicinou.

+ +

Crie uma novo diretório chamado "bookmarks", navegue até ele, e execute jpm init, aceitando todos os padrões. Então abra o "index.js" e adicione o seguinte código:

+ +
var {Cc, Ci, Cu} = require("chrome");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+var bookmarkService = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]
+                          .getService(Ci.nsINavBookmarksService);
+
+var bookmarkObserver = {
+  onItemAdded: function(aItemId, aFolder, aIndex) {
+    console.log("added ", bookmarkService.getBookmarkURI(aItemId).spec);
+  },
+  onItemVisited: function(aItemId, aVisitID, time) {
+    console.log("visited ", bookmarkService.getBookmarkURI(aItemId).spec);
+  },
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver])
+};
+
+exports.main = function() {
+  bookmarkService.addObserver(bookmarkObserver, false);
+};
+
+exports.onUnload = function() {
+  bookmarkService.removeObserver(bookmarkObserver);
+}
+
+ +

Tente executar este add-on, adicionando e visitando favoritos, e observando a saída no console.

+ +

Módulos como Alvos de Evento

+ +

Nós podemos adaptar esse código em módulos separados que expõe a interface de evento padrão do SDK.

+ +

Para fazer isso nós usaremos o módulo event/core.

+ +

Crie um novo arquivo no "lib" chamado "bookmarks.js", e adicione o seguinte código:

+ +
var { emit, on, once, off } = require("sdk/event/core");
+
+var {Cc, Ci, Cu} = require("chrome");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+var bookmarkService = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]
+                          .getService(Ci.nsINavBookmarksService);
+
+var bookmarkObserver = {
+  onItemAdded: function(aItemId, aFolder, aIndex) {
+    emit(exports, "added", bookmarkService.getBookmarkURI(aItemId).spec);
+  },
+  onItemVisited: function(aItemId, aVisitID, time) {
+    emit(exports, "visited", bookmarkService.getBookmarkURI(aItemId).spec);
+  },
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver])
+};
+
+bookmarkService.addObserver(bookmarkObserver, false);
+
+exports.on = on.bind(null, exports);
+exports.once = once.bind(null, exports);
+exports.removeListener = function removeListener(type, listener) {
+  off(exports, type, listener);
+};
+
+ +

Este código implementa um módulo que pode emitir eventos added e visited. Ele duplica o código anterior, mas com um pouco de mudanças:

+ + + +

O on() e once() exporta delegação a uma função correspondente do event/core, e usa bind() para passar o objeto exports por si só como o argumento target(alvo) à função subjacente. A função removeListener() é implementada pela chamada da função subjacente  off().

+ +

Nós podemos usar este módulo do mesmo modo que nós usamos qualquer outro módulo que emite eventos a nível de módulo, tais como tabs. Por exemplo, nós podemos adaptar o "index.js" como segue:

+ +
var bookmarks = require("./bookmarks");
+
+function logAdded(uri) {
+  console.log("added: " + uri);
+}
+
+function logVisited(uri) {
+  console.log("visited: " + uri);
+}
+
+exports.main = function() {
+  bookmarks.on("added", logAdded);
+  bookmarks.on("visited", logVisited);
+};
+
+exports.onUnload = function() {
+  bookmarks.removeListener("added", logAdded);
+  bookmarks.removeListener("visited", logVisited);
+}
+
+ +

Classes como Alvos de Eventos

+ +

Às vezes nós queremos emitir eventos à nível de objetos individuais, em vez de à nível de módulo.

+ +

Para fazer isto, nós podemos herdar da classe EventTarget do SDK. EventTarget fornece uma implementação das funções necessárias a adicionar e remover escutas: on(), once(), e removeListener().

+ +

Neste exemplo, nós poderíamos definir uma classe BookmarkManager que herda do EventTarget e emite eventos added e visited.

+ +

Abra o "bookmarks.js" e substitua seu conteúdo com este código:

+ +
var { emit } = require("sdk/event/core");
+var { EventTarget } = require("sdk/event/target");
+var { Class } = require("sdk/core/heritage");
+var { merge } = require("sdk/util/object");
+
+var {Cc, Ci, Cu} = require("chrome");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+var bookmarkService = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]
+                          .getService(Ci.nsINavBookmarksService);
+
+function createObserver(target) {
+   var bookmarkObserver = {
+     onItemAdded: function(aItemId, aFolder, aIndex) {
+       emit(target, "added", bookmarkService.getBookmarkURI(aItemId).spec);
+     },
+     onItemVisited: function(aItemId, aVisitID, time) {
+       emit(target, "visited", bookmarkService.getBookmarkURI(aItemId).spec);
+     },
+     QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver])
+   };
+   bookmarkService.addObserver(bookmarkObserver, false);
+}
+
+var BookmarkManager = Class({
+  extends: EventTarget,
+  initialize: function initialize(options) {
+    EventTarget.prototype.initialize.call(this, options);
+    merge(this, options);
+    createObserver(this);
+  }
+});
+
+exports.BookmarkManager = BookmarkManager;
+
+ +

O código para interagir com a API Local é o mesmo que aqui. Porém:

+ + + +

Para usar este alvo de evento nós podemos criar ele e chamar a funções on(), once(), e removeListener() que ele herdou:

+ +
var bookmarks = require("./bookmarks");
+var bookmarkManager = bookmarks.BookmarkManager({});
+
+function logAdded(uri) {
+  console.log("added: " + uri);
+}
+
+function logVisited(uri) {
+  console.log("visited: " + uri);
+}
+
+exports.main = function() {
+  bookmarkManager.on("added", logAdded);
+  bookmarkManager.on("visited", logVisited);
+};
+
+exports.onUnload = function() {
+  bookmarkManager.removeListener("added", logAdded);
+  bookmarkManager.removeListener("visited", logVisited);
+}
+
+ +

Implementando uma opção "onEvent"

+ +

Finalmente, a maioria dos alvos de eventos aceitam opções na forma "onEvent", onde "Event" é o nome do evento com a primeira letra em maiúsculo. Por exemplo, você pode escutar o evento show do objeto Panel ou chamando:

+ +
myPanel.on("show", listenerFunction);
+
+ +

ou passando a opção onShow para o construtor do Painel:

+ +
var myPanel = require("sdk/panel").Panel({
+  onShow: listenerFunction,
+  contentURL: "https://en.wikipedia.org/w/index.php"
+});
+
+ +

Se sua classe herda do EventTarget, opções como this são automaticamente manipuladas para você. Por exemplo, dada a implementação do BookmarkManager acima, seu "index.js" seria reescrito como isto:

+ +
var bookmarks = require("./bookmarks");
+
+function logAdded(uri) {
+  console.log("added: " + uri);
+}
+
+function logVisited(uri) {
+  console.log("visited: " + uri);
+}
+
+var bookmarkManager = bookmarks.BookmarkManager({
+  onAdded: logAdded,
+  onVisited: logVisited
+});
+
+exports.onUnload = function() {
+  bookmarkManager.removeListener("added", logAdded);
+  bookmarkManager.removeListener("visited", logVisited);
+}
+
diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/creating_reusable_modules/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/creating_reusable_modules/index.html new file mode 100644 index 0000000000..837583f9c8 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/creating_reusable_modules/index.html @@ -0,0 +1,253 @@ +--- +title: Criando Módulos Reutilizáveis +slug: Mozilla/Add-ons/SDK/Tutorials/Creating_reusable_modules +tags: + - Add-on SDK +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Creating_reusable_modules +--- +
Para seguir este tutorial você precisa do SDK instalado e conhecimento básico de cfx.
+ +

Com o SDK você não precisa manter tudo em um único arquivo "main.js". Você pode separar seu código em módulos separados com interfaces claramente definidas entre eles. Você então importa e usa estes módulos de outras partes de seu add-on usando a declaração require(), da mesma forma que você importa os módulos core do SDK como page-mod or panel.

+ +

Muitas vezes faz sentido estruturar um add-on muito grande ou complexo como uma coleção de módulos. Isso torna o desenho do add-on mais fácil de entender e fornece algum encapsulamento em que cada módulo exportará somente o que ele escolheu, então você pode mudar o módulo internamente sem quebrar seu usuário.

+ +

Uma vez que você fez isso, você pode empacotar os módulos e distribui-los independentemente de seu add-on, tornando-os disponíveis para outros desenvolvedores de add-on e efetivamente extendendo o SDK.

+ +

Neste tutorial faremos exatamente isso com o módulo que calcula hashes de arquivo.

+ +

Um add-on de hashing

+ +

Uma função hash leva uma string de qualquer tamanho de bytes, e produz uma string curta e de tamanho fixo de bytes como saída. É um modo útil para criar um "fingerprint" que pode ser usado para identificar um arquivo. MD5 é uma função hash comumente usada: embora não seja considerada segura, ela trabalha bem desconsiderando o contexto da segurança.

+ +

Aqui nós escreveremos um add-on que deixa o usuário escolher uma arquivo no disco e calcula seu hash. Para ambas operações nós usaremos as interfaces XPCOM.

+ +

File picker

+ +

Para deixar o usuário selecionar um arquivo nós usaremos  o nsIFilePicker. A documentação para esta interface inclui um exemplo que nós podemos adaptar como este:

+ +
var {Cc, Ci} = require("chrome");
+
+function promptForFile() {
+  const nsIFilePicker = Ci.nsIFilePicker;
+
+  var fp = Cc["@mozilla.org/filepicker;1"]
+           .createInstance(nsIFilePicker);
+
+  var window = require("sdk/window/utils").getMostRecentBrowserWindow();
+  fp.init(window, "Select a file", nsIFilePicker.modeOpen);
+  fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
+
+  var rv = fp.show();
+  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
+    var file = fp.file;
+    // Pega o caminho como string. Note que você normalmente não
+    // precisará trabalhar com strings de caminho.
+    var path = fp.file.path;
+    // Trabalhe com o retorno de nsILocalFile...
+  }
+  return path;
+}
+ +

Função Hash

+ +

Firefox tem suporte embutido para funções hash, exposto via interface XPCOM nsICryptoHash. A página da documentação para esta interface inclui um exemplo de calculadora de hash MD5 do conteúdo do arquivo, dado seu caminho. Nós adaptamos como esta:

+ +
var {Cc, Ci} = require("chrome");
+
+// retorna o código hexadecimal de dois dígitos para um byte
+function toHexString(charCode) {
+  return ("0" + charCode.toString(16)).slice(-2);
+}
+
+function md5File(path) {
+  var f = Cc["@mozilla.org/file/local;1"]
+          .createInstance(Ci.nsILocalFile);
+  f.initWithPath(path);
+  var istream = Cc["@mozilla.org/network/file-input-stream;1"]
+                .createInstance(Ci.nsIFileInputStream);
+  // abrindo para leitura
+  istream.init(f, 0x01, 0444, 0);
+  var ch = Cc["@mozilla.org/security/hash;1"]
+           .createInstance(Ci.nsICryptoHash);
+  // nós queremos usar o algoritmo MD5
+  ch.init(ch.MD5);
+  // isto diz para updateFromStream ler o arquivo todo
+  const PR_UINT32_MAX = 0xffffffff;
+  ch.updateFromStream(istream, PR_UINT32_MAX);
+  // passe false aqui para conseguir os dados binários de volta
+  var hash = ch.finish(false);
+
+  // converte o hash binário para hex string.
+  var s = Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
+  return s;
+}
+ +

Colocando tudo junto

+ +

O add-on completo adiciona um botão ao Firfox: quando o usuário clica no botão, nós pedimos lhe para selecionar  um arquivo, e registramos o hash no console:

+ +
var {Cc, Ci} = require("chrome");
+
+// retorna o código hexadecimal de dois dígitos para um byte
+function toHexString(charCode) {
+  return ("0" + charCode.toString(16)).slice(-2);
+}
+
+function md5File(path) {
+  var f = Cc["@mozilla.org/file/local;1"]
+          .createInstance(Ci.nsILocalFile);
+  f.initWithPath(path);
+  var istream = Cc["@mozilla.org/network/file-input-stream;1"]
+                .createInstance(Ci.nsIFileInputStream);
+  // abrindo para leitura
+  istream.init(f, 0x01, 0444, 0);
+  var ch = Cc["@mozilla.org/security/hash;1"]
+           .createInstance(Ci.nsICryptoHash);
+  // nós queremos usar o algoritmo MD5
+  ch.init(ch.MD5);
+  // isto diz para updateFromStream ler o arquivo todo
+  const PR_UINT32_MAX = 0xffffffff;
+  ch.updateFromStream(istream, PR_UINT32_MAX);
+  // passe false aqui para conseguir os dados binários de volta
+  var hash = ch.finish(false);
+
+  // converte o hash binário para hex string.
+  var s = Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
+  return s;
+}
+
+function promptForFile() {
+  var window = require("sdk/window/utils").getMostRecentBrowserWindow();
+  const nsIFilePicker = Ci.nsIFilePicker;
+
+  var fp = Cc["@mozilla.org/filepicker;1"]
+           .createInstance(nsIFilePicker);
+  fp.init(window, "Select a file", nsIFilePicker.modeOpen);
+  fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
+
+  var rv = fp.show();
+  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
+    var file = fp.file;
+    // Pega o caminho como string. Note que você normalmente não
+    // precisará trabalhar com strings de caminho.
+    var path = fp.file.path;
+    // Trabalhe com o retorno de nsILocalFile...
+  }
+  return path;
+}
+
+require("sdk/ui/button/action").ActionButton({
+  id: "show-panel",
+  label: "Show Panel",
+  icon: {
+    "16": "./icon-16.png"
+  },
+  onClick: function() {
+    console.log(md5File(promptForFile()));
+  }
+});
+
+ +

Isso funciona, mas main.js está agora ficando mais longo e sua lógica mais difícil de entender. This works , but main.js is now getting longer and its logic is harder to understand. Vamos levar os códigos do "file picker" e do "hashing code" para módulos separados.

+ +

Criando módulos separados

+ +

filepicker.js

+ +

Primeiro criamos um novo arquivo no diretório "lib" chamado "filepicker.js". Copiamos o código do seletor de arquivos, e adicionamos a seguinte linha de código no fim dele:

+ +
exports.promptForFile = promptForFile;
+
+ +

Isso define a interface pública do novo módulo.

+ +

Então "filepicker.js" deve parecer com isto:

+ +
var {Cc, Ci} = require("chrome");
+
+function promptForFile() {
+  var window = require("sdk/window/utils").getMostRecentBrowserWindow();
+  const nsIFilePicker = Ci.nsIFilePicker;
+
+  var fp = Cc["@mozilla.org/filepicker;1"]
+           .createInstance(nsIFilePicker);
+  fp.init(window, "Select a file", nsIFilePicker.modeOpen);
+  fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
+
+  var rv = fp.show();
+  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
+    var file = fp.file;
+    // Get the path as string. Note that you usually won't
+    // need to work with the string paths.
+    var path = fp.file.path;
+    // work with returned nsILocalFile...
+  }
+  return path;
+}
+
+exports.promptForFile = promptForFile;
+
+ +

md5.js

+ +

Próximo, crie um outro arquivo no "lib", chamado "md5.js". Copie o código do hashing, e adicione esta linha ao seu fim:

+ +
exports.hashFile = md5File;
+ +

O arquivo completo parece com isto:

+ +
var {Cc, Ci} = require("chrome");
+
+//retorna o código hexadecimal de dois dígitos para um byte
+function toHexString(charCode) {
+  return ("0" + charCode.toString(16)).slice(-2);
+}
+
+function md5File(path) {
+  var f = Cc["@mozilla.org/file/local;1"]
+          .createInstance(Ci.nsILocalFile);
+  f.initWithPath(path);
+  var istream = Cc["@mozilla.org/network/file-input-stream;1"]
+                .createInstance(Ci.nsIFileInputStream);
+  // abrindo para leitura
+  istream.init(f, 0x01, 0444, 0);
+  var ch = Cc["@mozilla.org/security/hash;1"]
+           .createInstance(Ci.nsICryptoHash);
+  // nós queremos usar o algoritmo MD5
+  ch.init(ch.MD5);
+  // isto diz para updateFromStream ler o arquivo todo
+  const PR_UINT32_MAX = 0xffffffff;
+  ch.updateFromStream(istream, PR_UINT32_MAX);
+  // passe false aqui para conseguir os dados binários de volta
+  var hash = ch.finish(false);
+
+  // converte o hash binário para hex string.
+  var s = Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
+  return s;
+}
+
+exports.hashFile = md5File;
+ +

main.js

+ +

Finalmente, atualizamos o main.js para importar estes dois módulos e usá-los:

+ +
var filepicker = require("./filepicker.js");
+var md5 = require("./md5.js");
+
+require("sdk/ui/button/action").ActionButton({
+  id: "show-panel",
+  label: "Show Panel",
+  icon: {
+    "16": "./icon-16.png"
+  },
+  onClick: function() {
+    console.log(md5.hashFile(filepicker.promptForFile()));
+  }
+});
+ +

Você pode distribuir estes módulos para outros desenvolvedores, também. Eles podem copia-los em algum lugar do add-on, e inclui-los usando require() do mesmo modo.

+ +

Aprendendo Mais

+ +

Para ver alguns módulos que as pessoas já desenvolveram, veja a página community-developed. Para aprender como usar módulos de terceiros em seu próprio código, veja o tutorial adicionando itens de menu.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html new file mode 100644 index 0000000000..9190e825ab --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html @@ -0,0 +1,155 @@ +--- +title: Começando (jpm) +slug: Mozilla/Add-ons/SDK/Tutorials/Getting_Started_(jpm) +tags: + - Add-on SDK + - JPM +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Getting_Started_(jpm) +--- +
+

O Add-on SDK inclui uma ferramenta de linha de comando que você usa para inicializar, executar, testar, e empacotar add-ons. A ferramenta de linha de comando atual é chamada de jpm, e é baseada no Node.js. Ela substitui a ferramenta antiga cfx.

+ +

Você pode usar o jpm do Firefox 38 em diante.

+ +

Este artigo descreve como desenvolver usando jpm.

+
+ +

Este tutorial ensina a criação de uma add-on simples usando o SDK.

+ +

Pré-requisitos

+ +

Para criar add-ons para Firefox usando o SDK, você precisará:

+ + + +

Inicializando um add-on vazio

+ +

No promp de comando, crie um novo diretório. Navegue até ele, digite jpm init, e tecle enter:

+ +
mkdir my-addon
+cd my-addon
+jpm init
+
+ +

Você será instado à fornecer algumas informações para seu add-on: isso será usado para criar o arquivo package.json do seu add-on. Por enquanto, apenas pressione enter para aceitar o padrão para cada propriedade. Para mais informação sobre jpm init, veja o jpm command reference.

+ +

Uma vez que você forneceu um valor ou aceitou o padrão para estas propriedades, será apresentado a você o conteúdo completo do "package.json" e instado a aceitá-lo.

+ +

Implementando o add-on

+ +

Agora você pode escrever o código do add-on. A menos que você mudou o valor de entrada ("main" no package.json), ele vai no arquivo "index.js" na raiz de seu add-on. Este arquivo foi criado para você no passo anterior. Abra-o e adicione o seguinte código:

+ +
var buttons = require('sdk/ui/button/action');
+var tabs = require("sdk/tabs");
+
+var button = buttons.ActionButton({
+  id: "mozilla-link",
+  label: "Visit Mozilla",
+  icon: {
+    "16": "./icon-16.png",
+    "32": "./icon-32.png",
+    "64": "./icon-64.png"
+  },
+  onClick: handleClick
+});
+
+function handleClick(state) {
+  tabs.open("http://www.mozilla.org/");
+}
+
+ +
+

Note que os "pontos de entrada" padrões para "index.js" no jpm, signifca que seu arquivo principal é "index.js", e é encontrado diretamente na raiz do seu add-on.

+ +

No cfx, o ponto de entrada padrão para "main.js", e é localizado no diretório "lib" na raiz no add-on.

+
+ +

Salve o arquivo.

+ +

Próximo, crie um diretório chamado "data" na raiz do add-on, e salve estes três ícones no diretório "data":

+ + + + + + + + + + + + + + + + +
icon-16.png
icon-32.png
icon-64.png
+ +

Volte ao promp de comando, digite:

+ +
jpm run
+ +

Este é o comando jpm para executar uma nova instância do Firefox com seu add-on instalado.

+ +

Quando o Firefox lança, no canto superior direito do navegador você verá um ícone com o logotipo do Firefox. Clique no ícone, e uma nova tab abrirá com o site http://www.mozilla.org/ carregado.

+ +

Isso é tudo que este add-on faz. Ele usa dois módulos SDK: o módulo action button, que lhe permite adicionar botões ao navegador, e o módulo tab, que lhe permite executar operações básicas com o módulo tabs. Neste caso, nós criamos um botão cujo ícone é o ícone do Firefox, e adicionamos um manipulado de click que carrega a página do Mozilla na nova tab.

+ +

Tente editar este arquivo. Por exemplo, nós poderíamos mudar a página que está sendo carregada:

+ +
var buttons = require('sdk/ui/button/action');
+var tabs = require("sdk/tabs");
+
+var button = buttons.ActionButton({
+  id: "mozilla-link",
+  label: "Visit Mozilla",
+  icon: {
+    "16": "./icon-16.png",
+    "32": "./icon-32.png",
+    "64": "./icon-64.png"
+  },
+  onClick: handleClick
+});
+
+function handleClick(state) {
+  tabs.open("https://developer.mozilla.org/");
+}
+ +

No promp de comando, execute jpm run novamente. Desta vez clicando lhe levará para https://developer.mozilla.org/.

+ +

Empacotando o add-on

+ +

Quando você terminou o add-on e estiver preparado para distribui-lo, você precisará empacotá-lo como um arquivo XPI. Esta é a forma instalável dos add-ons do Firefox. Você pode distribuir os arquivos XPI por si mesmo ou publicá-los em https://addons.mozilla.org então outros usuários podem baixar eles.

+ +

Para construir um XPI, apenas execute o comando jpm xpi do diretório do add-on:

+ +
jpm xpi
+
+ +

Você deveria ver uma mensagem como:

+ +
JPM info Successfully created xpi at /path/to/getting-started/@getting-started.xpi
+
+ +

Para testar que isso funciona, tente instalar o arquivo XPI em sua própria instalação do Firefox. Você pode fazer isso pressionando a combinação de teclas Ctrl+O (Cmd+O no Mac) de dentro do Firefox, ou selecionando o menu "Open" do menu "Arquivo" do Firefox. Isso trará uma caixa de diálogo de seleção de arquivo: navegue para o arquivo "@getting-started.xpi", abra-o e siga o prompt para instalar o add-on.

+ +

Resumo

+ +

Neste tutorial nós construímos e empacotamos um add-on usando três comandos:

+ + + +

Há três comandos principais que você usará quando desenvolvendo add-ons com SDK. Há documentação abrangente no reference documentation cobrindo todos os comandos  que você pode usar e todas as opções que eles levam.

+ +

O código do add-on por si usa dois módulos SDK, action button e tabs. Há documentação de referência para todas as APIS do SDK tanto as de alto nível quanto as de baixo nível.

+ +

O que vem agora?

+ +

Para ter uma ideia das coisas que você pode fazer com as APIs do SDK, tente trabalhar com alguns dos tutoriais.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/index.html new file mode 100644 index 0000000000..6d5484bc46 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/index.html @@ -0,0 +1,144 @@ +--- +title: Tutoriais +slug: Mozilla/Add-ons/SDK/Tutorials +tags: + - Add-on SDK +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials +--- +

Esta página lista artigos úteis e práticos sobre como executar tarefas específicas usando o SDK.

+ +
+

Começando

+ +
+
+
+
Instalação
+
Download, instalar, e inicializar o SDK no Windows, OS X e Linux.
+
+ +
+
Solução de problemas
+
Algumas dicas para resolver problemas comuns e conseguir mais ajuda.
+
+
+ +
+
+
Começando
+
Criação passo-a-passo de um add-on simples com o SDK.
+
+
+
+ +
+

Criando interfaces de usuário

+ +
+
+
+
Adicionando um botão de barra de ferramenta
+
Anexe um botão à barra de ferramentas de add-on do Firefox.
+
Adicione um item de menu ao Firefox
+
Adicione itens ao menu principal do Firefox.
+
+
+ +
+
+
Mostre um popup
+
Mostre um diálogo popup implementado com HTML e JavaScript.
+
Adicione um item ao menu de contexto
+
Adicione itens ao menu de contexto do Firefox.
+
+
+
+ +
+

Interagindo com o navegador

+ +
+
+
+
Abra uma página
+
Abra uma página web em um novo navegador ou janela usando o módulo tabs, e acesse seu conteúdo.
+
Observando páginas carregadas
+
Use o módulo tabs para conseguir notificação quando novas páginas são carregadas, e acesse seu conteúdo.
+
+
+ +
+
+
Capturando a lista de tabs abertas
+
Use o módulo tab para interagir pelas tabs atualmente abertas, e acesse seu conteúdo.
+
+
+
+ +
+

Modificando páginas web

+ +
+
+
+
Modificar páginas web baseado na URL
+
Crie um filtro para páginas web baseado em sua URL: sempre que uma página web cuja URL combinar com o filtro carregado, executa um script espeficado nela.
+
+
+ +
+
+
Modificar a página web ativa
+
Carrega dinamicamente um script dentro da página web ativa atualmente.
+
+
+
+ +
+

Técnicas de desenvolvimento

+ +
+
+
+
Restro de log
+
Registra mensagens para o console para propósito de diagnóstico.
+
Criando módulos reutilizáveis
+
Estruture seu add-on em módulos separados deixando mais fácil o desenvolvimento, depuração e manutenção. Crie pacotes reutilizáveis contendo seus módulos, assim outros desenvolvedores de add-on podem usá-los também.
+
Teste de unidade
+
Escrevendo e executando teste de unidade usando framework de teste do SDK.
+
Chrome authority
+
Conseguindo acesso ao objeto Components, permitindo a seu add-on carregar e usar qualquer objeto XPCOM.
+
Criando event targets
+
Permite aos objeto que você define emitir seus próprios eventos.
+
+
+ +
+
+
Observando load e unload
+
Receba notificações quando seu add-on é caregado ou descarregado pelo Firefox, e passa argumentos do seu add-on a partir da linha de comando.
+
Usando módulos de terceiros
+
Instale e use módulos adicionais que não são fornecidos com o SDK.
+
Localização
+
Escrever código localizável.
+
Desenvolvimento mobile
+
Develop add-ons for Firefox Mobile on Android.
+
Depuração do Add-on
+
Depure o JavaScript do seu add-on.
+
+
+
+ +
+

Colocando tudo junto

+ +
+
+
+
Add-on Annotator
+
Um guia para um add-on relativamente complexo.
+
+
+
+ +

 

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/l10n/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/l10n/index.html new file mode 100644 index 0000000000..4a762bda9b --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/l10n/index.html @@ -0,0 +1,380 @@ +--- +title: Localização +slug: Mozilla/Add-ons/SDK/Tutorials/l10n +tags: + - Add-on SDK + - Localização +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/l10n +--- +

O SDK suporta localização de strings que aparecem no:

+ + + +

Ele, ainda, não suporta localização de conteúdo CSS ou Scripts.

+ +

Strings de Localização

+ +

Strings traduzidas são mantidas em um diretório chamado "locale" no diretório principal do seu add-on, um arquivo para cada locale. Os arquivos:

+ + + +

Suponha que seu add-on contém uma única string localizável, representada em Inglês como "Hello!", e você quer suprir com localizações US English e Francês.

+ +

Você adiciona dois arquivos ao diretório "locale":

+ +
my-addon/
+         data
+         lib
+         locale/
+                en-US.properties
+                fr-FR.properties
+
+ +

"en-US.properties" contém isto:

+ +
hello_id= Hello!
+
+ +

"fr-FR.properties" contém isto:

+ +
hello_id= Bonjour !
+
+ +

Agora que sempre que em seu código JavaScript ou HTML pedir  ao sistema de localização pela tradução do identificador hello_id, ele pegará a tradução correta para a localidade atual.

+ +

Usando Strings de Localização no HTML

+ +
+

Este exemplo usa a API action button, que está disponível somente do Firefox 29 em diante.

+
+ +

Para referenciar uma string localizada do HTML, adicione um atributo data-l10n-id à tag HTML onde você quiser que a string localizada apareça, e atribua o identificador a ele:

+ +
<html>
+  <body>
+    <h1 data-l10n-id="hello_id"></h1>
+  </body>
+</html>
+
+ +

Então você pode usar o arquivo HTML para construir sua interface, por exemplo dentro de um painel:

+ +
var button = require("sdk/ui/button/action").ActionButton({
+  id: "localized-hello",
+  label: "Localized hello",
+  icon: "./icon-16.png",
+  onClick: function() {
+    hello.show();
+  }
+});
+
+var hello = require("sdk/panel").Panel({
+  height: 75,
+  width: 150,
+  contentURL: require("sdk/self").data.url("my-panel.html")
+});
+ +

Dados os arquivos locale para "en-US" e "fr-FR" que fornece uma tradução para o hello_id, o painel agora mostrará o "Hello!" ou "Bonjour !", de acordo com a localidade atual:

+ +

+ +

A tradução é inserida dentro do nó que tem o atributo data-l10n-id. Qualquer conteúdo anteriormente existente é substituído.

+ +

A string é inserida como texto, então você não pode inserir HTML usando declarações como:

+ +
hello_id= <blink>Hello!</blink>
+
+ +

Localizando Atributos de Elementos

+ +
Esta característica é nova no Firefox 39
+ +


+ Você pode localizar certos atributos de elementos com um l10n-id configurando seu valor com o l10-id.attributeName no arquivo da propriedade como isto:

+ +
hello_id.accesskey= H
+ +

Os seguintes atributos são suportados:

+ + + +

Além disso, a localização dos atributos ARIA aria-label, aria-valuetext e aria-moz-dica são suportados com os mesmos apelidos que no Firefox OS:

+ + + +

Usando Strings de Localização no JavaScript

+ +

Para referenciar Strings de Localização do código principal do seu add-on, você faz isso:

+ +
var _ = require("sdk/l10n").get;
+console.log(_("hello_id!"));
+ +

A atribuição de "_" em particular não é requerida, mas é uma convenção da ferramente gettext e torna possível trabalhar com ferramentas existentes que esperam "_" para indicar Strings de Localização.

+ +
    +
  1. Importe o módulo l10n, atribua sua função get o "_" (underscore).
  2. +
  3. Envolva todas as referências a Strings de Localização com uma função _().
  4. +
+ +

Se você executar ela você verá a saída esperada para a localidade atual:

+ +
info: Hello!
+
+ +
info: Bonjour !
+
+ +

Observe que você não pode require() módulos nos scripts de conteúdo, você ainda não pode referenciar strings de localização nos scripts de conteúdo.

+ +

Plurais

+ +

O módulo l10n suporta formas plurais. Diferentes línguas tem diferentes regras para formação de plurais. Por exemplo, Inglês tem duas formas: uma forma singular para "one", e uma forma plural para "everything else, including zero":

+ +
one tomato
+no tomatoes
+two tomatoes
+
+ +

Mas a Russa tem diferentes formas para números terminados em 1 (exceto 11), números terminados em 2-4 (exceto 12-14) e outros números:

+ +
один помидор     // one tomato
+два помидора     // two tomatoes
+пять помидоров   // five tomatoes
+
+ +

O SDK usa dados do Unicode CLDR para descrever as diferentes formas de plural usadas pelas diferentes línguas.

+ +

Formas Plurais do Unicode CLDR

+ +

O projeto Unicode CLDR define um esquema que descreve a regras de plural de uma língua em particular. Neste esquema uma  língua mapeia cada abrangência distinta de números para um ou mais formas, identificado pelas categorias: zero, one, two, few, many, e other.

+ +

Inglês tem duas formas, que podem ser descritas pelo mapeamento "1" para "one" e "everything else" para "other":

+ +
one   → n is 1;
+other → everything else
+
+ +

A Russa usa quatro formas, que podem ser descritas como se segue:

+ +
one   → n mod 10 is 1 and n mod 100 is not 11;
+few   → n mod 10 in 2..4 and n mod 100 not in 12..14;
+many  → n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14;
+other → everything else
+
+ +

As regras de plural para todas as línguas podem ser encontrada na página de Regras para Plural das Línguas do CLDR (embora esta tabela esteja desatualizada se comparada com a CLDR XML source).

+ +

Formas Plurais no SDK

+ +

No código, você fornece uma parâmetro extra ao lado do identificador, descrevendo quantos itens há:

+ +
var _ = require("sdk/l10n").get;
+console.log(_("tomato_id"));
+console.log(_("tomato_id", 1));
+console.log(_("tomato_id", 2));
+console.log(_("tomato_id", 5));
+console.log(_("tomato_id", .5));
+ +

No arquivo .properties para cada língua você pode definir uma localização diferente para cada forma de plural possível naquela língua, usando palavras reservadas do CLDR. Então no Inglês nós teríamos duas localizações de plural (observe que a categoria "other" não leva palavra reservada do CLDR:

+ +
# en-US translations
+tomato_id[one]= %d tomato
+tomato_id= %d tomatoes
+
+ +

Na Russa nós teríamos quatro localizações de plural:

+ +
# ru-RU translations
+tomato_id[one]= %d помидор
+tomato_id[few]= %d помидора
+tomato_id[many]= %d помидоров
+tomato_id= %d помидоры
+
+ +

O módulo de localização por si só entende as definições CLDR para cada língua, permitindo a ele mapear, por exemplo, "2" no código e "few" no arquivo ru-RU.properties. Então ele pega e retorna a localização apropriada para a contagem fornecida.

+ +

Placeholders

+ +

O módulo l10n suporta placeholders, permitindo a você inserir uma string que não deveria ser localizada em uma que é. Os seguintes arquivos "en-US" e "fr-FR" ".properties" estão incluídos placeholders:

+ +
# en-US translations
+hello_id= Hello %s!
+
+ +
# fr-FR translations
+hello_id= Bonjour %s !
+
+ +

Para usar placeholders, forneça uma string placeholder depois do identificador:

+ +
var _ = require("sdk/l10n").get;
+console.log(_("hello_id", "Bob"));
+console.log(_("hello_id", "Alice"));
+ +

Na localidade Inglês "en-US", isto nos é dado:

+ +
info: Hello Bob!
+info: Hello Alice!
+
+ +

No "fr-FR" nós conseguimos:

+ +
info: Bonjour Bob !
+info: Bonjour Alice !
+
+ +

Ordenando Placeholders

+ +

Quando strings localizáveis podem levar dois ou mais placeholders, tradutores podem definir a ordem em que placeholders são inseridos, sem afetar o código.

+ +

Primeiramente, isto é importante porque diferentes línguas tem regras diferentes para ordernar palavras. Mesmo dentro de uma mesma língua, embora traduzida, tradutores deve ter liberdade para definir a ordem.

+ +

Por exemplo, suponha que nós queremos incluir uma string de localização designando a cidade de uma pessoa. Há dois placeholders: o nome da pessoa e o nome da cidade em que ela reside:

+ +
var _ = require("sdk/l10n").get;
+console.log(_("home_town_id", "Bob", "London"));
+ +

An English translator might want to choose between the following:

+ +
"<town_name> is <person_name>'s home town."
+
+ +
"<person_name>'s home town is <town_name>"
+
+ +

Para escolher a primeira opção, o arquivo .properties pode ordenar o placeholders como:

+ +
home_town_id= %2s is %1s's home town.
+
+ +

Isso nos dá a seguinte saída:

+ +
info: London is Bob's home town.
+
+ +

Usando Strings de localização em Preferências

+ +

Pela inclusão de uma estrutura "preferences" no arquivo "package.json" do seu add-on, você pode definir preferências para seu add-on que o usuário pode ver e editar usando o gerenciador de add-ons do Firefox.

+ +

Preferências tem um campo title obrigatório e um campo description opcional. Há strings que aparecem ao lado da preferência no gerenciador de Add-on, para ajudar a explicar ao usuário o que a preferência significa.

+ + + +

Por exemplo, suponha que seu "package.json" defina uma única preferência:

+ +
{
+    "preferences": [
+        {
+            "type": "string",
+            "name": "monster_name",
+            "value": "Gerald",
+            "title": "Name"
+        }
+    ],
+    "name": "monster-builder",
+    "license": "MPL 2.0",
+    "author": "me",
+    "version": "0.1",
+    "fullName": "Monster Builder",
+    "id": "monster-builder@me.org",
+    "description": "Build your own monster"
+}
+
+ +

Em seu arquivo "en-US.properties", inclua estes dois itens:

+ +
monster_name_title= Name
+monster_name_description= What is the monster's name?
+
+ +

Em seu arquivo "fr-FR.properties", inclui a tradução francesa:

+ +
monster_name_title= Nom
+monster_name_description= Quel est le nom du monstre ?
+
+ +

Agora quando o local do navegador estiver configurado para "en-US", os usuários verão este Gerenciador de Add-on:

+ +

+ +

Quando o local do navegador estiver configurado para "fr-FR", eles verão isto:

+ +

+ +

Os tipos de preferência de menulist e radio tem opções. O atributo label de cada opção é mostrado para o usuário. Se o arquivo de local tem uma entrada com o valor do atributo label prefixado com "{name}_options." como sua chave, onde {name} é o nome da preferência, seu valor é usado como rótulo por localização.

+ +

Usando identificadores

+ +

Se o sistema de localização não pode encontrar uma entrada para um identificador em particular usando a localidade atual, então ele apenas retorna o identificador por si mesmo.

+ +

Isto tem a bonita propriedade que você pode escrever add-on localizável, inteiramente funcional sem ter que escrever qualquer arquivo local. Você pode usar somente a linguagem padrão como seu identificador, e subsequentemente fornecer arquivos .properties para todos os locais adicionais que você quiser suportar.

+ +

Por exemplo, no caso acima você poderia usar "Hello!" como o identificador, e apenas ter um arquivo .properties para a localidade "fr-FR":

+ +
Hello!= Bonjour !
+
+ +

Então quando a localidade é "en-US", o sistema falharia ao encontrar o arquivo  .properties file, e retornaria "Hello!".

+ +

Porém, essa técnica torna difícil manter um add-on que tem muitas localizações, porque você estará usando a língua padrão tanto para strings de interface quanto chaves de tradução. Isto significa que se você quiser mudar o nome de uma string na língua padrão, ou consertar a digitação, então você quebrará todos os seus arquivos de tradução.

+ +

Locale Updater

+ +

O addon locale updater torna fácil atualizar arquivos de localidade. Uma vez que você o instalou, abra o Gerenciador de Add-on, e você verá um novo botão rotulado "Update l10n" próximo a cada add-on que você instalou:

+ +

+ +

Clique no botão e você será instado a enviar um arquivo .properties para aquele add-on. Se você fornecer um novo arquivo, o locale do add-on será atualizado com o novo arquivo.

+ +

Limitações

+ +

A localização atual suportada é o primeiro passo  ao inteiro suporte, e contem uma série de limitações.

+ + + +

Veja também - para desenvolvedores que localização em add-on que não são do SDK

+ + diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/lista_de_tabs_abertas/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/lista_de_tabs_abertas/index.html new file mode 100644 index 0000000000..d3d537037d --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/lista_de_tabs_abertas/index.html @@ -0,0 +1,67 @@ +--- +title: Lista de Tabs Abertas +slug: Mozilla/Add-ons/SDK/Tutorials/Lista_de_Tabs_Abertas +tags: + - Add-on SDK + - Listando tabs abertas +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/List_Open_Tabs +--- +
+

Para seguir este tutorial você precisará ter instalado o SDK e ter conhecimento básico sobre cfx.

+ +

Este tutorial usa a API action button, que está disponível somente do Firefox 29 em diante.

+
+ +

Para listar as tabs abertas, você pode iterar sobre o objeto tabs.

+ +

O add-on a seguir adiciona um action button que registra as URLs abertas nas tabs quando clicado:

+ +
require("sdk/ui/button/action").ActionButton({
+  id: "list-tabs",
+  label: "List Tabs",
+  icon: "./icon-16.png",
+  onClick: listTabs
+});
+
+function listTabs() {
+  var tabs = require("sdk/tabs");
+  for (let tab of tabs)
+    console.log(tab.url);
+}
+
+ +

Note que para fazer isso funcionar você precisa salvar um ícone para o botão no diretório "data" do seu add-on como "icon-15.png": você pode baixar o ícone daqui: .

+ +

Se você executar o add-on, carregar um grupo de tabs, e clicar no botão, você verá a saída no linha de comando do console que parece com isto:

+ +
info: http://www.mozilla.org/en-US/about/
+info: http://www.bbc.co.uk/
+
+ +

Você não consegue acesso direto a qualquer conteúdo hospedado na tab. Para acessar o conteúdo da tab você precisa anexar um script à tab usando tab.attach(). Este add-on anexa um script a todas as tabs abertas. O script adiciona uma borda vermelha ao documento da tab:

+ +
require("sdk/ui/button/action").ActionButton({
+  id: "list-tabs",
+  label: "List Tabs",
+  icon: "./icon-16.png",
+  onClick: listTabs
+});
+
+function listTabs() {
+  var tabs = require("sdk/tabs");
+  for (let tab of tabs)
+    runScript(tab);
+}
+
+function runScript(tab) {
+  tab.attach({
+    contentScript: "document.body.style.border = '5px solid red';"
+  });
+}
+
+ +

Aprendendo Mais

+ +

Para aprender mais sobre como trabalhar com tabs no SDK, veja a referência da API tabs.

+ +

Para aprender mais sobre execução de scripts em tabs, veja o tutorial sobre uso do tab.attach().

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/listening_for_load_and_unload/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/listening_for_load_and_unload/index.html new file mode 100644 index 0000000000..5e3818036f --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/listening_for_load_and_unload/index.html @@ -0,0 +1,60 @@ +--- +title: Capturando Load e Unload +slug: Mozilla/Add-ons/SDK/Tutorials/Listening_for_load_and_unload +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Listening_for_load_and_unload +--- +
+

Para seguir este tutorial você precisará ter conhecimento básico de jpm.

+
+ +

Se seu add-on exporta uma função chamada main(), então aquela função será chamada sempre que o add-on for carregado, e será passada uma string descrevendo a razão de ele ter sido carregado bem como qualquer argumento passado para ele. Se seu add-on exporta uma função chamada onUnload(), então esta função será chamada quando o add-on for descarregado, e será passada uma string descrevendo a razão da descarga.

+ +

Você não tem que usar exports.main() ou exports.onUnload(). Você pode colocar o código do seu add-on no nível superior ao invés de envolver ele em uma atribuição de função para exports.main(). Ele será carregado nas mesmas circunstâncias, mas você não conseguirá acesso às razões da carga ou descarga dele bem como de seus argumentos.

+ +

exports.main()

+ +

O código main.js do seu add-on é executado assim que ele é carregado. Ele é carregado quando ele é instalado, habilitado ou quando inicia o Firefox.

+ +

Se seu add-on exporta uma função chamada main(), aquela função será chamada imediatamente depois que o main.js esteja completamente avaliado, e depois de todas as declarações require() de nível superior serem executadas (então geralmente depois de todas módulos dependentes serem carregados).

+ +
+
+
exports.main = function (options, callbacks) {};
+
+
+ +

options é um objeto descrevendo os parâmetros com os quais seu add-on foi carregado

+ +

options.loadReason

+ +

options.loadReason é uma das seguintes strings descrevendo a razão de seu add-on ter sido carregado:

+ +
install
+enable
+startup
+upgrade
+downgrade
+
+ +

exports.onUnload()

+ +

Se seu add-on exporta uma função chamada onUnload(), aquela função será chamando quando o add-on for descarregado.

+ +
+
+
exports.onUnload = function (reason) {};
+
+
+ +

reason

+ +

reason é uma das seguintes strings descrevendo a razão do add-on ter sido descarregado:

+ +
uninstall
+disable
+shutdown
+upgrade
+downgrade
+
+ +

Devido ao bug 627432, sua captura de descarga (onUnload) nunca será chamada com uninstall: ela somente é chamada com disable. Veja no comentário particular sobre este bug.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/logging/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/logging/index.html new file mode 100644 index 0000000000..088d694408 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/logging/index.html @@ -0,0 +1,55 @@ +--- +title: Logging +slug: Mozilla/Add-ons/SDK/Tutorials/Logging +tags: + - Add-on SDK + - console +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Logging +--- +
Para seguir este tutorial você precisa do SDK instalado e conhecimento básico de cfx.
+ +

O objeto DOM console é útil para depuração do JavaScript. Porque os objetos DOM não estão disponíveis para o código principal do add-on, o SDK fornece seu próprio objeto global console com a maiorira dos mesmos métodos do do console DOM, incluindo métodos para registrar erros, avisos, ou mensagens informativas. Você não tem que usar require() qualquer coisa para conseguir acesso ao console. Ele está disponível para você.

+ +

O método console.log() imprime mensagens informativas:

+ +
console.log("Hello World");
+
+ +

Tente:

+ + + +

O Firefox iniciará, e a linha a seguir aparecerá na janela de comando que você usou para executar cfx run:

+ +
info: Hello World!
+
+ +

console em Scripts de Conteúdo

+ +

Você pode usar console em scripts de conteúdo assim como no código principal do seu add-on. O add-on a seguir registra o conteúdo do HTML de toda a tab que o usuário carregar, chamando console.log() dentro do script de conteúdo:

+ +
require("sdk/tabs").on("ready", function(tab) {
+  tab.attach({
+    contentScript: "console.log(document.body.innerHTML);"
+  });
+});
+
+ +

Saída do console

+ +

Se você estiver executando seu add-on da linha de comando (por exemplo, executando cfx run ou cfx test) então as mensagens do console aparece no shell de comando usado.

+ +

Se você instalou o add-on no Firefox então as mensagens aparecerão no Console do Navegador do Firefox.

+ +

Mas note que por padrão, chamadas à console.log() não resultarão em qualquer saída no Console de Erro por qualquer add-on instalado: isso inclui add-ons instalados usando o Add-on Builder ou usando ferramentas como Extension Auto-installer.

+ +

Veja "Logging Levels" na documentação de referência para mais informações.

+ +

Aprendendo Mais

+ +

Para a API completa do console, veja sua referência da API.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html new file mode 100644 index 0000000000..6b8f02c265 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html @@ -0,0 +1,137 @@ +--- +title: Modificando a Página Aberta em uma Tab +slug: Mozilla/Add-ons/SDK/Tutorials/Modifying_the_Page_Hosted_by_a_Tab +tags: + - Add-on SDK +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Modifying_the_Page_Hosted_by_a_Tab +--- +
+

Para seguir este tutorial, você precisará ter instalado add-on SDK e ter conhecimento básico jpm (Firefox 38 em diante) ou básico do cfx .

+ +

Este tutorial usa a API action button, que está disponível a partir do Firefox 29 em diante.

+
+ +

Para modificar uma página armazenada em uma tab em particular, carregue um ou mais scripts de conteúdo dentro dela usando o método attach() do objeto tab. A tarefa desses scripts é interagir com o conteúdo web.

+ +

Aqui está um exemplo simples:

+ +
var button = require("sdk/ui/button/action").ActionButton({
+  id: "style-tab",
+  label: "Style Tab",
+  icon: "./icon-16.png",
+  onClick: function() {
+    require("sdk/tabs").activeTab.attach({
+      contentScript: 'document.body.style.border = "5px solid red";'
+    });
+  }
+});
+ +

Execute esse exemplo, salve o ícone chamado "icon-16.png" no diretório "data" do add-on. Você To run this example, save an icon file named "icon-16.png" in add-on's "data" directory. Você pode baixar este ícone: .

+ +

This add-on creates a button with Mozilla favicon as an icon. It has a click handler which fetches the active tab and loads a script into the page hosted by the active tab. The script is specified using the contentScript option, and just draws a red border around the page.

+ +

Then open any web page in the browser window, and click the button . You should see a red border appear around the page, like this:

+ +

+ +

Mantendo o script de conteúdo em arquivo separado

+ +

No exemplo acima, nós passamos o script de conteúdo como uma string.

+ +

A menos que o script seja extremamente simples, o melhor é manter o script em um arquivo separado no diretório data do add-on. Isso deixa o código mais fácil para manter, depurar, e revisar. Faça isto, forneça a opção contentScriptFile não contentScript, cujo valor é uma URL apontando para um ou mais arquivos de script de conteúdo.

+ +

Por exemplo, se nós salvarmos o script acima no diretório data do add-on em um arquivo chamado my-script.js:

+ +
var self = require("sdk/self");
+
+var button = require("sdk/ui/button/action").ActionButton({
+  id: "style-tab",
+  label: "Style Tab",
+  icon: "./icon-16.png",
+  onClick: function() {
+    require("sdk/tabs").activeTab.attach({
+      contentScriptFile: self.data.url("my-script.js")
+    });
+  }
+});
+
+ +

Você pode carregar mais de um script, e os scripts podem interagir diretamente um com o outro. Então você pode carregar o jQuery, e então seu script de conteúdo pode usá-lo.

+ +

Carregue vários arquivos de script de conteúdo

+ +

O dado atribuído ao contentScriptFile pode ser um array. Os scripts serão carregados na mesma ordem em que estiverem no array.

+ +

No exemplo a seguir, nós carregaremos dois scripts, first.js & second.js. Ambos serão executados no mesmo contexto, então tudo publicamente definido no first.js será acessível do second.js.

+ +
// lib/main.js
+
+var self = require("sdk/self");
+var tabs = require("sdk/tabs");
+
+require("sdk/ui/button/action").ActionButton({
+  id: "load-several",
+  label: "load several scripts",
+  icon: "./icon-16.png",
+  onClick: function () {
+    tabs.activeTab.attach({
+      contentScriptFile: [self.data.url('first.js'),
+                          self.data.url('second.js')]
+    });
+  }
+});
+
+ +

Comunicando com o script de conteúdo

+ +

O script do seu add-on e os scripts de conteúdo não podem acessar diretamente as variáveis ou funções um do outro, mas eles podem trocar mensagens.

+ +

Para enviar mensagens de um lado para o outro, são usados o emitente de chamadas port.emit() e o recebendor port.on().

+ + + +

Vamos reescrever o exemplo acima para passar mensagens de um add-on para o script de conteúdo.

+ +

O script de conteúdo agora precisa parecer com isto:

+ +
// "self" é um objeto global no script de conteúdo
+// Espera por um "drawBorder"
+self.port.on("drawBorder", function(color) {
+  document.body.style.border = "5px solid " + color;
+});
+
+ +

No script do add-on, nós enviaremos ao script de conteúdo uma mensagem "drawBorder" usando o objeto retornado de attach():

+ +
var self = require("sdk/self");
+var tabs = require("sdk/tabs");
+
+var button = require("sdk/ui/button/action").ActionButton({
+  id: "style-tab",
+  label: "Style Tab",
+  icon: "./icon-16.png",
+  onClick: function() {
+    var worker = tabs.activeTab.attach({
+      contentScriptFile: self.data.url("my-script.js")
+    });
+    worker.port.emit("drawBorder", "red");
+  }
+});
+
+ +

A mensagem drawBorder não é uma mensagem embutida, é uma que este add-on definiu na chamada de port.emit().

+ +

Injetando CSS

+ +

Diferente da API page-mod, tab.attach() não permite a você injetar CSS diretamente na página.

+ +

Para modificar o estilo de uma página, você tem que usar JavaScript, como no exemplo acima.

+ +

Aprendendo Mais

+ +

Para aprender mais sobre como trabalhar com tabs no SDK, veja o tutorial Abrindo uma Página da Web, O tutorial Lista de Tabs Abertas, e a referência da API tabs.

+ +

Para aprender mais sobre scripts de conteúdo, veja o guia de scripts de conteúdo.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html new file mode 100644 index 0000000000..4e846d75c7 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html @@ -0,0 +1,228 @@ +--- +title: Modificando Página Web Baseado na URL +slug: Mozilla/Add-ons/SDK/Tutorials/Modifying_Web_Pages_Based_on_URL +tags: + - Add-on SDK + - content scripts +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Modifying_Web_Pages_Based_on_URL +--- +
Para seguir este tutorial, você precisará instalar o SDK e ter conhecimento básico de jpm (Firefox 38 em diante) ou básico de cfx.
+ +

Para modificar qualquer página que combine com um padrão particular (por exemplo, "http://example.org/") a medida que elas são carregadas, use o módulo page-mod.

+ +

Para criar um page-mod, você precisa de duas coisas:

+ + + +

Um trecho simples de códingo onde o script de conteúdo é fornecido com a opção contentScript e o padrão de busca da URL é dado pela opção include como a seguir:

+ +
// Importe a API page-mod
+var pageMod = require("sdk/page-mod");
+
+// Crie um page-mod
+// Ele executará um script toda vez que uma URL ".org" é carregada
+// O script substitui o conteúdo da página por uma mensagem
+pageMod.PageMod({
+  include: "*.org",
+  contentScript: 'document.body.innerHTML = ' +
+                 ' "<h1>Page matches ruleset</h1>";'
+});
+
+ +

Faça o seguinte:

+ + + +

Abaixo é o que você deve ver.

+ +

+ +

Especificando o Padão a Combinar

+ +

O padrão de combinação usa a síntaxe match-pattern. Você pode passar uma única string como padrão a combinar ou um array.

+ +

Mantendo o Conteúdo do Script em um Arquivo Separado

+ +

No exemplo acima, nós fornecemos o script de conteúdo como uma string.

+ +

A menos que o script seja extremamente simples, é melhor manter o script em um arquivo separado. Isso torna o código mais fácil para manter, depurar, e revisar. Para fazer isso, você precisa:

+ + + +

Por exemplo, se você salvar o script acima no diretório data do add-on em um arquivo chamado my-script.js:

+ +
// Importe a API page-mod
+var pageMod = require("sdk/page-mod");
+// Importe a API self
+var self = require("sdk/self");
+
+// Crie um page-mod
+// Ele executará um script toda vez que uma URL ".org" é carregada
+// O script substitui o conteúdo da página por uma mensagem
+pageMod.PageMod({
+  include: "*.org",
+  contentScriptFile: self.data.url("my-script.js")
+});
+ +

Ou a partir do Firefox 34:

+ +
// Importe a API page-mod
+var pageMod = require("sdk/page-mod");
+
+// Crie um page-mod
+// Ele executará um script toda vez que uma URL ".org" é carregada
+// O script substitui o conteúdo da página por uma mensagem
+pageMod.PageMod({
+  include: "*.org",
+  contentScriptFile: "./my-script.js"
+});
+ +

Carregando Múltiplos Scripts de Conteúdo

+ +

Você pode carregar mais do que um script, e eles podem interagir um com o outro.

+ +

Por exmeplo, você poderia reescrever o my-script.js para usar o jQuery.

+ +
$("body").html("<h1>Page matches ruleset</h1>");
+
+ +

Então baixe o jQuery para o diretório data do add-on, e carregue o script e o jQuery juntos (tenha certeza de carregar o jQuery primeiro).

+ +
// Importe a API page-mod
+var pageMod = require("sdk/page-mod");
+// Importe a API self
+var self = require("sdk/self");
+
+// Crie um page-mod
+// Ele executará um script toda vez que uma URL ".org" é carregada
+// O script substitui o conteúdo da página por uma mensagem
+pageMod.PageMod({
+  include: "*.org",
+  contentScriptFile: [self.data.url("jquery-1.7.min.js"), self.data.url("my-script.js")]
+});
+
+ +

Você pode usar ambos contentScript e contentScriptFile no mesmo page-mod. Se você fizer isto, o script carregado usando contentScriptFile são carregados primeiro.

+ +
// Importe a API page-mod
+var pageMod = require("sdk/page-mod");
+// Importe a API self
+var self = require("sdk/self");
+
+// Crie um page-mod
+// Ele executará um script toda vez que uma URL ".org" é carregada
+// O script substitui o conteúdo da página por uma mensagem
+pageMod.PageMod({
+  include: "*.org",
+  contentScriptFile: self.data.url("jquery-1.7.min.js"),
+  contentScript: '$("body").html("<h1>Page matches ruleset</h1>");'
+});
+
+ +

Note, porém, que você não pode carregar um script de um site web. O script deve ser carregado do data.

+ +

Comunicando com o Script de Conteúdo

+ +

Seu script do add-on e o script de conteúdo não podem acessar diretamente a variável de um ou outro ou chamar função dos outros, mas eles podem enviar mensagens um para o outro.

+ +

Para enviar mensagens de um lado para o outro, use o emitente de chamadas port.emit() e receba respostas usando port.on().

+ + + +

Vamos reescrever o exemplo acima para passar uma mensagem do add-on para o script de conteúdo. A mensagem conterá o novo conteúdo para inserir dentro do documento

+ +

O script de conteúdo agora precisa parecer com isto:

+ +
// "self" é um objeto global no script de conteúdo
+// Espera pelas mensagens, e substitui o conteúdo do
+// documento com a mensagem recebida
+self.port.on("replacePage", function(message) {
+  document.body.innerHTML = "<h1>" + message + "</h1>";
+});
+
+ +

No script do add-on, nós enviaremos ao script de conteúdo uma mensagem dentro do onAttach.

+ +
// Importe a API page-mod
+var pageMod = require("sdk/page-mod");
+// Importe a API self
+var self = require("sdk/self");
+
+// Crie um page-mod
+// Ele executará um script toda vez que uma URL ".org" é carregada
+// O script substitui o conteúdo da página por uma mensagem
+pageMod.PageMod({
+  include: "*.org",
+  contentScriptFile: self.data.url("my-script.js"),
+  // Envia ao script de conteúdo uma mensagem dentro de onAttach
+  onAttach: function(worker) {
+    worker.port.emit("replacePage", "Page matches ruleset");
+  }
+});
+
+ +

A mensagem replacePage não é uma mensagem embutida: é uma mensagem definida pelo add-on na chamada do port.emit().

+ +
+

Injetando CSS

+ +

Note que a característica descrita nesta seção é experimental no momento. Nós devemos provavelmente continuar suportando essa característica, mas os detalhes da API devem mudar.

+ +

Em vez de injetar JavaScript na página, você pode injetar CSS definindo a opção do contentStyle do mod-page.

+ +
var pageMod = require("sdk/page-mod").PageMod({
+  include: "*",
+  contentStyle: "body {" +
+                "  border: 5px solid green;" +
+                "}"
+});
+
+ +

Como com o contentScript, há uma opção correspondente para contentStyleFile que leva uma URL de um arquivo CSS situado no diretório "data"; é uma boa prática usar essa opção ao invés de contentStyle se o CSS é muito complexo.

+ +
var pageMod = require("sdk/page-mod").PageMod({
+  include: "*",
+  contentStyleFile: require("sdk/self").data.url("my-style.css")
+});
+
+ +

Ou, a partir do Firefox 34, você pode usar a versão mais simples:

+ +
var pageMod = require("sdk/page-mod").PageMod({
+  include: "*",
+  contentStyleFile: "./my-style.css"
+});
+
+ +

Aprendendo mais

+ +

Para aprender mais sobre o page-mod, veja a referência da API page. Em particular, o construtor PageMod leva várias opções adicionais para controlar seu comportamento:

+ + + +

Para aprender mais sobre o script de conteúdo,, veja o guia content scripts.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/mostrar_um_popup/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/mostrar_um_popup/index.html new file mode 100644 index 0000000000..b66c9fb06a --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/mostrar_um_popup/index.html @@ -0,0 +1,165 @@ +--- +title: Mostrar um Popup +slug: Mozilla/Add-ons/SDK/Tutorials/Mostrar_um_Popup +tags: + - Add-on SDK + - Painel +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Display_a_Popup +--- +
+

Para seguir este tutorial você precisará ter instalado o SDK e ter conhecimento básico sobre cfx.

+ +

Este tutorial usa a API action button, que está disponível somente do Firefox 29 em diante.

+
+ +

Para mostrar um popup de diálogo, use o módulo panel. Um painel de conteúdo é definido usando HTML. Você pode executar scripts no painel: embora o script em execução no painel não pode acessar diretamente o código de seu add-on, você pode trocar mensagens entre o script do painel e o código do add-on.

+ +

Neste tutorial nós criaremos um add-on que adiciona um action button à barra de ferramentas que mostra um painel quando clicado. O painel contém apenas um elemento <textarea>:quando o usuário aperta a tecla return, o conteúdo da <textarea> é enviado ao código principal do add-on. O código principal do add-on repassa a mensagem ao console

+ +

O add-on consiste em seis arquivos:

+ + + +

O "main.js" se parece com isso:

+ +
var data = require("sdk/self").data;
+// Constrói um painel, carrega seu conteúdo do arquivo
+// "text-entry.html" no diretório "data", e carrega o script "get-text.js"
+// para ele.
+var text_entry = require("sdk/panel").Panel({
+  contentURL: data.url("text-entry.html"),
+  contentScriptFile: data.url("get-text.js")
+});
+
+// Cria um botão
+require("sdk/ui/button/action").ActionButton({
+  id: "show-panel",
+  label: "Show Panel",
+  icon: {
+    "16": "./icon-16.png",
+    "32": "./icon-32.png",
+    "64": "./icon-64.png"
+  },
+  onClick: handleClick
+});
+
+//Mostra o painel quando o usuário clica no botão
+function handleClick(state) {
+  text_entry.show();
+}
+
+//Quando o painel é mostrado ele gera um evento chamado
+//"show": nós esperaremos por este evento e quando ele ocorrer
+//enviamos nosso próprio evento "show" para o script do painel,
+//então o script pode preparar o painel para mostrar.
+text_entry.on("show", function() {
+  text_entry.port.emit("show");
+});
+
+//Espera pela mensagem chamada "text-entered" vinda do
+//script do conteúdo. A carga útil da mensagem é o texto
+//digitado pelo usuário.
+//Nesta implementação nós passaremos o texto para o console.
+text_entry.port.on("text-entered", function (text) {
+  console.log(text);
+  text_entry.hide();
+});
+ +

O conteúdo do script "get-text.js" parece com isto:

+ +
+
//Quando o usuário digita return, envia a mensagem "text-entered"
+// para o main.js.
+//A carga útil da mensagem é o conteúdo da caixa de edição.
+var textArea = document.getElementById("edit-box");
+textArea.addEventListener('keyup', function onkeyup(event) {
+  if (event.keyCode == 13) {
+    // Remove a nova linha.
+    text = textArea.value.replace(/(\r\n|\n|\r)/gm,"");
+    self.port.emit("text-entered", text);
+    textArea.value = '';
+  }
+}, false);
+//Espera pelo evento "show" vim do
+//código principal do add-on. O que significa que o
+//painel sobre será mostrado.
+//
+//Configura o foco para a área de texto então o usuário pode
+//começar a digitar.
+self.port.on("show", function onShow() {
+  textArea.focus();
+});
+ +
 
+
+ +

Finalmente, o arquivo "text-entry.html" define o elemento <textarea>:

+ +
+
+
<html>
+<head>
+    <style type="text/css" media="all">
+      textarea {
+        margin: 10px;
+      }
+      body {
+        background-color: gray;
+      }
+    </style>
+  </head>
+<body>
+    <textarea rows="13" cols="33" id="edit-box"></textarea>
+  </body>
+</html>
+ +
 
+
+
+ +

Finalmente, salve estes três ícones no diretório "data":

+ + + + + + + + + + + + + + + + +
icon-16.png
icon-32.png
icon-64.png
+ +

Teste: o "main.js" está salveo no diretório lib do add-on, e os outros cinco arquivos vão no diretório data do add-on:

+ +
my-addon/
+         data/
+              get-text.js
+              icon-16.png
+              icon-32.png
+              icon-64.png
+              text-entry.html
+         lib/
+             main.js
+
+ +

Execute o add-on, clique no botão, e você deverá ver o painel. Digite algum texto e pressione "return" e você deverá ver a saída no console.

+ +

Do Firefox 30 em diante, se você usar o toggle button, você pode anexar o painel ao botão.

+ +

Aprendendo Mais

+ +

Para aprender mais sobre o módulo panel, veja a referência da API panel.

+ +

Para aprender mais sobre buttons, veja referência da API action button e toggle button.

diff --git a/files/pt-br/mozilla/add-ons/sdk/tutorials/unit_testing/index.html b/files/pt-br/mozilla/add-ons/sdk/tutorials/unit_testing/index.html new file mode 100644 index 0000000000..2e65659ed5 --- /dev/null +++ b/files/pt-br/mozilla/add-ons/sdk/tutorials/unit_testing/index.html @@ -0,0 +1,127 @@ +--- +title: Teste de unidade +slug: Mozilla/Add-ons/SDK/Tutorials/Unit_testing +tags: + - Add-on SDK + - JPM +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Unit_testing +--- +
+

Para seguir este tutorial você precisará ter conhecimento básico de jpm e ter seguido o tutorial de criação de módulos reutilizáveis.

+
+ +
+

Se você está migrando código de teste do cfx para o jpm, veja o guia de migração do cfx, em particular a seção loading modules from test code.

+
+ +

O SDK fornece um framework para ajudar a criar e executar testes de unidade para seu código. Para demonstrar como ele funciona nós escreveremos um teste de unidade para um módulo simples de codificação Base64.

+ +

Um módulo simples Base64

+ +

Em uma página web, você pode executar uma codificação Base64 e decodificação usando as funções btoa() e atob(). Infelizmente essas funções pertencem ao objeto window: uma vez que o objeto não está disponível no código principal do add-on, atob() e btoa() não estão disponíveis de qualquer forma. Então nós criaremos um módulo base64 para exibir estas funções da plataforma.

+ +

Para começar, crie um novo diretório, navegue para ele, e execute o jpm init. Agora crie um novo arquivo chamado "base64.js", e de lhe o seguinte conteúdo:

+ +
const { atob, btoa } = require("chrome").Cu.import("resource://gre/modules/Services.jsm", {});
+
+exports.atob = a => atob(a);
+exports.btoa = b => btoa(b);
+
+ +

Este código exporta duas funções, que chamamos btoa() and atob(). Para mostrar o módulo em uso, edit o arquivo "index.js" como segue:

+ +
var base64 = require("./base64");
+
+var button = require("sdk/ui/button/action").ActionButton({
+  id: "base64",
+  label: "base64",
+  icon: "./icon-16.png",
+  onClick: function() {
+    encoded = base64.btoa("hello");
+    console.log(encoded);
+    decoded = base64.atob(encoded);
+    console.log(decoded);
+  }
+});
+ +

Para executar esse exemplo você também terá que ter um ícone chamado "icon-16.png" salvo no diretório data do add-on. Você pode baixar este ícone: .

+ +

Agora o "index.js" importa o módulo base64 e chama suas duas funções exportadas. Se nós executarmos o add-on e clicarmos no botão, nós devemos ver a seguinte saída:

+ +
info: aGVsbG8=
+info: hello
+
+ +

Testando o módulo Base64

+ +

Navegue para o diretório test e delete o arquivo test-index.js. Em seu lugar crie um arquivo chamado test-base64.js com o seguinte conteúdo:

+ +
var base64 = require("../base64");
+
+exports["test atob"] = function(assert) {
+      assert.ok(base64.atob("aGVsbG8=") == "hello", "atob works");
+}
+
+exports["test btoa"] = function(assert) {
+  assert.ok(base64.btoa("hello") == "aGVsbG8=", "btoa works");
+}
+
+exports["test empty string"] = function(assert) {
+  assert.throws(function() {
+                  base64.atob();
+                },
+                "empty string check works");
+}
+
+require("sdk/test").run(exports);
+
+ +
+

Note que com o  jpm nós devemos dar o caminho exato do módulo base64.js.

+
+ +

Esse arquivo: exporta três funções, cada qual espera receber um único argumento que é o objeto assert. assert é fornecida pelo módulo test/assert e implementa o CommonJS Unit Testing specification.

+ + + +

Neste ponto seu add-on deve parecer com isto:

+ +
  /base64
+      /data
+          icon-16.png
+      package.json
+      README.md
+      index.js
+      base64.js
+      /test
+          test-base64.js
+
+ +

Agora execute o jpm --verbose test da pasta principal do add-on. Você deve ver algo como isto:

+ +
console.info: jpm-utest: executing './test/test-base64.test atob'
+console.info: jpm-utest: pass: atob works
+console.info: jpm-utest: executing './test/test-base64.test btoa'
+console.info: jpm-utest: pass: btoa works
+console.info: jpm-utest: executing './test/test-base64.test empty string'
+console.info: jpm-utest: pass: empty string check works
+
+3 of 3 tests passed.
+All tests passed!
+ +

O que aconteceu aqui é que o jpm test:

+ + + +

Obviamente, você não tem que passar a opção --verbose para o jpm se você não quiser; fazendo assim torna a saída mais fácil de ler.

-- cgit v1.2.3-54-g00ecf