<commit_before>// https://wiki.mozilla.org/Extension_Manager:Bootstrapped_Extensions

const NAME = "bootstrap";
const global = this;

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;

Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");

const resourceProto = Services.io.getProtocolHandler("resource")
                              .QueryInterface(Ci.nsIResProtocolHandler);
const categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
const manager = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
const storage = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication).storage;

function httpGet(url) {
    let xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
    xmlhttp.open("GET", url, false);
    xmlhttp.send(null);
    return xmlhttp;
}

function writeFile(file, buf) {
    let fstream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
    let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);

    fstream.init(file, 0x02 | 0x08 | 0x20, parseInt("0644", 8), 0);
    stream.init(fstream, "UTF-8", 0, "?");
    stream.writeString(buf);
    stream.close();
    fstream.close();
}

let initialized = false;
let addon = null;
let basePath = null;
let components = {};
let getURI = null;
storage.set("dactyl.bootstrap", this);
var JSMLoader = storage.get("dactyl.JSMLoader", { get load() Cu.import });

function startup(data, reason) {
    dump("dactyl: bootstrap: startup " + reasonToString(reason) + "\n");
    basePath = data.installPath;

    if (!initialized) {
        initialized = true;

        dump("dactyl: bootstrap: init" + " " + data.id + "\n");

        addon = data;
        AddonManager.getAddonByID(addon.id, function (a) { addon = a });

        if (basePath.isDirectory())
            getURI = function getURI(path) {
                let file = basePath.clone().QueryInterface(Ci.nsILocalFile);
                file.appendRelativePath(path);
                return (Services.io || services.io).newFileURI(file);
            }
        else
            getURI = function getURI(path)
                Services.io.newURI("jar:" + Services.io.newFileURI(file).spec + "!" + path);
        try {
            init();
        }
        catch (e) {
            dump("dactyl: bootstrap: " + e + "\n" + e.stack);
            Cu.reportError(e);
        }
    }
}

function FactoryProxy(url, classID) {
    this.url = url;
    this.classID = Components.ID(classID);
}
FactoryProxy.prototype = {
    QueryInterface: XPCOMUtils.generateQI(Ci.nsIFactory),
    register: function () {
        dump("dactyl: bootstrap: register: " + this.classID + " " + this.contractID + "\n");
        manager.registerFactory(this.classID,
                                String(this.classID),
                                this.contractID,
                                this);
    },
    unregister: function () {
        dump("dactyl: bootstrap: unregister: " + this.classID + " " + this.contractID + "\n");
        manager.unregisterFactory(this.classID, this);
    },
    get module() {
        Object.defineProperty(this, "module", { value: {}, enumerable: true });
        JSMLoader.load(this.url, this.module);
        JSMLoader.registerGlobal(this.url, this.module.global);
        return this.module;
    },
    createInstance: function (iids) {
        dump("dactyl: bootstrap: createInstance: " + this.classID + " " + this.contractID + " " + iids + "\n");
        return let (factory = this.module.NSGetFactory(this.classID))
            factory.createInstance.apply(factory, arguments)
    }
}

function init() {
    dump("dactyl: bootstrap: init\n");

    let manifestURI = getURI("chrome.manifest");
    let manifest = httpGet(manifestURI.spec)
            .responseText
            .replace(/^\s*|\s*$|#.*/g, "")
            .replace(/^\s*\n/gm, "");

    function url(path) getURI(path).spec;

    let result = [];

    for each (let line in manifest.split("\n")) {
        let fields = line.split(/\s+/);
        switch(fields[0]) {
        case "content":
            fields[2] = url(fields[2]);
        default:
            result.push(fields);
            break;

        case "locale":
        case "skin":
            fields[3] = url(fields[3]);
            result.push(fields);
            break;

        case "category":
            categoryManager.addCategoryEntry(fields[1], fields[2], fields[3], false, true);
            break;
        case "component":
            components[fields[1]] = new FactoryProxy(url(fields[2]), fields[1]);
            break;
        case "contract":
            components[fields[2]].contractID = fields[1];
            break;

        case "resource":
            resourceProto.setSubstitution(fields[1], getURI(fields[2]));
        }
    }

    Services.obs.notifyObservers(null, "dactyl-rehash", null);

    JSMLoader.load("resource://dactyl/base.jsm", global);

    for each (let component in components)
        component.register();

    require(global, "prefs");
    require(global, "services");

    services.subscriptLoader.loadSubScript(
        url("defaults/preferences/dactyl.js"),
        {
            pref: function pref(name, val) {
                if (prefs.get(name, null) == null)
                    prefs.set(name, val);
            }
        });

    let manifestText = result.map(function (line) line.join(" ")).join("\n");

    if (manifestURI instanceof Ci.nsIFileURL)
        manager.autoRegister(manifestURI.QueryInterface(Ci.nsIFileURL).file);
    else {
        var file = basePath.parent;
        file.append(addon.id + ".manifest");

        writeFile(file, manifestText);
        manager.autoRegister(file);
        file.remove(false);
    }

    require(global, "overlay");
}

function shutdown(data, reason) {
    dump("dactyl: bootstrap: shutdown " + reasonToString(reason) + "\n");
    if (reason != APP_SHUTDOWN) {
        if ([ADDON_UPGRADE, ADDON_DOWNGRADE, ADDON_UNINSTALL].indexOf(reason) >= 0)
            services.observer.notifyObservers(null, "dactyl-purge", null);

        services.observer.notifyObservers(null, "dactyl-cleanup", null);
        services.observer.notifyObservers(null, "dactyl-cleanup-modules", null);
        for (let factory in values(components))
            // TODO: Categories;
            factory.unregister();
    }
}

function reasonToString(reason) {
    for each (let name in ["disable", "downgrade", "enable",
                           "install", "shutdown", "startup",
                           "uninstall", "upgrade"])
        if (reason == global["ADDON_" + name.toUpperCase()] ||
            reason == global["APP_" + name.toUpperCase()])
            return name;
}

function install(data, reason) { dump("dactyl: bootstrap: install " + reasonToString(reason) + "\n") }
function uninstall(data, reason) { dump("dactyl: bootstrap: uninstall " + reasonToString(reason) + "\n") }

<commit_msg>[bootstrap] Fix running from an xpi on Gecko 2.<commit_after>// https://wiki.mozilla.org/Extension_Manager:Bootstrapped_Extensions

const NAME = "bootstrap";
const global = this;

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;

Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");

const resourceProto = Services.io.getProtocolHandler("resource")
                              .QueryInterface(Ci.nsIResProtocolHandler);
const categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
const manager = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
const storage = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication).storage;

function httpGet(url) {
    let xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
    xmlhttp.open("GET", url, false);
    xmlhttp.send(null);
    return xmlhttp;
}

function writeFile(file, buf) {
    let fstream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
    let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);

    fstream.init(file, 0x02 | 0x08 | 0x20, parseInt("0644", 8), 0);
    stream.init(fstream, "UTF-8", 0, "?");
    stream.writeString(buf);
    stream.close();
    fstream.close();
}

let initialized = false;
let addon = null;
let basePath = null;
let components = {};
let getURI = null;
storage.set("dactyl.bootstrap", this);
var JSMLoader = storage.get("dactyl.JSMLoader", { get load() Cu.import });

function startup(data, reason) {
    dump("dactyl: bootstrap: startup " + reasonToString(reason) + "\n");
    basePath = data.installPath;

    if (!initialized) {
        initialized = true;

        dump("dactyl: bootstrap: init" + " " + data.id + "\n");

        addon = data;
        AddonManager.getAddonByID(addon.id, function (a) { addon = a });

        if (basePath.isDirectory())
            getURI = function getURI(path) {
                let file = basePath.clone().QueryInterface(Ci.nsILocalFile);
                file.appendRelativePath(path);
                return (Services.io || services.io).newFileURI(file);
            }
        else
            getURI = function getURI(path)
                Services.io.newURI("jar:" + Services.io.newFileURI(basePath).spec + "!/" + path, null, null);
        try {
            init();
        }
        catch (e) {
            dump("dactyl: bootstrap: " + e + "\n" + e.stack);
            Cu.reportError(e);
        }
    }
}

function FactoryProxy(url, classID) {
    this.url = url;
    this.classID = Components.ID(classID);
}
FactoryProxy.prototype = {
    QueryInterface: XPCOMUtils.generateQI(Ci.nsIFactory),
    register: function () {
        dump("dactyl: bootstrap: register: " + this.classID + " " + this.contractID + "\n");
        manager.registerFactory(this.classID,
                                String(this.classID),
                                this.contractID,
                                this);
    },
    unregister: function () {
        dump("dactyl: bootstrap: unregister: " + this.classID + " " + this.contractID + "\n");
        manager.unregisterFactory(this.classID, this);
    },
    get module() {
        Object.defineProperty(this, "module", { value: {}, enumerable: true });
        JSMLoader.load(this.url, this.module);
        JSMLoader.registerGlobal(this.url, this.module.global);
        return this.module;
    },
    createInstance: function (iids) {
        dump("dactyl: bootstrap: createInstance: " + this.classID + " " + this.contractID + " " + iids + "\n");
        return let (factory = this.module.NSGetFactory(this.classID))
            factory.createInstance.apply(factory, arguments)
    }
}

