From 48cd7438a1ca7309386a44be78cb460f4e729e01 Mon Sep 17 00:00:00 2001 From: marktaiwan Date: Sun, 15 Mar 2015 22:18:58 +0800 Subject: initial commit file-selector.js --- js/file-selector.js | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 js/file-selector.js (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js new file mode 100644 index 00000000..437e1d4a --- /dev/null +++ b/js/file-selector.js @@ -0,0 +1,187 @@ +/* + * file-selector.js - Add support for drag and drop file selection, and paste from clipbboard on supported browsers. + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/file-selector.js'; + */ + +onready(function () { + +// add options panel item +$(document).ready(function () { + if (window.Options && Options.get_tab('general')) { + Options.extend_tab('general', ''); + + $('#file-drag-drop>input').on('click', function() { + if ($('#file-drag-drop>input').is(':checked')) { + localStorage.file_dragdrop = 'true'; + } else { + localStorage.file_dragdrop = 'false'; + } + }); + + if (localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true'; + if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true); + } +}); + +// disabled by user, or incompatible browser. +// fallback to old +if (localStorage.file_dragdrop == 'false' || !(window.FileReader || window.File)) { + $('.dropzone-wrap').remove(); + $('#upload_file').show(); + + return; +} + +// multipost not enabled +if (typeof max_images == 'undefined') { + var max_images = 1; +} + +var files = []; + +function addFile(file) { + if (files.length == max_images) + return; + + files.push(file); + addThumb(file); +} + +function removeFile(file) { + files.splice(files.indexOf(file), 1); +} + +function getThumbElement(file) { + return $('.tmb-container').filter(function(){return($(this).data('file-ref')==file);}); +} + +function addThumb(file) { + + var fileName = (file.name.length < 24) ? file.name : file.name.substr(0, 22) + '…'; + var fileType = file.type.split('/')[0]; + var fileExt = file.type.split('/')[1]; + var $fileThumb; + + $('.file-thumbs').append($('
') + .addClass('tmb-container') + .data('file-ref', file) + .append( + $('
').addClass('remove-btn').html('✖'), + $('
').addClass('file-tmb'), + $('
').addClass('tmb-filename').html(fileName) + ) + ); + + if (fileType == 'image') { + // if image file, generate thumbnail + var reader = new FileReader(); + + reader.onloadend = function () { + var dataURL = reader.result; + var $fileThumb = getThumbElement(file).find('.file-tmb'); + $fileThumb.css('background-image', 'url('+ dataURL +')'); + }; + + reader.readAsDataURL(file); + } else { + $fileThumb = getThumbElement(file).find('.file-tmb'); + $fileThumb.html('' + fileExt.toUpperCase() + ''); + } +} + +$(document).on('ajax_before_post', function (e, formData) { + var i; + + for (i=0; i 0) key += i + 1; + formData.append(key, files[i]); + } + + // clear file queue and UI + files = []; + $('.file-thumbs').empty(); +}); + +var dragCounter = 0; +var dropHandlers = { + dragenter: function (e) { + e.stopPropagation(); + e.preventDefault(); + + if (dragCounter === 0) $(this).addClass('dragover'); + dragCounter++; + }, + dragover: function (e) { + // needed for webkit to work + e.stopPropagation(); + e.preventDefault(); + }, + dragleave: function (e) { + e.stopPropagation(); + e.preventDefault(); + + dragCounter--; + if (dragCounter === 0) $(this).removeClass('dragover'); + }, + drop: function (e) { + e.stopPropagation(); + e.preventDefault(); + + $(this).removeClass('dragover'); + dragCounter = 0; + + var fileList = e.originalEvent.dataTransfer.files; + for (var i=0; i'); + + $fileSelector.on('change', function (e) { + if (this.files.length > 0) { + for (var i=0; i Date: Sun, 15 Mar 2015 23:32:53 +0800 Subject: Run on index and thread Clear file queue after upload success corrected fallback detection --- js/file-selector.js | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index 437e1d4a..c820db48 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -6,29 +6,28 @@ * $config['additional_javascript'][] = 'js/file-selector.js'; */ -onready(function () { +if (active_page == 'index' || active_page == 'thread') { +$(document).ready(function () { // add options panel item -$(document).ready(function () { - if (window.Options && Options.get_tab('general')) { - Options.extend_tab('general', ''); - - $('#file-drag-drop>input').on('click', function() { - if ($('#file-drag-drop>input').is(':checked')) { - localStorage.file_dragdrop = 'true'; - } else { - localStorage.file_dragdrop = 'false'; - } - }); +if (window.Options && Options.get_tab('general')) { + Options.extend_tab('general', ''); + + $('#file-drag-drop>input').on('click', function() { + if ($('#file-drag-drop>input').is(':checked')) { + localStorage.file_dragdrop = 'true'; + } else { + localStorage.file_dragdrop = 'false'; + } + }); - if (localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true'; - if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true); - } -}); + if (localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true'; + if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true); +} // disabled by user, or incompatible browser. // fallback to old -if (localStorage.file_dragdrop == 'false' || !(window.FileReader || window.File)) { +if (localStorage.file_dragdrop == 'false' || !(window.FileReader && window.File)) { $('.dropzone-wrap').remove(); $('#upload_file').show(); @@ -93,15 +92,15 @@ function addThumb(file) { } $(document).on('ajax_before_post', function (e, formData) { - var i; - - for (i=0; i 0) key += i + 1; formData.append(key, files[i]); } +}); - // clear file queue and UI +// clear file queue and UI on success +$(document).on('ajax_after_post', function () { files = []; $('.file-thumbs').empty(); }); @@ -185,3 +184,4 @@ $(document).on('paste', function (e) { }); }); +} -- cgit v1.3 From 3bd7f94861e9a2a8b9a7f8f972f04eb6eaa45453 Mon Sep 17 00:00:00 2001 From: marktaiwan Date: Wed, 18 Mar 2015 18:44:47 +0800 Subject: Fallback for browsers that disables javascript Conflicts: stylesheets/style.css templates/post_form.html --- js/file-selector.js | 3 +- stylesheets/style.css | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ templates/post_form.html | 8 +++++ 3 files changed, 91 insertions(+), 1 deletion(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index c820db48..ddae2d09 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -140,7 +140,8 @@ var dropHandlers = { } }; -$('.dropzone').css('user-select', 'none') // let jquery add browser specific prefix +$('#upload input[type=file]').hide(); // hide the original file selector +$('.dropzone-wrap').css('user-select', 'none').show(); // let jquery add browser specific prefix // attach handlers $(document).on(dropHandlers, '.dropzone'); diff --git a/stylesheets/style.css b/stylesheets/style.css index e0ce08c5..56140561 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -959,3 +959,84 @@ span.pln { cursor: pointer; } +#youtube-size input { + width: 50px; +} + +/* File selector */ +.dropzone { + color: #000; + cursor: default; + margin: auto; + padding: 0px 4px; + text-align: center; + min-height: 50px; + max-height: 140px; + transition: 0.2s; + background-color: rgba(200, 200, 200, 0.5); + overflow-y: auto; +} +.dropzone-wrap { + width: 100%; +} +.dropzone .file-hint { + color: rgba(0, 0, 0, 0.5); + cursor: pointer; + position: relative; + margin-bottom: 5px; + padding: 10px 0px; + top: 5px; + transition: 0.2s; + border: 2px dashed rgba(125, 125, 125, 0.4); +} +.file-hint:hover, .dropzone.dragover .file-hint { + color: rgba(0, 0, 0, 1); + border-color: rgba(125, 125, 125, 0.8); +} +.dropzone.dragover { + background-color: rgba(200, 200, 200, 1); +} +.dropzone .file-thumbs { + text-align: left; + width: 100%; +} +.dropzone .tmb-container { + padding: 3px; + overflow-x: hidden; + white-space: nowrap; +} +.dropzone .file-tmb { + height: 40px; + width: 70px; + cursor: pointer; + display: inline-block; + text-align: center; + background-color: rgba(187, 187, 187, 0.5); + background-size: cover; + background-position: center; +} +.dropzone .file-tmb span { + font-weight: 600; + position: relative; + top: 13px; +} +.dropzone .tmb-filename { + display: inline-block; + vertical-align: bottom; + bottom: 12px; + position: relative; + margin-left: 5px; +} +.dropzone .remove-btn { + cursor: pointer; + color: rgba(125, 125, 125, 0.5); + display: inline-block; + vertical-align: bottom; + bottom: 10px; + position: relative; + margin-right: 5px; + font-size: 20px +} +.dropzone .remove-btn:hover { + color: rgba(125, 125, 125, 1); +} diff --git a/templates/post_form.html b/templates/post_form.html index 1846adb5..9596ee6b 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -98,6 +98,14 @@ + + + {% if config.allow_upload_by_url %}
: -- cgit v1.3 From 0005f11098890ad76c1b9963792cd686493649a9 Mon Sep 17 00:00:00 2001 From: marktaiwan Date: Wed, 18 Mar 2015 21:35:58 +0800 Subject: initialize file selector soon as it's loaded Conflicts: templates/post_form.html --- js/file-selector.js | 44 +++++++++++++++++++------------------------- templates/post_form.html | 2 ++ 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index ddae2d09..b4589706 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -5,34 +5,29 @@ * $config['additional_javascript'][] = 'js/jquery.min.js'; * $config['additional_javascript'][] = 'js/file-selector.js'; */ +function init_file_selector() { -if (active_page == 'index' || active_page == 'thread') { $(document).ready(function () { + // add options panel item + if (window.Options && Options.get_tab('general')) { + Options.extend_tab('general', ''); + + $('#file-drag-drop>input').on('click', function() { + if ($('#file-drag-drop>input').is(':checked')) { + localStorage.file_dragdrop = 'true'; + } else { + localStorage.file_dragdrop = 'false'; + } + }); -// add options panel item -if (window.Options && Options.get_tab('general')) { - Options.extend_tab('general', ''); - - $('#file-drag-drop>input').on('click', function() { - if ($('#file-drag-drop>input').is(':checked')) { - localStorage.file_dragdrop = 'true'; - } else { - localStorage.file_dragdrop = 'false'; - } - }); - - if (localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true'; - if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true); -} + if (localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true'; + if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true); + } +}); // disabled by user, or incompatible browser. -// fallback to old -if (localStorage.file_dragdrop == 'false' || !(window.FileReader && window.File)) { - $('.dropzone-wrap').remove(); - $('#upload_file').show(); - +if (localStorage.file_dragdrop == 'false' || !(window.FileReader && window.File)) return; -} // multipost not enabled if (typeof max_images == 'undefined') { @@ -40,6 +35,8 @@ if (typeof max_images == 'undefined') { } var files = []; +$('#upload_file').hide(); // hide the original file selector +$('.dropzone-wrap').css('user-select', 'none').show(); // let jquery add browser specific prefix function addFile(file) { if (files.length == max_images) @@ -140,8 +137,6 @@ var dropHandlers = { } }; -$('#upload input[type=file]').hide(); // hide the original file selector -$('.dropzone-wrap').css('user-select', 'none').show(); // let jquery add browser specific prefix // attach handlers $(document).on(dropHandlers, '.dropzone'); @@ -184,5 +179,4 @@ $(document).on('paste', function (e) { } }); -}); } diff --git a/templates/post_form.html b/templates/post_form.html index 9596ee6b..809230f0 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -106,6 +106,8 @@
+ + {% if config.allow_upload_by_url %}
: -- cgit v1.3 From 4da073b6e85aae15b8eed227b3b3b16798d2a99e Mon Sep 17 00:00:00 2001 From: marktaiwan Date: Thu, 19 Mar 2015 19:29:48 +0800 Subject: Keep quick-reply and main form in sync Use object-url instead of data-url due to shorter length --- js/file-selector.js | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index b4589706..e5451f1a 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -26,7 +26,7 @@ $(document).ready(function () { }); // disabled by user, or incompatible browser. -if (localStorage.file_dragdrop == 'false' || !(window.FileReader && window.File)) +if (localStorage.file_dragdrop == 'false' || !(window.URL.createObjectURL && window.File)) return; // multipost not enabled @@ -59,9 +59,9 @@ function addThumb(file) { var fileName = (file.name.length < 24) ? file.name : file.name.substr(0, 22) + '…'; var fileType = file.type.split('/')[0]; var fileExt = file.type.split('/')[1]; - var $fileThumb; + var $container = $('
'); - $('.file-thumbs').append($('
') + $container .addClass('tmb-container') .data('file-ref', file) .append( @@ -69,21 +69,14 @@ function addThumb(file) { $('
').addClass('file-tmb'), $('
').addClass('tmb-filename').html(fileName) ) - ); + .appendTo($('.file-thumbs')); + var $fileThumb = $container.find('.file-tmb'); if (fileType == 'image') { // if image file, generate thumbnail - var reader = new FileReader(); - - reader.onloadend = function () { - var dataURL = reader.result; - var $fileThumb = getThumbElement(file).find('.file-tmb'); - $fileThumb.css('background-image', 'url('+ dataURL +')'); - }; - - reader.readAsDataURL(file); + var objURL = window.URL.createObjectURL(file); + $fileThumb.css('background-image', 'url('+ objURL +')'); } else { - $fileThumb = getThumbElement(file).find('.file-tmb'); $fileThumb.html('' + fileExt.toUpperCase() + ''); } } @@ -144,8 +137,8 @@ $(document).on(dropHandlers, '.dropzone'); $(document).on('click', '.dropzone .remove-btn', function (e) { var file = $(e.target).parent().data('file-ref'); + getThumbElement(file).remove(); removeFile(file); - $(e.target).parent().remove(); }); $(document).on('click', '.dropzone .file-hint', function (e) { -- cgit v1.3 From 6e84a25f9a882bc4c2cbd1e376416ac34ca9943b Mon Sep 17 00:00:00 2001 From: marktaiwan Date: Fri, 20 Mar 2015 08:53:57 +0800 Subject: Adds keyboard focus to file selector --- js/file-selector.js | 10 +++++++++- templates/post_form.html | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index e5451f1a..dbe8ea82 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -135,13 +135,21 @@ var dropHandlers = { $(document).on(dropHandlers, '.dropzone'); $(document).on('click', '.dropzone .remove-btn', function (e) { + e.stopPropagation(); + var file = $(e.target).parent().data('file-ref'); getThumbElement(file).remove(); removeFile(file); }); -$(document).on('click', '.dropzone .file-hint', function (e) { +$(document).on('keypress click', '.dropzone, .dropzone .file-hint', function (e) { + e.stopPropagation(); + + // accept mosue click or Enter + if (e.which != 1 || e.which != 13) + return; + var $fileSelector = $(''); $fileSelector.on('change', function (e) { diff --git a/templates/post_form.html b/templates/post_form.html index 809230f0..7cdcc7d3 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -100,7 +100,7 @@ - + {% if config.allow_upload_by_url %}
-- cgit v1.3 From 419d69b4eea23b1ec92762d2ba2771ac0b46a315 Mon Sep 17 00:00:00 2001 From: 8chan Date: Thu, 19 Mar 2015 20:34:54 -0700 Subject: ayylmao @marktaiwan --- js/file-selector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index 687920d0..6a7e6773 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -147,7 +147,7 @@ $(document).on('keypress click', '.dropzone, .dropzone .file-hint', function (e) e.stopPropagation(); // accept mosue click or Enter - if (e.which != 1 || e.which != 13) + if (e.which != 1 && e.which != 13) return; var $fileSelector = $(''); -- cgit v1.3 From e42ffb27684e159473320c512052246f081d04f0 Mon Sep 17 00:00:00 2001 From: marktaiwan Date: Fri, 20 Mar 2015 12:48:32 +0800 Subject: fix file selector element reference fix thumbnail image not applying to main form with quick reply open --- js/file-selector.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index 6a7e6773..9869e347 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -59,9 +59,7 @@ function addThumb(file) { var fileName = (file.name.length < 24) ? file.name : file.name.substr(0, 22) + '…'; var fileType = file.type.split('/')[0]; var fileExt = file.type.split('/')[1]; - var $container = $('
'); - - $container + var $container = $('
') .addClass('tmb-container') .data('file-ref', file) .append( @@ -69,7 +67,7 @@ function addThumb(file) { $('
').addClass('file-tmb'), $('
').addClass('tmb-filename').html(fileName) ) - .appendTo($('.file-thumbs')); + .appendTo('.file-thumbs'); var $fileThumb = $container.find('.file-tmb'); if (fileType == 'image') { -- cgit v1.3 From 6f94a0658603f3f39032655b3cebe738c2bced0d Mon Sep 17 00:00:00 2001 From: marktaiwan Date: Sun, 22 Mar 2015 22:15:43 +0800 Subject: file selector: correct typo, click event target --- js/file-selector.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index 9869e347..fc9c83e2 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -141,11 +141,12 @@ $(document).on('click', '.dropzone .remove-btn', function (e) { removeFile(file); }); -$(document).on('keypress click', '.dropzone, .dropzone .file-hint', function (e) { +$(document).on('keypress click', '.dropzone', function (e) { e.stopPropagation(); - // accept mosue click or Enter - if (e.which != 1 && e.which != 13) + // accept mouse click or Enter + if ((e.which != 1 || e.target.className != 'file-hint') && + e.which != 13) return; var $fileSelector = $(''); -- cgit v1.3 From 765dea599bd010bc00a3a40df58953b239ec0e9d Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 31 Mar 2015 06:50:05 +0200 Subject: trivial fixes to file-selector.js --- js/file-selector.js | 11 ++++++++++- js/upload-selection.js | 2 ++ templates/post_form.html | 7 ------- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index fc9c83e2..6aad9382 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -34,8 +34,16 @@ if (typeof max_images == 'undefined') { var max_images = 1; } +$(''+ +'
').prependTo('#upload td'); + var files = []; -$('#upload_file').hide(); // hide the original file selector +$('#upload_file').remove(); // remove the original file selector $('.dropzone-wrap').css('user-select', 'none').show(); // let jquery add browser specific prefix function addFile(file) { @@ -83,6 +91,7 @@ $(document).on('ajax_before_post', function (e, formData) { for (var i=0; i 0) key += i + 1; + if (typeof files[i] === 'undefined') break; formData.append(key, files[i]); } }); diff --git a/js/upload-selection.js b/js/upload-selection.js index e2032748..b342a134 100644 --- a/js/upload-selection.js +++ b/js/upload-selection.js @@ -25,6 +25,7 @@ $(function(){ $("#upload_url").hide(); $("#upload_embed").hide(); $(".add_image").hide(); + $(".dropzone-wrap").hide(); $('[id^=upload_file]').each(function(i, v) { $(v).val(''); @@ -40,6 +41,7 @@ $(function(){ enable_file = function() { disable_all(); $("#upload").show(); + $(".dropzone-wrap").show(); $(".file_separator").show(); $("[id^=upload_file]").show(); $(".add_image").show(); diff --git a/templates/post_form.html b/templates/post_form.html index 00390daf..d6a77452 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -99,13 +99,6 @@ - - {% if config.allow_upload_by_url %} -- cgit v1.3 From 0e805c25d8f3044a2c6640a1e8818d3774a0ff07 Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 31 Mar 2015 07:20:53 +0200 Subject: file-selector.js: allow file dropping anywhere --- js/file-selector.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'js/file-selector.js') diff --git a/js/file-selector.js b/js/file-selector.js index 6aad9382..207a5ae9 100644 --- a/js/file-selector.js +++ b/js/file-selector.js @@ -108,7 +108,7 @@ var dropHandlers = { e.stopPropagation(); e.preventDefault(); - if (dragCounter === 0) $(this).addClass('dragover'); + if (dragCounter === 0) $('.dropzone').addClass('dragover'); dragCounter++; }, dragover: function (e) { @@ -121,13 +121,13 @@ var dropHandlers = { e.preventDefault(); dragCounter--; - if (dragCounter === 0) $(this).removeClass('dragover'); + if (dragCounter === 0) $('.dropzone').removeClass('dragover'); }, drop: function (e) { e.stopPropagation(); e.preventDefault(); - $(this).removeClass('dragover'); + $('.dropzone').removeClass('dragover'); dragCounter = 0; var fileList = e.originalEvent.dataTransfer.files; @@ -139,7 +139,7 @@ var dropHandlers = { // attach handlers -$(document).on(dropHandlers, '.dropzone'); +$(document).on(dropHandlers); $(document).on('click', '.dropzone .remove-btn', function (e) { e.stopPropagation(); -- cgit v1.3