sunrise-widgets 0.1.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.
- data/Gemfile +34 -0
 - data/MIT-LICENSE +20 -0
 - data/README.rdoc +21 -0
 - data/Rakefile +27 -0
 - data/app/controllers/manage/widgets_controller.rb +33 -0
 - data/app/views/manage/widgets/_form.html.erb +21 -0
 - data/app/views/manage/widgets/_model_filter.html.erb +40 -0
 - data/app/views/manage/widgets/_widget.html.erb +41 -0
 - data/app/views/manage/widgets/edit.html.erb +6 -0
 - data/app/views/manage/widgets/index.html.erb +30 -0
 - data/app/views/manage/widgets/new.html.erb +6 -0
 - data/app/views/manage/widgets/show.html.erb +29 -0
 - data/config/locales/ru.yml +18 -0
 - data/config/locales/uk.yml +18 -0
 - data/config/routes.rb +5 -0
 - data/lib/generators/sunrise/widgets/USAGE +12 -0
 - data/lib/generators/sunrise/widgets/install_generator.rb +40 -0
 - data/lib/generators/sunrise/widgets/templates/create_widgets.rb +24 -0
 - data/lib/generators/sunrise/widgets/templates/widget.rb +6 -0
 - data/lib/generators/sunrise/widgets/templates/widget_position.rb +14 -0
 - data/lib/generators/sunrise/widgets/templates/widget_sweeper.rb +21 -0
 - data/lib/generators/sunrise/widgets/templates/widget_type.rb +15 -0
 - data/lib/sunrise/models/widget.rb +39 -0
 - data/lib/sunrise/widgets/engine.rb +18 -0
 - data/lib/sunrise/widgets/version.rb +5 -0
 - data/lib/sunrise/widgets.rb +12 -0
 - data/lib/sunrise-widgets.rb +1 -0
 - data/spec/controllers/manage/widgets_controller_spec.rb +95 -0
 - data/spec/dummy/Rakefile +7 -0
 - data/spec/dummy/app/controllers/application_controller.rb +3 -0
 - data/spec/dummy/app/helpers/application_helper.rb +2 -0
 - data/spec/dummy/app/helpers/manage/assets_helper.rb +2 -0
 - data/spec/dummy/app/helpers/manage/base_helper.rb +81 -0
 - data/spec/dummy/app/helpers/manage/pages_helper.rb +2 -0
 - data/spec/dummy/app/helpers/manage/settings_helper.rb +2 -0
 - data/spec/dummy/app/helpers/manage/structures_helper.rb +12 -0
 - data/spec/dummy/app/helpers/manage/users_helper.rb +6 -0
 - data/spec/dummy/app/models/defaults/ability.rb +39 -0
 - data/spec/dummy/app/models/defaults/asset.rb +7 -0
 - data/spec/dummy/app/models/defaults/attachment_file.rb +33 -0
 - data/spec/dummy/app/models/defaults/avatar.rb +37 -0
 - data/spec/dummy/app/models/defaults/header.rb +5 -0
 - data/spec/dummy/app/models/defaults/page.rb +5 -0
 - data/spec/dummy/app/models/defaults/picture.rb +35 -0
 - data/spec/dummy/app/models/defaults/position_type.rb +7 -0
 - data/spec/dummy/app/models/defaults/role.rb +20 -0
 - data/spec/dummy/app/models/defaults/role_type.rb +8 -0
 - data/spec/dummy/app/models/defaults/structure.rb +16 -0
 - data/spec/dummy/app/models/defaults/structure_type.rb +9 -0
 - data/spec/dummy/app/models/defaults/user.rb +47 -0
 - data/spec/dummy/app/views/layouts/application.html.erb +37 -0
 - data/spec/dummy/app/views/pages/show.html.erb +2 -0
 - data/spec/dummy/app/views/shared/_notice.html.erb +17 -0
 - data/spec/dummy/config/application.rb +47 -0
 - data/spec/dummy/config/application.yml.sample +4 -0
 - data/spec/dummy/config/boot.rb +10 -0
 - data/spec/dummy/config/database.yml +22 -0
 - data/spec/dummy/config/database.yml.sample +34 -0
 - data/spec/dummy/config/environment.rb +5 -0
 - data/spec/dummy/config/environments/development.rb +26 -0
 - data/spec/dummy/config/environments/production.rb +49 -0
 - data/spec/dummy/config/environments/test.rb +35 -0
 - data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
 - data/spec/dummy/config/initializers/devise.rb +204 -0
 - data/spec/dummy/config/initializers/inflections.rb +10 -0
 - data/spec/dummy/config/initializers/mime_types.rb +5 -0
 - data/spec/dummy/config/initializers/secret_token.rb +7 -0
 - data/spec/dummy/config/initializers/session_store.rb +8 -0
 - data/spec/dummy/config/initializers/simple_form.rb +93 -0
 - data/spec/dummy/config/initializers/sunrise.rb +7 -0
 - data/spec/dummy/config/locales/devise.en.yml +53 -0
 - data/spec/dummy/config/locales/en.yml +5 -0
 - data/spec/dummy/config/locales/simple_form.en.yml +24 -0
 - data/spec/dummy/config/logrotate-config.sample +9 -0
 - data/spec/dummy/config/nginx-config-passenger.sample +51 -0
 - data/spec/dummy/config/routes.rb +64 -0
 - data/spec/dummy/config.ru +4 -0
 - data/spec/dummy/db/migrate/20110801124809_sunrise_create_users.rb +29 -0
 - data/spec/dummy/db/migrate/20110801124909_sunrise_create_roles.rb +16 -0
 - data/spec/dummy/db/migrate/20110801125009_sunrise_create_structures.rb +27 -0
 - data/spec/dummy/db/migrate/20110801125109_sunrise_create_pages.rb +17 -0
 - data/spec/dummy/db/migrate/20110801125209_sunrise_create_assets.rb +28 -0
 - data/spec/dummy/db/migrate/20110801125309_sunrise_create_headers.rb +20 -0
 - data/spec/dummy/db/migrate/20110801161138_sunrise_create_widgets.rb +24 -0
 - data/spec/dummy/db/seeds.rb +25 -0
 - data/spec/dummy/db/test.sqlite3 +0 -0
 - data/spec/dummy/lib/templates/erb/scaffold/_form.html.erb +13 -0
 - data/spec/dummy/log/development.log +5 -0
 - data/spec/dummy/log/production.log +0 -0
 - data/spec/dummy/log/server.log +0 -0
 - data/spec/dummy/log/test.log +2324 -0
 - data/spec/dummy/public/404.html +26 -0
 - data/spec/dummy/public/422.html +26 -0
 - data/spec/dummy/public/500.html +26 -0
 - data/spec/dummy/public/favicon.ico +0 -0
 - data/spec/dummy/public/images/manage/add_post_bot.gif +0 -0
 - data/spec/dummy/public/images/manage/add_post_top.gif +0 -0
 - data/spec/dummy/public/images/manage/add_white_bot.gif +0 -0
 - data/spec/dummy/public/images/manage/add_white_top.gif +0 -0
 - data/spec/dummy/public/images/manage/arrow.png +0 -0
 - data/spec/dummy/public/images/manage/back_but_lc.gif +0 -0
 - data/spec/dummy/public/images/manage/back_but_rc.gif +0 -0
 - data/spec/dummy/public/images/manage/bot_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/bot_duo_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/but_bg.png +0 -0
 - data/spec/dummy/public/images/manage/but_block_lc.gif +0 -0
 - data/spec/dummy/public/images/manage/but_block_rc.gif +0 -0
 - data/spec/dummy/public/images/manage/but_freze_lc.gif +0 -0
 - data/spec/dummy/public/images/manage/but_freze_rc.gif +0 -0
 - data/spec/dummy/public/images/manage/but_gr.gif +0 -0
 - data/spec/dummy/public/images/manage/but_gr_l.gif +0 -0
 - data/spec/dummy/public/images/manage/but_gr_r.gif +0 -0
 - data/spec/dummy/public/images/manage/but_search.gif +0 -0
 - data/spec/dummy/public/images/manage/but_unfreze_lc.gif +0 -0
 - data/spec/dummy/public/images/manage/but_unfreze_rc.gif +0 -0
 - data/spec/dummy/public/images/manage/button_add_foto.gif +0 -0
 - data/spec/dummy/public/images/manage/button_add_foto_ru.gif +0 -0
 - data/spec/dummy/public/images/manage/button_add_foto_ua.gif +0 -0
 - data/spec/dummy/public/images/manage/button_add_foto_uk.gif +0 -0
 - data/spec/dummy/public/images/manage/cancelbutton.gif +0 -0
 - data/spec/dummy/public/images/manage/dark_arr.gif +0 -0
 - data/spec/dummy/public/images/manage/dark_arr_left.gif +0 -0
 - data/spec/dummy/public/images/manage/dark_cross_ico.gif +0 -0
 - data/spec/dummy/public/images/manage/dot.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bg.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bg_small.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bg_small_blocked.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bg_small_frozed.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bg_small_notact.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bot_small.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bot_small_blocked.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bot_small_frozed.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_bot_small_notact.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_top_small.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_top_small_blocked.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_top_small_frozed.gif +0 -0
 - data/spec/dummy/public/images/manage/duo_top_small_notact.gif +0 -0
 - data/spec/dummy/public/images/manage/edit_white_top.gif +0 -0
 - data/spec/dummy/public/images/manage/empty.gif +0 -0
 - data/spec/dummy/public/images/manage/filter_bot_bg.gif +0 -0
 - data/spec/dummy/public/images/manage/filter_top_bg.gif +0 -0
 - data/spec/dummy/public/images/manage/flag_en.gif +0 -0
 - data/spec/dummy/public/images/manage/flag_en_nonact.gif +0 -0
 - data/spec/dummy/public/images/manage/flag_ru.gif +0 -0
 - data/spec/dummy/public/images/manage/flag_ru_nonact.gif +0 -0
 - data/spec/dummy/public/images/manage/flag_ua.gif +0 -0
 - data/spec/dummy/public/images/manage/flag_ua_nonact.gif +0 -0
 - data/spec/dummy/public/images/manage/foto.jpg +0 -0
 - data/spec/dummy/public/images/manage/ico_add.gif +0 -0
 - data/spec/dummy/public/images/manage/ico_del.gif +0 -0
 - data/spec/dummy/public/images/manage/ico_down.gif +0 -0
 - data/spec/dummy/public/images/manage/ico_edit.gif +0 -0
 - data/spec/dummy/public/images/manage/ico_settings.gif +0 -0
 - data/spec/dummy/public/images/manage/ico_up.gif +0 -0
 - data/spec/dummy/public/images/manage/input_bg.gif +0 -0
 - data/spec/dummy/public/images/manage/l_but_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/minimise_but.gif +0 -0
 - data/spec/dummy/public/images/manage/mp3.png +0 -0
 - data/spec/dummy/public/images/manage/page_arr_hover.png +0 -0
 - data/spec/dummy/public/images/manage/page_next_arr.gif +0 -0
 - data/spec/dummy/public/images/manage/page_num_hover.gif +0 -0
 - data/spec/dummy/public/images/manage/page_prev_arr.gif +0 -0
 - data/spec/dummy/public/images/manage/panel/l_but_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/panel/maximise_but.gif +0 -0
 - data/spec/dummy/public/images/manage/panel/r_but_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/panel/top_menu_arr.gif +0 -0
 - data/spec/dummy/public/images/manage/panel/user_pic.gif +0 -0
 - data/spec/dummy/public/images/manage/preloader.gif +0 -0
 - data/spec/dummy/public/images/manage/r_but_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/select_bg.gif +0 -0
 - data/spec/dummy/public/images/manage/select_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/struct_corn_lg.gif +0 -0
 - data/spec/dummy/public/images/manage/struct_corn_llg.gif +0 -0
 - data/spec/dummy/public/images/manage/struct_corn_lw.gif +0 -0
 - data/spec/dummy/public/images/manage/struct_corn_rg.gif +0 -0
 - data/spec/dummy/public/images/manage/struct_corn_rlg.gif +0 -0
 - data/spec/dummy/public/images/manage/struct_corn_rw.gif +0 -0
 - data/spec/dummy/public/images/manage/tab_gl.gif +0 -0
 - data/spec/dummy/public/images/manage/tab_gr.gif +0 -0
 - data/spec/dummy/public/images/manage/tab_wl.gif +0 -0
 - data/spec/dummy/public/images/manage/tab_wr.gif +0 -0
 - data/spec/dummy/public/images/manage/top_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/top_duo_corn.gif +0 -0
 - data/spec/dummy/public/images/manage/top_menu_arr.gif +0 -0
 - data/spec/dummy/public/images/manage/transp_cross.png +0 -0
 - data/spec/dummy/public/images/manage/upload_progress.gif +0 -0
 - data/spec/dummy/public/images/manage/user_act_lc.gif +0 -0
 - data/spec/dummy/public/images/manage/user_act_rc.gif +0 -0
 - data/spec/dummy/public/images/manage/user_ico.gif +0 -0
 - data/spec/dummy/public/images/manage/user_pic.gif +0 -0
 - data/spec/dummy/public/images/manage/user_pic_small.gif +0 -0
 - data/spec/dummy/public/images/manage/user_pic_thumb.gif +0 -0
 - data/spec/dummy/public/javascripts/application.js +2 -0
 - data/spec/dummy/public/javascripts/controls.js +965 -0
 - data/spec/dummy/public/javascripts/datepicker/jquery-ui-i18n.js +1176 -0
 - data/spec/dummy/public/javascripts/datepicker/jquery.ui.datepicker-ru.js +37 -0
 - data/spec/dummy/public/javascripts/datepicker/jquery.ui.datepicker-uk.js +37 -0
 - data/spec/dummy/public/javascripts/dragdrop.js +974 -0
 - data/spec/dummy/public/javascripts/effects.js +1123 -0
 - data/spec/dummy/public/javascripts/fileupload/fileuploader-input.js +217 -0
 - data/spec/dummy/public/javascripts/fileupload/fileuploader.css +31 -0
 - data/spec/dummy/public/javascripts/fileupload/fileuploader.js +1288 -0
 - data/spec/dummy/public/javascripts/jquery-ui-timepicker-addon.js +911 -0
 - data/spec/dummy/public/javascripts/jquery.cookie.js +97 -0
 - data/spec/dummy/public/javascripts/jquery.fancybox-1.3.4.pack.js +46 -0
 - data/spec/dummy/public/javascripts/jquery.tmpl.min.js +10 -0
 - data/spec/dummy/public/javascripts/manage-fileuploader.js +182 -0
 - data/spec/dummy/public/javascripts/manage.js +294 -0
 - data/spec/dummy/public/javascripts/preloader.js +47 -0
 - data/spec/dummy/public/javascripts/prototype.js +6001 -0
 - data/spec/dummy/public/javascripts/rails.js +331 -0
 - data/spec/dummy/public/stylesheets/application.css +1 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/blank.gif +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_close.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_loading.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_nav_left.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_nav_right.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_e.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_n.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_ne.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_nw.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_s.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_se.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_sw.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_shadow_w.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_title_left.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_title_main.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_title_over.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancy_title_right.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancybox-x.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancybox-y.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/images/fancybox.png +0 -0
 - data/spec/dummy/public/stylesheets/fancybox/jquery.fancybox-1.3.4.css +359 -0
 - data/spec/dummy/public/stylesheets/manage/buttons.css +42 -0
 - data/spec/dummy/public/stylesheets/manage/ie.css +16 -0
 - data/spec/dummy/public/stylesheets/manage/main.css +1108 -0
 - data/spec/dummy/public/stylesheets/manage/panel.css +126 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-icons_222222_256x240.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-icons_454545_256x240.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-icons_888888_256x240.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
 - data/spec/dummy/public/stylesheets/smoothness/jquery-ui-1.8.13.custom.css +578 -0
 - data/spec/dummy/script/rails +6 -0
 - data/spec/factories/structure_factory.rb +22 -0
 - data/spec/factories/user_factory.rb +48 -0
 - data/spec/factories/widget_factory.rb +12 -0
 - data/spec/generators/install_generator_spec.rb +27 -0
 - data/spec/integration/navigation_spec.rb +9 -0
 - data/spec/models/widget_spec.rb +30 -0
 - data/spec/spec.opts +2 -0
 - data/spec/spec_helper.rb +57 -0
 - data/spec/sunrise_widgets_spec.rb +7 -0
 - data/spec/support/helpers/controller_macros.rb +40 -0
 - data/spec/tmp/app/models/widget.rb +6 -0
 - data/spec/tmp/app/models/widget_position.rb +14 -0
 - data/spec/tmp/app/models/widget_type.rb +15 -0
 - data/spec/tmp/app/sweepers/widget_sweeper.rb +21 -0
 - data/spec/tmp/db/migrate/20110818113026_sunrise_create_widgets.rb +24 -0
 - metadata +587 -0
 
