waiter 0.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
 - data/.rspec +2 -0
 - data/README.md +34 -32
 - data/Rakefile +10 -0
 - data/app/assets/images/waiter/bg.gif +0 -0
 - data/app/assets/images/waiter/selected-bg.gif +0 -0
 - data/app/assets/stylesheets/waiter/menu.css.scss +129 -0
 - data/app/views/waiter/_item.haml +8 -0
 - data/app/views/waiter/_menu_bar.haml +3 -0
 - data/app/views/waiter/_section.haml +5 -0
 - data/app/views/waiter/_sub_item.haml +2 -0
 - data/app/views/waiter/_submenu.haml +6 -0
 - data/lib/waiter/dsl.rb +24 -0
 - data/lib/waiter/menu/drawer.rb +7 -55
 - data/lib/waiter/menu/item.rb +137 -0
 - data/lib/waiter/menu/item_list.rb +19 -0
 - data/lib/waiter/menu/section.rb +21 -0
 - data/lib/waiter/menu.rb +54 -12
 - data/lib/waiter/version.rb +1 -1
 - data/lib/waiter.rb +12 -3
 - data/spec/spec_helper.rb +89 -0
 - data/spec/support/matchers/have_a_submenu.rb +34 -0
 - data/spec/support/matchers/have_exactly.rb +24 -0
 - data/spec/support/matchers/have_menu_items_named.rb +32 -0
 - data/spec/support/matchers/have_options.rb +23 -0
 - data/spec/support/shared_examples/menu_item_shared_examples.rb +67 -0
 - data/spec/waiter/menu/item_list_spec.rb +38 -0
 - data/spec/waiter/menu/item_spec.rb +161 -0
 - data/spec/waiter/menu/section_spec.rb +21 -0
 - data/spec/waiter/menu_spec.rb +298 -0
 - data/waiter.gemspec +4 -0
 - metadata +97 -13
 - data/lib/waiter/menu/builder.rb +0 -18
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            !binary "U0hBMQ==":
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: !binary |-
         
     | 
| 
      
 4 
     | 
    
         
            +
                YmQ1YzdlZmU3MDM4ZDgwOWQ0ZmNhMjI5MDcwNGYxZTUwMTE5YzI1MQ==
         
     | 
| 
      
 5 
     | 
    
         
            +
              data.tar.gz: !binary |-
         
     | 
| 
      
 6 
     | 
    
         
            +
                ZTg1ZmIzMDc1MmQ4MDQ0MDk1ZDRmZjIwNzViMDVmYmFlYzBjYzhiNQ==
         
     | 
| 
      
 7 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 8 
     | 
    
         
            +
              metadata.gz: !binary |-
         
     | 
| 
      
 9 
     | 
    
         
            +
                NTBhMTMxOWQ4ZmNiZWEwZmNkMDkwMDBiZDA3YjIyODNhYTM1M2ZhNDgwYjY2
         
     | 
| 
      
 10 
     | 
    
         
            +
                OThhODZmYmQ3MDVhMWQzYTY4YWM4NWMwNGFiNzg5MTk4NWM1OTlkODIxMDM3
         
     | 
| 
      
 11 
     | 
    
         
            +
                ZTAwYjFhMTE1YWU3ZDhjYzE5ZDkyODI1ZjllNjdmMDEyZTY2ZGQ=
         
     | 
| 
      
 12 
     | 
    
         
            +
              data.tar.gz: !binary |-
         
     | 
| 
      
 13 
     | 
    
         
            +
                MGVjZTZmMWY4NmY3MTM4NDI0NGQyNjBkMTc1MTFkZGM4OWFkYjU1YTc2MmIz
         
     | 
| 
      
 14 
     | 
    
         
            +
                MWNkNWYwNjhiMWY5YTRhNGQ2NWNkMzdjMDQzZDA3YzBkN2FlNzEwMzc4OTIz
         
     | 
| 
      
 15 
     | 
    
         
            +
                NzU4YmZjZTA2YjFhNDVmNWEwMTM2NTJhMzk1ZGIyOTZkMzVjNGY=
         
     | 
    
        data/.rspec
    ADDED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -24,33 +24,41 @@ Or install it yourself as: 
     | 
|
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
            To create a new menu:
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                Waiter::Menu.serve do 
     | 
| 
       28 
     | 
    
         
            -
                   
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
       30 
     | 
    
         
            -
                   
     | 
| 
      
 27 
     | 
    
         
            +
                Waiter::Menu.serve(:my_menu) do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  file
         
     | 
| 
      
 29 
     | 
    
         
            +
                  edit
         
     | 
| 
      
 30 
     | 
    
         
            +
                  view
         
     | 
| 
       31 
31 
     | 
    
         
             
                  # ...
         
     | 
| 
       32 
