<commit_before>import Ember from "ember";
const isSimpleClick = Ember.ViewUtils.isSimpleClick;

import get from 'ember-metal/get';
import set from 'ember-metal/set';
import { copy, generateGuid } from 'ember-metal/utils';
import computed from 'ember-computed';
import { w } from 'ember-string';
import { bind, next, later } from 'ember-runloop';
import $ from 'jquery';
import { assert } from 'ember-metal/utils';
import { A } from 'ember-array/utils';
import Evented from 'ember-evented';
import EmberObject from 'ember-object';

function guard (fn) {
  return function (evt) {
    if (get(this, 'component.disabled')) { return; }
    fn.call(this, evt);
  };
}

function getElementForTarget(target) {
  if (typeof target === 'string') {
    return document.getElementById(target);
  } else if (get(target, 'element')) {
    return get(target, 'element');
  } else {
    return target;
  }
}

function getLabelSelector($element) {
  let id = $element.attr('id');
  if (id) {
    return `label[for="${id}"]`;
  }
}

function labelForEvent(evt) {
  let $target = $(evt.target);
  if ($target[0].tagName.toLowerCase() === 'label') {
    return $target;
  } else {
    return $target.parents('label');
  }
}

function isLabelClicked(target, label) {
  if (label == null) {
    return false;
  }
  return $(label).attr('for') === $(target).attr('id');
}

const VALID_ACTIVATORS = ["focus", "hover", "click", "hold"];
function parseActivators(value) {
  if (value) {
    let activators = value;
    if (typeof value === "string") {
      activators = A(w(value));
    }
    assert(
      `${value} are not valid activators.
        Valid events are ${VALID_ACTIVATORS.join(', ')}`,
      A(copy(activators)).removeObjects(VALID_ACTIVATORS).length === 0
    );
    return activators;
  }

  assert(
    `You must provide an event name to the {{pop-over}}.
      Valid events are ${VALID_ACTIVATORS.join(', ')}`,
    false
  );
}

function poll(target, scope, fn) {
  if (getElementForTarget(target)) {
    scope[fn]();
  } else {
    next(null, poll, target, scope, fn);
  }
}

export default EmberObject.extend(Evented, {

  init: function () {
    let target = get(this, 'target');
    assert("You cannot make the {{pop-over}} a target of itself.", get(this, 'component') !== target);

    this.eventManager = {
      focusin:    bind(this, 'focus'),
      focusout:   bind(this, 'blur'),
      mouseenter: bind(this, 'mouseEnter'),
      mouseleave: bind(this, 'mouseLeave'),
      mousedown:  bind(this, 'mouseDown')
    };

    if (get(target, 'element')) {
      this.attach();
    } else if (target.one) {
      target.one('didInsertElement', this, 'attach');
    } else if (typeof target === 'string') {
      poll(target, this, 'attach');
    }
  },

  attach: function () {
    let element = getElementForTarget(this.target);
    let $element = $(element);
    let $document = $(document);

    // Already attached or awaiting an element to exist
    if (get(this, 'attached') || element == null) { return; }

    set(this, 'attached', true);
    set(this, 'element', element);

    let id = $element.attr('id');
    if (id == null) {
      id = generateGuid();
      $element.attr('id', id);
    }

    let eventManager = this.eventManager;

    Object.keys(eventManager).forEach(function (event) {
      $document.on(event, `#${id}`, eventManager[event]);
    });

    let selector = getLabelSelector($element);
    if (selector) {
      Object.keys(eventManager).forEach(function (event) {
        $document.on(event, selector, eventManager[event]);
      });
    }
  },

  detach: function () {
    let element = this.element;
    let $element = $(element);
    let $document = $(document);

    let eventManager = this.eventManager;

    let id = $element.attr('id');
    Object.keys(eventManager).forEach(function (event) {
      $document.off(event, '#' + id, eventManager[event]);
    });

    let selector = getLabelSelector($element);
    if (selector) {
      Object.keys(eventManager).forEach(function (event) {
        $document.off(event, selector, eventManager[event]);
      });
    }

    // Remove references for GC
    this.eventManager = null;
    set(this, 'element', null);
    set(this, 'target', null);
    set(this, 'component', null);
  },

  on: computed({
    set(key, value) {
      return parseActivators(value);
    }
  }),

  isClicked: function (evt) {
    if (isSimpleClick(evt)) {
      let label = labelForEvent(evt);
      let element = this.element;
      return evt.target === element || $.contains(element, evt.target) ||
        isLabelClicked(element, label);
    }
    return false;
  },

  active: computed('focused', 'hovered', 'pressed', 'component.hovered', 'component.pressed', {
    set(key, value) {
      let activators = get(this, 'on');
      if (value) {
        if (activators.contains('focus')) {
          set(this, 'focused', true);
        } else if (activators.contains('hover')) {
          set(this, 'hovered', true);
        } else if (activators.contains('click')) {
          set(this, 'pressed', true);
        }
      } else {
        set(this, 'focused', false);
        set(this, 'hovered', false);
        set(this, 'pressed', false);
      }
      return value;
    },

    get() {
      let activators = get(this, 'on');
      let active = false;

      if (activators.contains('focus')) {
        active = active || get(this, 'focused');
        if (activators.contains('hold')) {
          active = active || get(this, 'component.pressed');
        }
      }

      if (activators.contains('hover')) {
        active = active || get(this, 'hovered');
        if (activators.contains('hold')) {
          active = active || get(this, 'component.hovered');
        }
      }

      if (activators.contains('click') || activators.contains('hold')) {
        active = active || get(this, 'pressed');
      }

      return !!active;
    }
  }),

  focus: guard(function () {
    set(this, 'focused', true);
  }),

  blur: guard(function () {
    set(this, 'focused', false);
  }),

  mouseEnter: guard(function () {
    this._willLeave = false;
    set(this, 'hovered', true);
    this._willLeave = false;
  }),

  mouseLeave: guard(function () {
    this._willLeave = true;
    later(() => {
      if (get(this, 'component.disabled')) { return; }
      if (this._willLeave) {
        this._willLeave = false;
        set(this, 'hovered', false);
      }
    }, 150);
  }),

  mouseDown: guard(function (evt) {
    if (!this.isClicked(evt)) {
      return false;
    }

    let element = this.element;
    let active = !get(this, 'active');
    set(this, 'pressed', active);

    if (active) {
      this.holdStart = new Date().getTime();

      let eventManager = this.eventManager;
      eventManager.mouseup = bind(this, 'mouseUp');
      $(document).on('mouseup', eventManager.mouseup);

      evt.preventDefault();
    }

    $(element).focus();
    return true;
  }),

  mouseUp: function (evt) {
    // Remove mouseup event
    let eventManager = this.eventManager;
    $(document).off('mouseup', eventManager.mouseup);
    eventManager.mouseup = null;

    let label = labelForEvent(evt);

    // Treat clicks on <label> elements as triggers to
    // open the menu
    if (isLabelClicked(this.element, label)) {
      return true;
    }

    let activators = get(this, 'on');

    if (activators.contains('click') && activators.contains('hold')) {
      // If the user waits more than 400ms between mouseDown and mouseUp,
      // we can assume that they are clicking and dragging to the menu item,
      // and we should close the menu if they mouseup anywhere not inside
      // the menu.
      if (new Date().getTime() - this.holdStart > 400) {
        set(this, 'pressed', false);
      }
    }
    return true;
  }

});

<commit_msg>fix #34 by supporting new includes syntax for ember 2.8<commit_after>import Ember from "ember";
const isSimpleClick = Ember.ViewUtils.isSimpleClick;

import get from 'ember-metal/get';
import set from 'ember-metal/set';
import { copy, generateGuid } from 'ember-metal/utils';
import computed from 'ember-computed';
import { w } from 'ember-string';
import { bind, next, later } from 'ember-runloop';
import $ from 'jquery';
import { assert } from 'ember-metal/utils';
import { A } from 'ember-array/utils';
import Evented from 'ember-evented';
import EmberObject from 'ember-object';

function includes(haystack, needle) {
  if (haystack.includes) {
    return haystack.includes(needle);
  } else {
    return haystack.contains(needle);
  }
}

function guard (fn) {
  return function (evt) {
    if (get(this, 'component.disabled')) { return; }
    fn.call(this, evt);
  };
}

function getElementForTarget(target) {
  if (typeof target === 'string') {
    return document.getElementById(target);
  } else if (get(target, 'element')) {
    return get(target, 'element');
  } else {
    return target;
  }
}

function getLabelSelector($element) {
  let id = $element.attr('id');
  if (id) {
    return `label[for="${id}"]`;
  }
}

function labelForEvent(evt) {
  let $target = $(evt.target);
  if ($target[0].tagName.toLowerCase() === 'label') {
    return $target;
  } else {
    return $target.parents('label');
  }
}

function isLabelClicked(target, label) {
  if (label == null) {
    return false;
  }
  return $(label).attr('for') === $(target).attr('id');
}

const VALID_ACTIVATORS = ["focus", "hover", "click", "hold"];
function parseActivators(value) {
  if (value) {
    let activators = value;
    if (typeof value === "string") {
      activators = A(w(value));
    }
    assert(
      `${value} are not valid activators.
        Valid events are ${VALID_ACTIVATORS.join(', ')}`,
      A(copy(activators)).removeObjects(VALID_ACTIVATORS).length === 0
    );
    return activators;
  }

  assert(
    `You must provide an event name to the {{pop-over}}.
      Valid events are ${VALID_ACTIVATORS.join(', ')}`,
    false
  );
}

function poll(target, scope, fn) {
  if (getElementForTarget(target)) {
    scope[fn]();
  } else {
    next(null, poll, target, scope, fn);
  }
}

