diff --git a/www/code/inner.html b/www/code/inner.html index 5d914b6c8..327363fd0 100644 --- a/www/code/inner.html +++ b/www/code/inner.html @@ -6,6 +6,7 @@ diff --git a/www/code/inner.js b/www/code/inner.js index d5d7edfdd..7fd66721e 100644 --- a/www/code/inner.js +++ b/www/code/inner.js @@ -7,6 +7,7 @@ define([ '/common/sframe-common.js', '/common/sframe-app-framework.js', '/common/common-util.js', + '/common/common-thumbnail.js', '/common/modes.js', 'cm/lib/codemirror', @@ -45,6 +46,7 @@ define([ SFCommon, Framework, Util, + Thumb, Modes, CMeditor) { @@ -145,6 +147,10 @@ define([ $codeMirror.addClass('cp-app-code-fullpage'); }; + var isVisible = function () { + return $previewContainer.is(':visible'); + }; + framework.onReady(function () { // add the splitter var splitter = $('
', { @@ -184,7 +190,8 @@ define([ return { forceDraw: forceDrawPreview, draw: drawPreview, - modeChange: modeChange + modeChange: modeChange, + isVisible: isVisible }; }; @@ -317,6 +324,17 @@ define([ framework.start(); }; + var getThumbnailContainer = function () { + var $preview = $('#cp-app-code-preview-content'); + var $codeMirror = $('.CodeMirror'); + if ($preview.length && $preview.is(':visible')) { + return $preview[0]; + } + if ($codeMirror.length) { + return $codeMirror[0]; + } + }; + var main = function () { var CodeMirror; var editor; @@ -327,7 +345,8 @@ define([ Framework.create({ toolbarContainer: '#cme_toolbox', - contentContainer: '#cp-app-code-editor' + contentContainer: '#cp-app-code-editor', + getThumbnailContainer: getThumbnailContainer }, waitFor(function (fw) { framework = fw; })); nThen(function (waitFor) { diff --git a/www/common/common-file.js b/www/common/common-file.js index 73a58cc50..4501882b3 100644 --- a/www/common/common-file.js +++ b/www/common/common-file.js @@ -296,18 +296,11 @@ define([ if (!Thumb.isSupportedType(file.type)) { return finish(); } // make a resized thumbnail from the image.. - Thumb.fromBlob(file, function (e, thumb_blob) { + Thumb.fromBlob(file, function (e, thumb64) { if (e) { console.error(e); } - if (!thumb_blob) { return finish(); } - - blobToArrayBuffer(thumb_blob, function (e, buffer) { - if (e) { - console.error(e); - return finish(); - } - thumb = arrayBufferToString(buffer); - finish(); - }); + if (!thumb64) { return finish(); } + thumb = thumb64; + finish(); }); }); }; diff --git a/www/common/common-thumbnail.js b/www/common/common-thumbnail.js index 18e963a4e..a2deea346 100644 --- a/www/common/common-thumbnail.js +++ b/www/common/common-thumbnail.js @@ -48,7 +48,14 @@ define([ var dim = Thumb.dimension; // if the image is too small, don't bother making a thumbnail - if (h <= dim && w <= dim) { return null; } + if (h <= dim && w <= dim) { + return { + x: Math.floor((dim - w) / 2), + w: w, + y: Math.floor((dim - h) / 2), + h : h + }; + } // the image is taller than it is wide, so scale to that. var r = dim / (h > w? h: w); // ratio @@ -77,18 +84,16 @@ define([ // assumes that your canvas is square // nodeback returning blob - Thumb.fromCanvas = Thumb.fromImage = function (canvas, D, cb) { + Thumb.fromCanvas = function (canvas, D, cb) { var c2 = document.createElement('canvas'); - if (!D) { return void cb('TOO_SMALL'); } + if (!D) { return void cb('ERROR'); } c2.width = Thumb.dimension; c2.height = Thumb.dimension; var ctx = c2.getContext('2d'); ctx.drawImage(canvas, D.x, D.y, D.w, D.h); - c2.toBlob(function (blob) { - cb(void 0, blob); - }); + cb(void 0, c2.toDataURL()); }; Thumb.fromImageBlob = function (blob, cb) { @@ -97,10 +102,7 @@ define([ img.onload = function () { var D = getResizedDimensions(img, 'image'); - Thumb.fromImage(img, D, function (err, t) { - if (err === 'TOO_SMALL') { return void cb(void 0, blob); } - cb(err, t); - }); + Thumb.fromCanvas(img, D, cb); }; img.onerror = function () { cb('ERROR'); @@ -145,9 +147,7 @@ define([ PDFJS.getDocument(url).promise .then(function (doc) { return doc.getPage(1).then(makeThumb).then(function (canvas) { - canvas.toBlob(function (blob) { - cb(void 0, blob); - }); + cb(void 0, canvas.toDataURL()); }); }).catch(function () { cb('ERROR'); @@ -164,8 +164,19 @@ define([ Thumb.fromImageBlob(blob, cb); }; - Thumb.fromVideo = function (video, cb) { - cb = cb; // WIP + window.html2canvas = undefined; + Thumb.fromDOM = function (element, cb) { + var todo = function () { + html2canvas(element, { + allowTaint: true, + onrendered: function (canvas) { + var D = getResizedDimensions(canvas, 'image'); + Thumb.fromCanvas(canvas, D, cb); + } + }); + }; + if (html2canvas) { return void todo(); } + require(['/bower_components/html2canvas/build/html2canvas.min.js'], todo); }; return Thumb; diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 2bb6090aa..8295560ad 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -8,8 +8,10 @@ define([ '/common/cryptpad-common.js', '/bower_components/nthen/index.js', '/common/sframe-common.js', + '/common/sframe-common-interface.js', '/customize/messages.js', '/common/common-util.js', + '/common/common-thumbnail.js', '/customize/application_config.js', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', @@ -25,8 +27,10 @@ define([ Cryptpad, nThen, SFCommon, + SFUI, Messages, Util, + Thumb, AppConfig) { var SaveAs = window.saveAs; @@ -264,6 +268,29 @@ define([ Cryptpad.removeLoadingScreen(emitResize); + if (options.getThumbnailContainer) { + var oldThumbnailState; + var privateDat = cpNfInner.metadataMgr.getPrivateData(); + var hash = privateDat.availableHashes.editHash || privateDat.availableHashes.viewHash; + var href = privateDat.pathname + '#' + hash; + var mkThumbnail = function () { + if (!hash) { return; } + if (state !== STATE.READY) { return; } + if (!cpNfInner.chainpad) { return; } + var content = cpNfInner.chainpad.getUserDoc(); + if (content === oldThumbnailState) { return; } + var el = options.getThumbnailContainer(); + if (!el) { return; } + $(el).parents().css('overflow', 'visible'); + Thumb.fromDOM(el, function (err, b64) { + oldThumbnailState = content; + $(el).parents().css('overflow', ''); + SFUI.setPadThumbnail(href, b64) + }); + }; + window.setInterval(mkThumbnail, 5000); + } + if (newPad) { common.openTemplatePicker(); } diff --git a/www/common/sframe-common-file.js b/www/common/sframe-common-file.js index 724c13349..aebec38e6 100644 --- a/www/common/sframe-common-file.js +++ b/www/common/sframe-common-file.js @@ -247,18 +247,11 @@ define([ if (!Thumb.isSupportedType(file.type)) { return finish(); } // make a resized thumbnail from the image.. - Thumb.fromBlob(file, function (e, thumb_blob) { + Thumb.fromBlob(file, function (e, thumb64) { if (e) { console.error(e); } - if (!thumb_blob) { return finish(); } - - blobToArrayBuffer(thumb_blob, function (e, buffer) { - if (e) { - console.error(e); - return finish(); - } - thumb = arrayBufferToString(buffer); - finish(); - }); + if (!thumb64) { return finish(); } + thumb = thumb64; + finish(); }); }); }; diff --git a/www/common/sframe-common-interface.js b/www/common/sframe-common-interface.js index e53db847d..6835039cb 100644 --- a/www/common/sframe-common-interface.js +++ b/www/common/sframe-common-interface.js @@ -35,15 +35,20 @@ define([ var addThumbnail = function (err, thumb, $span, cb) { var img = new Image(); - img.src = 'data:;base64,'+thumb; + img.src = thumb.slice(0,5) === 'data:' ? thumb : 'data:;base64,'+thumb; $span.find('.cp-icon').hide(); $span.prepend(img); cb($(img)); }; + UI.setPadThumbnail = function (href, b64, cb) { + cb = cb || $.noop; + var k ='thumbnail-' + href; + localForage.setItem(k, b64, cb); + }; + localForage.removeItem('thumbnail-/1/edit/lqg6RRnynI76LV0sR8F0YA/Nh1SNXxB5U2UjaADvODfvI5l/'); UI.displayThumbnail = function (href, $container, cb) { cb = cb || $.noop; var parsed = Hash.parsePadUrl(href); - if (parsed.type !== 'file') { return; } var k ='thumbnail-' + href; var whenNewThumb = function () { var secret = Hash.getSecrets('file', parsed.hash); @@ -61,7 +66,10 @@ define([ }); }; localForage.getItem(k, function (err, v) { - if (!v) { return void whenNewThumb(); } + if (!v && parsed.type === 'file') { + // We can only create thumbnails for files here since we can't easily decrypt pads + return void whenNewThumb(); + } if (v === 'EMPTY') { return; } addThumbnail(err, v, $container, cb); });