Skip to content

Commit

Permalink
Fix #1800: Styling enhancements for thumbnail content and rotatable i…
Browse files Browse the repository at this point in the history
…mages
  • Loading branch information
kartik-v committed Jun 28, 2022
1 parent cb42fc9 commit 48f7198
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 55 deletions.
3 changes: 2 additions & 1 deletion CHANGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Change Log: `bootstrap-fileinput`

**Major Release: BC Breaking**

**Date**: 27-Jun-2022
**Date**: 28-Jun-2022

- (enh #1800): Styling enhancements for thumbnail content and rotatable images.
- (enh #1799): Correct translations containing `{maxSize}, {minSize}, {size}`.
- (enh #1796): Add two new Font Awesome 6.x themes.
- `fa6`
Expand Down
8 changes: 6 additions & 2 deletions css/fileinput.css
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ input[type=file].file-loading {
display: none;
}

.file-preview-other-frame, .file-preview-object, .kv-zoom-body {
.file-preview-other-frame, .file-preview-object, .kv-file-content, .kv-zoom-body {
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -676,9 +676,13 @@ input[type=file].file-loading {
.rotatable .file-zoom-detail,
.rotatable .kv-file-content,
.rotatable .kv-file-content > :first-child {
transform-origin: top left;
transform-origin: center center;
}

.rotate-animate {
transition: transform 0.3s ease;
}

.kv-overflow-hidden {
overflow: hidden;
}
2 changes: 1 addition & 1 deletion css/fileinput.min.css

Large diffs are not rendered by default.

61 changes: 37 additions & 24 deletions js/fileinput.js
Original file line number Diff line number Diff line change
Expand Up @@ -1112,8 +1112,7 @@
return out;
},
exists: function (id) {
var list = self.fileManager.getIdList();
return $.inArray(id, list) !== -1 && (!altId || $.inArray(altId, list) !== -1);
return $.inArray(id, self.fileManager.getIdList()) !== -1;
},
count: function () {
return self.fileManager.getIdList().length;
Expand Down Expand Up @@ -2333,9 +2332,10 @@
},
_resetErrors: function (fade) {
var self = this, $error = self.$errorContainer, history = self.resumableUploadOptions.retainErrorHistory;
if (self.isPersistentError || (self.enableResumableUpload && history)) {
if (self.isPersistentError || (self.enableResumableUpload && history && !self.clearInput)) {
return;
}
self.clearInput = false;
self.isError = false;
self.$container.removeClass('has-error');
self.$caption.removeClass('is-invalid is-valid file-processing');
Expand Down Expand Up @@ -2910,6 +2910,7 @@
self._raise('filezoom' + event, getParams(e));
}
if (event === 'shown') {
self._handleRotation($modal, $modal.find('.file-zoom-detail'), $modal.data('angle'));
$btnBord.removeClass('active').attr('aria-pressed', 'false');
$btnFull.removeClass('active').attr('aria-pressed', 'false');
if ($modal.hasClass('file-zoom-fullscreen')) {
Expand Down Expand Up @@ -4070,39 +4071,51 @@
}, self.processDelay);
},
_handleRotation: function ($el, $content, angle) {
var self = this, css, newCss, addCss = '', scale = 1, elContent = $content[0], quadrant, transform, h, w;
var self = this, css, newCss, addCss = '', scale = 1, elContent = $content[0], quadrant, transform, h, w,
wNew, $parent = $content.parent(), hParent, wParent, $body = $('body'), bodyExists = !!$body.length;
if (bodyExists) {
$body.addClass('kv-overflow-hidden');
}
if (!$content.length || $el.hasClass('hide-rotate')) {
if (bodyExists) {
$body.removeClass('kv-overflow-hidden');
}
return;
}
transform = $content.css('transform');
if (transform) {
$content.css('transform', 'none');
}
w = elContent.naturalWidth || $content.outerWidth() || 0;
h = elContent.naturalHeight || $content.outerHeight() || 0;
scale = w > h && w != 0 ? (h / w).toFixed(2) : 1;
if (transform) {
$content.css('transform', transform);
}
angle = angle || 0;
quadrant = angle % 360;
css = 'rotate(' + angle + 'deg)';
newCss = 'rotate(' + quadrant + 'deg)';
switch (quadrant) {
case 90:
addCss = ' translateY(-100%)' + (scale === 1 ? '' : ' scale(' + scale + ')');
break;
case 180:
addCss = ' translate(-100%,-100%)';
break;
case 270:
var x = scale * 100, y = 100 - x;
addCss = scale === 1 ? ' translateX(-100%)' : ' translate(-' + x + '%, ' + y + '%) scale(' + scale + ')';
break;
addCss = '';
if (quadrant === 90 || quadrant === 270) {
w = elContent.naturalWidth || $content.outerWidth() || 0;
h = elContent.naturalHeight || $content.outerHeight() || 0;
scale = w > h && w != 0 ? (h / w).toFixed(2) : 1;
if ($parent.length) {
hParent = $parent.height();
wParent = $parent.width();
wNew = Math.min(w, wParent);
if (hParent > scale * wNew) {
scale = wNew > hParent && wNew != 0 ? (hParent / wNew).toFixed(2) : 1;
}
}
if (scale !== 1) {
addCss = ' scale(' + scale + ')';
}
}
$content.addClass('rotate-animate').css('transform', css + addCss);
setTimeout(function () {
$content.removeClass('rotate-animate').css('transform', newCss + addCss);
if (bodyExists) {
$body.removeClass('kv-overflow-hidden');
}
$el.data('angle', quadrant);
}, self.fadeDelay);
},
Expand All @@ -4120,12 +4133,13 @@
_initRotateZoom: function ($frame, $content) {
var self = this, $modal = self.$modal, $rotate = $modal.find('.btn-kv-rotate'),
angle = $frame.data('angle');
$modal.data('angle', angle);
if ($rotate.length) {
$rotate.off('click');
if ($modal.hasClass('rotatable')) {
self._handleRotation($modal, $modal.find('.file-zoom-detail'), angle);
$rotate.on('click', function () {
angle = ($modal.data('angle') || 0) + 90;
$modal.data('angle', angle);
self._handleRotation($modal, $modal.find('.file-zoom-detail'), angle);
self._handleRotation($frame, $content, angle);
if ($frame.hasClass('hide-rotate')) {
Expand Down Expand Up @@ -4329,7 +4343,6 @@
if (newSize == sizeHuman) {
newSize = sizeHuman;
}
console.log('size ', size);
out = newSize + ' ' + sizeUnits[i];
}
return skipTemplate ? out : self._getLayoutTemplate('size').replace('{sizeText}', out);
Expand Down Expand Up @@ -4361,7 +4374,7 @@
config, title = caption, alt = caption, typeCss = 'type-default', getContent, addFrameCss,
footer = foot || self._renderFileFooter(cat, caption, size, 'auto', isError), isRotatable,
forcePrevIcon = self.preferIconicPreview, forceZoomIcon = self.preferIconicZoomPreview,
newCat = forcePrevIcon ? 'other' : cat, ext = filename.split('.').pop().toLowerCase();
newCat = forcePrevIcon ? 'other' : cat, ext = filename.split('.').pop().toLowerCase();
config = screenW < 400 ? (self.previewSettingsSmall[newCat] || self.defaults.previewSettingsSmall[newCat]) :
(self.previewSettings[newCat] || self.defaults.previewSettings[newCat]);
if (config) {
Expand Down Expand Up @@ -4423,7 +4436,7 @@
ind = ind || previewId.slice(previewId.lastIndexOf('-') + 1);
isRotatable = self.fileActionSettings.showRotate && $.inArray(ext, self.rotatableFileExtensions) !== -1;
if (self.fileActionSettings.showZoom) {
addFrameCss = 'kv-zoom-thumb'
addFrameCss = 'kv-zoom-thumb';
if (isRotatable) {
addFrameCss += ' rotatable' + (forceZoomIcon ? ' hide-rotate' : '');
}
Expand Down Expand Up @@ -4512,7 +4525,6 @@
name = ($h.isIE(9) && $h.findFileName($el.val())) || ($el[0].files[0] && $el[0].files[0].name);
if (!name && self.fileManager.count() > 0) {
file = self.fileManager.getFirstFile();
console.log('KV SAYS', file);
label = file.nameFmt;
} else {
label = name ? self.slug(name) : '_';
Expand Down Expand Up @@ -5638,7 +5650,7 @@
$status.html(msg);
self._updateFileDetails(numFiles);
if (self.getFilesCount(true) > 0 && self.getFrames(':visible')) {
self.$dropZone.find('.'+ self.dropZoneTitleClass).remove();
self.$dropZone.find('.' + self.dropZoneTitleClass).remove();
}
readFile(i + 1);
}, self.processDelay);
Expand Down Expand Up @@ -6008,6 +6020,7 @@
if (!self._raise('fileclear')) {
return;
}
self.clearInput = true;
self.$btnUpload.removeAttr('disabled');
self._getThumbs().find('video,audio,img').each(function () {
$h.cleanMemory($(this));
Expand Down
6 changes: 1 addition & 5 deletions js/fileinput.min.js

Large diffs are not rendered by default.

74 changes: 57 additions & 17 deletions js/plugins/filetype.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,44 @@
var KrajeeFileTypeConfig = {
minimumBytes: 4100, // A fair amount of file-types are detectable within this range,
defaultMessages: 'End-Of-Stream',
tarHeaderChecksumMatches: function(buffer, offset = 0) {
var readSum = Number.parseInt(buffer.toString('utf8', 148, 154).replace(/\0.*$/, '').trim(), 8); // Read sum in header
if (Number.isNaN(readSum)) {
return false;
}

var sum = 8 * 0x20; // Initialize signed bit sum

for (let i = offset; i < offset + 148; i++) {
sum += buffer[i];
}

for (let i = offset + 156; i < offset + 512; i++) {
sum += buffer[i];
}

return readSum === sum;
},
uint32SyncSafeToken: {
get: function(buffer, offset) {
return (buffer[offset + 3] & 0x7F) | ((buffer[offset + 2]) << 7) | ((buffer[offset + 1]) << 14) | ((buffer[offset]) << 21);
},
len: 4,
},
dv: function(array) {
return new DataView(array.buffer, array.byteOffset);
},
Token: {
/**
* 8-bit unsigned integer
*/
UINT8: {
len: 1,
get: function(array, offset) {
return dv(array).getUint8(offset);
return KrajeeFileTypeConfig.dv(array).getUint8(offset);
},
put: function(array, offset, value) {
dv(array).setUint8(offset, value);
KrajeeFileTypeConfig.dv(array).setUint8(offset, value);
return offset + 1;
}
},
Expand All @@ -31,10 +58,10 @@ var KrajeeFileTypeConfig = {
UINT16_LE: {
len: 2,
get: function(array, offset) {
return dv(array).getUint16(offset, true);
return KrajeeFileTypeConfig.dv(array).getUint16(offset, true);
},
put: function(array, offset, value) {
dv(array).setUint16(offset, value, true);
KrajeeFileTypeConfig.dv(array).setUint16(offset, value, true);
return offset + 2;
}
},
Expand All @@ -44,23 +71,36 @@ var KrajeeFileTypeConfig = {
UINT16_BE: {
len: 2,
get: function(array, offset) {
return dv(array).getUint16(offset);
return KrajeeFileTypeConfig.dv(array).getUint16(offset);
},
put: function(array, offset, value) {
dv(array).setUint16(offset, value);
KrajeeFileTypeConfig.dv(array).setUint16(offset, value);
return offset + 2;
}
},
/**
* 32-bit unsigned integer, Big Endian byte order
*/
INT32_BE: {
len: 4,
get: function(array, offset) {
return KrajeeFileTypeConfig.dv(array).getInt32(offset);
},
put: function(array, offset, value) {
KrajeeFileTypeConfig.dv(array).setInt32(offset, value);
return offset + 4;
}
},
/**
* 32-bit unsigned integer, Little Endian byte order
*/
UINT32_LE: {
len: 4,
get: function(array, offset) {
return dv(array).getUint32(offset, true);
return KrajeeFileTypeConfig.dv(array).getUint32(offset, true);
},
put: function(array, offset, value) {
dv(array).setUint32(offset, value, true);
KrajeeFileTypeConfig.dv(array).setUint32(offset, value, true);
return offset + 4;
}
},
Expand All @@ -70,10 +110,10 @@ var KrajeeFileTypeConfig = {
UINT32_BE: {
len: 4,
get: function(array, offset) {
return dv(array).getUint32(offset);
return KrajeeFileTypeConfig.dv(array).getUint32(offset);
},
put: function(array, offset, value) {
dv(array).setUint32(offset, value);
KrajeeFileTypeConfig.dv(array).setUint32(offset, value);
return offset + 4;
}
},
Expand All @@ -84,10 +124,10 @@ var KrajeeFileTypeConfig = {
UINT64_LE: {
len: 8,
get: function(array, offset) {
return dv(array).getBigUint64(offset, true);
return KrajeeFileTypeConfig.dv(array).getBigUint64(offset, true);
},
put: function(array, offset, value) {
dv(array).setBigUint64(offset, value, true);
KrajeeFileTypeConfig.dv(array).setBigUint64(offset, value, true);
return offset + 8;
}
},
Expand All @@ -97,10 +137,10 @@ var KrajeeFileTypeConfig = {
UINT64_BE: {
len: 8,
get: function(array, offset) {
return dv(array).getBigUint64(offset);
return KrajeeFileTypeConfig.dv(array).getBigUint64(offset);
},
put: function(array, offset, value) {
dv(array).setBigUint64(offset, value);
KrajeeFileTypeConfig.dv(array).setBigUint64(offset, value);
return offset + 8;
}
}
Expand Down Expand Up @@ -433,7 +473,7 @@ class FileTypeParser {

if (this.checkString('ID3')) {
await tokenizer.ignore(6); // Skip ID3 header until the header size
const id3HeaderLength = await tokenizer.readToken(uint32SyncSafeToken);
const id3HeaderLength = await tokenizer.readToken(KrajeeFileTypeConfig.uint32SyncSafeToken);
if (tokenizer.position + id3HeaderLength > tokenizer.fileInfo.size) {
// Guess file type based on ID3 header for backward compatibility
return {
Expand Down Expand Up @@ -1200,7 +1240,7 @@ class FileTypeParser {

async function readChunkHeader() {
return {
length: await tokenizer.readToken(INT32_BE),
length: await tokenizer.readToken(Token.INT32_BE),
type: await tokenizer.readToken(new StringType(4, 'binary')),
};
}
Expand Down Expand Up @@ -1600,7 +1640,7 @@ class FileTypeParser {
await tokenizer.peekBuffer(this.buffer, {length: Math.min(512, tokenizer.fileInfo.size), mayBeLess: true});

// Requires a buffer size of 512 bytes
if (tarHeaderChecksumMatches(this.buffer)) {
if (KrajeeFileTypeConfig.tarHeaderChecksumMatches(this.buffer)) {
return {
ext: 'tar',
mime: 'application/x-tar',
Expand Down
2 changes: 1 addition & 1 deletion js/plugins/filetype.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit 48f7198

Please sign in to comment.