<commit_before>import { DropShadowFilter } from 'pixi-filters';

// Components
import PixiTrack from './PixiTrack';
import Inset from './Inset';
import DataFetcher from './DataFetcher';

// Services
import { chromInfo } from './services';
import { create } from './services/pub-sub';

// Utils
import {
  absToChr, base64ToCanvas, colorToHex, flatten, tileToCanvas
} from './utils';

const BASE_MIN_RES = 12;
const BASE_MAX_RES = 24;
const BASE_SCALE = 4;

export default class Insets2dTrack extends PixiTrack {
  constructor(
    scene,
    dataConfig,
    dataType,
    chromInfoPath,
    options,
    animate,
    positioning  // Computed track position, location, and offset
  ) {
    super(scene, options);

    this.dataConfig = dataConfig;
    this.dataType = dataType;
    this.options = options;
    this.animate = animate;
    this.positioning = positioning;  // Needed for the gallery view

    this.fetchChromInfo = this.dataType === 'cooler'
      ? chromInfo.get(chromInfoPath)
      : undefined;

    this.dropShadow = new DropShadowFilter(
      90,
      this.options.dropDistance,
      this.options.dropBlur,
      0x000000,
      this.options.dropOpacity,
    );

    this.pBase.alpha = this.options.opacity;
    this.pMain.filters = [this.dropShadow];

    this.insets = {};

    this.insetMouseHandler = {
      click: this.clickHandler.bind(this),
      mouseOver: this.mouseOverHandler.bind(this),
      mouseOut: this.mouseOutHandler.bind(this),
      mouseDown: this.mouseDownHandler.bind(this),
      mouseUp: this.mouseUpHandler.bind(this)
    };

    // Create a custom pubSub interface
    const { publish, subscribe, unsubscribe } = create({});
    this.publish = publish;
    this.subscribe = subscribe;
    this.unsubscribe = unsubscribe;

    this.options.fill = colorToHex(this.options.fill);
    this.options.borderColor = colorToHex(this.options.borderColor);
    this.options.leaderLineColor = colorToHex(this.options.leaderLineColor);

    this.insetMinRes = this.options.minRes || BASE_MIN_RES;
    this.insetMaxRes = this.options.maxRes || BASE_MAX_RES;
    this.insetScale = this.options.scale || BASE_SCALE;

    this.dataFetcher = new DataFetcher(dataConfig);
    this.dataFetcher.tilesetInfo((tilesetInfo) => {
      if (tilesetInfo.error) {
        console.error(
          'Error retrieving tileset info:', dataConfig, this.tilesetInfo.error
        );
      }
      this.tilesetInfo = tilesetInfo;
    });
  }

  clear() {
    this.pMain.clear();
  }

  /**
   * Clean up inset instances
   *
   * @param  {Set}  insetIds  Set of inset IDs to keep
   */
  cleanUp(insetIds) {
    Object.keys(this.insets)
      .filter(id => !insetIds.has(id))
      .forEach(this.destroyInset.bind(this));
  }

  createFetchRenderInset(
    uid, x, y, w, h, sx, sy, dX1, dX2, dY1, dY2, remotePos
  ) {
    const inset = (
      this.insets[uid] ||
      this.initInset(
        uid,
        [dX1, dX2, dY1, dY2],
        remotePos
      )
    );

    inset.clear(this.options);
    inset.globalOffset(...this.position);
    inset.origin(sx, sy);
    inset.position(x, y);
    inset.size(w, h);
    inset.drawLeaderLine();
    inset.drawBorder();
    return inset.drawImage(this.rendererInset.bind(this));
  }

  dataToGenomePos(dX1, dX2, dY1, dY2, _chromInfo) {
    const x = absToChr(dX1, _chromInfo);
    const y = absToChr(dX2, _chromInfo);

    return [
      x[0],
      x[1],
      x[1] + dX2 - dX1,
      y[0],
      y[1],
      y[1] + dY2 - dY1,
    ];
  }

  dataToImPos(dX1, dX2, dY1, dY2) {
    return [dX1, dX2, dY1, dY2];
  }

  drawInset(inset) {
    if (this.dataType === 'cooler') {
      if (!this.fetchChromInfo) return Promise.reject('This is truly odd!');

      return this.fetchChromInfo
        .then(_chromInfo => this.createFetchRenderInset(
          ...inset,
          this.dataToGenomePos(
            inset[7], inset[8], inset[9], inset[10], _chromInfo
          )
        ));
    }

    return this.createFetchRenderInset(
      ...inset,
      this.dataToImPos(inset[7], inset[8], inset[9], inset[10])
    );
  }

  drawInsets(insets, insetIds) {
    if (!this.tilesetInfo) {
      return [Promise.reject('Tileset info not available')];
    }

    this.cleanUp(insetIds);

    return insets.map(inset => this.drawInset(inset));
  }

  /**
   * Destroy an inset, i.e., call the inset's destroy method and remove it from
   * the cache.
   *
   * @param  {String}  uid  UID of the inset to be destroyed.
   */
  destroyInset(uid) {
    this.insets[uid].destroy();
    this.insets[uid] = undefined;
    delete this.insets[uid];
  }

  initInset(
    uid,
    dataPos,
    remotePos,
    dataConfig = this.dataConfig,
    tilesetInfo = this.tilesetInfo,
    options = this.options,
    mouseHandler = this.insetMouseHandler
  ) {
    this.insets[uid] = new Inset(
      uid,
      dataPos,
      remotePos,
      dataConfig,
      tilesetInfo,
      options,
      mouseHandler,
      this.dataType
    );
    this.pMain.addChild(this.insets[uid].graphics);
    return this.insets[uid];
  }

  clickHandler(event, inset) {
    // console.log('PIXI CLICK', event.type, inset);
  }

  mouseOverHandler(event, inset) {
    // console.log('PIXI MOUSE OVER', event.type, inset);
    this.animate();
  }

  mouseOutHandler(event, inset) {
    // console.log('PIXI MOUSE OUT', event.type, inset);
    this.animate();
  }

  mouseDownHandler(event, inset) {
    this.hoveringInsetIdx = this.pMain.getChildIndex(inset);
    this.pMain.setChildIndex(inset, this.pMain.children.length - 1);
    this.animate();
  }

  mouseUpHandler(event, inset) {
    this.pMain.setChildIndex(inset, this.hoveringInsetIdx);
    this.animate();
  }

  rendererInset(data, w, h) {
    return data.dataTypes[0] === 'dataUrl'
      ? this.rendererImage(data.fragments[0], w, h)
      : this.rendererHeatmap(data.fragments[0], w, h);
  }

  rendererHeatmap(data, w, h) {
    const flatImg = flatten(data);

    const n = flatImg.length;

    const pixData = new Uint8ClampedArray(n * 4);

    for (let i = 0; i < n; i++) {
      const j = i * 4;
      const val = 255 - (flatImg[i] * 255);
      pixData[j] = val;
      pixData[j + 1] = val;
      pixData[j + 2] = val;
      pixData[j + 3] = 255;
    }

    return Promise.resolve(tileToCanvas(pixData, w, h));
  }

  rendererImage(data, w, h) {
    return base64ToCanvas(data, w, h);
  }

  zoomed(newXScale, newYScale, k) {
    super.zoomed(newXScale, newYScale, k);

    this.publish('zoom', { newXScale, newYScale, k });
  }
}
<commit_msg>Remove unused params<commit_after>import { DropShadowFilter } from 'pixi-filters';

// Components
import PixiTrack from './PixiTrack';
import Inset from './Inset';
import DataFetcher from './DataFetcher';

// Services
import { chromInfo } from './services';
import { create } from './services/pub-sub';

// Utils
import {
  absToChr, base64ToCanvas, colorToHex, flatten, tileToCanvas
} from './utils';

const BASE_MIN_RES = 12;
const BASE_MAX_RES = 24;
const BASE_SCALE = 4;