32 
     | 
    
         
             
                end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
            The above defines a menu with three items. By default, each item name (ie. "file", "edit", etc.) corresponds both to the 
     | 
| 
      
 34 
     | 
    
         
            +
            The above defines a menu with three items. By default, each item name (ie. "file", "edit", etc.) corresponds both to the
         
     | 
| 
      
 35 
     | 
    
         
            +
            I18n string to use (so `file` will call `I18n.t(:file, scope: [:menu, :my_menu])`) as well as to the controller to use
         
     | 
| 
      
 36 
     | 
    
         
            +
            (`file` will correspond to `FileController`, and the menu item will link to `FileController#index` by default).
         
     | 
| 
       35 
37 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
            Of course, there will be situations where the path may need to be explicitly specified. In this case,  
     | 
| 
       37 
     | 
    
         
            -
            and `:action` options can be specified:
         
     | 
| 
      
 38 
     | 
    
         
            +
            Of course, there will be situations where the path may need to be explicitly specified. In this case, you can use a path finder:
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                Waiter::Menu 
     | 
| 
       40 
     | 
    
         
            -
                  menu.file  
     | 
| 
      
 40 
     | 
    
         
            +
                Waiter::Menu::serve do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  menu.file documents_path
         
     | 
| 
       41 
42 
     | 
    
         
             
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
         
     | 
| 
      
 44 
     | 
    
         
            +
            Alternately, the `:controller` and `:action` options can be specified:
         
     | 
| 
       42 
45 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
                Waiter::Menu.serve do
         
     | 
| 
      
 47 
     | 
    
         
            +
                  menu.file :controller => :documents, :action => :index
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
                
         
     | 
| 
      
 50 
     | 
    
         
            +
            In both of the above examples, the File menu will correspond to `DocumentsController#index`, and will be shown as selected
         
     | 
| 
      
 51 
     | 
    
         
            +
            for any action within that controller.
         
     | 
| 
       45 
52 
     | 
    
         | 
| 
       46 
53 
     | 
    
         
             
            There may also be times where you need multiple controllers to light up the same menu item. This can be achieved by
         
     | 
| 
       47 
54 
     | 
    
         
             
            passing an array to the `:controllers` option:
         
     | 
| 
       48 
55 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                Waiter::Menu.serve do 
     | 
| 
       50 
     | 
    
         
            -
                   
     | 
| 
      
 56 
     | 
    
         
            +
                Waiter::Menu.serve do
         
     | 
| 
      
 57 
     | 
    
         
            +
                  file :controllers => ['files', 'print', ... ]
         
     | 
| 
       51 
58 
     | 
    
         
             
                end
         
     | 
| 
       52 
59 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
            This will create a menu that links to `DocumentsController#index`, which will be lit up the user hits any action within 
     | 
| 
      
 60 
     | 
    
         
            +
            This will create a menu that links to `DocumentsController#index`, which will be lit up the user hits any action within
         
     | 
| 
      
 61 
     | 
    
         
            +
            the `FilesController`, `PrintController`, as well as the `DocumentsController`.
         
     | 
| 
       54 
62 
     | 
    
         | 
| 
       55 
63 
     | 
    
         | 
| 
       56 
64 
     | 
    
         
             
            ### Submenus
         
     | 
| 
         @@ -61,20 +69,18 @@ passed as a block to the root menu item. 
     | 
|
| 
       61 
69 
     | 
    
         | 
| 
       62 
70 
     | 
    
         
             
            Submenus automatically assume the controller to use is the controller specified by its root menu item, so a
         
     | 
| 
       63 
71 
     | 
    
         
             
            controller does not need to be specified unless it differs. As well, the menu item name is assumed to be used
         
     | 
| 
       64 
     | 
    
         
            -
            for the  
     | 
| 
      
 72 
     | 
    
         
            +
            for the controller for that item, so it does not need to be specified unless it differs from the name.
         
     | 
| 
       65 
73 
     | 
    
         
             
            An id can also be specified if necessary (with the `:id` option).
         
     | 
| 
       66 
74 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                Waiter::Menu.serve do 
     | 
| 
       68 
     | 
    
         
            -
                   
     | 
| 
       69 
     | 
    
         
            -
                     
     | 
| 
       70 
     | 
    
         
            -
                     
     | 
| 
       71 
     | 
    
         
            -
                     
     | 
| 
       72 
     | 
    
         
            -
                    file.print, :controller => 'print'  # Corresponds to PrintController#print
         
     | 
| 
      
 75 
     | 
    
         
            +
                Waiter::Menu.serve do
         
     | 
| 
      
 76 
     | 
    
         
            +
                  file do
         
     | 
| 
      
 77 
     | 
    
         
            +
                    new                            # Corresponds to FileController#new
         
     | 
