rails_design 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +18 -0
  4. data/Rakefile +18 -0
  5. data/app/assets/images/image-square.png +0 -0
  6. data/app/assets/images/logo.png +0 -0
  7. data/app/assets/javascripts/default_form/datetime.js +31 -0
  8. data/app/assets/javascripts/default_form/default_valid.js +101 -0
  9. data/app/assets/javascripts/default_form/field.js +33 -0
  10. data/app/assets/javascripts/default_form/index.js +9 -0
  11. data/app/assets/javascripts/default_form/valid_weui.js +17 -0
  12. data/app/assets/javascripts/rails_design/attachment.js +295 -0
  13. data/app/assets/javascripts/rails_design/cable.js +3 -0
  14. data/app/assets/javascripts/rails_design/dataset.js +39 -0
  15. data/app/assets/javascripts/rails_design/index.js +4 -0
  16. data/app/assets/javascripts/rails_design/stimulus.js +19 -0
  17. data/app/assets/javascripts/rails_design/turbo.js +35 -0
  18. data/app/assets/javascripts/stimulus_com/checkbox.js +77 -0
  19. data/app/assets/javascripts/stimulus_com/choice.js +18 -0
  20. data/app/assets/javascripts/stimulus_com/common.js +52 -0
  21. data/app/assets/javascripts/stimulus_com/count_down.js +27 -0
  22. data/app/assets/javascripts/stimulus_com/former.js +26 -0
  23. data/app/assets/javascripts/stimulus_com/hover.js +40 -0
  24. data/app/assets/javascripts/stimulus_com/index.js +58 -0
  25. data/app/assets/javascripts/stimulus_com/input.js +36 -0
  26. data/app/assets/javascripts/stimulus_com/menu.js +34 -0
  27. data/app/assets/javascripts/stimulus_com/modal.js +85 -0
  28. data/app/assets/javascripts/stimulus_com/modal_show.js +16 -0
  29. data/app/assets/javascripts/stimulus_com/navbar.js +11 -0
  30. data/app/assets/javascripts/stimulus_com/notice.js +10 -0
  31. data/app/assets/javascripts/stimulus_com/picture.js +85 -0
  32. data/app/assets/javascripts/stimulus_com/show.js +26 -0
  33. data/app/assets/javascripts/stimulus_com/showcase.js +34 -0
  34. data/app/assets/javascripts/stimulus_com/slide.js +188 -0
  35. data/app/assets/javascripts/stimulus_com/slide_y.js +189 -0
  36. data/app/assets/javascripts/stimulus_com/sortable.js +41 -0
  37. data/app/assets/javascripts/stimulus_com/sticky.js +11 -0
  38. data/app/assets/javascripts/stimulus_com/swipe.js +78 -0
  39. data/app/assets/javascripts/stimulus_com/taxon.js +45 -0
  40. data/app/assets/javascripts/stimulus_com/time.js +19 -0
  41. data/app/assets/javascripts/stimulus_com/touch.js +83 -0
  42. data/app/assets/javascripts/stimulus_com/tree.js +34 -0
  43. data/app/assets/javascripts/stimulus_com/tree_remote.js +64 -0
  44. data/app/assets/javascripts/stimulus_com/typer.js +41 -0
  45. data/app/assets/javascripts/stimulus_com/visit.js +61 -0
  46. data/app/assets/javascripts/stimulus_phone/index.js +19 -0
  47. data/app/assets/javascripts/stimulus_phone/qq_map.js +29 -0
  48. data/app/assets/javascripts/stimulus_phone/search.js +37 -0
  49. data/app/assets/javascripts/stimulus_phone/wechat.js +80 -0
  50. data/app/assets/javascripts/stimulus_phone/weui-actionsheet.js +43 -0
  51. data/app/assets/javascripts/stimulus_phone/weui-datepicker.js +38 -0
  52. data/app/assets/javascripts/stimulus_phone/weui-dialog.js +24 -0
  53. data/app/assets/javascripts/stimulus_phone/weui-picker.js +54 -0
  54. data/app/assets/javascripts/stimulus_phone/wxpay.js +29 -0
  55. data/app/assets/stylesheets/app.scss +3 -0
  56. data/app/assets/stylesheets/ext_bulma/base/_all.scss +5 -0
  57. data/app/assets/stylesheets/ext_bulma/base/_choices.scss +3 -0
  58. data/app/assets/stylesheets/ext_bulma/base/_global.scss +19 -0
  59. data/app/assets/stylesheets/ext_bulma/base/_main.scss +15 -0
  60. data/app/assets/stylesheets/ext_bulma/components/_all.scss +10 -0
  61. data/app/assets/stylesheets/ext_bulma/components/_box.scss +15 -0
  62. data/app/assets/stylesheets/ext_bulma/components/_breadcrumb.scss +17 -0
  63. data/app/assets/stylesheets/ext_bulma/components/_card.scss +12 -0
  64. data/app/assets/stylesheets/ext_bulma/components/_level.scss +8 -0
  65. data/app/assets/stylesheets/ext_bulma/components/_media.scss +14 -0
  66. data/app/assets/stylesheets/ext_bulma/components/_menu.scss +76 -0
  67. data/app/assets/stylesheets/ext_bulma/components/_pagination.scss +9 -0
  68. data/app/assets/stylesheets/ext_bulma/components/_panel.scss +5 -0
  69. data/app/assets/stylesheets/ext_bulma/elements/_all.scss +7 -0
  70. data/app/assets/stylesheets/ext_bulma/elements/_button.scss +14 -0
  71. data/app/assets/stylesheets/ext_bulma/elements/_fa.scss +4 -0
  72. data/app/assets/stylesheets/ext_bulma/elements/_image.scss +38 -0
  73. data/app/assets/stylesheets/ext_bulma/elements/_table.scss +52 -0
  74. data/app/assets/stylesheets/ext_bulma/elements/_title.scss +9 -0
  75. data/app/assets/stylesheets/ext_bulma/expand/_all.scss +2 -0
  76. data/app/assets/stylesheets/ext_bulma/expand/_slide.scss +26 -0
  77. data/app/assets/stylesheets/ext_bulma/expand/_sortable.scss +4 -0
  78. data/app/assets/stylesheets/ext_bulma/form/_all.scss +34 -0
  79. data/app/assets/stylesheets/ext_bulma/form/_checkbox.scss +267 -0
  80. data/app/assets/stylesheets/ext_bulma/form/_file.scss +23 -0
  81. data/app/assets/stylesheets/ext_bulma/form/_select.scss +5 -0
  82. data/app/assets/stylesheets/ext_bulma/form/_tools.scss +30 -0
  83. data/app/assets/stylesheets/ext_bulma/grid/_all.scss +3 -0
  84. data/app/assets/stylesheets/ext_bulma/grid/_columns.scss +13 -0
  85. data/app/assets/stylesheets/ext_bulma/helpers/_all.scss +5 -0
  86. data/app/assets/stylesheets/ext_bulma/helpers/_dot.scss +11 -0
  87. data/app/assets/stylesheets/ext_bulma/helpers/_drawable.scss +3 -0
  88. data/app/assets/stylesheets/ext_bulma/helpers/_grid.scss +10 -0
  89. data/app/assets/stylesheets/ext_bulma/index.scss +22 -0
  90. data/app/assets/stylesheets/ext_bulma/layout/_all.scss +4 -0
  91. data/app/assets/stylesheets/ext_bulma/layout/_footer.scss +4 -0
  92. data/app/assets/stylesheets/ext_bulma/layout/_level.scss +1 -0
  93. data/app/assets/stylesheets/ext_choices/index.scss +16 -0
  94. data/app/assets/stylesheets/ext_font/index.scss +4 -0
  95. data/app/assets/stylesheets/ext_weui/index.scss +24 -0
  96. data/app/assets/stylesheets/ext_weui/widget/_actionsheet.scss +3 -0
  97. data/app/assets/stylesheets/ext_weui/widget/_article.scss +7 -0
  98. data/app/assets/stylesheets/ext_weui/widget/_button.scss +7 -0
  99. data/app/assets/stylesheets/ext_weui/widget/_cell.scss +17 -0
  100. data/app/assets/stylesheets/ext_weui/widget/_form.scss +3 -0
  101. data/app/assets/stylesheets/ext_weui/widget/_half_screen_dialog.scss +10 -0
  102. data/app/assets/stylesheets/ext_weui/widget/_icon.scss +9 -0
  103. data/app/assets/stylesheets/ext_weui/widget/_media.scss +43 -0
  104. data/app/assets/stylesheets/ext_weui/widget/_panel.scss +4 -0
  105. data/app/assets/stylesheets/ext_weui/widget/_preview.scss +5 -0
  106. data/app/assets/stylesheets/ext_weui/widget/_search.scss +5 -0
  107. data/app/assets/stylesheets/ext_weui/widget/_tab.scss +10 -0
  108. data/app/assets/stylesheets/ext_weui/widget/_tabbar.scss +12 -0
  109. data/app/assets/stylesheets/ext_weui/widget/_uploader.scss +14 -0
  110. data/app/assets/stylesheets/phone.scss +6 -0
  111. data/app/assets/stylesheets/slide/index.scss +208 -0
  112. data/app/assets/stylesheets/ui_tooltip/_mixins.scss +46 -0
  113. data/app/assets/stylesheets/ui_tooltip/_variables.scss +5 -0
  114. data/app/assets/stylesheets/ui_tooltip/index.scss +278 -0
  115. data/app/controllers/design/base_controller.rb +4 -0
  116. data/app/controllers/design/home_controller.rb +13 -0
  117. data/app/views/design/home/swipe.html.erb +7 -0
  118. data/app/views/layouts/ui/base.html.erb +5 -0
  119. data/config/routes.rb +11 -0
  120. data/lib/rails_design/config.rb +8 -0
  121. data/lib/rails_design/engine.rb +5 -0
  122. data/lib/rails_design.rb +2 -0
  123. metadata +181 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2be348b3116b5dd3a69e1ffe60ca2ccebf355cfa8b97a71bedb65ca9fc9a53af