export default class Insets2dTrack extends PixiTrack {
  constructor(
    scene,
    dataConfig,
    dataType,
    chromInfoPath,
    options,
    animate,
    positioning  // Computed track position, location, and offset
  ) {
    super(scene, options);

    this.dataConfig = dataConfig;
    this.dataType = dataType;
    this.options = options;
    this.animate = animate;
    this.positioning = positioning;  // Needed for the gallery view

    this.fetchChromInfo = this.dataType === 'cooler'
      ? chromInfo.get(chromInfoPath)
      : undefined;

    this.dropShadow = new DropShadowFilter(
      90,
      this.options.dropDistance,
      this.options.dropBlur,
      0x000000,
      this.options.dropOpacity,
    );

    this.pBase.alpha = this.options.opacity;
    this.pMain.filters = [this.dropShadow];

    this.insets = {};

    this.insetMouseHandler = {
      click: this.clickHandler.bind(this),
      mouseOver: this.mouseOverHandler.bind(this),
      mouseOut: this.mouseOutHandler.bind(this),
      mouseDown: this.mouseDownHandler.bind(this),
      mouseUp: this.mouseUpHandler.bind(this)
    };

    // Create a custom pubSub interface
    const { publish, subscribe, unsubscribe } = create({});
    this.publish = publish;
    this.subscribe = subscribe;
    this.unsubscribe = unsubscribe;

    this.options.fill = colorToHex(this.options.fill);
    this.options.borderColor = colorToHex(this.options.borderColor);
    this.options.leaderLineColor = colorToHex(this.options.leaderLineColor);

    this.insetMinRes = this.options.minRes || BASE_MIN_RES;
    this.insetMaxRes = this.options.maxRes || BASE_MAX_RES;
    this.insetScale = this.options.scale || BASE_SCALE;

    this.dataFetcher = new DataFetcher(dataConfig);
    this.dataFetcher.tilesetInfo((tilesetInfo) => {
      if (tilesetInfo.error) {
        console.error(
          'Error retrieving tileset info:', dataConfig, this.tilesetInfo.error
        );
      }
      this.tilesetInfo = tilesetInfo;
    });
  }

  clear() {
    this.pMain.clear();
  }

  /**
   * Clean up inset instances
   *
   * @param  {Set}  insetIds  Set of inset IDs to keep
   */
  cleanUp(insetIds) {
    Object.keys(this.insets)
      .filter(id => !insetIds.has(id))
      .forEach(this.destroyInset.bind(this));
  }

  createFetchRenderInset(
    uid, x, y, w, h, sx, sy, dX1, dX2, dY1, dY2, remotePos
  ) {
    const inset = (
      this.insets[uid] ||
      this.initInset(
        uid,
        [dX1, dX2, dY1, dY2],
        remotePos
      )
    );

    inset.clear(this.options);
    inset.globalOffset(...this.position);
    inset.origin(sx, sy);
    inset.position(x, y);
    inset.size(w, h);
    inset.drawLeaderLine();
    inset.drawBorder();
    return inset.drawImage(this.rendererInset.bind(this));
  }

  dataToGenomePos(dX1, dX2, dY1, dY2, _chromInfo) {
    const x = absToChr(dX1, _chromInfo);
    const y = absToChr(dX2, _chromInfo);

    return [
      x[0],
      x[1],
      x[1] + dX2 - dX1,
      y[0],
      y[1],
      y[1] + dY2 - dY1,
    ];
  }

  dataToImPos(dX1, dX2, dY1, dY2) {
    return [dX1, dX2, dY1, dY2];
  }

  drawInset(inset) {
    if (this.dataType === 'cooler') {
      if (!this.fetchChromInfo) return Promise.reject('This is truly odd!');

      return this.fetchChromInfo
        .then(_chromInfo => this.createFetchRenderInset(
          ...inset,
          this.dataToGenomePos(
            inset[7], inset[8], inset[9], inset[10], _chromInfo
          )
        ));
    }

    return this.createFetchRenderInset(
      ...inset,
      this.dataToImPos(inset[7], inset[8], inset[9], inset[10])
    );
  }

  drawInsets(insets, insetIds) {
    if (!this.tilesetInfo) {
      return [Promise.reject('Tileset info not available')];
    }

    this.cleanUp(insetIds);

    return insets.map(inset => this.drawInset(inset));
  }

  /**
   * Destroy an inset, i.e., call the inset's destroy method and remove it from
   * the cache.
   *
   * @param  {String}  uid  UID of the inset to be destroyed.
   */
  destroyInset(uid) {
    this.insets[uid].destroy();
    this.insets[uid] = undefined;
    delete this.insets[uid];
  }

  initInset(
    uid,
    dataPos,
    remotePos,
    dataConfig = this.dataConfig,
    tilesetInfo = this.tilesetInfo,
    options = this.options,
    mouseHandler = this.insetMouseHandler
  ) {
    this.insets[uid] = new Inset(
      uid,
      dataPos,
      remotePos,
      dataConfig,
      tilesetInfo,
      options,
      mouseHandler,
      this.dataType
    );
    this.pMain.addChild(this.insets[uid].graphics);
    return this.insets[uid];
  }

  clickHandler(event, inset) {
    // console.log('PIXI CLICK', event.type, inset);
  }

  mouseOverHandler(event, inset) {
    // console.log('PIXI MOUSE OVER', event.type, inset);
    this.animate();
  }

  mouseOutHandler(event, inset) {
    // console.log('PIXI MOUSE OUT', event.type, inset);
    this.animate();
  }

  mouseDownHandler(event, inset) {
    this.hoveringInsetIdx = this.pMain.getChildIndex(inset);
    this.pMain.setChildIndex(inset, this.pMain.children.length - 1);
    this.animate();
  }

  mouseUpHandler(event, inset) {
    this.pMain.setChildIndex(inset, this.hoveringInsetIdx);
    this.animate();
  }

  rendererInset(data, w, h) {
    return data.dataTypes[0] === 'dataUrl'
      ? this.rendererImage(data.fragments[0])
      : this.rendererHeatmap(data.fragments[0], w, h);
  }

  rendererHeatmap(data, w, h) {
    const flatImg = flatten(data);

    const n = flatImg.length;

    const pixData = new Uint8ClampedArray(n * 4);

    for (let i = 0; i < n; i++) {
      const j = i * 4;
      const val = 255 - (flatImg[i] * 255);
      pixData[j] = val;
      pixData[j + 1] = val;
      pixData[j + 2] = val;
      pixData[j + 3] = 255;
    }

    return Promise.resolve(tileToCanvas(pixData, w, h));
  }

  rendererImage(data) {
    return base64ToCanvas(data);
  }

