card-mod-format 0.14.2 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/assets/script/decko/clicks_and_hovers.js.coffee +49 -0
  3. data/assets/script/decko/decko.js.coffee +37 -0
  4. data/assets/script/decko/decko_jquery.js.coffee +25 -0
  5. data/assets/script/decko/slot.js.coffee +150 -0
  6. data/assets/script/decko/slot_ready.js.coffee +11 -0
  7. data/assets/script/decko/slotter.js.coffee +210 -0
  8. data/assets/script/jquery/jquery-ui.min.js +13 -0
  9. data/assets/script/jquery/jquery.autosize.js +274 -0
  10. data/assets/script/jquery/jquery.ui.autocomplete.html.js +41 -0
  11. data/assets/script/manifest.yml +38 -0
  12. data/assets/style/common.scss +75 -0
  13. data/assets/style/logo_and_credit.scss +24 -0
  14. data/assets/style/menu.scss +51 -0
  15. data/assets/style/messaging.scss +59 -0
  16. data/assets/style/misc.scss +86 -0
  17. data/assets/style/open_and_closed.scss +68 -0
  18. data/{locales → config/locales}/de.yml +1 -0
  19. data/{locales → config/locales}/en.yml +1 -0
  20. data/data/files/credit_image.svg +59 -0
  21. data/data/files/mod_format_script_asset_output/file.js +66 -0
  22. data/data/real.yml +67 -0
  23. data/lib/card/format/html_format.rb +0 -2
  24. data/lib/card/mod/format.rb +4 -0
  25. data/lib/card/path.rb +20 -20
  26. data/set/all/base.rb +1 -11
  27. data/set/all/content.rb +3 -11
  28. data/set/all/csv.rb +22 -74
  29. data/set/all/data.rb +12 -12
  30. data/set/all/demo.rb +6 -2
  31. data/set/all/error.rb +1 -1
  32. data/set/all/html/error.rb +2 -2
  33. data/set/all/html/head.rb +22 -12
  34. data/set/all/html/header.rb +10 -40
  35. data/set/all/html/header_wrap.haml +3 -4
  36. data/set/all/html/labeled.haml +1 -1
  37. data/set/all/html/menu.rb +45 -22
  38. data/set/all/html/views.rb +11 -28
  39. data/set/all/html/wrap.rb +5 -4
  40. data/set/all/html.rb +2 -3
  41. data/set/all/json.rb +1 -5
  42. data/set/right/head.rb +1 -0
  43. data/set/type/basic.rb +1 -1
  44. data/set/type/cardtype.rb +4 -6
  45. data/set/type/json.rb +1 -1
  46. data/set/type/number.rb +1 -16
  47. data/vendor/jquery_file_upload/LICENSE.txt +20 -0
  48. data/vendor/jquery_file_upload/README.md +224 -0
  49. data/vendor/jquery_file_upload/SECURITY.md +227 -0
  50. data/vendor/jquery_file_upload/VULNERABILITIES.md +118 -0
  51. data/vendor/jquery_file_upload/cors/postmessage.html +85 -0
  52. data/vendor/jquery_file_upload/cors/result.html +26 -0
  53. data/vendor/jquery_file_upload/css/jquery.fileupload-noscript.css +22 -0
  54. data/vendor/jquery_file_upload/css/jquery.fileupload-ui-noscript.css +17 -0
  55. data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +68 -0
  56. data/vendor/jquery_file_upload/css/jquery.fileupload.css +36 -0
  57. data/vendor/jquery_file_upload/docker-compose.yml +55 -0
  58. data/vendor/jquery_file_upload/img/loading.gif +0 -0
  59. data/vendor/jquery_file_upload/img/progressbar.gif +0 -0
  60. data/vendor/jquery_file_upload/index.html +357 -0
  61. data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +126 -0
  62. data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +97 -0
  63. data/vendor/jquery_file_upload/js/demo.js +75 -0
  64. data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +101 -0
  65. data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +347 -0
  66. data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +170 -0
  67. data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +759 -0
  68. data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +119 -0
  69. data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +101 -0
  70. data/vendor/jquery_file_upload/js/jquery.fileupload.js +1604 -0
  71. data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +227 -0
  72. data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +805 -0
  73. data/vendor/jquery_file_upload/package-lock.json +6853 -0
  74. data/vendor/jquery_file_upload/package.json +116 -0
  75. data/vendor/jquery_file_upload/server/gae-python/app.yaml +18 -0
  76. data/vendor/jquery_file_upload/server/gae-python/main.py +204 -0
  77. data/vendor/jquery_file_upload/server/gae-python/static/favicon.ico +0 -0
  78. data/vendor/jquery_file_upload/server/gae-python/static/robots.txt +2 -0
  79. data/vendor/jquery_file_upload/server/php/Dockerfile +44 -0
  80. data/vendor/jquery_file_upload/server/php/UploadHandler.php +1480 -0
  81. data/vendor/jquery_file_upload/server/php/index.php +15 -0
  82. data/vendor/jquery_file_upload/server/php/php.ini +5 -0
  83. data/vendor/jquery_file_upload/test/index.html +49 -0
  84. data/vendor/jquery_file_upload/test/unit.js +989 -0
  85. data/vendor/jquery_file_upload/test/vendor/chai.js +10854 -0
  86. data/vendor/jquery_file_upload/test/vendor/mocha.css +325 -0
  87. data/vendor/jquery_file_upload/test/vendor/mocha.js +18178 -0
  88. data/vendor/jquery_file_upload/wdio/LICENSE.txt +20 -0
  89. data/vendor/jquery_file_upload/wdio/assets/black+white-3x2.jpg +0 -0
  90. data/vendor/jquery_file_upload/wdio/assets/black+white-60x40.gif +0 -0
  91. data/vendor/jquery_file_upload/wdio/conf/chrome.js +40 -0
  92. data/vendor/jquery_file_upload/wdio/conf/firefox.js +25 -0
  93. data/vendor/jquery_file_upload/wdio/hooks/index.js +36 -0
  94. data/vendor/jquery_file_upload/wdio/test/pages/file-upload.js +79 -0
  95. data/vendor/jquery_file_upload/wdio/test/specs/01-file-upload.js +25 -0
  96. data/vendor/jquery_file_upload/wdio/wdio.conf.js +4 -0
  97. data/vendor/jquery_rails/CHANGELOG.md +359 -0
  98. data/vendor/jquery_rails/CONTRIBUTING.md +132 -0
  99. data/vendor/jquery_rails/Gemfile +22 -0
  100. data/vendor/jquery_rails/MIT-LICENSE +21 -0
  101. data/vendor/jquery_rails/README.md +75 -0
  102. data/vendor/jquery_rails/Rakefile +59 -0
  103. data/vendor/jquery_rails/VERSIONS.md +62 -0
  104. data/vendor/jquery_rails/jquery-rails.gemspec +26 -0
  105. data/vendor/jquery_rails/lib/jquery/assert_select.rb +149 -0
  106. data/vendor/jquery_rails/lib/jquery/rails/engine.rb +6 -0
  107. data/vendor/jquery_rails/lib/jquery/rails/version.rb +9 -0
  108. data/vendor/jquery_rails/lib/jquery/rails.rb +8 -0
  109. data/vendor/jquery_rails/lib/jquery-rails.rb +1 -0
  110. data/vendor/jquery_rails/test/assert_select_jquery_test.rb +85 -0
  111. data/vendor/jquery_rails/test/test_helper.rb +6 -0
  112. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.js +11008 -0
  113. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.js +5 -0
  114. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.map +1 -0
  115. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.js +9814 -0
  116. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.js +4 -0
  117. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.map +1 -0
  118. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.js +10364 -0
  119. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.js +2 -0
  120. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.map +1 -0
  121. data/vendor/jquery_rails/vendor/assets/javascripts/jquery_ujs.js +555 -0
  122. metadata +106 -9