| 
      
 78 
     | 
    
         
            +
                    print print_file_path          # Corresponds to PrintController#print
         
     | 
| 
      
 79 
     | 
    
         
            +
                    list :action => :all           # Corresponds to ListController#all
         
     | 
| 
       73 
80 
     | 
    
         
             
                  end
         
     | 
| 
       74 
81 
     | 
    
         
             
                end
         
     | 
| 
       75 
82 
     | 
    
         | 
| 
       76 
     | 
    
         
            -
            If  
     | 
| 
       77 
     | 
    
         
            -
            action for the controller will be used instead.
         
     | 
| 
      
 83 
     | 
    
         
            +
            If a path hash is given without an `action` key, the index action will be inferred.
         
     | 
| 
       78 
84 
     | 
    
         | 
| 
       79 
85 
     | 
    
         | 
| 
       80 
86 
     | 
    
         
             
            ### Menu Options
         
     | 
| 
         @@ -82,14 +88,6 @@ action for the controller will be used instead. 
     | 
|
| 
       82 
88 
     | 
    
         
             
            There are two options that you can use when building your menu. Options can be passed into build when defining
         
     | 
| 
       83 
89 
     | 
    
         
             
            a menu or specified once the menu is defined by accessing the menu.options hash.
         
     | 
| 
       84 
90 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
            `string_prefix`: Allows for a prefix for I18n strings to be specified.
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                Waiter::Menu.serve(:string_prefix => 'menu_') do |menu|
         
     | 
| 
       88 
     | 
    
         
            -
                  menu.file
         
     | 
| 
       89 
     | 
    
         
            -
                end
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                # will use I18n.t(:menu_file) instead of I18n.t(:file)
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
91 
     | 
    
         
             
            `selected`: Allows the selected menu item to be overridden, so a specified menu item can be lit up regardless of
         
     | 
| 
       94 
92 
     | 
    
         
             
            what the current controller/action is. This can be useful if there is an action that falls under different menu
         
     | 
| 
       95 
93 
     | 
    
         
             
            items depending on application context, or if there is a controller that may correspond to multiple menu items.
         
     | 
| 
         @@ -123,7 +121,11 @@ the context is self. 
     | 
|
| 
       123 
121 
     | 
    
         | 
| 
       124 
122 
     | 
    
         
             
                Waiter::Menu::Drawer.new(menu, context).draw
         
     | 
| 
       125 
123 
     | 
    
         | 
| 
       126 
     | 
    
         
            -
            If a different `Drawer` is desired, `Waiter::Menu::Drawer` can be subclassed and the  
     | 
| 
      
 124 
     | 
    
         
            +
            If a different `Drawer` is desired, `Waiter::Menu::Drawer` can be subclassed and the method `draw` overridden to provide an alternate format.
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            Alternately, `Waiter::Menu` responds to `draw` directly:
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                menu.draw(context)
         
     | 
| 
       127 
129 
     | 
    
         | 
| 
       128 
130 
     | 
    
         
             
            ## Contributing
         
     | 
| 
       129 
131 
     | 
    
         | 
    
        data/Rakefile
    CHANGED
    
    
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         @@ -0,0 +1,129 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             * Menu bar
         
     | 
| 
      
 3 
     | 
    
         
            +
             */
         
     | 
| 
      
 4 
     | 
    
         
            +
            .waiter-menu
         
     | 