function init() {
    dump("dactyl: bootstrap: init\n");

    let manifestURI = getURI("chrome.manifest");
    let manifest = httpGet(manifestURI.spec)
            .responseText
            .replace(/^\s*|\s*$|#.*/g, "")
            .replace(/^\s*\n/gm, "");

    function url(path) getURI(path).spec;

    let result = [];

    for each (let line in manifest.split("\n")) {
        let fields = line.split(/\s+/);
        switch(fields[0]) {
        case "content":
            fields[2] = url(fields[2]);
        default:
            result.push(fields);
            break;

        case "locale":
        case "skin":
            fields[3] = url(fields[3]);
            result.push(fields);
            break;

        case "category":
            categoryManager.addCategoryEntry(fields[1], fields[2], fields[3], false, true);
            break;
        case "component":
            components[fields[1]] = new FactoryProxy(url(fields[2]), fields[1]);
            break;
        case "contract":
            components[fields[2]].contractID = fields[1];
            break;

        case "resource":
            resourceProto.setSubstitution(fields[1], getURI(fields[2]));
        }
    }

    Services.obs.notifyObservers(null, "dactyl-rehash", null);

    JSMLoader.load("resource://dactyl/base.jsm", global);

    for each (let component in components)
        component.register();

    require(global, "prefs");
    require(global, "services");
    Cu.import("resource://gre/modules/Services.jsm", global);

    services.subscriptLoader.loadSubScript(
        url("defaults/preferences/dactyl.js"),
        {
            pref: function pref(name, val) {
                if (prefs.get(name, null) == null)
                    prefs.set(name, val);
            }
        });

    let manifestText = result.map(function (line) line.join(" ")).join("\n");

    if (manifestURI instanceof Ci.nsIFileURL)
        manager.autoRegister(manifestURI.QueryInterface(Ci.nsIFileURL).file);
    else {
        var file = basePath.parent;
        file.append(addon.id + ".manifest");

        writeFile(file, manifestText);
        manager.autoRegister(file);
        file.remove(false);
    }

    require(global, "overlay");
}

function shutdown(data, reason) {
    dump("dactyl: bootstrap: shutdown " + reasonToString(reason) + "\n");
    if (reason != APP_SHUTDOWN) {
        if ([ADDON_UPGRADE, ADDON_DOWNGRADE, ADDON_UNINSTALL].indexOf(reason) >= 0)
            services.observer.notifyObservers(null, "dactyl-purge", null);

        services.observer.notifyObservers(null, "dactyl-cleanup", null);
        services.observer.notifyObservers(null, "dactyl-cleanup-modules", null);
        for (let factory in values(components))
            // TODO: Categories;
            factory.unregister();
    }
}

function reasonToString(reason) {
    for each (let name in ["disable", "downgrade", "enable",
                           "install", "shutdown", "startup",
                           "uninstall", "upgrade"])
        if (reason == global["ADDON_" + name.toUpperCase()] ||
            reason == global["APP_" + name.toUpperCase()])
            return name;
}

function install(data, reason) { dump("dactyl: bootstrap: install " + reasonToString(reason) + "\n") }
function uninstall(data, reason) { dump("dactyl: bootstrap: uninstall " + reasonToString(reason) + "\n") }

<|endoftext|>


<commit_before>/**!
 *
 * Copyright (c) 2015-2016 Cisco Systems, Inc. See LICENSE file.
 * @private
 */

/* eslint no-invalid-this: [0] */

import {
  curry,
  debounce,
  identity,
  result,
  wrap
} from 'lodash';
import {NotFoundError} from './errors';
import {make} from '@ciscospark/common';

/**
 * Stores the result of fn before returning it
 * @param  {string}   key
 * @returns {Promise} resolves with the result of fn
 */
export function persist(...args) {
  if (args.length === 3) {
    return persist(`@`)(...args);
  }

  const [key] = args;

  return function persistDecorator(target, prop, descriptor) {
    if (prop !== `initialize`) {
      // Once we have class-based alternative to AmpersandState, it should be
      // detected here.
      throw new TypeError(`@persist can only currently be applied to AmpersandState objects or their derivatives and must be applied to the initialize method`);
    }

    descriptor.value = wrap(descriptor.value, function persistExecutor(fn, ...initializeArgs) {
      // eslint-disable-next-line no-invalid-this
      const ret = Reflect.apply(fn, this, initializeArgs);
      const changeEvent = key === `@` ? `change` : `change:${key}`;

      // Some scenarios will lead to lots of change events on a single tick; we
      // really only care about writing once things have stopped changing. with
      // a debounce of zero, we're effectively coalescing all the changes
      // triggered by a single call to set() and commiting them on the next tick
      // eslint-disable-next-line no-invalid-this
      this.on(changeEvent, debounce(() => {
        if (key === `@`) {
          // eslint-disable-next-line no-invalid-this
          return this.boundedStorage.put(key, this);
        }

        // eslint-disable-next-line no-invalid-this
        return this.boundedStorage.put(key, this[key]);
      }, 0));
      return ret;
    });

    prepareInitialize(target, prop);
  };
}

const sym = Symbol();
const M = Map;
const S = Set;
const BlockingKeyMap = make(M, M, S);
const blockingKeys = new BlockingKeyMap();

/**
 * Prevents fn from executing until key has been (attempted to be) loaded
 * @param {string} key
 * @param {Function} fn
 * @returns {Promise} result of fn
 */
export function waitForValue(key) {
  if (!key) {
    throw new Error(`\`key\` is required`);
  }

  return function waitForValueDecorator(target, prop, descriptor) {
    blockingKeys.add(target, prop, key);
    descriptor.value = wrap(descriptor.value, function waitForValueExecutor(fn, ...args) {
      const keys = blockingKeys.get(target, prop);
      return Promise.all([...keys].map((k) => this.boundedStorage.waitFor(k)))
        .then(() => Reflect.apply(fn, this, args));
    });

    // This *should* make decorators compatible with AmpersandState class
    // definitions
    if (typeof target === `object` && !target.prototype) {
      target[prop] = descriptor.value;
    }

    prepareInitialize(target, prop);

    return descriptor;
  };
}

/**
 * @param {Function} target
 * @param {string} prop
 * @returns {undefined}
 */
function prepareInitialize(target, prop) {
  if (!target[sym]) {
    target[sym] = true;
    if (target.initialize) {
      target.initialize = wrap(target.initialize, function applyInit(fn, ...args) {
        const ret = Reflect.apply(fn, this, args);
        Reflect.apply(init, this, args);
        return ret;
      });
      return;
    }

    target.initialize = init;
  }

  /**
   * @returns {undefined}
   */
  function init() {
    const self = this;
    this.spark.initialize = wrap(this.spark.initialize || identity, function applyInit(fn, ...args) {
      // Reminder: context here is `spark`, not `self`.
      Reflect.apply(fn, this, args);

      const set = curry((key, value) => {
        this.logger.info(`storage:(${self.getNamespace()}): got \`${key}\` for first time`);
        if (key === `@`) {
          self.parent.set({
            [self.getNamespace().toLowerCase()]: value
          });
        }
        else if (result(self[key], `isState`)) {
          self[key].set(value);
        }
        else {
          self.set(key, value);
        }
        this.logger.info(`storage:(${self.getNamespace()}): set \`${key}\` for first time`);
      });

      const handle = curry((key, reason) => {
        if (reason instanceof NotFoundError || process.env.NODE_ENV !== `production` && reason.toString().includes(`MockNotFoundError`)) {
          this.logger.info(`storage(${self.getNamespace()}): no data for \`${key}\`, continuing`);
          return Promise.resolve();
        }
        this.logger.error(`storage(${self.getNamespace()}): failed to init \`${key}\``, reason);
        return Promise.reject(reason);
      });

      const keys = blockingKeys.get(target, prop);
      keys.forEach((key) => this.boundedStorage.get(self.getNamespace(), key)
        .then(set(key))
        .catch(handle(key)));
    });
  }
}
<commit_msg>fix(spark-core): fix double-loading (and therefore double-saving) of array-like data when classes have namespace collisions<commit_after>/**!
 *
 * Copyright (c) 2015-2016 Cisco Systems, Inc. See LICENSE file.
 * @private
 */

/* eslint no-invalid-this: [0] */

import {
  curry,
  debounce,
  identity,
  result,
  wrap
} from 'lodash';
import {NotFoundError} from './errors';
import {make} from '@ciscospark/common';

/**
 * Stores the result of fn before returning it
 * @param  {string}   key
 * @returns {Promise} resolves with the result of fn
 */
export function persist(...args) {
  if (args.length === 3) {
    return persist(`@`)(...args);
  }

  const [key] = args;

  return function persistDecorator(target, prop, descriptor) {
    if (prop !== `initialize`) {
      // Once we have class-based alternative to AmpersandState, it should be
      // detected here.
      throw new TypeError(`@persist can only currently be applied to AmpersandState objects or their derivatives and must be applied to the initialize method`);
    }

    descriptor.value = wrap(descriptor.value, function persistExecutor(fn, ...initializeArgs) {
      // eslint-disable-next-line no-invalid-this
      const ret = Reflect.apply(fn, this, initializeArgs);
      const changeEvent = key === `@` ? `change` : `change:${key}`;

      // Some scenarios will lead to lots of change events on a single tick; we
      // really only care about writing once things have stopped changing. with
      // a debounce of zero, we're effectively coalescing all the changes
      // triggered by a single call to set() and commiting them on the next tick
      // eslint-disable-next-line no-invalid-this
      this.on(changeEvent, debounce(() => {
        if (key === `@`) {
          // eslint-disable-next-line no-invalid-this
          return this.boundedStorage.put(key, this);
        }

        // eslint-disable-next-line no-invalid-this
        return this.boundedStorage.put(key, this[key]);
      }, 0));
      return ret;
    });

    prepareInitialize(target, prop);
  };
}

const M = Map;
const S = Set;
const BlockingKeyMap = make(M, M, S);
const blockingKeys = new BlockingKeyMap();

/**
 * Prevents fn from executing until key has been (attempted to be) loaded
 * @param {string} key
 * @param {Function} fn
 * @returns {Promise} result of fn
 */
export function waitForValue(key) {
  if (!key) {
    throw new Error(`\`key\` is required`);
  }

  return function waitForValueDecorator(target, prop, descriptor) {
    blockingKeys.add(target, prop, key);
    descriptor.value = wrap(descriptor.value, function waitForValueExecutor(fn, ...args) {
      const keys = blockingKeys.get(target, prop);
      return Promise.all([...keys].map((k) => this.boundedStorage.waitFor(k)))
        .then(() => Reflect.apply(fn, this, args));
    });

    // This *should* make decorators compatible with AmpersandState class
    // definitions
    if (typeof target === `object` && !target.prototype) {
      target[prop] = descriptor.value;
    }

    prepareInitialize(target, prop);

    return descriptor;
  };
}

const inited = new Set();

function identifyTarget(target) {
  if (target.namespace) {
    return target.namespace;
  }

  return target;
}

/**
 * @param {Function} target
 * @param {string} prop
 * @returns {undefined}
 */
function prepareInitialize(target, prop) {
  const id = identifyTarget(target);
  if (!inited.has(id)) {
    inited.add(id);
    if (target.initialize) {
      target.initialize = wrap(target.initialize, function applyInit(fn, ...args) {
        const ret = Reflect.apply(fn, this, args);
        Reflect.apply(init, this, args);
        return ret;
      });
      return;
    }

    target.initialize = init;
  }

  /**
   * @returns {undefined}
   */
  function init() {
    const self = this;
    this.spark.initialize = wrap(this.spark.initialize || identity, function applyInit(fn, ...args) {
      // Reminder: context here is `spark`, not `self`.
      Reflect.apply(fn, this, args);

      const set = curry((key, value) => {
        this.logger.info(`storage:(${self.getNamespace()}): got \`${key}\` for first time`);
        if (key === `@`) {
          self.parent.set({
            [self.getNamespace().toLowerCase()]: value
          });
        }
        else if (result(self[key], `isState`)) {
          self[key].set(value);
        }
        else {
          self.set(key, value);
        }
        this.logger.info(`storage:(${self.getNamespace()}): set \`${key}\` for first time`);
      });

      const handle = curry((key, reason) => {
        if (reason instanceof NotFoundError || process.env.NODE_ENV !== `production` && reason.toString().includes(`MockNotFoundError`)) {
          this.logger.info(`storage(${self.getNamespace()}): no data for \`${key}\`, continuing`);
          return Promise.resolve();
        }
        this.logger.error(`storage(${self.getNamespace()}): failed to init \`${key}\``, reason);
        return Promise.reject(reason);
      });

      const keys = blockingKeys.get(target, prop);
      keys.forEach((key) => this.boundedStorage.get(self.getNamespace(), key)
        .then(set(key))
        .catch(handle(key)));
    });
  }
}
<|endoftext|>


<commit_before>'use strict';

/**
  * @desc new responsive lazyload image script, servering the image depending on parent-wrapper width and aspect-ratio parameter
  * html example
  * js init example: novicell.responsiveLazyloadImage.image();
  * js resize example: novicell.responsiveLazyloadImage.onResize();
  * js scroll example:
  * if($('.responsiveLazyload').length)
  *     novicell.responsiveLazyloadImage.image();
  * @author Tommy Pedersen - TPE, DLA & JHA
  * @return generates img and removes noscript image
  * @requires jquery > 1.11.0
  *
  For pretty loading of the image you can use this snippet of less
    .nc-grid-focalpointimagelink figure {
        background-position: center center;
        background-size: cover;

        img {
            opacity: 0;
            transition: opacity 0.2s ease-in;
        }
    }

Usecase:

                >

     */

var novicell = novicell || {};

novicell.responsiveLazyloadImage = novicell.responsiveLazyloadImage || function (){
    var lastRefreshWidth = 0;
    var refreshWidth = 50;

    function onScroll(){
        $('.responsiveLazyload').each(function () {
            loadImage($(this));
        });
    }

    function onLoad() {
        $('.responsiveLazyload').each(function () {
            var $figure = $(this).parent();

            if ($figure.visible(true) || $figure.data("load") === "always") {
                loadImage($(this), true);
            } else {
                constructPlaceholder($figure);
            }
        });
    }

    function onResize(callback) {
        if (window.innerWidth > lastRefreshWidth + refreshWidth || window.innerWidth < lastRefreshWidth - refreshWidth) {
            $('.lazyResizeReload').each(function () {
                constructImage($(this));
                constructPlaceholder($(this));
                if (typeof callback == 'function') {
                    callback();
                }
            });
            lastRefreshWidth = window.innerWidth;
        }
    }

    // Loads the image.
    function loadImage($element, isVisible) {
        var $this = $element;
        var $figure = $this.parent();

        if (isVisible || $figure.visible(true) || $this.data("load") === "always") {
            if ($this.first()) {
                $this.remove();
                constructImage($figure);
                lastRefreshWidth = window.innerWidth;
                $figure.addClass('lazyResizeReload');
            }
        }
    }

    function constructImage(figure) {
        var $image = new Image();
        var $figure = $(figure);

        //data variables and images settings
        var width, maxWidth, heightRatio, focalPoint, mode, filter, quality, height;
        var isBackgroundImage = false, forceHeight = false;

        var $parent = $figure.data('parent') ? $figure.closest($figure.data('parent')) : null;
        isBackgroundImage = $figure.data('is-background') ? true : false;
        width = $figure.width() !== 0 ? figure.width() : $figure.parent().width();
        width = $parent ? $parent.width() : width;
        heightRatio = $figure.data('height-ratio') !== 0 ? $figure.data('height-ratio') : null;
        height = $parent ? $parent.outerHeight() : null;
        forceHeight = $figure.data('force-height') !== 0 ? $figure.data('force-height') : null;
        focalPoint = $figure.data('focalpoint');
        mode = $figure.data('mode');
        filter = $figure.data('filter');
        quality = $figure.data('quality') || 80;

        var newImageSrc = $figure.data('src');
        newImageSrc += focalPoint ? nextQuerySign(newImageSrc) + "center=" + focalPoint : "";
        newImageSrc += mode ? nextQuerySign(newImageSrc) + "mode=" + mode : "";
        newImageSrc += filter ? nextQuerySign(newImageSrc) + "filter=" + filter : "";
        newImageSrc += nextQuerySign(newImageSrc) + "quality=" + quality;

        $figure.find('img').remove();

        // Append the image as a background or as a
        if(isBackgroundImage && $parent) {
            var bgSrc = newImageSrc;
            bgSrc += height ? nextQuerySign(bgSrc) + "height=" + height : "";
            bgSrc += mode ? nextQuerySign(bgSrc) + "width=" + width : "";

            $parent.css('background-image', 'url("'+ bgSrc +'")');

        }
        else {
            // Add attributes only needed when pretending an image
            maxWidth = $figure.data('original-width');
            if(width > maxWidth) {
                width = maxWidth;
                $figure.addClass('contain-width');
            }

            newImageSrc += mode ? nextQuerySign(newImageSrc) + "width=" + width : "";
            newImageSrc += height && !heightRatio && !forceHeight ? nextQuerySign(newImageSrc) + "height=" + height : "";
            newImageSrc += heightRatio && !forceHeight ? nextQuerySign(newImageSrc) + "height=" + heightRatio * width : "";
            newImageSrc += forceHeight && !heightRatio ? nextQuerySign(newImageSrc) + "height=" + forceHeight : "";

            $image.src = newImageSrc;
            $figure.prepend($image);
            $image = $figure.find('img');
            $image.css('opacity', '0');
            // Fade the image
            $image.on('load', function(event) {
                $image.css('opacity', '1');
            });

            $image.attr('class', $figure.data('class'));
            $image.attr('alt', $figure.data('alt'));
            $image.attr('title', $figure.data('title'));
            $image.attr('property', 'contentUrl');
        }
    }

    function nextQuerySign(url) {
        return url.indexOf("?") > -1 ? "&" : "?";
    }

    function constructPlaceholder(figure) {
        var $el = figure;
        var width, heightRatio, maxWidth;
        var height = 0;

        // Calc the height
        maxWidth = figure.data('original-width');
        width = figure.width() !== 0 ? figure.width() : $(figure).parent().width();
        width = width > maxWidth ? maxWidth : width;
        heightRatio = $el.data('height-ratio');

        if(width && heightRatio) {
            height = heightRatio * width;
        }

        // Set the height
        if(height > 0) {
            $el.css('minHeight', height);
        }
    }

    // public functions:
    return {
        onScroll: onScroll,
        onResize: onResize,
        onLoad: onLoad
    };
}();
<commit_msg>remove focal point js #82<commit_after><|endoftext|>


<commit_before>/**
 * Shopware 4.0
 * Copyright © 2012 shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 *
 * @category   Shopware
 * @package    Order
 * @subpackage Controller
 * @copyright  Copyright (c) 2012, shopware AG (http://www.shopware.de)
 * @version    $Id$
 * @author shopware AG
 */

//{namespace name=backend/order/main}

/**
 * Shopware Controller - Order list backend module
 *
 * The shopware order list controller handles all actions around the order list.
 * Listeners:
 *  - Search field => Fires when the user insert a search string into the search field to filter the grid store
 */
//{block name="backend/order/controller/list"}
Ext.define('Shopware.apps.Order.controller.List', {

    /**
     * Defines that this component is a extJs controller extension
     * @string
     */
    extend:'Ext.app.Controller',

    /**
     * Contains all snippets for the component
     * @object
     */
    snippets: {
        successTitle:'{s name=message/save/success_title}Successful{/s}',
        failureTitle:'{s name=message/save/error_title}Error{/s}',
        changeStatus: {
            successMessage: '{s name=message/status/success}The status has been changed successfully{/s}',
            failureMessage: '{s name=message/status/failure}An error has occurred while changing the status.{/s}'
        },
        deleteOrder: {
            title: '{s name=delete_order/title}Delete selected order{/s}',
            message: '{s name=delete_order/message}Are you sure you want to delete the selected order: {/s}',
            successTitle:'{s name=delete_order/success_message}Successful{/s}',
            successMessage:'{s name=delete_order/success_title}Order has been removed{/s}',
            failureTitle:'{s name=delete_order/error_title}Failure{/s}',
            failureMessage:'{s name=delete_order/error_message}An error has occurred while deleting:{/s}'
        },
        deletePosition: {
            title: '{s name=delete_position/title}Delete selected order position{/s}',
            message: '{s name=delete_position/message}Are you sure you want to delete the selected order: {/s}',
            successTitle:'{s name=delete_position/success_message}Successful{/s}',
            successMessage:'{s name=delete_position/success_title}Order position has been removed{/s}',
            failureTitle:'{s name=delete_position/error_title}Error{/s}',
            failureMessage:'{s name=delete_position/error_message}An error has occurred while deleting:{/s}'
        },

		growlMessage: '{s name=growlMessage}Order{/s}'

    },

    /**
    * all references to get the elements by the applicable selector
    */
    refs:[
       { ref:'orderListGrid', selector:'order-list-main-window order-list' },
       { ref:'orderPositionGrid', selector:'order-list-main-window order-position-grid' },
       { ref:'orderReceiptGrid', selector:'order-list-main-window order-list-navigation order-document-list' },
    ],

    /**
     * A template method that is called when your application boots.
     * It is called before the Application's launch function is executed
     * so gives a hook point to run any code before your Viewport is created.
     *
     * @return void
     */
    init:function () {
        var me = this;

        me.control({
            'order-list-main-window order-list': {
                deleteOrder: me.onDeleteOrder,
                openCustomer: me.onOpenCustomer,
                showBatch: me.onShowBatch,
                selectionchange: me.onSelectionChange,
                saveOrder: me.onSaveOrder
            },
            'order-position-grid': {
                openArticle: me.onOpenArticle,
                deletePosition: me.onDeletePosition
            }
        });

        me.callParent(arguments);
    },

    /**
     * Called when the user clicks the 'Update' button in the rowEditor
     * saves the current order with its changes
     * @param editor
     * @param event
     * @param store
     */
    onSaveOrder: function(editor, event, store) {
        var me = this,
            record, rawData,
            grid = me.getOrderListGrid();

        record = store.getAt(event.rowIdx);
        if(record == null) {
            return;
        }

        record.save({
            callback:function (data, operation) {
                var records = operation.getRecords(),
                    record = records[0],
                    proxyReader = record.getProxy().getReader(),
                    rawData = proxyReader.rawData;

                if ( operation.success === true ) {
                    Shopware.Notification.createGrowlMessage(me.snippets.successTitle, me.snippets.changeStatus.successMessage, me.snippets.growlMessage);
                    record.set('invoiceAmount', rawData.data.invoiceAmount);

                    //Check if a status mail is created and create a model with the returned data and open the mail window.
                    if (!Ext.isEmpty(rawData.data.mail) && !Ext.isEmpty(proxyReader.jsonData.data.mail.content)) {
                        var mail = Ext.create('Shopware.apps.Order.model.Mail', rawData.data.mail);
                        me.showOrderMail(mail)
                    }

                } else {
                    Shopware.Notification.createGrowlMessage(me.snippets.failureTitle, me.snippets.changeStatus.failureMessage + '
 ' + rawData.message, me.snippets.growlMessage)
                }
            }
        });
    },

    /**
     * Creates the batch window with a special mode, so only the mail panel will be displayed.
     *
     * @param mail
     */
    showOrderMail: function(mail) {
        var me = this;

        //open the order listing window
        me.mainWindow = me.getView('batch.Window').create({
            mail: mail,
            mode: 'single'
        }).show();
    },

    onShowBatch: function(grid) {
        var me = this;
        var records = grid.getSelectionModel().getSelection();
        //open the order listing window
        me.mainWindow = me.getView('batch.Window').create({
            orderStatusStore: grid.orderStatusStore,
            records: records,
            mode: 'multi'
        }).show();
    },

    onSelectionChange: function(selectionModel, selected, eOpts) {
        var me = this,
            positionGrid = me.getOrderPositionGrid(),
            receiptStore = Ext.create('Ext.data.Store', { model: 'Shopware.apps.Order.model.Receipt' }),
            positionStore = Ext.create('Ext.data.Store', { model: 'Shopware.apps.Order.model.Position' }),
            receiptGrid = me.getOrderReceiptGrid(),
            record = null;

        if (Ext.isArray(selected)) {
            record = selected[selected.length-1];
        } else {
            record = selected;
        }

        if (record instanceof Ext.data.Model && record.getReceipt() instanceof Ext.data.Store) {
            receiptStore = record.getReceipt();
        }
        if (record instanceof Ext.data.Model && record.getPositions() instanceof Ext.data.Store) {
            positionStore = record.getPositions();
        }

        receiptGrid.reconfigure(receiptStore);
        positionGrid.reconfigure(positionStore);

    },

    /**
     * Event listener method which fired when the user clicks the delete button
     * in the order list to delete a single order.
     * @param record
     * @return void
     */
    onDeleteOrder:function (record) {
        var me = this,
            store = me.subApplication.getStore('Order'),
            message = me.snippets.deleteOrder.message + ' ' + record.get('number'),
            title = me.snippets.deleteOrder.title;

        // we do not just delete - we are polite and ask the user if he is sure.
        Ext.MessageBox.confirm(title, message, function (response) {
            if ( response !== 'yes' ) {
                return;
            }
            record.destroy({
                callback: function(data, operation) {
                    var records = operation.getRecords(),
                        record = records[0],
                        rawData = record.getProxy().getReader().rawData;

                    if ( operation.success === true ) {
                        Shopware.Notification.createGrowlMessage(me.snippets.deleteOrder.successTitle,me.snippets.deleteOrder.successMessage, me.snippets.growlMessage);
                    } else {
                        Shopware.Notification.createGrowlMessage(me.snippets.deleteOrder.failureTitle, me.snippets.deleteOrder.failureMessage + ' ' + rawData.message, me.snippets.growlMessage);
                    }
                    store.load();
                }
            });
        });
    },

    /**
     * Event listener method which fired when the user clicks the customer button
     * in the order list to show the customer detail page.
     *
     * @param [Ext.data.Model] record - The row record
     */
    onOpenCustomer: function(record) {
        Shopware.app.Application.addSubApplication({
            name: 'Shopware.apps.Customer',
            action: 'detail',
            params: {
                customerId: record.get('customerId')
            }
        });
    },

    /**
     * Event listener method which is fired when the user clicks the
     * action column icon to open the article detail page of the order position article.
     *
     * @param [Ext.data.Model] record - The row record
     */
    onOpenArticle: function(record) {
        Shopware.app.Application.addSubApplication({
            name: 'Shopware.apps.Article',
            action: 'detail',
            params: {
                articleId: record.get('articleId')
            }
        });
    },

    /**
     * Event listener method which is fired when the user clicks the
     * action column icon to delete a single order position.
     *
     * @param [Ext.data.Model] record - The row record
     * @param [Ext.data.Store] store - The position store
     * @param [object] options - can contain an callback function
     * @callback Return parameters order, position, store
     */
    onDeletePosition: function(position, store, options) {
        var me = this,
            orderPositionGrid = me.getOrderPositionGrid(),
            order = me.subApplication.getStore('Order').getById(position.get('orderId')),
            message = me.snippets.deletePosition.message + ' ' + order.get('number'),
            title = me.snippets.deletePosition.title;

        // we do not just delete - we are polite and ask the user if he is sure.
        Ext.MessageBox.confirm(title, message, function (response) {
            if ( response !== 'yes' ) {
                return;
            }
            if (orderPositionGrid) {
                orderPositionGrid.setLoading(true);
            }
            position.destroy({
                params: {
                    orderID: position.get('orderId')
                },
                callback: function(data, operation) {
                    var records = operation.getRecords(),
                        record = records[0],
                        rawData = record.getProxy().getReader().rawData;

                    if (orderPositionGrid) {
                        orderPositionGrid.setLoading(true);
                    }
                    if ( operation.success === true ) {
                        Shopware.Notification.createGrowlMessage(me.snippets.deletePosition.successTitle,me.snippets.deletePosition.successMessage, me.snippets.growlMessage);

                        store.remove(position);
                        order.set('invoiceAmount', rawData.data.invoiceAmount);
                        if (options !== Ext.undefined && Ext.isFunction(options.callback)) {
                            options.callback(order);
                        }

                    } else {
                        Shopware.Notification.createGrowlMessage(me.snippets.deletePosition.failureTitle, me.snippets.deletePosition.failureMessage + ' ' + rawData.message, me.snippets.growlMessage);
                    }
                }
            });
        });
    }

});
//{/block}
<commit_msg>SW-5804 fix row selection for batchmode in order module<commit_after>/**
 * Shopware 4.0
 * Copyright © 2012 shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 *
 * @category   Shopware
 * @package    Order
 * @subpackage Controller
 * @copyright  Copyright (c) 2012, shopware AG (http://www.shopware.de)
 * @version    $Id$
 * @author shopware AG
 */

//{namespace name=backend/order/main}

/**
 * Shopware Controller - Order list backend module
 *
 * The shopware order list controller handles all actions around the order list.
 * Listeners:
 *  - Search field => Fires when the user insert a search string into the search field to filter the grid store
 */
//{block name="backend/order/controller/list"}
Ext.define('Shopware.apps.Order.controller.List', {

    /**
     * Defines that this component is a extJs controller extension
     * @string
     */
    extend:'Ext.app.Controller',

    /**
     * Contains all snippets for the component
     * @object
     */
    snippets: {
        successTitle:'{s name=message/save/success_title}Successful{/s}',
        failureTitle:'{s name=message/save/error_title}Error{/s}',
        changeStatus: {
            successMessage: '{s name=message/status/success}The status has been changed successfully{/s}',
            failureMessage: '{s name=message/status/failure}An error has occurred while changing the status.{/s}'
        },
        deleteOrder: {
            title: '{s name=delete_order/title}Delete selected order{/s}',
            message: '{s name=delete_order/message}Are you sure you want to delete the selected order: {/s}',
            successTitle:'{s name=delete_order/success_message}Successful{/s}',
            successMessage:'{s name=delete_order/success_title}Order has been removed{/s}',
            failureTitle:'{s name=delete_order/error_title}Failure{/s}',
            failureMessage:'{s name=delete_order/error_message}An error has occurred while deleting:{/s}'
        },
        deletePosition: {
            title: '{s name=delete_position/title}Delete selected order position{/s}',
            message: '{s name=delete_position/message}Are you sure you want to delete the selected order: {/s}',
            successTitle:'{s name=delete_position/success_message}Successful{/s}',
            successMessage:'{s name=delete_position/success_title}Order position has been removed{/s}',
            failureTitle:'{s name=delete_position/error_title}Error{/s}',
            failureMessage:'{s name=delete_position/error_message}An error has occurred while deleting:{/s}'
        },

		growlMessage: '{s name=growlMessage}Order{/s}'

    },

    /**
    * all references to get the elements by the applicable selector
    */
    refs:[
       { ref:'orderListGrid', selector:'order-list-main-window order-list' },
       { ref:'orderPositionGrid', selector:'order-list-main-window order-position-grid' },
       { ref:'orderReceiptGrid', selector:'order-list-main-window order-list-navigation order-document-list' },
    ],

    /**
     * A template method that is called when your application boots.
     * It is called before the Application's launch function is executed
     * so gives a hook point to run any code before your Viewport is created.
     *
     * @return void
     */
    init:function () {
        var me = this;

        me.control({
            'order-list-main-window order-list': {
                deleteOrder: me.onDeleteOrder,
                openCustomer: me.onOpenCustomer,
                showBatch: me.onShowBatch,
                selectionchange: me.onSelectionChange,
                saveOrder: me.onSaveOrder
            },
            'order-position-grid': {
                openArticle: me.onOpenArticle,
                deletePosition: me.onDeletePosition
            }
        });

        me.callParent(arguments);
    },

    /**
     * Called when the user clicks the 'Update' button in the rowEditor
     * saves the current order with its changes
     * @param editor
     * @param event
     * @param store
     */
    onSaveOrder: function(editor, event, store) {
        var me = this,
            record, rawData,
            grid = me.getOrderListGrid();

        record = store.getAt(event.rowIdx);
        if(record == null) {
            return;
        }

        record.save({
            callback:function (data, operation) {
                var records = operation.getRecords(),
                    record = records[0],
                    proxyReader = record.getProxy().getReader(),
                    rawData = proxyReader.rawData;

                if ( operation.success === true ) {
                    Shopware.Notification.createGrowlMessage(me.snippets.successTitle, me.snippets.changeStatus.successMessage, me.snippets.growlMessage);
                    record.set('invoiceAmount', rawData.data.invoiceAmount);

                    //Check if a status mail is created and create a model with the returned data and open the mail window.
                    if (!Ext.isEmpty(rawData.data.mail) && !Ext.isEmpty(proxyReader.jsonData.data.mail.content)) {
                        var mail = Ext.create('Shopware.apps.Order.model.Mail', rawData.data.mail);
                        me.showOrderMail(mail)
                    }

                } else {
                    Shopware.Notification.createGrowlMessage(me.snippets.failureTitle, me.snippets.changeStatus.failureMessage + '
 ' + rawData.message, me.snippets.growlMessage)
                }
                grid.getSelectionModel().deselectAll(false);
            }
        });
    },

    /**
     * Creates the batch window with a special mode, so only the mail panel will be displayed.
     *
     * @param mail
     */
    showOrderMail: function(mail) {
        var me = this;

        //open the order listing window
        me.mainWindow = me.getView('batch.Window').create({
            mail: mail,
            mode: 'single'
        }).show();
    },

    onShowBatch: function(grid) {
        var me = this;
        var records = grid.getSelectionModel().getSelection();
        //open the order listing window
        me.mainWindow = me.getView('batch.Window').create({
            orderStatusStore: grid.orderStatusStore,
            records: records,
            mode: 'multi'
        }).show();
    },

    onSelectionChange: function(selectionModel, selected, eOpts) {
        var me = this,
            positionGrid = me.getOrderPositionGrid(),
            receiptStore = Ext.create('Ext.data.Store', { model: 'Shopware.apps.Order.model.Receipt' }),
            positionStore = Ext.create('Ext.data.Store', { model: 'Shopware.apps.Order.model.Position' }),
            receiptGrid = me.getOrderReceiptGrid(),
            record = null;

        if (Ext.isArray(selected)) {
            record = selected[selected.length-1];
        } else {
            record = selected;
        }

        if (record instanceof Ext.data.Model && record.getReceipt() instanceof Ext.data.Store) {
            receiptStore = record.getReceipt();
        }
        if (record instanceof Ext.data.Model && record.getPositions() instanceof Ext.data.Store) {
            positionStore = record.getPositions();
        }

        receiptGrid.reconfigure(receiptStore);
        positionGrid.reconfigure(positionStore);

    },

    /**
     * Event listener method which fired when the user clicks the delete button
     * in the order list to delete a single order.
     * @param record
     * @return void
     */
    onDeleteOrder:function (record) {
        var me = this,
            store = me.subApplication.getStore('Order'),
            message = me.snippets.deleteOrder.message + ' ' + record.get('number'),
            title = me.snippets.deleteOrder.title;

        // we do not just delete - we are polite and ask the user if he is sure.
        Ext.MessageBox.confirm(title, message, function (response) {
            if ( response !== 'yes' ) {
                return;
            }
            record.destroy({
                callback: function(data, operation) {
                    var records = operation.getRecords(),
                        record = records[0],
                        rawData = record.getProxy().getReader().rawData;

                    if ( operation.success === true ) {
                        Shopware.Notification.createGrowlMessage(me.snippets.deleteOrder.successTitle,me.snippets.deleteOrder.successMessage, me.snippets.growlMessage);
                    } else {
                        Shopware.Notification.createGrowlMessage(me.snippets.deleteOrder.failureTitle, me.snippets.deleteOrder.failureMessage + ' ' + rawData.message, me.snippets.growlMessage);
                    }
                    store.load();
                }
            });
        });
    },

    /**
     * Event listener method which fired when the user clicks the customer button
     * in the order list to show the customer detail page.
     *
     * @param [Ext.data.Model] record - The row record
     */
    onOpenCustomer: function(record) {
        Shopware.app.Application.addSubApplication({
            name: 'Shopware.apps.Customer',
            action: 'detail',
            params: {
                customerId: record.get('customerId')
            }
        });
    },

    /**
     * Event listener method which is fired when the user clicks the
     * action column icon to open the article detail page of the order position article.
     *
     * @param [Ext.data.Model] record - The row record
     */
    onOpenArticle: function(record) {
        Shopware.app.Application.addSubApplication({
            name: 'Shopware.apps.Article',
            action: 'detail',
            params: {
                articleId: record.get('articleId')
            }
        });
    },

    /**
     * Event listener method which is fired when the user clicks the
     * action column icon to delete a single order position.
     *
     * @param [Ext.data.Model] record - The row record
     * @param [Ext.data.Store] store - The position store
     * @param [object] options - can contain an callback function
     * @callback Return parameters order, position, store
     */
    onDeletePosition: function(position, store, options) {
        var me = this,
            orderPositionGrid = me.getOrderPositionGrid(),
            order = me.subApplication.getStore('Order').getById(position.get('orderId')),
            message = me.snippets.deletePosition.message + ' ' + order.get('number'),
            title = me.snippets.deletePosition.title;

        // we do not just delete - we are polite and ask the user if he is sure.
        Ext.MessageBox.confirm(title, message, function (response) {
            if ( response !== 'yes' ) {
                return;
            }
            if (orderPositionGrid) {
                orderPositionGrid.setLoading(true);
            }
            position.destroy({
                params: {
                    orderID: position.get('orderId')
                },
                callback: function(data, operation) {
                    var records = operation.getRecords(),
                        record = records[0],
                        rawData = record.getProxy().getReader().rawData;

                    if (orderPositionGrid) {
                        orderPositionGrid.setLoading(true);
                    }
                    if ( operation.success === true ) {
                        Shopware.Notification.createGrowlMessage(me.snippets.deletePosition.successTitle,me.snippets.deletePosition.successMessage, me.snippets.growlMessage);

                        store.remove(position);
                        order.set('invoiceAmount', rawData.data.invoiceAmount);
                        if (options !== Ext.undefined && Ext.isFunction(options.callback)) {
                            options.callback(order);
                        }

                    } else {
                        Shopware.Notification.createGrowlMessage(me.snippets.deletePosition.failureTitle, me.snippets.deletePosition.failureMessage + ' ' + rawData.message, me.snippets.growlMessage);
                    }
                }
            });
        });
    }

});
//{/block}
<|endoftext|>


<commit_before>'use strict';

var Node = require('../node');

var TYPE = 'data-observatory-measure';
var PARAMS = {
    source: Node.PARAM.NODE(Node.GEOMETRY.POINT, Node.GEOMETRY.POLYGON),
    final_column: Node.PARAM.STRING(),
    segment_name: Node.PARAM.STRING(),
    percent: Node.PARAM.NULLABLE(Node.PARAM.BOOLEAN())
};

var DataObservatoryMeasure = Node.create(TYPE, PARAMS, { cache: true, lazy: true });

module.exports = DataObservatoryMeasure;

DataObservatoryMeasure.prototype.sql = function() {
    return queryTemplate({
        columns: this.source.getColumns().join(', '),
        source: this.source.getQuery(false),
        final_column: this.final_column,
        segment_name: this.segment_name,
        percent: this.percent ? 'denominator' : undefined
    });
};

var queryTemplate = Node.template([
    'WITH _summary AS ( ',
    '  SELECT ST_SetSRID(ST_Extent(the_geom), 4326) extent, ',
    '         count(*)::INT numgeoms, ',
    '         ARRAY_AGG(DISTINCT ST_GeometryType(the_geom)) AS geom_types, ',
    '         ARRAY_AGG((the_geom, cartodb_id)::geomval) geomvals ',
    '  FROM ({{=it.source}}) AS _camshaft_do_measure_analysis',
    '  ), ',
    '_meta AS ( ',
    '  SELECT cdb_dataservices_client.OBS_GetMeta( ',
    '            extent, ',
    '            (\'[{"numer_id": "{{=it.segment_name}}"}]\')::JSON ',
    '          , null, null, numgeoms) as meta FROM _summary ',
    '  ), ',
    '_data AS ( ',
    '  SELECT id, (data->0->>\'value\')::Numeric {{=it.final_column}} ',
    '  FROM cdb_dataservices_client.OBS_GetData( ',
    '    (SELECT geomvals FROM _summary), ',
    '    (SELECT jsonb_set(meta::jsonb, \'{0,normalization}\', ',
    '        CASE ',
    '          WHEN meta->0->>\'numer_aggregate\' = \'sum\' AND geom_types = \'{ST_Point}\' ',
    '            THEN \'"area"\'::jsonb ',
    '          ELSE \'"prenormalized"\'::jsonb ',
    '        END ',
    '    )::json FROM _meta, _summary) ',
    '  )) ',
    'SELECT {{=it.columns}}, _data.{{=it.final_column}} ',
    'FROM _data, ({{=it.source}}) AS _camshaft_do_measure_analysis ',
    'WHERE _camshaft_do_measure_analysis.cartodb_id = _data.id '
].join('\n'));
<commit_msg>use less-likely-to-conflict column in DO camshaft node.  fixes #264<commit_after>'use strict';

var Node = require('../node');

var TYPE = 'data-observatory-measure';
var PARAMS = {
    source: Node.PARAM.NODE(Node.GEOMETRY.POINT, Node.GEOMETRY.POLYGON),
    final_column: Node.PARAM.STRING(),
    segment_name: Node.PARAM.STRING(),
    percent: Node.PARAM.NULLABLE(Node.PARAM.BOOLEAN())
};

var DataObservatoryMeasure = Node.create(TYPE, PARAMS, { cache: true, lazy: true });

module.exports = DataObservatoryMeasure;

DataObservatoryMeasure.prototype.sql = function() {
    return queryTemplate({
        columns: this.source.getColumns().join(', '),
        source: this.source.getQuery(false),
        final_column: this.final_column,
        segment_name: this.segment_name,
        percent: this.percent ? 'denominator' : undefined
    });
};

var queryTemplate = Node.template([
    'WITH _summary AS ( ',
    '  SELECT ST_SetSRID(ST_Extent(the_geom), 4326) extent, ',
    '         count(*)::INT numgeoms, ',
    '         ARRAY_AGG(DISTINCT ST_GeometryType(the_geom)) AS geom_types, ',
    '         ARRAY_AGG((the_geom, cartodb_id)::geomval) geomvals ',
    '  FROM ({{=it.source}}) AS _camshaft_do_measure_analysis',
    '  ), ',
    '_meta AS ( ',
    '  SELECT cdb_dataservices_client.OBS_GetMeta( ',
    '            extent, ',
    '            (\'[{"numer_id": "{{=it.segment_name}}"}]\')::JSON ',
    '          , null, null, numgeoms) as meta FROM _summary ',
    '  ), ',
    '_data AS ( ',
    '  SELECT id AS __obs_id__, (data->0->>\'value\')::Numeric {{=it.final_column}} ',
    '  FROM cdb_dataservices_client.OBS_GetData( ',
    '    (SELECT geomvals FROM _summary), ',
    '    (SELECT jsonb_set(meta::jsonb, \'{0,normalization}\', ',
    '        CASE ',
    '          WHEN meta->0->>\'numer_aggregate\' = \'sum\' AND geom_types = \'{ST_Point}\' ',
    '            THEN \'"area"\'::jsonb ',
    '          ELSE \'"prenormalized"\'::jsonb ',
    '        END ',
    '    )::json FROM _meta, _summary) ',
    '  )) ',
    'SELECT {{=it.columns}}, _data.{{=it.final_column}} ',
    'FROM _data, ({{=it.source}}) AS _camshaft_do_measure_analysis ',
    'WHERE _camshaft_do_measure_analysis.cartodb_id = _data.__obs_id__ '
].join('\n'));
<|endoftext|>


<commit_before>define([
        'config',
        'mustache',
        'text!views/FindAChurch/Search.html'
        ],
        function(config, Mustache, template){

    return Backbone.View.extend({
        initialize: function(){
            _.bindAll(this, 'location_keyup', 'geocode', 'do_search')
            window.app.geocoder = new google.maps.Geocoder();
        },
        render: function(){
            this.$el.html(Mustache.render(template))

            // Attach search event handler to search button and text box
            $('.search').click(this.do_search)
            $('.location').keyup(this.location_keyup)
            $('#radius').on('change', this.do_search)
            // $('#radius').on('change', ($('.search').click())

//           Improve User Interface:
//            	   - Try to be able to guess which unit of distance (Mi or KM) they prefer based on some input from the user. TODO: Figure out the right order of if-clauses to use below, and outline it in comments in the code.
//   TODO         	 * Event Handler: On page load
//   TODO       	   * If the distance unit cookie is set, set the distance units in the form based on what is in the cookie.
//   TODO      	       * Else, on page load, before the person searches, guess what units they want based on one of the following:
//   TODO      	         * First try the users' browser's geolocation information. Google for "calculate distance units from geolocation" to see how others have done this. You can geocode the location using window.app.geocoder = new google.maps.Geocoder(); window.app.geocoder.geocode(..., then filter (using the Underscore.js _.filter() method) for results[0].address_components[x].types.short_name == 'US', then if the user is in one of the countries that use miles, select "miles" in the form and save it to the cookie.
//   TODO      	         * Next try figuring it based on the country in which they are searching.
//   TODO      	         * Next, try the browser country or language setting.
//   TODO      	         * Maybe try their IP address (but this might be hard to do from JavaScript in the browser).
            },

        location_keyup:function(event){
            if (event.which == 13){
                this.do_search(event)
            }
        },
        geocode: function ( address_line){
        	var thiz=this
            window.app.geocoder.geocode( { 'address': $('.location').val()}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                	  // Use Circle() as a helper to avoid doing math.
//         		    // Convert radius*units to meters
//         		    var radius = $('#radius').val();
//         		    var units = $('#units').val();
//         		    var distance;
//         		    if (units == 'miles'){
//         		        distance = radius * 1609.344;
//         		    } else if (units == 'km') {
//         		        distance = radius * 1000;
//         		    }
        		    // Create an instance of Circle() with the selected radius
        		    var loc = results[0].geometry.location;
        		    var center = new google.maps.LatLng(loc.lat(), loc.lng());
        		    var circle = new google.maps.Circle({radius: distance, center: center});
        		    // Center and zoom the map to the bounds of the circle.
        		    window.app.map.setCenter(loc);
        		    window.app.map.fitBounds(circle.getBounds()); // this sets the zoom
        		    // Plot congs on map
        		    //thiz.plot_congs_on_map()
                    //TODO  Send the request to Google; if Google says the location is ambiguous, then use one of the location methods above (geolocation, etc.) to send Google a hint about in which country the user is attempting to search.
             		//TODO  Event handler: On search results being returned to the browser from the Google Maps API, Google's geocode responses state in which country the searched-for location is found, so after they search, you can set their distance units for them (in a cookie and in the form) based on the country, unless (in a cookie you can see) they have already selected a distance unit manually.

                } else {
                    alert("Geocode was not successful for the following reason: " + status);
                }
            });

		},
        do_search: function( event ){
            event.preventDefault()
            // If user submitted an address, put that address into this.model
            // Use location user entered
            // TODO: Start here.  Create a new Backbone model named
            //    search_params and update it [DONE], then update map bounds when it changes.  Create this model
            //    in main.js, then pass it into SearchView as its model, and into
            //    MapView via new View([options]) syntax (accessed as this.options.name).

            // Convert radius*units to meters
            var radius = $('#radius').val();
            var units = $('#units').val();
            var distance;
            if (units == 'miles'){
                distance = radius * 1609.344;
            } else if (units == 'km') {
                distance = radius * 1000;
            }
            // Put the above variables into this.model in one action so there's only one change event
            this.model.set({
                location:$('.location').val(),
                radius:radius,
                distance:distance,
                units:units
            })

          //  TODO   Event handler: On search form submission, record the currently-selected distance unit in a cookie, and record there whether they selected it manually or not.
//             // TODO: Geocode location, then set new map center in MapView.js
//             location = window.app.map.getCenter().toUrlValue()
            // TODO: Move this code to MapView.js
//             this.geocode(location)
        }
    });
});<commit_msg>Fixed indentation<commit_after>define([
        'config',
        'mustache',
        'text!views/FindAChurch/Search.html'
        ],
        function(config, Mustache, template){

    return Backbone.View.extend({
        initialize: function(){
            _.bindAll(this, 'location_keyup', 'geocode', 'do_search')
            window.app.geocoder = new google.maps.Geocoder();
        },
        render: function(){
            this.$el.html(Mustache.render(template))

            // Attach search event handler to search button and text box
            $('.search').click(this.do_search)
            $('.location').keyup(this.location_keyup)
            $('#radius').on('change', this.do_search)
            // $('#radius').on('change', ($('.search').click())

            // TODO: Improve User Interface:
            // TODO: - Try to be able to guess which unit of distance (Mi or KM) they prefer based on some input from the user. TODO: Figure out the right order of if-clauses to use below, and outline it in comments in the code.
            // TODO:   * Event Handler: On page load
            // TODO:     * If the distance unit cookie is set, set the distance units in the form based on what is in the cookie.
            // TODO:     * Else, on page load, before the person searches, guess what units they want based on one of the following:
            // TODO:       * First try the users' browser's geolocation information. Google for "calculate distance units from geolocation" to see how others have done this. You can geocode the location using window.app.geocoder = new google.maps.Geocoder(); window.app.geocoder.geocode(..., then filter (using the Underscore.js _.filter() method) for results[0].address_components[x].types.short_name == 'US', then if the user is in one of the countries that use miles, select "miles" in the form and save it to the cookie.
            // TODO:       * Next try figuring it based on the country in which they are searching.
            // TODO:       * Next, try the browser country or language setting.
            // TODO:       * Maybe try their IP address (but this might be hard to do from JavaScript in the browser).
        },
        location_keyup:function(event){
            if (event.which == 13){
                this.do_search(event)
            }
        },
        geocode: function ( address_line){
        	var thiz=this
            window.app.geocoder.geocode( { 'address': $('.location').val()}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                	  // Use Circle() as a helper to avoid doing math.
//         		    // Convert radius*units to meters
//         		    var radius = $('#radius').val();
//         		    var units = $('#units').val();
//         		    var distance;
//         		    if (units == 'miles'){
//         		        distance = radius * 1609.344;
//         		    } else if (units == 'km') {
//         		        distance = radius * 1000;
//         		    }
        		    // Create an instance of Circle() with the selected radius
        		    var loc = results[0].geometry.location;
        		    var center = new google.maps.LatLng(loc.lat(), loc.lng());
        		    var circle = new google.maps.Circle({radius: distance, center: center});
        		    // Center and zoom the map to the bounds of the circle.
        		    window.app.map.setCenter(loc);
        		    window.app.map.fitBounds(circle.getBounds()); // this sets the zoom
        		    // Plot congs on map
        		    //thiz.plot_congs_on_map()
                    // TODO: Send the request to Google; if Google says the location is ambiguous, then use one of the location methods above (geolocation, etc.) to send Google a hint about in which country the user is attempting to search.
             		// TODO: Event handler: On search results being returned to the browser from the Google Maps API, Google's geocode responses state in which country the searched-for location is found, so after they search, you can set their distance units for them (in a cookie and in the form) based on the country, unless (in a cookie you can see) they have already selected a distance unit manually.
                } else {
                    alert("Geocode was not successful for the following reason: " + status);
                }
            });
		},
        do_search: function( event ){
            event.preventDefault()
            // If user submitted an address, put that address into this.model
            // Use location user entered
            // TODO: Start here.  Create a new Backbone model named
            //    search_params and update it [DONE], then update map bounds when it changes.  Create this model
            //    in main.js, then pass it into SearchView as its model, and into
            //    MapView via new View([options]) syntax (accessed as this.options.name).

            // Convert radius*units to meters
            var radius = $('#radius').val();
            var units = $('#units').val();
            var distance;
            if (units == 'miles'){
                distance = radius * 1609.344;
            } else if (units == 'km') {
                distance = radius * 1000;
            }
            // Put the above variables into this.model in one action so there's only one change event
            this.model.set({
                location:$('.location').val(),
                radius:radius,
                distance:distance,
                units:units
            })

            // TODO: Event handler: On search form submission, record the currently-selected distance unit in a cookie, and record there whether they selected it manually or not.
            // TODO: Geocode location, then set new map center in MapView.js
//             location = window.app.map.getCenter().toUrlValue()
            // TODO: Move this code to MapView.js
//             this.geocode(location)
        }
    });
});<|endoftext|>