| 
         @@ -0,0 +1,1288 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /**
         
     | 
| 
      
 2 
     | 
    
         
            +
             * http://github.com/valums/file-uploader
         
     | 
| 
      
 3 
     | 
    
         
            +
             * 
         
     | 
| 
      
 4 
     | 
    
         
            +
             * Multiple file upload component with progress-bar, drag-and-drop. 
         
     | 
| 
      
 5 
     | 
    
         
            +
             * © 2010 Andrew Valums ( andrew(at)valums.com ) 
         
     | 
| 
      
 6 
     | 
    
         
            +
             * 
         
     | 
| 
      
 7 
     | 
    
         
            +
             * Licensed under GNU GPL 2 or later, see license.txt.
         
     | 
| 
      
 8 
     | 
    
         
            +
             */    
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            //
         
     | 
| 
      
 11 
     | 
    
         
            +
            // Helper functions
         
     | 
| 
      
 12 
     | 
    
         
            +
            //
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            var qq = qq || {};
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            /**
         
     | 
| 
      
 17 
     | 
    
         
            +
             * Adds all missing properties from second obj to first obj
         
     | 
| 
      
 18 
     | 
    
         
            +
             */ 
         
     | 
| 
      
 19 
     | 
    
         
            +
            qq.extend = function(first, second){
         
     | 
| 
      
 20 
     | 
    
         
            +
                for (var prop in second){
         
     | 
| 
      
 21 
     | 
    
         
            +
                    first[prop] = second[prop];
         
     | 
| 
      
 22 
     | 
    
         
            +
                }
         
     | 
| 
      
 23 
     | 
    
         
            +
            };  
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            /**
         
     | 
| 
      
 26 
     | 
    
         
            +
             * Searches for a given element in the array, returns -1 if it is not present.
         
     | 
| 
      
 27 
     | 
    
         
            +
             * @param {Number} [from] The index at which to begin the search
         
     | 
| 
      
 28 
     | 
    
         
            +
             */
         
     | 
| 
      
 29 
     | 
    
         
            +
            qq.indexOf = function(arr, elt, from){
         
     | 
| 
      
 30 
     | 
    
         
            +
                if (arr.indexOf) return arr.indexOf(elt, from);
         
     | 
| 
      
 31 
     | 
    
         
            +
                
         
     | 
| 
      
 32 
     | 
    
         
            +
                from = from || 0;
         
     | 
| 
      
 33 
     | 
    
         
            +
                var len = arr.length;    
         
     | 
| 
      
 34 
     | 
    
         
            +
                
         
     | 
| 
      
 35 
     | 
    
         
            +
                if (from < 0) from += len;  
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                for (; from < len; from++){  
         
     | 
| 
      
 38 
     | 
    
         
            +
                    if (from in arr && arr[from] === elt){  
         
     | 
| 
      
 39 
     | 
    
         
            +
                        return from;
         
     | 
| 
      
 40 
     | 
    
         
            +
                    }
         
     | 
| 
      
 41 
     | 
    
         
            +
                }  
         
     | 
| 
      
 42 
     | 
    
         
            +
                return -1;  
         
     | 
| 
      
 43 
     | 
    
         
            +
            }; 
         
     | 
| 
      
 44 
     | 
    
         
            +
                
         
     | 
| 
      
 45 
     | 
    
         
            +
            qq.getUniqueId = (function(){
         
     | 
| 
      
 46 
     | 
    
         
            +
                var id = 0;
         
     | 
| 
      
 47 
     | 
    
         
            +
                return function(){ return id++; };
         
     | 
| 
      
 48 
     | 
    
         
            +
            })();
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            //
         
     | 
| 
      
 51 
     | 
    
         
            +
            // Events
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            qq.attach = function(element, type, fn){
         
     | 
| 
      
 54 
     | 
    
         
            +
                if (element.addEventListener){
         
     | 
| 
      
 55 
     | 
    
         
            +
                    element.addEventListener(type, fn, false);
         
     | 
| 
      
 56 
     | 
    
         
            +
                } else if (element.attachEvent){
         
     | 
| 
      
 57 
     | 
    
         
            +
                    element.attachEvent('on' + type, fn);
         
     | 
| 
      
 58 
     | 
    
         
            +
                }
         
     | 
| 
      
 59 
     | 
    
         
            +
            };
         
     | 
| 
      
 60 
     | 
    
         
            +
            qq.detach = function(element, type, fn){
         
     | 
| 
      
 61 
     | 
    
         
            +
                if (element.removeEventListener){
         
     | 
| 
      
 62 
     | 
    
         
            +
                    element.removeEventListener(type, fn, false);
         
     | 
| 
      
 63 
     | 
    
         
            +
                } else if (element.attachEvent){
         
     | 
| 
      
 64 
     | 
    
         
            +
                    element.detachEvent('on' + type, fn);
         
     | 
| 
      
 65 
     | 
    
         
            +
                }
         
     | 
| 
      
 66 
     | 
    
         
            +
            };
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            qq.preventDefault = function(e){
         
     | 
| 
      
 69 
     | 
    
         
            +
                if (e.preventDefault){
         
     | 
| 
      
 70 
     | 
    
         
            +
                    e.preventDefault();
         
     | 
| 
      
 71 
     | 
    
         
            +
                } else{
         
     | 
| 
      
 72 
     | 
    
         
            +
                    e.returnValue = false;
         
     | 
| 
      
 73 
     | 
    
         
            +
                }
         
     | 
| 
      
 74 
     | 
    
         
            +
            };
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            //
         
     | 
| 
      
 77 
     | 
    
         
            +
            // Node manipulations
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            /**
         
     | 
| 
      
 80 
     | 
    
         
            +
             * Insert node a before node b.
         
     | 
| 
      
 81 
     | 
    
         
            +
             */
         
     | 
| 
      
 82 
     | 
    
         
            +
            qq.insertBefore = function(a, b){
         
     | 
| 
      
 83 
     | 
    
         
            +
                b.parentNode.insertBefore(a, b);
         
     | 
| 
      
 84 
     | 
    
         
            +
            };
         
     | 
| 
      
 85 
     | 
    
         
            +
            qq.remove = function(element){
         
     | 
| 
      
 86 
     | 
    
         
            +
                element.parentNode.removeChild(element);
         
     | 
| 
      
 87 
     | 
    
         
            +
            };
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            qq.contains = function(parent, descendant){       
         
     | 
| 
      
 90 
     | 
    
         
            +
                // compareposition returns false in this case
         
     | 
| 
      
 91 
     | 
    
         
            +
                if (parent == descendant) return true;
         
     | 
| 
      
 92 
     | 
    
         
            +
                
         
     | 
| 
      
 93 
     | 
    
         
            +
                if (parent.contains){
         
     | 
| 
      
 94 
     | 
    
         
            +
                    return parent.contains(descendant);
         
     | 
| 
      
 95 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 96 
     | 
    
         
            +
                    return !!(descendant.compareDocumentPosition(parent) & 8);
         
     | 
| 
      
 97 
     | 
    
         
            +
                }
         
     | 
| 
      
 98 
     | 
    
         
            +
            };
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            /**
         
     | 
| 
      
 101 
     | 
    
         
            +
             * Creates and returns element from html string
         
     | 
| 
      
 102 
     | 
    
         
            +
             * Uses innerHTML to create an element
         
     | 
| 
      
 103 
     | 
    
         
            +
             */
         
     | 
| 
      
 104 
     | 
    
         
            +
            qq.toElement = (function(){
         
     | 
| 
      
 105 
     | 
    
         
            +
                var div = document.createElement('div');
         
     | 
| 
      
 106 
     | 
    
         
            +
                return function(html){
         
     | 
| 
      
 107 
     | 
    
         
            +
                    div.innerHTML = html;
         
     | 
| 
      
 108 
     | 
    
         
            +
                    var element = div.firstChild;
         
     | 
| 
      
 109 
     | 
    
         
            +
                    div.removeChild(element);
         
     | 
| 
      
 110 
     | 
    
         
            +
                    return element;
         
     | 
| 
      
 111 
     | 
    
         
            +
                };
         
     | 
| 
      
 112 
     | 
    
         
            +
            })();
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            //
         
     | 
| 
      
 115 
     | 
    
         
            +
            // Node properties and attributes
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            /**
         
     | 
| 
      
 118 
     | 
    
         
            +
             * Sets styles for an element.
         
     | 
| 
      
 119 
     | 
    
         
            +
             * Fixes opacity in IE6-8.
         
     | 
| 
      
 120 
     | 
    
         
            +
             */
         
     | 
| 
      
 121 
     | 
    
         
            +
            qq.css = function(element, styles){
         
     | 
| 
      
 122 
     | 
    
         
            +
                if (styles.opacity != null){
         
     | 
| 
      
 123 
     | 
    
         
            +
                    if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
         
     | 
| 
      
 124 
     | 
    
         
            +
                        styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
         
     | 
| 
      
 125 
     | 
    
         
            +
                    }
         
     | 
| 
      
 126 
     | 
    
         
            +
                }
         
     | 
| 
      
 127 
     | 
    
         
            +
                qq.extend(element.style, styles);
         
     | 
| 
      
 128 
     | 
    
         
            +
            };
         
     | 
| 
      
 129 
     | 
    
         
            +
            qq.hasClass = function(element, name){
         
     | 
| 
      
 130 
     | 
    
         
            +
                var re = new RegExp('(^| )' + name + '( |$)');
         
     | 
| 
      
 131 
     | 
    
         
            +
                return re.test(element.className);
         
     | 
| 
      
 132 
     | 
    
         
            +
            };
         
     | 
| 
      
 133 
     | 
    
         
            +
            qq.addClass = function(element, name){
         
     | 
| 
      
 134 
     | 
    
         
            +
                if (!qq.hasClass(element, name)){
         
     | 
| 
      
 135 
     | 
    
         
            +
                    element.className += ' ' + name;
         
     | 
| 
      
 136 
     | 
    
         
            +
                }
         
     | 
| 
      
 137 
     | 
    
         
            +
            };
         
     | 
| 
      
 138 
     | 
    
         
            +
            qq.removeClass = function(element, name){
         
     | 
| 
      
 139 
     | 
    
         
            +
                var re = new RegExp('(^| )' + name + '( |$)');
         
     | 
| 
      
 140 
     | 
    
         
            +
                element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
         
     | 
| 
      
 141 
     | 
    
         
            +
            };
         
     | 
| 
      
 142 
     | 
    
         
            +
            qq.setText = function(element, text){
         
     | 
| 
      
 143 
     | 
    
         
            +
                element.innerText = text;
         
     | 
| 
      
 144 
     | 
    
         
            +
                element.textContent = text;
         
     | 
| 
      
 145 
     | 
    
         
            +
            };
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
            //
         
     | 
| 
      
 148 
     | 
    
         
            +
            // Selecting elements
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            qq.children = function(element){
         
     | 
| 
      
 151 
     | 
    
         
            +
                var children = [],
         
     | 
| 
      
 152 
     | 
    
         
            +
                child = element.firstChild;
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                while (child){
         
     | 
| 
      
 155 
     | 
    
         
            +
                    if (child.nodeType == 1){
         
     | 
| 
      
 156 
     | 
    
         
            +
                        children.push(child);
         
     | 
| 
      
 157 
     | 
    
         
            +
                    }
         
     | 
| 
      
 158 
     | 
    
         
            +
                    child = child.nextSibling;
         
     | 
| 
      
 159 
     | 
    
         
            +
                }
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                return children;
         
     | 
| 
      
 162 
     | 
    
         
            +
            };
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            qq.getByClass = function(element, className){
         
     | 
| 
      
 165 
     | 
    
         
            +
                if (element.querySelectorAll){
         
     | 
| 
      
 166 
     | 
    
         
            +
                    return element.querySelectorAll('.' + className);
         
     | 
| 
      
 167 
     | 
    
         
            +
                }
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                var result = [];
         
     | 
| 
      
 170 
     | 
    
         
            +
                var candidates = element.getElementsByTagName("*");
         
     | 
| 
      
 171 
     | 
    
         
            +
                var len = candidates.length;
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                for (var i = 0; i < len; i++){
         
     | 
| 
      
 174 
     | 
    
         
            +
                    if (qq.hasClass(candidates[i], className)){
         
     | 
| 
      
 175 
     | 
    
         
            +
                        result.push(candidates[i]);
         
     | 
| 
      
 176 
     | 
    
         
            +
                    }
         
     | 
| 
      
 177 
     | 
    
         
            +
                }
         
     | 
| 
      
 178 
     | 
    
         
            +
                return result;
         
     | 
| 
      
 179 
     | 
    
         
            +
            };
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            /**
         
     | 
| 
      
 182 
     | 
    
         
            +
             * obj2url() takes a json-object as argument and generates
         
     | 
| 
      
 183 
     | 
    
         
            +
             * a querystring. pretty much like jQuery.param()
         
     | 
| 
      
 184 
     | 
    
         
            +
             * 
         
     | 
| 
      
 185 
     | 
    
         
            +
             * how to use:
         
     | 
| 
      
 186 
     | 
    
         
            +
             *
         
     | 
| 
      
 187 
     | 
    
         
            +
             *    `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
         
     | 
| 
      
 188 
     | 
    
         
            +
             *
         
     | 
| 
      
 189 
     | 
    
         
            +
             * will result in:
         
     | 
| 
      
 190 
     | 
    
         
            +
             *
         
     | 
| 
      
 191 
     | 
    
         
            +
             *    `http://any.url/upload?otherParam=value&a=b&c=d`
         
     | 
| 
      
 192 
     | 
    
         
            +
             *
         
     | 
| 
      
 193 
     | 
    
         
            +
             * @param  Object JSON-Object
         
     | 
| 
      
 194 
     | 
    
         
            +
             * @param  String current querystring-part
         
     | 
| 
      
 195 
     | 
    
         
            +
             * @return String encoded querystring
         
     | 
| 
      
 196 
     | 
    
         
            +
             */
         
     | 