  zoomed(newXScale, newYScale, k) {
    super.zoomed(newXScale, newYScale, k);

    this.publish('zoom', { newXScale, newYScale, k });
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */

 suite('customElements', function() {
  var work;
  var assert = chai.assert;

  setup(function() {
    work = document.createElement('div');
    document.body.appendChild(work);
  });

  teardown(function() {
    document.body.removeChild(work);
  });

  test('document.register requires name argument', function() {
    try {
      document.registerElement();
    } catch(x) {
      return;
    }
    assert.ok(false, 'document.register failed to throw when given no arguments');
  });

  test('document.register requires name argument to contain a dash', function() {
    try {
      document.registerElement('xfoo', {prototype: Object.create(HTMLElement.prototype)});
    } catch(x) {
      return;
    }
    assert.ok(false, 'document.register failed to throw when given no arguments');
  });

  test('document.register requires name argument to be unique', function() {
    var proto = {prototype: Object.create(HTMLElement.prototype)};
    document.registerElement('x-duplicate', proto);
    try {
      document.registerElement('x-duplicate', proto);
    } catch(x) {
      return;
    }
    assert.ok(false, 'document.register failed to throw when called multiple times with the same element name');
  });

  test('document.register create via new', function() {
    // register x-foo
    var XFoo = document.registerElement('x-foo', {prototype: Object.create(HTMLElement.prototype)});
    // create an instance via new
    var xfoo = new XFoo();
    // test localName
    assert.equal(xfoo.localName, 'x-foo');
    // attach content
    work.appendChild(xfoo).textContent = '[x-foo]';
    // reacquire
    var xfoo = work.querySelector('x-foo');
    // test textContent
    assert.equal(xfoo.textContent, '[x-foo]');
  });

  test('document.register create via createElement', function() {
    // register x-foo
    var XFoo = document.registerElement('x-foo2', {prototype:  Object.create(HTMLElement.prototype)});
    // create an instance via createElement
    var xfoo = document.createElement('x-foo2');
    // test localName
    assert.equal(xfoo.localName, 'x-foo2');
    // attach content
    xfoo.textContent = '[x-foo2]';
    // test textContent
    assert.equal(xfoo.textContent, '[x-foo2]');
  });

  test('document.register treats names as case insensitive', function() {
    var proto = {prototype: Object.create(HTMLElement.prototype)};
    proto.prototype.isXCase = true;
    var XCase = document.registerElement('X-CASE', proto);
    // createElement
    var x = document.createElement('X-CASE');
    assert.equal(x.isXCase, true);
    x = document.createElement('x-case');
    assert.equal(x.isXCase, true);
    // upgrade
    work.innerHTML = '<X-CASE></X-CASE><x-CaSe></x-CaSe>';
    CustomElements.takeRecords();
    assert.equal(work.firstChild.isXCase, true);
    assert.equal(work.firstChild.nextSibling.isXCase, true);
  });

  test('document.register create multiple instances', function() {
    var XFooPrototype = Object.create(HTMLElement.prototype);
    XFooPrototype.bluate = function() {
      this.color = 'lightblue';
    };
    var XFoo = document.registerElement('x-foo3', {
      prototype: XFooPrototype
    });
    // create an instance
    var xfoo1 = new XFoo();
    // create another instance
    var xfoo2 = new XFoo();
    // test textContent
    xfoo1.textContent = '[x-foo1]';
    xfoo2.textContent = '[x-foo2]';
    assert.equal(xfoo1.textContent, '[x-foo1]');
    assert.equal(xfoo2.textContent, '[x-foo2]');
    // test bluate
    xfoo1.bluate();
    assert.equal(xfoo1.color, 'lightblue');
    assert.isUndefined(xfoo2.color);
  });

  test('document.register extend native element', function() {
    // test native element extension
    var XBarPrototype = Object.create(HTMLButtonElement.prototype);
    var XBar = document.registerElement('x-bar', {
      prototype: XBarPrototype,
      extends: 'button'
    });
    var xbar = new XBar();
    work.appendChild(xbar).textContent = 'x-bar';
    xbar = work.querySelector('button[is=x-bar]');
    assert(xbar);
    assert.equal(xbar.textContent, 'x-bar');
    // test extension of native element extension
    var XBarBarPrototype = Object.create(XBarPrototype);
    var XBarBar = document.registerElement('x-barbar', {
      prototype: XBarBarPrototype,
      extends: 'button'
    });
    var xbarbar = new XBarBar();
    work.appendChild(xbarbar).textContent = 'x-barbar';
    xbarbar = work.querySelector('button[is=x-barbar]');
    assert(xbarbar);
    assert.equal(xbarbar.textContent, 'x-barbar');
    // test extension^3
    var XBarBarBarPrototype = Object.create(XBarBarPrototype);
    var XBarBarBar = document.registerElement('x-barbarbar', {
      prototype: XBarBarBarPrototype,
      extends: 'button'
    });
    var xbarbarbar = new XBarBarBar();
    work.appendChild(xbarbarbar).textContent = 'x-barbarbar';
    xbarbarbar = work.querySelector('button[is=x-barbarbar]');
    assert(xbarbarbar);
    assert.equal(xbarbarbar.textContent, 'x-barbarbar');
  });

  test('document.register createdCallback in prototype', function() {
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.createdCallback = function() {
      this.style.fontStyle = 'italic';
    }
    var XBoo = document.registerElement('x-boo', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    assert.equal(xboo.style.fontStyle, 'italic');
    //
    var XBooBooPrototype = Object.create(XBooPrototype);
    XBooBooPrototype.createdCallback = function() {
      XBoo.prototype.createdCallback.call(this);
      this.style.fontSize = '32pt';
    };
    var XBooBoo = document.registerElement('x-booboo', {
      prototype: XBooBooPrototype
    });
    var xbooboo = new XBooBoo();
    assert.equal(xbooboo.style.fontStyle, 'italic');
    assert.equal(xbooboo.style.fontSize, '32pt');
  });

  test('document.register [created|attached|detached]Callbacks in prototype', function(done) {
    var ready, inserted, removed;
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.createdCallback = function() {
      ready = true;
    }
    XBooPrototype.attachedCallback = function() {
      inserted = true;
    }
    XBooPrototype.detachedCallback = function() {
      removed = true;
    }
    var XBoo = document.registerElement('x-boo-ir', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    assert(ready, 'ready must be true [XBoo]');
    assert(!inserted, 'inserted must be false [XBoo]');
    assert(!removed, 'removed must be false [XBoo]');
    work.appendChild(xboo);
    CustomElements.takeRecords();
    assert(inserted, 'inserted must be true [XBoo]');
    work.removeChild(xboo);
    CustomElements.takeRecords();
    assert(removed, 'removed must be true [XBoo]');
    //
    ready = inserted = removed = false;
    var XBooBooPrototype = Object.create(XBooPrototype);
    XBooBooPrototype.createdCallback = function() {
      XBoo.prototype.createdCallback.call(this);
    };
    XBooBooPrototype.attachedCallback = function() {
      XBoo.prototype.attachedCallback.call(this);
    };
    XBooBooPrototype.detachedCallback = function() {
      XBoo.prototype.detachedCallback.call(this);
    };
    var XBooBoo = document.registerElement('x-booboo-ir', {
      prototype: XBooBooPrototype
    });
    var xbooboo = new XBooBoo();
    assert(ready, 'ready must be true [XBooBoo]');
    assert(!inserted, 'inserted must be false [XBooBoo]');
    assert(!removed, 'removed must be false [XBooBoo]');
    work.appendChild(xbooboo);
    CustomElements.takeRecords();
    assert(inserted, 'inserted must be true [XBooBoo]');
    work.removeChild(xbooboo);
    CustomElements.takeRecords();
    assert(removed, 'removed must be true [XBooBoo]');
    done();
  });

  test('document.register attributeChangedCallback in prototype', function(done) {
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.attributeChangedCallback = function(inName, inOldValue) {
      if (inName == 'foo' && inOldValue=='bar'
          && this.attributes.foo.value == 'zot') {
        done();
      }
    }
    var XBoo = document.registerElement('x-boo-acp', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    xboo.setAttribute('foo', 'bar');
    xboo.setAttribute('foo', 'zot');
  });

  test('document.register can use Functions as definitions', function() {
    // function used as Custom Element defintion
    function A$A() {
      this.alive = true;
    }
    A$A.prototype = Object.create(HTMLElement.prototype);
    // bind createdCallback to function body
    A$A.prototype.createdCallback = A$A;
    A$A = document.registerElement('a-a', A$A);
    // test via new
    var a = new A$A();
    assert.equal(a.alive, true);
    // test via parser upgrade
    work.innerHTML = '<a-a></a-a>';
    CustomElements.takeRecords();
    assert.equal(work.firstElementChild.alive, true);
  });

  test('node.cloneNode upgrades', function(done) {
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.createdCallback = function() {
      this.__ready__ = true;
    };
    var XBoo = document.registerElement('x-boo-clone', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    work.appendChild(xboo);
    CustomElements.takeRecords();
    var xboo2 = xboo.cloneNode(true);
    assert(xboo2.__ready__, 'clone createdCallback must be called');
    done();
  });

  test('entered left apply to view', function() {
    var invocations = [];
    var elementProto = Object.create(HTMLElement.prototype);
    elementProto.createdCallback = function() {
      invocations.push('created');
    }
    elementProto.attachedCallback = function() {
      invocations.push('entered');
    }
    elementProto.detachedCallback = function() {
      invocations.push('left');
    }
    var tagName = 'x-entered-left-view';
    var CustomElement = document.registerElement(tagName, { prototype: elementProto });

    var docB = document.implementation.createHTMLDocument('');
    docB.body.innerHTML = '<' + tagName + '></' + tagName + '>';
    CustomElements.parser.parse(docB);
    CustomElements.takeRecords();
    assert.deepEqual(invocations, ['created'], 'created but not entered view');

    var element = docB.body.childNodes[0];
    // note, cannot use instanceof due to IE
    assert.equal(element.__proto__, CustomElement.prototype, 'element is correct type');

    work.appendChild(element)
    CustomElements.takeRecords();
    assert.deepEqual(invocations, ['created', 'entered'],
        'created and entered view');

    docB.body.appendChild(element);
    CustomElements.takeRecords();
    assert.deepEqual(invocations, ['created', 'entered', 'left'],
        'created, entered then left view');
  });
});

htmlSuite('customElements (html)', function() {
  htmlTest('html/attributes.html');
});
<commit_msg>test for detachedCallback firing without attachCallback<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */

 suite('customElements', function() {
  var work;
  var assert = chai.assert;

  setup(function() {
    work = document.createElement('div');
    document.body.appendChild(work);
  });

  teardown(function() {
    document.body.removeChild(work);
  });

  test('document.register requires name argument', function() {
    try {
      document.registerElement();
    } catch(x) {
      return;
    }
    assert.ok(false, 'document.register failed to throw when given no arguments');
  });

  test('document.register requires name argument to contain a dash', function() {
    try {
      document.registerElement('xfoo', {prototype: Object.create(HTMLElement.prototype)});
    } catch(x) {
      return;
    }
    assert.ok(false, 'document.register failed to throw when given no arguments');
  });

  test('document.register requires name argument to be unique', function() {
    var proto = {prototype: Object.create(HTMLElement.prototype)};
    document.registerElement('x-duplicate', proto);
    try {
      document.registerElement('x-duplicate', proto);
    } catch(x) {
      return;
    }
    assert.ok(false, 'document.register failed to throw when called multiple times with the same element name');
  });

  test('document.register create via new', function() {
    // register x-foo
    var XFoo = document.registerElement('x-foo', {prototype: Object.create(HTMLElement.prototype)});
    // create an instance via new
    var xfoo = new XFoo();
    // test localName
    assert.equal(xfoo.localName, 'x-foo');
    // attach content
    work.appendChild(xfoo).textContent = '[x-foo]';
    // reacquire
    var xfoo = work.querySelector('x-foo');
    // test textContent
    assert.equal(xfoo.textContent, '[x-foo]');
  });

  test('document.register create via createElement', function() {
    // register x-foo
    var XFoo = document.registerElement('x-foo2', {prototype:  Object.create(HTMLElement.prototype)});
    // create an instance via createElement
    var xfoo = document.createElement('x-foo2');
    // test localName
    assert.equal(xfoo.localName, 'x-foo2');
    // attach content
    xfoo.textContent = '[x-foo2]';
    // test textContent
    assert.equal(xfoo.textContent, '[x-foo2]');
  });

  test('document.register treats names as case insensitive', function() {
    var proto = {prototype: Object.create(HTMLElement.prototype)};
    proto.prototype.isXCase = true;
    var XCase = document.registerElement('X-CASE', proto);
    // createElement
    var x = document.createElement('X-CASE');
    assert.equal(x.isXCase, true);
    x = document.createElement('x-case');
    assert.equal(x.isXCase, true);
    // upgrade
    work.innerHTML = '<X-CASE></X-CASE><x-CaSe></x-CaSe>';
    CustomElements.takeRecords();
    assert.equal(work.firstChild.isXCase, true);
    assert.equal(work.firstChild.nextSibling.isXCase, true);
  });

  test('document.register create multiple instances', function() {
    var XFooPrototype = Object.create(HTMLElement.prototype);
    XFooPrototype.bluate = function() {
      this.color = 'lightblue';
    };
    var XFoo = document.registerElement('x-foo3', {
      prototype: XFooPrototype
    });
    // create an instance
    var xfoo1 = new XFoo();
    // create another instance
    var xfoo2 = new XFoo();
    // test textContent
    xfoo1.textContent = '[x-foo1]';
    xfoo2.textContent = '[x-foo2]';
    assert.equal(xfoo1.textContent, '[x-foo1]');
    assert.equal(xfoo2.textContent, '[x-foo2]');
    // test bluate
    xfoo1.bluate();
    assert.equal(xfoo1.color, 'lightblue');
    assert.isUndefined(xfoo2.color);
  });

  test('document.register extend native element', function() {
    // test native element extension
    var XBarPrototype = Object.create(HTMLButtonElement.prototype);
    var XBar = document.registerElement('x-bar', {
      prototype: XBarPrototype,
      extends: 'button'
    });
    var xbar = new XBar();
    work.appendChild(xbar).textContent = 'x-bar';
    xbar = work.querySelector('button[is=x-bar]');
    assert(xbar);
    assert.equal(xbar.textContent, 'x-bar');
    // test extension of native element extension
    var XBarBarPrototype = Object.create(XBarPrototype);
    var XBarBar = document.registerElement('x-barbar', {
      prototype: XBarBarPrototype,
      extends: 'button'
    });
    var xbarbar = new XBarBar();
    work.appendChild(xbarbar).textContent = 'x-barbar';
    xbarbar = work.querySelector('button[is=x-barbar]');
    assert(xbarbar);
    assert.equal(xbarbar.textContent, 'x-barbar');
    // test extension^3
    var XBarBarBarPrototype = Object.create(XBarBarPrototype);
    var XBarBarBar = document.registerElement('x-barbarbar', {
      prototype: XBarBarBarPrototype,
      extends: 'button'
    });
    var xbarbarbar = new XBarBarBar();
    work.appendChild(xbarbarbar).textContent = 'x-barbarbar';
    xbarbarbar = work.querySelector('button[is=x-barbarbar]');
    assert(xbarbarbar);
    assert.equal(xbarbarbar.textContent, 'x-barbarbar');
  });

  test('document.register createdCallback in prototype', function() {
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.createdCallback = function() {
      this.style.fontStyle = 'italic';
    }
    var XBoo = document.registerElement('x-boo', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    assert.equal(xboo.style.fontStyle, 'italic');
    //
    var XBooBooPrototype = Object.create(XBooPrototype);
    XBooBooPrototype.createdCallback = function() {
      XBoo.prototype.createdCallback.call(this);
      this.style.fontSize = '32pt';
    };
    var XBooBoo = document.registerElement('x-booboo', {
      prototype: XBooBooPrototype
    });
    var xbooboo = new XBooBoo();
    assert.equal(xbooboo.style.fontStyle, 'italic');
    assert.equal(xbooboo.style.fontSize, '32pt');
  });

  test('document.register [created|attached|detached]Callbacks in prototype', function(done) {
    var ready, inserted, removed;
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.createdCallback = function() {
      ready = true;
    }
    XBooPrototype.attachedCallback = function() {
      inserted = true;
    }
    XBooPrototype.detachedCallback = function() {
      removed = true;
    }
    var XBoo = document.registerElement('x-boo-ir', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    assert(ready, 'ready must be true [XBoo]');
    assert(!inserted, 'inserted must be false [XBoo]');
    assert(!removed, 'removed must be false [XBoo]');
    work.appendChild(xboo);
    CustomElements.takeRecords();
    assert(inserted, 'inserted must be true [XBoo]');
    work.removeChild(xboo);
    CustomElements.takeRecords();
    assert(removed, 'removed must be true [XBoo]');
    //
    ready = inserted = removed = false;
    var XBooBooPrototype = Object.create(XBooPrototype);
    XBooBooPrototype.createdCallback = function() {
      XBoo.prototype.createdCallback.call(this);
    };
    XBooBooPrototype.attachedCallback = function() {
      XBoo.prototype.attachedCallback.call(this);
    };
    XBooBooPrototype.detachedCallback = function() {
      XBoo.prototype.detachedCallback.call(this);
    };
    var XBooBoo = document.registerElement('x-booboo-ir', {
      prototype: XBooBooPrototype
    });
    var xbooboo = new XBooBoo();
    assert(ready, 'ready must be true [XBooBoo]');
    assert(!inserted, 'inserted must be false [XBooBoo]');
    assert(!removed, 'removed must be false [XBooBoo]');
    work.appendChild(xbooboo);
    CustomElements.takeRecords();
    assert(inserted, 'inserted must be true [XBooBoo]');
    work.removeChild(xbooboo);
    CustomElements.takeRecords();
    assert(removed, 'removed must be true [XBooBoo]');
    done();
  });

  test('document.register attributeChangedCallback in prototype', function(done) {
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.attributeChangedCallback = function(inName, inOldValue) {
      if (inName == 'foo' && inOldValue=='bar'
          && this.attributes.foo.value == 'zot') {
        done();
      }
    }
    var XBoo = document.registerElement('x-boo-acp', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    xboo.setAttribute('foo', 'bar');
    xboo.setAttribute('foo', 'zot');
  });

test('document.register detachedCallbacks in prototype', function(done) {
    var ready, inserted, removed;
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.detachedCallback = function() {
      removed = true;
    }
    var XBoo = document.registerElement('x-boo-ir2', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    assert(!removed, 'removed must be false [XBoo]');
    work.appendChild(xboo);
    CustomElements.takeRecords();
    work.removeChild(xboo);
    CustomElements.takeRecords();
    assert(removed, 'removed must be true [XBoo]');
    //
    ready = inserted = removed = false;
    var XBooBooPrototype = Object.create(XBooPrototype);
    XBooBooPrototype.detachedCallback = function() {
      XBoo.prototype.detachedCallback.call(this);
    };
    var XBooBoo = document.registerElement('x-booboo-ir2', {
      prototype: XBooBooPrototype
    });
    var xbooboo = new XBooBoo();
    assert(!removed, 'removed must be false [XBooBoo]');
    work.appendChild(xbooboo);
    CustomElements.takeRecords();
    work.removeChild(xbooboo);
    CustomElements.takeRecords();
    assert(removed, 'removed must be true [XBooBoo]');
    done();
  });

  test('document.register can use Functions as definitions', function() {
    // function used as Custom Element defintion
    function A$A() {
      this.alive = true;
    }
    A$A.prototype = Object.create(HTMLElement.prototype);
    // bind createdCallback to function body
    A$A.prototype.createdCallback = A$A;
    A$A = document.registerElement('a-a', A$A);
    // test via new
    var a = new A$A();
    assert.equal(a.alive, true);
    // test via parser upgrade
    work.innerHTML = '<a-a></a-a>';
    CustomElements.takeRecords();
    assert.equal(work.firstElementChild.alive, true);
  });

  test('node.cloneNode upgrades', function(done) {
    var XBooPrototype = Object.create(HTMLElement.prototype);
    XBooPrototype.createdCallback = function() {
      this.__ready__ = true;
    };
    var XBoo = document.registerElement('x-boo-clone', {
      prototype: XBooPrototype
    });
    var xboo = new XBoo();
    work.appendChild(xboo);
    CustomElements.takeRecords();
    var xboo2 = xboo.cloneNode(true);
    assert(xboo2.__ready__, 'clone createdCallback must be called');
    done();
  });

  test('entered left apply to view', function() {
    var invocations = [];
    var elementProto = Object.create(HTMLElement.prototype);
    elementProto.createdCallback = function() {
      invocations.push('created');
    }
    elementProto.attachedCallback = function() {
      invocations.push('entered');
    }
    elementProto.detachedCallback = function() {
      invocations.push('left');
    }
    var tagName = 'x-entered-left-view';
    var CustomElement = document.registerElement(tagName, { prototype: elementProto });

    var docB = document.implementation.createHTMLDocument('');
    docB.body.innerHTML = '<' + tagName + '></' + tagName + '>';
    CustomElements.parser.parse(docB);
    CustomElements.takeRecords();
    assert.deepEqual(invocations, ['created'], 'created but not entered view');

    var element = docB.body.childNodes[0];
    // note, cannot use instanceof due to IE
    assert.equal(element.__proto__, CustomElement.prototype, 'element is correct type');

    work.appendChild(element)
    CustomElements.takeRecords();
    assert.deepEqual(invocations, ['created', 'entered'],
        'created and entered view');

    docB.body.appendChild(element);
    CustomElements.takeRecords();
    assert.deepEqual(invocations, ['created', 'entered', 'left'],
        'created, entered then left view');
  });
});

htmlSuite('customElements (html)', function() {
  htmlTest('html/attributes.html');
});
<|endoftext|>


<commit_before>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-present Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */
// http://www.material-ui.com/#/components/select-field
import 'moment-duration-format';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import ExpansionPanel from '@material-ui/core/ExpansionPanel';
import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
import Typography from '@material-ui/core/Typography';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';

import PropTypes from 'prop-types';
import moment from 'moment';
import React from 'react';
// import PropTypes from 'prop-types';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Appointment.css';
import history from '../../../history';

const stylesRed = {
  color: 'red',
};

const stylesGreen = {
  color: 'green',
};

class AppointmentList extends React.Component {
  static propTypes = {
    rows: PropTypes.array.isRequired,
    services: PropTypes.array.isRequired,
  };

  rows(values) {
    return values.map((value /* ,index*/) =>
      <TableRow key={value.id}>
        <TableCell>

            {value.shortURL
              ?
                  {' '}{value.name}

              : value.name}

              {value.status === 'confirmed'
                ? `${value.status} - ${value.confirmed}`
                : `${value.status}`}

        </TableCell>
        <TableCell>

            {moment(value.start).format('DD MMM YYYY')}

            {moment(value.start).format('hh:mm A')}

          <ExpansionPanel>
            <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
              <Typography>Details</Typography>
            </ExpansionPanelSummary>
            <ExpansionPanelDetails>
              <Typography>
                Created On:{' '}
                {moment(value.created).format('DD MMM YYYY hh:mm A')}
              </Typography>
            </ExpansionPanelDetails>
          </ExpansionPanel>
        </TableCell>
        <TableCell style={{ whiteSpace: 'wrap', textOverflow: 'wrap' }}>

            {value.serviceIds
              .map(
                serviceId =>
                  // console.log(serviceId);
                  this.props.services.peekByKey(serviceId).service,
              )
              .join(', ')}

            ${value.serviceIds.reduce(
              (prevValue, serviceId) =>
                prevValue + this.props.services.peekByKey(serviceId).price,
              0,
            )}

        </TableCell>
      </TableRow>,
    );
  }

  select(rows) {
    return row => {
      const event = rows[row];
      const to = `/appointment/edit/${event.apptId}`;
      history.push(to);
    };
  }

  render() {
    return (

        <TableHead displaySelectAll={false} adjustForCheckbox={false}>
          <TableRow>
            <TableCell>Name</TableCell>
            <TableCell>Date/Time</TableCell>
            <TableCell>Services</TableCell>
          </TableRow>
        </TableHead>
        <TableBody displayRowCheckbox={false}>
          {this.rows(this.props.rows)}
        </TableBody>

    );
  }
}
export default withStyles(s)(AppointmentList);
<commit_msg>removing one column<commit_after>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-present Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */
// http://www.material-ui.com/#/components/select-field
import 'moment-duration-format';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import ExpansionPanel from '@material-ui/core/ExpansionPanel';
import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
import Typography from '@material-ui/core/Typography';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';

import PropTypes from 'prop-types';
import moment from 'moment';
import React from 'react';
// import PropTypes from 'prop-types';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Appointment.css';
import history from '../../../history';

const stylesRed = {
  color: 'red',
};

const stylesGreen = {
  color: 'green',
};

class AppointmentList extends React.Component {
  static propTypes = {
    rows: PropTypes.array.isRequired,
    services: PropTypes.array.isRequired,
  };

  rows(values) {
    return values.map((value /* ,index*/) =>
      <TableRow key={value.id}>
        <TableCell>

            {value.shortURL
              ?
                  {' '}{value.name}

              : value.name}

              {value.status === 'confirmed'
                ? `${value.status} - ${value.confirmed}`
                : `${value.status}`}

        </TableCell>
        <TableCell>

            {moment(value.start).format('DD MMM YYYY')}

            {moment(value.start).format('hh:mm A')}

          <ExpansionPanel>
            <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
              <Typography>Expand</Typography>
            </ExpansionPanelSummary>
            <ExpansionPanelDetails>

                Created On:{' '}
                {moment(value.created).format('DD MMM YYYY hh:mm A')}

              -

                {value.serviceIds
                  .map(
                    serviceId =>
                      // console.log(serviceId);
                      this.props.services.peekByKey(serviceId).service,
                  )
                  .join(', ')}

              -

                ${value.serviceIds.reduce(
                  (prevValue, serviceId) =>
                    prevValue + this.props.services.peekByKey(serviceId).price,
                  0,
                )}

            </ExpansionPanelDetails>
          </ExpansionPanel>
        </TableCell>
      </TableRow>,
    );
  }

  select(rows) {
    return row => {
      const event = rows[row];
      const to = `/appointment/edit/${event.apptId}`;
      history.push(to);
    };
  }

  render() {
    return (

        <TableHead displaySelectAll={false} adjustForCheckbox={false}>
          <TableRow>
            <TableCell>Name</TableCell>
            <TableCell>Details</TableCell>
          </TableRow>
        </TableHead>
        <TableBody displayRowCheckbox={false}>
          {this.rows(this.props.rows)}
        </TableBody>

    );
  }
}
export default withStyles(s)(AppointmentList);
<|endoftext|>


<commit_before>// 修复ie8对trim不支持
String.prototype.trim = function () {
    return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}

//回顶部
$("#go_top").click(function (){
	$("html, body").animate({ scrollTop: 0 }, 400);
});

//将指定id的控件滚动到浏览器顶部，如：接口详情页目录
function scrollToId(id){
	$("html, body").animate({ scrollTop: $("#"+id).offset().top }, 400);
}

/**
 * 替换字符串中自定的字符
 * @param originalStr 原字符串
 * @param oldStr 待替换的字符串
 * @param newStr 替换后的字符串
 */
function replaceAll(originalStr,oldStr,newStr){
	var regExp = new RegExp(oldStr,"gm");
	return originalStr.replace(regExp,newStr)
}

/***********启用bootstrap提示*********************/
$(function () {
	  $('[data-toggle="tooltip"]').tooltip();
});
/************显示id1，隐藏id2*********************/
function changeDisplay(id1, id2) {
	$("#" + id2).addClass('none');
	$("#" + id1).removeClass('none');
};
/**********打开Dialog******************/
function openMyDialog(title,iwidth){
	if(!iwidth){
		iwidth = 400;
	}
	//对话框最高为浏览器的百分之80
	lookUp('myDialog', '', '', iwidth ,7,'');
	$("#myDialogContent").css("max-height",($(document).height()*0.8)+'px');
	showMessage('myDialog','false',false,-1);
	showMessage('fade','false',false,-1);
	title = title? title:"编辑";
	$("#myDialog-title").html(title);
}
function closeMyDialog(tagDiv){
	iClose(tagDiv);
	iClose('fade');
}
function loadPick(event,iwidth,iheight,radio,tag,code,type,def,params,showType,iCallBack,iCallBackParam) {
	/***********加载选择对话框********************/
	if(!params)
		params='';
	if(showType!=0&&!showType)
		showType=5
	//事件，宽度，高度，是否为单选，html元素id，查询的code，查询的type，默认值，其他参数，回调函数，回调参数
	callAjaxByName("iUrl=pick.do|isHowMethod=updateDiv|iParams=&type="
			+type+"&radio="+radio+"&code="+code+"&tag="+tag+"&def="+def+params,iCallBack,iCallBackParam);
	lookUp('lookUp', event, iheight, iwidth ,showType,tag);
	showMessage('lookUp','false',false,-1);
}

/**
 * size 单位为kb
 * @param event
 * @param id
 * @param size
 * @returns {Boolean}
 */
function uploadImage(id,size,form){
	 if(!iLength(id,1,-1,"未选着图片，上传失败")){
		return false;
	 }
     var fileSize =document.getElementById(id).files[0].size;
     if(fileSize>size*1024){
          alert("图片不能大于"+size+"kb,约"+(Math.round(size*1000/1024)/1000)+"M");
          return false;
     }
	lookUp('lookUp',event,100,350,0);
	$("#lookUpContent").html("上传中，请稍后...");
	showMessage('lookUp', 'false', false, -1);
	form.submit();
}
//上传图片非编辑器默认回调方法
function uploadImgCallBack(msg, url) {
	if (msg.indexOf("[OK]") >= 0) {
		$("#image").attr("src", url + "");
		$("#image").removeClass("ndis");
		showMessage('lookUp', 'false', false, 0);
		if (url!= undefined) {
			//修改setting中的value
			var rootScope = getRootScope();
			rootScope.$apply(function () {
			    rootScope.model.value = url;
			});
		}
	}else {
		$("#lookUpContent").html(err1 + "  " + url + "" + err2);
		showMessage('lookUp', 'false', false, 3);
	}
}
//文章页面上传图片回调方法
function acticleUploadImgCallBack(msg, url) {
	if (msg.indexOf("[OK]") >= 0) {
		showMessage('lookUp', 'false', false, 0);
		if (url!= undefined) {
			//修改setting中的value
			var rootScope = getRootScope();
			rootScope.$apply(function () {
				if(rootScope.model.content)
					rootScope.model.content =  rootScope.model.content + "

";
				else
					rootScope.model.content =  "

";

			});
		}
	}else {
		$("#lookUpContent").html(err1 + "  " + url + "" + err2);
		showMessage('lookUp', 'false', false, 3);
	}
}

/**
 * 图片id 验证码输入框id
 */
function changeimg(imgId,inputId){
	try{
		document.getElementById(imgId).src='getImgCode.do?'+Math.random();
		document.getElementById(inputId).focus();
	}catch(ex){}
	return false;
}
/*************************js调用anjularjs 获取$rootScope****************/
function getRootScope(){
	var $body = angular.element(document.body);
	return $body.scope().$root;
}

function initDatePicker(id){
	if($('#'+id)){
		$('#'+id).datetimepicker({
			language:  'zh-CN',
	        weekStart: 1,
			autoclose: 1,
			startView: 2,
			minView: 2,
			forceParse: 0,
		    format: 'yyyy-mm-dd'
		});
	}
}
function initDatePicker2(id){
	if($('#'+id)){
		$('#'+id).datetimepicker({
			language:  'zh-CN',
	        weekStart: 1,
			autoclose: 1,
			startView: 2,
			minView: 1,
			forceParse: 0,
		    format: 'yyyy-mm-dd hh'
		});
	}
}

function addCookieToParams(key,value){
	var params = $.cookie('params');
	params= addParams(params, key , value);
	$.cookie('params', params);
}
function clearCookie(params){
	$.cookie(params, "");
}

/** ************刷新验证吗*********** */
/*******************清空表单，除了nots(,#id)*****************/
function clearForm(id,nots){
	$(':input','#'+id)
	.not(':button, :submit, :reset'+nots)
	.val('')
	.removeAttr('checked')
	.removeAttr('selected');
}

/**
 * 单选
 */
/** ********************************** */
function selectRadio(className,id,radioId){
	var objs = $("."+className);
	objs.removeClass("active");
	var obj = $("#"+id);
	var cobj = $("#"+radioId);
	if(!obj.hasClass("active")){
		obj.addClass("active");
		$(cobj).prop("checked",true);
	}

}<commit_msg>解决系统设置中使用火狐浏览器上传图片无响应bug<commit_after>// 修复ie8对trim不支持
String.prototype.trim = function () {
    return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}

//回顶部
$("#go_top").click(function (){
	$("html, body").animate({ scrollTop: 0 }, 400);
});

//将指定id的控件滚动到浏览器顶部，如：接口详情页目录
function scrollToId(id){
	$("html, body").animate({ scrollTop: $("#"+id).offset().top }, 400);
}

/**
 * 替换字符串中自定的字符
 * @param originalStr 原字符串
 * @param oldStr 待替换的字符串
 * @param newStr 替换后的字符串
 */
function replaceAll(originalStr,oldStr,newStr){
	var regExp = new RegExp(oldStr,"gm");
	return originalStr.replace(regExp,newStr)
}

/***********启用bootstrap提示*********************/
$(function () {
	  $('[data-toggle="tooltip"]').tooltip();
});
/************显示id1，隐藏id2*********************/
function changeDisplay(id1, id2) {
	$("#" + id2).addClass('none');
	$("#" + id1).removeClass('none');
};
/**********打开Dialog******************/
function openMyDialog(title,iwidth){
	if(!iwidth){
		iwidth = 400;
	}
	//对话框最高为浏览器的百分之80
	lookUp('myDialog', '', '', iwidth ,7,'');
	$("#myDialogContent").css("max-height",($(document).height()*0.8)+'px');
	showMessage('myDialog','false',false,-1);
	showMessage('fade','false',false,-1);
	title = title? title:"编辑";
	$("#myDialog-title").html(title);
}
function closeMyDialog(tagDiv){
	iClose(tagDiv);
	iClose('fade');
}
function loadPick(event,iwidth,iheight,radio,tag,code,type,def,params,showType,iCallBack,iCallBackParam) {
	/***********加载选择对话框********************/
	if(!params)
		params='';
	if(showType!=0&&!showType)
		showType=5
	//事件，宽度，高度，是否为单选，html元素id，查询的code，查询的type，默认值，其他参数，回调函数，回调参数
	callAjaxByName("iUrl=pick.do|isHowMethod=updateDiv|iParams=&type="
			+type+"&radio="+radio+"&code="+code+"&tag="+tag+"&def="+def+params,iCallBack,iCallBackParam);
	lookUp('lookUp', event, iheight, iwidth ,showType,tag);
	showMessage('lookUp','false',false,-1);
}

/**
 * size 单位为kb
 * @param event
 * @param id
 * @param size
 * @returns {Boolean}
 */
function uploadImage(id,size,form){
	 if(!iLength(id,1,-1,"未选着图片，上传失败")){
		return false;
	 }
     var fileSize =document.getElementById(id).files[0].size;
     if(fileSize>size*1024){
          alert("图片不能大于"+size+"kb,约"+(Math.round(size*1000/1024)/1000)+"M");
          return false;
     }
	lookUp('lookUp','',100,350,0);
	$("#lookUpContent").html("上传中，请稍后...");
	showMessage('lookUp', 'false', false, -1);
	form.submit();
}
//上传图片非编辑器默认回调方法
function uploadImgCallBack(msg, url) {
	if (msg.indexOf("[OK]") >= 0) {
		$("#image").attr("src", url + "");
		$("#image").removeClass("ndis");
		showMessage('lookUp', 'false', false, 0);
		if (url!= undefined) {
			//修改setting中的value
			var rootScope = getRootScope();
			rootScope.$apply(function () {
			    rootScope.model.value = url;
			});
		}
	}else {
		$("#lookUpContent").html(err1 + "  " + url + "" + err2);
		showMessage('lookUp', 'false', false, 3);
	}
}
//文章页面上传图片回调方法
function acticleUploadImgCallBack(msg, url) {
	if (msg.indexOf("[OK]") >= 0) {
		showMessage('lookUp', 'false', false, 0);
		if (url!= undefined) {
			//修改setting中的value
			var rootScope = getRootScope();
			rootScope.$apply(function () {
				if(rootScope.model.content)
					rootScope.model.content =  rootScope.model.content + "

";
				else
					rootScope.model.content =  "

";

			});
		}
	}else {
		$("#lookUpContent").html(err1 + "  " + url + "" + err2);
		showMessage('lookUp', 'false', false, 3);
	}
}

/**
 * 图片id 验证码输入框id
 */
function changeimg(imgId,inputId){
	try{
		document.getElementById(imgId).src='getImgCode.do?'+Math.random();
		document.getElementById(inputId).focus();
	}catch(ex){}
	return false;
}
/*************************js调用anjularjs 获取$rootScope****************/
function getRootScope(){
	var $body = angular.element(document.body);
	return $body.scope().$root;
}

function initDatePicker(id){
	if($('#'+id)){
		$('#'+id).datetimepicker({
			language:  'zh-CN',
	        weekStart: 1,
			autoclose: 1,
			startView: 2,
			minView: 2,
			forceParse: 0,
		    format: 'yyyy-mm-dd'
		});
	}
}
function initDatePicker2(id){
	if($('#'+id)){
		$('#'+id).datetimepicker({
			language:  'zh-CN',
	        weekStart: 1,
			autoclose: 1,
			startView: 2,
			minView: 1,
			forceParse: 0,
		    format: 'yyyy-mm-dd hh'
		});
	}
}

function addCookieToParams(key,value){
	var params = $.cookie('params');
	params= addParams(params, key , value);
	$.cookie('params', params);
}
function clearCookie(params){
	$.cookie(params, "");
}

/** ************刷新验证吗*********** */
/*******************清空表单，除了nots(,#id)*****************/
function clearForm(id,nots){
	$(':input','#'+id)
	.not(':button, :submit, :reset'+nots)
	.val('')
	.removeAttr('checked')
	.removeAttr('selected');
}

/**
 * 单选
 */
/** ********************************** */
function selectRadio(className,id,radioId){
	var objs = $("."+className);
	objs.removeClass("active");
	var obj = $("#"+id);
	var cobj = $("#"+radioId);
	if(!obj.hasClass("active")){
		obj.addClass("active");
		$(cobj).prop("checked",true);
	}

}<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc run config
 * @name marinaFrontendApp.routeProvider
 * @description
 * route provider of the marinaFrontendApp
 */
angular.module('marinaFrontendApp')
  .run(
  ['$rootScope', '$state', '$stateParams',
    function ($rootScope, $state, $stateParams) {
      $rootScope.$state = $state;
      $rootScope.$stateParams = $stateParams;
    }
  ]
)
  .config(
  ['$stateProvider', '$urlRouterProvider', '$locationProvider',
    function ($stateProvider, $urlRouterProvider, $locationProvider) {
      $locationProvider.html5Mode(true);
      $urlRouterProvider.otherwise('/');
      $stateProvider
        .state('index', {
          url: '/',
          templateUrl: 'views/index.html'
        })
        .state('app', {
          abstract: true,
          url: '',
          templateUrl: 'views/app.html',
          resolve: {
            auth: function($auth) {
              return $auth.validateUser();
            }
          }
        })
        .state('app.dashboard', {
          url: '/dashboard',
          templateUrl: 'views/app_dashboard.html',
          controller: 'DashboardCtrl',
          resolve: {
            dashboard_data: ['marinaApi',
              function(marinaApi) {
                return marinaApi.Dashboard.get();
              }
            ]
          }
        })
        .state('app.profile', {
          url: '/profile/:id',
          templateUrl: 'views/app_profile.html',
          controller: 'ProfileCtrl',
          resolve: {
            profile_user: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.User.get({id: $stateParams.id});
              }
            ]
          }
        })
        .state('app.repository', {
          url: '/repos/:owner/:name',
          templateUrl: 'views/app_repository.html',
          controller: 'RepositoryCtrl',
          resolve: {
            repository: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Repository.get({namespace: $stateParams.owner,  name: $stateParams.name});
              }
            ]
          }
        })
        .state('app.repository_list', {
          url: '/repos/:owner',
          templateUrl: 'views/app_repository_list.html',
          controller: 'RepositoryListCtrl',
          resolve: {
            repositoryList: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Repository.query({namespace: $stateParams.owner});
              }
            ]
          }
        })
        .state('app.repository_edit', {
          url: '/repos/:owner/:name/edit',
          templateUrl: 'views/app_repository_form.html',
          controller: 'RepositoryCtrl',
          resolve: {
            repository: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Repository.get({namespace: $stateParams.owner,  name: $stateParams.name});
              }
            ]
          }
        })
        .state('app.repository_new', {
          url: '/repos/new',
          templateUrl: 'views/app_repository_form.html',
          controller: 'RepositoryCtrl',
          resolve: {
            repository: ['marinaApi',
              function(marinaApi) {
                return new marinaApi.Repository;
              }
            ]
          }
        })
        .state('app.organization_edit', {
          url: '/organizations/:id/edit',
          templateUrl: 'views/app_organization_form.html',
          controller: 'OrganizationCtrl',
          resolve: {
            organization: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Organization.get({id: $stateParams.id});
              }
            ]
          }
        })
        .state('app.organization_new', {
          url: '/organizations/new',
          templateUrl: 'views/app_organization_form.html',
          controller: 'OrganizationCtrl',
          resolve: {
            organization: ['marinaApi',
              function(marinaApi) {
                return new marinaApi.Organization;
              }
            ]
          }
        })
        .state('app.repository_build_logs', {
          url: '/repos/:owner/:name/builds/:build_id/logs',
          templateUrl: 'views/app_repository_build_logs.html'
        })
        .state('auth', {
          abstract: true,
          url: '/auth',
          templateUrl: 'views/auth.html'
        })
        .state('auth.register', {
          url: '/register',
          templateUrl: 'views/auth_register.html'
        })
        .state('auth.login', {
          url: '/login',
          templateUrl: 'views/auth_login.html'
        })
        .state('auth.reset_password', {
          url: '/reset-password',
          templateUrl: 'views/auth_reset_password.html'
        })
        .state('auth.update_password', {
          url: '/update-password',
          templateUrl: 'views/auth_update_password.html'
        })

    }
  ]
);
<commit_msg>move repository new up to take precendence over repository show<commit_after>'use strict';