<commit_before>var mysql = require('../index.js');

var EventEmitter = require('events').EventEmitter;
var Util = require('util');
var PoolConnection = require('./pool_connection.js');
var Queue = require('denque');
var Connection = require('./connection.js');

module.exports = Pool;

Util.inherits(Pool, EventEmitter);
function Pool(options) {
  EventEmitter.call(this);
  this.config = options.config;
  this.config.connectionConfig.pool = this;

  this._allConnections = new Queue();
  this._freeConnections = new Queue();
  this._connectionQueue = new Queue();
  this._closed = false;
}

Pool.prototype.getConnection = function(cb) {
  if (this._closed) {
    return process.nextTick(function() {
      return cb(new Error('Pool is closed.'));
    });
  }

  var connection;

  if (this._freeConnections.length > 0) {
    connection = this._freeConnections.shift();

    return process.nextTick(function() {
      return cb(null, connection);
    });
  }

  if (
    this.config.connectionLimit === 0 ||
    this._allConnections.length < this.config.connectionLimit
  ) {
    connection = new PoolConnection(this, {
      config: this.config.connectionConfig
    });

    this._allConnections.push(connection);

    return connection.connect(
      function(err) {
        if (this._closed) {
          return cb(new Error('Pool is closed.'));
        }
        if (err) {
          return cb(err);
        }

        this.emit('connection', connection);
        return cb(null, connection);
      }.bind(this)
    );
  }

  if (!this.config.waitForConnections) {
    return process.nextTick(function() {
      return cb(new Error('No connections available.'));
    });
  }

  if (
    this.config.queueLimit &&
    this._connectionQueue.length >= this.config.queueLimit
  ) {
    return cb(new Error('Queue limit reached.'));
  }

  this.emit('enqueue');
  return this._connectionQueue.push(cb);
};