| 
      
 197 
     | 
    
         
            +
            qq.obj2url = function(obj, temp, prefixDone){
         
     | 
| 
      
 198 
     | 
    
         
            +
                var uristrings = [],
         
     | 
| 
      
 199 
     | 
    
         
            +
                    prefix = '&',
         
     | 
| 
      
 200 
     | 
    
         
            +
                    add = function(nextObj, i){
         
     | 
| 
      
 201 
     | 
    
         
            +
                        var nextTemp = temp 
         
     | 
| 
      
 202 
     | 
    
         
            +
                            ? (/\[\]$/.test(temp)) // prevent double-encoding
         
     | 
| 
      
 203 
     | 
    
         
            +
                               ? temp
         
     | 
| 
      
 204 
     | 
    
         
            +
                               : temp+'['+i+']'
         
     | 
| 
      
 205 
     | 
    
         
            +
                            : i;
         
     | 
| 
      
 206 
     | 
    
         
            +
                        if ((nextTemp != 'undefined') && (i != 'undefined')) {  
         
     | 
| 
      
 207 
     | 
    
         
            +
                            uristrings.push(
         
     | 
| 
      
 208 
     | 
    
         
            +
                                (typeof nextObj === 'object') 
         
     | 
| 
      
 209 
     | 
    
         
            +
                                    ? qq.obj2url(nextObj, nextTemp, true)
         
     | 
| 
      
 210 
     | 
    
         
            +
                                    : (Object.prototype.toString.call(nextObj) === '[object Function]')
         
     | 
| 
      
 211 
     | 
    
         
            +
                                        ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
         
     | 
| 
      
 212 
     | 
    
         
            +
                                        : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)                                                          
         
     | 
| 
      
 213 
     | 
    
         
            +
                            );
         
     | 
| 
      
 214 
     | 
    
         
            +
                        }
         
     | 
| 
      
 215 
     | 
    
         
            +
                    }; 
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                if (!prefixDone && temp) {
         
     | 
| 
      
 218 
     | 
    
         
            +
                  prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
         
     | 
| 
      
 219 
     | 
    
         
            +
                  uristrings.push(temp);
         
     | 
| 
      
 220 
     | 
    
         
            +
                  uristrings.push(qq.obj2url(obj));
         
     | 
| 
      
 221 
     | 
    
         
            +
                } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) {
         
     | 
| 
      
 222 
     | 
    
         
            +
                    // we wont use a for-in-loop on an array (performance)
         
     | 
| 
      
 223 
     | 
    
         
            +
                    for (var i = 0, len = obj.length; i < len; ++i){
         
     | 
| 
      
 224 
     | 
    
         
            +
                        add(obj[i], i);
         
     | 
| 
      
 225 
     | 
    
         
            +
                    }
         
     | 
| 
      
 226 
     | 
    
         
            +
                } else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){
         
     | 
| 
      
 227 
     | 
    
         
            +
                    // for anything else but a scalar, we will use for-in-loop
         
     | 
| 
      
 228 
     | 
    
         
            +
                    for (var i in obj){
         
     | 
| 
      
 229 
     | 
    
         
            +
                        add(obj[i], i);
         
     | 
| 
      
 230 
     | 
    
         
            +
                    }
         
     | 
| 
      
 231 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 232 
     | 
    
         
            +
                    uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
         
     | 
| 
      
 233 
     | 
    
         
            +
                }
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                return uristrings.join(prefix)
         
     | 
| 
      
 236 
     | 
    
         
            +
                                 .replace(/^&/, '')
         
     | 
| 
      
 237 
     | 
    
         
            +
                                 .replace(/%20/g, '+'); 
         
     | 
| 
      
 238 
     | 
    
         
            +
            };
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
            //
         
     | 
| 
      
 241 
     | 
    
         
            +
            //
         
     | 
| 
      
 242 
     | 
    
         
            +
            // Uploader Classes
         
     | 
| 
      
 243 
     | 
    
         
            +
            //
         
     | 
| 
      
 244 
     | 
    
         
            +
            //
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
            var qq = qq || {};
         
     | 
| 
      
 247 
     | 
    
         
            +
                
         
     | 
| 
      
 248 
     | 
    
         
            +
            /**
         
     | 
| 
      
 249 
     | 
    
         
            +
             * Creates upload button, validates upload, but doesn't create file list or dd. 
         
     | 
| 
      
 250 
     | 
    
         
            +
             */
         
     | 
| 
      
 251 
     | 
    
         
            +
            qq.FileUploaderBasic = function(o){
         
     | 
| 
      
 252 
     | 
    
         
            +
                this._options = {
         
     | 
| 
      
 253 
     | 
    
         
            +
                    // set to true to see the server response
         
     | 
| 
      
 254 
     | 
    
         
            +
                    debug: false,
         
     | 
| 
      
 255 
     | 
    
         
            +
                    action: '/server/upload',
         
     | 
| 
      
 256 
     | 
    
         
            +
                    params: {},
         
     | 
| 
      
 257 
     | 
    
         
            +
                    button: null,
         
     | 
| 
      
 258 
     | 
    
         
            +
                    multiple: true,
         
     | 
| 
      
 259 
     | 
    
         
            +
                    maxConnections: 3,
         
     | 
| 
      
 260 
     | 
    
         
            +
                    method: 'POST',
         
     | 
| 
      
 261 
     | 
    
         
            +
                    fieldName: 'qqfile',
         
     | 
| 
      
 262 
     | 
    
         
            +
                    // validation        
         
     | 
| 
      
 263 
     | 
    
         
            +
                    allowedExtensions: [],               
         
     | 
| 
      
 264 
     | 
    
         
            +
                    sizeLimit: 0,   
         
     | 
| 
      
 265 
     | 
    
         
            +
                    minSizeLimit: 0,
         
     | 
| 
      
 266 
     | 
    
         
            +
                    maxFilesCount: 0, // 0 - no limit, works only in multiple mode
         
     | 
| 
      
 267 
     | 
    
         
            +
                    minFilesCount: 0, // 0 - no limit, works only in multiple mode
         
     | 
| 
      
 268 
     | 
    
         
            +
                    // events
         
     | 
| 
      
 269 
     | 
    
         
            +
                    // return false to cancel submit
         
     | 
| 
      
 270 
     | 
    
         
            +
                    onSubmit: function(id, fileName){},
         
     | 
| 
      
 271 
     | 
    
         
            +
                    onProgress: function(id, fileName, loaded, total){},
         
     | 
| 
      
 272 
     | 
    
         
            +
                    onComplete: function(id, fileName, responseJSON){},
         
     | 
| 
      
 273 
     | 
    
         
            +
                    onCancel: function(id, fileName){},
         
     | 
| 
      
 274 
     | 
    
         
            +
                    // messages                
         
     | 
| 
      
 275 
     | 
    
         
            +
                    messages: {
         
     | 
| 
      
 276 
     | 
    
         
            +
                        typeError: "{file} has invalid extension. Only {extensions} are allowed.",
         
     | 
| 
      
 277 
     | 
    
         
            +
                        sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
         
     | 
| 
      
 278 
     | 
    
         
            +
                        minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
         
     | 
| 
      
 279 
     | 
    
         
            +
                        emptyError: "{file} is empty, please select files again without it.",
         
     | 
| 
      
 280 
     | 
    
         
            +
                        onLeave: "The files are being uploaded, if you leave now the upload will be cancelled.",
         
     | 
| 
      
 281 
     | 
    
         
            +
                        maxFilesError: "You must select less then {maxFilesCount} files.",
         
     | 
| 
      
 282 
     | 
    
         
            +
                        minFilesError: "You must select more then {minFilesCount} files."
         
     | 
| 
      
 283 
     | 
    
         
            +
                    },
         
     | 
| 
      
 284 
     | 
    
         
            +
                    showMessage: function(message){
         
     | 
| 
      
 285 
     | 
    
         
            +
                        alert(message);
         
     | 
| 
      
 286 
     | 
    
         
            +
                    }               
         
     | 
| 
      
 287 
     | 
    
         
            +
                };
         
     | 
| 
      
 288 
     | 
    
         
            +
                qq.extend(this._options, o);
         
     | 
| 
      
 289 
     | 
    
         
            +
                    
         
     | 
| 
      
 290 
     | 
    
         
            +
                // number of files being uploaded
         
     | 
| 
      
 291 
     | 
    
         
            +
                this._filesInProgress = 0;
         
     | 
| 
      
 292 
     | 
    
         
            +
                // number of files was processed
         
     | 
| 
      
 293 
     | 
    
         
            +
                this._filesUploaded = 0;
         
     | 
| 
      
 294 
     | 
    
         
            +
                this._handler = this._createUploadHandler(); 
         
     | 
| 
      
 295 
     | 
    
         
            +
                
         
     | 
| 
      
 296 
     | 
    
         
            +
                if (this._options.button){ 
         
     | 
| 
      
 297 
     | 
    
         
            +
                    this._button = this._createUploadButton(this._options.button);
         
     | 
| 
      
 298 
     | 
    
         
            +
                }
         
     | 
| 
      
 299 
     | 
    
         
            +
                                    
         
     | 
| 
      
 300 
     | 
    
         
            +
                this._preventLeaveInProgress();         
         
     | 
| 
      
 301 
     | 
    
         
            +
            };
         
     | 
| 
      
 302 
     | 
    
         
            +
               
         
     | 
| 
      
 303 
     | 
    
         
            +
            qq.FileUploaderBasic.prototype = {
         
     | 
| 
      
 304 
     | 
    
         
            +
                setParams: function(params){
         
     | 
| 
      
 305 
     | 
    
         
            +
                    this._options.params = params;
         
     | 
| 
      
 306 
     | 
    
         
            +
                },
         
     | 
| 
      
 307 
     | 
    
         
            +
                getInProgress: function(){
         
     | 
| 
      
 308 
     | 
    
         
            +
                    return this._filesInProgress;         
         
     | 
| 
      
 309 
     | 
    
         
            +
                },
         
     | 
| 
      
 310 
     | 
    
         
            +
                _createUploadButton: function(element){
         
     | 
| 
      
 311 
     | 
    
         
            +
                    var self = this;
         
     | 
| 
      
 312 
     | 
    
         
            +
                    
         
     | 
| 
      
 313 
     | 
    
         
            +
                    return new qq.UploadButton({
         
     | 
| 
      
 314 
     | 
    
         
            +
                        element: element,
         
     | 
| 
      
 315 
     | 
    
         
            +
                        multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
         
     | 
| 
      
 316 
     | 
    
         
            +
                        onChange: function(input){
         
     | 
| 
      
 317 
     | 
    
         
            +
                            self._onInputChange(input);
         
     | 
| 
      
 318 
     | 
    
         
            +
                        }        
         
     | 
| 
      
 319 
     | 
    
         
            +
                    });           
         
     | 
| 
      
 320 
     | 
    
         
            +
                },    
         
     | 
| 
      
 321 
     | 
    
         
            +
                _createUploadHandler: function(){
         
     | 
| 
      
 322 
     | 
    
         
            +
                    var self = this,
         
     | 
| 
      
 323 
     | 
    
         
            +
                        handlerClass;        
         
     | 
| 
      
 324 
     | 
    
         
            +
                    
         
     | 
| 
      
 325 
     | 
    
         
            +
                    if(qq.UploadHandlerXhr.isSupported()){           
         
     | 
| 
      
 326 
     | 
    
         
            +
                        handlerClass = 'UploadHandlerXhr';                        
         
     | 
| 
      
 327 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 328 
     | 
    
         
            +
                        handlerClass = 'UploadHandlerForm';
         
     | 
| 
      
 329 
     | 
    
         
            +
                    }
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
      
 331 
     | 
    
         
            +
                    var handler = new qq[handlerClass]({
         
     | 
| 
      
 332 
     | 
    
         
            +
                        debug: this._options.debug,
         
     | 
| 
      
 333 
     | 
    
         
            +
                        action: this._options.action,         
         
     | 
| 
      
 334 
     | 
    
         
            +
                        maxConnections: this._options.maxConnections,
         
     | 
| 
      
 335 
     | 
    
         
            +
                        fieldName: this._options.fieldName,
         
     | 
| 
      
 336 
     | 
    
         
            +
                        method: this._options.method,   
         
     | 
| 
      
 337 
     | 
    
         
            +
                        onProgress: function(id, fileName, loaded, total){                
         
     | 
| 
      
 338 
     | 
    
         
            +
                            self._onProgress(id, fileName, loaded, total);
         
     | 
| 
      
 339 
     | 
    
         
            +
                            self._options.onProgress(id, fileName, loaded, total);                    
         
     | 
| 
      
 340 
     | 
    
         
            +
                        },            
         
     | 
| 
      
 341 
     | 
    
         
            +
                        onComplete: function(id, fileName, result){
         
     | 
| 
      
 342 
     | 
    
         
            +
                            self._onComplete(id, fileName, result);
         
     | 
| 
      
 343 
     | 
    
         
            +
                            self._options.onComplete(id, fileName, result);
         
     | 
| 
      
 344 
     | 
    
         
            +
                        },
         
     | 
| 
      
 345 
     | 
    
         
            +
                        onCancel: function(id, fileName){
         
     | 
| 
      
 346 
     | 
    
         
            +
                            self._onCancel(id, fileName);
         
     | 
| 
      
 347 
     | 
    
         
            +
                            self._options.onCancel(id, fileName);
         
     | 
| 
      
 348 
     | 
    
         
            +
                        }
         
     | 
| 
      
 349 
     | 
    
         
            +
                    });
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
                    return handler;
         
     | 
| 
      
 352 
     | 
    
         
            +
                },    
         
     | 
| 
      
 353 
     | 
    
         
            +
                _preventLeaveInProgress: function(){
         
     | 
| 
      
 354 
     | 
    
         
            +
                    var self = this;
         
     | 
| 
      
 355 
     | 
    
         
            +
                    
         
     | 
| 
      
 356 
     | 
    
         
            +
                    qq.attach(window, 'beforeunload', function(e){
         
     | 
| 
      
 357 
     | 
    
         
            +
                        if (!self._filesInProgress){return;}
         
     | 
| 
      
 358 
     | 
    
         
            +
                        
         
     | 
| 
      
 359 
     | 
    
         
            +
                        var e = e || window.event;
         
     | 
| 
      
 360 
     | 
    
         
            +
                        // for ie, ff
         
     | 
| 
      
 361 
     | 
    
         
            +
                        e.returnValue = self._options.messages.onLeave;
         
     | 
| 
      
 362 
     | 
    
         
            +
                        // for webkit
         
     | 
| 
      
 363 
     | 
    
         
            +
                        return self._options.messages.onLeave;             
         
     | 
| 
      
 364 
     | 
    
         
            +
                    });        
         
     | 
| 
      
 365 
     | 
    
         
            +
                },    
         
     | 
| 
      
 366 
     | 
    
         
            +
                _onSubmit: function(id, fileName){
         
     | 
| 
      
 367 
     | 
    
         
            +
                    this._filesInProgress++;  
         
     | 
| 
      
 368 
     | 
    
         
            +
                },
         
     | 
| 
      
 369 
     | 
    
         
            +
                _onProgress: function(id, fileName, loaded, total){        
         
     | 
| 
      
 370 
     | 
    
         
            +
                },
         
     | 
| 
      
 371 
     | 
    
         
            +
                _onComplete: function(id, fileName, result){
         
     | 
| 
      
 372 
     | 
    
         
            +
                    this._filesInProgress--;                 
         
     | 
| 
      
 373 
     | 
    
         
            +
                    if (result.error){
         
     | 
| 
      
 374 
     | 
    
         
            +
                        this._options.showMessage(result.error);
         
     | 
| 
      
 375 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 376 
     | 
    
         
            +
                      this._filesUploaded++;
         
     | 
| 
      
 377 
     | 
    
         
            +
                    }             
         
     | 
| 
      
 378 
     | 
    
         
            +
                },
         
     | 
| 
      
 379 
     | 
    
         
            +
                _onCancel: function(id, fileName){
         
     | 
| 
      
 380 
     | 
    
         
            +
                    this._filesInProgress--;        
         
     | 
| 
      
 381 
     | 
    
         
            +
                },
         
     | 
| 
      
 382 
     | 
    
         
            +
                _onInputChange: function(input){
         
     | 
| 
      
 383 
     | 
    
         
            +
                    if (this._handler instanceof qq.UploadHandlerXhr){                
         
     | 
| 
      
 384 
     | 
    
         
            +
                        this._uploadFileList(input.files);                   
         
     | 
| 
      
 385 
     | 
    
         
            +
                    } else {             
         
     | 
| 
      
 386 
     | 
    
         
            +
                        if (this._validateFile(input)){                
         
     | 
| 
      
 387 
     | 
    
         
            +
                            this._uploadFile(input);                                    
         
     | 
| 
      
 388 
     | 
    
         
            +
                        }                      
         
     | 
| 
      
 389 
     | 
    
         
            +
                    }               
         
     | 
| 
      
 390 
     | 
    
         
            +
                    this._button.reset();   
         
     | 
| 
      
 391 
     | 
    
         
            +
                },  
         
     | 
| 
      
 392 
     | 
    
         
            +
                _uploadFileList: function(files){
         
     | 
| 
      
 393 
     | 
    
         
            +
                    if ( this._validateFiles(files) ) {
         
     | 
| 
      
 394 
     | 
    
         
            +
                      for (var i=0; i<files.length; i++){
         
     | 
| 
      
 395 
     | 
    
         
            +
                          this._uploadFile(files[i]);        
         
     | 
| 
      
 396 
     | 
    
         
            +
                      }
         
     | 
| 
      
 397 
     | 
    
         
            +
                    }
         
     | 
| 
      
 398 
     | 
    
         
            +
                },       
         
     | 
| 
      
 399 
     | 
    
         
            +
                _uploadFile: function(fileContainer){      
         
     | 
| 
      
 400 
     | 
    
         
            +
                    var id = this._handler.add(fileContainer);
         
     | 
| 
      
 401 
     | 
    
         
            +
                    var fileName = this._handler.getName(id);
         
     | 
| 
      
 402 
     | 
    
         
            +
                    
         
     | 
| 
      
 403 
     | 
    
         
            +
                    if (this._options.onSubmit(id, fileName) !== false){
         
     | 
| 
      
 404 
     | 
    
         
            +
                        this._onSubmit(id, fileName);
         
     | 
| 
      
 405 
     | 
    
         
            +
                        this._handler.upload(id, this._options.params);
         
     | 
| 
      
 406 
     | 
    
         
            +
                    }
         
     | 
| 
      
 407 
     | 
    
         
            +
                },
         
     | 
| 
      
 408 
     | 
    
         
            +
                _validateFiles: function(files){
         
     | 
| 
      
 409 
     | 
    
         
            +
                    var uploadedCount = this._filesUploaded + files.length;
         
     | 
| 
      
 410 
     | 
    
         
            +
                    
         
     | 
| 
      
 411 
     | 
    
         
            +
                    if (this._options.maxFilesCount > 0) {
         
     | 
| 
      
 412 
     | 
    
         
            +
                      if ( uploadedCount > this._options.maxFilesCount) { 
         
     | 
| 
      
 413 
     | 
    
         
            +
                        this._error('maxFilesError', 'name');
         
     | 
| 
      
 414 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 415 
     | 
    
         
            +
                      }
         
     | 
| 
      
 416 
     | 
    
         
            +
                    }
         
     | 
| 
      
 417 
     | 
    
         
            +
                    
         
     | 
| 
      
 418 
     | 
    
         
            +
                    if (this._options.minFilesCount > 0) {
         
     | 
| 
      
 419 
     | 
    
         
            +
                      if ( uploadedCount < this._options.minFilesCount) {
         
     | 
| 
      
 420 
     | 
    
         
            +
                        this._error('minFilesError', 'name');
         
     | 
| 
      
 421 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 422 
     | 
    
         
            +
                      }
         
     | 
| 
      
 423 
     | 
    
         
            +
                    }
         
     | 
| 
      
 424 
     | 
    
         
            +
                    
         
     | 
| 
      
 425 
     | 
    
         
            +
                    for (var i=0; i<files.length; i++){
         
     | 
| 
      
 426 
     | 
    
         
            +
                        if ( !this._validateFile(files[i])){
         
     | 
| 
      
 427 
     | 
    
         
            +
                            return false;
         
     | 
| 
      
 428 
     | 
    
         
            +
                        }            
         
     | 
| 
      
 429 
     | 
    
         
            +
                    }
         
     | 
| 
      
 430 
     | 
    
         
            +
                    
         
     | 
| 
      
 431 
     | 
    
         
            +
                    return true;
         
     | 
| 
      
 432 
     | 
    
         
            +
                },      
         
     | 
| 
      
 433 
     | 
    
         
            +
                _validateFile: function(file){
         
     | 
| 
      
 434 
     | 
    
         
            +
                    var name, size;
         
     | 
| 
      
 435 
     | 
    
         
            +
                    
         
     | 
| 
      
 436 
     | 
    
         
            +
                    if (file.value){
         
     | 
| 
      
 437 
     | 
    
         
            +
                        // it is a file input            
         
     | 
| 
      
 438 
     | 
    
         
            +
                        // get input value and remove path to normalize
         
     | 
| 
      
 439 
     | 
    
         
            +
                        name = file.value.replace(/.*(\/|\\)/, "");
         
     | 
| 
      
 440 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 441 
     | 
    
         
            +
                        // fix missing properties in Safari
         
     | 
| 
      
 442 
     | 
    
         
            +
                        name = file.fileName != null ? file.fileName : file.name;
         
     | 
| 
      
 443 
     | 
    
         
            +
                        size = file.fileSize != null ? file.fileSize : file.size;
         
     | 
| 
      
 444 
     | 
    
         
            +
                    }
         
     | 
| 
      
 445 
     | 
    
         
            +
                                
         
     | 
| 
      
 446 
     | 
    
         
            +
                    if (! this._isAllowedExtension(name)){            
         
     | 
| 
      
 447 
     | 
    
         
            +
                        this._error('typeError', name);
         
     | 
| 
      
 448 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 449 
     | 
    
         
            +
                        
         
     | 
| 
      
 450 
     | 
    
         
            +
                    } else if (size === 0){            
         
     | 
| 
      
 451 
     | 
    
         
            +
                        this._error('emptyError', name);
         
     | 
| 
      
 452 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 453 
     | 
    
         
            +
                                                                 
         
     | 
| 
      
 454 
     | 
    
         
            +
                    } else if (size && this._options.sizeLimit && size > this._options.sizeLimit){            
         
     | 
| 
      
 455 
     | 
    
         
            +
                        this._error('sizeError', name);
         
     | 
| 
      
 456 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 457 
     | 
    
         
            +
                                    
         
     | 
| 
      
 458 
     | 
    
         
            +
                    } else if (size && size < this._options.minSizeLimit){
         
     | 
| 
      
 459 
     | 
    
         
            +
                        this._error('minSizeError', name);
         
     | 
| 
      
 460 
     | 
    
         
            +
                        return false;            
         
     | 
| 
      
 461 
     | 
    
         
            +
                    }
         
     | 
| 
      
 462 
     | 
    
         
            +
                    
         
     | 
| 
      
 463 
     | 
    
         
            +
                    return true;                
         
     | 
| 
      
 464 
     | 
    
         
            +
                },
         
     | 
| 
      
 465 
     | 
    
         
            +
                _error: function(code, fileName){
         
     | 
| 
      
 466 
     | 
    
         
            +
                    var message = this._options.messages[code];        
         
     | 
| 
      
 467 
     | 
    
         
            +
                    function r(name, replacement){ message = message.replace(name, replacement); }
         
     | 
| 
      
 468 
     | 
    
         
            +
                    
         
     | 
| 
      
 469 
     | 
    
         
            +
                    r('{file}', this._formatFileName(fileName));        
         
     | 
| 
      
 470 
     | 
    
         
            +
                    r('{extensions}', this._options.allowedExtensions.join(', '));
         
     | 
| 
      
 471 
     | 
    
         
            +
                    r('{sizeLimit}', this._formatSize(this._options.sizeLimit));
         
     | 
| 
      
 472 
     | 
    
         
            +
                    r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit));
         
     | 
