Difference between revisions of "MediaWiki:Common.js"

From Inkscape Wiki
Jump to navigation Jump to search
m (Replaced content with "$('img').each(function( i, l ){ if (l.src.slice(-4) == ".gif") { $(this).data("src", $(this).src); $(this).src = undefined; } })")
Tag: Replaced
Line 1: Line 1:
// Build a worker from an anonymous function body
$('img').each(function( i, l ){
// http://stackoverflow.com/a/19201292/2487925
if (l.src.slice(-4) == ".gif") {
// something like workify (https://github.com/shama/workerify) would be
$(this).data("src", $(this).src);
// prettier, but it requires a bunch of dependencies and looks like it
         $(this).src = undefined;
// might not work with bundlers other than browserify
}
var blobURL = URL.createObjectURL( new Blob([ '(',
 
  function()
      var read = function(data, index) {
      return data.charCodeAt(index) & 0xff;
    }
 
    // Safari does not support console.log for web workers.
    // Chrome does not support alert for web workers
    // WTF?
    var debug = function(msg) {
      var enabled = true;
      if (enabled && typeof console !== 'undefined' && console.log) {
        console.log(msg);
      }
    }
 
    // Nicolas Perriault (nperriault@gmail.com) via http://stackoverflow.com/a/7372816
    var base64Encode = function(str) {
      var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      var out = "", i = 0, len = str.length, c1, c2, c3;
      while (i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len) {
          out += CHARS.charAt(c1 >> 2);
          out += CHARS.charAt((c1 & 0x3) << 4);
          out += "==";
          break;
        }
        c2 = str.charCodeAt(i++);
        if (i == len) {
          out += CHARS.charAt(c1 >> 2);
          out += CHARS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
          out += CHARS.charAt((c2 & 0xF) << 2);
          out += "=";
          break;
        }
        c3 = str.charCodeAt(i++);
        out += CHARS.charAt(c1 >> 2);
        out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        out += CHARS.charAt(c3 & 0x3F);
      }
      return out;
    }
 
    // Note: The code below was borrowed from Dean McNamee's omggif and slightly modified.
    //
    //
    // (c) Dean McNamee <dean@gmail.com>, 2013.
    //
    // https://github.com/deanm/omggif
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to
    // deal in the Software without restriction, including without limitation the
    // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    // sell copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    // IN THE SOFTWARE.
    //
    // omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
    // including animation and compression.  It does not rely on any specific
    // underlying system, so should run in the browser, Node, or Plask.
    var readImage = function(buffer, limit) {
      var p = 0;
 
      // Header
      if (read(buffer, p++) !== 0x47 || // G
          read(buffer, p++) !== 0x49 || // I
          read(buffer, p++) !== 0x46 || // F
          read(buffer, p++) !== 0x38 || // 8
          read(buffer, p++) !== 0x39 || // 9
          read(buffer, p++) !== 0x61) { // a
        throw "Invalid GIF 89a header.";
      }
 
      // - Logical Screen Descriptor.
      var width = read(buffer, p++) | read(buffer, p++) << 8;
      var height = read(buffer, p++) | read(buffer, p++) << 8;
      var pf0 = read(buffer, p++);  // <Packed Fields>.
      var global_palette_flag = pf0 >> 7;
      var num_global_colors_pow2 = pf0 & 0x7;
      var num_global_colors = 1 << (num_global_colors_pow2 + 1);
      var background = read(buffer, p++);
      read(buffer, p++);  // Pixel aspect ratio
 
      var global_palette_offset = null;
 
      if (global_palette_flag) {
        global_palette_offset = p;
        p += num_global_colors * 3;  // Seek past palette.
      }
 
      while (p < buffer.length) {
        var b = read(buffer, p++);
        if (b == 0x21) { //  Graphics Control Extension Block
          switch (read(buffer,p++)) {
            case 0xff:  // Application specific block
              // Try if it's a Netscape block (with animation loop counter).
              if (read(buffer,p) !== 0x0b ||  // 21 FF already read, check block size.
                  // NETSCAPE2.0
                  read(buffer,p+1) == 0x4e && read(buffer,p+2) == 0x45 && read(buffer,p+2) == 0x54 &&
                  read(buffer,p+4) == 0x53 && read(buffer,p+5) == 0x43 && read(buffer,p+6) == 0x41 &&
                  read(buffer,p+7) == 0x50 && read(buffer,p+8) == 0x45 && read(buffer,p+9) == 0x32 &&
                  read(buffer,p+10) == 0x2e && read(buffer,p+11) == 0x30 &&
                  // Sub-block
                  read(buffer,p+12) == 0x03 && read(buffer,p+13) == 0x01 && read(buffer,p+16) == 0) {
                p += 14;
                p++;  // Skip terminator.
              } else {  // We don't know what it is, just try to get past it.
                p += 12;
                while (true) {  // Seek through subblocks.
                  var block_size = read(buffer,p++);
                  if (block_size === 0) break;
                  p += block_size;
                }
              }
              break;
 
            case 0xf9:  // Graphics Control Extension
              if (read(buffer,p++) !== 0x4 || read(buffer, p+4) !== 0)
                throw "Invalid graphics extension block.";
              var pf1 = read(buffer,p++);
              delay = read(buffer,p++) | read(buffer,p++) << 8;
              transparent_index = read(buffer,p++);
              if ((pf1 & 1) === 0) transparent_index = null;
              disposal = pf1 >> 2 & 0x7;
              p++;  // Skip terminator.
              break;
 
            case 0xfe:  // Comment Extension.
              while (true) { // Seek through subblocks.
                var block_size = read(buffer, p++);
                if (block_size === 0) break;
                p += block_size;
              }
              break;
 
            default:
              throw "Unknown graphic control label: 0x" + read(buffer,p-1).toString(16);
          }
        } else if (b == 0x2c) { // Image descriptor
          break;
        }
      }
 
      p += 10; // Jump to image buffer
 
      while (true) {
        var block_size = read(buffer, p++);
 
        if (block_size === 0 && p <= limit) {
          debug(" [Worker] found frame offset at byte " + p);
          var frame_data = "data:image/gif;base64,"+base64Encode(buffer.substring(0, p));
          return frame_data;
        }
 
        p += block_size;
 
        if (p >= limit) {
          // Range was too small. Fetch more bytes.
          debug(" Worker needs to fetch more bytes " + p);
          return -1;
        }
      }
    }
 
    // Returns either -1 if more bytes need to be fetched or offset for first frame
    onmessage = function(e) {
      var buffer = e.data.buffer;
      var limit = e.data.limit;
      try {
        var response = readImage(buffer, limit); // either -1 (fetch more bytes) or encoded frame data
        postMessage(response);
      } catch(e) {
        // Error reading buffer due to bad headers or data
        postMessage(-2);
      }
    };
 
  }.toString(),
 
')()' ], { type: 'application/javascript' } ) );
 
 
function PreviewGIF(url, callback) {
 
  // Cachebuster for Safari so it does not reuse the cached 206 partial response for
  // subsequent range requests
  var cb = function() {
    return '?cb=' + (Math.floor(Math.random() * 1000000));
  };
 
  // TODO: add support for IE by using XDomain object
  var _processGIF = function(url, callback) {
    var buffer = '';
    var range_start = 0,
      range_end = 100000,
      range_increment = 25000;
    var worker = new Worker(blobURL); // should each request have its own worker?
 
    // Setup XHR request
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url + cb());
    xhr.setRequestHeader('Range', 'bytes=' + range_start + '-' + range_end);
 
    if (xhr.overrideMimeType) { // not supported by ie
      xhr.overrideMimeType('text/plain; charset=x-user-defined');
    }
 
    // Pass response to web worker for processing
    xhr.onload = function() {
      buffer += xhr.responseText;
 
      worker.onmessage = function(event) {
        if (event.data == -1) { // Fetch more bytes
          // Fetch more bytes
          range_start = range_end + 1;
          range_end += range_increment;
          xhr.abort();
          xhr.open('GET', url + cb());
          xhr.setRequestHeader('Range', 'bytes=' + range_start + '-' + range_end);
          xhr.send();
        } else if (event.data == -2) { // Error occured while reading
          callback({
            type: 'DECODE_ERROR',
            message: 'Error reading image from ' + url
          });
          URL.revokeObjectURL(blobURL);
        } else { // Preview for first frame!
          var preview = event.data;
          callback(null, preview);
          URL.revokeObjectURL(blobURL);
        }
      };
 
      worker.postMessage({
        buffer: buffer,
        limit: range_end
      });
    };
 
    // Error while making request
    xhr.onerror = function() {
      callback({
        type: 'REQUEST_ERROR',
        message: 'Error requesting image from ' + url
      });
    }
 
    xhr.send();
  };
 
  _processGIF(url, callback);
 
}
 
if (typeof module !== 'undefined') {
  module.exports = PreviewGIF;
}
 
 
var images = document.querySelectorAll('main img');
      [].forEach.call(images, function(image) {
        PreviewGIF(image.dataset.src, function(err, blob) {
          if (err) console.error(err);
          else image.src = blob;
         });
      });
 
$(function () {
$('img').each(function( i, l ){
PreviewGIF(image.dataset.src, function(err, blob) {
        if (err) console.error(err);
        else image.src = blob;
    });
})
})
});

Revision as of 00:34, 7 September 2020

$('img').each(function( i, l ){
	if (l.src.slice(-4)	== ".gif") {
		$(this).data("src", $(this).src);
        $(this).src = undefined;
	}
})