diff --git a/CHANGELOG.md b/CHANGELOG.md
index b42da98c8..5a636d212 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,5 @@
+- The QR now allows you to edit the filename on the fly.
+
### 3.7.1 - *2013-08-13*
- Fixed an error for Firefox <23 users.
diff --git a/css/style.css b/css/style.css
index e9777b123..3678628ed 100644
--- a/css/style.css
+++ b/css/style.css
@@ -812,55 +812,74 @@ a.hide-announcement {
height: 57px;
width: 300px;
}
-#file-n-submit > input {
- margin: 0;
-}
-#file-n-submit.has-file #qr-no-file {
- visibility: hidden;
-}
-#file-n-submit:not(.has-file) #qr-filename,
-#file-n-submit:not(.has-file) #qr-file-spoiler,
-#file-n-submit:not(.has-file) #qr-filerm {
- display: none;
+#file-n-submit-container {
+ position: relative;
}
#file-n-submit {
- display: -webkit-flex;
- display: flex;
- -webkit-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: center;
- align-items: center;
-}
-#qr-no-file, #qr-filename-container {
- -webkit-flex: 1;
- flex: 1;
-}
-#qr-filename-container {
- cursor: default;
- position: relative;
- margin-left: 2px;
-}
-#qr-filename {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
+ display: -webkit-flex;
+ display: flex;
+ -webkit-align-items: center;
+ align-items: center;
}
-#qr-filerm {
- padding: 0 2px;
+#file-n-submit-container input[type='file'] {
+ /* Keep it to set an appropriate height to the container. */
+ visibility: hidden;
}
-#file-n-submit > #qr-file-spoiler {
- margin: 0 2px;
+#file-n-submit-container input {
+ margin: 0;
+ padding: 0;
}
#file-n-submit input[type='submit'] {
- min-width: 40px;
-webkit-order: 1;
order: 1;
}
+#file-n-submit.has-file #qr-no-file,
+#file-n-submit:not(.has-file) #qr-filename,
+#file-n-submit:not(.has-file) #qr-filesize,
+#file-n-submit:not(.has-file) #qr-file-spoiler,
+#file-n-submit:not(.has-file) #qr-filerm,
+#qr-filename:focus ~ #qr-filesize {
+ display: none;
+}
+#qr-no-file,
+#qr-filename,
+#qr-filesize,
+#qr-filerm,
+#qr-file-spoiler {
+ margin: 0 2px !important;
+}
+#qr-no-file {
+ cursor: default;
+ -webkit-flex: 1;
+ flex: 1;
+}
+#qr-filename {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ background: none;
+ border: none !important;
+ color: inherit;
+ font-family: inherit;
+ font-size: inherit;
+ -webkit-flex: 1;
+ flex: 1;
+ text-overflow: ellipsis;
+}
+#qr-filesize {
+ font-size: .8em;
+}
+#qr-filesize::before {
+ content: " (";
+}
+#qr-filesize::after {
+ content: ")";
+}
/* Menu */
.menu-button {
diff --git a/html/Posting/QR.html b/html/Posting/QR.html
index b34fb36b3..9b9786933 100644
--- a/html/Posting/QR.html
+++ b/html/Posting/QR.html
@@ -21,17 +21,18 @@
-
-
-
-
+
-
diff --git a/lib/$.coffee b/lib/$.coffee
index 0fc239340..bfea3c47f 100644
--- a/lib/$.coffee
+++ b/lib/$.coffee
@@ -25,10 +25,8 @@ $.formData = (form) ->
return new FormData form
fd = new FormData()
for key, val of form when val
- # XXX GM bug
- # if val instanceof Blob
- if val.size and val.name
- fd.append key, val, val.name
+ if typeof val is 'object' and 'newName' of val
+ fd.append key, val, val.newName
else
fd.append key, val
fd
diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee
index 6da3f8cf0..f38082acb 100644
--- a/src/Posting/QR.coffee
+++ b/src/Posting/QR.coffee
@@ -507,11 +507,11 @@ QR =
lock: (lock=true) ->
@isLocked = lock
return unless @ is QR.selected
- for name in ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'spoiler']
+ for name in ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler']
QR.nodes[name].disabled = lock
@nodes.rm.style.visibility =
QR.nodes.fileRM.style.visibility = if lock then 'hidden' else ''
- (if lock then $.off else $.on) QR.nodes.filename.parentNode, 'click', QR.openFileInput
+ (if lock then $.off else $.on) QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput
@nodes.spoiler.disabled = lock
@nodes.el.draggable = !lock
unlock: ->
@@ -531,7 +531,7 @@ QR =
$.event 'QRPostSelection', @
load: ->
# Load this post's values.
- for name in ['thread', 'name', 'email', 'sub', 'com']
+ for name in ['thread', 'name', 'email', 'sub', 'com', 'filename']
QR.nodes[name].value = @[name] or null
@showFileData()
QR.characterCount()
@@ -551,16 +551,20 @@ QR =
# during the last 5 seconds of the cooldown.
if QR.cooldown.auto and @ is QR.posts[0] and 0 < QR.cooldown.seconds <= 5
QR.cooldown.auto = false
+ when 'filename'
+ return unless @file
+ @file.newName = @filename
+ @updateFilename()
forceSave: ->
return unless @ is QR.selected
# Do this in case people use extensions
# that do not trigger the `input` event.
- for name in ['thread', 'name', 'email', 'sub', 'com', 'spoiler']
+ for name in ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler']
@save QR.nodes[name]
return
setFile: (@file) ->
- @filename = "#{file.name} (#{$.bytesToString file.size})"
- @nodes.el.title = @filename
+ @filename = file.name
+ @filesize = $.bytesToString file.size
@nodes.label.hidden = false if QR.spoiler
URL.revokeObjectURL @URL
@showFileData()
@@ -604,15 +608,22 @@ QR =
rmFile: ->
delete @file
delete @filename
+ delete @filesize
@nodes.el.title = null
@nodes.el.style.backgroundImage = null
@nodes.label.hidden = true if QR.spoiler
@showFileData()
URL.revokeObjectURL @URL
+ updateFilename: ->
+ long = "#{@filename} (#{@filesize})"
+ @nodes.el.title = long
+ return unless @ is QR.selected
+ QR.nodes.filename.title = long
showFileData: ->
if @file
- QR.nodes.filename.textContent = @filename
- QR.nodes.filename.title = @filename
+ @updateFilename()
+ QR.nodes.filename.value = @filename
+ QR.nodes.filesize.textContent = @filesize
QR.nodes.spoiler.checked = @spoiler
$.addClass QR.nodes.fileSubmit, 'has-file'
else
@@ -783,6 +794,7 @@ QR =
fileSubmit: $ '#file-n-submit', dialog
fileButton: $ '#qr-file-button', dialog
filename: $ '#qr-filename', dialog
+ filesize: $ '#qr-filesize', dialog
fileRM: $ '#qr-filerm', dialog
spoiler: $ '#qr-file-spoiler', dialog
status: $ '[type=submit]', dialog
@@ -836,10 +848,9 @@ QR =
$.on elm, 'blur', QR.focusout
$.on elm, 'focus', QR.focusin
<% } %>
- $.on dialog, 'focusin', QR.focusin
- $.on dialog, 'focusout', QR.focusout
- for node in [nodes.fileButton, nodes.filename.parentNode]
- $.on node, 'click', QR.openFileInput
+ $.on dialog, 'focusin', QR.focusin
+ $.on dialog, 'focusout', QR.focusout
+ $.on nodes.fileButton, 'click', QR.openFileInput
$.on nodes.autohide, 'change', QR.toggleHide
$.on nodes.close, 'click', QR.close
$.on nodes.dumpButton, 'click', -> nodes.el.classList.toggle 'dump'
@@ -849,7 +860,7 @@ QR =
$.on nodes.spoiler, 'change', -> QR.selected.nodes.spoiler.click()
$.on nodes.fileInput, 'change', QR.fileInput
# save selected post's data
- for name in ['name', 'email', 'sub', 'com']
+ for name in ['name', 'email', 'sub', 'com', 'filename']
$.on nodes[name], 'input', -> QR.selected.save @
$.on nodes.thread, 'change', -> QR.selected.save @