| 
      
 5 
     | 
    
         
            +
            {
         
     | 
| 
      
 6 
     | 
    
         
            +
              width: 100%;
         
     | 
| 
      
 7 
     | 
    
         
            +
              display: block;
         
     | 
| 
      
 8 
     | 
    
         
            +
              height: 40px;
         
     | 
| 
      
 9 
     | 
    
         
            +
              border: 0px;
         
     | 
| 
      
 10 
     | 
    
         
            +
              background: image-url('waiter/bg.gif') repeat-x left top;
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              div.top-item
         
     | 
| 
      
 13 
     | 
    
         
            +
              {
         
     | 
| 
      
 14 
     | 
    
         
            +
                float: left;
         
     | 
| 
      
 15 
     | 
    
         
            +
                position: relative;
         
     | 
| 
      
 16 
     | 
    
         
            +
                top: 10px;
         
     | 
| 
      
 17 
     | 
    
         
            +
                height: 20px;
         
     | 
| 
      
 18 
     | 
    
         
            +
                min-width: 80px;
         
     | 
| 
      
 19 
     | 
    
         
            +
                border-right: 1px solid #e6e9ef;
         
     | 
| 
      
 20 
     | 
    
         
            +
                border-left: 0;
         
     | 
| 
      
 21 
     | 
    
         
            +
                margin: 0;
         
     | 
| 
      
 22 
     | 
    
         
            +
                text-align: center;
         
     | 
| 
      
 23 
     | 
    
         
            +
                /* Fix IE7 z-index bug - See http://brenelz.com/blog/squish-the-internet-explorer-z-index-bug/ */
         
     | 
| 
      
 24 
     | 
    
         
            +
                z-index: 10501;
         
     | 
| 
      
 25 
     | 
    
         
            +
                color: #e6e9ef;
         
     | 
| 
      
 26 
     | 
    
         
            +
                font-family: "Arial";
         
     | 
| 
      
 27 
     | 
    
         
            +
                font-weight: bold;
         
     | 
| 
      
 28 
     | 
    
         
            +
                font-size: 14px;
         
     | 
| 
      
 29 
     | 
    
         
            +
                padding: 5px 15px 5px 10px;
         
     | 
| 
      
 30 
     | 
    
         
            +
                cursor: default;
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                a
         
     | 
| 
      
 33 
     | 
    
         
            +
                {
         
     | 
| 
      
 34 
     | 
    
         
            +
                  color: #FFF;
         
     | 
| 
      
 35 
     | 
    
         
            +
                  display: block;
         
     | 
| 
      
 36 
     | 
    
         
            +
                  height: 20px;
         
     | 
| 
      
 37 
     | 
    
         
            +
                  min-width: 80px;
         
     | 
| 
      
 38 
     | 
    
         
            +
                  text-decoration: none;
         
     | 
| 
      
 39 
     | 
    
         
            +
                }
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                &:hover, &.selected
         
     | 
| 
      
 42 
     | 
    
         
            +
                {
         
     | 
| 
      
 43 
     | 
    
         
            +
                  color: #FFF;
         
     | 
| 
      
 44 
     | 
    
         
            +
                  background: image-url('waiter/selected-bg.gif') repeat-x left top;
         
     | 
| 
      
 45 
     | 
    
         
            +
                }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                $submenu-border-color: #888;
         
     | 
| 
      
 48 
     | 
    
         
            +
                $submenu-item-border-color: #CCC;
         
     | 
| 
      
 49 
     | 
    
         
            +
                $submenu-item-height: 20px;
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                ul.submenu
         
     | 
| 
      
 52 
     | 
    
         
            +
                {
         
     | 
| 
      
 53 
     | 
    
         
            +
                  position: absolute;
         
     | 
| 
      
 54 
     | 
    
         
            +
                  top: 30px;
         
     | 
| 
      
 55 
     | 
    
         
            +
                  left: 0;
         
     | 
| 
      
 56 
     | 
    
         
            +
                  background-color: #ffffff;
         
     | 
| 
      
 57 
     | 
    
         
            +
                  display: none;
         
     | 
| 
      
 58 
     | 
    
         
            +
                  z-index: 10500;
         
     | 
| 
      
 59 
     | 
    
         
            +
                  margin: 0;
         
     | 
| 
      
 60 
     | 
    
         
            +
                  padding: 0;
         
     | 
| 
      
 61 
     | 
    
         
            +
                  border: 2px solid $submenu-border-color;
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  li
         
     | 
| 
      
 64 
     | 
    
         
            +
                  {
         
     | 
| 
      
 65 
     | 
    
         
            +
                    list-style-type: none;
         
     | 
| 
      
 66 
     | 
    
         
            +
                    min-height: $submenu-item-height;
         
     | 
| 
      
 67 
     | 
    
         
            +
                    line-height: $submenu-item-height;
         
     | 
| 
      
 68 
     | 
    
         
            +
                    vertical-align: middle;
         
     | 
| 
      
 69 
     | 
    
         
            +
                    background-color: #e6e9ef;
         
     | 
| 
      
 70 
     | 
    
         
            +
                    border-top: 1px solid $submenu-item-border-color;
         
     | 
| 
      
 71 
     | 
    
         
            +
                    min-width: 150px;
         
     | 
| 
      
 72 
     | 
    
         
            +
                    text-align: left;
         
     | 
| 
      
 73 
     | 
    
         
            +
                    white-space: nowrap;
         
     | 
| 
      
 74 
     | 
    
         
            +
                    color: #000000;
         
     | 
| 
      
 75 
     | 
    
         
            +
                    border-collapse: collapse;
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    font-family: "Arial";
         
     | 
| 
      
 78 
     | 
    
         
            +
                    font-weight: normal;
         
     | 
| 
      
 79 
     | 
    
         
            +
                    font-size: 12px;
         
     | 
| 
      
 80 
     | 
    
         
            +
                    white-space: nowrap;
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    a, a:hover
         
     | 
| 
      
 83 
     | 
    
         
            +
                    {
         
     | 
| 
      
 84 
     | 
    
         
            +
                      color: #000000;
         
     | 
| 
      
 85 
     | 
    
         
            +
                      font-weight: normal;
         
     | 
| 
      
 86 
     | 
    
         
            +
                      padding-left: 8px;
         
     | 
| 
      
 87 
     | 
    
         
            +
                      padding-right: 8px;
         
     | 
| 
      
 88 
     | 
    
         
            +
                      line-height: $submenu-item-height + 12px;
         
     | 
| 
      
 89 
     | 
    
         
            +
                      height: $submenu-item-height + 12px;
         
     | 
| 
      
 90 
     | 
    
         
            +
                    }
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                    &:first-child
         
     | 
| 
      
 93 
     | 
    
         
            +
                    {
         
     | 
| 
      
 94 
     | 
    
         
            +
                      border-top: 0;
         
     | 
| 
      
 95 
     | 
    
         
            +
                    }
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    &:hover
         
     | 
| 
      
 98 
     | 
    
         
            +
                    {
         
     | 
| 
      
 99 
     | 
    
         
            +
                      background-color: #ff9900;
         
     | 
| 
      
 100 
     | 
    
         
            +
                    }
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                    &.separator
         
     | 
| 
      
 103 
     | 
    
         
            +
                    {
         
     | 
| 
      
 104 
     | 
    
         
            +
                      min-height: 0;
         
     | 
| 
      
 105 
     | 
    
         
            +
                      max-height: 0;
         
     | 
| 
      
 106 
     | 
    
         
            +
                      padding: 0;
         
     | 
| 
      
 107 
     | 
    
         
            +
                      border: 0;
         
     | 
| 
      
 108 
     | 
    
         
            +
                    }
         
     | 
| 
      
 109 
     | 
    
         
            +
                  }
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                  li.separator + li
         
     | 
| 
      
 112 
     | 
    
         
            +
                  {
         
     | 
| 
      
 113 
     | 
    
         
            +
                    border-top: 2px solid $submenu-border-color;
         
     | 
| 
      
 114 
     | 
    
         
            +
                  }
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                  li.separator + li.separator
         
     | 
| 
      
 117 
     | 
    
         
            +
                  {
         
     | 
| 
      
 118 
     | 
    
         
            +
                    display: none;
         
     | 
| 
      
 119 
     | 
    
         
            +
                  }
         
     | 
| 
      
 120 
     | 
    
         
            +
                }
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                &:hover ul.submenu
         
     | 
| 
      
 123 
     | 
    
         
            +
                {
         
     | 
| 
      
 124 
     | 
    
         
            +
                  background-color: #333333;
         
     | 
| 
      
 125 
     | 
    
         
            +
                  /*border:1px solid #333333;*/
         
     | 
| 
      
 126 
     | 
    
         
            +
                  display: block;
         
     | 
| 
      
 127 
     | 
    
         
            +
                }
         
     | 
| 
      
 128 
     | 
    
         
            +
              }
         
     | 
| 
      
 129 
     | 
    
         
            +
            }
         
     | 
    
        data/lib/waiter/dsl.rb
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/core_ext/array/extract_options'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Waiter
         
     | 