Pool.prototype.releaseConnection = function(connection) {
  var cb;

  if (!connection._pool) {
    // The connection has been removed from the pool and is no longer good.
    if (this._connectionQueue.length) {
      cb = this._connectionQueue.shift();

      process.nextTick(this.getConnection.bind(this, cb));
    }
  } else if (this._connectionQueue.length) {
    cb = this._connectionQueue.shift();

    process.nextTick(cb.bind(null, null, connection));
  } else {
    this._freeConnections.push(connection);
  }
};

Pool.prototype.end = function(cb) {
  this._closed = true;

  if (typeof cb != 'function') {
    cb = function(err) {
      if (err) {
        throw err;
      }
    };
  }

  var calledBack = false;
  var closedConnections = 0;
  var connection;

  var endCB = function(err) {
    if (calledBack) {
      return;
    }

    if (err || ++closedConnections >= this._allConnections.length) {
      calledBack = true;
      cb(err);
      return;
    }
  }.bind(this);

  if (this._allConnections.length === 0) {
    endCB();
    return;
  }

  for (var i = 0; i < this._allConnections.length; i++) {
    connection = this._allConnections.get(i);
    connection._realEnd(endCB);
  }
};

Pool.prototype.query = function(sql, values, cb) {
  var cmdQuery = Connection.createQuery(
    sql,
    values,
    cb,
    this.config.connectionConfig
  );
  cmdQuery.namedPlaceholders = this.config.connectionConfig.namedPlaceholders;

  this.getConnection(function(err, conn) {
    if (err) {
      if (typeof cmdQuery.onResult === 'function') {
        cmdQuery.onResult(err);
      } else {
        cmdQuery.emit('error', err);
      }
      return;
    }

    conn.query(cmdQuery).once('end', function() {
      conn.release();
    });
  });
  return cmdQuery;
};