export default EmberObject.extend(Evented, {

  init: function () {
    let target = get(this, 'target');
    assert("You cannot make the {{pop-over}} a target of itself.", get(this, 'component') !== target);

    this.eventManager = {
      focusin:    bind(this, 'focus'),
      focusout:   bind(this, 'blur'),
      mouseenter: bind(this, 'mouseEnter'),
      mouseleave: bind(this, 'mouseLeave'),
      mousedown:  bind(this, 'mouseDown')
    };

    if (get(target, 'element')) {
      this.attach();
    } else if (target.one) {
      target.one('didInsertElement', this, 'attach');
    } else if (typeof target === 'string') {
      poll(target, this, 'attach');
    }
  },

  attach: function () {
    let element = getElementForTarget(this.target);
    let $element = $(element);
    let $document = $(document);

    // Already attached or awaiting an element to exist
    if (get(this, 'attached') || element == null) { return; }

    set(this, 'attached', true);
    set(this, 'element', element);

    let id = $element.attr('id');
    if (id == null) {
      id = generateGuid();
      $element.attr('id', id);
    }

    let eventManager = this.eventManager;

    Object.keys(eventManager).forEach(function (event) {
      $document.on(event, `#${id}`, eventManager[event]);
    });

    let selector = getLabelSelector($element);
    if (selector) {
      Object.keys(eventManager).forEach(function (event) {
        $document.on(event, selector, eventManager[event]);
      });
    }
  },

  detach: function () {
    let element = this.element;
    let $element = $(element);
    let $document = $(document);

    let eventManager = this.eventManager;

    let id = $element.attr('id');
    Object.keys(eventManager).forEach(function (event) {
      $document.off(event, '#' + id, eventManager[event]);
    });

    let selector = getLabelSelector($element);
    if (selector) {
      Object.keys(eventManager).forEach(function (event) {
        $document.off(event, selector, eventManager[event]);
      });
    }

    // Remove references for GC
    this.eventManager = null;
    set(this, 'element', null);
    set(this, 'target', null);
    set(this, 'component', null);
  },

  on: computed({
    set(key, value) {
      return parseActivators(value);
    }
  }),

  isClicked: function (evt) {
    if (isSimpleClick(evt)) {
      let label = labelForEvent(evt);
      let element = this.element;
      return evt.target === element || $.contains(element, evt.target) ||
        isLabelClicked(element, label);
    }
    return false;
  },

  active: computed('focused', 'hovered', 'pressed', 'component.hovered', 'component.pressed', {
    set(key, value) {
      let activators = get(this, 'on');
      if (value) {
        if (includes(activators, 'focus')) {
          set(this, 'focused', true);
        } else if (includes(activators, 'hover')) {
          set(this, 'hovered', true);
        } else if (includes(activators, 'click')) {
          set(this, 'pressed', true);
        }
      } else {
        set(this, 'focused', false);
        set(this, 'hovered', false);
        set(this, 'pressed', false);
      }
      return value;
    },

    get() {
      let activators = get(this, 'on');
      let active = false;

      if (includes(activators, 'focus')) {
        active = active || get(this, 'focused');
        if (includes(activators, 'hold')) {
          active = active || get(this, 'component.pressed');
        }
      }

      if (includes(activators, 'hover')) {
        active = active || get(this, 'hovered');
        if (includes(activators, 'hold')) {
          active = active || get(this, 'component.hovered');
        }
      }

      if (includes(activators, 'click') || includes(activators, 'hold')) {
        active = active || get(this, 'pressed');
      }

      return !!active;
    }
  }),

  focus: guard(function () {
    set(this, 'focused', true);
  }),

  blur: guard(function () {
    set(this, 'focused', false);
  }),

  mouseEnter: guard(function () {
    this._willLeave = false;
    set(this, 'hovered', true);
    this._willLeave = false;
  }),

  mouseLeave: guard(function () {
    this._willLeave = true;
    later(() => {
      if (get(this, 'component.disabled')) { return; }
      if (this._willLeave) {
        this._willLeave = false;
        set(this, 'hovered', false);
      }
    }, 150);
  }),

  mouseDown: guard(function (evt) {
    if (!this.isClicked(evt)) {
      return false;
    }

    let element = this.element;
    let active = !get(this, 'active');
    set(this, 'pressed', active);

    if (active) {
      this.holdStart = new Date().getTime();

      let eventManager = this.eventManager;
      eventManager.mouseup = bind(this, 'mouseUp');
      $(document).on('mouseup', eventManager.mouseup);

      evt.preventDefault();
    }

    $(element).focus();
    return true;
  }),

  mouseUp: function (evt) {
    // Remove mouseup event
    let eventManager = this.eventManager;
    $(document).off('mouseup', eventManager.mouseup);
    eventManager.mouseup = null;

    let label = labelForEvent(evt);

    // Treat clicks on <label> elements as triggers to
    // open the menu
    if (isLabelClicked(this.element, label)) {
      return true;
    }

    let activators = get(this, 'on');

    if (includes(activators, 'click') && includes(activators, 'hold')) {
      // If the user waits more than 400ms between mouseDown and mouseUp,
      // we can assume that they are clicking and dragging to the menu item,
      // and we should close the menu if they mouseup anywhere not inside
      // the menu.
      if (new Date().getTime() - this.holdStart > 400) {
        set(this, 'pressed', false);
      }
    }
    return true;
  }

});

<|endoftext|>


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

// @ts-nocheck
// TODO(crbug.com/1011811): Enable TypeScript compiler checks

import * as Common from '../common/common.js';  // eslint-disable-line no-unused-vars
import * as Host from '../host/host.js';
import * as UI from '../ui/ui.js';

import {DeviceModeWrapper} from './DeviceModeWrapper.js';
import {Events, instance} from './InspectedPagePlaceholder.js';

/** @type {!AdvancedApp} */
let _appInstance;

/**
 * @implements {Common.App.App}
 * @unrestricted
 */
export class AdvancedApp {
  constructor() {
    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.BeforeDockSideChanged, this._openToolboxWindow, this);
  }

  /**
   * @return {!AdvancedApp}
   */
  static _instance() {
    if (!_appInstance) {
      _appInstance = new AdvancedApp();
    }
    return _appInstance;
  }

  /**
   * @override
   * @param {!Document} document
   */
  presentUI(document) {
    const rootView = new UI.RootView.RootView();

    this._rootSplitWidget = new UI.SplitWidget.SplitWidget(false, true, 'InspectorView.splitViewState', 555, 300, true);
    this._rootSplitWidget.show(rootView.element);
    this._rootSplitWidget.setSidebarWidget(UI.InspectorView.InspectorView.instance());
    this._rootSplitWidget.setDefaultFocusedChild(UI.InspectorView.InspectorView.instance());
    UI.InspectorView.InspectorView.instance().setOwnerSplit(this._rootSplitWidget);

    this._inspectedPagePlaceholder = instance();
    this._inspectedPagePlaceholder.addEventListener(Events.Update, this._onSetInspectedPageBounds.bind(this), this);
    this._deviceModeView = new DeviceModeWrapper(this._inspectedPagePlaceholder);

    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.BeforeDockSideChanged, this._onBeforeDockSideChange, this);
    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.DockSideChanged, this._onDockSideChange, this);
    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.AfterDockSideChanged, this._onAfterDockSideChange, this);
    this._onDockSideChange();

    console.timeStamp('AdvancedApp.attachToBody');
    rootView.attachToDocument(document);
    rootView.focus();
    this._inspectedPagePlaceholder.update();
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _openToolboxWindow(event) {
    if (/** @type {string} */ (event.data.to) !== UI.DockController.State.Undocked) {
      return;
    }

    if (this._toolboxWindow) {
      return;
    }

    const url = window.location.href.replace('devtools_app.html', 'toolbox.html');
    this._toolboxWindow = window.open(url, undefined);
  }

  /**
   * @param {!Document} toolboxDocument
   */
  toolboxLoaded(toolboxDocument) {
    UI.UIUtils.initializeUIUtils(
        toolboxDocument, Common.Settings.Settings.instance().createSetting('uiTheme', 'default'));
    UI.UIUtils.installComponentRootStyles(/** @type {!Element} */ (toolboxDocument.body));
    UI.ContextMenu.ContextMenu.installHandler(toolboxDocument);
    UI.Tooltip.Tooltip.installHandler(toolboxDocument);

    this._toolboxRootView = new UI.RootView.RootView();
    this._toolboxRootView.attachToDocument(toolboxDocument);

    this._updateDeviceModeView();
  }

  _updateDeviceModeView() {
    if (this._isDocked()) {
      this._rootSplitWidget.setMainWidget(this._deviceModeView);
    } else if (this._toolboxRootView) {
      this._deviceModeView.show(this._toolboxRootView.element);
    }
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _onBeforeDockSideChange(event) {
    if (/** @type {string} */ (event.data.to) === UI.DockController.State.Undocked && this._toolboxRootView) {
      // Hide inspectorView and force layout to mimic the undocked state.
      this._rootSplitWidget.hideSidebar();
      this._inspectedPagePlaceholder.update();
    }

    this._changingDockSide = true;
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent=} event
   */
  _onDockSideChange(event) {
    this._updateDeviceModeView();

    const toDockSide =
        event ? /** @type {string} */ (event.data.to) : UI.DockController.DockController.instance().dockSide();
    if (toDockSide === UI.DockController.State.Undocked) {
      this._updateForUndocked();
    } else if (
        this._toolboxRootView && event &&
        /** @type {string} */ (event.data.from) === UI.DockController.State.Undocked) {
      // Don't update yet for smooth transition.
      this._rootSplitWidget.hideSidebar();
    } else {
      this._updateForDocked(toDockSide);
    }
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _onAfterDockSideChange(event) {
    // We may get here on the first dock side change while loading without BeforeDockSideChange.
    if (!this._changingDockSide) {
      return;
    }
    if (/** @type {string} */ (event.data.from) === UI.DockController.State.Undocked) {
      // Restore docked layout in case of smooth transition.
      this._updateForDocked(/** @type {string} */ (event.data.to));
    }
    this._changingDockSide = false;
    this._inspectedPagePlaceholder.update();
  }

  /**
   * @param {string} dockSide
   */
  _updateForDocked(dockSide) {
    this._rootSplitWidget.resizerElement().style.transform = dockSide === UI.DockController.State.DockedToRight ?
        'translateX(2px)' :
        dockSide === UI.DockController.State.DockedToLeft ? 'translateX(-2px)' : '';
    this._rootSplitWidget.setVertical(
        dockSide === UI.DockController.State.DockedToRight || dockSide === UI.DockController.State.DockedToLeft);
    this._rootSplitWidget.setSecondIsSidebar(
        dockSide === UI.DockController.State.DockedToRight || dockSide === UI.DockController.State.DockedToBottom);
    this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), true);
    this._rootSplitWidget.toggleResizer(
        UI.InspectorView.InspectorView.instance().topResizerElement(),
        dockSide === UI.DockController.State.DockedToBottom);
    this._rootSplitWidget.showBoth();
  }

  _updateForUndocked() {
    this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), false);
    this._rootSplitWidget.toggleResizer(UI.InspectorView.InspectorView.instance().topResizerElement(), false);
    this._rootSplitWidget.hideMain();
  }

  _isDocked() {
    return UI.DockController.DockController.instance().dockSide() !== UI.DockController.State.Undocked;
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _onSetInspectedPageBounds(event) {
    if (this._changingDockSide) {
      return;
    }
    const window = this._inspectedPagePlaceholder.element.window();
    if (!window.innerWidth || !window.innerHeight) {
      return;
    }
    if (!this._inspectedPagePlaceholder.isShowing()) {
      return;
    }
    const bounds = /** @type {{x: number, y: number, width: number, height: number}} */ (event.data);
    console.timeStamp('AdvancedApp.setInspectedPageBounds');
    Host.InspectorFrontendHost.InspectorFrontendHostInstance.setInspectedPageBounds(bounds);
  }
}

/**
 * @implements {Common.AppProvider.AppProvider}
 * @unrestricted
 */