| 
      
 4 
     | 
    
         
            +
              module DSL
         
     | 
| 
      
 5 
     | 
    
         
            +
                def section(options = {}, &block)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  add_section(options, &block)
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def method_missing(name, *args, &block)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  return context.send(name, *args, &block) if context.respond_to?(name)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  path = args.shift
         
     | 
| 
      
 13 
     | 
    
         
            +
                  options = args.extract_options!
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  if path.is_a?(Hash) && !(path.key?(:controller) || path.key?(:action))
         
     | 
| 
      
 16 
     | 
    
         
            +
                    options, path = path, nil
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  options[:controllers] ||= []
         
     | 
| 
      
 20 
     | 
    
         
            +
                  add(name, path, options, &block)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  return nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/waiter/menu/drawer.rb
    CHANGED
    
    | 
         @@ -1,63 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/core_ext/module/delegation'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Waiter
         
     | 
| 
       2 
4 
     | 
    
         
             
              class Menu
         
     | 
| 
       3 
5 
     | 
    
         
             
                # Outputs a Menu into HTML
         
     | 
| 
       4 
6 
     | 
    
         
             
                class Drawer
         
     | 
| 
       5 
     | 
    
         
            -
                   
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_reader :menu, :context
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  delegate :render, :link_to, :content_tag, :params, :to => :context
         
     | 
| 
       7 
10 
     | 
    
         | 
| 
       8 
11 
     | 
    
         
             
                  def initialize(menu, context)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    # context is a Controller binding, which allows the ActionView helpers to work in the correct context
         
     | 
| 
       9 
13 
     | 
    
         
             
                    @context = context
         
     | 
| 
       10 
14 
     | 
    
         
             
                    @menu = menu
         
     | 
| 
       11 
15 
     | 
    
         
             
                  end
         
     | 