Pool.prototype.execute = function(sql, values, cb) {
  var useNamedPlaceholders = this.config.connectionConfig.namedPlaceholders;

  // TODO construct execute command first here and pass it to connection.execute
  // so that polymorphic arguments logic is there in one place
  if (typeof values == 'function') {
    cb = values;
    values = [];
  }

  this.getConnection(function(err, conn) {
    if (err) {
      return cb(err);
    }

    const executeCmd = conn.execute(sql, values, cb);
    executeCmd.once('end', function() {
      conn.release();
    });
  });
};

Pool.prototype._removeConnection = function(connection) {
  // Remove connection from all connections
  spliceConnection(this._allConnections, connection);

  // Remove connection from free connections
  spliceConnection(this._freeConnections, connection);

  this.releaseConnection(connection);
};

Pool.prototype.format = function(sql, values) {
  return mysql.format(
    sql,
    values,
    this.config.connectionConfig.stringifyObjects,
    this.config.connectionConfig.timezone
  );
};

Pool.prototype.escape = function(value) {
  return mysql.escape(
    value,
    this.config.connectionConfig.stringifyObjects,
    this.config.connectionConfig.timezone
  );
};

Pool.prototype.escapeId = function escapeId(value) {
  return mysql.escapeId(value, false);
};

function spliceConnection(queue, connection) {
  var len = queue.length;
  if (len) {
    if (queue.get(len - 1) === connection) {
      queue.pop();
    } else {
      for (; --len; ) {
        if (queue.get(0) === connection) {
          queue.shift();
          break;
        }
        queue.push(queue.shift());
      }
    }
  }
}
<commit_msg>Improve performance of removing connections from pools<commit_after>var mysql = require('../index.js');

