1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
---
title: XForms Custom Controls
slug: orphaned/XForms/Controles_Customizados
tags:
- XForms
original_slug: XForms/Controles_Customizados
---
<p> </p>
<h3 id="Proposta"> Proposta </h3>
<p>Se você quer criar suas próprias formas dos controles XForm como <code>input</code>, <code>output</code>, <code>trigger</code>, etc., você está no lugar certo. Vamos mostrar tambem como criar controles que funcionam com o modelo XForms e são automaticamente atualizados como os controles XForms. A proposta deste artigo é de fornecer informações suficientes para permitir-lhe um bom início. Para realmente entender as seguintes informações é necessário um bom entendimento de <a href="pt/XForms">XForms</a>, <a href="pt/XBL">XBL</a>, <a href="pt/JavaScript">JavaScript</a> e <a href="pt/CSS">CSS</a>. Conhecimentos em <a href="pt/XPCOM">XPCOM</a> certamente não farão mal. Mas mesmo que você tenha conhecimentos em sómente algumas destas tecnologias, esperamos que as possibilidades delineadas abaixo o inspirem a aprender mais onde fôr necessário.
</p>
<h3 id="Status_de_implementa.C3.A7.C3.A3o"> Status de implementação </h3>
<p>O sistema que usamos no processador Mozilla XForms é muito um "trabalho em andamento". Por favor mantenha em mente que tudo que mencionamos aqui pode mudar de algum maneira assim que continuamos a trabalhar no assunto. O trabalho já começou no <a class="external" href="http://www.w3.org/MarkUp/Forms/#wg">W3C XForms Working Group</a> a investigar o assunto de controles customizadas, assim eventualmente (esperamos?)que vai existir um caminho "oficial" e comum de customizar suas máscaras de interface de usuário em todos os processadores XForm.
</p>
<h3 id="Porque_.C3.A9_necess.C3.A1rio"> Porque é necessário </h3>
<p>Você provávelmente vai achar que suas necessidades de customização se encaixam numa das seguintes categorias:
</p>
<ul><li> apresentação customizada - controles XForms como as realizadas no processador Mozilla XForms não lhe fornecem a aparência certa.
</li><li> tipos de dados customizadas - controles Xforms existentes não estão aptos a trabalhar apropriamente seus tipos de dados
</li><li> controles XForms avançados - você necessita que seus controles estejam aptos a fazer mais coisas que os controles XForms tradicionais
</li><li> nova linguagem de hospedagem- você quer suportar XForms em linguagems de hospedagem diferentes de XHTML ou XUL
</li></ul>
<h4 id="Apresenta.C3.A7.C3.A3o_customizada"> Apresentação customizada </h4>
<p>A extensão Mozilla XForms não pode antecipar todas as possibilidades de uso que vão ser envolvidas em aplicações e páginas web quando XForms amadurece e a base de usuários cresce. E com estas novas formas de usar mais e mais flexibilidade vai ser exigida dos controles. Introduzindo controles customizadas ao seu ambiente pode ser a solução que está procurando. Por exemplo, você pode estar querendo render imagens que estão sendo mantidos dentro de um documento de instancia ou querer mostrar um <code>trigger</code> deshabilitado quando seu nó se torna irrelevante em vez de não mostrá-lo (o atual comportamento padrão).
</p><p>Toda apresentação de controle XForms possui seu próprio XBL binding. Em muitos casos valores diferentes fornecidos para os atributos <code>appearance</code> ou <code>mediatype</code> vão determinar qual XBL binding será usado para um controle XForms particular. Como mencionado na especificação, o atributo <code>appearance</code> pode ser usado para influenciar a aparência do controle mesmo que todas as outras condições permanecam constantes. Por exemplo, na extensão Mozilla XForms vamos render uma combobox widget ao <code>appearance='minimal'</code> num controle <code>select1</code>. Se o autor do formulário escolher um <code>appearance='compact'</code> neste controle, vamos desenhar uma listbox widget. Aqui é uma forma fragmentada do nosso arquivo .css para mostrar o tipo de regra CSS que usariamos para tal determinação.
</p>
<pre>xf|select1[appearance="compact"] {
-moz-binding: url('chrome://xforms/content/select-xhtml.xml#xformswidget-select1-compact');
}
</pre>
<p>O atributo <code>mediatype</code> pode ser usado pelo autor do formulário para alinhar o tipo de apresentação com o tipo de data que o bound instance node contém. Por exemplo, se <code>mediatype='image/*'</code> então o usuário deve ver a imagen que os bytes representam em vez da sequência de bytes.
</p>
<pre>xf|output[mediatype^="image"] {
-moz-binding: url('chrome://xforms/content/xforms-xhtml.xml#xformswidget-output-mediatype-anyURI');
}
</pre>
<h4 id="Tipos_de_dados_customizados"> Tipos de dados customizados </h4>
<p>Se definir um novo tipo de dado esquemático ou usar tipo de data built-in e achar os controles XForms atuais insuficientes, então deve escrever um novo controle customizado. Por exemplo se tiver um nó de instância do tipo <code>xsd:date</code> e quiser que os dados sejam visualizados num formato local.
</p><p>Em Mozilla, cada controle XForms ligado tem um atributo <code>typelist</code> de <code>mozType</code> que contém o espaço de nome da cadeia herdada dos tipo de dados que detectamos. O espaço de nome <code>mozType</code> é introduzido pela implementação de Mozilla XForms e suas URI é <code><a class=" external" href="http://www.mozilla.org/projects/xforms/2005/type">http://www.mozilla.org/projects/xforms/2005/type</a></code>. Por exemplo, se um controle é ligado a um nó do tipo <code>xsd:integer</code> e então o atributo <code>typelist</code> será <code><span>"http://www.w3.org/2001/XMLSchema#integer http://www.w3.org/2001/XMLSchema#decimal"</span></code>. Isto é porque <code>xsd:integer</code> é herdado do tipo de dado <code>xsd:decimal</code>. Recomendamos que use este atributo para criar a regra de ligação CSS para seu controle customizado. Isto lhe permite ligar seu controle customizado para o tipo de dado que está desejando e todo tipo derivado deste tipo desejado. Então se quiser um <code>input</code> ligado a um nó de instância do tipo <code>integer</code> (e todos os tipos derivados de <code>integer</code>), você usaria:
</p>
<pre>@namespace xf url(http://www.w3.org/2002/xforms);
@namespace mozType url(http://www.mozilla.org/projects/xforms/2005/type);
xf|input[mozType|typelist~="http://www.w3.org/2001/XMLSchema#integer"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-integer');
}
</pre>
<h4 id="Controles_XForms_Avan.C3.A7ados"> Controles XForms Avançados </h4>
<p>Vão existir momentos em que precisa de um controle muito específico a sua tarefa mas também quer que funcione com modelos XForms e nós de instância como um controle XForms regular. A esspecificação XForms fornece uma bela maneira de realizar isto usando atributos ligados XForms (como <code>ref</code>, ou <code>nodeset</code>) no seu elemento de controle customizado. Porém, a implementação de Mozilla XForms atualmente não suporta esta aproximação. Mas existe um caminho para alcançr o mesmo resultado. Você pode pôr os controles dentro da sua ligação XBL. Note que deve assegurar que os controles XForms incorporados funcionam com o tipo de dados do nó de instância ao que seu controle está ligado. Para lhe dar uma ideía sobre o que estamos falando veja a seguir:
</p>
<pre><content>
<xf:input xbl:inherits="ref=ref1" anonid="ref1"/>
<xf:input xbl:inherits="ref=ref2" anonid="ref2"/>
</content>
<implementation>
<method name="refresh">
<body>
// Aqui devemos renovar o controle customizado.
</body>
</method>
<constructor>
// Devemos redirecionar chamadas do modo de inputs 'refresh' para controles customizados 'refresh'.
var control = this;
var refreshStub = function() {
control.refresh();
}
this.ref1.refresh = refreshStub;
this.ref2.refresh = refreshStub;
</constructor>
<property name="ref1" readonly="true"
onget="return this.ownerDocument.getAnonymousElementByAttribute(this, 'anonid', 'ref1');"/>
<property name="ref2" readonly="true"
onget="return this.ownerDocument.getAnonymousElementByAttribute(this, 'anonid', 'ref2');"/>
</implementation>
</pre>
<h4 id="Nova_linguagem_Host"> Nova linguagem Host </h4>
<p>A implementação Mozilla XForms atualmente somente suporta XForms hospedados em documentos XHTML ou XUL. Se precisar XForms em outros tipos de documentos como SVG, MathML ou alguma outra marca de linguagem que Mozilla suporta, então precisa implementar controles XForms para o formato de documento desejado. A implementação XForms tem ligações básicas XBL para cada controle XForms. Vocè pode escrever ligações de implementação que vão herdar as ligações básicas. Por exemplo, cada implementação de controle <code>output</code> extende a ligação básica <code><span>xforms.xml#xformswidget-output-base</span></code>. As peças específicas XHTML de nossa implementação de <code>output</code> é mantido na liagação <code><span>xforms-xhtml.xml#xformswidget-output</span></code>. Se desenvolvedores como você quiserem fazer este tipo de trabalho heróico eão por favor contate os desenvolvedores do Mozilla XForms antes de iniciar. Esperamos poder ajudá-lo em evitar um monte de frustração e desespéro:).
</p>
<h3 id="Resumo"> Resumo </h3>
<p>Os controles Mozilla XForms são largamente implementados usando XBL e as ligações são aplicados aos tags de controle individuais XForms via CSS. Assim sempre pode referir-scom nossas atuais e ao nosso source code para obter alguns grandes exemplos de como controles XForms são escritos. Isto também lhe permite estar por dentro das nossas atuais atualizações (muitas vezes o resultado de duras lições) e esperamos que o ajude a escrever seus próprios controles mais facilmente. Para iniciar, realmente só precisa saber a linguagem aonde quer usar XForms (como <a href="pt/XHTML">XHTML</a> ou <a href="pt/XUL">XUL</a>), alguns <a href="pt/XBL">XBL</a> e <a href="pt/JavaScript">JavaScript</a>, e a interface <a href="pt/XPCOM">XPCOM</a> que estamos mostrando.
</p>
<h3 id="Detalhes"> Detalhes </h3>
<h4 id="Interfaces"> Interfaces </h4>
<p>Esta secção descreve interfaces que deve conhecer. Existem dois grupos principais de interfaces -> callback interfaces que precisam ser implementados pelos controles customizados e as interfaces que controles customizados podem usar para acessar a Mozilla XForms engine.
</p>
<h5 id="nsIXFormsUIWidget"> nsIXFormsUIWidget </h5>
<p>Todo controle customizado deve implementar a interface <code>nsIXFormsUIWidget</code>. Esta interface é usada pelo modulo XForms para interagir com o controle básico. De acordo com as regras do XForms, por exemplo, quando o controle precisa ser atualizado, é chamado o método <code>refresh</code> pelo processador. Abaixo encontra-se a estrutura da interface. Como sempre por favor veja diretamente o source code para estar seguro que está usando a versão mais recente: {{ Source("extensions/xforms/nsIXFormsUIWidget.idl") }}.
</p>
<pre>interface nsIXFormsUIWidget : nsIDOMElement
{
/**
* É chamada quando o controle deve ser atualizado para refletir o valor do nó ligado.
*/
void refresh();
/**
* É chamado quando o foco é avançado sobre o elemento XForms.
*/
boolean focus();
/**
* É chamado quando o controle deve ser desabilitado.
* Isto realmente só se aplica ao elemento submetido.
*/
void disable(in boolean disable);
/**
* É chamado para obter o valor atual do controle.
*/
string getCurrentValue();
}
</pre>
<p>Notas:
</p>
<ul><li> getCurrentValue() deve retornar o valor do controle como visto pelo usuário. O valor atual de um controle pode ser diferente do valor do nó ligado em casos onde @incremental='false'.
</li><li> disable() é chamado pelo processador XForms para indicar a um elemento submetido que precisa desabilitar/habilitar devido ao começo/fim de um processo de submissão. Atualmente não tem nenhum sentido fora deste contexto.
</li><li> focus() é usado pelo processador para comunicar ao controle que ele está recebendo foco através de uma das várias maneiras (p.ex. através de xf:setfocus action) e que o controle precisa assegurar que o widget apropriado está recebendo foco.
</li></ul>
<p>Com raras exceções seu controle precisa somente implementar a interface <code>nsIXFormsUIWidget</code>. Mas certos controles XForms precisam implementar interfaces adicionais. Tais elementos incluem <code>upload</code> e <code>case</code>.
</p>
<h5 id="nsIXFormsAccessors"> nsIXFormsAccessors </h5>
<p>A interface <code>nsIXFormsAccessors</code> permite acessar o valor e o estado do nó de instância ao qual o controle está ligado (veja {{ Source("extensions/xforms/nsIXFormsAccessors.idl") }}). Interface atual é:
</p>
<pre>interface nsIXFormsAccessors : nsISupports
{
/**
* Valor de retorno do nó de instância.
*/
DOMString getValue();
/**
* Valor nominal do nó de instância.
*/
void setValue(in DOMString value);
/**
* Retorna verdadeiro se o nó de instância é readonly como determinado pelo MDG.
*/
boolean isReadonly();
/**
* Retorna verdadeiro se o nó de instância é relevante como determinado pelo MDG.
*/
boolean isRelevant();
/**
* Retorna verdadeiro se o nó de instância é requerido como determinado pelo MDG.
*/
boolean isRequired();
/**
* Retorna verdadeiro se o nó de instância é válido como determinado pelo MDG.
*/
boolean isValid();
/**
* Retorna verdadeiro se o controle é ligado ao nó de instância.
*/
boolean hasBoundNode();
/**
* Retorna o nó de instância ligado.
*/
nsIDOMNode getBoundNode();
/**
* Setar o conteúdo do nó de instância. Se um ForceUpdate é verdadeiro então o
* modelo XForms será reconstruído/recalculado/revalidado/renovado.
*/
void setContent(in nsIDOMNode aNode, in boolean aForceUpdate);
}
</pre>
<p>note: setContent() pode ser usado para colocar complexContent (mistura de texto e nós elementares) sob o nó ligado ao controle. Favor verificar os comentários no arquivo fonte .idl para maiores informações sobre como usar este método.
</p>
<h4 id="Liga.C3.A7.C3.B5es_XBL"> Ligações XBL </h4>
<p>A maioria dos elementos de controle XForms tem no mínimo duas ligações aplicadas a si mesmas. Uma é a ligação básica que implementa o comportamento do núcleo do controle XForms. A outra é a ligação de impelmentação que adiciona a representação específica da linguagem do host do controle XForms. Um exemplo do mencionado é a ligação que usa um html:input como conteúdo anônimo de um elemento xforms:input quando este é hospedado num documento XHTML.
</p><p>Nossa extenção XForms usa o seguinte formato para nomes de arquivos. O nome do arquivo onde são localizadas as ligações básicas de um controle é <code>controlfile.xml</code>. <code>controlfile-xhtml.xml</code> contém as ligações de implementação XHTML para o controle e <code>controlfile-xul.xml</code> contém as ligações de implementação quando este controle é hospedado num documento XUL. A seguinte lista mostra onde estão definidas as ligações básicas de nosso controle XForms:
</p>
<ul><li> <code>xforms.xml</code> - contém as ligações básicas para controles XForms <code>output</code>, <code>label</code>, <code>trigger</code>, <code>submit</code>, <code>case</code>, <code>message</code>, <code>hint</code>, <code>help</code>, <code>alert</code>, <code>upload</code> e <code>repeat</code> .
</li><li> <code>input.xml</code> - contém as ligações básicas para controles XForms <code>input</code>, <code>secret</code> e <code>textarea</code>.
</li><li> <code>select.xml</code> - contém as ligações básicas para controles XForms <code>select</code> e <code>select1</code> (exceto <code>minimal/default select1</code> que está hospedado no arquivo <code>select1.xml</code>)
</li><li> <code>range.xml</code> - contém as ligações básicas para controles XForms <code>range</code>.
</li></ul>
<p><code>xforms.xml</code> também define as poucas ligações básicas comuns para todos os controles XForms. Estes são:
</p>
<ul><li> <code>xformswidget-general</code> - define propriedades utilitárias e métodos comuns para todos os controles XForms.
</li><li> <code>xformswidget-accessors</code> - define os métodos que permitem às ligações de trabalhar com nós de instância ligados e com o próprio elemento XForms.
</li><li> <code>xformswidget-base</code> - implementa interfaces <code>nsIXFormsUIWidgets</code>.
</li></ul>
<p>Você está livre em escolher qual tipo de ligação para seu controle customizado fornecerá à fundação. Normalmente será uma das ligações de implementação ou uma das básicas.
</p>
<h3 id="Exemplo"> Exemplo </h3>
<p>Uma coleção de exemplos de controles customizados pode ser encontrada em <a href="pt/XForms/Custom_Controls_Examples">XForms:Custom Controls Examples</a>, e você também pode ver os blogs <a class="external" href="http://www.oreillynet.com/xml/blog/2006/07/understanding_xforms_customiza.html">"Compreendendo XForms: Customização"</a>.
</p><p>Aqui está um exemplo completo que define um novo controle de saída que carrega seu valor como uma imagen. Ele está ligado a <code><xf:output mediatype="image/*"/></code> imitando o atual <a class="external" href="http://www.w3.org/TR/xforms11/#render-nontext">XForms 1.1 draft</a>:
</p>
<pre><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<title>Custom Image Control Sample</title>
<bindings id="xformsBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="output-image"
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
<content>
<html:div>
<html:img anonid="content"/>
</html:div>
</content>
<implementation implements="nsIXFormsUIWidget">
<method name="refresh">
<body>
<!--
set the src attribute on the html:img to be the simpleContent
of the instance node bound to this control
-->
var img = document.getAnonymousElementByAttribute(this, "anonid", "content");
img.setAttribute("src", this.stringValue);
return true;
</body>
</method>
</implementation>
</binding>
</bindings>
<xf:model>
<xf:instance xmlns="">
<data>
<curimg></curimg>
<img label="Firefox">http://www.mozilla.com/images/firefox-logo-64x64.png</img>
<img label="Thunderbird">http://www.mozilla.com/images/thunderbird-logo-64x64.png</img>
<img label="Bugzilla">http://www.mozilla.org/images/p-bugz.gif</img>
<img label="Mozilla">http://www.mozilla.org/images/mozhead-80x64.gif</img>
</data>
</xf:instance>
</xf:model>
<style type="text/css">
@namespace xf url(http://www.w3.org/2002/xforms);
xf|output[mediatype="image/*"] {
-moz-binding: url('#output-image');
}
</style>
</head>
<body>
<h1>Custom Control Sample</h1>
<xf:select1 ref="curimg">
<xf:label>Select image to display: </xf:label>
<xf:itemset nodeset="../img">
<xf:label ref="@label"/>
<xf:value ref="."/>
</xf:itemset>
</xf:select1>
<xf:output ref="curimg" mediatype="image/*"/>
</body>
</html>
</pre>
<p><span>Categorias</span>
</p><p><span>Interwiki links de idiomas</span><a href="pt/Pt-br/XForms/Controles_Customizados">pt-br:XForms:Controles Customizados</a>
</p>{{ languages( { "en": "en/XForms/Custom_Controls" } ) }}
|