| 
      
 473 
     | 
    
         
            +
                    r('{maxFilesCount}', this._options.maxFilesCount);
         
     | 
| 
      
 474 
     | 
    
         
            +
                    r('{minFilesCount}', this._options.minFilesCount);
         
     | 
| 
      
 475 
     | 
    
         
            +
                    
         
     | 
| 
      
 476 
     | 
    
         
            +
                    this._options.showMessage(message);                
         
     | 
| 
      
 477 
     | 
    
         
            +
                },
         
     | 
| 
      
 478 
     | 
    
         
            +
                _formatFileName: function(name){
         
     | 
| 
      
 479 
     | 
    
         
            +
                    if (name.length > 33){
         
     | 
| 
      
 480 
     | 
    
         
            +
                        name = name.slice(0, 19) + '...' + name.slice(-13);    
         
     | 
| 
      
 481 
     | 
    
         
            +
                    }
         
     | 
| 
      
 482 
     | 
    
         
            +
                    return name;
         
     | 
| 
      
 483 
     | 
    
         
            +
                },
         
     | 
| 
      
 484 
     | 
    
         
            +
                _isAllowedExtension: function(fileName){
         
     | 
| 
      
 485 
     | 
    
         
            +
                    var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
         
     | 
| 
      
 486 
     | 
    
         
            +
                    var allowed = this._options.allowedExtensions;
         
     | 
| 
      
 487 
     | 
    
         
            +
                    
         
     | 
| 
      
 488 
     | 
    
         
            +
                    if (!allowed.length){return true;}        
         
     | 
| 
      
 489 
     | 
    
         
            +
                    
         
     | 
| 
      
 490 
     | 
    
         
            +
                    for (var i=0; i<allowed.length; i++){
         
     | 
| 
      
 491 
     | 
    
         
            +
                        if (allowed[i].toLowerCase() == ext){ return true;}    
         
     | 
| 
      
 492 
     | 
    
         
            +
                    }
         
     | 
| 
      
 493 
     | 
    
         
            +
                    
         
     | 
| 
      
 494 
     | 
    
         
            +
                    return false;
         
     | 
| 
      
 495 
     | 
    
         
            +
                },    
         
     | 
| 
      
 496 
     | 
    
         
            +
                _formatSize: function(bytes){
         
     | 
| 
      
 497 
     | 
    
         
            +
                    var i = -1;                                    
         
     | 
| 
      
 498 
     | 
    
         
            +
                    do {
         
     | 
| 
      
 499 
     | 
    
         
            +
                        bytes = bytes / 1024;
         
     | 
| 
      
 500 
     | 
    
         
            +
                        i++;  
         
     | 
| 
      
 501 
     | 
    
         
            +
                    } while (bytes > 99);
         
     | 
| 
      
 502 
     | 
    
         
            +
                    
         
     | 
| 
      
 503 
     | 
    
         
            +
                    return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];          
         
     | 
| 
      
 504 
     | 
    
         
            +
                }
         
     | 
| 
      
 505 
     | 
    
         
            +
            };
         
     | 
| 
      
 506 
     | 
    
         
            +
                
         
     | 
| 
      
 507 
     | 
    
         
            +
                   
         
     | 
| 
      
 508 
     | 
    
         
            +
            /**
         
     | 
| 
      
 509 
     | 
    
         
            +
             * Class that creates upload widget with drag-and-drop and file list
         
     | 
| 
      
 510 
     | 
    
         
            +
             * @inherits qq.FileUploaderBasic
         
     | 
| 
      
 511 
     | 
    
         
            +
             */
         
     | 
| 
      
 512 
     | 
    
         
            +
            qq.FileUploader = function(o){
         
     | 
| 
      
 513 
     | 
    
         
            +
                // call parent constructor
         
     | 
| 
      
 514 
     | 
    
         
            +
                qq.FileUploaderBasic.apply(this, arguments);
         
     | 
| 
      
 515 
     | 
    
         
            +
                
         
     | 
| 
      
 516 
     | 
    
         
            +
                // additional options    
         
     | 
| 
      
 517 
     | 
    
         
            +
                qq.extend(this._options, {
         
     | 
| 
      
 518 
     | 
    
         
            +
                    element: null,
         
     | 
| 
      
 519 
     | 
    
         
            +
                    // if set, will be used instead of qq-upload-list in template
         
     | 
| 
      
 520 
     | 
    
         
            +
                    listElement: null,
         
     | 
| 
      
 521 
     | 
    
         
            +
                            
         
     | 
| 
      
 522 
     | 
    
         
            +
                    template: '<div class="qq-uploader">' + 
         
     | 
| 
      
 523 
     | 
    
         
            +
                            '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
         
     | 
| 
      
 524 
     | 
    
         
            +
                            '<div class="qq-upload-button">Upload a file</div>' +
         
     | 
| 
      
 525 
     | 
    
         
            +
                            '<ul class="qq-upload-list"></ul>' + 
         
     | 
| 
      
 526 
     | 
    
         
            +
                         '</div>',
         
     | 
| 
      
 527 
     | 
    
         
            +
             
     | 
| 
      
 528 
     | 
    
         
            +
                    // template for one item in file list
         
     | 
| 
      
 529 
     | 
    
         
            +
                    fileTemplate: '<li>' +
         
     | 
| 
      
 530 
     | 
    
         
            +
                            '<span class="qq-upload-file"></span>' +
         
     | 
| 
      
 531 
     | 
    
         
            +
                            '<span class="qq-upload-spinner"></span>' +
         
     | 
| 
      
 532 
     | 
    
         
            +
                            '<span class="qq-upload-size"></span>' +
         
     | 
| 
      
 533 
     | 
    
         
            +
                            '<a class="qq-upload-cancel" href="#">Cancel</a>' +
         
     | 
| 
      
 534 
     | 
    
         
            +
                            '<span class="qq-upload-failed-text">Failed</span>' +
         
     | 
| 
      
 535 
     | 
    
         
            +
                        '</li>',        
         
     | 
| 
      
 536 
     | 
    
         
            +
                    
         
     | 
| 
      
 537 
     | 
    
         
            +
                    classes: {
         
     | 
| 
      
 538 
     | 
    
         
            +
                        // used to get elements from templates
         
     | 
| 
      
 539 
     | 
    
         
            +
                        button: 'qq-upload-button',
         
     | 
| 
      
 540 
     | 
    
         
            +
                        drop: 'qq-upload-drop-area',
         
     | 
| 
      
 541 
     | 
    
         
            +
                        dropActive: 'qq-upload-drop-area-active',
         
     | 
| 
      
 542 
     | 
    
         
            +
                        list: 'qq-upload-list',
         
     | 
| 
      
 543 
     | 
    
         
            +
                                    
         
     | 
| 
      
 544 
     | 
    
         
            +
                        file: 'qq-upload-file',
         
     | 
| 
      
 545 
     | 
    
         
            +
                        spinner: 'qq-upload-spinner',
         
     | 
| 
      
 546 
     | 
    
         
            +
                        size: 'qq-upload-size',
         
     | 
| 
      
 547 
     | 
    
         
            +
                        cancel: 'qq-upload-cancel',
         
     | 
| 
      
 548 
     | 
    
         
            +
             
     | 
| 
      
 549 
     | 
    
         
            +
                        // added to list item when upload completes
         
     | 
| 
      
 550 
     | 
    
         
            +
                        // used in css to hide progress spinner
         
     | 
| 
      
 551 
     | 
    
         
            +
                        success: 'qq-upload-success',
         
     | 
| 
      
 552 
     | 
    
         
            +
                        fail: 'qq-upload-fail'
         
     | 
| 
      
 553 
     | 
    
         
            +
                    }
         
     | 
| 
      
 554 
     | 
    
         
            +
                });
         
     | 
| 
      
 555 
     | 
    
         
            +
                // overwrite options with user supplied    
         
     | 
| 
      
 556 
     | 
    
         
            +
                qq.extend(this._options, o);       
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
      
 558 
     | 
    
         
            +
                this._element = this._options.element;
         
     | 
| 
      
 559 
     | 
    
         
            +
                this._element.innerHTML = this._options.template;        
         
     | 
| 
      
 560 
     | 
    
         
            +
                this._listElement = this._options.listElement || this._find(this._element, 'list');
         
     | 
| 
      
 561 
     | 
    
         
            +
                
         
     | 
| 
      
 562 
     | 
    
         
            +
                this._classes = this._options.classes;
         
     | 
| 
      
 563 
     | 
    
         
            +
                    
         
     | 
| 
      
 564 
     | 
    
         
            +
                this._button = this._createUploadButton(this._find(this._element, 'button'));        
         
     | 
| 
      
 565 
     | 
    
         
            +
                
         
     | 
| 
      
 566 
     | 
    
         
            +
                this._bindCancelEvent();
         
     | 
| 
      
 567 
     | 
    
         
            +
                this._setupDragDrop();
         
     | 
| 
      
 568 
     | 
    
         
            +
            };
         
     | 
| 
      
 569 
     | 
    
         
            +
             
     | 
| 
      
 570 
     | 
    
         
            +
            // inherit from Basic Uploader
         
     | 
| 
      
 571 
     | 
    
         
            +
            qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype);
         
     | 
| 
      
 572 
     | 
    
         
            +
             
     | 