var EventEmitter = require('events').EventEmitter;
var Util = require('util');
var PoolConnection = require('./pool_connection.js');
var Queue = require('denque');
var Connection = require('./connection.js');

module.exports = Pool;

Util.inherits(Pool, EventEmitter);
function Pool(options) {
  EventEmitter.call(this);
  this.config = options.config;
  this.config.connectionConfig.pool = this;

  this._allConnections = new Queue();
  this._freeConnections = new Queue();
  this._connectionQueue = new Queue();
  this._closed = false;
}

Pool.prototype.getConnection = function(cb) {
  if (this._closed) {
    return process.nextTick(function() {
      return cb(new Error('Pool is closed.'));
    });
  }

  var connection;

  if (this._freeConnections.length > 0) {
    connection = this._freeConnections.shift();

    return process.nextTick(function() {
      return cb(null, connection);
    });
  }

  if (
    this.config.connectionLimit === 0 ||
    this._allConnections.length < this.config.connectionLimit
  ) {
    connection = new PoolConnection(this, {
      config: this.config.connectionConfig
    });

    this._allConnections.push(connection);

    return connection.connect(
      function(err) {
        if (this._closed) {
          return cb(new Error('Pool is closed.'));
        }
        if (err) {
          return cb(err);
        }

        this.emit('connection', connection);
        return cb(null, connection);
      }.bind(this)
    );
  }

  if (!this.config.waitForConnections) {
    return process.nextTick(function() {
      return cb(new Error('No connections available.'));
    });
  }

  if (
    this.config.queueLimit &&
    this._connectionQueue.length >= this.config.queueLimit
  ) {
    return cb(new Error('Queue limit reached.'));
  }

  this.emit('enqueue');
  return this._connectionQueue.push(cb);
};