| 
       12 
16 
     | 
    
         | 
| 
       13 
17 
     | 
    
         
             
                  def draw
         
     | 
| 
       14 
     | 
    
         
            -
                     
     | 
| 
       15 
     | 
    
         
            -
                      out = ActiveSupport::SafeBuffer.new
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                      @menu.items.each do |(name, menu)|
         
     | 
| 
       18 
     | 
    
         
            -
                        menu[:controller] = name unless menu[:controller]
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                        # Allow an :if option which will only display the menu if true
         
     | 
| 
       21 
     | 
    
         
            -
                        if !menu[:if] or menu[:if].call
         
     | 
| 
       22 
     | 
    
         
            -
                          # If there is a :selected option, use that instead of trying to determine the selected menu item
         
     | 
| 
       23 
     | 
    
         
            -
                          selected = menu_selected?(name, menu[:controller], menu[:action] || menu[:actions], menu.delete(:controllers))
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                          out << content_tag(:span, :class => selected ? "selected" : nil) do
         
     | 
| 
       26 
     | 
    
         
            -
                            out2 = ActiveSupport::SafeBuffer.new
         
     | 
| 
       27 
     | 
    
         
            -
                            out2 << link_to(I18n.t(@menu.options[:string_prefix].to_s + name.to_s), { :controller => menu.delete(:controller).to_s.absolutify, :action => (menu.delete(:action) || menu.delete(:actions).andand.first) }.merge(menu))
         
     | 
| 
       28 
     | 
    
         
            -
                            out2 << draw_submenu(@menu.submenus[name]) if @menu.submenus[name]
         
     | 
| 
       29 
     | 
    
         
            -
                            out2
         
     | 
| 
       30 
     | 
    
         
            -
                          end
         
     | 
| 
       31 
     | 
    
         
            -
                        end
         
     | 
| 
       32 
     | 
    
         
            -
                      end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                      out << '<br class="clear" />'.html_safe
         
     | 
| 
       35 
     | 
    
         
            -
                      out
         
     | 
| 
       36 
     | 
    
         
            -
                    end
         
     | 
| 
       37 
     | 
    
         
            -
                  end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                  def draw_submenu(submenu)
         
     | 
| 
       40 
     | 
    
         
            -
                    content_tag :table, :class => "dropdown", :cellspacing => 0 do
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                      out = ActiveSupport::SafeBuffer.new
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                      submenu.items.each do |(name, menu)|
         
     | 
| 
       45 
     | 
    
         
            -
                        out << content_tag(:tr) do
         
     | 
| 
       46 
     | 
    
         
            -
                          content_tag :td do
         
     | 
| 
       47 
     | 
    
         
            -
                            controller = menu.delete(:controller) || submenu.options[:controller]
         
     | 
| 
       48 
     | 
    
         
            -
                            action =
         
     | 
| 
       49 
     | 
    
         
            -
                                menu.delete(:action) || begin
         
     | 
| 
       50 
     | 
    
         
            -
                                  controller_class = "#{controller}_controller".classify.constantize
         
     | 
| 
       51 
     | 
    
         
            -
                                  controller_class.action_methods.include?(name.to_s) ? name : nil
         
     | 
| 
       52 
     | 
    
         
            -
                                end rescue nil || :index
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                            link_to I18n.t(submenu.options[:string_prefix].to_s + name.to_s), { :controller => controller.to_s.absolutify, :action => action }.merge(menu)
         
     | 
| 
       55 
     | 
    
         
            -
                          end
         
     | 
| 
       56 
     | 
    
         
            -
                        end
         
     | 
| 
       57 
     | 
    
         
            -
                      end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                      out
         
     | 
| 
       60 
     | 
    
         
            -
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
                    render partial: 'waiter/menu_bar', locals: { menu: menu }
         
     | 
| 
       61 
19 
     | 
    
         
             
                  end
         
     | 
| 
       62 
20 
     | 
    
         | 
| 
       63 
21 
     | 
    
         
             
                  protected
         
     | 
| 
         @@ -82,10 +40,4 @@ module Waiter 
     | 
|
| 
       82 
40 
     | 
    
         
             
                  end
         
     | 
| 
       83 
41 
     | 
    
         
             
                end
         
     | 
| 
       84 
42 
     | 
    
         
             
              end
         
     | 
| 
       85 
     | 
    
         
            -
            end
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
            class String
         
     | 
| 
       88 
     | 
    
         
            -
              def absolutify
         
     | 
| 
       89 
     | 
    
         
            -
                self.gsub(%r{^(?!/)}, "/")
         
     | 
| 
       90 
     | 
    
         
            -
              end
         
     | 
| 
       91 