export class AdvancedAppProvider {
  /**
   * @override
   * @return {!Common.App.App}
   */
  createApp() {
    return AdvancedApp._instance();
  }
}
<commit_msg>Enable TypeScript for AdvancedApp.js<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as Common from '../common/common.js';  // eslint-disable-line no-unused-vars
import * as Host from '../host/host.js';
import * as UI from '../ui/ui.js';

import {DeviceModeWrapper} from './DeviceModeWrapper.js';
import {Events, InspectedPagePlaceholder, instance} from './InspectedPagePlaceholder.js';  // eslint-disable-line no-unused-vars

/** @type {!AdvancedApp} */
let _appInstance;

/**
 * @implements {Common.App.App}
 * @unrestricted
 */
export class AdvancedApp {
  constructor() {
    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.BeforeDockSideChanged, this._openToolboxWindow, this);

    // These attributes are guaranteed to be initialised in presentUI that
    // is invoked immediately after construction.
    /**
     * @type {!UI.SplitWidget.SplitWidget}
     */
    this._rootSplitWidget;

    /**
     * @type {!DeviceModeWrapper}
     */
    this._deviceModeView;

    /**
     * @type {!InspectedPagePlaceholder}
     */
    this._inspectedPagePlaceholder;
  }

  /**
   * @return {!AdvancedApp}
   */
  static _instance() {
    if (!_appInstance) {
      _appInstance = new AdvancedApp();
    }
    return _appInstance;
  }

  /**
   * @override
   * @param {!Document} document
   */
  presentUI(document) {
    const rootView = new UI.RootView.RootView();

    this._rootSplitWidget = new UI.SplitWidget.SplitWidget(false, true, 'InspectorView.splitViewState', 555, 300, true);
    this._rootSplitWidget.show(rootView.element);
    this._rootSplitWidget.setSidebarWidget(UI.InspectorView.InspectorView.instance());
    this._rootSplitWidget.setDefaultFocusedChild(UI.InspectorView.InspectorView.instance());
    UI.InspectorView.InspectorView.instance().setOwnerSplit(this._rootSplitWidget);

    this._inspectedPagePlaceholder = instance();
    this._inspectedPagePlaceholder.addEventListener(Events.Update, this._onSetInspectedPageBounds.bind(this), this);
    this._deviceModeView = new DeviceModeWrapper(this._inspectedPagePlaceholder);

    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.BeforeDockSideChanged, this._onBeforeDockSideChange, this);
    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.DockSideChanged, this._onDockSideChange, this);
    UI.DockController.DockController.instance().addEventListener(
        UI.DockController.Events.AfterDockSideChanged, this._onAfterDockSideChange, this);
    this._onDockSideChange();

    console.timeStamp('AdvancedApp.attachToBody');
    rootView.attachToDocument(document);
    rootView.focus();
    this._inspectedPagePlaceholder.update();
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _openToolboxWindow(event) {
    if (/** @type {string} */ (event.data.to) !== UI.DockController.State.Undocked) {
      return;
    }

    if (this._toolboxWindow) {
      return;
    }

    const url = window.location.href.replace('devtools_app.html', 'toolbox.html');
    this._toolboxWindow = window.open(url, undefined);
  }

  /**
   * @param {!Document} toolboxDocument
   */
  toolboxLoaded(toolboxDocument) {
    UI.UIUtils.initializeUIUtils(
        toolboxDocument, Common.Settings.Settings.instance().createSetting('uiTheme', 'default'));
    UI.UIUtils.installComponentRootStyles(/** @type {!Element} */ (toolboxDocument.body));
    UI.ContextMenu.ContextMenu.installHandler(toolboxDocument);
    UI.Tooltip.Tooltip.installHandler(toolboxDocument);

    this._toolboxRootView = new UI.RootView.RootView();
    this._toolboxRootView.attachToDocument(toolboxDocument);

    this._updateDeviceModeView();
  }

  _updateDeviceModeView() {
    if (this._isDocked()) {
      this._rootSplitWidget.setMainWidget(this._deviceModeView);
    } else if (this._toolboxRootView) {
      this._deviceModeView.show(this._toolboxRootView.element);
    }
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _onBeforeDockSideChange(event) {
    if (/** @type {string} */ (event.data.to) === UI.DockController.State.Undocked && this._toolboxRootView) {
      // Hide inspectorView and force layout to mimic the undocked state.
      this._rootSplitWidget.hideSidebar();
      this._inspectedPagePlaceholder.update();
    }

    this._changingDockSide = true;
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent=} event
   */
  _onDockSideChange(event) {
    this._updateDeviceModeView();

    const toDockSide =
        event ? /** @type {string} */ (event.data.to) : UI.DockController.DockController.instance().dockSide();
    if (toDockSide === UI.DockController.State.Undocked) {
      this._updateForUndocked();
    } else if (
        this._toolboxRootView && event &&
        /** @type {string} */ (event.data.from) === UI.DockController.State.Undocked) {
      // Don't update yet for smooth transition.
      this._rootSplitWidget.hideSidebar();
    } else {
      this._updateForDocked(toDockSide);
    }
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _onAfterDockSideChange(event) {
    // We may get here on the first dock side change while loading without BeforeDockSideChange.
    if (!this._changingDockSide) {
      return;
    }
    if (/** @type {string} */ (event.data.from) === UI.DockController.State.Undocked) {
      // Restore docked layout in case of smooth transition.
      this._updateForDocked(/** @type {string} */ (event.data.to));
    }
    this._changingDockSide = false;
    this._inspectedPagePlaceholder.update();
  }

  /**
   * @param {string} dockSide
   */
  _updateForDocked(dockSide) {
    const resizerElement = /** @type {!HTMLElement} */ (this._rootSplitWidget.resizerElement());
    resizerElement.style.transform = dockSide === UI.DockController.State.DockedToRight ?
        'translateX(2px)' :
        dockSide === UI.DockController.State.DockedToLeft ? 'translateX(-2px)' : '';
    this._rootSplitWidget.setVertical(
        dockSide === UI.DockController.State.DockedToRight || dockSide === UI.DockController.State.DockedToLeft);
    this._rootSplitWidget.setSecondIsSidebar(
        dockSide === UI.DockController.State.DockedToRight || dockSide === UI.DockController.State.DockedToBottom);
    this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), true);
    this._rootSplitWidget.toggleResizer(
        UI.InspectorView.InspectorView.instance().topResizerElement(),
        dockSide === UI.DockController.State.DockedToBottom);
    this._rootSplitWidget.showBoth();
  }

  _updateForUndocked() {
    this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), false);
    this._rootSplitWidget.toggleResizer(UI.InspectorView.InspectorView.instance().topResizerElement(), false);
    this._rootSplitWidget.hideMain();
  }

  _isDocked() {
    return UI.DockController.DockController.instance().dockSide() !== UI.DockController.State.Undocked;
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  _onSetInspectedPageBounds(event) {
    if (this._changingDockSide) {
      return;
    }
    const window = this._inspectedPagePlaceholder.element.window();
    if (!window.innerWidth || !window.innerHeight) {
      return;
    }
    if (!this._inspectedPagePlaceholder.isShowing()) {
      return;
    }
    const bounds = /** @type {{x: number, y: number, width: number, height: number}} */ (event.data);
    console.timeStamp('AdvancedApp.setInspectedPageBounds');
    Host.InspectorFrontendHost.InspectorFrontendHostInstance.setInspectedPageBounds(bounds);
  }
}

/**
 * @implements {Common.AppProvider.AppProvider}
 * @unrestricted
 */
export class AdvancedAppProvider {
  /**
   * @override
   * @return {!Common.App.App}
   */
  createApp() {
    return AdvancedApp._instance();
  }
}
<|endoftext|>


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

import {ls} from '../common/common.js';  // eslint-disable-line rulesdir/es_modules_import

import {Issue, IssueCategory, IssueKind, MarkdownIssueDescription} from './Issue.js';  // eslint-disable-line no-unused-vars

export class MixedContentIssue extends Issue {
  /**
   * @param {!Protocol.Audits.MixedContentIssueDetails} issueDetails
   */
  constructor(issueDetails) {
    super(Protocol.Audits.InspectorIssueCode.MixedContentIssue);
    this._issueDetails = issueDetails;
  }

  /**
   * @param {string} resolutionStatus
   * @returns {!string}
   */
  static translateStatus(resolutionStatus) {
    return mixedContentStatus.get(resolutionStatus) || resolutionStatus;
  }

  /**
   * @override
   * @returns {!Iterable<Protocol.Audits.AffectedRequest>}
   */
  requests() {
    if (this._issueDetails.request) {
      return [this._issueDetails.request];
    }
    return [];
  }

  /**
   * @override
   * @returns {!Iterable<!Protocol.Audits.MixedContentIssueDetails>}
   */
  mixedContents() {
    return [this._issueDetails];
  }

  /**
   * @override
   * @return {!IssueCategory}
   */
  getCategory() {
    return IssueCategory.MixedContent;
  }

  /**
   * @override
   * @returns {!MarkdownIssueDescription}
   */
  getDescription() {
    return {
      file: 'issues/descriptions/mixedContent.md',
      issueKind: IssueKind.BreakingChange,
      links: [{
        link: 'https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content',
        linkTitle: ls`Preventing mixed content`
      }],
    };
  }

  /**
  * @override
  */
  primaryKey() {
    return JSON.stringify(this._issueDetails);
  }
}

/** @type {!Map<string, string>} */
const mixedContentStatus = new Map([
  ['MixedContentBlocked', ls`blocked`],
  ['MixedContentAutomaticallyUpgraded', ls`automatically upgraded`],
  ['MixedContentWarning', ls`warned`],
]);
<commit_msg>Update URL for link to mixed content explainer<commit_after>// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {ls} from '../common/common.js';  // eslint-disable-line rulesdir/es_modules_import

import {Issue, IssueCategory, IssueKind, MarkdownIssueDescription} from './Issue.js';  // eslint-disable-line no-unused-vars

export class MixedContentIssue extends Issue {
  /**
   * @param {!Protocol.Audits.MixedContentIssueDetails} issueDetails
   */
  constructor(issueDetails) {
    super(Protocol.Audits.InspectorIssueCode.MixedContentIssue);
    this._issueDetails = issueDetails;
  }

  /**
   * @param {string} resolutionStatus
   * @returns {!string}
   */
  static translateStatus(resolutionStatus) {
    return mixedContentStatus.get(resolutionStatus) || resolutionStatus;
  }

  /**
   * @override
   * @returns {!Iterable<Protocol.Audits.AffectedRequest>}
   */
  requests() {
    if (this._issueDetails.request) {
      return [this._issueDetails.request];
    }
    return [];
  }

  /**
   * @override
   * @returns {!Iterable<!Protocol.Audits.MixedContentIssueDetails>}
   */
  mixedContents() {
    return [this._issueDetails];
  }

  /**
   * @override
   * @return {!IssueCategory}
   */
  getCategory() {
    return IssueCategory.MixedContent;
  }