data/set/all/html/menu.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  format :html do
2
2
  view :menu, denial: :blank, unknown: true do
3
- return "" if card.unknown?
4
-
3
+ return "" unless card.known?
4
+ # would be preferable to do this with unknown: :blank, but that fails with view
5
+ # caching on, because voo always thinks it's the root.
5
6
  wrap_with :div, class: "card-menu #{menu_link_classes}" do
6
7
  [render_help_link,
7
8
  menu_link,
8
- (voo.show?(:bridge_link) ? bridge_link(false) : nil)]
9
+ (voo.show?(:bridge_link) ? bridge_link(in_modal: false) : nil)]
9
10
  end
10
11
  end
11
12
 
@@ -35,6 +36,11 @@ format :html do
35
36
  edit_link edit_link_view
36
37
  end
37
38
 
39
+ view :edit_button do
40
+ view = voo.edit == :inline ? :edit_inline : :edit
41
+ link_to_view view, "Edit", class: "btn btn-sm btn-outline-primary me-2"
42
+ end
43
+
38
44
  def edit_link_view
39
45
  :edit
40
46
  end
@@ -47,13 +53,11 @@ format :html do
47
53
  bridge_link
48
54
  end
49
55
 
50
- def bridge_link in_modal=true
56
+ def bridge_link text: "", in_modal: true, confirm: false
51
57
  opts = { class: "bridge-link" }