| 
      
 573 
     | 
    
         
            +
            qq.extend(qq.FileUploader.prototype, {
         
     | 
| 
      
 574 
     | 
    
         
            +
                /**
         
     | 
| 
      
 575 
     | 
    
         
            +
                 * Gets one of the elements listed in this._options.classes
         
     | 
| 
      
 576 
     | 
    
         
            +
                 **/
         
     | 
| 
      
 577 
     | 
    
         
            +
                _find: function(parent, type){                                
         
     | 
| 
      
 578 
     | 
    
         
            +
                    var element = qq.getByClass(parent, this._options.classes[type])[0];        
         
     | 
| 
      
 579 
     | 
    
         
            +
                    if (!element){
         
     | 
| 
      
 580 
     | 
    
         
            +
                        throw new Error('element not found ' + type);
         
     | 
| 
      
 581 
     | 
    
         
            +
                    }
         
     | 
| 
      
 582 
     | 
    
         
            +
                    
         
     | 
| 
      
 583 
     | 
    
         
            +
                    return element;
         
     | 
| 
      
 584 
     | 
    
         
            +
                },
         
     | 
| 
      
 585 
     | 
    
         
            +
                _setupDragDrop: function(){
         
     | 
| 
      
 586 
     | 
    
         
            +
                    var self = this,
         
     | 
| 
      
 587 
     | 
    
         
            +
                        dropArea = this._find(this._element, 'drop');                        
         
     | 
| 
      
 588 
     | 
    
         
            +
             
     | 
| 
      
 589 
     | 
    
         
            +
                    var dz = new qq.UploadDropZone({
         
     | 
| 
      
 590 
     | 
    
         
            +
                        element: dropArea,
         
     | 
| 
      
 591 
     | 
    
         
            +
                        onEnter: function(e){
         
     | 
| 
      
 592 
     | 
    
         
            +
                            qq.addClass(dropArea, self._classes.dropActive);
         
     | 
| 
      
 593 
     | 
    
         
            +
                            e.stopPropagation();
         
     | 
| 
      
 594 
     | 
    
         
            +
                        },
         
     | 
| 
      
 595 
     | 
    
         
            +
                        onLeave: function(e){
         
     | 
| 
      
 596 
     | 
    
         
            +
                            e.stopPropagation();
         
     | 
| 
      
 597 
     | 
    
         
            +
                        },
         
     | 
| 
      
 598 
     | 
    
         
            +
                        onLeaveNotDescendants: function(e){
         
     | 
| 
      
 599 
     | 
    
         
            +
                            qq.removeClass(dropArea, self._classes.dropActive);  
         
     | 
| 
      
 600 
     | 
    
         
            +
                        },
         
     | 
| 
      
 601 
     | 
    
         
            +
                        onDrop: function(e){
         
     | 
| 
      
 602 
     | 
    
         
            +
                            dropArea.style.display = 'none';
         
     | 
| 
      
 603 
     | 
    
         
            +
                            qq.removeClass(dropArea, self._classes.dropActive);
         
     | 
| 
      
 604 
     | 
    
         
            +
                            self._uploadFileList(e.dataTransfer.files);    
         
     | 
| 
      
 605 
     | 
    
         
            +
                        }
         
     | 
| 
      
 606 
     | 
    
         
            +
                    });
         
     | 
| 
      
 607 
     | 
    
         
            +
                            
         
     | 
| 
      
 608 
     | 
    
         
            +
                    dropArea.style.display = 'none';
         
     | 
| 
      
 609 
     | 
    
         
            +
             
     | 
| 
      
 610 
     | 
    
         
            +
                    qq.attach(document, 'dragenter', function(e){     
         
     | 
| 
      
 611 
     | 
    
         
            +
                        if (!dz._isValidFileDrag(e)) return; 
         
     | 
| 
      
 612 
     | 
    
         
            +
                        
         
     | 
| 
      
 613 
     | 
    
         
            +
                        dropArea.style.display = 'block';            
         
     | 
| 
      
 614 
     | 
    
         
            +
                    });                 
         
     | 
| 
      
 615 
     | 
    
         
            +
                    qq.attach(document, 'dragleave', function(e){
         
     | 
| 
      
 616 
     | 
    
         
            +
                        if (!dz._isValidFileDrag(e)) return;            
         
     | 
| 
      
 617 
     | 
    
         
            +
                        
         
     | 
| 
      
 618 
     | 
    
         
            +
                        var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
         
     | 
| 
      
 619 
     | 
    
         
            +
                        // only fire when leaving document out
         
     | 
| 
      
 620 
     | 
    
         
            +
                        if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){               
         
     | 
| 
      
 621 
     | 
    
         
            +
                            dropArea.style.display = 'none';                                            
         
     | 
| 
      
 622 
     | 
    
         
            +
                        }
         
     | 
| 
      
 623 
     | 
    
         
            +
                    });                
         
     | 
| 
      
 624 
     | 
    
         
            +
                },
         
     | 
| 
      
 625 
     | 
    
         
            +
                _onSubmit: function(id, fileName){
         
     | 
| 
      
 626 
     | 
    
         
            +
                    qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
         
     | 
| 
      
 627 
     | 
    
         
            +
                    this._addToList(id, fileName);  
         
     | 
| 
      
 628 
     | 
    
         
            +
                },
         
     | 
| 
      
 629 
     | 
    
         
            +
                _onProgress: function(id, fileName, loaded, total){
         
     | 
| 
      
 630 
     | 
    
         
            +
                    qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
         
     | 
| 
      
 631 
     | 
    
         
            +
             
     | 
| 
      
 632 
     | 
    
         
            +
                    var item = this._getItemByFileId(id);
         
     | 
| 
      
 633 
     | 
    
         
            +
                    var size = this._find(item, 'size');
         
     | 
| 
      
 634 
     | 
    
         
            +
                    size.style.display = 'inline';
         
     | 
| 
      
 635 
     | 
    
         
            +
                    
         
     | 
| 
      
 636 
     | 
    
         
            +
                    var text; 
         
     | 
| 
      
 637 
     | 
    
         
            +
                    if (loaded != total){
         
     | 
| 
      
 638 
     | 
    
         
            +
                        text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
         
     | 
| 
      
 639 
     | 
    
         
            +
                    } else {                                   
         
     | 
| 
      
 640 
     | 
    
         
            +
                        text = this._formatSize(total);
         
     | 
| 
      
 641 
     | 
    
         
            +
                    }          
         
     | 
| 
      
 642 
     | 
    
         
            +
                    
         
     | 
| 
      
 643 
     | 
    
         
            +
                    qq.setText(size, text);         
         
     | 
| 
      
 644 
     | 
    
         
            +
                },
         
     | 
| 
      
 645 
     | 
    
         
            +
                _onComplete: function(id, fileName, result){
         
     | 
| 
      
 646 
     | 
    
         
            +
                    qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
         
     | 
| 
      
 647 
     | 
    
         
            +
             
     | 
| 
      
 648 
     | 
    
         
            +
                    // mark completed
         
     | 
| 
      
 649 
     | 
    
         
            +
                    var item = this._getItemByFileId(id);                
         
     | 
| 
      
 650 
     | 
    
         
            +
                    qq.remove(this._find(item, 'cancel'));
         
     | 
| 
      
 651 
     | 
    
         
            +
                    qq.remove(this._find(item, 'spinner'));
         
     | 
| 
      
 652 
     | 
    
         
            +
                    
         
     | 
| 
      
 653 
     | 
    
         
            +
                    if (result.success){
         
     | 
| 
      
 654 
     | 
    
         
            +
                        qq.addClass(item, this._classes.success);    
         
     | 
| 
      
 655 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 656 
     | 
    
         
            +
                        qq.addClass(item, this._classes.fail);
         
     | 
| 
      
 657 
     | 
    
         
            +
                    }         
         
     | 
| 
      
 658 
     | 
    
         
            +
                },
         
     | 
| 
      
 659 
     | 
    
         
            +
                _addToList: function(id, fileName){
         
     | 
| 
      
 660 
     | 
    
         
            +
                    var item = qq.toElement(this._options.fileTemplate);                
         
     | 
| 
      
 661 
     | 
    
         
            +
                    item.qqFileId = id;
         
     | 
| 
      
 662 
     | 
    
         
            +
             
     | 
| 
      
 663 
     | 
    
         
            +
                    var fileElement = this._find(item, 'file');        
         
     | 
| 
      
 664 
     | 
    
         
            +
                    qq.setText(fileElement, this._formatFileName(fileName));
         
     | 
| 
      
 665 
     | 
    
         
            +
                    this._find(item, 'size').style.display = 'none';        
         
     | 
| 
      
 666 
     | 
    
         
            +
             
     | 
| 
      
 667 
     | 
    
         
            +
                    this._listElement.appendChild(item);
         
     | 
| 
      
 668 
     | 
    
         
            +
                },
         
     | 
| 
      
 669 
     | 
    
         
            +
                _getItemByFileId: function(id){
         
     | 
| 
      
 670 
     | 
    
         
            +
                    var item = this._listElement.firstChild;        
         
     | 
| 
      
 671 
     | 
    
         
            +
                    
         
     | 
| 
      
 672 
     | 
    
         
            +
                    // there can't be txt nodes in dynamically created list
         
     | 
| 
      
 673 
     | 
    
         
            +
                    // and we can  use nextSibling
         
     | 
| 
      
 674 
     | 
    
         
            +
                    while (item){            
         
     | 
| 
      
 675 
     | 
    
         
            +
                        if (item.qqFileId == id) return item;            
         
     | 
| 
      
 676 
     | 
    
         
            +
                        item = item.nextSibling;
         
     | 
| 
      
 677 
     | 
    
         
            +
                    }          
         
     | 
| 
      
 678 
     | 
    
         
            +
                },
         
     | 
| 
      
 679 
     | 
    
         
            +
                /**
         
     | 
| 
      
 680 
     | 
    
         
            +
                 * delegate click event for cancel link 
         
     | 
| 
      
 681 
     | 
    
         
            +
                 **/
         
     | 
| 
      
 682 
     | 
    
         
            +
                _bindCancelEvent: function(){
         
     | 
| 
      
 683 
     | 
    
         
            +
                    var self = this,
         
     | 
| 
      
 684 
     | 
    
         
            +
                        list = this._listElement;            
         
     | 
| 
      
 685 
     | 
    
         
            +
                    
         
     | 
| 
      
 686 
     | 
    
         
            +
                    qq.attach(list, 'click', function(e){            
         
     | 
| 
      
 687 
     | 
    
         
            +
                        e = e || window.event;
         
     | 
| 
      
 688 
     | 
    
         
            +
                        var target = e.target || e.srcElement;
         
     | 
| 
      
 689 
     | 
    
         
            +
                        
         
     | 
| 
      
 690 
     | 
    
         
            +
                        if (qq.hasClass(target, self._classes.cancel)){                
         
     | 
| 
      
 691 
     | 
    
         
            +
                            qq.preventDefault(e);
         
     | 
| 
      
 692 
     | 
    
         
            +
                           
         
     | 
| 
      
 693 
     | 
    
         
            +
                            var item = target.parentNode;
         
     | 
| 
      
 694 
     | 
    
         
            +
                            self._handler.cancel(item.qqFileId);
         
     | 
| 
      
 695 
     | 
    
         
            +
                            qq.remove(item);
         
     | 
| 
      
 696 
     | 
    
         
            +
                        }
         
     | 
| 
      
 697 
     | 
    
         
            +
                    });
         
     | 
| 
      
 698 
     | 
    
         
            +
                }    
         
     | 
| 
      
 699 
     | 
    
         
            +
            });
         
     | 
| 
      
 700 
     | 
    
         
            +
                
         
     | 
| 
      
 701 
     | 
    
         
            +
            qq.UploadDropZone = function(o){
         
     | 
| 
      
 702 
     | 
    
         
            +
                this._options = {
         
     | 
| 
      
 703 
     | 
    
         
            +
                    element: null,  
         
     | 
| 
      
 704 
     | 
    
         
            +
                    onEnter: function(e){},
         
     | 
| 
      
 705 
     | 
    
         
            +
                    onLeave: function(e){},  
         
     | 
| 
      
 706 
     | 
    
         
            +
                    // is not fired when leaving element by hovering descendants   
         
     | 
| 
      
 707 
     | 
    
         
            +
                    onLeaveNotDescendants: function(e){},   
         
     | 
| 
      
 708 
     | 
    
         
            +
                    onDrop: function(e){}                       
         
     | 
| 
      
 709 
     | 
    
         
            +
                };
         
     | 
| 
      
 710 
     | 
    
         
            +
                qq.extend(this._options, o); 
         
     | 
| 
      
 711 
     | 
    
         
            +
                
         
     | 
| 
      
 712 
     | 
    
         
            +
                this._element = this._options.element;
         
     | 
| 
      
 713 
     | 
    
         
            +
                
         
     | 
| 
      
 714 
     | 
    
         
            +
                this._disableDropOutside();
         
     | 
| 
      
 715 
     | 
    
         
            +
                this._attachEvents();   
         
     | 
| 
      
 716 
     | 
    
         
            +
            };
         
     | 
| 
      
 717 
     | 
    
         
            +
             
     | 
| 
      
 718 
     | 
    
         
            +
            qq.UploadDropZone.prototype = {
         
     | 
| 
      
 719 
     | 
    
         
            +
                _disableDropOutside: function(e){
         
     | 
| 
      
 720 
     | 
    
         
            +
                    // run only once for all instances
         
     | 
| 
      
 721 
     | 
    
         
            +
                    if (!qq.UploadDropZone.dropOutsideDisabled ){
         
     | 
| 
      
 722 
     | 
    
         
            +
             
     | 
| 
      
 723 
     | 
    
         
            +
                        qq.attach(document, 'dragover', function(e){
         
     | 
| 
      
 724 
     | 
    
         
            +
                            if (e.dataTransfer){
         
     | 
| 
      
 725 
     | 
    
         
            +
                                e.dataTransfer.dropEffect = 'none';
         
     | 
| 
      
 726 
     | 
    
         
            +
                                e.preventDefault(); 
         
     | 
| 
      
 727 
     | 
    
         
            +
                            }           
         
     | 
| 
      
 728 
     | 
    
         
            +
                        });
         
     | 
| 
      
 729 
     | 
    
         
            +
                        
         
     | 
| 
      
 730 
     | 
    
         
            +
                        qq.UploadDropZone.dropOutsideDisabled = true; 
         
     | 
| 
      
 731 
     | 
    
         
            +
                    }        
         
     | 
| 
      
 732 
     | 
    
         
            +
                },
         
     | 
| 
      
 733 
     | 
    
         
            +
                _attachEvents: function(){
         
     | 
| 
      
 734 
     | 
    
         
            +
                    var self = this;              
         
     | 
| 
      
 735 
     | 
    
         
            +
                              
         
     | 
| 
      
 736 
     | 
    
         
            +
                    qq.attach(self._element, 'dragover', function(e){
         
     | 
| 
      
 737 
     | 
    
         
            +
                        if (!self._isValidFileDrag(e)) return;
         
     | 
| 
      
 738 
     | 
    
         
            +
                        
         
     | 
| 
      
 739 
     | 
    
         
            +
                        var effect = e.dataTransfer.effectAllowed;
         
     | 
| 
      
 740 
     | 
    
         
            +
                        if (effect == 'move' || effect == 'linkMove'){
         
     | 
| 
      
 741 
     | 
    
         
            +
                            e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)    
         
     | 
| 
      
 742 
     | 
    
         
            +
                        } else {                    
         
     | 
| 
      
 743 
     | 
    
         
            +
                            e.dataTransfer.dropEffect = 'copy'; // for Chrome
         
     | 
| 
      
 744 
     | 
    
         
            +
                        }
         
     | 
| 
      
 745 
     | 
    
         
            +
                                                                 
         
     | 
| 
      
 746 
     | 
    
         
            +
                        e.stopPropagation();
         
     | 
| 
      
 747 
     | 
    
         
            +
                        e.preventDefault();                                                                    
         
     | 
| 
      
 748 
     | 
    
         
            +
                    });
         
     | 
| 
      
 749 
     | 
    
         
            +
                    
         
     | 
| 
      
 750 
     | 
    
         
            +
                    qq.attach(self._element, 'dragenter', function(e){
         
     | 
| 
      
 751 
     | 
    
         
            +
                        if (!self._isValidFileDrag(e)) return;
         
     | 
| 
      
 752 
     | 
    
         
            +
                                    
         
     | 
| 
      
 753 
     | 
    
         
            +
                        self._options.onEnter(e);
         
     | 
| 
      
 754 
     | 
    
         
            +
                    });
         
     | 
| 
      
 755 
     | 
    
         
            +
                    
         
     | 
| 
      
 756 
     | 
    
         
            +
                    qq.attach(self._element, 'dragleave', function(e){
         
     | 
| 
      
 757 
     | 
    
         
            +
                        if (!self._isValidFileDrag(e)) return;
         
     | 
| 
      
 758 
     | 
    
         
            +
                        
         
     | 
| 
      
 759 
     | 
    
         
            +
                        self._options.onLeave(e);
         
     | 
| 
      
 760 
     | 
    
         
            +
                        
         
     | 
| 
      
 761 
     | 
    
         
            +
                        var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);                      
         
     | 
| 
      
 762 
     | 
    
         
            +
                        // do not fire when moving a mouse over a descendant
         
     | 
| 
      
 763 
     | 
    
         
            +
                        if (qq.contains(this, relatedTarget)) return;
         
     | 
| 
      
 764 
     | 
    
         
            +
                                    
         
     | 
| 
      
 765 
     | 
    
         
            +
                        self._options.onLeaveNotDescendants(e); 
         
     | 
| 
      
 766 
     | 
    
         
            +
                    });
         
     | 