43 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,137 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/core_ext/object/try'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_support/core_ext/hash/reverse_merge'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'active_support/core_ext/module/delegation'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'active_support/core_ext/object/blank'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Waiter
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Menu
         
     | 
| 
      
 8 
     | 
    
         
            +
                class Item
         
     | 
| 
      
 9 
     | 
    
         
            +
                  attr_reader :parent, :name, :path, :submenu
         
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_accessor :options
         
     | 
| 
      
 11 
     | 
    
         
            +
                  delegate :context, to: :parent
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def initialize(parent, name, path = {}, options = {}, &block)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @parent = parent
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @name = name
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @path = complete_path_for(path)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @options = options
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    collect_controllers
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    @options.reverse_merge!(parent.options || {})
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    if block_given?
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @submenu = Menu.new([@parent.name, name].compact, @parent.context, @options.dup)
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @submenu.parent = self
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @submenu.update(&block)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def section?
         
     | 
| 
      
 31 
     | 
    
         
            +
                    false
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def items
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @submenu.try(:items) || []
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def [](name)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    return nil if items.empty?
         
     | 
| 
      
 40 
     | 
    
         
            +
                    items[name]
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def submenu?
         
     | 
| 
      
 44 
     | 
    
         
            +
                    submenu.present?
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def menu_title
         
     | 
| 
      
 48 
     | 
    
         
            +
                    translate(:title)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def item_title
         
     | 
| 
      
 52 
     | 
    
         
            +
                    translate(name)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  def controller
         
     | 
| 
      
 56 
     | 
    
         
            +
                    @controller ||= find_controller
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  def controllers
         
     | 
| 
      
 60 
     | 
    
         
            +
                    options[:controllers]
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  def selected?
         
     | 
| 
      
 64 
     | 
    
         
            +
                    return name == options[:selected] if options[:selected]
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    current_controller = context.params[:controller]
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    if wildcard_controllers.any?
         
     | 
| 
      
 69 
     | 
    
         
            +
                      return true if wildcard_controllers.any? do |c|
         
     | 
| 
      
 70 
     | 
    
         
            +
                        r = Regexp.new(c.sub(%r{/\*$}, '(/*)?').gsub('*', '.*'))
         
     | 
| 
      
 71 
     | 
    
         
            +
                        r =~ current_controller
         
     | 
| 
      
 72 
     | 
    
         
            +
                      end
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    controllers.include?(current_controller)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  def inspect
         
     | 
| 
      
 79 
     | 
    
         
            +
                    "#<#{self.class.name}:#{'0x%x' % (36971870 << 1)} name=#{name.inspect} options=#{options.inspect} parent=#{parent.inspect} submenu=#{submenu.inspect}>"
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                private
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def translate(key)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    scope = i18n_scope
         
     | 
| 
      
 86 
     | 
    
         
            +
                    scope.pop if scope.last == key
         
     | 
| 
      
 87 
     | 
    
         
            +
                    I18n.t(key, scope: scope, cascade: true)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  def i18n_scope
         
     | 
| 
      
 91 
     | 
    
         
            +
                    [:menu, parent.name, name].flatten.compact
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  def complete_path_for(path)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    return if path.nil? && parent.top?
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    case path
         
     | 
| 
      
 98 
     | 
    
         
            +
                      when String
         
     | 
| 
      
 99 
     | 
    
         
            +
                        path
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                      when Hash, NilClass
         
     | 
| 
      
 102 
     | 
    
         
            +
                        path ||= {}
         
     | 
| 
      
 103 
     | 
    
         
            +
                        path[:action] ||= :index
         
     | 
| 
      
 104 
     | 
    
         
            +
                        path[:controller] ||= name
         
     | 
| 
      
 105 
     | 
    
         
            +
                        path[:controller] = path[:controller].to_s.gsub(%r{^(?!/)}, '/')
         
     | 
| 
      
 106 
     | 
    
         
            +
                        path
         
     | 
| 
      
 107 
     | 
    
         
            +
                    end
         
     | 
| 
      
 108 
     | 
    
         
            +
                  end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                  def find_controller
         
     | 
| 
      
 111 
     | 
    
         
            +
                    case path
         
     | 
| 
      
 112 
     | 
    
         
            +
                      when Hash
         
     | 
| 
      
 113 
     | 
    
         
            +
                        path[:controller].to_s.gsub(%r{^/}, '')
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                      when String
         
     | 
| 
      
 116 
     | 
    
         
            +
                        request = parent.context.request
         
     | 
| 
      
 117 
     | 
    
         
            +
                        route = Rails.application.routes.recognize_path("#{request.protocol}#{request.host}#{path}")
         
     | 
| 
      
 118 
     | 
    
         
            +
                        route ? route[:controller].to_s : nil
         
     | 
| 
      
 119 
     | 
    
         
            +
                    end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  rescue ActionController::RoutingError
         
     | 