Pool.prototype.releaseConnection = function(connection) {
  var cb;

  if (!connection._pool) {
    // The connection has been removed from the pool and is no longer good.
    if (this._connectionQueue.length) {
      cb = this._connectionQueue.shift();

      process.nextTick(this.getConnection.bind(this, cb));
    }
  } else if (this._connectionQueue.length) {
    cb = this._connectionQueue.shift();

    process.nextTick(cb.bind(null, null, connection));
  } else {
    this._freeConnections.push(connection);
  }
};

Pool.prototype.end = function(cb) {
  this._closed = true;

  if (typeof cb != 'function') {
    cb = function(err) {
      if (err) {
        throw err;
      }
    };
  }

  var calledBack = false;
  var closedConnections = 0;
  var connection;

  var endCB = function(err) {
    if (calledBack) {
      return;
    }

    if (err || ++closedConnections >= this._allConnections.length) {
      calledBack = true;
      cb(err);
      return;
    }
  }.bind(this);

  if (this._allConnections.length === 0) {
    endCB();
    return;
  }

  for (var i = 0; i < this._allConnections.length; i++) {
    connection = this._allConnections.get(i);
    connection._realEnd(endCB);
  }
};

Pool.prototype.query = function(sql, values, cb) {
  var cmdQuery = Connection.createQuery(
    sql,
    values,
    cb,
    this.config.connectionConfig
  );
  cmdQuery.namedPlaceholders = this.config.connectionConfig.namedPlaceholders;

  this.getConnection(function(err, conn) {
    if (err) {
      if (typeof cmdQuery.onResult === 'function') {
        cmdQuery.onResult(err);
      } else {
        cmdQuery.emit('error', err);
      }
      return;
    }

    conn.query(cmdQuery).once('end', function() {
      conn.release();
    });
  });
  return cmdQuery;
};