52
- if in_modal
53
- # add_class opts, "close"
54
- opts["data-slotter-mode"] = "modal-replace"
55
- end
56
- link_to_view :bridge, material_icon(:more_horiz), opts
58
+ opts["data-slotter-mode"] = "modal-replace" if in_modal
59
+ confirm_edit_loss opts if confirm
60
+ link_to_view :bridge, "#{bridge_icon} #{text}", opts
57
61
  end
58
62
 
59
63
  # no caching because help_text view doesn't cache, and we can't have a
@@ -65,19 +69,15 @@ format :html do
65
69
  def help_link text=nil, title=nil
66
70
  opts = help_popover_opts text, title
67
71
  add_class opts, "_card-menu-popover"
68
- link_to help_icon, opts
72
+ link_to icon_tag(:help), opts
69
73
  end
70
74
 
71
75
  def help_popover_opts text=nil, title=nil
72
76
  text ||= render_help_text
73
- opts = { "data-placement": :left, class: "help-link" }
77
+ opts = { "data-bs-placement": :left, class: "help-link" }
74
78
  popover_opts text, title, opts
75
79
  end
76
80
 
77
- def help_icon
78
- material_icon("help")
79
- end
80
-
81
81
  def help_title
82
82
  "#{name_parts_links} (#{render_type}) #{full_page_link unless card.simple?}"
83
83
  end
@@ -88,8 +88,18 @@ format :html do
88
88
  end.join Card::Name.joint
89
89
  end
90
90
 
91
- def full_page_link
92
- link_to_card full_page_card, full_page_icon, class: classy("full-page-link")
91
+ def full_page_link text: ""
92
+ link_to_card full_page_card, "#{full_page_icon} #{text}",
93
+ class: classy("full-page-link")
94
+ end
95
+
96
+ def modal_page_link text: ""
97
+ modal_link "#{modal_icon} #{text}",
98
+ path: { mark: card }, size: modal_page_size, class: "_modal-page-link"
99
+ end
100
+
101
+ def modal_page_size
102
+ :xl
93
103
  end
94
104
 
95
105
  def full_page_card
@@ -97,12 +107,12 @@ format :html do
97
107
  end
98
108
 
99
109
  def edit_in_bridge_link opts={}
100
- edit_link :bridge, opts
110
+ edit_link :bridge, *opts
101
111
  end
102
112
 