| 
      
 122 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  def collect_controllers
         
     | 
| 
      
 126 
     | 
    
         
            +
                    target = parent.top? ? self : parent
         
     | 
| 
      
 127 
     | 
    
         
            +
                    target.options[:controllers] ||= []
         
     | 
| 
      
 128 
     | 
    
         
            +
                    target.options[:controllers] << controller unless controller.blank?
         
     | 
| 
      
 129 
     | 
    
         
            +
                    target.options[:controllers].uniq!
         
     | 
| 
      
 130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  def wildcard_controllers
         
     | 
| 
      
 133 
     | 
    
         
            +
                    @wildcard_controllers ||= controllers.select{ |c| c['*'] }
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Waiter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Menu
         
     | 
| 
      
 3 
     | 
    
         
            +
                class ItemList < Array
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def include?(other)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    return map(&:name).include?(other) if other.is_a? Symbol
         
     | 
| 
      
 6 
     | 
    
         
            +
                    super
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def [](index)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    return detect{ |item| item.name == index } if index.is_a? Symbol
         
     | 
| 
      
 11 
     | 
    
         
            +
                    super
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def names
         
     | 
| 
      
 15 
     | 
    
         
            +
                    map(&:name)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'waiter/menu/item'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Waiter
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Menu
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Section < Item
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(parent, options = {}, &block)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    super(parent, nil, nil, options, &block)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def section?
         
     | 
| 
      
 11 
     | 
    
         
            +
                    true
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                private
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def complete_path_for(*)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/waiter/menu.rb
    CHANGED
    
    | 
         @@ -1,26 +1,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'waiter/dsl'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'waiter/menu/item_list'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'waiter/menu/item'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'waiter/menu/section'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'waiter/menu/drawer'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       1 
7 
     | 
    
         
             
            module Waiter
         
     | 
| 
       2 
8 
     | 
    
         
             
              class Menu
         
     | 
| 
       3 
     | 
    
         
            -
                attr_accessor :options, : 
     | 
| 
      
 9 
     | 
    
         
            +
                attr_accessor :name, :context, :options, :submenu, :parent
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                include DSL
         
     | 
| 
       4 
12 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
                 
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
                    obj
         
     | 
| 
      
 13 
     | 
    
         
            +
                def self.serve(name, context = nil, options = {}, &block)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  new(name, context, options).tap do |menu|
         
     | 
| 
      
 15 
     | 
    
         
            +
                    menu.update(&block)
         
     | 
| 
       9 
16 
     | 
    
         
             
                  end
         
     | 
| 
       10 
17 
     | 
    
         
             
                end
         
     | 
| 
       11 
18 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                def initialize(options = {})
         
     | 
| 
       13 
     | 
    
         
            -
                  @ 
     | 
| 
       14 
     | 
    
         
            -
                  @ 
     | 
| 
      
 19 
     | 
    
         
            +
                def initialize(name, context, options = {})
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @context = context
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @items = ItemList.new
         
     | 
| 
       15 
23 
     | 
    
         
             
                  @options = options
         
     | 
| 
       16 
24 
     | 
    
         
             
                end
         
     | 
| 
       17 
25 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                def  
     | 
| 
       19 
     | 
    
         
            -
                   
     | 
| 
      
 26 
     | 
    
         
            +
                def update(&block)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  instance_eval(&block)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def draw(context = nil)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  Drawer.new(self, context).draw
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def add(name, path = {}, options = {}, &block)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  items << Item.new(self, name, path, options, &block)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def add_section(options = {}, &block)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  section = Section.new(self, options, &block)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  items << section if section.items.any?
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def sections
         
     | 
| 
      
 44 
     | 
    
         
            +
                  items.select(&:section?) || []
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def [](name)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  items[name]
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def items(sorted = false)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  return @items unless sorted
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  items = @items.dup
         
     | 
| 
      
 55 
     | 
    
         
            +
                  items.sort_by!(&options[:sort].to_sym) if options.fetch(:sort, false)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  items.reverse! if options.fetch(:reverse, false)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  ItemList.new(items)
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                def top?
         
     | 
| 
      
 61 
     | 
    
         
            +
                  parent.nil?
         
     | 
| 
       20 
62 
     | 
    
         
             
                end
         
     | 
| 
       21 
63 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                def  
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
      
 64 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 65 
     | 
    
         
            +
                  "#<#{self.class.name}:#{'0x%x' % (36971870 << 1)} name=#{name.inspect} options=#{options.inspect}>"
         
     | 
| 
       24 
66 
     | 
    
         
             
                end
         
     | 
| 
       25 
67 
     | 
    
         
             
              end
         
     | 
| 
       26 
68 
     | 
    
         
             
            end
         
     | 
    
        data/lib/waiter/version.rb
    CHANGED