YUI Preview Release 3.4.0 3 já está disponível na CDN

28 de julho de 2011 às 0:39 pm por George Puckett | Em Desenvolvimento | 4 Comentários

A equipe YUI acaba de completar o sprint final de desenvolvimento para o lançamento 3.4.0. Neste momento, considere o código funcionalmente completo. Estamos planejando gastar o nosso próximo sprint focando nossa rodada final de testes e criando mais exemplos e documentação. Temos postou um FC (completa funcional) construir a CDN para a exploração da comunidade e feedback. Você pode acessar esta versão em http://yui.yahooapis.com/3.4.0pr3/build/yui/yui-min.js .

Há algumas áreas específicas da biblioteca onde nós adoraríamos ter feedback da comunidade:

  • Carregador teve uma atualização significativa para o 3.4.0. Se você está fazendo especificações de carga manual via use("*") ou fazer uso de configurações submódulo, nós apreciamos muito você está tentando o seu código com o carregador novo para ter certeza de que estamos tratando correctamente todos os casos de uso. Para informações mais detalhadas sobre as mudanças Carregador nesta versão, consulte o post no blog descrevendo 3.4.0 mudanças carregador .
  • Painel de calendário e são totalmente funcionais e pronto para uso do desenvolvedor.
  • Gráficos:. Houve uma mudança API poucos que afetará qualquer código experimental escrito na API gráfica distribuída na versão PR2 getShape() foi renomeado addShape() . Houve também várias substituições atributo.
  • Transição: transições nativas são agora suportados em FireFox.
  • WidgetButtons foi lançado como uma extensão do novo widget que permite que você coloque css de estilo botões no cabeçalho e rodapé de qualquer widget que implementa suporte ao módulo padrão.
  • Modalidade widget plugins e Widget AutoHide-foram convertidos para extensões.
  • Widget: Adicionado suporte para destruir (true), que irá remover e destruir todos os nós filhos (e não apenas BoundingBox e Contentbox) contido dentro BoundingBox do widget. destroy () irá manter o seu comportamento atual, devido ao alto custo potencialmente em tempo de execução de destruir todos os nós filhos. Se você destruir Widgets em seu aplicativo ou é um desenvolvedor widget personalizado, sua ajuda para testar esta mudança seria apreciada.
  • ScrollView agora suporta paginação vertical, inclui um plugin ScrollView lista para adicionar nomes de classes CSS para os elementos da lista imediato, bem várias correções de bugs e refatoração
  • App Framework: Queremos estender um sincero agradecimento a todos os desenvolvedores da comunidade que tenham tomado a tempo para test drive do Quadro App novo. Temos recebido um excelente feedback após o lançamento PR2. Por favor, continuem a explorar estes componentes e envie-nos as suas observações e sugestões.

Você pode obter informações adicionais sobre o conteúdo deste comunicado revisando o Rollup História ea lista completa de bilhetes abordados na PR3 . Por favor, envie pedidos de qualquer acessório, bugs e regressões no banco de dados de bilhete no YUILibrary.com .

Compartilhar e ampliar: Bookmark with del.icio.us | digg it! | reddit!

YUI: Open Hours qui 28 de julho

25 de julho de 2011 às 10:56 pm por Luke Smith | Em Desenvolvimento , Horário de funcionamento | 2 Comentários

Y.Calendar está chegando ao 3.4.0

Calendário é um dos nossos widgets mais populares no 2 YUI família, e está fazendo sua estréia no 3 YUI arquitetura em 3.4.0. Allen Rabinovich é o proprietário do componente e autor e será na chamada reintroduzindo-nos a este favorito velho, mostrando algumas novas abordagens a problemas enfrentados pelos 2.x Calendar. Estou particularmente jazzed sobre o apoio à internacionalização, mas as regras de renderização novo também são muito fascinante.

Venha e traga o seu selecionador de data, calendário de eventos-import-from-iCal-e-faz-de-panquecas, perguntas e solicitações de recursos com você, como nós carne para fora do agora e do futuro Y.Calendar . (Não, não vai importar iCal, mas se alguém quer criar um módulo de galeria de domar essa besta, não há certeza de ser um bilhete YUIConf nele para você;))

Estamos de volta a nosso tempo usual nesta semana, então vamos vê-lo em Ligar às 10h PDT.

Time & Detalhes

Nós vamos estar on-line 10:00-11:00 PDT quinta-feira. Os detalhes de conexão são os mesmos, como de costume.

  1. Discar para 1-888-371-8922 (Skype funciona muito bem para não-americanos participantes *)
  2. Digite o código de participante 47188953 #
  3. Junte-se a sessão de compartilhamento de tela (este irá pedir-lhe para instalar o plugin Adobe Connect se esta é sua primeira vez de usá-lo)

Nota: Porque é uma linha de conferência aberta, pedimos que os chamadores silenciar suas linhas a menos que eles estão participando de discussões ativas.

* - Se o Skype não é uma opção, e-mail me ou me pegar (ls_n) no canal de IRC # yui na freenode para um número local.

Gravação

Obrigado a todos para chamar dentro! A gravação da sessão on-line já está disponível.

A alta qualidade, iPhone / iPad compatível, gravando para download está aqui .

Compartilhar e ampliar: Bookmark with del.icio.us | digg it! | reddit!

YUI: Open Hours qui 21 de julho

19 de julho de 2011 às 02:16 por Luke Smith | Em Desenvolvimento , Horário de funcionamento | 12 Comments

A atualização DataTable e galeria de showcase