  /**
   * @override
   * @returns {!MarkdownIssueDescription}
   */
  getDescription() {
    return {
      file: 'issues/descriptions/mixedContent.md',
      issueKind: IssueKind.BreakingChange,
      links: [{link: 'https://web.dev/what-is-mixed-content/', linkTitle: ls`Preventing mixed content`}],
    };
  }

  /**
  * @override
  */
  primaryKey() {
    return JSON.stringify(this._issueDetails);
  }
}

/** @type {!Map<string, string>} */
const mixedContentStatus = new Map([
  ['MixedContentBlocked', ls`blocked`],
  ['MixedContentAutomaticallyUpgraded', ls`automatically upgraded`],
  ['MixedContentWarning', ls`warned`],
]);
<|endoftext|>


<commit_before>/**
 * Created by lev on 26.11.13.
 */

var app = angular.module("ghashStatusApp", ['ngTouch']);

    app.controller("dataCtrl", function ($scope, $http) {

        function loadSettings() {

            var session = {};

            for (var i in window.localStorage) {
                session[i] = window.localStorage[i] == "undefined"? "": window.localStorage[i];
            }
            return session;
        }

        $scope.session = loadSettings();

        function GenButtons(id) {

            this.buttons = [
                {"id": 0, "name": "Th", "len": 1e6},
                {"id": 1, "name": "Gh", "len": 1e3},
                {"id": 2, "name": "Mh", "len": 1e1},
                {"id": 3, "name": "Kh", "len": 1}
            ];

            this.now = this.buttons[id];
            this.len = this.now.len;
            this.now.style = 'active';
        }

        ($scope.setActive = function (button) {

            window.localStorage.setItem("measure", button.id || 0);
            $scope.measure = new GenButtons(button.id || 0);

        })({"id": window.localStorage.measure});

        $scope.round = function (data) {
            if (!data) return "No data!";
            return Math.round(data / $scope.measure.len);
        };

        function Requester() {

            var genParamObj = function () {

                var S = window.localStorage,
                    nonce = Date.now(),
                    signature = genSig();

                function genSig() {

                    var message = (nonce + S.userName + S.api_key) || "null",
                        hash = CryptoJS.HmacSHA256(message, S.api_secret || "null");

                    return CryptoJS.enc.Hex.stringify(hash).toUpperCase();
                }

                return  {
                    key: S.api_key,
                    signature: signature,
                    nonce: nonce
                };
            };

            this.getPower = function (url, model) {
                $http.post(url, genParamObj())
                    .success(function (data) {
                        $scope[model] = data;
                    });
            };
        }

        $scope.saveSettings = function () {
            for (var i in this.session) {
                window.localStorage.setItem(i, this.session[i]);
            }
        };

        (function () {
            var workersPowerUrl = "https://cex.io/api/ghash.io/workers",
                generalPowerUrl = "https://cex.io/api/ghash.io/hashrate";

            var r = new Requester();

            req();
            setInterval(function () {
                req();
            },  $scope.session.time * 1000 || 5000);

            function req() {
                r.getPower(generalPowerUrl, "generalPower");

                if ($scope.needWorkers === true) {
                    r.getPower(workersPowerUrl, "workersPower");
                }
            }

        })();

    });<commit_msg>refractoring<commit_after>/**
 * Created by lev on 26.11.13.
 */

var app = angular.module("ghashStatusApp", ['ngTouch']);

    app.controller("dataCtrl", function ($scope, $http) {

        function loadSettings() {

            var session = {};

            for (var i in window.localStorage) {
                session[i] = window.localStorage[i] == "undefined"? "": window.localStorage[i];
            }
            return session;
        }

        $scope.session = loadSettings();

        function GenButtons(id) {

            this.buttons = [

                {"id": 0, "name": "Th", "len": 1e6},
                {"id": 1, "name": "Gh", "len": 1e3},
                {"id": 2, "name": "Mh", "len": 1e1},
                {"id": 3, "name": "Kh", "len": 1}
            ];

            this.now = this.buttons[id];
            this.len = this.now.len;
            this.now.style = 'active';
        }

        ($scope.setActive = function (button) {

            window.localStorage.setItem("measure", button.id || 0);
            $scope.measure = new GenButtons(button.id || 0);

        })({"id": window.localStorage.measure});

        $scope.round = function (data) {
            if (!data) return "No data!";
            return Math.round(data / $scope.measure.len);
        };

        function Requester() {

            var genParamObj = function () {

                var S = window.localStorage,
                    nonce = Date.now(),
                    signature = genSig();

                function genSig() {

                    var message = (nonce + S.userName + S.api_key) || "null",
                        hash = CryptoJS.HmacSHA256(message, S.api_secret || "null");

                    return CryptoJS.enc.Hex.stringify(hash).toUpperCase();
                }

                return  {
                    key: S.api_key,
                    signature: signature,
                    nonce: nonce
                };
            };

            this.getPower = function (url, model) {
                $http.post(url, genParamObj())
                    .success(function (data) {
                        $scope[model] = data;
                    });
            };
        }

        $scope.saveSettings = function () {
            for (var i in this.session) {
                window.localStorage.setItem(i, this.session[i]);
            }
        };

        (function () {
            var workersPowerUrl = "https://cex.io/api/ghash.io/workers",
                generalPowerUrl = "https://cex.io/api/ghash.io/hashrate";

            var r = new Requester();

            req();
            setInterval(function () {
                req();
            },  $scope.session.time * 1000 || 5000);

            function req() {
                r.getPower(generalPowerUrl, "generalPower");

                if ($scope.needWorkers === true) {
                    r.getPower(workersPowerUrl, "workersPower");
                }
            }

        })();

    });<|endoftext|>


<commit_before>angular.module('events', [])
    .filter('onlyFavorites', function() {
      return function(items) {
        var _items = [];
        angular.forEach(items, function(item) {
          if(_.where(item.eventos, 'favorite').length > 0) {
            _items.push(item);
          }
        });
        return _items;
      }
    })
    .factory('eventsAPI', function($q, $http, $filter) {
      var toAPIDate = function(date) {
            return Date.parse(date).toString('yyyyMMddTHHmmss')
          };
      return {
        getEvents: function(from, to) {
          var defer = $q.defer();

          $http({
            method:'get',
            url: 'backend/event/EventAPI.php',
            params: {
              from: toAPIDate(from),
              to: toAPIDate(to)
            }
          }).success(function(response) {
            var days = _.chain(response).map(function(event) {
              event.fecha = Date.parse(event.FechaHoraInicio.split('T')[0]).toString('yyyy/MM/dd');
              event.fecha_real = Date.parse(event.FechaHoraInicio.split('T')[0]);
              event.rating = 0;
              event.favorite = false; // eliminar cuando forme parte de los datos devueltos por la consulta
              return event;
            }).groupBy('fecha_real').map(function(item, key) {
              return {
                fecha: Date.parse(key),
                fecha_completa: $filter('date')(Date.parse(key), 'fullDate', 'es_AR'),
                eventos: item
              }
            }).value();
            defer.resolve(days);
          });
          return defer.promise;
        }
      };
    });
<commit_msg>Events<commit_after>angular.module('events', [])
    .filter('onlyFavorites', function() {
      return function(items) {
        var _items = [];
        angular.forEach(items, function(item) {
          if(_.where(item.eventos, 'favorite').length > 0) {
            _items.push(item);
          }
        });
        return _items;
      }
    })
    .factory('eventsAPI', function($q, $http, $filter) {
      var toAPIDate = function(date) {
            return Date.parse(date).toString('yyyyMMddTHHmmss')
          };
      return {
        getEvents: function(from, to) {
          var defer = $q.defer();

          $http({
            method:'get',
            url: 'backend/apiConnect/testData.php',
            params: {
              from: toAPIDate(from),
              to: toAPIDate(to)
            }
          }).success(function(response) {
            var days = _.chain(response).map(function(event) {
              event.fecha = Date.parse(event.FechaHoraInicio.split('T')[0]).toString('yyyy/MM/dd');
              event.fecha_real = Date.parse(event.FechaHoraInicio.split('T')[0]);
              event.rating = 0;
              event.favorite = false; // eliminar cuando forme parte de los datos devueltos por la consulta
              return event;
            }).groupBy('fecha_real').map(function(item, key) {
              return {
                fecha: Date.parse(key),
                fecha_completa: $filter('date')(Date.parse(key), 'fullDate', 'es_AR'),
                eventos: item
              }
            }).value();
            defer.resolve(days);
          });
          return defer.promise;
        }
      };
    });
<|endoftext|>