/**
 * @ngdoc run config
 * @name marinaFrontendApp.routeProvider
 * @description
 * route provider of the marinaFrontendApp
 */
angular.module('marinaFrontendApp')
  .run(
  ['$rootScope', '$state', '$stateParams',
    function ($rootScope, $state, $stateParams) {
      $rootScope.$state = $state;
      $rootScope.$stateParams = $stateParams;
    }
  ]
)
  .config(
  ['$stateProvider', '$urlRouterProvider', '$locationProvider',
    function ($stateProvider, $urlRouterProvider, $locationProvider) {
      $locationProvider.html5Mode(true);
      $urlRouterProvider.otherwise('/');
      $stateProvider
        .state('index', {
          url: '/',
          templateUrl: 'views/index.html'
        })
        .state('app', {
          abstract: true,
          url: '',
          templateUrl: 'views/app.html',
          resolve: {
            auth: function($auth) {
              return $auth.validateUser();
            }
          }
        })
        .state('app.dashboard', {
          url: '/dashboard',
          templateUrl: 'views/app_dashboard.html',
          controller: 'DashboardCtrl',
          resolve: {
            dashboard_data: ['marinaApi',
              function(marinaApi) {
                return marinaApi.Dashboard.get();
              }
            ]
          }
        })
        .state('app.profile', {
          url: '/profile/:id',
          templateUrl: 'views/app_profile.html',
          controller: 'ProfileCtrl',
          resolve: {
            profile_user: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.User.get({id: $stateParams.id});
              }
            ]
          }
        })
        .state('app.repository_new', {
          url: '/repos/new',
          templateUrl: 'views/app_repository_form.html',
          controller: 'RepositoryCtrl',
          resolve: {
            repository: ['marinaApi',
              function(marinaApi) {
                return new marinaApi.Repository;
              }
            ]
          }
        })
        .state('app.repository', {
          url: '/repos/:owner/:name',
          templateUrl: 'views/app_repository.html',
          controller: 'RepositoryCtrl',
          resolve: {
            repository: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Repository.get({namespace: $stateParams.owner,  name: $stateParams.name});
              }
            ]
          }
        })
        .state('app.repository_list', {
          url: '/repos/:owner',
          templateUrl: 'views/app_repository_list.html',
          controller: 'RepositoryListCtrl',
          resolve: {
            repositoryList: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Repository.query({namespace: $stateParams.owner});
              }
            ]
          }
        })
        .state('app.repository_edit', {
          url: '/repos/:owner/:name/edit',
          templateUrl: 'views/app_repository_form.html',
          controller: 'RepositoryCtrl',
          resolve: {
            repository: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Repository.get({namespace: $stateParams.owner,  name: $stateParams.name});
              }
            ]
          }
        })
        .state('app.organization_edit', {
          url: '/organizations/:id/edit',
          templateUrl: 'views/app_organization_form.html',
          controller: 'OrganizationCtrl',
          resolve: {
            organization: ['marinaApi', '$stateParams',
              function(marinaApi, $stateParams) {
                return marinaApi.Organization.get({id: $stateParams.id});
              }
            ]
          }
        })
        .state('app.organization_new', {
          url: '/organizations/new',
          templateUrl: 'views/app_organization_form.html',
          controller: 'OrganizationCtrl',
          resolve: {
            organization: ['marinaApi',
              function(marinaApi) {
                return new marinaApi.Organization;
              }
            ]
          }
        })
        .state('app.repository_build_logs', {
          url: '/repos/:owner/:name/builds/:build_id/logs',
          templateUrl: 'views/app_repository_build_logs.html'
        })
        .state('auth', {
          abstract: true,
          url: '/auth',
          templateUrl: 'views/auth.html'
        })
        .state('auth.register', {
          url: '/register',
          templateUrl: 'views/auth_register.html'
        })
        .state('auth.login', {
          url: '/login',
          templateUrl: 'views/auth_login.html'
        })
        .state('auth.reset_password', {
          url: '/reset-password',
          templateUrl: 'views/auth_reset_password.html'
        })
        .state('auth.update_password', {
          url: '/update-password',
          templateUrl: 'views/auth_update_password.html'
        })

    }
  ]
);
<|endoftext|>