4
+ data.tar.gz: c522568def1eb5e290ab2236b318205bc303714f29a2243a67c7864e0a5450ed
5
+ SHA512:
6
+ metadata.gz: f1087f76b800686f4fdc6d7b25f153a898e1c8b64ee7615ae7e5c6013df4c5d37ab2e6a2a3969171817df06301d166cc9c28204ee2e02971859b354ede0abcb3
7
+ data.tar.gz: e470d05f89c365b9ada4320c5f121b5411c780fafbbf955ef961976b8b271038d9b209663e77fb5f882b3567a8c315d65e7172e8cf2011731449aee9602715b1
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2020-Present Mingyuan Qin <mingyuan0715@foxmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # RailsDesign
2
+
3
+ [![测试](https://github.com/work-design/rails_design/actions/workflows/test.yml/badge.svg)](https://github.com/work-design/rails_design/actions/workflows/test.yml)
4
+ [![Docker构建](https://github.com/work-design/rails_design/actions/workflows/cd.yml/badge.svg)](https://github.com/work-design/rails_design/actions/workflows/cd.yml)
5
+ [![Gem](https://github.com/work-design/rails_design/actions/workflows/gempush.yml/badge.svg)](https://github.com/work-design/rails_design/actions/workflows/gempush.yml)
6
+
7
+ ## 约定
8
+
9
+ * 可以 import:
10
+ * app/assets 下的文件
11
+ * entry(rollup input)
12
+ * app/javascripts 下的文件进入
13
+
14
+ ## 开发
15
+ * 采用[viter](https://github.com/vitejs/vite)
16
+
17
+ * 不再支持 [webpacker](https://github.com/rails/webpacker)
18
+ * 不再支持 [sprockets](https://github.com/rails/sprockets)
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
9
+
10
+ require "rake/testtask"
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
17
+
18
+ task default: :test
Binary file
Binary file
@@ -0,0 +1,31 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+
5
+ // data-action="datetime#default"
6
+ default(event) {
7
+ let el = event.currentTarget
8
+ let date = new Date(el.value)
9
+ let form = el.form
10
+
11
+ this.append(form, el.name.replace('(date)', '(1i)'), date.getFullYear())
12
+ this.append(form, el.name.replace('(date)', '(2i)'), date.getMonth() + 1)
13
+ this.append(form, el.name.replace('(date)', '(3i)'), date.getDate())
14
+ }
15
+
16
+ append(form, name, value) {
17
+ let input = form.elements.namedItem(name)
18
+ if (input) {
19
+ input.setAttribute('value', value)
20
+ } else {
21
+ input = document.createElement('input')
22
+ input.setAttribute('type', 'hidden')
23
+ input.setAttribute('name', name)
24
+ input.setAttribute('value', value)
25
+
26
+ this.element.appendChild(input)
27
+ }
28
+ }
29
+
30
+ }
31
+
@@ -0,0 +1,101 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+
5
+ defaultValid(input) {
6
+ let label
7
+ let locale = document.querySelector('html').lang
8
+ let word
9
+ const i18ns = {
10
+ zh: {
11
+ badInput: '{label}格式不正确',
12
+ customError: '{label}输入错误',
13
+ patternMismatch: '非法的{label}',
14
+ rangeOverflow: '{label}输入错误',
15
+ rangeUnderflow: '{label}输入错误',
16
+ stepMismatch: '{label}输入错误',
17
+ tooLong: '{label}太长了',
18
+ tooShort: '{label}太短了',
19
+ typeMismatch: '{label}输入错误',
20
+ valid: '{label}为非法值',
21
+ valueMissing: '请输入{label}'
22
+ },
23
+ en: {
24
+ badInput: 'Bad Input: {label}',
25
+ customError: 'Custom Error: {label}',
26
+ patternMismatch: 'Invalid Input: {label}',
27
+ rangeOverflow: 'Range Over Flow: {label}',
28
+ rangeUnderflow: 'Range Under Flow: {label}',
29
+ stepMismatch: 'Step Mismatch',
30
+ tooLong: '{label} is too long',
31
+ tooShort: '{label} is Too Short',
32
+ typeMismatch: '{label} Type Mismatch',
33
+ valid: '{label} is not valid',
34
+ valueMissing: 'Please enter: {label}'
35
+ }
36
+ }
37
+
38
+ for (let key in input.validity) {
39
+ if (input.validity[key]) {
40
+ word = i18ns[locale][key]
41
+ }
42
+ }
43
+
44
+ if (input.labels.length > 0) {
45
+ label = input.labels[0].innerText
46
+ } else {
47
+ label = input.dataset['label']
48
+ }
49
+ let text = word.replace('{label}', label)
50
+
51
+ input.classList.add('is-danger')
52
+ if (!input.parentNode.nextElementSibling) {
53
+ let help = document.createElement('p')
54
+ help.classList.add('help', 'is-danger')
55
+ help.innerText = text
56
+ input.parentNode.after(help)
57
+ }
58
+ }
59
+
60
+ defaultClear(input) {
61
+ if (input.validity.valid) {
62
+ input.classList.remove('is-danger')
63
+ let help = input.parentNode.nextElementSibling
64
+ if (help && help.classList.contains('help') && help.classList.contains('is-danger')) {
65
+ help.remove()
66
+ }
67
+ }
68
+ }
69
+
70
+ // data-action="blur->default_valid#check"
71
+ check(event) {
72
+ event.currentTarget.checkValidity()
73
+ }
74
+
75
+ clear(event) {
76
+ this.defaultClear(event.currentTarget)
77
+ }
78
+
79
+ // data-action="invalid->default_valid#notice"
80
+ notice(event) {
81
+ event.preventDefault()
82
+ this.defaultValid(event.currentTarget)
83
+ }
84
+
85
+ // form[method="get"]
86
+ // submit->xx
87
+ filter(event) {
88
+ event.preventDefault()
89
+ let url = new URL(location)
90
+ let form = new FormData(event.currentTarget)
91
+
92
+ for (let el of form.entries()) {
93
+ if (el[1].length > 0) {
94
+ url.searchParams.set(el[0], el[1])
95
+ }
96
+ }
97
+
98
+ Turbo.visit(url.href)
99
+ }
100
+
101
+ }
@@ -0,0 +1,33 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+ static targets = ['node']
5
+ static values = {
6
+ index: Number
7
+ }
8
+
9
+ // data-action="click->field#add"
10
+ add(event) {
11
+ let el = this.element.cloneNode(true)
12
+ let label = el.querySelector('label')
13
+ if (label) {
14
+ label.remove()
15
+ }
16
+ let nextIndex = this.indexValue + Math.random() // todo find an better implement
17
+ el.setAttribute('data-field-index-value', nextIndex)
18
+ el.querySelectorAll('input, select').forEach(input => {
19
+ input.name = input.name.replace(`[${this.indexValue}]`, `[${nextIndex}]`)
20
+ input.id = input.id.replace(`${this.indexValue}`, `${nextIndex}`)
21
+ input.value = null
22
+ })
23
+
24
+ if (this.element.parentNode) {
25
+ this.element.parentNode.insertBefore(el, this.element.nextSibling)
26
+ }
27
+ }
28
+
29
+ remove() {
30
+ this.element.remove()
31
+ }
32
+
33
+ }
@@ -0,0 +1,9 @@
1
+ import DefaultValidController from './default_valid'
2
+ import DatetimeController from './datetime'
3
+ import FieldController from './field'
4
+ import WeuiFormController from './valid_weui'
5
+
6
+ application.register('field', FieldController)
7
+ application.register('datetime', DatetimeController)
8
+ application.register('default_valid', DefaultValidController)
9
+ application.register('weui_form', WeuiFormController)
@@ -0,0 +1,17 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+
5
+ validForm() {
6
+ let node = this.parentNode.parentNode
7
+ node.classList.add('weui-cell_warn')
8
+ node.insertAdjacentHTML('beforeend', '<i class="weui-icon-warn"></i>')
9
+ }
10
+
11
+ clearValid () {
12
+ let node = this.parentNode
13
+ node.parentNode.classList.remove('weui-cell_warn')
14
+ node.nextElementSibling.remove()
15
+ }
16
+
17
+ }
@@ -0,0 +1,295 @@
1
+ /*
2
+ * Input Field with Attachment
3
+ */
4
+
5
+ export default class InputAttachment {
6
+
7
+ /**
8
+ * Default configuration options
9
+ *
10
+ * @type {Object}
11
+ */
12
+ static defaults = {
13
+ /**
14
+ * URL where the file will be send
15
+ */
16
+ uploadUrl: 'upload_attachment.php',
17
+
18
+ /**
19
+ * Which method will be used to send the file to the upload URL
20
+ */
21
+ uploadMethod: 'POST',
22
+
23
+ /**
24
+ * Name in which the file will be placed
25
+ */
26
+ uploadFieldName: 'file',
27
+
28
+ uploadFileInput: '',
29
+
30
+ templateDiv: 'file_template',
31
+
32
+ /**
33
+ * Extension which will be used when a file extension could not
34
+ * be detected
35
+ */
36
+ defaultExtension: 'png',
37
+
38
+ /**
39
+ * JSON field which refers to the uploaded file URL
40
+ */
41
+ jsonFieldName: 'filename',
42
+
43
+ /**
44
+ * Allowed MIME types
45
+ */
46
+ allowedTypes: [
47
+ 'image/jpeg',
48
+ 'image/png',
49
+ 'image/jpg',
50
+ 'image/gif'
51
+ ],
52
+
53
+ /**
54
+ * Text which will be inserted when dropping or pasting a file.
55
+ * Acts as a placeholder which will be replaced when the file is done with uploading
56
+ */
57
+ progressText: '![Uploading file...]()',
58
+
59
+ /**
60
+ * When a file has successfully been uploaded the progressText
61
+ * will be replaced by the urlText, the {filename} tag will be replaced
62
+ * by the filename that has been returned by the server
63
+ */
64
+ urlText: "![file]({filename})",
65
+
66
+ /**
67
+ * Text which will be used when uploading has failed
68
+ */
69
+ errorText: 'Error uploading file',
70
+
71
+ /**
72
+ * Extra parameters which will be send when uploading a file
73
+ */
74
+ extraParams: {},
75
+
76
+ /**
77
+ * Extra headers which will be send when uploading a file
78
+ */
79
+ extraHeaders: {},
80
+
81
+ /**
82
+ * Before the file is send
83
+ */
84
+ beforeFileUpload() {
85
+ return true;
86
+ },
87
+
88
+ /**
89
+ * Triggers when a file is dropped or pasted
90
+ */
91
+ onFileReceived() {
92
+
93
+ },
94
+
95
+ /**
96
+ * Custom upload handler
97
+ *
98
+ * @return {Boolean} when false is returned it will prevent default upload behavior
99
+ */
100
+ onFileUploadResponse() {
101
+ return true;
102
+ },
103
+
104
+ /**
105
+ * Custom error handler. Runs after removing the placeholder text and before the alert().
106
+ * Return false from this function to prevent the alert dialog.
107
+ *
108
+ * @return {Boolean} when false is returned it will prevent default error behavior
109
+ */
110
+ onFileUploadError() {
111
+ return true;
112
+ },
113
+
114
+ /**
115
+ * When a file has successfully been uploaded
116
+ */
117
+ onFileUploaded() {}
118
+ };
119
+
120
+ constructor(options) {
121
+ this.settings = Object.assign(InputAttachment.defaults, options);
122
+ this.editor = this.settings['editor'];
123
+ this.filenameTag = '{filename}';
124
+ this.lastValue = null;
125
+ };
126
+
127
+ /**
128
+ * Uploads the blob
129
+ *
130
+ * @param {Blob} file blob data received from event.dataTransfer object
131
+ * @return {XMLHttpRequest} request object which sends the file
132
+ */
133
+ uploadFile(file) {
134
+ let me = this
135
+ let formData = new FormData()
136
+ let xhr = new XMLHttpRequest()
137
+ let settings = this.settings
138
+ let extension = settings.defaultExtension
139
+
140
+ if (typeof settings.setupFormData === 'function') {
141
+ settings.setupFormData(formData, file);
142
+ }
143
+
144
+ // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
145
+ // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
146
+ if (file.name) {
147
+ var fileNameMatches = file.name.match(/\.(.+)$/);
148
+ if (fileNameMatches) {
149
+ extension = fileNameMatches[1];
150
+ }
151
+ }
152
+
153
+ var remoteFilename = 'image-' + Date.now() + '.' + extension;
154
+ if (typeof settings.remoteFilename === 'function') {
155
+ remoteFilename = settings.remoteFilename(file);
156
+ }
157
+
158
+ formData.append(settings.uploadFieldName, file, remoteFilename);
159
+
160
+ // Append the extra parameters to the form data
161
+ if (typeof settings.extraParams === 'object') {
162
+ for (var key in settings.extraParams) {
163
+ if (settings.extraParams.hasOwnProperty(key)) {
164
+ formData.append(key, settings.extraParams[key]);
165
+ }
166
+ }
167
+ }
168
+
169
+ xhr.open('POST', settings.uploadUrl);
170
+
171
+ // Add any available extra headers
172
+ if (typeof settings.extraHeaders === 'object') {
173
+ for (var header in settings.extraHeaders) {
174
+ if (settings.extraHeaders.hasOwnProperty(header)) {
175
+ xhr.setRequestHeader(header, settings.extraHeaders[header]);
176
+ }
177
+ }
178
+ }
179
+
180
+ xhr.onload = function() {
181
+ // If HTTP status is OK or Created
182
+ if (xhr.status === 200 || xhr.status === 201) {
183
+ me.onFileUploadResponse(xhr);
184
+ } else {
185
+ me.onFileUploadError(xhr);
186
+ }
187
+ };
188
+ if (settings.beforeFileUpload(xhr) !== false) {
189
+ xhr.send(formData);
190
+ }
191
+ return xhr;
192
+ };
193
+
194
+
195
+
196
+ /**
197
+ * Returns if the given file is allowed to handle
198
+ *
199
+ * @param {File} file clipboard data file
200
+ */
201
+ isFileAllowed(file) {
202
+ if (file.kind === 'string') { return false; }
203
+ if (this.settings.allowedTypes.indexOf('*') === 0){
204
+ return true;
205
+ } else {
206
+ return this.settings.allowedTypes.indexOf(file.type) >= 0;
207
+ }
208
+ };
209
+
210
+ /**
211
+ * Handles upload response
212
+ *
213
+ * @param {XMLHttpRequest} xhr
214
+ * @return {void}
215
+ */
216
+ onFileUploadResponse(xhr) {
217
+ if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
218
+ var result = JSON.parse(xhr.responseText),
219
+ filename = result[this.settings.jsonFieldName];
220
+
221
+ if (result && filename) {
222
+ var newValue;
223
+ if (typeof this.settings.urlText === 'function') {
224
+ newValue = this.settings.urlText.call(this, filename, result);
225
+ } else {
226
+ newValue = this.settings.urlText.replace(this.filenameTag, filename);
227
+ }
228
+ this.editor.value.replace(this.lastValue, newValue);
229
+ this.settings.onFileUploaded.call(this, filename, result);
230
+ }
231
+ }
232
+ };
233
+
234
+
235
+ /**
236
+ * Called when a file has failed to upload
237
+ *
238
+ * @param {XMLHttpRequest} xhr
239
+ * @return {void}
240
+ */
241
+ onFileUploadError(xhr) {
242
+ if (this.settings.onFileUploadError.call(this, xhr) !== false) {
243
+ this.editor.value.replace(this.lastValue, '');
244
+ }
245
+ };
246
+
247
+ /**
248
+ * Called when a file has been inserted, either by drop or paste
249
+ *
250
+ * @param {File} file
251
+ * @return {void}
252
+ */
253
+ onFileInserted(file) {
254
+ if (this.settings.onFileReceived.call(this, file) !== false) {
255
+ this.lastValue = this.settings.progressText;
256
+
257
+ var scrollPos = el.scrollTop;
258
+ el.value = this.lastValue;
259
+ el.scrollTop = scrollPos;
260
+ }
261
+ };
262
+
263
+
264
+ onFileInputChange(e) {
265
+ var result = false;
266
+ for (var i = 0; i < e.target.files.length; i++) {
267
+ var file = e.target.files[i];
268
+ if (this.isFileAllowed(file)) {
269
+ result = true;
270
+ this.uploadFile(file);
271
+ }
272
+ }
273
+
274
+ return result;
275
+ };
276
+
277
+ imagePreview(e, previewDiv){
278
+ var result = false;
279
+
280
+ for (var i = 0; i < e.target.files.length; i++) {
281
+ var file = e.target.files[i];
282
+ if (this.isFileAllowed(file)) {
283
+ result = true;
284
+ this.previewFile(file, previewDiv);
285
+ }
286
+ }
287
+
288
+ return result;
289
+ };
290
+
291
+ onFileInputClick(e) {
292
+ console.log('fileInputClick', e)
293
+ };
294
+
295
+ }