103
- def edit_link view=:edit, opts={}
104
- link_to_view view, opts.delete(:link_text) || menu_icon,
105
- edit_link_opts(modal: (opts[:modal] || :lg))
113
+ def edit_link view=:edit, link_text: nil, text: "", modal: nil
114
+ link_to_view view, link_text || "#{menu_icon} #{text}",
115
+ edit_link_opts(modal: (modal || :lg))
106
116
  end
107
117
 
108
118
  # @param modal [Symbol] modal size
@@ -120,10 +130,23 @@ format :html do
120
130
  end
121
131
 
122
132
  def menu_icon
123
- material_icon "edit"
133
+ icon_tag "edit"
124
134
  end
125
135
 
126
136
  def full_page_icon
127
137
  icon_tag :open_in_new
128
138
  end
139
+
140
+ def modal_icon
141
+ icon_tag :modal
142
+ end
143
+
144
+ def bridge_icon
145
+ icon_tag :board
146
+ end
147
+
148
+ def confirm_edit_loss opts
149
+ add_class opts, "_confirm"
150
+ opts["data-confirm-msg"] = t(:format_confirm_edit_loss)
151
+ end
129
152
  end
@@ -1,25 +1,19 @@
1
+ # require "truncato"
2
+
1
3
  format :html do
2
4
  def prepare_content_slot
3
5
  class_up "card-slot", "d0-card-content"
4
- voo.hide :menu
5
6
  end
6
7
 
7
8
  before(:content) { prepare_content_slot }
8
9
 
9
10
  view :content do
10
- voo.hide :edit_button
11
- wrap do
12
- [_render_menu, _render_core, _render_edit_button(edit: :inline)]
13
- end
14
- end
15
-
16
- before :content_with_edit_button do
17
- prepare_content_slot
18
- end
19
-
20
- view :content_with_edit_button, unknown: true do
21
11
  wrap do
22
- [_render_menu, _render_core, _render_edit_button(edit: :inline)]
12
+ [
13
+ render_menu(optional: :hide),
14
+ render_core,
15
+ render_edit_button(optional: :hide, edit: :inline)
16
+ ]
23
17
  end
24
18
  end
25
19
 
@@ -41,7 +35,7 @@ format :html do
41
35
 
42
36
  view :content_with_title do
43
37
  wrap true, title: card.format(:text).render_core do
44
- [_render_menu, _render_core]
38
+ [render_menu, render_core]
45
39
  end
46
40
  end
47
41
 
@@ -53,7 +47,7 @@ format :html do
53
47
  view :content_panel do
54
48
  wrap do
55
49
  wrap_with :div, class: "card-body" do
56
- [_render_menu, _render_core]
50
+ [render_menu, render_core]
57
51
  end
58
52
  end
59
53
  end
@@ -69,7 +63,8 @@ format :html do
69
63
  end
70
64
  end
71
65
 
72
- view :labeled, unknown: true do
66
+ # unlike unknown: true, unknown: (same view) can be overridden
67
+ view :labeled, unknown: :labeled do
73
68
  @content_body = true
74
69
  wrap(true, class: "row") do
75
70
  labeled(render_title, wrap_body { "#{render_menu}#{render_labeled_content}" })
@@ -114,18 +109,6 @@ format :html do
114
109
  Card.fetch(set_name)
115
110
  end
116
111
 
117
- def raw_one_line_content
118
- cleaned = Card::Content.clean! render_raw, {}
119
- cut_with_ellipsis cleaned
120
- end
121
-
122
- def one_line_content
123
- # TODO: use a version of Card::Content.smart_truncate
124
- # that counts characters instead of clean!
125
- cleaned = Card::Content.clean! render_core, {}
126
- cut_with_ellipsis cleaned
127
- end
128
-
129
112
  # LOCALIZE
130
113
  def short_content
131
114
  short_content_items || short_content_fields || short_content_from_core
data/set/all/html/wrap.rb CHANGED
@@ -9,7 +9,6 @@ format :html do
9
9
  end