<commit_before>define(function(require) {

    describe("Test lux.grid.dataProviderWebsocket module", function() {

        var GridDataProviderWebsocket;
        var listener;
        var dataProvider;
        var websocketUrl = 'websocket://url';
        var channel = 'some channel';
        var scope = {};
        var connectSpy;
        var addListenerSpy;
        var sockJsSpy;

        beforeEach(function () {
            sockJsSpy = jasmine.createSpy();
            connectSpy = jasmine.createSpy();
            addListenerSpy = jasmine.createSpy();

            sockJsSpy.and.returnValue({
                connect: connectSpy,
                addListener: addListenerSpy
            });

            angular.mock.module('lux.grid.dataProviderWebsocket', function ($provide) {
                $provide.value('$lux', {});
            });

            inject(function (_GridDataProviderWebsocket_, $rootScope) {
                GridDataProviderWebsocket = _GridDataProviderWebsocket_;
                $rootScope.sockJs = sockJsSpy;
            });

            listener = {
                onMetadataReceived: jasmine.createSpy(),
                onDataReceived: jasmine.createSpy()
            };

            dataProvider = new GridDataProviderWebsocket(websocketUrl, channel, listener);
        });

        afterEach(function () {
        });

        it('connect() calls connectSockJs and websocketListener', function () {
            dataProvider.connect();

            expect(sockJsSpy).toHaveBeenCalledWith(websocketUrl);
            expect(addListenerSpy).toHaveBeenCalledWith(channel, jasmine.any(Function));
            expect(connectSpy).toHaveBeenCalledWith(jasmine.any(Function));
        });

        it('connect() passes record-update data from websocket response to onDataReceived', function () {
            var msg = {
                data: {
                    event: 'record-update',
                    data: 'dummy data'
                }
            };

            dataProvider.connect();

            var onMessage = addListenerSpy.calls.all()[0].args[1];

            onMessage({}, msg);

            expect(listener.onDataReceived).toHaveBeenCalledWith(jasmine.any(Object));
            var obj = listener.onDataReceived.calls.all()[0].args[0];
            expect(obj.result).toBe('dummy data');

        });

        it('connect() passes records data from websocket response to onDataReceived', function () {
            var msg = {
                data: {
                    event: 'records',
                    data: 'dummy data'
                }
            };

            dataProvider.connect();

            var onMessage = addListenerSpy.calls.all()[0].args[1];

            onMessage({}, msg);

            expect(listener.onDataReceived).toHaveBeenCalledWith(jasmine.any(Object));
            var obj = listener.onDataReceived.calls.all()[0].args[0];
            expect(obj.result).toBe('dummy data');

        });

        it('connect() passes columns-metadata data from websocket response to onMetadataReceived', function () {
            var msg = {
                data: {
                    event: 'columns-metadata',
                    data: 'dummy data'
                }
            };

            dataProvider.connect();

            var onMessage = addListenerSpy.calls.all()[0].args[1];

            onMessage({}, msg);

            expect(listener.onMetadataReceived).toHaveBeenCalledWith('dummy data');
        });

        it('destroy() disables the data provider', function () {
            dataProvider.destroy();

            expect(dataProvider.connect).toThrow();
        });

    });

    // Function.prototype.bind polyfill
    // PhantomJS has no Function.prototype.bind method
    if (!Function.prototype.bind) {
    Function.prototype.bind = function(oThis) {
        if (typeof this !== 'function') {
            // closest thing possible to the ECMAScript 5
            // internal IsCallable function
            throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
        }

        var aArgs   = Array.prototype.slice.call(arguments, 1),
            fToBind = this,
            fNOP    = function() {},
            fBound  = function() {
                return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
            };

        if (this.prototype) {
            // native functions don't have a prototype
            fNOP.prototype = this.prototype;
        }
        fBound.prototype = new fNOP();
            return fBound;
        };
    }

});<commit_msg>Tests now account for event property being moved in message from back-end<commit_after>define(function(require) {

    describe("Test lux.grid.dataProviderWebsocket module", function() {

        var GridDataProviderWebsocket;
        var listener;
        var dataProvider;
        var websocketUrl = 'websocket://url';
        var channel = 'some channel';
        var scope = {};
        var connectSpy;
        var addListenerSpy;
        var sockJsSpy;

        beforeEach(function () {
            sockJsSpy = jasmine.createSpy();
            connectSpy = jasmine.createSpy();
            addListenerSpy = jasmine.createSpy();

            sockJsSpy.and.returnValue({
                connect: connectSpy,
                addListener: addListenerSpy
            });

            angular.mock.module('lux.grid.dataProviderWebsocket', function ($provide) {
                $provide.value('$lux', {});
            });

            inject(function (_GridDataProviderWebsocket_, $rootScope) {
                GridDataProviderWebsocket = _GridDataProviderWebsocket_;
                $rootScope.sockJs = sockJsSpy;
            });

            listener = {
                onMetadataReceived: jasmine.createSpy(),
                onDataReceived: jasmine.createSpy()
            };

            dataProvider = new GridDataProviderWebsocket(websocketUrl, channel, listener);
        });

        afterEach(function () {
        });

        it('connect() calls connectSockJs and websocketListener', function () {
            dataProvider.connect();

            expect(sockJsSpy).toHaveBeenCalledWith(websocketUrl);
            expect(addListenerSpy).toHaveBeenCalledWith(channel, jasmine.any(Function));
            expect(connectSpy).toHaveBeenCalledWith(jasmine.any(Function));
        });

        it('connect() passes record-update data from websocket response to onDataReceived', function () {
            var msg = {
                event: 'record-update',
                data: {
                    data: 'dummy data'
                }
            };

            dataProvider.connect();

            var onMessage = addListenerSpy.calls.all()[0].args[1];

            onMessage({}, msg);

            expect(listener.onDataReceived).toHaveBeenCalledWith(jasmine.any(Object));
            var obj = listener.onDataReceived.calls.all()[0].args[0];
            expect(obj.result).toBe('dummy data');

        });

        it('connect() passes records data from websocket response to onDataReceived', function () {
            var msg = {
                event: 'records',
                data: {
                    data: 'dummy data'
                }
            };

            dataProvider.connect();

            var onMessage = addListenerSpy.calls.all()[0].args[1];

            onMessage({}, msg);

            expect(listener.onDataReceived).toHaveBeenCalledWith(jasmine.any(Object));
            var obj = listener.onDataReceived.calls.all()[0].args[0];
            expect(obj.result).toBe('dummy data');

        });

        it('connect() passes columns-metadata data from websocket response to onMetadataReceived', function () {
            var msg = {
                event: 'columns-metadata',
                data: {
                    data: 'dummy data'
                }
            };

            dataProvider.connect();

            var onMessage = addListenerSpy.calls.all()[0].args[1];

            onMessage({}, msg);

            expect(listener.onMetadataReceived).toHaveBeenCalledWith('dummy data');
        });

        it('destroy() disables the data provider', function () {
            dataProvider.destroy();

            expect(dataProvider.connect).toThrow();
        });

    });

    // Function.prototype.bind polyfill
    // PhantomJS has no Function.prototype.bind method
    if (!Function.prototype.bind) {
    Function.prototype.bind = function(oThis) {
        if (typeof this !== 'function') {
            // closest thing possible to the ECMAScript 5
            // internal IsCallable function
            throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
        }

        var aArgs   = Array.prototype.slice.call(arguments, 1),
            fToBind = this,
            fNOP    = function() {},
            fBound  = function() {
                return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
            };

        if (this.prototype) {
            // native functions don't have a prototype
            fNOP.prototype = this.prototype;
        }
        fBound.prototype = new fNOP();
            return fBound;
        };
    }

});<|endoftext|>


<commit_before>import {keys} from "ramda"
import {mapObjIndexed} from "ramda"
import {pick} from "ramda"
import {pipe} from "ramda"
import {prop} from "ramda"
import {merge} from "ramda"
import {map} from "ramda"
import {identity} from "ramda"
import {reject} from "ramda"

const applicate = (...argument) => (ƒunction) => ƒunction(...argument)
const coerce = (schema) => (value, key) => prop(key, schema)(value)
const coerced = (schema) => pipe(pick(keys(schema)), mapObjIndexed(coerce(schema)))
const virtualized = (virtuals) => (raw) => map((virtual) => virtual(raw), virtuals)

// {...} -> f()
export default function abstract (configuration) {
  const {name} = configuration
  const {source} = configuration || identity
  const {schema} = configuration
  const {virtuals} = configuration
  const {validations} = configuration
  const coercedFrom = coerced(schema)
  const virtualizedFrom = virtualized(virtuals)

  return (raw) => {
    const data = source(raw)
    const coercedAttributes = coercedFrom(data)
    const virtualizedAttributes = virtualizedFrom(data)
    const attributes = merge(coercedAttributes, virtualizedAttributes)
    const errors = keys(reject(applicate(attributes), validations))

    return {
      name,
      raw,
      errors,
      attributes
    }
  }
}
<commit_msg>This was the wrong way to set a default<commit_after>import {keys} from "ramda"
import {mapObjIndexed} from "ramda"
import {pick} from "ramda"
import {pipe} from "ramda"
import {prop} from "ramda"
import {merge} from "ramda"
import {map} from "ramda"
import {identity} from "ramda"
import {reject} from "ramda"

const applicate = (...argument) => (ƒunction) => ƒunction(...argument)
const coerce = (schema) => (value, key) => prop(key, schema)(value)
const coerced = (schema) => pipe(pick(keys(schema)), mapObjIndexed(coerce(schema)))
const virtualized = (virtuals) => (raw) => map((virtual) => virtual(raw), virtuals)

// {...} -> f()
export default function abstract (configuration) {
  const {name} = configuration
  const {source = identity} = configuration
  const {schema} = configuration
  const {virtuals} = configuration
  const {validations} = configuration
  const coercedFrom = coerced(schema)
  const virtualizedFrom = virtualized(virtuals)

  return (raw) => {
    const data = source(raw)
    const coercedAttributes = coercedFrom(data)
    const virtualizedAttributes = virtualizedFrom(data)
    const attributes = merge(coercedAttributes, virtualizedAttributes)
    const errors = keys(reject(applicate(attributes), validations))

    return {
      name,
      raw,
      errors,
      attributes
    }
  }
}
<|endoftext|>


<commit_before>require("should");
var PurchaseRequest = require('../../data-util/purchasing/purchase-request-data-util');
var helper = require("../../helper");
var validate = require("dl-models").validator.purchasing.purchaseRequest;

var PurchaseRequestManager = require("../../../src/managers/purchasing/purchase-request-manager");
var purchaseRequestManager = null;

