SlideShare une entreprise Scribd logo
1  sur  90
DESENVOLVENDO PLUGINS COM
  O JQUERY UI E TESTANDO
       COM JASMINE




         FISL 13
QUEM SOU EU?
Alexandre Magno
                  na




                       atualmente no
PROJETOS
OPEN SOURCE
Twitter Bootstrap BR                     jQuery sliding




https://github.com/alexanmtz/bootstrap
                                          http://www.github.com/alexanmtz

jQuery Destaque                          WP-Agenda




                                           https://github.com/alexanmtz/wp-agenda
 https://github.com/globocom/destaque
OUTROS PROJETOS...
  Blog Webpoint
  http://blog.alexadremagno.net   eutro.co
                                   http://eutro.co




Balloon3
http://balloon3.com


                                  Salve a web por favo
                                   http://salveaweb.com/
NAS HORAS VAGAS...
http://www.gandhifica.com
VAMOS FALAR DE QUÊ?
Jasmine
                      jQuery
            Plugins
                               design
                 Pattern
      Widget
      factory
                                          TDD
                      javascript         BDD
jQuery UI




              Ajax
                           Refactoring
TUDO ISSO NA PRÁTICA?
SIM!
MAS ANTES
VAMOS FALAR DE
JAVASCRIPT
fonte: http://aaroncrowder.com/
POR QUE O JAVASCRIPT
 FICOU TÃO POPULAR?
JQUERY
“MEU PRIMEIRO CONTATO COM
O JAVASCRIPT FOI COM JQUERY”
                      Beethoven
API
<script type="text/javascript">
! $(function(){
! ! $('div').css('color', 'red').appendTo('body');
! });
</script>
ALGUMA SEMELHANÇA




COM O BRANDING DO JQUERY?
PLUGINS
USE OS PLUGINS JQUERY PARA
CRIAR COMPONENTES JAVASCRIPT




                        https://moqups.com
UM PLUGIN BÁSICO
// Create the defaults once
    var pluginName = 'defaultPluginName',
        defaults = {
            propertyName: "value"
        };

    // The actual plugin constructor
    function Plugin( element, opt ) {
        this.element = element;

        this.options = $.extend( {}, defaults,opt );

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }
Plugin.prototype = {
        
        init: function() {
           this.yourOtherFunction(this.element, this.options);
        },
        
        yourOtherFunction: function(el, options) {
            // some logic
        }
    };

    $.fn[pluginName] = function ( options ) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName);
                new Plugin( this, options ));
            }
        });
    }
<script type="text/javascript">
! $(function(){
! ! console.log($('body').defaultPluginName());
! });
</script>




       fonte: https://github.com/addyosmani/jquery-plugin-patterns/
EXEMPLO MAIS REAL?




  JQUERY JFLOW
"   >
                                 sc ript
                      xt/ java                   JQUERY JFLOW
                  = "t e
           type (){
     ript ction             ) .jfl
                                   ow()
                                        ;
                                                 PATTERN DE PLUGIN BÁSICO
< s c fun              nto'
                 leme
                                                 https://github.com/alexanmtz/jflow
     $(
 !        (' # e
  !   ! $
   !   }); t>
            p
    </ scri
             ao clicar aqui




                                                                            Os elementos se mo
                                                                                               vem
                   e aqui
Ô NÓ, Eu quero usar o jflow em
meu projeto, mas a minha listagem
vai ser dinâmica, com possibilidade
de novos itens serem adicionados,
   porém não está funcionando!
BUG?
<scrip
                                                        t type
                        avasc r i p t" >        ! $(fu         = "t e x t
                                                                          /javas
                 text/j                                 nction
                                                               (){               c r i p t"
      t  type="                                 ! ! $
                                                       ('#ele                               >
<scrip ction(){              flow({                           mento2
   $(fun                  .j                                            ').jfl
!                e nto1')                                    items:            ow({
       ( ' #elem s: 5                                                   4
 ! ! $         item                            ! });
                                                         });

            });                                </scri
                                                      pt>
  ! });
           t>
  < /scrip



                                           e aqui