| 
      
 767 
     | 
    
         
            +
                            
         
     | 
| 
      
 768 
     | 
    
         
            +
                    qq.attach(self._element, 'drop', function(e){
         
     | 
| 
      
 769 
     | 
    
         
            +
                        if (!self._isValidFileDrag(e)) return;
         
     | 
| 
      
 770 
     | 
    
         
            +
                        
         
     | 
| 
      
 771 
     | 
    
         
            +
                        e.preventDefault();
         
     | 
| 
      
 772 
     | 
    
         
            +
                        self._options.onDrop(e);
         
     | 
| 
      
 773 
     | 
    
         
            +
                    });          
         
     | 
| 
      
 774 
     | 
    
         
            +
                },
         
     | 
| 
      
 775 
     | 
    
         
            +
                _isValidFileDrag: function(e){
         
     | 
| 
      
 776 
     | 
    
         
            +
                    var dt = e.dataTransfer,
         
     | 
| 
      
 777 
     | 
    
         
            +
                        // do not check dt.types.contains in webkit, because it crashes safari 4            
         
     | 
| 
      
 778 
     | 
    
         
            +
                        isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;                        
         
     | 
| 
      
 779 
     | 
    
         
            +
             
     | 
| 
      
 780 
     | 
    
         
            +
                    // dt.effectAllowed is none in Safari 5
         
     | 
| 
      
 781 
     | 
    
         
            +
                    // dt.types.contains check is for firefox            
         
     | 
| 
      
 782 
     | 
    
         
            +
                    return dt && dt.effectAllowed != 'none' && 
         
     | 
| 
      
 783 
     | 
    
         
            +
                        (dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files')));
         
     | 
| 
      
 784 
     | 
    
         
            +
                    
         
     | 
| 
      
 785 
     | 
    
         
            +
                }        
         
     | 
| 
      
 786 
     | 
    
         
            +
            }; 
         
     | 
| 
      
 787 
     | 
    
         
            +
             
     | 
| 
      
 788 
     | 
    
         
            +
            qq.UploadButton = function(o){
         
     | 
| 
      
 789 
     | 
    
         
            +
                this._options = {
         
     | 
| 
      
 790 
     | 
    
         
            +
                    element: null,  
         
     | 
| 
      
 791 
     | 
    
         
            +
                    // if set to true adds multiple attribute to file input      
         
     | 
| 
      
 792 
     | 
    
         
            +
                    multiple: false,
         
     | 
| 
      
 793 
     | 
    
         
            +
                    // name attribute of file input
         
     | 
| 
      
 794 
     | 
    
         
            +
                    name: 'file',
         
     | 
| 
      
 795 
     | 
    
         
            +
                    onChange: function(input){},
         
     | 
| 
      
 796 
     | 
    
         
            +
                    hoverClass: 'qq-upload-button-hover',
         
     | 
| 
      
 797 
     | 
    
         
            +
                    focusClass: 'qq-upload-button-focus'                       
         
     | 
| 
      
 798 
     | 
    
         
            +
                };
         
     | 
| 
      
 799 
     | 
    
         
            +
                
         
     | 
| 
      
 800 
     | 
    
         
            +
                qq.extend(this._options, o);
         
     | 
| 
      
 801 
     | 
    
         
            +
                    
         
     | 
| 
      
 802 
     | 
    
         
            +
                this._element = this._options.element;
         
     | 
| 
      
 803 
     | 
    
         
            +
                
         
     | 
| 
      
 804 
     | 
    
         
            +
                // make button suitable container for input
         
     | 
| 
      
 805 
     | 
    
         
            +
                qq.css(this._element, {
         
     | 
| 
      
 806 
     | 
    
         
            +
                    position: 'relative',
         
     | 
| 
      
 807 
     | 
    
         
            +
                    overflow: 'hidden',
         
     | 
| 
      
 808 
     | 
    
         
            +
                    // Make sure browse button is in the right side
         
     | 
| 
      
 809 
     | 
    
         
            +
                    // in Internet Explorer
         
     | 
| 
      
 810 
     | 
    
         
            +
                    direction: 'ltr'
         
     | 
| 
      
 811 
     | 
    
         
            +
                });   
         
     | 
| 
      
 812 
     | 
    
         
            +
                
         
     | 
| 
      
 813 
     | 
    
         
            +
                this._input = this._createInput();
         
     | 
| 
      
 814 
     | 
    
         
            +
            };
         
     | 
| 
      
 815 
     | 
    
         
            +
             
     | 
| 
      
 816 
     | 
    
         
            +
            qq.UploadButton.prototype = {
         
     | 
| 
      
 817 
     | 
    
         
            +
                /* returns file input element */    
         
     | 
| 
      
 818 
     | 
    
         
            +
                getInput: function(){
         
     | 
| 
      
 819 
     | 
    
         
            +
                    return this._input;
         
     | 
| 
      
 820 
     | 
    
         
            +
                },
         
     | 
| 
      
 821 
     | 
    
         
            +
                /* cleans/recreates the file input */
         
     | 
| 
      
 822 
     | 
    
         
            +
                reset: function(){
         
     | 
| 
      
 823 
     | 
    
         
            +
                    if (this._input.parentNode){
         
     | 
| 
      
 824 
     | 
    
         
            +
                        qq.remove(this._input);    
         
     | 
| 
      
 825 
     | 
    
         
            +
                    }                
         
     | 
| 
      
 826 
     | 
    
         
            +
                    
         
     | 
| 
      
 827 
     | 
    
         
            +
                    qq.removeClass(this._element, this._options.focusClass);
         
     | 
| 
      
 828 
     | 
    
         
            +
                    this._input = this._createInput();
         
     | 
| 
      
 829 
     | 
    
         
            +
                },    
         
     | 
| 
      
 830 
     | 
    
         
            +
                _createInput: function(){                
         
     | 
| 
      
 831 
     | 
    
         
            +
                    var input = document.createElement("input");
         
     | 
| 
      
 832 
     | 
    
         
            +
                    
         
     | 
| 
      
 833 
     | 
    
         
            +
                    if (this._options.multiple){
         
     | 
| 
      
 834 
     | 
    
         
            +
                        input.setAttribute("multiple", "multiple");
         
     | 
| 
      
 835 
     | 
    
         
            +
                    }
         
     | 
| 
      
 836 
     | 
    
         
            +
                            
         
     | 
| 
      
 837 
     | 
    
         
            +
                    input.setAttribute("type", "file");
         
     | 
| 
      
 838 
     | 
    
         
            +
                    input.setAttribute("name", this._options.name);
         
     | 
| 
      
 839 
     | 
    
         
            +
                    
         
     | 
| 
      
 840 
     | 
    
         
            +
                    qq.css(input, {
         
     | 
| 
      
 841 
     | 
    
         
            +
                        position: 'absolute',
         
     | 
| 
      
 842 
     | 
    
         
            +
                        // in Opera only 'browse' button
         
     | 
| 
      
 843 
     | 
    
         
            +
                        // is clickable and it is located at
         
     | 
| 
      
 844 
     | 
    
         
            +
                        // the right side of the input
         
     | 
| 
      
 845 
     | 
    
         
            +
                        right: 0,
         
     | 
| 
      
 846 
     | 
    
         
            +
                        top: 0,
         
     | 
| 
      
 847 
     | 
    
         
            +
                        fontFamily: 'Arial',
         
     | 
| 
      
 848 
     | 
    
         
            +
                        // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
         
     | 
| 
      
 849 
     | 
    
         
            +
                        fontSize: '118px',
         
     | 
| 
      
 850 
     | 
    
         
            +
                        margin: 0,
         
     | 
| 
      
 851 
     | 
    
         
            +
                        padding: 0,
         
     | 
| 
      
 852 
     | 
    
         
            +
                        cursor: 'pointer',
         
     | 
| 
      
 853 
     | 
    
         
            +
                        opacity: 0
         
     | 
| 
      
 854 
     | 
    
         
            +
                    });
         
     | 
| 
      
 855 
     | 
    
         
            +
                    
         
     | 
| 
      
 856 
     | 
    
         
            +
                    this._element.appendChild(input);
         
     | 
| 
      
 857 
     | 
    
         
            +
             
     | 
| 
      
 858 
     | 
    
         
            +
                    var self = this;
         
     | 
| 
      
 859 
     | 
    
         
            +
                    qq.attach(input, 'change', function(){
         
     | 
| 
      
 860 
     | 
    
         
            +
                        self._options.onChange(input);
         
     | 
| 
      
 861 
     | 
    
         
            +
                    });
         
     | 
| 
      
 862 
     | 
    
         
            +
                            
         
     | 
| 
      
 863 
     | 
    
         
            +
                    qq.attach(input, 'mouseover', function(){
         
     | 
| 
      
 864 
     | 
    
         
            +
                        qq.addClass(self._element, self._options.hoverClass);
         
     | 
| 
      
 865 
     | 
    
         
            +
                    });
         
     | 
| 
      
 866 
     | 
    
         
            +
                    qq.attach(input, 'mouseout', function(){
         
     | 
| 
      
 867 
     | 
    
         
            +
                        qq.removeClass(self._element, self._options.hoverClass);
         
     | 
| 
      
 868 
     | 
    
         
            +
                    });
         
     | 
| 
      
 869 
     | 
    
         
            +
                    qq.attach(input, 'focus', function(){
         
     | 
| 
      
 870 
     | 
    
         
            +
                        qq.addClass(self._element, self._options.focusClass);
         
     | 
| 
      
 871 
     | 
    
         
            +
                    });
         
     | 
| 
      
 872 
     | 
    
         
            +
                    qq.attach(input, 'blur', function(){
         
     | 
| 
      
 873 
     | 
    
         
            +
                        qq.removeClass(self._element, self._options.focusClass);
         
     | 
| 
      
 874 
     | 
    
         
            +
                    });
         
     | 
| 
      
 875 
     | 
    
         
            +
             
     | 
| 
      
 876 
     | 
    
         
            +
                    // IE and Opera, unfortunately have 2 tab stops on file input
         
     | 
| 
      
 877 
     | 
    
         
            +
                    // which is unacceptable in our case, disable keyboard access
         
     | 
| 
      
 878 
     | 
    
         
            +
                    if (window.attachEvent){
         
     | 
| 
      
 879 
     | 
    
         
            +
                        // it is IE or Opera
         
     | 
| 
      
 880 
     | 
    
         
            +
                        input.setAttribute('tabIndex', "-1");
         
     | 
| 
      
 881 
     | 
    
         
            +
                    }
         
     | 
| 
      
 882 
     | 
    
         
            +
             
     | 
| 
      
 883 
     | 
    
         
            +
                    return input;            
         
     | 
| 
      
 884 
     | 
    
         
            +
                }        
         
     | 
| 
      
 885 
     | 
    
         
            +
            };
         
     | 
| 
      
 886 
     | 
    
         
            +
             
     | 
| 
      
 887 
     | 
    
         
            +
            /**
         
     | 
| 
      
 888 
     | 
    
         
            +
             * Class for uploading files, uploading itself is handled by child classes
         
     | 
| 
      
 889 
     | 
    
         
            +
             */
         
     | 
| 
      
 890 
     | 
    
         
            +
            qq.UploadHandlerAbstract = function(o){
         
     | 
| 
      
 891 
     | 
    
         
            +
                this._options = {
         
     | 
| 
      
 892 
     | 
    
         
            +
                    debug: false,
         
     | 
| 
      
 893 
     | 
    
         
            +
                    action: '/upload.php',
         
     | 
| 
      
 894 
     | 
    
         
            +
                    method: 'POST',
         
     | 
| 
      
 895 
     | 
    
         
            +
                    fieldName: 'qqfile',
         
     | 
| 
      
 896 
     | 
    
         
            +
                    // maximum number of concurrent uploads        
         
     | 
| 
      
 897 
     | 
    
         
            +
                    maxConnections: 999,
         
     | 
| 
      
 898 
     | 
    
         
            +
                    onProgress: function(id, fileName, loaded, total){},
         
     | 
| 
      
 899 
     | 
    
         
            +
                    onComplete: function(id, fileName, response){},
         
     | 
| 
      
 900 
     | 
    
         
            +
                    onCancel: function(id, fileName){}
         
     | 
| 
      
 901 
     | 
    
         
            +
                };
         
     | 
| 
      
 902 
     | 
    
         
            +
                qq.extend(this._options, o);    
         
     | 
| 
      
 903 
     | 
    
         
            +
                
         
     | 
| 
      
 904 
     | 
    
         
            +
                this._queue = [];
         
     | 
| 
      
 905 
     | 
    
         
            +
                // params for files in queue
         
     | 
| 
      
 906 
     | 
    
         
            +
                this._params = [];
         
     | 
| 
      
 907 
     | 
    
         
            +
            };
         
     | 