10
10
 
11
11
  wrapper :slot do |opts|
12
- class_up "card-slot", opts[:class] if opts[:class]
13
12
  attrib = slot_attributes true, opts
14
13
  method_wrap(:wrap_with, :div, attrib) { interior }
15
14
  end
@@ -25,7 +24,7 @@ format :html do
25
24
  end
26
25
 
27
26
  def slot_attributes slot, slot_attr
28
- { id: slot_id, class: wrap_classes(slot), data: wrap_data }.tap do |hash|
27
+ { id: slot_id, class: wrap_classes(slot), data: wrap_data(true) }.tap do |hash|
29
28
  add_class hash, slot_attr.delete(:class)
30
29
  hash.deep_merge! slot_attr
31
30
  end
@@ -35,11 +34,12 @@ format :html do
35
34
  "#{card.name.safe_key}-#{@current_view}-view"
36
35
  end
37
36
 
38
- def wrap_data slot=true
37
+ def wrap_data slot=false
39
38
  with_slot_data slot do
40
39
  {
41
40
  "card-id": card.id,
42
41
  "card-name": slot_cardname,
42
+ "card-type-id": card.type_id,
43
43
  "card-link-name": card.name.url_key,
44
44
  "slot-id": SecureRandom.hex(10)
45
45
  }
@@ -109,7 +109,8 @@ format :html do
109
109
 
110
110
  def body_css_classes
111
111
  css_classes = ["d0-card-body"]
112
- css_classes += ["d0-card-content", card.safe_set_keys] if @content_body
112
+ css_classes << "d0-card-content" if @content_body
113
+ css_classes << card.safe_set_keys if @content_body || @set_keys
113
114
  classy(*css_classes)
114
115
  end
115
116
 
data/set/all/html.rb CHANGED
@@ -9,14 +9,13 @@ format :html do
9
9
  view :type_info do
10
10
  return unless card.type_code != :basic
11
11
 
12
- wrap_with :span, class: "type-info float-right" do
12
+ wrap_with :span, class: "type-info float-end" do
13
13
  link_to_card card.type_name, nil, class: "navbar-link"
14
14
  end
15
15
  end
16
16
 
17
17
  def default_nest_view
18
- :titled
19
- # card.rule(:default_html_view) || :titled
18
+ Cardio.config.default_html_view
20
19
  end
21
20
 
22
21
  def default_item_view
data/set/all/json.rb CHANGED
@@ -40,10 +40,6 @@ format :json do
40
40
 
41
41
  private
42
42
 
43
- def request_url
44
- controller.request&.original_url || path
45
- end
46
-
47
43
  def string_with_page_details
48
44
  raw = yield
49
45
  return raw if raw.is_a? String
@@ -54,7 +50,7 @@ format :json do
54
50
  def page_details obj
55
51
  return obj unless obj.is_a? Hash
56
52
 
57
- obj.merge url: request_url, requested_at: Time.now.to_s
53
+ obj.merge url: request_url, requested_at: Time.now.utc.to_s
58
54
  end
59
55
 
60
56
  def stringify raw
data/set/right/head.rb ADDED
@@ -0,0 +1 @@
1
+ assign_type :html
data/set/type/basic.rb CHANGED
@@ -1,3 +1,3 @@
1
- def export_type
1
+ def pod_type
2
2
  nil
3
3
  end
data/set/type/cardtype.rb CHANGED
@@ -5,7 +5,7 @@ format :html do
5
5
 
6
6
  def type_formgroup args={}
7
7
  if card.cards_of_type_exist?
8
- wrap_with :div, t(:format_cards_exist, scope: "core", cardname: safe_name)
8
+ wrap_with :div, t(:core_cards_exist, scope: "core", cardname: safe_name)
9
9
  else
10
10
  super
11
11
  end
@@ -50,7 +50,7 @@ format :html do
50
50
  end
51
51
 
52
52
  # don't cache because it depends on update permission for another card