before('#00. connect db', function (done) {
    helper.getDb()
        .then(db => {
            purchaseRequestManager = new PurchaseRequestManager(db, {
                username: 'dev'
            });
            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#01. should error when create with empty data ', function (done) {
    purchaseRequestManager.create({})
        .then(id => {
            done("should error when create with empty data");
        })
        .catch(e => {
            try {
                e.errors.should.have.property('date');
                e.errors.should.have.property('unit');
                e.errors.should.have.property('category');
                e.errors.should.have.property('budget');
                e.errors.should.have.property('items');
                done();
            }
            catch (ex) {
                done(ex);
            }
        });
});

var purchaseRequest;
it('#02. should success when create new data', function (done) {
    PurchaseRequest.getNewTestData()
        .then(pr => {
            purchaseRequest = pr;
            validate(purchaseRequest);
            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#02. should error when create new data using duplicate item', function (done) {
    PurchaseRequest.getNewData()
        .then(pr => {
            pr.items[1] = pr.items[0];
            purchaseRequestManager.create(pr)
                .then(id => {
                    done("should error when create with empty data");
                })
                .catch(e => {
                    try {
                        e.errors.should.have.property('items');
                        done();
                    }
                    catch (ex) {
                        done(ex);
                    }
                });
        })
        .catch(e => {
            done(e);
        });
});
<commit_msg>update unit test create<commit_after>require("should");
var PurchaseRequest = require('../../data-util/purchasing/purchase-request-data-util');
var helper = require("../../helper");
var validate = require("dl-models").validator.purchasing.purchaseRequest;

var PurchaseRequestManager = require("../../../src/managers/purchasing/purchase-request-manager");
var purchaseRequestManager = null;

before('#00. connect db', function (done) {
    helper.getDb()
        .then(db => {
            purchaseRequestManager = new PurchaseRequestManager(db, {
                username: 'dev'
            });
            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#01. should error when create with empty data ', function (done) {
    purchaseRequestManager.create({})
        .then(id => {
            done("should error when create with empty data");
        })
        .catch(e => {
            try {
                e.errors.should.have.property('date');
                e.errors.should.have.property('unit');
                e.errors.should.have.property('category');
                e.errors.should.have.property('budget');
                e.errors.should.have.property('items');
                done();
            }
            catch (ex) {
                done(ex);
            }
        });
});

var purchaseRequest;
it('#02. should success when create new data', function (done) {
    PurchaseRequest.getNewTestData()
        .then(pr => {
            purchaseRequest = pr;
            validate(purchaseRequest);
            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#02. should error when create new data using duplicate item', function (done) {
    PurchaseRequest.getNewData()
        .then(pr => {
            pr.items[1] = pr.items[0];
            var item = Object.assign({},pr.items[1]);
            delete item.product;
            pr.items.push(item);
            purchaseRequestManager.create(pr)
                .then(id => {
                    done("should error when create with empty data");
                })
                .catch(e => {
                    try {
                        e.errors.should.have.property('items');
                        done();
                    }
                    catch (ex) {
                        done(ex);
                    }
                });
        })
        .catch(e => {
            done(e);
        });
});
<|endoftext|>


<commit_before><commit_msg>Support sound files in Abecedarium Journal Chooser<commit_after><|endoftext|>


<commit_before><commit_msg>Localize Journal Chooser in EN/ES/FR<commit_after><|endoftext|>


<commit_before>odoo.define('stock.InventoryValidationController', function (require) {
"use strict";

var core = require('web.core');
var ListController = require('web.ListController');

var _t = core._t;
var qweb = core.qweb;

var InventoryValidationController = ListController.extend({
    events: _.extend({
        'click .o_button_validate_inventory': '_onValidateInventory'
    }, ListController.prototype.events),
    /**
     * @override
     */
    init: function (parent, model, renderer, params) {
        var context = renderer.state.getContext();
        this.inventory_id = context.active_id;
        return this._super.apply(this, arguments);
    },

    // -------------------------------------------------------------------------
    // Public
    // -------------------------------------------------------------------------

    /**
     * @override
     */
    renderButtons: function ($node) {
        this._super.apply(this, arguments);
        var $validationButton = $(qweb.render('InventoryLines.Buttons'));
        $validationButton.prependTo($node.find('.o_list_buttons'));
    },

    // -------------------------------------------------------------------------
    // Handlers
    // -------------------------------------------------------------------------

    /**
     * Handler called when user click on validation button in inventory lines
     * view. Makes an rpc to try to validate the inventory, then will go back on
     * the inventory view form if it was validated.
     * This method could also open a wizard in case something was missing.
     *
     * @private
     */
    _onValidateInventory: function () {
        var self = this;
        var prom = Promise.resolve();
        var recordID = this.renderer.getEditableRecordID();
        if (recordID) {
            // If user's editing a record, we wait to save it before to try to
            // validate the inventory.
            prom = this.saveRecord(recordID);
        }

        prom.then(function () {
            self._rpc({
                model: 'stock.inventory',
                method: 'action_validate',
                args: [self.inventory_id]
            }).then(function (res) {
                var exitCallback = function (infos) {
                    // In case we discarded a wizard, we do nothing to stay on
                    // the same view...
                    if (infos && infos.special) {
                        return;
                    }
                    // ... but in any other cases, we go back on the inventory form.
                    self.do_notify(
                        _t("Success"),
                        _t("The inventory has been validated"));
                    self.do_action({
                        type: 'ir.actions.act_window',
                        res_model: 'stock.inventory',
                        res_id: self.inventory_id,
                        views: [[false, 'form']],
                        target: 'main'
                    });
                };

                if (_.isObject(res)) {
                    self.do_action(res, { on_close: exitCallback });
                } else {
                    return exitCallback();
                }
            });
        });
    },
});

return InventoryValidationController;

});
<commit_msg>[FIX] stock: throw back at inventory validation<commit_after>odoo.define('stock.InventoryValidationController', function (require) {
"use strict";

var core = require('web.core');
var ListController = require('web.ListController');

var _t = core._t;
var qweb = core.qweb;

var InventoryValidationController = ListController.extend({
    events: _.extend({
        'click .o_button_validate_inventory': '_onValidateInventory'
    }, ListController.prototype.events),
    /**
     * @override
     */
    init: function (parent, model, renderer, params) {
        var context = renderer.state.getContext();
        this.inventory_id = context.active_id;
        return this._super.apply(this, arguments);
    },

    // -------------------------------------------------------------------------
    // Public
    // -------------------------------------------------------------------------

    /**
     * @override
     */
    renderButtons: function ($node) {
        this._super.apply(this, arguments);
        var $validationButton = $(qweb.render('InventoryLines.Buttons'));
        $validationButton.prependTo($node.find('.o_list_buttons'));
    },

    // -------------------------------------------------------------------------
    // Handlers
    // -------------------------------------------------------------------------

    /**
     * Handler called when user click on validation button in inventory lines
     * view. Makes an rpc to try to validate the inventory, then will go back on
     * the inventory view form if it was validated.
     * This method could also open a wizard in case something was missing.
     *
     * @private
     */
    _onValidateInventory: function () {
        var self = this;
        var prom = Promise.resolve();
        var recordID = this.renderer.getEditableRecordID();
        if (recordID) {
            // If user's editing a record, we wait to save it before to try to
            // validate the inventory.
            prom = this.saveRecord(recordID);
        }

        prom.then(function () {
            self._rpc({
                model: 'stock.inventory',
                method: 'action_validate',
                args: [self.inventory_id]
            }).then(function (res) {
                var exitCallback = function (infos) {
                    // In case we discarded a wizard, we do nothing to stay on
                    // the same view...
                    if (infos && infos.special) {
                        return;
                    }
                    // ... but in any other cases, we go back on the inventory form.
                    self.do_notify(
                        _t("Success"),
                        _t("The inventory has been validated"));
                    self.trigger_up('history_back');
                };

                if (_.isObject(res)) {
                    self.do_action(res, { on_close: exitCallback });
                } else {
                    return exitCallback();
                }
            });
        });
    },
});

return InventoryValidationController;

});
<|endoftext|>


<commit_before>describe("Gerstner.WeightedRandom", function() {

  var r;

  beforeEach(function() {
    r = new Gerstner.WeightedRandom();
  });

  it("should add, sort elements, and add to total weight", function()
  {
    r.add("Zach", 1);
    r.add("Steve", 3);
    r.add("Rune", 2);

    expect(r.totalWeight).toBe(6);
    expect(r.elements[0].value).toEqual("Steve");
    expect(r.elements[1].value).toEqual("Rune");
    expect(r.elements[2].value).toEqual("Zach");
  });

  it("should give back a random value back", function()
  {
    r.add("Zach", 1);
    r.add("Steve", 3);
    r.add("Rune", 2);

    expect(["Zach", "Steve", "Rune"]).toContain(r.random());
  });

});
<commit_msg>weighted random working<commit_after>describe("Gerstner.WeightedRandom", function() {

  var r;

  beforeEach(function() {
    r = new Gerstner.WeightedRandom();
  });

  it("should add, sort elements, and add to total weight", function()
  {
    r.add("Zach", 1);
    r.add("Steve", 3);
    r.add("Rune", 2);

    expect(r.totalWeight).toBe(6);
    expect(r.elements[0].value).toEqual("Steve");
    expect(r.elements[1].value).toEqual("Rune");
    expect(r.elements[2].value).toEqual("Zach");
  });

  it("should give back a random value back", function()
  {
    r.add("Zach", 1);
    r.add("Steve", 3);
    r.add("Rune", 2);

    expect(["Zach", "Steve", "Rune"]).toContain(r.random());
  });

  it("should pick correct values", function() {
    r.add("Zach", 1);
    r.add("Steve", 10);

    var results = [];
    results["Zach"] = 0;
    results["Steve"] = 0;

    _.times(5000, function() {
      var ran = r.random();
      results[ran] += 1;
    });

    var ratio = Math.round(results["Steve"] / results["Zach"]);
    expect(ratio).toBeLessThan(12);
    expect(ratio).toBeGreaterThan(8);
  });

});
<|endoftext|>


<commit_before>/*!
 * viewport-units-buggyfill v0.4.0
 * @web: https://github.com/rodneyrehm/viewport-units-buggyfill/
 * @author: Rodney Rehm - http://rodneyrehm.de/en/
 */

(function (root, factory) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like enviroments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.viewportUnitsBuggyfill = factory();
  }
}(this, function () {
  'use strict';
  /*global document, window, location, XMLHttpRequest, XDomainRequest*/

  var initialized = false;
  var options;
  var isMobileSafari = /(iPhone|iPod|iPad).+AppleWebKit/i.test(window.navigator.userAgent);
  var viewportUnitExpression = /([+-]?[0-9.]+)(vh|vw|vmin|vmax)/g;
  var forEach = [].forEach;
  var dimensions;
  var declarations;
  var styleNode;
  var isOldInternetExplorer = false;

  // Do not remove the following comment!
  // It is a conditional comment used to
  // identify old Internet Explorer versions

  /*@cc_on

  @if (@_jscript_version <= 10)
    isOldInternetExplorer = true;
  @end

  @*/

  function debounce(func, wait) {
    var timeout;
    return function() {
      var context = this;
      var args = arguments;
      var callback = function() {
        func.apply(context, args);
      };

      clearTimeout(timeout);
      timeout = setTimeout(callback, wait);
    };
  }

  // from http://stackoverflow.com/questions/326069/how-to-identify-if-a-webpage-is-being-loaded-inside-an-iframe-or-directly-into-t
  function inIframe() {
    try {
      return window.self !== window.top;
    } catch (e) {
      return true;
    }
  }

  function initialize(initOptions) {
    if (initialized) {
      return;
    }

    if (initOptions === true) {
      initOptions = {
        force: true
      };
    }

    options = initOptions || {};
    options.isMobileSafari = isMobileSafari;

    if (!options.force && !isMobileSafari && !isOldInternetExplorer && (!options.hacks || !options.hacks.required(options))) {
      // this buggyfill only applies to mobile safari
      return;
    }

    options.hacks && options.hacks.initialize(options);

    initialized = true;
    styleNode = document.createElement('style');
    styleNode.id = 'patched-viewport';
    document.head.appendChild(styleNode);

    // Issue #6: Cross Origin Stylesheets are not accessible through CSSOM,
    // therefore download and inject them as <style> to circumvent SOP.
    importCrossOriginLinks(function() {
      var _refresh = debounce(refresh, options.refreshDebounceWait || 100);
      // doing a full refresh rather than updateStyles because an orientationchange
      // could activate different stylesheets
      window.addEventListener('orientationchange', _refresh, true);
      // orientationchange might have happened while in a different window
      window.addEventListener('pageshow', _refresh, true);

      if (options.force || isOldInternetExplorer || inIframe()) {
        window.addEventListener('resize', _refresh, true);
        options._listeningToResize = true;
      }

      options.hacks && options.hacks.initializeEvents(options, refresh, _refresh);

      refresh();
    });
  }

  function updateStyles() {
    styleNode.textContent = getReplacedViewportUnits();
  }

  function refresh() {
    if (!initialized) {
      return;
    }

    findProperties();

    // iOS Safari will report window.innerWidth and .innerHeight as 0
    // unless a timeout is used here.
    // TODO: figure out WHY innerWidth === 0
    setTimeout(function() {
      updateStyles();
    }, 1);
  }

  function findProperties() {
    declarations = [];
    forEach.call(document.styleSheets, function(sheet) {
      if (sheet.ownerNode.id === 'patched-viewport' || !sheet.cssRules) {
        // skip entire sheet because no rules ara present or it's the target-element of the buggyfill
        return;
      }

      if (sheet.media && sheet.media.mediaText && window.matchMedia && !window.matchMedia(sheet.media.mediaText).matches) {
        // skip entire sheet because media attribute doesn't match
        return;
      }

      forEach.call(sheet.cssRules, findDeclarations);
    });

    return declarations;
  }

  function findDeclarations(rule) {
    if (rule.type === 7) {
      var value = rule.cssText;
      viewportUnitExpression.lastIndex = 0;
      if (viewportUnitExpression.test(value)) {
        // KeyframesRule does not have a CSS-PropertyName
        declarations.push([rule, null, value]);
        options.hacks && options.hacks.findDeclarations(declarations, rule, null, value);
      }

      return;
    }

    if (!rule.style) {
      if (!rule.cssRules) {
        return;
      }

      forEach.call(rule.cssRules, function(_rule) {
        findDeclarations(_rule);
      });

      return;
    }

    forEach.call(rule.style, function(name) {
      var value = rule.style.getPropertyValue(name);
      viewportUnitExpression.lastIndex = 0;
      if (viewportUnitExpression.test(value)) {
        declarations.push([rule, name, value]);
        options.hacks && options.hacks.findDeclarations(declarations, rule, name, value);
      }
    });
  }

  function getReplacedViewportUnits() {
    dimensions = getViewport();

    var css = [];
    var buffer = [];
    var open;
    var close;

    declarations.forEach(function(item) {
      var _item = overwriteDeclaration.apply(null, item);
      var _open = _item.selector.length ? (_item.selector.join(' {\n') + ' {\n') : '';
      var _close = new Array(_item.selector.length + 1).join('\n}');

      if (!_open || _open !== open) {
        if (buffer.length) {
          css.push(open + buffer.join('\n') + close);
          buffer.length = 0;
        }

        if (_open) {
          open = _open;
          close = _close;
          buffer.push(_item.content);
        } else {
          css.push(_item.content);
          open = null;
          close = null;
        }

        return;
      }

      if (_open && !open) {
        open = _open;
        close = _close;
      }

      buffer.push(_item.content);
    });

    if (buffer.length) {
      css.push(open + buffer.join('\n') + close);
    }

    return css.join('\n\n');
  }

  function overwriteDeclaration(rule, name, value) {
    var _value = value.replace(viewportUnitExpression, replaceValues);
    var  _selectors = [];

    if (options.hacks) {
      _value = options.hacks.overwriteDeclaration(rule, name, _value);
    }

    if (name) {
      // skipping KeyframesRule
      _selectors.push(rule.selectorText);
      _value = name + ': ' + _value + ';';
    }

    var _rule = rule.parentRule;
    while (_rule) {
      _selectors.unshift('@media ' + _rule.media.mediaText);
      _rule = _rule.parentRule;
    }

    return {
      selector: _selectors,
      content: _value
    };
  }

  function replaceValues(match, number, unit) {
    var _base = dimensions[unit];
    var _number = parseFloat(number) / 100;
    return (_number * _base) + 'px';
  }

  function getViewport() {
    var vh = window.innerHeight;
    var vw = window.innerWidth;

    return {
      vh: vh,
      vw: vw,
      vmax: Math.max(vw, vh),
      vmin: Math.min(vw, vh)
    };
  }

  function importCrossOriginLinks(next) {
    var _waiting = 0;
    var decrease = function() {
      _waiting--;
      if (!_waiting) {
        next();
      }
    };

    forEach.call(document.styleSheets, function(sheet) {
      if (!sheet.href || origin(sheet.href) === origin(location.href)) {
        // skip <style> and <link> from same origin
        return;
      }

      _waiting++;
      convertLinkToStyle(sheet.ownerNode, decrease);
    });

    if (!_waiting) {
      next();
    }
  }

  function origin(url) {
    return url.slice(0, url.indexOf('/', url.indexOf('://') + 3));
  }

  function convertLinkToStyle(link, next) {
    getCors(link.href, function() {
      var style = document.createElement('style');
      style.media = link.media;
      style.setAttribute('data-href', link.href);
      style.textContent = this.responseText;
      link.parentNode.replaceChild(style, link);
      next();
    }, next);
  }

  function getCors(url, success, error) {
    var xhr = new XMLHttpRequest();
    if ('withCredentials' in xhr) {
      // XHR for Chrome/Firefox/Opera/Safari.
      xhr.open('GET', url, true);
    } else if (typeof XDomainRequest !== 'undefined') {
      // XDomainRequest for IE.
      xhr = new XDomainRequest();
      xhr.open('GET', url);
    } else {
      throw new Error('cross-domain XHR not supported');
    }

    xhr.onload = success;
    xhr.onerror = error;
    xhr.send();
    return xhr;
  }

  return {
    version: '0.3.1',
    findProperties: findProperties,
    getCss: getReplacedViewportUnits,
    init: initialize,
    refresh: refresh
  };

}));
<commit_msg>fixing version<commit_after>/*!
 * viewport-units-buggyfill v0.4.0
 * @web: https://github.com/rodneyrehm/viewport-units-buggyfill/
 * @author: Rodney Rehm - http://rodneyrehm.de/en/
 */

(function (root, factory) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like enviroments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.viewportUnitsBuggyfill = factory();
  }
}(this, function () {
  'use strict';
  /*global document, window, location, XMLHttpRequest, XDomainRequest*/

  var initialized = false;
  var options;
  var isMobileSafari = /(iPhone|iPod|iPad).+AppleWebKit/i.test(window.navigator.userAgent);
  var viewportUnitExpression = /([+-]?[0-9.]+)(vh|vw|vmin|vmax)/g;
  var forEach = [].forEach;
  var dimensions;
  var declarations;
  var styleNode;
  var isOldInternetExplorer = false;

  // Do not remove the following comment!
  // It is a conditional comment used to
  // identify old Internet Explorer versions

  /*@cc_on

  @if (@_jscript_version <= 10)
    isOldInternetExplorer = true;
  @end

  @*/

  function debounce(func, wait) {
    var timeout;
    return function() {
      var context = this;
      var args = arguments;
      var callback = function() {
        func.apply(context, args);
      };

      clearTimeout(timeout);
      timeout = setTimeout(callback, wait);
    };
  }

  // from http://stackoverflow.com/questions/326069/how-to-identify-if-a-webpage-is-being-loaded-inside-an-iframe-or-directly-into-t
  function inIframe() {
    try {
      return window.self !== window.top;
    } catch (e) {
      return true;
    }
  }

  function initialize(initOptions) {
    if (initialized) {
      return;
    }

    if (initOptions === true) {
      initOptions = {
        force: true
      };
    }

    options = initOptions || {};
    options.isMobileSafari = isMobileSafari;

    if (!options.force && !isMobileSafari && !isOldInternetExplorer && (!options.hacks || !options.hacks.required(options))) {
      // this buggyfill only applies to mobile safari
      return;
    }

    options.hacks && options.hacks.initialize(options);

    initialized = true;
    styleNode = document.createElement('style');
    styleNode.id = 'patched-viewport';
    document.head.appendChild(styleNode);

    // Issue #6: Cross Origin Stylesheets are not accessible through CSSOM,
    // therefore download and inject them as <style> to circumvent SOP.
    importCrossOriginLinks(function() {
      var _refresh = debounce(refresh, options.refreshDebounceWait || 100);
      // doing a full refresh rather than updateStyles because an orientationchange
      // could activate different stylesheets
      window.addEventListener('orientationchange', _refresh, true);
      // orientationchange might have happened while in a different window
      window.addEventListener('pageshow', _refresh, true);

      if (options.force || isOldInternetExplorer || inIframe()) {
        window.addEventListener('resize', _refresh, true);
        options._listeningToResize = true;
      }

      options.hacks && options.hacks.initializeEvents(options, refresh, _refresh);

      refresh();
    });
  }

  function updateStyles() {
    styleNode.textContent = getReplacedViewportUnits();
  }

  function refresh() {
    if (!initialized) {
      return;
    }

    findProperties();

    // iOS Safari will report window.innerWidth and .innerHeight as 0
    // unless a timeout is used here.
    // TODO: figure out WHY innerWidth === 0
    setTimeout(function() {
      updateStyles();
    }, 1);
  }

  function findProperties() {
    declarations = [];
    forEach.call(document.styleSheets, function(sheet) {
      if (sheet.ownerNode.id === 'patched-viewport' || !sheet.cssRules) {
        // skip entire sheet because no rules ara present or it's the target-element of the buggyfill
        return;
      }

      if (sheet.media && sheet.media.mediaText && window.matchMedia && !window.matchMedia(sheet.media.mediaText).matches) {
        // skip entire sheet because media attribute doesn't match
        return;
      }

      forEach.call(sheet.cssRules, findDeclarations);
    });

    return declarations;
  }

  function findDeclarations(rule) {
    if (rule.type === 7) {
      var value = rule.cssText;
      viewportUnitExpression.lastIndex = 0;
      if (viewportUnitExpression.test(value)) {
        // KeyframesRule does not have a CSS-PropertyName
        declarations.push([rule, null, value]);
        options.hacks && options.hacks.findDeclarations(declarations, rule, null, value);
      }

      return;
    }

    if (!rule.style) {
      if (!rule.cssRules) {
        return;
      }

      forEach.call(rule.cssRules, function(_rule) {
        findDeclarations(_rule);
      });

      return;
    }

    forEach.call(rule.style, function(name) {
      var value = rule.style.getPropertyValue(name);
      viewportUnitExpression.lastIndex = 0;
      if (viewportUnitExpression.test(value)) {
        declarations.push([rule, name, value]);
        options.hacks && options.hacks.findDeclarations(declarations, rule, name, value);
      }
    });
  }

  function getReplacedViewportUnits() {
    dimensions = getViewport();

    var css = [];
    var buffer = [];
    var open;
    var close;

    declarations.forEach(function(item) {
      var _item = overwriteDeclaration.apply(null, item);
      var _open = _item.selector.length ? (_item.selector.join(' {\n') + ' {\n') : '';
      var _close = new Array(_item.selector.length + 1).join('\n}');

      if (!_open || _open !== open) {
        if (buffer.length) {
          css.push(open + buffer.join('\n') + close);
          buffer.length = 0;
        }

        if (_open) {
          open = _open;
          close = _close;
          buffer.push(_item.content);
        } else {
          css.push(_item.content);
          open = null;
          close = null;
        }

        return;
      }

      if (_open && !open) {
        open = _open;
        close = _close;
      }

      buffer.push(_item.content);
    });

    if (buffer.length) {
      css.push(open + buffer.join('\n') + close);
    }

    return css.join('\n\n');
  }

  function overwriteDeclaration(rule, name, value) {
    var _value = value.replace(viewportUnitExpression, replaceValues);
    var  _selectors = [];

    if (options.hacks) {
      _value = options.hacks.overwriteDeclaration(rule, name, _value);
    }

    if (name) {
      // skipping KeyframesRule
      _selectors.push(rule.selectorText);
      _value = name + ': ' + _value + ';';
    }

    var _rule = rule.parentRule;
    while (_rule) {
      _selectors.unshift('@media ' + _rule.media.mediaText);
      _rule = _rule.parentRule;
    }

    return {
      selector: _selectors,
      content: _value
    };
  }

  function replaceValues(match, number, unit) {
    var _base = dimensions[unit];
    var _number = parseFloat(number) / 100;
    return (_number * _base) + 'px';
  }

  function getViewport() {
    var vh = window.innerHeight;
    var vw = window.innerWidth;

    return {
      vh: vh,
      vw: vw,
      vmax: Math.max(vw, vh),
      vmin: Math.min(vw, vh)
    };
  }

  function importCrossOriginLinks(next) {
    var _waiting = 0;
    var decrease = function() {
      _waiting--;
      if (!_waiting) {
        next();
      }
    };

    forEach.call(document.styleSheets, function(sheet) {
      if (!sheet.href || origin(sheet.href) === origin(location.href)) {
        // skip <style> and <link> from same origin
        return;
      }

      _waiting++;
      convertLinkToStyle(sheet.ownerNode, decrease);
    });

    if (!_waiting) {
      next();
    }
  }

  function origin(url) {
    return url.slice(0, url.indexOf('/', url.indexOf('://') + 3));
  }

  function convertLinkToStyle(link, next) {
    getCors(link.href, function() {
      var style = document.createElement('style');
      style.media = link.media;
      style.setAttribute('data-href', link.href);
      style.textContent = this.responseText;
      link.parentNode.replaceChild(style, link);
      next();
    }, next);
  }

  function getCors(url, success, error) {
    var xhr = new XMLHttpRequest();
    if ('withCredentials' in xhr) {
      // XHR for Chrome/Firefox/Opera/Safari.
      xhr.open('GET', url, true);
    } else if (typeof XDomainRequest !== 'undefined') {
      // XDomainRequest for IE.
      xhr = new XDomainRequest();
      xhr.open('GET', url);
    } else {
      throw new Error('cross-domain XHR not supported');
    }

    xhr.onload = success;
    xhr.onerror = error;
    xhr.send();
    return xhr;
  }

  return {
    version: '0.4.0',
    findProperties: findProperties,
    getCss: getReplacedViewportUnits,
    init: initialize,
    refresh: refresh
  };

}));
<|endoftext|>


<commit_before>var fs = require('fs'),
    path = require('path'),
    fsExtra = require('fs-extra'),
    Q = require('Q'),
    Config = require('../../../lib/config'),
    Model = require('../../../lib/model/model'),
    DocsLoadFile = require('../../../lib/tasks-docs/load-from-file');

describe('DocsLoadFile', function() {
    var sandbox = sinon.sandbox.create(),
        config = new Config('debug'),
        task = new DocsLoadFile(config, {}),
        model;

    beforeEach(function() {
        sandbox.stub(fsExtra);
        sandbox.stub(task, 'readFileFromCache');
        sandbox.stub(task, 'writeFileToCache');
        model = new Model();
    });

    afterEach(function() {
        sandbox.restore();
    });

    it('should return valid task name', function() {
        DocsLoadFile.getName().should.equal('docs load from file');
    });

    describe('getCriteria', function() {
        it('should return false on missed language version of page', function() {
            var page = {url: '/url1'};
            task.getCriteria(page, 'en').should.equal(false);
        });

        it('should return false on missed contentFile field for lang version of page', function() {
            var page = {url: '/url1', en: {}};
            task.getCriteria(page, 'en').should.equal(false);
        });

        it('should return false if contentFile value does not match regular expression', function() {
            var page = {
                url: '/url1',
                en: {sourceUrl: 'http://github.com/foo/bar'}
            };
            task.getCriteria(page, 'en').should.equal(false);
        });

        describe('file path matches on task criteria', function() {
            it('should match on file path like a "/foo/bar.file"', function() {
                var page = {url: '/url', en: {sourceUrl: '/foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });

            it('should match on file path like a "./foo/bar.md"', function() {
                var page = {url: '/url', en: {sourceUrl: './foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });

            it('should match on file path like a "../foo/bar.md"', function() {
                var page = {url: '/url', en: {sourceUrl: '../foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });

            it('should match on file path like a "../../foo/bar.md"', function() {
                var page = {url: '/url', en: {sourceUrl: '../../foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });
        });
    });

    describe('processPage', function() {
        var languages = ['en'],
            page;

        beforeEach(function() {
            sandbox.stub(fs, 'readFile').yields(null, 'Hello World');
            task.readFileFromCache.returns(Q('Hello World'));
            task.writeFileToCache.returns(Q());
            page = {url: '/url', en: {sourceUrl: '../foo.file'}};
        });

        it('should not load mismatching source file for page language version', function() {
            page = {url: '/url1', en: {sourceFile: 'http://url'}};
            return task.processPage(model, page, languages).then(function() {
                fs.readFile.should.not.be.called;
                task.readFileFromCache.should.not.be.called;
            });
        });

        it('should read file from cache from given file path', function() {
            return task.processPage(model, page, languages).then(function() {
                task.readFileFromCache.should.be
                    .calledWithMatch(path.join(page.url, 'en.file'));
            });
        });

        it('should read file from local filesystem', function() {
            return task.processPage(model, page, languages).then(function() {
                fs.readFile.should.be.calledWithMatch('foo.file');
            });
        });

        it('should reject operation in case of missed local file', function() {
            fs.readFile.yields(new Error('ENOENT'));
            return task.processPage(model, page, languages).then(function() {
                task.writeFileToCache.should.not.be.called;
                should.not.exist(page.en.contentFile);
            });
        });

        it('should process file as new if it was not file in cache', function() {
            task.readFileFromCache.returns(Q.reject('Error'));
            return task.processPage(model, page, languages).then(function() {
                model.getChanges().pages.added.should.have.length(1);
            });
        });

        it('should process file as modified if it is not same as in cache', function() {
            task.readFileFromCache.returns(Q('Hello World old'));
            return task.processPage(model, page, languages).then(function() {
                model.getChanges().pages.modified.should.have.length(1);
            });
        });

        it('should not to do anything if file was not changed', function() {
            return task.processPage(model, page, languages).then(function() {
                var changes = model.getChanges().pages;
                changes.added.should.be.empty;
                changes.modified.should.be.empty;
            });
        });

        it('should set valid value of "contentFile" field', function() {
            return task.processPage(model, page, languages).then(function() {
                page.en.contentFile.should.equal('/url/en.file');
            });
        });

        it('should be resolved with page model instance', function() {
            task.processPage(model, page, languages).should.eventually.be.eql(page);
        });
    });
});
<commit_msg>Fix issue with invalid requirement of q library<commit_after>var fs = require('fs'),
    path = require('path'),
    fsExtra = require('fs-extra'),
    Q = require('q'),
    Config = require('../../../lib/config'),
    Model = require('../../../lib/model/model'),
    DocsLoadFile = require('../../../lib/tasks-docs/load-from-file');

describe('DocsLoadFile', function() {
    var sandbox = sinon.sandbox.create(),
        config = new Config('debug'),
        task = new DocsLoadFile(config, {}),
        model;

    beforeEach(function() {
        sandbox.stub(fsExtra);
        sandbox.stub(task, 'readFileFromCache');
        sandbox.stub(task, 'writeFileToCache');
        model = new Model();
    });

    afterEach(function() {
        sandbox.restore();
    });

    it('should return valid task name', function() {
        DocsLoadFile.getName().should.equal('docs load from file');
    });

    describe('getCriteria', function() {
        it('should return false on missed language version of page', function() {
            var page = {url: '/url1'};
            task.getCriteria(page, 'en').should.equal(false);
        });

        it('should return false on missed contentFile field for lang version of page', function() {
            var page = {url: '/url1', en: {}};
            task.getCriteria(page, 'en').should.equal(false);
        });

        it('should return false if contentFile value does not match regular expression', function() {
            var page = {
                url: '/url1',
                en: {sourceUrl: 'http://github.com/foo/bar'}
            };
            task.getCriteria(page, 'en').should.equal(false);
        });

        describe('file path matches on task criteria', function() {
            it('should match on file path like a "/foo/bar.file"', function() {
                var page = {url: '/url', en: {sourceUrl: '/foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });

            it('should match on file path like a "./foo/bar.md"', function() {
                var page = {url: '/url', en: {sourceUrl: './foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });

            it('should match on file path like a "../foo/bar.md"', function() {
                var page = {url: '/url', en: {sourceUrl: '../foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });

            it('should match on file path like a "../../foo/bar.md"', function() {
                var page = {url: '/url', en: {sourceUrl: '../../foo/bar.md'}};
                task.getCriteria(page, 'en').should.equal(true);
            });
        });
    });

    describe('processPage', function() {
        var languages = ['en'],
            page;

        beforeEach(function() {
            sandbox.stub(fs, 'readFile').yields(null, 'Hello World');
            task.readFileFromCache.returns(Q('Hello World'));
            task.writeFileToCache.returns(Q());
            page = {url: '/url', en: {sourceUrl: '../foo.file'}};
        });

        it('should not load mismatching source file for page language version', function() {
            page = {url: '/url1', en: {sourceFile: 'http://url'}};
            return task.processPage(model, page, languages).then(function() {
                fs.readFile.should.not.be.called;
                task.readFileFromCache.should.not.be.called;
            });
        });

        it('should read file from cache from given file path', function() {
            return task.processPage(model, page, languages).then(function() {
                task.readFileFromCache.should.be
                    .calledWithMatch(path.join(page.url, 'en.file'));
            });
        });

        it('should read file from local filesystem', function() {
            return task.processPage(model, page, languages).then(function() {
                fs.readFile.should.be.calledWithMatch('foo.file');
            });
        });

        it('should reject operation in case of missed local file', function() {
            fs.readFile.yields(new Error('ENOENT'));
            return task.processPage(model, page, languages).then(function() {
                task.writeFileToCache.should.not.be.called;
                should.not.exist(page.en.contentFile);
            });
        });

        it('should process file as new if it was not file in cache', function() {
            task.readFileFromCache.returns(Q.reject('Error'));
            return task.processPage(model, page, languages).then(function() {
                model.getChanges().pages.added.should.have.length(1);
            });
        });

        it('should process file as modified if it is not same as in cache', function() {
            task.readFileFromCache.returns(Q('Hello World old'));
            return task.processPage(model, page, languages).then(function() {
                model.getChanges().pages.modified.should.have.length(1);
            });
        });

        it('should not to do anything if file was not changed', function() {
            return task.processPage(model, page, languages).then(function() {
                var changes = model.getChanges().pages;
                changes.added.should.be.empty;
                changes.modified.should.be.empty;
            });
        });

        it('should set valid value of "contentFile" field', function() {
            return task.processPage(model, page, languages).then(function() {
                page.en.contentFile.should.equal('/url/en.file');
            });
        });

        it('should be resolved with page model instance', function() {
            task.processPage(model, page, languages).should.eventually.be.eql(page);
        });
    });
});
<|endoftext|>