| 
      
 908 
     | 
    
         
            +
            qq.UploadHandlerAbstract.prototype = {
         
     | 
| 
      
 909 
     | 
    
         
            +
                log: function(str){
         
     | 
| 
      
 910 
     | 
    
         
            +
                    if (this._options.debug && window.console) console.log('[uploader] ' + str);        
         
     | 
| 
      
 911 
     | 
    
         
            +
                },
         
     | 
| 
      
 912 
     | 
    
         
            +
                /**
         
     | 
| 
      
 913 
     | 
    
         
            +
                 * Adds file or file input to the queue
         
     | 
| 
      
 914 
     | 
    
         
            +
                 * @returns id
         
     | 
| 
      
 915 
     | 
    
         
            +
                 **/    
         
     | 
| 
      
 916 
     | 
    
         
            +
                add: function(file){},
         
     | 
| 
      
 917 
     | 
    
         
            +
                /**
         
     | 
| 
      
 918 
     | 
    
         
            +
                 * Sends the file identified by id and additional query params to the server
         
     | 
| 
      
 919 
     | 
    
         
            +
                 */
         
     | 
| 
      
 920 
     | 
    
         
            +
                upload: function(id, params){
         
     | 
| 
      
 921 
     | 
    
         
            +
                    var len = this._queue.push(id);
         
     | 
| 
      
 922 
     | 
    
         
            +
             
     | 
| 
      
 923 
     | 
    
         
            +
                    var copy = {};        
         
     | 
| 
      
 924 
     | 
    
         
            +
                    qq.extend(copy, params);
         
     | 
| 
      
 925 
     | 
    
         
            +
                    this._params[id] = copy;        
         
     | 
| 
      
 926 
     | 
    
         
            +
                            
         
     | 
| 
      
 927 
     | 
    
         
            +
                    // if too many active uploads, wait...
         
     | 
| 
      
 928 
     | 
    
         
            +
                    if (len <= this._options.maxConnections){               
         
     | 
| 
      
 929 
     | 
    
         
            +
                        this._upload(id, this._params[id]);
         
     | 
| 
      
 930 
     | 
    
         
            +
                    }
         
     | 
| 
      
 931 
     | 
    
         
            +
                },
         
     | 
| 
      
 932 
     | 
    
         
            +
                /**
         
     | 
| 
      
 933 
     | 
    
         
            +
                 * Cancels file upload by id
         
     | 
| 
      
 934 
     | 
    
         
            +
                 */
         
     | 
| 
      
 935 
     | 
    
         
            +
                cancel: function(id){
         
     | 
| 
      
 936 
     | 
    
         
            +
                    this._cancel(id);
         
     | 
| 
      
 937 
     | 
    
         
            +
                    this._dequeue(id);
         
     | 
| 
      
 938 
     | 
    
         
            +
                },
         
     | 
| 
      
 939 
     | 
    
         
            +
                /**
         
     | 
| 
      
 940 
     | 
    
         
            +
                 * Cancells all uploads
         
     | 
| 
      
 941 
     | 
    
         
            +
                 */
         
     | 
| 
      
 942 
     | 
    
         
            +
                cancelAll: function(){
         
     | 
| 
      
 943 
     | 
    
         
            +
                    for (var i=0; i<this._queue.length; i++){
         
     | 
| 
      
 944 
     | 
    
         
            +
                        this._cancel(this._queue[i]);
         
     | 
| 
      
 945 
     | 
    
         
            +
                    }
         
     | 
| 
      
 946 
     | 
    
         
            +
                    this._queue = [];
         
     | 
| 
      
 947 
     | 
    
         
            +
                },
         
     | 
| 
      
 948 
     | 
    
         
            +
                /**
         
     | 
| 
      
 949 
     | 
    
         
            +
                 * Returns name of the file identified by id
         
     | 
| 
      
 950 
     | 
    
         
            +
                 */
         
     | 
| 
      
 951 
     | 
    
         
            +
                getName: function(id){},
         
     | 
| 
      
 952 
     | 
    
         
            +
                /**
         
     | 
| 
      
 953 
     | 
    
         
            +
                 * Returns size of the file identified by id
         
     | 
| 
      
 954 
     | 
    
         
            +
                 */          
         
     | 
| 
      
 955 
     | 
    
         
            +
                getSize: function(id){},
         
     | 
| 
      
 956 
     | 
    
         
            +
                /**
         
     | 
| 
      
 957 
     | 
    
         
            +
                 * Returns id of files being uploaded or
         
     | 
| 
      
 958 
     | 
    
         
            +
                 * waiting for their turn
         
     | 
| 
      
 959 
     | 
    
         
            +
                 */
         
     | 
| 
      
 960 
     | 
    
         
            +
                getQueue: function(){
         
     | 
| 
      
 961 
     | 
    
         
            +
                    return this._queue;
         
     | 
| 
      
 962 
     | 
    
         
            +
                },
         
     | 
| 
      
 963 
     | 
    
         
            +
                /**
         
     | 
| 
      
 964 
     | 
    
         
            +
                 * Actual upload method
         
     | 
| 
      
 965 
     | 
    
         
            +
                 */
         
     | 
| 
      
 966 
     | 
    
         
            +
                _upload: function(id){},
         
     | 
| 
      
 967 
     | 
    
         
            +
                /**
         
     | 
| 
      
 968 
     | 
    
         
            +
                 * Actual cancel method
         
     | 
| 
      
 969 
     | 
    
         
            +
                 */
         
     | 
| 
      
 970 
     | 
    
         
            +
                _cancel: function(id){},     
         
     | 
| 
      
 971 
     | 
    
         
            +
                /**
         
     | 
| 
      
 972 
     | 
    
         
            +
                 * Removes element from queue, starts upload of next
         
     | 
| 
      
 973 
     | 
    
         
            +
                 */
         
     | 
| 
      
 974 
     | 
    
         
            +
                _dequeue: function(id){
         
     | 
| 
      
 975 
     | 
    
         
            +
                    var i = qq.indexOf(this._queue, id);
         
     | 
| 
      
 976 
     | 
    
         
            +
                    this._queue.splice(i, 1);
         
     | 
| 
      
 977 
     | 
    
         
            +
                            
         
     | 
| 
      
 978 
     | 
    
         
            +
                    var max = this._options.maxConnections;
         
     | 
| 
      
 979 
     | 
    
         
            +
                    
         
     | 
| 
      
 980 
     | 
    
         
            +
                    if (this._queue.length >= max && i < max){
         
     | 
| 
      
 981 
     | 
    
         
            +
                        var nextId = this._queue[max-1];
         
     | 
| 
      
 982 
     | 
    
         
            +
                        this._upload(nextId, this._params[nextId]);
         
     | 
| 
      
 983 
     | 
    
         
            +
                    }
         
     | 
| 
      
 984 
     | 
    
         
            +
                }        
         
     | 
| 
      
 985 
     | 
    
         
            +
            };
         
     | 
| 
      
 986 
     | 
    
         
            +
             
     | 
| 
      
 987 
     | 
    
         
            +
            /**
         
     | 
| 
      
 988 
     | 
    
         
            +
             * Class for uploading files using form and iframe
         
     | 
| 
      
 989 
     | 
    
         
            +
             * @inherits qq.UploadHandlerAbstract
         
     | 
| 
      
 990 
     | 
    
         
            +
             */
         
     | 
| 
      
 991 
     | 
    
         
            +
            qq.UploadHandlerForm = function(o){
         
     | 
| 
      
 992 
     | 
    
         
            +
                qq.UploadHandlerAbstract.apply(this, arguments);
         
     | 
| 
      
 993 
     | 
    
         
            +
                   
         
     | 
| 
      
 994 
     | 
    
         
            +
                this._inputs = {};
         
     | 
| 
      
 995 
     | 
    
         
            +
            };
         
     | 
| 
      
 996 
     | 
    
         
            +
            // @inherits qq.UploadHandlerAbstract
         
     | 
| 
      
 997 
     | 
    
         
            +
            qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
         
     | 
| 
      
 998 
     | 
    
         
            +
             
     | 
