1;(function ($) { 2 var _ = { 3 now : Date.now || function () { 4 return new Date().getTime(); 5 }, 6 debounce: function (func, wait, immediate) { 7 var timeout, args, context, timestamp, result; 8 9 var later = function () { 10 var last = _.now() - timestamp; 11 12 if (last < wait && last >= 0) { 13 timeout = setTimeout(later, wait - last); 14 } else { 15 timeout = null; 16 if (!immediate) { 17 result = func.apply(context, args); 18 if (!timeout) context = args = null; 19 } 20 } 21 }; 22 23 return function () { 24 context = this; 25 args = arguments; 26 timestamp = _.now(); 27 var callNow = immediate && !timeout; 28 if (!timeout) timeout = setTimeout(later, wait); 29 if (callNow) { 30 result = func.apply(context, args); 31 context = args = null; 32 } 33 34 return result; 35 }; 36 } 37 }; 38 window.LP_Certificate = function (el, options) { 39 var self = this, 40 viewport = { 41 width : 0, 42 height : 0, 43 templateWidth : 0, 44 templateHeight: 0, 45 ratio : 1 46 }, 47 $el = $(el), 48 $background = $el.find('.cert-template'), 49 $canvas = null; 50 ajaxData = new FormData(); 51 52 function init() { 53 initCanvas(); 54 $(document).on('click', '[data-cert="' + $el.attr('id') + '"]', download); 55 self.$canvas = $canvas; 56 self.$background = $background; 57 } 58 59 function dataURItoBlob(dataURI) { 60 // convert base64 to raw binary data held in a string 61 // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this 62 var byteString = atob(dataURI.split(',')[1]); 63 64 // separate out the mime component 65 var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] 66 67 // write the bytes of the string to an ArrayBuffer 68 var ab = new ArrayBuffer(byteString.length); 69 70 // create a view into the buffer 71 var ia = new Uint8Array(ab); 72 73 // set the bytes of the buffer to the correct values 74 for (var i = 0; i < byteString.length; i++) { 75 ia[i] = byteString.charCodeAt(i); 76 } 77 78 // write the ArrayBuffer to a blob, and you're done 79 var blob = new Blob([ab], {type: mimeString}); 80 return blob; 81 82 } 83 84 function download() { 85 86 var name = 'certificate', 87 type = $(this).data('type'), 88 args = { 89 format : type === 'jpg' ? 'jpeg' : 'png', 90 multiplier: 1 / $canvas.getZoom() 91 } 92 93 if (args.type === 'jpeg') { 94 args.quality = 1; 95 } 96 97 var data_url = $canvas.toDataURL(); 98 var imageBlob = dataURItoBlob(data_url); 99 var ajaxData = new FormData(); 100 ajaxData.append('files', imageBlob,options.name); 101 102 downloadjs($canvas.toDataURL(args), options.name); 103 return false; 104 } 105 106 function createPreview() { 107 var name = 'certificate', 108 type = 'png', 109 args = { 110 format : type === 'jpg' ? 'jpeg' : 'png', 111 multiplier: 1 / $canvas.getZoom() 112 } 113 114 if (args.type === 'jpeg') { 115 args.quality = 1 116 } 117 118 var data = $canvas.toDataURL(args), 119 $img = $el.siblings('.certificate-result'); 120 121 if ($img.length === 0) { 122 $img = $('<img class="certificate-result" />').css({'max-width': '100%'}).insertBefore($el); 123 } 124 125 $img.attr('src', data) 126 } 127 128 function initCanvas() { 129 if (!$canvas) { 130 131 $canvas = $el.find('canvas'); 132 $canvas = new fabric.Canvas($canvas.get(0)); 133 $canvas.selection = false; 134 $.each(options.layers, function (i, layer) { 135 if (!layer.type) return; 136 addLayer(layer, {setActive: false}); 137 }); 138 139 $background.on('load', function () { 140 var tester = new Image(); 141 tester.src = $background.attr('src'); 142 viewport = { 143 width : $background.width(), 144 height : $background.height(), 145 templateWidth : tester.width, 146 templateHeight: tester.height, 147 ratio : $background.width() / tester.width 148 }; 149 150 fabric.Image.fromURL(tester.src, function (img) { 151 $canvas.backgroundImage = img; 152 updateView(); 153 createPreview(); 154 155 $(document).triggerHandler('learn-press/certificates/loaded'); 156 });
157 158 }).trigger('load'); 159 } 160 161 162 $(window).on('resize.update-certificate-view', _.debounce(updateView, 300)).trigger('resize'); 163 } 164 165 function addLayer($layer, args) { 166 args = $.extend({ 167 setActive: true 168 }, args || {}); 169 170 if ($.isPlainObject($layer)) { 171 $layer = createLayer($layer); 172 } 173 174 try { 175 if ($layer) { 176 $canvas.add($layer); 177 178 if (args.setActive) { 179 $canvas.setActiveObject($layer); 180 } 181 $canvas.renderAll(); 182 } 183 } catch (e) { 184 console.log('Error:' + e) 185 } 186 return $layer; 187 } 188 189 function htmlDecode(input) { 190 var e = document.createElement('div'); 191 e.innerHTML = input; 192 return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue; 193 } 194 195 function createLayer(args) { 196 args.text = htmlDecode(args.text) || ''; 197 198 var defaults = $.extend({ 199 fontSize : 24, 200 left : 0, 201 top : 0, 202 lineHeight: 1, 203 originX : 'center', 204 originY : 'center', 205 fontFamily: 'Helvetica', 206 fieldType : 'custom' 207 }, args), 208 text = args.text || ''; 209 210 try { 211 var $object = new fabric.Text('' + text + 'xx', defaults), 212 that = this; 213 var is_url = /^(https?|s?ftp):\/\//i.test(args.text); 214 if( args.fieldType == 'verified-link' && args.qr_size > 0 && is_url ){ 215 var qr_code = new Image(); 216 defaults.type = 'image'; 217 defaults.height = defaults.qr_size; 218 defaults.width = defaults.qr_size; 219 qr_code.crossOrigin = "Anonymous"; 220 qr_code.src = args.text; 221 $object = new fabric.Image(qr_code, defaults); 222 } 223 $object.set({ 224 borderColor : '#AAA', 225 cornerColor : '#666', 226 cornerSize : 7, 227 transparentCorners: true, 228 padding : 0 229 }); 230 $object.set({ 231 hasControls: false 232 }); 233 $object.selectable = false; 234 235 $.each(defaults, function (k, v) { 236 setLayerProp($object, k, v); 237 }); 238 239 240 var $_object = $(document).triggerHandler('learn_press_certificate_layer_obj', [$object, args]); 241 242 if (typeof $_object === 'object') { 243 $object = $_object; 244 } 245 } catch (e) { 246 console.log(text) 247 } 248 249 return $object; 250 } 251 252 function getMaxWidth() { 253 return $el.width(); 254 } 255 256 function calculate() { 257 viewport = $.extend(viewport, { 258 width : $background.width(), 259 height: $background.height(), 260 ratio : $background.width() / viewport.templateWidth 261 }); 262 } 263 264 function updateView() { 265 calculate(); 266 $canvas.setHeight(viewport.height); 267 $canvas.setWidth(viewport.width); 268 $canvas.setZoom(viewport.ratio); 269 $canvas.calcOffset(); 270 $canvas.renderAll(); 271 272 fitImage(); 273 } 274 275 function fitImage() { 276 var $preview = $el.siblings('.certificate-result'), 277 scrWidth = $el.parent().width(), 278 scrHeight = $(window).height() - (60 + parseInt($el.parent().position().top)), 279 maxWidth = viewport.width, 280 maxHeight = viewport.height; 281 282 var scale = Math.min( 283 scrWidth / maxWidth, 284 scrHeight / maxHeight 285 ); 286 287 maxWidth = maxWidth * scale; 288 if (maxWidth) { 289 $preview.css({ 290 //maxWidth: maxWidth * scale 291 }); 292 } 293 } 294 295 function setLayerProp($layer, prop, value) { 296 var options = {}; 297 switch (prop) { 298 case 'textAlign': 299 //$layer.originX = value; 300 break; 301 case 'color': 302 //$layer.set('fill', value); 303 options['fill'] = value; 304 break; 305 case 'scaleX': 306 case 'scaleY': 307 if (value < 0) { 308 if (prop === 'scaleX') { 309 $layer.flipX = true; 310 } else { 311 $layer.flipY = true; 312 } 313 } else { 314 if (prop === 'scaleX') { 315 $layer.flipX = false; 316 } else { 317 $layer.flipY = false; 318 } 319 } 320 options[prop] = (Math.abs(value)); 321 break; 322 case 'top': 323 case 'left': 324 case 'angle': 325 options[prop] = parseInt(value); 326 break; 327 default: 328 options[prop] = value; 329 } 330 $.each(options, function (k, v) { 331 $layer.set(k, v); 332 }) 333 $layer.setCoords(); 334 } 335 336 init(); 337 } 338 339 LP_Certificate.loadJs = function (src, id) {
340 var d = document, s = 'script', js, fjs = d.getElementsByTagName(s)[0]; 341 if (id && d.getElementById(id)) return; 342 js = d.createElement(s); 343 id && (js.id = id); 344 js.src = src; 345 fjs.parentNode.insertBefore(js, fjs); 346 } 347 348 $(document).ready(function () { 349 var $html = $('html, body'), 350 $popup = $('#certificate-popup'), 351 docOverflow = ''; 352 if (!$popup.length) { 353 return; 354 } 355 356 function close() { 357 $popup.fadeOut(function () { 358 $html.css('overflow', docOverflow); 359 $popup.find('.learn-press-message').remove(); 360 }); 361 } 362 363 function open() { 364 $html.css('overflow', 'hidden'); 365 $popup.fadeIn(); 366 } 367 368 docOverflow = $html.css('overflow'); 369 370 $(document).on('learn-press/certificates/loaded', function () { 371 $popup.addClass('ready').hide(); 372 373 $(this) 374 .off('keyup.close-certificate-popup') 375 .on('keyup.close-certificate-popup', function (e) { 376 if (e.keyCode === 27) { 377 close(); 378 } 379 }) 380 .off('clic.close-certificate-popup') 381 .on('click.close-certificate-popup', '.close-popup', function (e) { 382 close(); 383 e.preventDefault(); 384 }); 385 386 $('form[name="certificate-form-button"]').on('submit', function () { 387 open(); 388 return false; 389 }); 390 391 if (window.auto_show_certificate === true) { 392 open(); 393 } else { 394 $popup.find('.learn-press-message').remove(); 395 } 396 397 }) 398 399 }) 400})(jQuery); 401
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.