Pool.prototype.execute = function(sql, values, cb) {
  var useNamedPlaceholders = this.config.connectionConfig.namedPlaceholders;

  // TODO construct execute command first here and pass it to connection.execute
  // so that polymorphic arguments logic is there in one place
  if (typeof values == 'function') {
    cb = values;
    values = [];
  }

  this.getConnection(function(err, conn) {
    if (err) {
      return cb(err);
    }

    const executeCmd = conn.execute(sql, values, cb);
    executeCmd.once('end', function() {
      conn.release();
    });
  });
};

Pool.prototype._removeConnection = function(connection) {
  // Remove connection from all connections
  spliceConnection(this._allConnections, connection);

  // Remove connection from free connections
  spliceConnection(this._freeConnections, connection);

  this.releaseConnection(connection);
};

Pool.prototype.format = function(sql, values) {
  return mysql.format(
    sql,
    values,
    this.config.connectionConfig.stringifyObjects,
    this.config.connectionConfig.timezone
  );
};

Pool.prototype.escape = function(value) {
  return mysql.escape(
    value,
    this.config.connectionConfig.stringifyObjects,
    this.config.connectionConfig.timezone
  );
};

Pool.prototype.escapeId = function escapeId(value) {
  return mysql.escapeId(value, false);
};

function spliceConnection(queue, connection) {
  var len = queue.length;
  for (var i = 0; i < len; i++) {
    if (queue.get(i) === connection) {
      queue.removeOne(i);
      break;
    }
  }
}
<|endoftext|>