53
- view :configure_link, cache: :never, perms: ->(fmt) { fmt.can_configure? } do
53
+ view :configure_link, cache: :never, perms: :can_configure? do
54
54
  configure_link
55
55
  end
56
56
 
@@ -58,9 +58,7 @@ format :html do
58
58
  Card.fetch(card, :type, :structure, new: {}).ok? :update
59
59
  end
60
60
 
61
- view :configure_button, cache: :never,
62
- denial: :blank,
63
- perms: ->(fmt) { fmt.can_configure? } do
61
+ view :configure_button, cache: :never, denial: :blank, perms: :can_configure? do
64
62
  configure_link "btn btn-secondary"
65
63
  end
66
64
 
@@ -73,7 +71,7 @@ format :html do
73
71
  path: { view: :bridge,
74
72
  bridge: { tab: :rules_tab },
75
73
  set: Card::Name[safe_name, :type] },
76
- class: css_classes("configure-type-link ml-3", css_class)
74
+ class: css_classes("configure-type-link ms-3", css_class)
77
75
  end
78
76
 
79
77
  private
data/set/type/json.rb CHANGED
@@ -11,7 +11,7 @@ rescue JSON::ParserError => e
11
11
  end
12
12
 
13
13
  def parse_content
14
- JSON.parse content
14
+ content.blank? ? "" : JSON.parse(content)
15
15
  end
16
16
 
17
17
  def item_names _args={}
data/set/type/number.rb CHANGED
@@ -5,20 +5,5 @@ format :html do
5
5
  end
6
6
 
7
7
  event :validate_number, :validate, on: :save do