| 
      
 999 
     | 
    
         
            +
            qq.extend(qq.UploadHandlerForm.prototype, {
         
     | 
| 
      
 1000 
     | 
    
         
            +
                add: function(fileInput){
         
     | 
| 
      
 1001 
     | 
    
         
            +
                    fileInput.setAttribute('name', this._options.fieldName);
         
     | 
| 
      
 1002 
     | 
    
         
            +
                    var id = 'qq-upload-handler-iframe' + qq.getUniqueId();       
         
     | 
| 
      
 1003 
     | 
    
         
            +
                    
         
     | 
| 
      
 1004 
     | 
    
         
            +
                    this._inputs[id] = fileInput;
         
     | 
| 
      
 1005 
     | 
    
         
            +
                    
         
     | 
| 
      
 1006 
     | 
    
         
            +
                    // remove file input from DOM
         
     | 
| 
      
 1007 
     | 
    
         
            +
                    if (fileInput.parentNode){
         
     | 
| 
      
 1008 
     | 
    
         
            +
                        qq.remove(fileInput);
         
     | 
| 
      
 1009 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1010 
     | 
    
         
            +
                            
         
     | 
| 
      
 1011 
     | 
    
         
            +
                    return id;
         
     | 
| 
      
 1012 
     | 
    
         
            +
                },
         
     | 
| 
      
 1013 
     | 
    
         
            +
                getName: function(id){
         
     | 
| 
      
 1014 
     | 
    
         
            +
                    // get input value and remove path to normalize
         
     | 
| 
      
 1015 
     | 
    
         
            +
                    return this._inputs[id].value.replace(/.*(\/|\\)/, "");
         
     | 
| 
      
 1016 
     | 
    
         
            +
                },    
         
     | 
| 
      
 1017 
     | 
    
         
            +
                _cancel: function(id){
         
     | 
| 
      
 1018 
     | 
    
         
            +
                    this._options.onCancel(id, this.getName(id));
         
     | 
| 
      
 1019 
     | 
    
         
            +
                    
         
     | 
| 
      
 1020 
     | 
    
         
            +
                    delete this._inputs[id];        
         
     | 
| 
      
 1021 
     | 
    
         
            +
             
     | 
| 
      
 1022 
     | 
    
         
            +
                    var iframe = document.getElementById(id);
         
     | 
| 
      
 1023 
     | 
    
         
            +
                    if (iframe){
         
     | 
| 
      
 1024 
     | 
    
         
            +
                        // to cancel request set src to something else
         
     | 
| 
      
 1025 
     | 
    
         
            +
                        // we use src="javascript:false;" because it doesn't
         
     | 
| 
      
 1026 
     | 
    
         
            +
                        // trigger ie6 prompt on https
         
     | 
| 
      
 1027 
     | 
    
         
            +
                        iframe.setAttribute('src', 'javascript:false;');
         
     | 
| 
      
 1028 
     | 
    
         
            +
             
     | 
| 
      
 1029 
     | 
    
         
            +
                        qq.remove(iframe);
         
     | 
| 
      
 1030 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1031 
     | 
    
         
            +
                },     
         
     | 
| 
      
 1032 
     | 
    
         
            +
                _upload: function(id, params){                        
         
     | 
| 
      
 1033 
     | 
    
         
            +
                    var input = this._inputs[id];
         
     | 
| 
      
 1034 
     | 
    
         
            +
                    
         
     | 
| 
      
 1035 
     | 
    
         
            +
                    if (!input){
         
     | 
| 
      
 1036 
     | 
    
         
            +
                        throw new Error('file with passed id was not added, or already uploaded or cancelled');
         
     | 
| 
      
 1037 
     | 
    
         
            +
                    }                
         
     | 
| 
      
 1038 
     | 
    
         
            +
             
     | 
| 
      
 1039 
     | 
    
         
            +
                    var fileName = this.getName(id);
         
     | 
| 
      
 1040 
     | 
    
         
            +
                            
         
     | 
| 
      
 1041 
     | 
    
         
            +
                    var iframe = this._createIframe(id);
         
     | 
| 
      
 1042 
     | 
    
         
            +
                    var form = this._createForm(iframe, params);
         
     | 
| 
      
 1043 
     | 
    
         
            +
                    form.appendChild(input);
         
     | 
| 
      
 1044 
     | 
    
         
            +
             
     | 
| 
      
 1045 
     | 
    
         
            +
                    var self = this;
         
     | 
| 
      
 1046 
     | 
    
         
            +
                    this._attachLoadEvent(iframe, function(){                                 
         
     | 
| 
      
 1047 
     | 
    
         
            +
                        self.log('iframe loaded');
         
     | 
| 
      
 1048 
     | 
    
         
            +
                        
         
     | 
| 
      
 1049 
     | 
    
         
            +
                        var response = self._getIframeContentJSON(iframe);
         
     | 
| 
      
 1050 
     | 
    
         
            +
             
     | 
| 
      
 1051 
     | 
    
         
            +
                        self._options.onComplete(id, fileName, response);
         
     | 
| 
      
 1052 
     | 
    
         
            +
                        self._dequeue(id);
         
     | 
| 
      
 1053 
     | 
    
         
            +
                        
         
     | 
| 
      
 1054 
     | 
    
         
            +
                        delete self._inputs[id];
         
     | 
| 
      
 1055 
     | 
    
         
            +
                        // timeout added to fix busy state in FF3.6
         
     | 
| 
      
 1056 
     | 
    
         
            +
                        setTimeout(function(){
         
     | 
| 
      
 1057 
     | 
    
         
            +
                            qq.remove(iframe);
         
     | 
| 
      
 1058 
     | 
    
         
            +
                        }, 1);
         
     | 
| 
      
 1059 
     | 
    
         
            +
                    });
         
     | 
| 
      
 1060 
     | 
    
         
            +
             
     | 
| 
      
 1061 
     | 
    
         
            +
                    form.submit();        
         
     | 
| 
      
 1062 
     | 
    
         
            +
                    qq.remove(form);        
         
     | 
| 
      
 1063 
     | 
    
         
            +
                    
         
     | 
| 
      
 1064 
     | 
    
         
            +
                    return id;
         
     | 
| 
      
 1065 
     | 
    
         
            +
                }, 
         
     | 
| 
      
 1066 
     | 
    
         
            +
                _attachLoadEvent: function(iframe, callback){
         
     | 
| 
      
 1067 
     | 
    
         
            +
                    qq.attach(iframe, 'load', function(){
         
     | 
| 
      
 1068 
     | 
    
         
            +
                        // when we remove iframe from dom
         
     | 
| 
      
 1069 
     | 
    
         
            +
                        // the request stops, but in IE load
         
     | 
| 
      
 1070 
     | 
    
         
            +
                        // event fires
         
     | 
| 
      
 1071 
     | 
    
         
            +
                        if (!iframe.parentNode){
         
     | 
| 
      
 1072 
     | 
    
         
            +
                            return;
         
     | 
| 
      
 1073 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1074 
     | 
    
         
            +
             
     | 
| 
      
 1075 
     | 
    
         
            +
                        // fixing Opera 10.53
         
     | 
| 
      
 1076 
     | 
    
         
            +
                        if (iframe.contentDocument &&
         
     | 
| 
      
 1077 
     | 
    
         
            +
                            iframe.contentDocument.body &&
         
     | 
| 
      
 1078 
     | 
    
         
            +
                            iframe.contentDocument.body.innerHTML == "false"){
         
     | 
| 
      
 1079 
     | 
    
         
            +
                            // In Opera event is fired second time
         
     | 
| 
      
 1080 
     | 
    
         
            +
                            // when body.innerHTML changed from false
         
     | 
| 
      
 1081 
     | 
    
         
            +
                            // to server response approx. after 1 sec
         
     | 
| 
      
 1082 
     | 
    
         
            +
                            // when we upload file with iframe
         
     | 
| 
      
 1083 
     | 
    
         
            +
                            return;
         
     | 
| 
      
 1084 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1085 
     | 
    
         
            +
             
     | 
| 
      
 1086 
     | 
    
         
            +
                        callback();
         
     | 
| 
      
 1087 
     | 
    
         
            +
                    });
         
     | 
| 
      
 1088 
     | 
    
         
            +
                },
         
     | 
| 
      
 1089 
     | 
    
         
            +
                /**
         
     | 
| 
      
 1090 
     | 
    
         
            +
                 * Returns json object received by iframe from server.
         
     | 
| 
      
 1091 
     | 
    
         
            +
                 */
         
     | 
| 
      
 1092 
     | 
    
         
            +
                _getIframeContentJSON: function(iframe){
         
     | 
| 
      
 1093 
     | 
    
         
            +
                    // iframe.contentWindow.document - for IE<7
         
     | 
| 
      
 1094 
     | 
    
         
            +
                    var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
         
     | 
| 
      
 1095 
     | 
    
         
            +
                        response;
         
     | 
| 
      
 1096 
     | 
    
         
            +
                    
         
     | 
| 
      
 1097 
     | 
    
         
            +
                    this.log("converting iframe's innerHTML to JSON");
         
     | 
| 
      
 1098 
     | 
    
         
            +
                    this.log("innerHTML = " + doc.body.innerHTML);
         
     | 
| 
      
 1099 
     | 
    
         
            +
                                    
         
     | 
| 
      
 1100 
     | 
    
         
            +
                    try {
         
     | 
| 
      
 1101 
     | 
    
         
            +
                        response = eval("(" + doc.body.innerHTML + ")");
         
     | 
| 
      
 1102 
     | 
    
         
            +
                    } catch(err){
         
     | 
| 
      
 1103 
     | 
    
         
            +
                        response = {};
         
     | 
| 
      
 1104 
     | 
    
         
            +
                    }        
         
     | 
| 
      
 1105 
     | 
    
         
            +
             
     | 
| 
      
 1106 
     | 
    
         
            +
                    return response;
         
     | 
| 
      
 1107 
     | 
    
         
            +
                },
         
     | 
| 
      
 1108 
     | 
    
         
            +
                /**
         
     | 
| 
      
 1109 
     | 
    
         
            +
                 * Creates iframe with unique name
         
     | 
| 
      
 1110 
     | 
    
         
            +
                 */
         
     | 
| 
      
 1111 
     | 
    
         
            +
                _createIframe: function(id){
         
     | 
| 
      
 1112 
     | 
    
         
            +
                    // We can't use following code as the name attribute
         
     | 
| 
      
 1113 
     | 
    
         
            +
                    // won't be properly registered in IE6, and new window
         
     | 
| 
      
 1114 
     | 
    
         
            +
                    // on form submit will open
         
     | 
| 
      
 1115 
     | 
    
         
            +
                    // var iframe = document.createElement('iframe');
         
     | 
| 
      
 1116 
     | 
    
         
            +
                    // iframe.setAttribute('name', id);
         
     | 
| 
      
 1117 
     | 
    
         
            +
             
     | 
| 
      
 1118 
     | 
    
         
            +
                    var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
         
     | 
| 
      
 1119 
     | 
    
         
            +
                    // src="javascript:false;" removes ie6 prompt on https
         
     | 
| 
      
 1120 
     | 
    
         
            +
             
     | 
| 
      
 1121 
     | 
    
         
            +
                    iframe.setAttribute('id', id);
         
     | 
| 
      
 1122 
     | 
    
         
            +
             
     | 
| 
      
 1123 
     | 
    
         
            +
                    iframe.style.display = 'none';
         
     | 
| 
      
 1124 
     | 
    
         
            +
                    document.body.appendChild(iframe);
         
     | 
| 
      
 1125 
     | 
    
         
            +
             
     | 
| 
      
 1126 
     | 
    
         
            +
                    return iframe;
         
     | 
| 
      
 1127 
     | 
    
         
            +
                },
         
     | 
| 
      
 1128 
     | 
    
         
            +
                /**
         
     | 
| 
      
 1129 
     | 
    
         
            +
                 * Creates form, that will be submitted to iframe
         
     | 
| 
      
 1130 
     | 
    
         
            +
                 */
         
     | 
| 
      
 1131 
     | 
    
         
            +
                _createForm: function(iframe, params){
         
     | 
| 
      
 1132 
     | 
    
         
            +
                    // We can't use the following code in IE6
         
     | 
| 
      
 1133 
     | 
    
         
            +
                    // var form = document.createElement('form');
         
     | 
| 
      
 1134 
     | 
    
         
            +
                    // form.setAttribute('method', 'post');
         
     | 
| 
      
 1135 
     | 
    
         
            +
                    // form.setAttribute('enctype', 'multipart/form-data');
         
     | 
| 
      
 1136 
     | 
    
         
            +
                    // Because in this case file won't be attached to request
         
     | 
| 
      
 1137 
     | 
    
         
            +
                    var form = qq.toElement('<form enctype="multipart/form-data"></form>');
         
     | 
| 
      
 1138 
     | 
    
         
            +
             
     | 
| 
      
 1139 
     | 
    
         
            +
                    var queryString = qq.obj2url(params, this._options.action);
         
     | 
| 
      
 1140 
     | 
    
         
            +
                    
         
     | 
| 
      
 1141 
     | 
    
         
            +
                    form.setAttribute('method', this._options.method);
         
     | 
| 
      
 1142 
     | 
    
         
            +
                    form.setAttribute('action', queryString);
         
     | 
| 
      
 1143 
     | 
    
         
            +
                    form.setAttribute('target', iframe.name);
         
     | 
| 
      
 1144 
     | 
    
         
            +
                    form.style.display = 'none';
         
     | 
| 
      
 1145 
     | 
    
         
            +
                    document.body.appendChild(form);
         
     | 
| 
      
 1146 
     | 
    
         
            +
             
     | 
| 
      
 1147 
     | 
    
         
            +
                    return form;
         
     | 
| 
      
 1148 
     | 
    
         
            +
                }
         
     | 
| 
      
 1149 
     | 
    
         
            +
            });
         
     | 
| 
      
 1150 
     | 
    
         
            +
             
     | 
| 
      
 1151 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1152 
     | 
    
         
            +
             * Class for uploading files using xhr
         
     | 
| 
      
 1153 
     | 
    
         
            +
             * @inherits qq.UploadHandlerAbstract
         
     | 
| 
      
 1154 
     | 
    
         
            +
             */
         
     | 
| 
      
 1155 
     | 
    
         
            +
            qq.UploadHandlerXhr = function(o){
         
     | 
| 
      
 1156 
     | 
    
         
            +
                qq.UploadHandlerAbstract.apply(this, arguments);
         
     | 
| 
      
 1157 
     | 
    
         
            +
             
     | 
| 
      
 1158 
     | 
    
         
            +
                this._files = [];
         
     | 
| 
      
 1159 
     | 
    
         
            +
                this._xhrs = [];
         
     | 
| 
      
 1160 
     | 
    
         
            +
                
         
     | 
| 
      
 1161 
     | 
    
         
            +
                // current loaded size in bytes for each file 
         
     | 
| 
      
 1162 
     | 
    
         
            +
                this._loaded = [];
         
     | 
| 
      
 1163 
     | 
    
         
            +
            };
         
     | 
| 
      
 1164 
     | 
    
         
            +
             
     | 
| 
      
 1165 
     | 
    
         
            +
            // static method
         
     | 
| 
      
 1166 
     | 
    
         
            +
            qq.UploadHandlerXhr.isSupported = function(){
         
     | 
| 
      
 1167 
     | 
    
         
            +
                var input = document.createElement('input');
         
     | 
| 
      
 1168 
     | 
    
         
            +
                input.type = 'file';        
         
     | 
| 
      
 1169 
     | 
    
         
            +
                
         
     | 
| 
      
 1170 
     | 
    
         
            +
                return (
         
     | 
| 
      
 1171 
     | 
    
         
            +
                    'multiple' in input &&
         
     | 
| 
      
 1172 
     | 
    
         
            +
                    typeof File != "undefined" &&
         
     | 
| 
      
 1173 
     | 
    
         
            +
                    typeof (new XMLHttpRequest()).upload != "undefined" );       
         
     | 
| 
      
 1174 
     | 
    
         
            +
            };
         
     | 
| 
      
 1175 
     | 
    
         
            +
             
     | 
| 
      
 1176 
     | 
    
         
            +
            // @inherits qq.UploadHandlerAbstract
         
     | 
| 
      
 1177 
     | 
    
         
            +
            qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
         
     | 
| 
      
 1178 
     | 
    
         
            +
             
     | 
| 
      
 1179 
     | 
    
         
            +
            qq.extend(qq.UploadHandlerXhr.prototype, {
         
     | 
| 
      
 1180 
     | 
    
         
            +
                /**
         
     | 
| 
      
 1181 
     | 
    
         
            +
                 * Adds file to the queue
         
     | 
| 
      
 1182 
     | 
    
         
            +
                 * Returns id to use with upload, cancel
         
     | 
| 
      
 1183 
     | 
    
         
            +
                 **/    
         
     | 
| 
      
 1184 
     | 
    
         
            +
                add: function(file){
         
     | 
| 
      
 1185 
     | 
    
         
            +
                    if (!(file instanceof File)){
         
     | 
| 
      
 1186 
     | 
    
         
            +
                        throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
         
     | 
| 
      
 1187 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1188 
     | 
    
         
            +
                            
         
     | 
| 
      
 1189 
     | 
    
         
            +
                    return this._files.push(file) - 1;        
         
     | 
| 
      
 1190 
     | 
    
         
            +
                },
         
     | 
| 
      
 1191 
     | 
    
         
            +
                getName: function(id){        
         
     | 
| 
      
 1192 
     | 
    
         
            +
                    var file = this._files[id];
         
     | 
| 
      
 1193 
     | 
    
         
            +
                    // fix missing name in Safari 4
         
     | 
| 
      
 1194 
     | 
    
         
            +
                    return file.fileName != null ? file.fileName : file.name;       
         
     | 
| 
      
 1195 
     | 
    
         
            +
                },
         
     | 
| 
      
 1196 
     | 
    
         
            +
                getSize: function(id){
         
     | 
| 
      
 1197 
     | 
    
         
            +
                    var file = this._files[id];
         
     | 
| 
      
 1198 
     | 
    
         
            +
                    return file.fileSize != null ? file.fileSize : file.size;
         
     | 
| 
      
 1199 
     | 
    
         
            +
                },    
         
     | 
| 
      
 1200 
     | 
    
         
            +
                /**
         
     | 
| 
      
 1201 
     | 
    
         
            +
                 * Returns uploaded bytes for file identified by id 
         
     | 
| 
      
 1202 
     | 
    
         
            +
                 */    
         
     | 
| 
      
 1203 
     | 
    
         
            +
                getLoaded: function(id){
         
     | 
| 
      
 1204 
     | 
    
         
            +
                    return this._loaded[id] || 0; 
         
     | 
| 
      
 1205 
     | 
    
         
            +
                },
         
     | 
| 
      
 1206 
     | 
    
         
            +
                /**
         
     | 
| 
      
 1207 
     | 
    
         
            +
                 * Sends the file identified by id and additional query params to the server
         
     | 
| 
      
 1208 
     | 
    
         
            +
                 * @param {Object} params name-value string pairs
         
     | 
| 
      
 1209 
     | 
    
         
            +
                 */    
         
     | 
| 
      
 1210 
     | 
    
         
            +
                _upload: function(id, params){
         
     | 
| 
      
 1211 
     | 
    
         
            +
                    var file = this._files[id],
         
     | 
| 
      
 1212 
     | 
    
         
            +
                        name = this.getName(id),
         
     | 
| 
      
 1213 
     | 
    
         
            +
                        size = this.getSize(id);
         
     | 
| 
      
 1214 
     | 
    
         
            +
                            
         
     | 
| 
      
 1215 
     | 
    
         
            +
                    this._loaded[id] = 0;
         
     | 
| 
      
 1216 
     | 
    
         
            +
                                            
         
     | 
| 
      
 1217 
     | 
    
         
            +
                    var xhr = this._xhrs[id] = new XMLHttpRequest();
         
     | 
| 
      
 1218 
     | 
    
         
            +
                    var self = this;
         
     | 
| 
      
 1219 
     | 
    
         
            +
                                                    
         
     | 
| 
      
 1220 
     | 
    
         
            +
                    xhr.upload.onprogress = function(e){
         
     | 
| 
      
 1221 
     | 
    
         
            +
                        if (e.lengthComputable){
         
     | 
| 
      
 1222 
     | 
    
         
            +
                            self._loaded[id] = e.loaded;
         
     | 
| 
      
 1223 
     | 
    
         
            +
                            self._options.onProgress(id, name, e.loaded, e.total);
         
     | 
| 
      
 1224 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1225 
     | 
    
         
            +
                    };
         
     | 
| 
      
 1226 
     | 
    
         
            +
             
     | 
| 
      
 1227 
     | 
    
         
            +
                    xhr.onreadystatechange = function(){            
         
     | 
| 
      
 1228 
     | 
    
         
            +
                        if (xhr.readyState == 4){
         
     | 
| 
      
 1229 
     | 
    
         
            +
                            self._onComplete(id, xhr);                    
         
     | 
| 
      
 1230 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1231 
     | 
    
         
            +
                    };
         
     | 
| 
      
 1232 
     | 
    
         
            +
             
     | 
| 
      
 1233 
     | 
    
         
            +
                    // build query string
         
     | 
| 
      
 1234 
     | 
    
         
            +
                    params = params || {};
         
     | 
| 
      
 1235 
     | 
    
         
            +
                    params[this._options.fieldName] = name;
         
     | 
| 
      
 1236 
     | 
    
         
            +
                    var queryString = qq.obj2url(params, this._options.action);
         
     | 
| 
      
 1237 
     | 
    
         
            +
             
     | 
| 
      
 1238 
     | 
    
         
            +
                    xhr.open(this._options.method, queryString, true);
         
     | 
| 
      
 1239 
     | 
    
         
            +
                    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
         
     | 
| 
      
 1240 
     | 
    
         
            +
                    xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
         
     | 
| 
      
 1241 
     | 
    
         
            +
                    xhr.setRequestHeader('X-File-Size', size);
         
     | 
| 
      
 1242 
     | 
    
         
            +
                    xhr.setRequestHeader('X-File-Type', file.type);
         
     | 
| 
      
 1243 
     | 
    
         
            +
                    xhr.setRequestHeader("Content-Type", "application/octet-stream");
         
     | 
| 
      
 1244 
     | 
    
         
            +
                    
         
     | 
| 
      
 1245 
     | 
    
         
            +
                    xhr.send(file);
         
     | 
| 
      
 1246 
     | 
    
         
            +
                },
         
     | 
| 
      
 1247 
     | 
    
         
            +
                _onComplete: function(id, xhr){
         
     | 
| 
      
 1248 
     | 
    
         
            +
                    // the request was aborted/cancelled
         
     | 
| 
      
 1249 
     | 
    
         
            +
                    if (!this._files[id]) return;
         
     | 
| 
      
 1250 
     | 
    
         
            +
                    
         
     | 
| 
      
 1251 
     | 
    
         
            +
                    var name = this.getName(id);
         
     | 
| 
      
 1252 
     | 
    
         
            +
                    var size = this.getSize(id);
         
     | 
| 
      
 1253 
     | 
    
         
            +
                    
         
     | 
| 
      
 1254 
     | 
    
         
            +
                    this._options.onProgress(id, name, size, size);
         
     | 
| 
      
 1255 
     | 
    
         
            +
                            
         
     | 
| 
      
 1256 
     | 
    
         
            +
                    if ([200, 201].indexOf( xhr.status ) > -1){
         
     | 
| 
      
 1257 
     | 
    
         
            +
                        this.log("xhr - server response received");
         
     | 
| 
      
 1258 
     | 
    
         
            +
                        this.log("responseText = " + xhr.responseText);
         
     | 
| 
      
 1259 
     | 
    
         
            +
                                    
         
     | 
| 
      
 1260 
     | 
    
         
            +
                        var response;
         
     | 
| 
      
 1261 
     | 
    
         
            +
                                
         
     | 
| 
      
 1262 
     | 
    
         
            +
                        try {
         
     | 
| 
      
 1263 
     | 
    
         
            +
                            response = eval("(" + xhr.responseText + ")");
         
     | 
| 
      
 1264 
     | 
    
         
            +
                        } catch(err){
         
     | 
| 
      
 1265 
     | 
    
         
            +
                            response = {};
         
     | 
| 
      
 1266 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1267 
     | 
    
         
            +
                        
         
     | 
| 
      
 1268 
     | 
    
         
            +
                        this._options.onComplete(id, name, response);
         
     | 
| 
      
 1269 
     | 
    
         
            +
                                    
         
     | 
| 
      
 1270 
     | 
    
         
            +
                    } else {                   
         
     | 
| 
      
 1271 
     | 
    
         
            +
                        this._options.onComplete(id, name, {});
         
     | 
| 
      
 1272 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1273 
     | 
    
         
            +
                            
         
     | 
| 
      
 1274 
     | 
    
         
            +
                    this._files[id] = null;
         
     | 
| 
      
 1275 
     | 
    
         
            +
                    this._xhrs[id] = null;    
         
     | 
| 
      
 1276 
     | 
    
         
            +
                    this._dequeue(id);                    
         
     | 
| 
      
 1277 
     | 
    
         
            +
                },
         
     | 
| 
      
 1278 
     | 
    
         
            +
                _cancel: function(id){
         
     | 
| 
      
 1279 
     | 
    
         
            +
                    this._options.onCancel(id, this.getName(id));
         
     | 
| 
      
 1280 
     | 
    
         
            +
                    
         
     | 
| 
      
 1281 
     | 
    
         
            +
                    this._files[id] = null;
         
     | 
| 
      
 1282 
     | 
    
         
            +
                    
         
     | 
| 
      
 1283 
     | 
    
         
            +
                    if (this._xhrs[id]){
         
     | 
| 
      
 1284 
     | 
    
         
            +
                        this._xhrs[id].abort();
         
     | 
| 
      
 1285 
     | 
    
         
            +
                        this._xhrs[id] = null;                                   
         
     | 
| 
      
 1286 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1287 
     | 
    
         
            +
                }
         
     | 
| 
      
 1288 
     | 
    
         
            +
            });
         
     |