<commit_before>/*!
 *
 * Portamento  v1.1.1 - 2011-09-02
 * http://simianstudios.com/portamento
 *
 * Copyright 2011 Kris Noble except where noted.
 *
 * Dual-licensed under the GPLv3 and Apache 2.0 licenses:
 * http://www.gnu.org/licenses/gpl-3.0.html
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 */
(function($){$.fn.portamento=function(options){var thisWindow=$(window);var thisDocument=$(document);$.fn.viewportOffset=function(){var win=$(window);var offset=$(this).offset();return{left:offset.left-win.scrollLeft(),top:offset.top-win.scrollTop()}};function positionFixedSupported(){var container=document.body;if(document.createElement&&container&&container.appendChild&&container.removeChild){var el=document.createElement("div");if(!el.getBoundingClientRect){return null}el.innerHTML="x";el.style.cssText="position:fixed;top:100px;";container.appendChild(el);var originalHeight=container.style.height,originalScrollTop=container.scrollTop;container.style.height="3000px";container.scrollTop=500;var elementTop=el.getBoundingClientRect().top;container.style.height=originalHeight;var isSupported=elementTop===100;container.removeChild(el);container.scrollTop=originalScrollTop;return isSupported}return null}function getScrollerWidth(){var scr=null;var inn=null;var wNoScroll=0;var wScroll=0;scr=document.createElement("div");scr.style.position="absolute";scr.style.top="-1000px";scr.style.left="-1000px";scr.style.width="100px";scr.style.height="50px";scr.style.overflow="hidden";inn=document.createElement("div");inn.style.width="100%";inn.style.height="200px";scr.appendChild(inn);document.body.appendChild(scr);wNoScroll=inn.offsetWidth;scr.style.overflow="auto";wScroll=inn.offsetWidth;document.body.removeChild(document.body.lastChild);return(wNoScroll-wScroll)}var opts=$.extend({},$.fn.portamento.defaults,options);var panel=this;var wrapper=opts.wrapper;var gap=opts.gap;var disableWorkaround=opts.disableWorkaround;var fullyCapableBrowser=positionFixedSupported();if(panel.length!=1){return this}if(!fullyCapableBrowser&&disableWorkaround){return this}panel.wrap('<div id="portamento_container" />');var float_container=$("#portamento_container");float_container.css({"min-height":panel.outerHeight(),width:panel.outerWidth()});var panelOffset=panel.offset().top;var panelMargin=parseFloat(panel.css("marginTop").replace(/auto/,0));var realPanelOffset=panelOffset-panelMargin;var topScrollBoundary=realPanelOffset-gap;var wrapperPaddingFix=parseFloat(wrapper.css("paddingTop").replace(/auto/,0));var containerMarginFix=parseFloat(float_container.css("marginTop").replace(/auto/,0));var ieFix=0;var isMSIE=
/*@cc_on!@*/
0;if(isMSIE){ieFix=getScrollerWidth()+4}thisWindow.bind("scroll.portamento",function(){if(thisWindow.height()>panel.outerHeight()&&thisWindow.width()>=(thisDocument.width()-ieFix)){var y=thisDocument.scrollTop();if(y>=(topScrollBoundary)){if((panel.innerHeight()-wrapper.viewportOffset().top)-wrapperPaddingFix+gap>=wrapper.height()){if(panel.hasClass("fixed")||thisWindow.height()>=panel.outerHeight()){panel.removeClass("fixed");panel.css("top",(wrapper.height()-panel.innerHeight())+"px")}}else{panel.addClass("fixed");if(fullyCapableBrowser){panel.css("top",gap+"px")}else{panel.clearQueue();panel.css("position","absolute").animate({top:(0-float_container.viewportOffset().top+gap)})}}}else{panel.removeClass("fixed");panel.css("top","0")}}else{panel.removeClass("fixed")}});thisWindow.bind("resize.portamento",function(){if(thisWindow.height()<=panel.outerHeight()||thisWindow.width()<thisDocument.width()){if(panel.hasClass("fixed")){panel.removeClass("fixed");panel.css("top","0")}}else{thisWindow.trigger("scroll.portamento")}});thisWindow.bind("orientationchange.portamento",function(){thisWindow.trigger("resize.portamento")});thisWindow.trigger("scroll.portamento");return this};$.fn.portamento.defaults={wrapper:$("body"),gap:10,disableWorkaround:false}})(jQuery);<commit_msg>Removed portamento.js because it wasn't doing what we needed it to<commit_after><|endoftext|>


