Mercurial Hosting > linkmystyle
view src/uploadcare/uploadcare.js @ 0:8f4df159f06b
start public repo
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 11 Jul 2025 20:57:49 -0600 |
parents | |
children |
line wrap: on
line source
'use strict'; let uploadcare = {}; /* to set an option: uploadcare[option] = value from https://uploadcare.com/docs/uploads/file-uploader-options/ publicKey, imagesOnly, doNotStore onError - function called with request for AJAX errors maxFileSize - maximum file size of images in bytes */ uploadcare.maxDim = 2000; uploadcare.processingImage = '/uploadcare/processing.gif'; uploadcare.cropprOptions = null; function logToServer(msg) { ajax( '/log_info.js', 'msg='+encodeURIComponent(msg) ); } { // compression function infoAddUrl(info) { if( info.url ) return; return new Promise( function(resolve) { let reader = new FileReader(); reader.onload = function() { info.url = reader.result; resolve(); }; reader.readAsDataURL(info.file); } ); } uploadcare.infoAddUrl = infoAddUrl; let croppr; let dialog = null; async function infoAddCroppedImage(info) { if( !dialog ) { let html = ` <dialog croppr> <img> <div buttons> <button save>Save</button> <button cancel>Cancel</button> </div> </dialog> ` ; document.body.insertAdjacentHTML( 'beforeend', html ); dialog = document.querySelector('dialog[croppr]'); dialog.onclose = function() { croppr.destroy(); }; } await infoAddUrl(info); let image = dialog.querySelector('img'); image.src = info.url; return new Promise( function(resolve) { dialog.querySelector('button[save]').onclick = function() { info.image = image; info.crop = croppr.getValue(); dialog.close(); resolve(); }; dialog.querySelector('button[cancel]').onclick = function() { info.canceled = true; dialog.close(); resolve(); }; image.onload = function() { dialog.showModal(); croppr = new Croppr( image, uploadcare.cropprOptions ); }; } ); } let supportsDialog = typeof HTMLDialogElement === 'function'; async function infoAddImage(info) { if( info.image ) return; if( uploadcare.cropprOptions && supportsDialog ) return infoAddCroppedImage(info); await infoAddUrl(info); return new Promise( function(resolve) { let image = new Image(); info.image = image; image.src = info.url; image.onload = function() { resolve(); }; } ); } async function infoAddCanvas(info,maxDim) { await infoAddImage(info); if( info.canceled ) return; let image = info.image; let width, height; let crop = info.crop; if( crop ) { width = crop.width; height = crop.height; } else { width = image.width; height = image.height; } if( maxDim ) { if( width > height ) { if( width > maxDim ) { height *= maxDim / width; width = maxDim; } } else { if( height > maxDim ) { width *= maxDim / height; height = maxDim; } } } let canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; let ctx = canvas.getContext('2d'); if( crop ) { ctx.drawImage( image, crop.x, crop.y, crop.width, crop.height, 0, 0, width, height ); } else { ctx.drawImage( image, 0, 0, width, height ); } info.canvas = canvas; } async function infoAddBlob(info,maxDim) { await infoAddCanvas(info,maxDim); if( info.canceled ) return; return new Promise( function(resolve) { function done(blob) { info.blob = blob; resolve(); } info.canvas.toBlob( done, 'image/jpeg' ); } ); } async function infoCompress(info) { let file = info.file; await infoAddBlob(info); if( info.canceled ) return; let maxFileSize = uploadcare.maxFileSize; if( !info.blob || maxFileSize && info.blob.size > maxFileSize ) { await infoAddBlob(info,uploadcare.maxDim); if( !info.blob ) throw 'no blob'; } info.compressed = info.blob; info.compressedName = file.name.replace( /(\.[^.]*)?$/, '.jpeg' ); } uploadcare.infoCompress = infoCompress; // uploading function onload(url,onSuccess,onError,count) { count = count || 1; let request = new XMLHttpRequest(); request.open( 'GET', url ); request.onload = function() { if( request.status === 200 ) { onSuccess(); } else if( request.status === 404 ) { console.log('onload failed '+count); if( count >= 20 ) { let text = 'Failed to get image after ' + count + ' tries, please try again'; onError( request.status, text ); return; } setTimeout( function() { onload(url,onSuccess,onError,count+1); }, 1000 ); } else { onError( request.status, request.responseText) ; } }; request.send(); } function call(file,filename,callback,onError) { let request = new XMLHttpRequest(); let url = 'https://upload.uploadcare.com/base/'; request.open( 'POST', url ); request.onload = function() { if( request.status !== 200 ) { onError( request.status, request.responseText ); return; } let response = JSON.parse(request.responseText); let uuid = response.file; let url = 'https://ucarecdn.com/' + uuid + '/'; function onSuccess() { callback( uuid, file.name ); } onload( url, onSuccess, onError ); }; let formData = new FormData(); formData.append( 'UPLOADCARE_PUB_KEY', uploadcare.publicKey ); formData.append( 'UPLOADCARE_STORE', uploadcare.doNotStore ? '0' : '1' ); formData.append( 'file', file, filename ); request.send(formData); } let input = null; let img = null; function showImg() { img.style.display = 'block'; } function hideImg() { img.style.display = 'none'; } uploadcare.upload = function(callback) { if( !uploadcare.publicKey ) throw new Error('uploadcare.publicKey required'); if( !input ) { let html = ` <input uploadcare type=file> <img uploadcare src="${uploadcare.processingImage}"> ` ; document.body.insertAdjacentHTML( 'beforeend', html ); input = document.querySelector('input[uploadcare][type="file"]'); img = document.querySelector('img[uploadcare]'); } input.accept = uploadcare.imagesOnly ? 'image/*' : ''; input.onchange = async function() { function onError(status,text) { hideImg(); if( text ) alert(text); if( uploadcare.onError ) uploadcare.onError(status,text); } function callback2(uuid,filename) { hideImg(); callback(uuid,filename) } let info = { file: input.files[0] }; input.value = null; await infoCompress(info); if( !info.canceled ) { showImg(); call(info.compressed,info.compressedName,callback2,onError); } }; input.click(); }; }