8
- unless valid_number?(content)
9
- errors.add :content,
10
- t(:format_not_numeric, content: content)
11
- end
12
- end
13
-
14
- def valid_number? string
15
- return true if string.empty?
16
-
17
- valid = true
18
- begin
19
- Kernel.Float(string)
20
- rescue ArgumentError, TypeError
21
- valid = false
22
- end
23
- valid
8
+ errors.add :content, t(:format_not_numeric, content: content) unless content.number?
24
9
  end
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright © 2010 Sebastian Tschan, https://blueimp.net
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,224 @@
1
+ # jQuery File Upload
2
+
3
+ ## Contents
4
+
5
+ - [Description](#description)
6
+ - [Demo](#demo)
7
+ - [Features](#features)
8
+ - [Security](#security)
9
+ - [Setup](#setup)
10
+ - [Requirements](#requirements)
11
+ - [Mandatory requirements](#mandatory-requirements)
12
+ - [Optional requirements](#optional-requirements)
13
+ - [Cross-domain requirements](#cross-domain-requirements)
14
+ - [Browsers](#browsers)
15
+ - [Desktop browsers](#desktop-browsers)
16
+ - [Mobile browsers](#mobile-browsers)
17
+ - [Extended browser support information](#extended-browser-support-information)
18
+ - [Testing](#testing)
19
+ - [Support](#support)
20
+ - [License](#license)
21
+
22
+ ## Description
23
+
24
+ > File Upload widget with multiple file selection, drag&drop support, progress
25
+ > bars, validation and preview images, audio and video for jQuery.
26
+ > Supports cross-domain, chunked and resumable file uploads and client-side
27
+ > image resizing.
28
+ > Works with any server-side platform (PHP, Python, Ruby on Rails, Java,
29
+ > Node.js, Go etc.) that supports standard HTML form file uploads.
30
+
31
+ ## Demo
32
+
33
+ [Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)
34
+
35
+ ## Features
36
+
37
+ - **Multiple file upload:**
38
+ Allows to select multiple files at once and upload them simultaneously.
39
+ - **Drag & Drop support:**
40
+ Allows to upload files by dragging them from your desktop or file manager and
41
+ dropping them on your browser window.
42
+ - **Upload progress bar:**
43
+ Shows a progress bar indicating the upload progress for individual files and
44
+ for all uploads combined.
45
+ - **Cancelable uploads:**
46
+ Individual file uploads can be canceled to stop the upload progress.
47
+ - **Resumable uploads:**
48
+ Aborted uploads can be resumed with browsers supporting the Blob API.
49
+ - **Chunked uploads:**
50
+ Large files can be uploaded in smaller chunks with browsers supporting the
51
+ Blob API.
52
+ - **Client-side image resizing:**
53
+ Images can be automatically resized on client-side with browsers supporting
54
+ the required JS APIs.
55
+ - **Preview images, audio and video:**
56
+ A preview of image, audio and video files can be displayed before uploading
57
+ with browsers supporting the required APIs.
58
+ - **No browser plugins (e.g. Adobe Flash) required:**
59
+ The implementation is based on open standards like HTML5 and JavaScript and
60
+ requires no additional browser plugins.
61
+ - **Graceful fallback for legacy browsers:**
62
+ Uploads files via XMLHttpRequests if supported and uses iframes as fallback
63
+ for legacy browsers.
64
+ - **HTML file upload form fallback:**
65
+ Allows progressive enhancement by using a standard HTML file upload form as
66
+ widget element.
67
+ - **Cross-site file uploads:**
68
+ Supports uploading files to a different domain with cross-site XMLHttpRequests
69
+ or iframe redirects.
70
+ - **Multiple plugin instances:**
71
+ Allows to use multiple plugin instances on the same webpage.
72
+ - **Customizable and extensible:**
73
+ Provides an API to set individual options and define callback methods for
74
+ various upload events.
75
+ - **Multipart and file contents stream uploads:**
76
+ Files can be uploaded as standard "multipart/form-data" or file contents
77
+ stream (HTTP PUT file upload).
78
+ - **Compatible with any server-side application platform:**
79
+ Works with any server-side platform (PHP, Python, Ruby on Rails, Java,
80
+ Node.js, Go etc.) that supports standard HTML form file uploads.
81
+
82
+ ## Security
83
+
84
+ ⚠️ Please read the [VULNERABILITIES](VULNERABILITIES.md) document for a list of
85
+ fixed vulnerabilities
86
+
87
+ Please also read the [SECURITY](SECURITY.md) document for instructions on how to
88
+ securely configure your Web server for file uploads.
89
+
90
+ ## Setup
91
+
92
+ jQuery File Upload can be installed via [NPM](https://www.npmjs.com/):
93
+
94
+ ```sh
95
+ npm install blueimp-file-upload
96
+ ```
97
+
98
+ This allows you to include [jquery.fileupload.js](js/jquery.fileupload.js) and
99
+ its extensions via `node_modules`, e.g:
100
+
101
+ ```html
102
+ <script src="node_modules/blueimp-file-upload/js/jquery.fileupload.js"></script>
103
+ ```
104
+
105
+ The widget can then be initialized on a file upload form the following way:
106
+
107
+ ```js
108
+ $('#fileupload').fileupload();
109
+ ```
110
+
111
+ For further information, please refer to the following guides:
112
+
113
+ - [Main documentation page](https://github.com/blueimp/jQuery-File-Upload/wiki)
114
+ - [List of all available Options](https://github.com/blueimp/jQuery-File-Upload/wiki/Options)
115
+ - [The plugin API](https://github.com/blueimp/jQuery-File-Upload/wiki/API)
116
+ - [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
117
+ - [How to use only the basic plugin.](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)
118
+
119
+ ## Requirements
120
+
121
+ ### Mandatory requirements
122
+
123
+ - [jQuery](https://jquery.com/) v1.7+
124
+ - [jQuery UI widget factory](https://api.jqueryui.com/jQuery.widget/) v1.9+
125
+ (included): Required for the basic File Upload plugin, but very lightweight
126
+ without any other dependencies from the jQuery UI suite.
127
+ - [jQuery Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js)
128
+ (included): Required for
129
+ [browsers without XHR file upload support](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).
130
+
131
+ ### Optional requirements
132
+
133
+ - [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates)
134
+ v3+: Used to render the selected and uploaded files.
135
+ - [JavaScript Load Image library](https://github.com/blueimp/JavaScript-Load-Image)
136
+ v2+: Required for the image previews and resizing functionality.
137
+ - [JavaScript Canvas to Blob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob)
138
+ v3+:Required for the resizing functionality.
139
+ - [blueimp Gallery](https://github.com/blueimp/Gallery) v2+: Used to display the
140
+ uploaded images in a lightbox.
141
+ - [Bootstrap](https://getbootstrap.com/) v3+: Used for the demo design.
142
+ - [Glyphicons](https://glyphicons.com/) Icon set used by Bootstrap.
143
+
144
+ ### Cross-domain requirements
145
+
146
+ [Cross-domain File Uploads](https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads)
147
+ using the
148
+ [Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js)
149
+ require a redirect back to the origin server to retrieve the upload results. The
150
+ [example implementation](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/main.js)
151
+ makes use of
152
+ [result.html](https://github.com/blueimp/jQuery-File-Upload/blob/master/cors/result.html)
153
+ as a static redirect page for the origin server.
154
+
155
+ The repository also includes the
156
+ [jQuery XDomainRequest Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/cors/jquery.xdr-transport.js),
157
+ which enables limited cross-domain AJAX requests in Microsoft Internet Explorer
158
+ 8 and 9 (IE 10 supports cross-domain XHR requests).
159
+ The XDomainRequest object allows GET and POST requests only and doesn't support
160
+ file uploads. It is used on the
161
+ [Demo](https://blueimp.github.io/jQuery-File-Upload/) to delete uploaded files
162
+ from the cross-domain demo file upload service.
163
+
164
+ ## Browsers
165
+
166
+ ### Desktop browsers
167
+
168
+ The File Upload plugin is regularly tested with the latest browser versions and
169
+ supports the following minimal versions:
170
+
171
+ - Google Chrome
172
+ - Apple Safari 4.0+
173
+ - Mozilla Firefox 3.0+
174
+ - Opera 11.0+
175
+ - Microsoft Internet Explorer 6.0+
176
+
177
+ ### Mobile browsers
178
+
179
+ The File Upload plugin has been tested with and supports the following mobile
180
+ browsers:
181
+
182
+ - Apple Safari on iOS 6.0+
183
+ - Google Chrome on iOS 6.0+
184
+ - Google Chrome on Android 4.0+
185
+ - Default Browser on Android 2.3+
186
+ - Opera Mobile 12.0+
187
+
188
+ ### Extended browser support information
189
+
190
+ For a detailed overview of the features supported by each browser version and
191
+ known operating system / browser bugs, please have a look at the
192
+ [Extended browser support information](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).
193
+
194
+ ## Testing
195
+
196
+ The project comes with three sets of tests:
197
+
198
+ 1. Code linting using [ESLint](https://eslint.org/).
199
+ 2. Unit tests using [Mocha](https://mochajs.org/).
200
+ 3. End-to-end tests using [blueimp/wdio](https://github.com/blueimp/wdio).
201
+
202
+ To run the tests, follow these steps:
203
+
204
+ 1. Start [Docker](https://docs.docker.com/).
205
+ 2. Install development dependencies:
206
+ ```sh
207
+ npm install
208
+ ```
209
+ 3. Run the tests:
210
+ ```sh
211
+ npm test
212
+ ```
213
+
214
+ ## Support
215
+
216
+ This project is actively maintained, but there is no official support channel.
217
+ If you have a question that another developer might help you with, please post
218
+ to
219
+ [Stack Overflow](https://stackoverflow.com/questions/tagged/blueimp+jquery+file-upload)
220
+ and tag your question with `blueimp jquery file upload`.
221
+
222
+ ## License
223
+
224
+ Released under the [MIT license](https://opensource.org/licenses/MIT).