ao clicar aqui
<scrip
                                                        t type
                        avasc r i p t" >        ! $(fu         = "t e x t
                                                                          /javas
                 text/j                                 nction
                                                               (){               c r i p t"
      t  type="                                 ! ! $
                                                       ('#ele                               >
<scrip ction(){              flow({                           mento2
   $(fun                  .j                                            ').jfl
!                e nto1')                                    items:            ow({
       ( ' #elem s: 5                                                   4
 ! ! $         item                            ! });
                                                         });

            });                                </scri
                                                      pt>
  ! });
           t>
  < /scrip



                                           e aqui
ao clicar aqui
TEMOS UM PROBLEMA
Plugins de jQuery são inicializados apenas uma vez


não podem ser
modificados
Ou seja,
um plugin
jQuery é...
que que é
  isso?




  STATELESS
r">
<div i    d = "c o n t a i n e
! ul>
 <
                                                     Métodos de classe
                           li>
! <
 !     li> item 1</
                             i>
! <l     i> item 2</l
 !
            > item 3</li
                                >          Atributos data
 ! <li
  !
                          /li>
 !!   <li> item 4<
 ! /ul>
  <
  </div>                              w({
  $('#conta      iner').jflo
  ! tens: 3,
   i                                         ,
                        ta  i n e r u l l i'
    i t e m : '# c o n                           Como chamar método
                         zon   t a l'                               s?
   ! mode: ' hori
   });
                   preciso executar u
                                               ma ação



                                      ow_metodo( ); //no!
     $('#contai n e r' ) . j f l
      $('#container
                            ').jflow.meto
                                                  do(); //wtf
MEU
CÓDIGO
VIROU UM
FRANKSTEIN
PATTERNS
STATELESS
     Basic plugin
Namespace                                                  Prototypal
                                                          inheritance
                                                         Widget factory
                                                             bridge
Custom events

                                                                Widget factory

                                                         Highly configurable
 Best options

                                                     Extend skeleton


   “UMA SOLUÇÃO GERAL REUSÁVEL DE
      UM PROBLEMA RECORRENTE”
                                                    Wikipedia

                    fonte: https://github.com/addyosmani/jquery-plugin-patterns/
JQUERY UI
p t" >
                         java
                              s    cri
                                                      ;
                                                                COM O WIDGET FACTORY
                      t/                    )
                " tex                  ete(
            ype= ){             c ompl
        pt t ion(          auto
< scri unct           o').
       ( f     e ment
 ! $ $(' # e l
  ! ! ;
         )
   ! } ipt>
    < /scr




                                                                                            ... ) })
                                                                                        (
                                                                                ete , {
                                                                     toc ompl
                                                          $.u i.au                               p t" >
                                                  "   ,                                      cri
                                          se arch                                 t/j avas
                               ui. auto                                    " tex                  h();
                           "                                           ype= ){               earc
                    get(
                                                                                           s
                 id                                               pt t ion(           auto
           $.w                                            < scri unct            o').
                                                                 (f       e ment
                                                           ! $ $('#el
                                                            ! ! ;
    TEMOS HERANÇA                                            !   })
                                                                     ipt>
                                                              < /scr
EU QUERY MEU WIDGET
EU TAMBÉM!
JQUERY UI SLIDING
COMO FUNCIONA?
O QUE É
O QUE É
O QUE É
O QUE É
O QUE É
um carrossel?
                                  jQuery Cycle Plugin

                 Isto é um carrossel!


jQuery Sliding




                           Elementos deslizantes
LETS CODE!
// widget factory
    $.widget( “ui.sliding”, {
        options: {
           items: 5
           // mais opcoes
        },
        pages: 0,
        _create: function() {
           this._enclose();
        },
        _enclose: function() {
            // enclose envolve o elemento deslizante
             // this.options são as opções
        }
        goToPage: function(page) {
            // logica de ir para pagina
             // this.element é o elemento
             // this.options são as opções
        }

    });
<script type="text/javascript">
! $(function(){
! ! $('#elemento').sliding();
    $('#elemento').sliding(“goToPage”, 2);
! });
</script>
<script type="text/javascript">
! $(function(){
! ! $('#elemento').sliding(“destroy”);
    $('#elemento').sliding(“option”, “items”, 3);
! });
</script>
<script type="text/javascript">
! $(function(){
! ! $('#elemento').sliding(“refresh”);
    $('#elemento').sliding(“restart”);
! });
</script>
// widget factory
    $.widget( “ui.sliding”, {
           _setOption: function(key, value) {
             // alguma logica, depois
           $.Widget.prototype._setOption.apply( this, arguments );
        },
        enable: function() {
            // logica de habilitar
            // this.options são as opções
        },
        disable: function() {
            // logica de desabilitar
            // this.element é o elemento
            // this.options são as opções
        }

    });
E COMO TESTA ISTO?
TESTAR MÉTODOS
                          getCurrentPage
  getTotalPages



                  $.ui.widget   setTotalPages




     goToPage
                                                before


                                           onAppend
next remote




              E CALLBACKS
USANDO O QUÊ?
METODOLOGIA
TDD É...




FICAR VERMELHO
PARA DEPOIS




FICAR VERDE
E SUCESSIVAMENTE




FICAR VERMELHO
PARA DEPOIS




FICAR VERDE
BDD
JASMINE
sliding / tests / spec / SlidingSpec.js

describe("Sliding", function() {

  beforeEach(function(){
    jQuery.fx.off = true;
  });

  it("should load the instance of the plugin",
function() {
    expect($.ui.sliding).toBeTruthy();
  });
});
JQUERY UI WIDGET
sliding / jquery.sliding.js
// widget factory
    $.widget( “ui.sliding”, {
           _create: function() {
             // codigo da inicializacao
        },
        options: {
               // objeto de opções
        },
        isLastPage: function() {
            return this.getCurrentPage() ==
this.getTotalPages();
        }

    });
SPEC
sliding / tests / spec / SlidingSpec.js

it("should get the currentPage and check if is last one", function(){

 $(container).sliding('goToPage', 2);

  var currPage = $(container).sliding.('getCurrentPage');

  expect(currPage).toBe(2);

  expect($(container).sliding(‘isLastPage’)).toBeTruthy();

});
O QUE MAIS A JASMINE




    TEM DE BOM?
JASMINE JQUERY
sliding / tests / spec / SlidingSpec.js


 it("should the first page should have previous button disabled",
 function(){

  expect($('.ui-sliding-prev').get(0)).toHaveClass('disabled');

  expect($('.ui-sliding-next').get(0)).not.toHaveClass('disabled');

 });
POSSÍVEIS RESULTADOS
AJAX MOCK
MOCK DO DATA
              VINDO DO AJAX
sliding / tests / spec / SlidingSpec.js



 describe("remote sliding", function(){
      var newData = '';
      beforeEach(function(){
        newData = createUnorderedList(30, true);
        spyOn($, 'ajax').andCallFake(function(options){
          options.success(newData);
        });
     });
E COM ISSO...
sliding / tests / spec / SlidingSpec.js

it("should make a ajax request for second page", function(){

        $(container).sliding({
          next: '.test-next',
          prev: '.test-prev',
          url: 'foo/test',
          items: 15 // one page
        });

        $(container).sliding('setTotalPages', 3);
        $('.test-next').trigger('click');

        expect($(container).get(0)).beInRange(15,30); // Next

     });
MATCHERS
sliding / tests / spec / SpecHelper.js
beforeEach(function() {
  this.addMatchers({
   beInRange: function(start, end) {
       var isIn = 0;
        var current_width = $(this.actual).width();
        var container_pos = $(this.actual).position();
        var final_pos = current_width + container_pos.left;

        $(this.actual).find('li').slice(start,
end).each(function(i, el){
            var el_pos = $(this).position();
            if (el_pos.left < final_pos && el_pos.left >=
container_pos.left) {
                isIn++;
            }
        });

        return isIn == $(this.actual).sliding('option','items');
    }
  });
});
MATCHER PARA DETECTAR
  QUANTOS ELEMENTOS
 ESTÃO SENDO EXIBIDOS
MATCHER PARA DETECTAR
  QUANTOS ELEMENTOS
 ESTÃO SENDO EXIBIDOS
MATCHER PARA DETECTAR
  QUANTOS ELEMENTOS
 ESTÃO SENDO EXIBIDOS
CHAMADAS AJAX
sliding / tests / spec / SlidingSpec.js
it("should not make ajax request when is going to previous page",
function(){

       $(container).sliding({
          next: '.test-next',
          prev: '.test-prev',
          url: 'foo/test2',
          items: 15
        });

        $(container).sliding('setTotalPages', 3);
        $(container).sliding('goToPage', 2);
        $('.test-prev').trigger('click');

        expect($.ajax.callCount).toEqual(1);

     });
CHAMADAS AJAX
sliding / tests / spec / SlidingSpec.js

it("should pass extra parameters in the request", function(){

       $(container).sliding({
         next: '.test-next',
         prev: '.test-prev',
         url: 'foo/test3',
         items: 15,
         params: {
           'extra' : 'foo'
         }
       });

       $(container).sliding('goToPage', 2);
       expect($.ajax.mostRecentCall.args[0]
["data"]).toEqual({'extra':'foo'});

     });
SPIES PARA
                  CALLBACKS
sliding / tests / spec / SlidingSpec.js


it("should call loading callback when request starts", function() {
     var callback = jasmine.createSpy();

     $(container).sliding({
       next: '.test-next',
       prev: '.test-prev',
       url: 'foo/test2',
       before: callback,
       items: 15
     });

     $(container).sliding('setTotalPages', 3);
     $(container).sliding('goToPage', 2);

     expect(callback).toHaveBeenCalled();
});
CLOCK.TICK
sliding / tests / spec / SlidingSpec.js


beforeEach(function() {
    jasmine.Clock.useMock();
});
it("Should set current page just when animation over", function(){

      $(‘#container’).sliding({ speed: 200 });

   $(‘#container’).sliding(‘goToPage’, 2);

   jasmine.Clock.tick(200);

   expect($(‘#container’).sliding(‘getCurrentPage’)).toBe(2);

});
FIXTURES
sliding / tests / spec / SlidingSpec.js


beforeEach(function() {
   loadFixtures("list.html");
});
spec / javascript / fixtures / list.html

<ul id=”list”>
  <li>item 01</li>
  <li>item 02</li>
</ul>

sliding / tests / spec / SlidingSpec.js

describe(“usando fixtures”, function() {
   expect($(‘#list’).length).toBe(1);
});
VOCÊ SÓ VAI APRENDER




     FAZENDO!
OBRIGADO!




  @alexanmtz

Contenu connexe

En vedette

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

En vedette (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Criando plugins com o j query ui e testando com o jasmine

  • 1. DESENVOLVENDO PLUGINS COM O JQUERY UI E TESTANDO COM JASMINE FISL 13
  • 3. Alexandre Magno na atualmente no
  • 5. Twitter Bootstrap BR jQuery sliding https://github.com/alexanmtz/bootstrap http://www.github.com/alexanmtz jQuery Destaque WP-Agenda https://github.com/alexanmtz/wp-agenda https://github.com/globocom/destaque
  • 6. OUTROS PROJETOS... Blog Webpoint http://blog.alexadremagno.net eutro.co http://eutro.co Balloon3 http://balloon3.com Salve a web por favo http://salveaweb.com/
  • 10. Jasmine jQuery Plugins design Pattern Widget factory TDD javascript BDD jQuery UI Ajax Refactoring
  • 11. TUDO ISSO NA PRÁTICA?
  • 12. SIM!
  • 16. POR QUE O JAVASCRIPT FICOU TÃO POPULAR?
  • 17.
  • 19. “MEU PRIMEIRO CONTATO COM O JAVASCRIPT FOI COM JQUERY” Beethoven
  • 20. API
  • 21. <script type="text/javascript"> ! $(function(){ ! ! $('div').css('color', 'red').appendTo('body'); ! }); </script>
  • 22. ALGUMA SEMELHANÇA COM O BRANDING DO JQUERY?
  • 24. USE OS PLUGINS JQUERY PARA CRIAR COMPONENTES JAVASCRIPT https://moqups.com
  • 26. // Create the defaults once     var pluginName = 'defaultPluginName',         defaults = {             propertyName: "value"         };     // The actual plugin constructor     function Plugin( element, opt ) {         this.element = element;         this.options = $.extend( {}, defaults,opt );         this._defaults = defaults;         this._name = pluginName;         this.init();     }
  • 27. Plugin.prototype = {                  init: function() {            this.yourOtherFunction(this.element, this.options);         },                  yourOtherFunction: function(el, options) {             // some logic         }     };     $.fn[pluginName] = function ( options ) {         return this.each(function () {             if (!$.data(this, 'plugin_' + pluginName)) {                 $.data(this, 'plugin_' + pluginName);                 new Plugin( this, options ));             }         });     }
  • 28. <script type="text/javascript"> ! $(function(){ ! ! console.log($('body').defaultPluginName()); ! }); </script> fonte: https://github.com/addyosmani/jquery-plugin-patterns/
  • 29. EXEMPLO MAIS REAL? JQUERY JFLOW
  • 30. " > sc ript xt/ java JQUERY JFLOW = "t e type (){ ript ction ) .jfl ow() ; PATTERN DE PLUGIN BÁSICO < s c fun nto' leme https://github.com/alexanmtz/jflow $( ! (' # e ! ! $ ! }); t> p </ scri ao clicar aqui Os elementos se mo vem e aqui
  • 31. Ô NÓ, Eu quero usar o jflow em meu projeto, mas a minha listagem vai ser dinâmica, com possibilidade de novos itens serem adicionados, porém não está funcionando!
  • 32. BUG?
  • 33. <scrip t type avasc r i p t" > ! $(fu = "t e x t /javas text/j nction (){ c r i p t" t type=" ! ! $ ('#ele > <scrip ction(){ flow({ mento2 $(fun .j ').jfl ! e nto1') items: ow({ ( ' #elem s: 5 4 ! ! $ item ! }); }); }); </scri pt> ! }); t> < /scrip e aqui ao clicar aqui
  • 34. <scrip t type avasc r i p t" > ! $(fu = "t e x t /javas text/j nction (){ c r i p t" t type=" ! ! $ ('#ele > <scrip ction(){ flow({ mento2 $(fun .j ').jfl ! e nto1') items: ow({ ( ' #elem s: 5 4 ! ! $ item ! }); }); }); </scri pt> ! }); t> < /scrip e aqui ao clicar aqui
  • 36. Plugins de jQuery são inicializados apenas uma vez não podem ser modificados Ou seja, um plugin jQuery é...
  • 37. que que é isso? STATELESS
  • 38. r"> <div i d = "c o n t a i n e ! ul> < Métodos de classe li> ! < ! li> item 1</ i> ! <l i> item 2</l ! > item 3</li > Atributos data ! <li ! /li> !! <li> item 4< ! /ul> < </div> w({ $('#conta iner').jflo ! tens: 3, i , ta i n e r u l l i' i t e m : '# c o n Como chamar método zon t a l' s? ! mode: ' hori }); preciso executar u ma ação ow_metodo( ); //no! $('#contai n e r' ) . j f l $('#container ').jflow.meto do(); //wtf
  • 41. STATELESS Basic plugin Namespace Prototypal inheritance Widget factory bridge Custom events Widget factory Highly configurable Best options Extend skeleton “UMA SOLUÇÃO GERAL REUSÁVEL DE UM PROBLEMA RECORRENTE” Wikipedia fonte: https://github.com/addyosmani/jquery-plugin-patterns/
  • 43.
  • 44. p t" > java s cri ; COM O WIDGET FACTORY t/ ) " tex ete( ype= ){ c ompl pt t ion( auto < scri unct o'). ( f e ment ! $ $(' # e l ! ! ; ) ! } ipt> < /scr ... ) }) ( ete , { toc ompl $.u i.au p t" > " , cri se arch t/j avas ui. auto " tex h(); " ype= ){ earc get( s id pt t ion( auto $.w < scri unct o'). (f e ment ! $ $('#el ! ! ; TEMOS HERANÇA ! }) ipt> < /scr
  • 45. EU QUERY MEU WIDGET
  • 54. um carrossel? jQuery Cycle Plugin Isto é um carrossel! jQuery Sliding Elementos deslizantes
  • 56. // widget factory     $.widget( “ui.sliding”, {         options: { items: 5 // mais opcoes }, pages: 0, _create: function() {            this._enclose();         },         _enclose: function() {             // enclose envolve o elemento deslizante // this.options são as opções         }         goToPage: function(page) {             // logica de ir para pagina // this.element é o elemento // this.options são as opções         } });
  • 57. <script type="text/javascript"> ! $(function(){ ! ! $('#elemento').sliding(); $('#elemento').sliding(“goToPage”, 2); ! }); </script>
  • 58. <script type="text/javascript"> ! $(function(){ ! ! $('#elemento').sliding(“destroy”); $('#elemento').sliding(“option”, “items”, 3); ! }); </script>
  • 59. <script type="text/javascript"> ! $(function(){ ! ! $('#elemento').sliding(“refresh”); $('#elemento').sliding(“restart”); ! }); </script>
  • 60. // widget factory     $.widget( “ui.sliding”, { _setOption: function(key, value) {             // alguma logica, depois $.Widget.prototype._setOption.apply( this, arguments );         },         enable: function() {             // logica de habilitar // this.options são as opções         },         disable: function() {             // logica de desabilitar // this.element é o elemento // this.options são as opções         } });
  • 61. E COMO TESTA ISTO?
  • 62. TESTAR MÉTODOS getCurrentPage getTotalPages $.ui.widget setTotalPages goToPage before onAppend next remote E CALLBACKS
  • 69. BDD
  • 71. sliding / tests / spec / SlidingSpec.js describe("Sliding", function() {   beforeEach(function(){     jQuery.fx.off = true;   });   it("should load the instance of the plugin", function() {     expect($.ui.sliding).toBeTruthy();   }); });
  • 72. JQUERY UI WIDGET sliding / jquery.sliding.js // widget factory     $.widget( “ui.sliding”, { _create: function() {             // codigo da inicializacao         },         options: { // objeto de opções         },         isLastPage: function() {             return this.getCurrentPage() == this.getTotalPages();         } });
  • 73. SPEC sliding / tests / spec / SlidingSpec.js it("should get the currentPage and check if is last one", function(){  $(container).sliding('goToPage', 2); var currPage = $(container).sliding.('getCurrentPage');   expect(currPage).toBe(2); expect($(container).sliding(‘isLastPage’)).toBeTruthy(); });
  • 74. O QUE MAIS A JASMINE TEM DE BOM?
  • 75. JASMINE JQUERY sliding / tests / spec / SlidingSpec.js it("should the first page should have previous button disabled", function(){  expect($('.ui-sliding-prev').get(0)).toHaveClass('disabled');  expect($('.ui-sliding-next').get(0)).not.toHaveClass('disabled'); });
  • 78. MOCK DO DATA VINDO DO AJAX sliding / tests / spec / SlidingSpec.js  describe("remote sliding", function(){       var newData = '';       beforeEach(function(){         newData = createUnorderedList(30, true);         spyOn($, 'ajax').andCallFake(function(options){           options.success(newData);         });      });
  • 79. E COM ISSO... sliding / tests / spec / SlidingSpec.js it("should make a ajax request for second page", function(){         $(container).sliding({           next: '.test-next',           prev: '.test-prev',           url: 'foo/test',           items: 15 // one page         });         $(container).sliding('setTotalPages', 3);         $('.test-next').trigger('click');         expect($(container).get(0)).beInRange(15,30); // Next      });
  • 80. MATCHERS sliding / tests / spec / SpecHelper.js beforeEach(function() {   this.addMatchers({    beInRange: function(start, end) {        var isIn = 0;         var current_width = $(this.actual).width();         var container_pos = $(this.actual).position();         var final_pos = current_width + container_pos.left;         $(this.actual).find('li').slice(start, end).each(function(i, el){             var el_pos = $(this).position();             if (el_pos.left < final_pos && el_pos.left >= container_pos.left) {                 isIn++;             }         });         return isIn == $(this.actual).sliding('option','items');     }   }); });
  • 81. MATCHER PARA DETECTAR QUANTOS ELEMENTOS ESTÃO SENDO EXIBIDOS
  • 82. MATCHER PARA DETECTAR QUANTOS ELEMENTOS ESTÃO SENDO EXIBIDOS
  • 83. MATCHER PARA DETECTAR QUANTOS ELEMENTOS ESTÃO SENDO EXIBIDOS
  • 84. CHAMADAS AJAX sliding / tests / spec / SlidingSpec.js it("should not make ajax request when is going to previous page", function(){        $(container).sliding({           next: '.test-next',           prev: '.test-prev',           url: 'foo/test2',           items: 15         });         $(container).sliding('setTotalPages', 3);         $(container).sliding('goToPage', 2);         $('.test-prev').trigger('click');         expect($.ajax.callCount).toEqual(1);      });
  • 85. CHAMADAS AJAX sliding / tests / spec / SlidingSpec.js it("should pass extra parameters in the request", function(){        $(container).sliding({          next: '.test-next',          prev: '.test-prev',          url: 'foo/test3',          items: 15,          params: {            'extra' : 'foo'          }        });        $(container).sliding('goToPage', 2);        expect($.ajax.mostRecentCall.args[0] ["data"]).toEqual({'extra':'foo'});      });
  • 86. SPIES PARA CALLBACKS sliding / tests / spec / SlidingSpec.js it("should call loading callback when request starts", function() {      var callback = jasmine.createSpy();      $(container).sliding({        next: '.test-next',        prev: '.test-prev',        url: 'foo/test2',        before: callback,        items: 15      });      $(container).sliding('setTotalPages', 3);      $(container).sliding('goToPage', 2);      expect(callback).toHaveBeenCalled(); });
  • 87. CLOCK.TICK sliding / tests / spec / SlidingSpec.js beforeEach(function() {     jasmine.Clock.useMock(); }); it("Should set current page just when animation over", function(){ $(‘#container’).sliding({ speed: 200 });    $(‘#container’).sliding(‘goToPage’, 2);    jasmine.Clock.tick(200);    expect($(‘#container’).sliding(‘getCurrentPage’)).toBe(2); });
  • 88. FIXTURES sliding / tests / spec / SlidingSpec.js beforeEach(function() {    loadFixtures("list.html"); }); spec / javascript / fixtures / list.html <ul id=”list”> <li>item 01</li> <li>item 02</li> </ul> sliding / tests / spec / SlidingSpec.js describe(“usando fixtures”, function() {    expect($(‘#list’).length).toBe(1); });
  • 89. VOCÊ SÓ VAI APRENDER FAZENDO!

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n