O ciclo de lançamento 3.4.0 está chegando ao fim e serão embalados com todos os tipos de grandes recursos, mas falando francamente, DataTable não chegou como foco o desenvolvimento tanto quanto deveria ter. Houve algumas correções de bugs, porém, e uma quantidade razoável de planejamento das mudanças que são direcionados, em 3.5.0, e um grande começo para o envolvimento da comunidade com o seu desenvolvimento.

Sabemos que é um widget DataTable incrivelmente importante para muitos clientes, por isso entendemos o custo de atrasar o desenvolvimento focado. Este Horas aberto será uma atualização sobre o trabalho que está sendo feito para a 3.4.0, que está previsto para 3.5.0, e uma introdução ao grande trabalho que está começando a brotar na Galeria para adicionar funcionalidades e corrigir erros para DataTable (e sua família de apoio classes).

Estaremos on-line de uma hora no início desta semana para o benefício de Eamon Brosnan (aka, mosen from # yui), que é fornecido um número de manchas Galeria estaremos olhando por cima. Caso contrário, teremos outros habitantes # yui e colaboradores Galeria mostrando seus produtos. Se você tem uma solução DataTable ou work in progress que você gostaria de compartilhar, por favor me avise para que eu possa bloquear a agenda para caber tudo (ls_n em # yui ou Twitter ).

Time & Detalhes

Nós vamos estar on-line 09:00-10:00 PDT quinta-feira. Os detalhes de conexão são os mesmos, como de costume.

  1. Discar para 1-888-371-8922 (Skype funciona muito bem para não-americanos participantes *)
  2. Digite o código de participante 47188953 #
  3. Junte-se a sessão de compartilhamento de tela (este irá pedir-lhe para instalar o plugin Adobe Connect se esta é sua primeira vez de usá-lo)

Nota: Porque é uma linha de conferência aberta, pedimos que os chamadores silenciar suas linhas a menos que eles estão participando de discussões ativas.

* - Se o Skype não é uma opção, e-mail me ou me pegar (ls_n) no canal de IRC # yui na freenode para um número local.

Compartilhar e ampliar: Bookmark with del.icio.us | digg it! | reddit!

Next-Gen YSlow alimentado por YUI

18 de julho de 2011 às 09:17 por Marcel Duran | Em Desenvolvimento , Desempenho | 4 Comentários

Um par de semanas atrás, o Yahoo! anunciou YSlow for Mobile no Velocity 2011 , trazendo o poder do YSlow análise de desempenho para o mundo móvel.

YSlow for Mobile funciona como um bookmarklet , tornando possível para rodar em outros navegadores além do Firefox (como um add-on) ou Chrome (como uma extensão) .

A arquitetura YSlow foi parcialmente remodelado para trabalhar cross-plataforma e YUI foi o fator essencial para fazer sandboxing, a captação de cross-browser e acesso YQL simples possível.

Sandboxing

, A fim de ser incorporado em uma página, sem interferir com a análise de desempenho e sem mexer com a própria página, o YSlow é um bookmarklet que injeta JavaScript e CSS em qualquer página, aproveitando o poder do YUI sandboxing:

Bookmarklet URL:

 javascript: (function (y, p, o) {
     p = y.body.appendChild (y.createElement ('iframe'));
     p.id = 'YSlow-bookmarklet ";
     'display: none' = p.style.cssText;
     o = p.contentWindow.document;
     o.open (). write ('
         <head>
         <Body onload = "
             YUI_config = {
                 win: window.parent,
                 doc: window.parent.document
             };
             var d = document;
             d.getElementsByTagName (\ "cabeça \ ') [0]
                 . AppendChild (
                     d.createElement (\ 'script \')
                 ). Src = \ 'http://d.yimg.com/jc/yslow-bookmarklet.js \' "
         >
     ');
     o.close ()
 } (Documento))

O código acima:

  • cria um iframe vazio;
  • acrescenta ao corpo da página;
  • esconde o * iframe;
  • recebe o seu manipulador de janela;
  • escreve em seu conteúdo o corpo do iframe;
  • este corpo está vazio, mas tem um onload evento
  • o onload evento define como injetar YSlow JS:
    • conjuntos YUI_config , então win e doc aponta para a página que está sendo analisada window e document respectivamente
    • dinamicamente injeta URL YSlow, criando um script elemento em iframe da head

* O iframe é exibido no momento em que todos os ativos apresentação YSlow são carregados

Isto irá colocar um iframe para a página que está sendo analisado. Este iframe irá funcionar como um ambiente de modo seguro e YSlow irá residir dentro dela. Desde o iframe é criado dinamicamente sem a src atributo, ele terá acesso a seu pai (a página que está sendo analisado), porque não há política de mesma origem violação acontecendo lá.

O YUI_config objeto é útil porque ele define win e doc para o pai do iframe (a página que está sendo analisado), portanto, qualquer instância YUI novo será vinculado ao documento pai de fiação padrão, qualquer chamada para Y.all e Y.one através Y.config.win ou Y.config.doc do YUI use callback.

Apresentação YSlow é tratado pelo iframe window e document referências, permitindo que o script YSlow principais para tornar a marcação, bem como buscar o CSS externo dentro deste iframe sem entrar em conflito com os estilos da página pai. YSlow scans da página pai, a fim de obter todos os componentes (imagens, scripts, links, imagens de fundo-, flash, etc) necessários para análise de desempenho mais tarde. Isto é feito acessando Y.config.win e Y.config.doc , uma vez que referem-se à página pai.

Cross-browser abstração

Sendo um bookmarklet, YSlow for Mobile deve funcionar em qualquer navegador *. YUI resumos cross-browser questões normalizando diferenças de navegador, resultando em um ambiente limpo, fácil de ler e codebase sustentável.

YSlow não foi totalmente portado para YUI 3 - apenas a camada controller (a partir do componente App próximos) para agora - mas ainda assim, toda a manipulação DOM e manipulação de eventos são feitos pelo node e event módulos. Em versões futuras pretendemos porto mais recursos para YSlow YUI 3.

* Nem todos os navegadores são suportados atualmente

YQL

YSlow analisa as páginas, verificando os cabeçalhos HTTP para os componentes encontrados na página. Cabeçalhos de resposta HTTP não estão disponíveis na página, portanto, os componentes precisam ser solicitada novamente, a fim de obter as informações YSlow cabeçalho de resposta. Isto poderia ser alcançado, solicitando a lista de URLs componente através XmlHttpRequest (AJAX), mas, infelizmente, devido à restrição de mesma origem política , isso não é possível se todos os componentes estão no mesmo domínio que a página que é muito improvável.

Uma solução comum para a restrição de mesma origem política está usando JSONP, onde um servidor externo funciona como um proxy solicitando a lista de URLs componentes e recuperar seus cabeçalhos de resposta HTTP em nome do YSlow. Devido à popularidade YSlow e recentes esforços de análise móvel de desempenho, estamos esperando o tráfego bastante pesado para o YSlow para bookmarklet Mobile. A fim de apoiar esse tipo de tráfego, YQL foi a solução adoptada pela YSlow escalável através de uma tabela de dados aberto chamado data.headers , que recupera os cabeçalhos de resposta e de conteúdo para uma determinada lista de URLs ao representar o agente de usuário para garantir o conteúdo esperado é recuperados.

A consulta YQL componente faz todo o trabalho de gerenciamento de consultas YQL enquanto gerencia solicitações JSONP sob o capô, tornando o código controlador YSlow muito mais simples e fácil de manter.

Melhorias futuras: YSlow para Nova interface amigável móvel

Atualmente, o YSlow para experiência do usuário móvel é o mesmo que a experiência de desktop. Lidar com uma longa lista de dados de análise de desempenho não é a melhor experiência em pequenas telas de celulares inteligentes. Desde YUI também resumos vários dispositivos gestos , YSlow para Mobile estará recebendo uma interface móvel-friendly nova em versões futuras.

Desempenho da ferramenta de desempenho

YSlow para a implantação Mobile foi feita com cuidado, considerando o seu impacto no desempenho do tempo de carregamento da página que está sendo analisado. O YUI 3 módulos usados ​​em YSlow foram examinados para incluir apenas os módulos necessários para carregar o YSlow o mais rápido possível. O arquivo de origem YUI e carregador não foram incluídos uma vez que todos os módulos necessários e sub-módulos foram combinados seguintes Ryan Grove de Desempenho Zen dicas, o que tornou possível carregar tudo junto em um pequeno pedido único single: yslow-bookmarklet.js: 204KB, 66KB ( gzip), onde:

  • YUI: 75KB, 27KB (gzip)
  • YSlow: 129KB, 39KB (gzip)

Mais sobre YSlow

Mantenha-se atualizado com os últimos anúncios YSlow por:

Marcel Duran Sobre o autor: Marcel Duran é o líder de Front End para Yahoo! 's Equipe de Desempenho excepcional. Ele foi para a otimização do desempenho em web sites de alto tráfego na página Yahoo! Frente e equipes de pesquisa aplicada e onde pesquisou as práticas web melhor desempenho tornando as páginas mais rápido. Ele é agora dedicada a YSlow e outras ferramentas de desenvolvimento de pesquisas de desempenho, e evangelismo. Seu objetivo é tornar a web mais rápido do que ele pode ser e acredita que não existe tal coisa como "apenas alguns milésimos de segundo não vai doer".

Compartilhar e ampliar: Bookmark with del.icio.us | digg it! | reddit!

Update Suporte classificados Navegador

12 de julho, 2011 em 08:55 pm por Jenny Donnelly e Matt Sweeney | Em Desenvolvimento , suporte do navegador Graded | 21 Comments

Alterações GBS

Mudanças específicas para essa atualização incluem:

Base Teste navegador

Internet Explorer 6 7 8 9
Firefox 3. † 4. † 5. †
Chrome † Versão estável mais recente
Safári 5. † iOS 3. † iOS 4. †
Webkit Android 2. †

Notas:

  • O símbolo de adaga (como em "Firefox 4. †") indica que a mais atual versão não-beta nesse nível ramo recebe apoio.
  • Nenhuma orientação é dada sobre o uso do dispositivo iOS ou Android OS. A recomendação é que você escolha os dispositivos que são mais representativas de sua base de usuários para cada OS.

Removendo Grades da linha de base de teste do navegador

Esta edição do GBS atualização representa um desvio de nossas atualizações anteriores em que estão se afastando de navegadores mapeamento diretamente aos graus de experiência (por exemplo, "A-grade" e "C-grade"). Em vez de prescrever o que a experiência do usuário é apropriado para que os navegadores, vamos nos concentrar na definição de uma estratégia de teste de linha de base eficiente que maximiza a cobertura de teste e minimiza a superfície de testes. Por exemplo, ainda é significativa a nível mundial IE6 mandados de marketshare continuou os seus ensaios; GBS no entanto hoje em dia permite a experiência do usuário IE6 para ser diferente da experiência IE9.

Removendo Sistemas Operacionais da Linha de Base Teste Navegador

A fim de agilizar o teste e minimizar as necessidades de recursos, já não especificar qual sistema operacional deve ser testado. A única exceção é quando o navegador está intimamente ligado com a versão do sistema operacional, caso em que nós nos referimos à versão do sistema operacional ao invés da versão do navegador (por exemplo, "Safari iOS 4"). Isso nos permite concentrar a cobertura do teste em versões do navegador, e minimizar os ensaios redundantes em várias plataformas. Problemas com o mesmo navegador em versões são insignificantes e, em geral relacionados a diferenças de nível superior do sistema operacional, tais como manipulação de chave e fontes disponíveis. Código que é conhecido por tocar em cross-platform questões devem ser testados em tantas plataformas quanto possível, mas geralmente este teste pode ser isolado para as questões específicas ao invés de executar um teste de regressão de todos os recursos. Recomendamos o alinhamento operacional prioridade teste do sistema com sua base de usuários.

Porque é que o IE6 ainda na lista?

IE6 ainda tem uma quota de mercado significativo o suficiente para justificar globais uma experiência de usuário verificado aceitável. Um equívoco comum com a estratégia de fortalecimento progressivo foi que uma vez que um navegador entra "C-grade", que torna-se "não suportado", quando na verdade o que realmente significa que ele deve ser entregue a experiência HTML-only. Agora que nós já não prescrever quais navegadores receber o que a experiência, isso é deixado para projetos de decidir com base em seus usuários e recursos. O GBS concentra-se em especificar quais navegadores precisam de uma experiência verificada utilizável com base em fatores tais como a quota de mercado e influência. Definir o que é "usável" e especificando níveis aceitáveis ​​de degradação são deixados para as equipes para decidir. Nós ainda promover um simples acessório Progressive modelo, e desencorajar a projetos de criação de novas camadas sem contabilizar os custos adicionais no desenvolvimento, testes e recursos de manutenção.

Previsão GBS

Esperamos fazer as seguintes alterações na próxima atualização:

  • Descontinuar a cobertura para o Safari no iOS 3.
  • Adicionar cobertura para Webkit no Android 3.
  • Adicionar cobertura para Firefox 6.
  • Adicionar cobertura para Safari iOS 5.

O Arquivo GBS

Compartilhar e ampliar: Bookmark with del.icio.us | digg it! | reddit!

O "MakeNode" Extensão Widget

8 de julho de 2011 em 02:11 por Satyam | Em Desenvolvimento | 6 Comentários

Nota do Editor: Uma vez que este artigo foi originalmente publicado, o módulo MakeNode tenha sido publicada para a Galeria YUI e recebeu algumas melhorias. Por favor, consulte o artigo atualizado, Atualizado: O "MakeNode" Extensão Widget .

Em meu artigo anterior, uma receita para um 3 YUI Aplicação , mostrei uma maneira de usar Y.substitute como um processador de template muito básico. A idéia tomou a vida de lá, com sugestões de o pessoal do canal de IRC # yui, e eu fiz-lhe uma extensão Widget que está disponível no meu site, chamado MakeNode . MakeNode não é um processador de modelo genérico e não se entende como um só. Por outro lado, é totalmente integrado com o YUI Widget classe fundação, incluindo className e eventos ajudantes e internacionalização. Neste artigo, vou tomar a Spinner exemplo e modificá-lo para seguir as orientações do meu artigo anterior e usar MakeNode. O componente Spinner modificados ( JS , CSS , sprites ), bem como um exemplo estão disponíveis em meu site. Links para recursos adicionais podem ser encontradas no final deste artigo.

Estendendo seu componente

Uma vez MakeNode é carregado, você precisa incluir o módulo em seu YUI().use() declaração usando o nome 'makenode' . Então, para estender o seu widget, você listá-lo no terceiro argumento para Y.Base.create() , como este:

  Y. Spinner = Y.Base.create (
      'Spinner',
      Y. Widget,
      [Y. MakeNode],
      {
         / Members / exemplo ...
      },
      {
          / / Membros estáticos
      }
 ); 

Você pode adicionar MakeNode ao longo de qualquer número de extensões adequado para Widget, como WidgetParent, WidgetChild, WidgetStdMode, etc MakeNode adiciona dois métodos protegidos, _makeNode e _locateNodes, e ele irá ler a partir de várias propriedades estáticas, se encontrado.

Todos os membros desta extensão são ou protegidos ou privados, uma vez que se destinam a ser usadas pelo desenvolvedor do componente e não pelo implementador usando esses componentes, que não deve ser incomodado com elas.

Definindo o Modelo

A primeira coisa que você normalmente faz é definir o modelo para seu componente. Para a Spinner, o nosso modelo será:

  _template: [
     "<input Type="text" title="{s input}" class="{c input}"> ',
     "<button Type="button" title="{s up}" class="{c up}"> botão </> ',
     "<button Type="button" title="{s down}" class="{c down}"> botão </> '
 ]. Join ('\ n'), 

O modelo padrão será normalmente chamado _TEMPLATE e declarou ao longo da outras propriedades estáticas da classe, como ATTRS . MakeNode vai usar este modelo, se nenhum outro é expressamente previsto. O modelo é feito de HTML simples, mais uma série de marcadores de posição entre chaves, cada um feito de um único personagem (o código de processamento) e seguido por um ou mais argumentos. Os espaços reservados eo que eles produzem são:

  • {@ attributeName} valor de atributo de configuração

  • {p propertyName} valor propriedade de instância

  • {m methodName arg1 arg2 ….} valor de retorno de um método. O código de processamento é seguido pelo nome do método e qualquer número de argumentos separados por espaço em branco. Cordas devem ser colocados entre aspas duplas. Números, booleanos e null serão convertidos de string para seus tipos de dados adequada

  • {c classNameKey} className CSS gerado a partir do _CLASS_NAMES propriedade estática

  • {s key} cadeia a partir da strings atributo, utilizando key como o atributo de sub-.

  • {? other placeholder } Produz a seqüência checked quando o resultado do processamento do resto do espaço reservado é verdade.

  • {} qualquer outro valor será tratado apenas como Y.substitute faz.

Por exemplo, {@ value} se traduzirá em this.get('value') , enquanto {p value} traduz a this['value'] .

A {m} espaço reservado é um pouco mais complexa. O primeiro argumento após o m código de processamento é o nome do método e do resto dos argumentos, todos separados por espaços em branco, que será passado para o método dado. Estes argumentos podem ser números, null , true , false ou strings entre aspas duplas. MakeNode irá analisá-los e convertê-los em seus tipos adequados, assim {m myMethod 123.45 true “this is a string”} resultará em chamar this.myMethod(123.45, true, “this is a string”) para que os dois primeiros argumentos são convertidos para seus tipos de dados corretos ea seqüência pode conter espaços. Para incluir uma aspas duplas, use \\" , a barra invertida dupla sendo necessária, porque o JavaScript irá interpretar um único e descarta-lo antes que ele chegue ao MakeNode. aspas Apenas são permitidos, MakeNode não usa eval() para que o analisador é limitado mas segura. Qualquer coisa, mas números, null , booleanos e strings de aspas duplas serão ignoradas.

O {?} espaço reservado é útil para uso com caixas de seleção e botões de rádio. Ele produzirá a string “checked” , dependendo do valor de verdade do código de instrução de processamento que se segue. Assim, <input type=”checkbox” {? m getLength}/> <input type=”checkbox” {? m getLength}/> irá produzir uma caixa de seleção marcada se o getLength método retorna nada, mas zero. {?} aceitará qualquer um dos outros espaços reservados, embora ela só faz sentido com os três primeiros.

Para o {c} espaço reservado, nós precisamos ter um _CLASS_NAMES propriedade definida.

Espaços reservados adicionais podem ser adicionados a MakeNode, adicionando-os na _templateHandlers hash.

A propriedade _CLASS_NAMES

Junto com o ATTRS e _TEMPLATE atributos estáticos, podemos definir uma _CLASS_NAMES propriedade que aponta para uma matriz de strings. Cada uma dessas cadeias será usado para gerar um className. Assim _CLASS_NAMES: ['input'] irá produzir o className “yui3-spinner-input” . Os nomes de classes são armazenados em uma propriedade de instância this._classNames . O {c input} espaço reservado no modelo acima será substituído por “yui3-spinner-input” .

Você pode usar o _CLASS_NAMES propriedade para gerar qualquer número de nomes de classes, se você usá-los no modelo ou não. Você ainda pode alcançar aqueles classnames extra a partir de dentro this._classNames . O className é gerada utilizando o yui3 prefixo seguido pelo valor do NAME propriedade estática transformou em letras minúsculas, e então a string dada em _CLASS_NAMES (este último não será transformado em minúsculas), todos separados por hífens. O _classNames de hash irá conter também o classnames para o boundingBox eo contentBox , a primeira sob o "." chave ea segunda sob o “content” chave. Widget atribui ao boundingBox de classnames derivado dos valores do NAME propriedade de cada uma das classes na cadeia de herança, começando com yui3-widget . Lojas MakeNode em this._classNames apenas className o mais alto para o boundingBox .

Se um componente é vários níveis longe de Widget, como SuperSpecialSpinner herdando de SuperSpinner que herda de Spinner que herda de Widget, e se algum ou todos eles têm _CLASS_NAMES propriedades definidas, MakeNode produzirá classnames para todos eles e armazená-los em this._classNames . Você não precisa incluir em cada nível os nomes já declarados nos níveis anteriores. Na verdade, é melhor que você não desde o classnames produzida em cada nível irá usar o valor do NAME propriedade desse nível. Assim, em SuperSpecialSpinner , {c input} ainda resultar em “yui3-spinner-input” e não “yui3-superspecialspinner-input” e por isso irá manter o seu arquivo CSS ainda válido.

O espaço reservado {s}

Widget tem um strings atributo de configuração definida, embora não seja inicializada com qualquer valor. Este atributo é utilizado para armazenar seqüências de caracteres que são visíveis (ou, via leitores de tela, leia a) o usuário. É importante que você nunca incluem strings visíveis diretamente no modelo. Esta não é uma exigência de MakeNode - nunca foi uma boa idéia de todo. Todas as seqüências que devem ser vistas por ou lidas para o usuário sempre deve ser colocado no strings atributo. O strings atributo contém um hash onde cada texto individual fica por sua chave. O componente Spinner tem o seguinte texto, que você pode ver usados ​​no modelo acima.

  strings: {
     valor: {
         entrada: ". Pressione a seta para cima / para baixo teclas para incrementos menores, page up / down para incrementos importantes",
         up: "Increment",
         para baixo: "Decrement"
     }
 }, 

A melhor parte de fazer isso é que o componente pode ser localizada para outros idiomas com muita facilidade pelos desenvolvedores usando o componente. Ao criar uma instância de Spinner, você pode fazer:

  var mySpinner = new Spinner ({strings: Y.Intl.get ('giratório')}); 

Definindo o atributo de configuração strings desta forma substitui o padrão strings com os valores do arquivo de recursos de linguagem utilizando a linguagem previamente definida. O {s} espaço reservado acessa as cordas armazenados no strings atributo, tanto os padrão ou os convertidos, se definido. O {s xxxx} espaço reservado é, na verdade, nada mais do que um atalho para o {@ strings.xxxx} espaço reservado. No entanto, o primeiro só pode acessar strings no nível superior, enquanto, por exemplo, {@ strings.xxxx.yyyy.zzzz} permitiria o acesso a uma série mais baixo.

Usando _makeNode em renderUI

Nós usamos o modelo para criar a marcação para o nosso componente. Para isso, podemos chamar de MakeNode _makeNode método, como este:

  renderUI: function () {
     . this.get ('Contentbox') append (this._makeNode ());
 }, 

Isto irá preencher o contentBox do nosso widget com a marcação do processamento do modelo. O _makeNode método retorna uma instância de Y.Node , que pode ser acrescentado ou inserido em qualquer lugar ou apenas mantidos para uso posterior. Ela não retorna uma string, ela produz um Node exemplo.

O _makeNode método leva dois argumentos opcionais: uma referência a um modelo e um objeto para preencher espaços reservados, como Y.substitute faz. No nosso exemplo Spinner simples há um modelo único para o widget todo, mas outros widgets podem requerer pedaços feitos de vários modelos. Nesse caso, você normalmente chamada _makeNode sem argumentos para a parte principal e chamá-lo mais uma vez com modelos diferentes para preencher as partes extra. O exemplo contém este renderUI método:

  renderUI: function () {
     var fieldset = this._makeNode ();
     this.each (function (item) {
         fieldset.appendChild (this._makeNode (MultipleTemplates.RADIO_TEMPLATE, item));
     }, This);
     . this.get ('Contentbox') append (fieldset);
 } 

A primeira chamada para _makeNode retorna um Node instância armazenada na variável fieldset . O componente de exemplo também é estendido com Y.ArrayList de modo que o RADIO_TEMPLATE será preenchido com valores retirados os itens armazenados na lista de matriz e os nós resultantes anexado ao fieldset antes de ser finalmente anexado ao contentBox . Os espaços reservados especiais, tais como {@} ou {p} ainda se referem a atributos ou propriedades no objeto principal. Os itens aninhados serão processadas assim como Y.substitute faria.

O método _locateNodes

MakeNode prevê ainda uma _locateNodes método que irá tentar localizar todos os elementos com os nomes de classes declarada em _CLASS_NAMES . Para localizar elementos específicos você pode passar qualquer número de chaves className, caso contrário, _locateNodes tenta todos eles. Para cada elemento encontrado de cada className, _locateNodes produzirá uma propriedade de instância privada usando o prefixo sublinhado seguido pelo nome da chave e do “Node” sufixo. Assim, em nosso exemplo Spinner, _locateNodes irá gerar as propriedades _inputNode , _upNode e _downNode . Se vários elementos têm a mesma className, _locateNodes irá retornar uma referência para o primeiro deles. Se um elemento não for encontrado, nenhuma variável será criada.

Na componente Spinner usamos _locateNodes depois de criar a marcação:

  renderUI: function () {
     . this.get (CBX) append (this._makeNode ());
     this._locateNodes ();
 }, 

A propriedade estática _EVENTS

Uma propriedade adicional pode ser definido ao longo das linhas de _TEMPLATE e _CLASS_NAMES e que é _EVENTS . _EVENTS conterá um hash composta de chaves nome da classe, cada uma contendo uma mistura de tipos de eventos e métodos para lidar com eles. É melhor explicada com um exemplo:

  _EVENTS: {
     '.': {
         chave: {
             fn: '_onDirectionKey',
             args: ((Y.UA.opera) "para baixo":? "imprensa:") + "38, 40, 33, 34"
         },
         mousedown: '_onMouseDown'
     },
     '..': {
         mouseup: '_onDocMouseUp'
     },
     entrada: {
         mudança: "_onInputChange '
     }
 }, 

_EVENTS é um objeto (um hash), com qualquer número de propriedades. Os nomes das propriedades, ou seja, as chaves do hash, identificar os elementos cujos eventos vamos ouvir. Eles são os mesmos identificadores usados ​​em _CLASS_NAMES . Há duas teclas especiais extras "." e ".." . Enquanto as chaves className referem-se a elementos aninhados dentro do contentBox , o "." chave refere-se ao boundingBox em si, enquanto ".." refere-se ao documento que contém este widget. Pense neles como fazer um chdir comando quando localizado no boundingBox nível. O _EVENTS propriedade é processado após a renderUI , bindUI e syncUI métodos têm sido chamados assim o widget deverá já estar inserido dentro do corpo do documento, caso contrário o ".." irá falhar.

Cada uma das entradas na _EVENTS é um objeto, ainda, que usa o tipo de evento como sua chave eo nome de um método de instância para lidar com isso. _EVENTS , sendo uma variável estática, não tem acesso a this para que ele não pode ter referências função real, somente o nome do método ouvinte de evento. Alguns tipos de eventos necessitam de argumentos extra, tais como a key do evento. Nesse caso, em vez de fornecer o nome do manipulador de eventos que você pode fornecer um objeto com propriedades fn e args para manter o nome da função e os argumentos extra, quando necessário.

MakeNode usará Node.delegate para ouvir os acontecimentos dos elementos aninhados, enquanto ele usará Y.on para ouvir a eventos do boundingBox eo corpo do documento. (Note: listening to the key event on any nested element works only with version 3.4.0pr1 and above, since delegation of the key event was not available before. All the other features work with previous versions as well.)

The _EVENTS declarations are cumulative when components inherit from one another. Each class in the inheritance chain will have its own _EVENTS declaration processed separately.

The _ATTRS_2_UI static property

Events go both ways, from the UI to the component and from the component to the UI. The first are handled by the _EVENTS property. Then there are the events fired by attribute value changes that need to be reflected in the user interface. As I mentioned in the previous article, when there are any secondary effects from changing a configuration attribute, they should be handled by change event listeners, not by the optional setter method of the attribute, which should only deal with normalizing the value being set. The UI should reflect the state of the configuration attributes, first in syncUI , when being initialized and then on every attribute change event. For the latter, we need to attach an event listener, which we do in bindUI . Widget already provides a mechanism to make that simple, which I described in the comments to the previous article.

Widget uses the instance property _UI_ATTRS that contains an object with two further properties, SYNC and BIND . Each of these is an array listing the names of the configuration attributes to be initially synched and then listened to in order to keep the UI reflecting current values. Widget expects each of those entries to have a method associated with it, named after the attribute name prefixed by _uiSet with the first character of the attribute name converted to uppercase to have the method name in proper camel case. Thus, if "value" was listed in any of the _UI_ATTRS arrays (in either SYNC or BIND ), Widget would expect to find a _uiSetValue method. This method will receive two arguments, the value being set and the src of the change. This is the code for our Spinner _uiSetValue method:

 _uiSetValue : function(value, src) {
    if (src === UI) {
         retorno;
     }
    this._inputNode.set(VALUE, this.get(FORMATTER)(value));
 }, 

All the uppercase identifiers you see in this piece of code correspond to string constants declared elsewhere, to allow the YUI compressor to do its job better. The method, basically, sets the value HTML attribute in the <input> box to the new value set, after being formatted. The reference to the textbox was provided by _locateNodes . The src argument is initially checked to see if set to the string value 'ui' . If this is so, no action will be taken. This is to avoid endless loops. If the user enters something in the input box, its value would go into the value configuration attribute which then would fire a valueChange event, which would get _uiSetValue called which, if unchecked, would then go and change the value of the input box, which would trigger the whole process again. Thus, in _uiSetValue , if we know the change comes from the UI, we do nothing and so break the loop. However, this requires another piece of code elsewhere. In the listener for the DOM event, when we set the configuration attribute, we use the third optional argument to set, like this:

 _afterValueChange : function(ev) {
    this.set(VALUE, ev.newVal, {src: UI});
 } 

It is up to us to ensure that changes coming from the UI are flagged thus and then check that same flag to avoid loops.

With all this said, I haven't yet mentioned the static property _ATTRS_2_UI mentioned in the heading of this section. As the comments in my previous article shows (through the blunders I made in them), making sure that all attributes affecting the UI are properly listed is somewhat messy. You should never initialize _UI_ATTRS from scratch since Widget already lists a whole lot of attributes and those would be lost. You have to concatenate new attribute names over the existing ones, which is somewhat hard to remember how to do it right. To make it simple, MakeNode will read from the static property _ATTRS_2_UI and do that concatenation for you. It will concatenate all such lists from each and every class in the inheritance chain so at each level each class can handle its own attributes. In Spinner, we have:

 _ATTRS_2_UI: {
    BIND: VALUE,
    SYNC: VALUE
 }, 

MakeNode will accept both an array of names or a single attribute name, as in this case.

The question naturally arises, why two lists, one for binding the other for syncing? Quite often the SYNC array has fewer entries than the BIND list and this is because the template for the component might already have the very same default value as the configuration attribute and there is no need to do an initial syncing. So, if the default value for the value configuration attribute is an empty string and the <input> element in the template has no value attribute, then there is no need to sync them on initialization.

MakeNode will check for duplicate entries in any of these arrays. If any appear, it means that a class our component inherits from already handles this attribute and any new declaration would most likely overstep the _uiSetXxxx handler for it. Incidentally, MakeNode also checks for duplicate entries in _CLASS_NAMES , which can also cause conflict in some, though not all, circumstances. MakeNode will write a message to the log for any such error.

Conclusão

MakeNode provides a very simple template processor, with simple functionality that is highly integrated with the Widget foundation class. It also provides helper methods to create classNames to be used in the template and use those names to locate the nodes created. It also provides the means to hook into the events generated both by the UI and the component itself and associate each with a method. It does all these things, while taking care to respect the inheritance chain straight up to Widget and any level of classes you may define.

It does not provide for absolutely all possibilities, but covers a good range of them. Nevertheless, it does not preclude you from adding extra functionality. You might rarely have to write a bindUI or syncUI method if you use the glue provided by MakeNode, but you may do so, since MakeNode does not use them.

As a bonus to those who had the patience to read this far, I have also modified Anthony Pipkin's Button set of gallery components:

The API docs can be found here .

Compartilhar e ampliar: Bookmark with del.icio.us | digg it! | reddit!

YUI e carregador de mudanças para 3.4.0

July 1, 2011 at 6:34 am by Dav Glass | In Development , Performance | 10 Comments

In 3.4.0 we started the process of shifting some of Loader's logic around, to not only make it more performant, but to make it more robust and easier to use in other places (like on the server). We will be rolling out more changes in future revisions, but I wanted to take some time and explain what was changed, why it was changed and how it may impact developers. For the majority of use-cases, developers will notice nothing different, except that things are a little faster and their requirement downloads are a little smaller.

Arquivo de sementes

The first thing I want to address is the YUI seed file. In previous versions of YUI, our seed file was very tiny and did not contain Loader or any of its meta-data. We've found that in the 90% use-case this was not as performant as we had hoped. The normal user includes the seed file then requests their modules, which in turn means that the seed needs to first fetch Loader, then calculate all of its dependencies, then fetch them all. We now feel that this extra http request is the wrong thing to do, so the new standard seed file contains Loader and its meta-data. Yes, this will make the initial request a little larger, but it will make the loading of modules that much faster since all of its meta-data requirements are now already on the page.

If you wish to use it the old way, you can just include the yui-base seed file instead. It contains everything that is needed to make YUI run in stand-alone mode plus it contains the ability to fetch Loader on demand. If you require even finer-grained dependencies, we have created a yui-core seed file that is exactly what the old yui-base seed was.

    /build/yui/yui-min.js //YUI Seed + Loader
    /build/yui-base/yui-base-min.js //Old YUI Seed with Loader fetch support
    /build/yui-core/yui-core-min.js //Old yui-base without Loader fetch support

It should be noted that these URLs are different than the previous URLs. Anyone that was using the yui/yui-base.js files need to repoint them to yui-core/yui-core.js . If you want the older way of loading the seed and fetching Loader, you would use the yui-base/yui-base.js seed file.

The other reasoning for this change is our roadmap for making YUI run in as many places as possible. The old seed file plus Loader in a single combo server request is all well and good if you have a combo server available in your application. But what about on the server? Or in an offline app on a mobile device? These places need to minimize file access while still getting the information they need.

Rollups

The next thing that we changed was removing rollups from the system and defaulting allowRollup to false in the Loader config. What does this mean to you? Well, hopefully nothing at all. Before I explain the impact of the change, let me explain the reasoning behind it. The primary reason is, again, performance, along with payload delivery. Veja este exemplo:

     Module A: requires event-a, event-b
     Module B: requires event-c, event-d

When you request both, the rollup logic prior to 3.4.0 used to determine that you should get the event rollup. Which actually meant that you were getting:

     event.a, event.b, event.c, event.d, event.e, event.f, event.g, event.h

You ended up with more on your page than you actually needed. By turning off the rollup support, YUI will now ask for only what you actually requested and nothing more. In most cases, you will not notice this . Module developers, may run into a situation where things that worked in the past may not work now. The reason for this is that they actually worked by accident before. Let me use a real world example: Dial .

In 3.3.0, Dial required this:

    requires: [
        'widget',
        'dd-drag',
        'substitute',
        'event-mouseenter', 
        'transition',
        'intl'
     ]

For the most part, Dial worked in 3.4.0, however keyboard support did not work. After doing some simple investigating, it turned out that the rollup support was actually requesting the entire Event rollup (which includes event-move and event-key). Without the rollup logic pulling in all of event, 3.4.0 Dial no longer had all of its requirements. Making Dial's requirements more specific and defining all of its actual dependencies properly makes it work as expected.

    requires: [
        'widget',
        'dd-drag',
        'substitute',
        'event-mouseenter',
        'event-move',
        'event-key',
        'transition',
        'intl'
     ]

For module developers, it is a best practice to make sure that your module requires exactly what it needs to function. Do not assume that an upstream module requirement is there. It's always better to make sure that you ask for what you need.

This also means that module requirements are more well defined. For example, datatype-date has Intl support built in. In previous versions you would access the Intl like this:

    Y.Intl.getAvailableLangs('datatype-date');

But since this module doesn't actually have a language (the datatype-date-format module does), this will fail. It needs to be more specific and actually ask for languages for the correct module:

    Y.Intl.getAvailableLangs('datatype-date-format');

Build File Explosion and Submodule Removal

After making this change, the next change we made was exploding the build directory and removing submodules from the core system. Submodule logic was not removed, only our meta-data structure was changed. This will provide backward compatibility for current installations.

Submodules in the core system caused a couple of issues that we needed to resolve. The first reason was performance. Each time Loader needed to calculate dependencies, it needed to walk the submodule/plugin structure of each module. Doing this thousands of times was hurting our performance during the Loader calculate routine. By removing support for submodules in the core system we saved tens of thousands of function calls and iterations.

Loader was changed so that if a use property in a module's meta-data defined more modules, it will use those modules instead of trying to load the original module. So, if you requested “ dd ” Loader would inspect “ dd “'s meta-data and see a use property that looks something like this:

    "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin"

In the core YUI seed file, we are also including what we are calling virtual rollups or aliases . These module definitions are exactly the same as the meta-data in Loader. This way you can include all the files exported from our Dependency Configurator and still use these rollups without having Loader present on the page. In future releases, we will be refining this approach even more.

After making this change, we then preceeded to explode our build files. In previous releases, the submodules determined the modules file path. Por exemplo:

    "dd": {
        "submodules": {
            "dd-drag": 
            // Module data
         }
     }

In 3.3.0 when you built “dd”, the file structure looked something like this:

    /build/dd/dd-drag.js
    /build/dd/dd-ddm.js
    /build/dd/dd-drop.js

With the build system exploded in 3.4.0, “dd”'s build files now look like this:

    /build/dd-drag/dd-drag.js
    /build/dd-ddm/dd-ddm.js
    /build/dd-drop/dd-drop.js

This allowed us to remove the “path” property from all of our module meta-data as well, saving file size and reducing the logic required to assemble the modules url paths.

If you are including a pre-configured combo URL, you must recalculate your URL when you upgrade.

The downside to this change is that if you are including a combo URL of modules to “prep” your page you can not just change the version number and upgrade. You will need to revisit the Dependency Configurator and generate a new URL with new module structure.

O Futuro

I will be continuing to refine, refactor and maximize every aspect of our Loader and Seed strategy. These first steps were needed to aid in future changes that need to be made for not only our client-side strategy but also our server, command-line and mobile device strategies as well.

Compartilhar e ampliar: Bookmark with del.icio.us | digg it! | reddit!

Hosted by Yahoo!

Copyright © 2006-2011 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service

Alimentado por WordPress sobre Yahoo! Web Hosting .