<commit_before>var tc = require('./testContext');
var expect = tc.expect;

function context(file, description, fn) {

	var ShapeFile = require('../lib/ShapeFile');

	var shapeFile = new ShapeFile(file);

	it(description, function(done) {

		fn.call(this, shapeFile, done);
	});

}

describe('On br.shp', function() {

	before(tc.download([
		{
			url: 'https://copy.com/yzHc6aQO76ko/shp.js/br.zip?download=1',
			name: 'br',
			test: 'br.shp'
		}
	]));

	describe('São João dos Patos / MA (-43.43312,-43.38103,-6.64456,-6.59436)', function() {

		geometry = tc.factory.toGeometry(tc.factory.envelope(-43.43312,-43.38103,-6.64456,-6.59436));
		context('br.shp', 'intersects', function(shapeFile, done) {

			this.timeout(1000);

			var cities = ['São João Dos Patos', 'Barão De Grajaú', 'Sucupira Do Riachão'];

			shapeFile.intersects(geometry, spy = tc.sinon.spy(tc.fix(function(err, result) {
				/*if (err)
					console.log(err.stack || err);*/

				expect(err).to.be.null;

				if (result !== null) {
					expect(cities).to.include(result.properties.NOME);
					cities = cities.filter(function(c) { return c !== result.properties.NOME;});
				}

				if (spy.callCount >= 4)
					done();
			})));

		});

	});

	describe('Paramirim / BA (-42.23482,-41.84175,-13.55158,-13.44922)', function() {

		var geometry = tc.factory.toGeometry(tc.factory.envelope(-42.23482,-41.84175,-13.55158,-13.44922));

		context('br.shp', 'intersects', function(shapeFile, done) {
			var spy;
			shapeFile.intersects(geometry, spy = tc.sinon.spy(tc.fix(function(err, response) {
				/*if (err !== null)
					console.log(err.stack || err);*/

				expect(err).to.be.null;

				/*console.log('callCount = %d', spy.callCount);*/

				//console.log(response.properties.NOME);

				if (spy.callCount >= 5)
					done();
			})));

		});
	});

});<commit_msg>Correct city name<commit_after>var tc = require('./testContext');
var expect = tc.expect;

function context(file, description, fn) {

	var ShapeFile = require('../lib/ShapeFile');

	var shapeFile = new ShapeFile(file);

	it(description, function(done) {

		fn.call(this, shapeFile, done);
	});

}

describe('On br.shp', function() {

	before(tc.download([
		{
			url: 'https://copy.com/yzHc6aQO76ko/shp.js/br.zip?download=1',
			name: 'br',
			test: 'br.shp'
		}
	]));

	describe('São João dos Patos / MA (-43.43312,-43.38103,-6.64456,-6.59436)', function() {

		geometry = tc.factory.toGeometry(tc.factory.envelope(-43.43312,-43.38103,-6.64456,-6.59436));
		context('br.shp', 'intersects', function(shapeFile, done) {

			this.timeout(1000);

			var cities = ['São João Dos Patos', 'Barão De Grajaú', 'Sucupira Do Riachão'];

			shapeFile.intersects(geometry, spy = tc.sinon.spy(tc.fix(function(err, result) {
				/*if (err)
					console.log(err.stack || err);*/

				expect(err).to.be.null;

				if (result !== null) {
					expect(cities).to.include(result.properties.NOME);
					cities = cities.filter(function(c) { return c !== result.properties.NOME;});
				}

				if (spy.callCount >= 4)
					done();
			})));

		});

	});

	describe('Érico Cardoso / BA (-42.23482,-41.84175,-13.55158,-13.44922)', function() {

		var geometry = tc.factory.toGeometry(tc.factory.envelope(-42.23482,-41.84175,-13.55158,-13.44922));

		context('br.shp', 'intersects', function(shapeFile, done) {
			var spy;
			shapeFile.intersects(geometry, spy = tc.sinon.spy(tc.fix(function(err, response) {
				/*if (err !== null)
					console.log(err.stack || err);*/

				expect(err).to.be.null;

				/*console.log('callCount = %d', spy.callCount);*/

				//console.log(response.properties.NOME);

				if (spy.callCount >= 5)
					done();
			})));

		});
	});

});<|endoftext|>