<commit_before>import React from 'react';
import NavigationPanel from './NavigationPanel/NavigationPanel';
import TranslationPanel from './TranslationPanel/TranslationPanel';
import TreePanel from './TreePanel/TreePanel';
import ContentPanel from './ContentPanel/ContentPanel';
import ContributorsPanel from './ContributorsPanel/ContributorsPanel';
import DataSourcePanel from './DataSourcePanel/DataSourcePanel';
import ActivityFeedPanel from './ActivityFeedPanel/ActivityFeedPanel';

class Deck extends React.Component {
    render() {
        return (

                  <NavigationPanel />

                  <TranslationPanel />

                  <TreePanel />

                    <ContentPanel />

                      <ActivityFeedPanel />

                        <ContributorsPanel />

                        <DataSourcePanel />

        );
    }
}

export default Deck;
<commit_msg>changed to two-column layout as suggested by Abi<commit_after>import React from 'react';
import NavigationPanel from './NavigationPanel/NavigationPanel';
import TranslationPanel from './TranslationPanel/TranslationPanel';
import TreePanel from './TreePanel/TreePanel';
import ContentPanel from './ContentPanel/ContentPanel';
import ContributorsPanel from './ContributorsPanel/ContributorsPanel';
import DataSourcePanel from './DataSourcePanel/DataSourcePanel';
import ActivityFeedPanel from './ActivityFeedPanel/ActivityFeedPanel';

class Deck extends React.Component {
    render() {
        return (

                    <TranslationPanel />

                  <NavigationPanel />

                        <TreePanel />

                        <ContributorsPanel />

                        <DataSourcePanel />

                    <ContentPanel />

                      <ActivityFeedPanel />

        );
    }
}

export default Deck;
<|endoftext|>


<commit_before>import React from 'react';
import Relay from 'react-relay';
import classNames from 'classnames';

import Emojify from '../../shared/Emojify';
import Panel from '../../shared/Panel';
import Spinner from '../../shared/Spinner';
import RevealButton from '../../shared/RevealButton';

import 'highlight.js/styles/github.css';

// Grab all the guide documents (*.mdx) from the file system (at ../../docs)
const GUIDES = ((guideRequire) =>
  guideRequire.keys().map((guidePath) =>
    guideRequire(guidePath).default
  )
)(require.context('../../docs', true, /\.mdx$/));

class QuickStart extends React.Component {
  static propTypes = {
    organization: React.PropTypes.shape({
      agentTokens: React.PropTypes.shape({
        edges: React.PropTypes.array.isRequired
      })
    }).isRequired,
    relay: React.PropTypes.object.isRequired
  };

  state = {
    selectedGuide: null
  };

  componentDidMount() {
    this.props.relay.setVariables({ isMounted: true });
  }

  handleSelectedGuideChange(selectedGuide, evt) {
    evt.preventDefault();
    const newState = { selectedGuide: null };

    if (selectedGuide !== this.state.selectedGuide) {
      newState.selectedGuide = selectedGuide;
    }

    this.setState(newState);
  }

  renderGuideButtons() {
    return (

        {
          GUIDES.map((Guide, index) => (

              <Emojify className="block mt1" text={Guide.emoji} />
              {Guide.title}

          ))
        }

    );
  }

  renderGuide() {
    const GuideToRender = GUIDES[this.state.selectedGuide];

    if (GuideToRender) {
      return (
        <GuideToRender
          className="border border-gray mt3"
          style={{
            borderLeft: 'none',
            borderRight: 'none',
            borderBottom: 'none'
          }}
          elementProps={{
            a: {
              className: 'blue hover-navy text-decoration-none hover-underline'
            },
            pre: {
              className: 'border border-gray rounded bg-silver overflow-auto p2 monospace'
            }
          }}
          token={this.props.organization.agentTokens.edges[0].node.token}
        />
      );
    }
  }

  render() {
    return (
      <Panel className="mb3">
        <Panel.Header>Agent Quick Start Guides</Panel.Header>
        <Panel.Section>
          {this.renderGuideButtons()}
          {this.renderGuide()}
        </Panel.Section>
      </Panel>
    );
  }
}

export default Relay.createContainer(QuickStart, {
  initialVariables: {
    isMounted: false
  },

  fragments: {
    organization: () => Relay.QL`
      fragment on Organization {
        agentTokens(first: 1, revoked: false) @include(if: $isMounted) {
          edges {
            node {
              id
              description
              token
            }
          }
        }
      }
    `
  }
});
<commit_msg>Update padding and layout of quickstart guides<commit_after>import React from 'react';
import Relay from 'react-relay';
import classNames from 'classnames';

import Emojify from '../../shared/Emojify';
import Panel from '../../shared/Panel';
import Spinner from '../../shared/Spinner';
import RevealButton from '../../shared/RevealButton';

import 'highlight.js/styles/github.css';

// Grab all the guide documents (*.mdx) from the file system (at ../../docs)
const GUIDES = ((guideRequire) =>
  guideRequire.keys().map((guidePath) =>
    guideRequire(guidePath).default
  )
)(require.context('../../docs', true, /\.mdx$/));

class QuickStart extends React.Component {
  static propTypes = {
    organization: React.PropTypes.shape({
      agentTokens: React.PropTypes.shape({
        edges: React.PropTypes.array.isRequired
      })
    }).isRequired,
    relay: React.PropTypes.object.isRequired
  };

  state = {
    selectedGuide: null
  };

  componentDidMount() {
    this.props.relay.setVariables({ isMounted: true });
  }

  handleSelectedGuideChange(selectedGuide, evt) {
    evt.preventDefault();
    const newState = { selectedGuide: null };

    if (selectedGuide !== this.state.selectedGuide) {
      newState.selectedGuide = selectedGuide;
    }

    this.setState(newState);
  }

  renderGuideButtons() {
    return (

        {
          GUIDES.map((Guide, index) => (

              <Emojify className="block mt1" style={{ fontSize: '1.15em' }} text={Guide.emoji} />
              {Guide.title}

          ))
        }

    );
  }

  renderGuide() {
    const GuideToRender = GUIDES[this.state.selectedGuide];

    if (GuideToRender) {
      return (
        <GuideToRender
          className="border border-gray mt3"
          style={{
            borderLeft: 'none',
            borderRight: 'none',
            borderBottom: 'none'
          }}
          elementProps={{
            a: {
              className: 'blue hover-navy text-decoration-none hover-underline'
            },
            pre: {
              className: 'border border-gray rounded bg-silver overflow-auto p2 monospace'
            }
          }}
          token={this.props.organization.agentTokens.edges[0].node.token}
        />
      );
    }
  }

  render() {
    return (
      <Panel className="mb3">
        <Panel.Header>Agent Quick Start Guides</Panel.Header>
        <Panel.Section>
          {this.renderGuideButtons()}
          {this.renderGuide()}
        </Panel.Section>
      </Panel>
    );
  }
}

export default Relay.createContainer(QuickStart, {
  initialVariables: {
    isMounted: false
  },

  fragments: {
    organization: () => Relay.QL`
      fragment on Organization {
        agentTokens(first: 1, revoked: false) @include(if: $isMounted) {
          edges {
            node {
              id
              description
              token
            }
          }
        }
      }
    `
  }
});
<|endoftext|>


<commit_before>define([
  'summernote/base/core/agent',
  'summernote/base/core/dom',
  'summernote/base/core/func',
  'summernote/base/core/list',
  'summernote/base/core/range'
], function (agent, dom, func, list, range) {
  var AirPopover = function (context) {
    var self = this;

    var $document = $(document);
    var $editable = context.layoutInfo.editable;
    var editable = $editable[0];

    var options = context.options;

    this.events = {
      'summernote.keyup summernote.mouseup summernote.scroll': function () {
        self.update();
        self.setLastRange();
      },
      'summernote.change summernote.dialog.shown': function () {
        self.update();
        self.setLastRange();
      },
      'summernote.focusout': function (we, e) {
        // [workaround] Firefox doesn't support relatedTarget on focusout
        //  - Ignore hide action on focus out in FF.
        if (agent.isFF) {
          return;
        }

        if (!e.relatedTarget) {
          self.hide();
        }
      }
    };

    $editable.on('mousedown', function () {
      $document.on('mouseup', function () {
        mouseUp();
      });
      $(window).on('mouseup', function () {
        mouseUp();
      });
      $(window).on('blur', function () {
        mouseUp();
      });

      function mouseUp() {
        self.update();
        self.setLastRange();

        $document.off('mouseup');
        $(window).off('mouseup');
        $(window).off('blur');
      }
    });

    this.shouldInitialize = function () {
      return options.airMode &&
        options.popover &&
        options.popover.air &&
        typeof options.popover.air.hide === 'function' &&
        typeof options.popover.air.update === 'function';
    };

    this.initialize = function () {
      this.fontInstalledMap = {};
    };

    this.destroy = function () {
      delete this.fontInstalledMap;
    };

    this.isFontInstalled = function (name) {
      if (!self.fontInstalledMap.hasOwnProperty(name)) {
        self.fontInstalledMap[name] = agent.isFontInstalled(name) ||
          list.contains(options.fontNamesIgnoreCheck, name);
      }

      return self.fontInstalledMap[name];
    };

    this.getAvailablesFont = function () {
      return options.fontNames.filter(self.isFontInstalled);
    };

    this.setLastRange = function () {
      var currentRange = range.createFromSelection();
      if (currentRange && (self.isAncestor(currentRange.sc, editable) || currentRange.sc === editable)) {
        self.lastRange = currentRange ? currentRange : self.lastRange;
      }
      return self.lastRange;
    };

    this.getLastRange = function () {
      return self.lastRange;
    };

    this.insertNode = function (node, rng, deep) {
      context.invoke('editor.beforeCommand');
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);
      rng = rng.deleteContents();
      var splitFn = deep ? splitPointDeep : splitPoint,
          info = splitFn(rng.getStartPoint());

      if (info.rightNode && info.rightNode.parentNode) {
        info.rightNode.parentNode.insertBefore(node, info.rightNode);
      } else {
        if (!info.container || !self.isAncestor(info.container, editable)) {
          editable.appendChild(node);
        } else {
          info.container.appendChild(node);
        }
      }

      self.lastRange = range.createFromNodeAfter(node);
      self.lastRange.select();
      context.invoke('editor.afterCommand');
    };

    this.moveCursorToEnd = function () {
      context.invoke('editor.beforeCommand');
      if (editable.lastChild || editable.lastElementChild) {
        self.lastRange = range.createFromNodeAfter(editable.lastChild || editable.lastElementChild);
        self.lastRange.select();
      }
      context.invoke('editor.afterCommand');
      return self.lastRange;
    };

    this.pasteHTML = function (markup, rng, deep) {
      context.invoke('editor.beforeCommand');
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);
      rng = rng.deleteContents();
      var splitFn = deep ? splitPointDeep : splitPoint,
          info = splitFn(rng.getStartPoint());

      var contentsContainer = $('

').html(markup)[0];
      if (contentsContainer && contentsContainer.childNodes) {
        var childNodes = list.from(contentsContainer.childNodes);

        var contents = childNodes.map(function (childNode) {
          if (info.rightNode && info.rightNode.parentNode) {
            info.rightNode.parentNode.insertBefore(childNode, info.rightNode);
          } else {
            if (!info.container || !self.isAncestor(info.container, editable)) {
              editable.appendChild(childNode);
            } else {
              info.container.appendChild(childNode);
            }
          }
          return childNode;
        });

        self.lastRange = range.createFromNodeAfter(list.last(contents));
        self.lastRange.select();
      }
      context.invoke('editor.afterCommand');
    };

    this.update = function (force) {
      var styleInfo = context.invoke('editor.currentStyle');
      if (styleInfo.range && (!styleInfo.range.isCollapsed() || force)) {
        var rect = list.last(styleInfo.range.getClientRects());
        var bnd;
        if (rect) {
          bnd = func.rect2bnd(rect);
          options.popover.air.update(styleInfo, bnd);
        } else if (force) {
          options.popover.air.update(styleInfo, null);
        }
      } else {
        this.hide();
      }
    };

    this.hide = function () {
      options.popover.air.hide();
    };

    this.isAncestor = function (node, parentNode) {
      while (node) {
        if (node === parentNode) { return true; }

        node = node.parentNode;
      }
      return null;
    };

    this.removeFormat = function (rng) {
      removeFormat(rng, function (node) {
        return node && /^BACKQUOTE|^A|^LI|^UL|^EM|^B|^I|^STRONG|^H[1-7]/.test(node.nodeName.toUpperCase());
      });
    };

    this.unquote = function (rng) {
      rng = self.getFullParaRange(rng);
      rng = self.createPara(rng);
      removeFormat(rng, dom.isBlockquote);
    };

    this.splitPara = function (rng) {
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);

      context.invoke('editor.beforeCommand');

      splitPointDeep(rng.getStartPoint());

      context.invoke('editor.afterCommand');
    };

    this.createPara = function (rng) {
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);

      var info = {},
          leftPoint, startPoint, endPoint,
          leftRange, rightRange;
      if (rng.sc === rng.ec && rng.so === rng.eo) {
        info.left = splitPointDeep(rng.getStartPoint());
      } else {
        startPoint = rng.getStartPoint();
        endPoint = rng.getEndPoint();
        if (startPoint.node === endPoint.node) {
          endPoint.offset -= startPoint.offset;
        }
        info.left = splitPointDeep(startPoint);
        if (info.left.rightNode) {
          leftRange = range.createFromNodeBefore(info.left.rightNode);
          leftPoint = dom.prevPoint(leftRange.getStartPoint());
          if (leftPoint) {
            leftRange = range.create(leftPoint.node, leftPoint.offset, leftPoint.node, leftPoint.offset);
          }
        }
        info.right = splitPointDeep(endPoint);
      }

      if (info.right) {
        if (info.right.rightNode) {
          rightRange = range.createFromNodeBefore(info.right.rightNode);
          leftPoint = dom.prevPointUntil(rightRange.getStartPoint(), dom.isVisiblePoint);
          if (leftPoint) {
            rightRange = range.create(leftPoint.node, leftPoint.offset, leftPoint.node, leftPoint.offset);
          }
        } else {
          rightRange = self.moveCursorToEnd();
        }
      } else if (!leftRange) {
        leftRange = self.moveCursorToEnd();
      }

      if (rightRange) {
        startPoint = leftRange.getStartPoint();
        endPoint = rightRange.getStartPoint();
        rng = range.create(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);
      } else {
        startPoint = leftRange.getStartPoint();
        rng = range.create(startPoint.node, startPoint.offset, startPoint.node, startPoint.offset);
      }

      self.lastRange = rng;
      self.lastRange.select();

      return self.lastRange;
    };

    this.getFullParaRange = function (rng) {
      rng = rng || self.lastRange || range.create(editable);
      if (!rng) {
        return null;
      }

      var startPoint = rng.getStartPoint(),
          endPoint = rng.getEndPoint(),
          leftPoint = getStartLinePoint(startPoint),
          rightPoint = getEndLinePoint(endPoint);

      if (leftPoint && !dom.isSamePoint(leftPoint, startPoint)) {
        startPoint = leftPoint;
      }

      if (rightPoint && !dom.isSamePoint(rightPoint, endPoint)) {
        endPoint = rightPoint;
      }

      return range.create(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);

      function getStartLinePoint(point) {
        return dom.prevPointUntil(point, function (newPoint) {
          var prevPoint = dom.prevPoint(newPoint);
          return (dom.isLeftEdgePoint(newPoint) && (dom.isPara(newPoint.node) || dom.isBlockquote(newPoint.node))) ||
            (prevPoint.node && /^BR|^HR|^IFRAME/.test(prevPoint.node.nodeName.toUpperCase()));
        });
      }

      function getEndLinePoint(point) {
        return dom.nextPointUntil(point, function (newPoint) {
          return (dom.isRightEdgePoint(newPoint) && (dom.isPara(newPoint.node) || dom.isBlockquote(newPoint.node))) ||
            (newPoint.node && /^BR|^HR|^IFRAME/.test(newPoint.node.nodeName.toUpperCase()));
        });
      }
    };

    function removeFormat(rng, pred) {
      if (!pred) {
        return;
      }

      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);

      context.invoke('editor.beforeCommand');

      if (rng.sc !== rng.ec) {
        $.each(list.from(rng.nodes()), removeFormatNode);
      } else {
        removeFormatNode(rng.sc);
      }

      context.invoke('editor.afterCommand');

      function removeFormatNode(idx, rangeNode) {
        var ancestors = dom.listAncestor(rangeNode);
        ancestors.filter(pred).forEach(function (node) {
          var ancestor = node.parentNode;
          if (ancestor) {
            $.each(list.from(node.childNodes), function (idx, child) {
              ancestor.insertBefore(child, node);
            });
            ancestor.removeChild(node);
          }
        });
      }
    }

    function splitPoint(point) {
      if (dom.isEdgePoint(point) && dom.isRightEdgePoint(point)) {
        if (dom.isText(point.node)) {
          return {
            rightNode: point.node.nextSibling,
            container: point.node.parentNode
          };
        }

        return {
          container: point.node
        };
      }

      // split #text
      if (dom.isText(point.node)) {
        return {
          rightNode: point.node.splitText(point.offset),
          container: point.node.parentNode
        };
      } else {
        if (point.offset < point.node.childNodes.length) {
          return {
            rightNode: point.node.childNodes[point.offset],
            container: point.node
          };
        }
        return {
          container: point.node
        };
      }
    }

    function splitPointDeep(point) {
      var leftPoint = dom.prevPointUntil(point, function (newPoint) {
        return !dom.isLeftEdgePoint(newPoint) || (dom.isLeftEdgePoint(newPoint) && newPoint.node === editable);
      });
      var rightPoint = dom.nextPointUntil(point, function (newPoint) {
        return !dom.isRightEdgePoint(newPoint) || (dom.isRightEdgePoint(newPoint) && newPoint.node === editable);
      });

      if (leftPoint && !dom.isSamePoint(leftPoint, point)) {
        point = leftPoint;
      } else if (rightPoint && !dom.isSamePoint(rightPoint, point)) {
        point = rightPoint;
      }

      var brNode;
      leftPoint = dom.prevPoint(point);
      rightPoint = dom.nextPoint(point);

      if (leftPoint && dom.isBR(leftPoint.node)) {
        brNode = leftPoint.node;
        leftPoint = dom.prevPoint(leftPoint);
        brNode.parentNode.removeChild(brNode);
        if (leftPoint) {
          point = leftPoint;
        }
      } else if (rightPoint && dom.isBR(rightPoint.node)) {
        brNode = rightPoint.node;
        rightPoint = dom.prevPoint(rightPoint);
        brNode.parentNode.removeChild(brNode);
        if (rightPoint) {
          point = rightPoint;
        }
      }

      var leftRng = range.create(editable, 0, point.node, point.offset),
          leftContent = leftRng.nativeRange().extractContents(),
          rightNode;

      if (list.from(editable.childNodes).length) {
        rightNode = editable.childNodes[0];
        editable.insertBefore(leftContent, rightNode);
      } else {
        editable.appendChild(leftContent);
      }

      return {
        container: editable,
        rightNode: rightNode
      };
    }
  };

  return AirPopover;
});
<commit_msg>fix(airPopover): Fix minor bug<commit_after>define([
  'summernote/base/core/agent',
  'summernote/base/core/dom',
  'summernote/base/core/func',
  'summernote/base/core/list',
  'summernote/base/core/range'
], function (agent, dom, func, list, range) {
  var AirPopover = function (context) {
    var self = this;

    var $document = $(document);
    var $editable = context.layoutInfo.editable;
    var editable = $editable[0];

    var options = context.options;

    this.events = {
      'summernote.keyup summernote.mouseup summernote.scroll': function () {
        self.update();
        self.setLastRange();
      },
      'summernote.change summernote.dialog.shown': function () {
        self.update();
        self.setLastRange();
      },
      'summernote.focusout': function (we, e) {
        // [workaround] Firefox doesn't support relatedTarget on focusout
        //  - Ignore hide action on focus out in FF.
        if (agent.isFF) {
          return;
        }

        if (!e.relatedTarget) {
          self.hide();
        }
      }
    };

    $editable.on('mousedown', function () {
      $document.on('mouseup', function () {
        mouseUp();
      });
      $(window).on('mouseup', function () {
        mouseUp();
      });
      $(window).on('blur', function () {
        mouseUp();
      });

      function mouseUp() {
        self.update();
        self.setLastRange();

        $document.off('mouseup');
        $(window).off('mouseup');
        $(window).off('blur');
      }
    });

    this.shouldInitialize = function () {
      return options.airMode &&
        options.popover &&
        options.popover.air &&
        typeof options.popover.air.hide === 'function' &&
        typeof options.popover.air.update === 'function';
    };

    this.initialize = function () {
      this.fontInstalledMap = {};
    };

    this.destroy = function () {
      delete this.fontInstalledMap;
    };

    this.isFontInstalled = function (name) {
      if (!self.fontInstalledMap.hasOwnProperty(name)) {
        self.fontInstalledMap[name] = agent.isFontInstalled(name) ||
          list.contains(options.fontNamesIgnoreCheck, name);
      }

      return self.fontInstalledMap[name];
    };

    this.getAvailablesFont = function () {
      return options.fontNames.filter(self.isFontInstalled);
    };

    this.setLastRange = function () {
      var currentRange = range.createFromSelection();
      if (currentRange && (self.isAncestor(currentRange.sc, editable) || currentRange.sc === editable)) {
        self.lastRange = currentRange ? currentRange : self.lastRange;
      }
      return self.lastRange;
    };

    this.getLastRange = function () {
      return self.lastRange;
    };

    this.insertNode = function (node, rng, deep) {
      context.invoke('editor.beforeCommand');
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);
      rng = rng.deleteContents();
      var splitFn = deep ? splitPointDeep : splitPoint,
          info = splitFn(rng.getStartPoint());

      if (info.rightNode && info.rightNode.parentNode) {
        info.rightNode.parentNode.insertBefore(node, info.rightNode);
      } else {
        if (!info.container || !self.isAncestor(info.container, editable)) {
          editable.appendChild(node);
        } else {
          info.container.appendChild(node);
        }
      }

      self.lastRange = range.createFromNodeAfter(node);
      self.lastRange.select();
      context.invoke('editor.afterCommand');
    };

    this.moveCursorToEnd = function () {
      context.invoke('editor.beforeCommand');
      if (editable.lastChild || editable.lastElementChild) {
        self.lastRange = range.createFromNodeAfter(editable.lastChild || editable.lastElementChild);
        self.lastRange.select();
      }
      context.invoke('editor.afterCommand');
      return self.lastRange;
    };

    this.pasteHTML = function (markup, rng, deep) {
      context.invoke('editor.beforeCommand');
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);
      rng = rng.deleteContents();
      var splitFn = deep ? splitPointDeep : splitPoint,
          info = splitFn(rng.getStartPoint());

      var contentsContainer = $('

').html(markup)[0];
      if (contentsContainer && contentsContainer.childNodes) {
        var childNodes = list.from(contentsContainer.childNodes);

        var contents = childNodes.map(function (childNode) {
          if (info.rightNode && info.rightNode.parentNode) {
            info.rightNode.parentNode.insertBefore(childNode, info.rightNode);
          } else {
            if (!info.container || !self.isAncestor(info.container, editable)) {
              editable.appendChild(childNode);
            } else {
              info.container.appendChild(childNode);
            }
          }
          return childNode;
        });

        self.lastRange = range.createFromNodeAfter(list.last(contents));
        self.lastRange.select();
      }
      context.invoke('editor.afterCommand');
    };

    this.update = function (force) {
      var styleInfo = context.invoke('editor.currentStyle');
      if (styleInfo.range && (!styleInfo.range.isCollapsed() || force)) {
        var rect = list.last(styleInfo.range.getClientRects());
        var bnd;
        if (rect) {
          bnd = func.rect2bnd(rect);
          options.popover.air.update(styleInfo, bnd);
        } else if (force) {
          options.popover.air.update(styleInfo, null);
        }
      } else {
        this.hide();
      }
    };

    this.hide = function () {
      options.popover.air.hide();
    };

    this.isAncestor = function (node, parentNode) {
      while (node) {
        if (node === parentNode) { return true; }

        node = node.parentNode;
      }
      return null;
    };

    this.removeFormat = function (rng) {
      removeFormat(rng, function (node) {
        return node && /^BACKQUOTE|^A|^LI|^UL|^EM|^B|^I|^STRONG|^H[1-7]/.test(node.nodeName.toUpperCase());
      });
    };

    this.unquote = function (rng) {
      rng = self.getFullParaRange(rng);
      rng = self.createPara(rng);
      removeFormat(rng, dom.isBlockquote);
    };

    this.splitPara = function (rng) {
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);

      context.invoke('editor.beforeCommand');

      splitPointDeep(rng.getStartPoint());

      context.invoke('editor.afterCommand');
    };

    this.createPara = function (rng) {
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);

      var info = {},
          leftPoint, startPoint, endPoint,
          leftRange, rightRange;
      if (rng.sc === rng.ec && rng.so === rng.eo) {
        info.left = splitPointDeep(rng.getStartPoint());
      } else {
        startPoint = rng.getStartPoint();
        endPoint = rng.getEndPoint();
        if (startPoint.node === endPoint.node) {
          endPoint.offset -= startPoint.offset;
        }
        info.left = splitPointDeep(startPoint);
        if (info.left.rightNode) {
          leftRange = range.createFromNodeBefore(info.left.rightNode);
          leftPoint = dom.prevPoint(leftRange.getStartPoint());
          if (leftPoint) {
            leftRange = range.create(leftPoint.node, leftPoint.offset, leftPoint.node, leftPoint.offset);
          }
        }
        info.right = splitPointDeep(endPoint);
      }

      if (info.right) {
        if (info.right.rightNode) {
          rightRange = range.createFromNodeBefore(info.right.rightNode);
          leftPoint = dom.prevPointUntil(rightRange.getStartPoint(), dom.isVisiblePoint);
          if (leftPoint) {
            rightRange = range.create(leftPoint.node, leftPoint.offset, leftPoint.node, leftPoint.offset);
          }
        } else {
          rightRange = self.moveCursorToEnd();
        }
      } else if (!leftRange) {
        leftRange = self.moveCursorToEnd();
      }

      if (rightRange) {
        startPoint = leftRange.getStartPoint();
        endPoint = rightRange.getStartPoint();
        rng = range.create(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);
      } else {
        startPoint = leftRange.getStartPoint();
        rng = range.create(startPoint.node, startPoint.offset, startPoint.node, startPoint.offset);
      }

      self.lastRange = rng;
      self.lastRange.select();

      return self.lastRange;
    };

    this.getFullParaRange = function (rng) {
      rng = rng || self.lastRange || range.create(editable);
      if (!rng) {
        return null;
      }

      var startPoint = rng.getStartPoint(),
          endPoint = rng.getEndPoint(),
          leftPoint = getStartLinePoint(startPoint),
          rightPoint = getEndLinePoint(endPoint);

      if (leftPoint && !dom.isSamePoint(leftPoint, startPoint)) {
        startPoint = leftPoint;
      }

      if (rightPoint && !dom.isSamePoint(rightPoint, endPoint)) {
        endPoint = rightPoint;
      }

      return range.create(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);

      function getStartLinePoint(point) {
        return dom.prevPointUntil(point, function (newPoint) {
          var prevPoint = dom.prevPoint(newPoint);
          return (dom.isLeftEdgePoint(newPoint) && (dom.isPara(newPoint.node) || dom.isBlockquote(newPoint.node))) ||
            (prevPoint && prevPoint.node && /^BR|^HR|^IFRAME/.test(prevPoint.node.nodeName.toUpperCase()));
        });
      }

      function getEndLinePoint(point) {
        return dom.nextPointUntil(point, function (newPoint) {
          return (dom.isRightEdgePoint(newPoint) && (dom.isPara(newPoint.node) || dom.isBlockquote(newPoint.node))) ||
            (newPoint.node && /^BR|^HR|^IFRAME/.test(newPoint.node.nodeName.toUpperCase()));
        });
      }
    };

    function removeFormat(rng, pred) {
      if (!pred) {
        return;
      }

      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);

      context.invoke('editor.beforeCommand');

      if (rng.sc !== rng.ec) {
        $.each(list.from(rng.nodes()), removeFormatNode);
      } else {
        removeFormatNode(rng.sc);
      }

      context.invoke('editor.afterCommand');

      function removeFormatNode(idx, rangeNode) {
        var ancestors = dom.listAncestor(rangeNode);
        ancestors.filter(pred).forEach(function (node) {
          var ancestor = node.parentNode;
          if (ancestor) {
            $.each(list.from(node.childNodes), function (idx, child) {
              ancestor.insertBefore(child, node);
            });
            ancestor.removeChild(node);
          }
        });
      }
    }

    function splitPoint(point) {
      if (dom.isEdgePoint(point) && dom.isRightEdgePoint(point)) {
        if (dom.isText(point.node)) {
          return {
            rightNode: point.node.nextSibling,
            container: point.node.parentNode
          };
        }

        return {
          container: point.node
        };
      }

      // split #text
      if (dom.isText(point.node)) {
        return {
          rightNode: point.node.splitText(point.offset),
          container: point.node.parentNode
        };
      } else {
        if (point.offset < point.node.childNodes.length) {
          return {
            rightNode: point.node.childNodes[point.offset],
            container: point.node
          };
        }
        return {
          container: point.node
        };
      }
    }

    function splitPointDeep(point) {
      var leftPoint = dom.prevPointUntil(point, function (newPoint) {
        return !dom.isLeftEdgePoint(newPoint) || (dom.isLeftEdgePoint(newPoint) && newPoint.node === editable);
      });
      var rightPoint = dom.nextPointUntil(point, function (newPoint) {
        return !dom.isRightEdgePoint(newPoint) || (dom.isRightEdgePoint(newPoint) && newPoint.node === editable);
      });

      if (leftPoint && !dom.isSamePoint(leftPoint, point)) {
        point = leftPoint;
      } else if (rightPoint && !dom.isSamePoint(rightPoint, point)) {
        point = rightPoint;
      }

      var brNode;
      leftPoint = dom.prevPoint(point);
      rightPoint = dom.nextPoint(point);

      if (leftPoint && dom.isBR(leftPoint.node)) {
        brNode = leftPoint.node;
        leftPoint = dom.prevPoint(leftPoint);
        brNode.parentNode.removeChild(brNode);
        if (leftPoint) {
          point = leftPoint;
        }
      } else if (rightPoint && dom.isBR(rightPoint.node)) {
        brNode = rightPoint.node;
        rightPoint = dom.prevPoint(rightPoint);
        brNode.parentNode.removeChild(brNode);
        if (rightPoint) {
          point = rightPoint;
        }
      }

      var leftRng = range.create(editable, 0, point.node, point.offset),
          leftContent = leftRng.nativeRange().extractContents(),
          rightNode;

      if (list.from(editable.childNodes).length) {
        rightNode = editable.childNodes[0];
        editable.insertBefore(leftContent, rightNode);
      } else {
        editable.appendChild(leftContent);
      }

      return {
        container: editable,
        rightNode: rightNode
      };
    }
  };

  return AirPopover;
});
<|endoftext|>


<commit_before>import ModalBase from 'ghost-admin/components/modal-base';
import classic from 'ember-classic-decorator';
import {action} from '@ember/object';
import {tracked} from '@glimmer/tracking';

// TODO: update modals to work fully with Glimmer components
@classic
export default class ModalPostPreviewComponent extends ModalBase {
    @tracked role;

    // TODO: rename to confirm() when modals have full Glimmer support
    @action
    confirmAction() {
        this.confirm(this.role);
        this.close();
    }

    @action
    close(event) {
        event?.preventDefault?.();
        this.closeModal();
    }

    @action
    setRoleFromModel() {
        this.role = this.model;
    }

    actions = {
        confirm() {
            this.confirmAction(...arguments);
        },

        // needed because ModalBase uses .send() for keyboard events
        closeModal() {
            this.args.close();
        }
    }
}
<commit_msg>Fixed "this.args is undefined" error when pressing Escape to close roles modal<commit_after>import ModalBase from 'ghost-admin/components/modal-base';
import classic from 'ember-classic-decorator';
import {action} from '@ember/object';
import {tracked} from '@glimmer/tracking';

// TODO: update modals to work fully with Glimmer components
@classic
export default class ModalPostPreviewComponent extends ModalBase {
    @tracked role;

    // TODO: rename to confirm() when modals have full Glimmer support
    @action
    confirmAction() {
        this.confirm(this.role);
        this.close();
    }

    @action
    close(event) {
        event?.preventDefault?.();
        this.closeModal();
    }

    @action
    setRoleFromModel() {
        this.role = this.model;
    }

    actions = {
        confirm() {
            this.confirmAction(...arguments);
        },

        // needed because ModalBase uses .send() for keyboard events
        closeModal() {
            this.close();
        }
    }
}
<|endoftext|>


<commit_before>/* Inspired from Atom
  https://github.com/atom/tabs
  https://github.com/atom/atom-dark-ui
*/
'use strict';

let StyleSheet = require('react-style');

const TabStyles = StyleSheet.create({

  wrapper: {
    height: '100%',
    width: '100%',
    position: 'relative'
  },

  relative: {
    position: 'relative'
  },

  tabBar: {
    // @TODO safari needs prefix. Style should be define in CSS.
    // Can't use duprecated key's for inline-style.
    // See https://github.com/facebook/react/issues/2020
    // display: '-webkit-flex',
    // display: '-ms-flexbox',
    display: 'flex',
    WebkitUserSelect: 'none',
    MozUserSelect: 'none',
    msUserSelect: 'none',
    userSelect: 'none',
    margin: 0,
    listStyle: 'none',
    outline: '0px',
    overflowY: 'hidden',
    overflowX: 'hiden',
    minWidth: '95%',
    maxWidth: '99%'
  },

  tabBarAfter: {
    content: '',
    position: 'absolute',
    top: '26px',
    height: '5px',
    left: '0',
    right: '0',
    zIndex: 2,
    backgroundColor: '#222222',
    borderBottom: '1px solid #111111',
    pointerEvents: 'none'
  },

  tab: {
    fontFamily: "'Lucida Grande', 'Segoe UI', Ubuntu, Cantarell, sans-serif",
    backgroundImage: 'linear-gradient(#454545, #333333)',
    height: '26px',
    fontSize: '11px',
    position: 'relative',
    marginLeft: '5px',
    paddingLeft: '15px',
    paddingRight: '24px',
    WebkutBoxFlex: 1,
    WebkitFlex: 1,
    MozFlex: 1,
    msFlex: 1,
    flex: 1,
    maxWidth: '175px',
    minWidth: '40px',
    transform: 'translate(0px, 0px)'
  },

  tabBefore: {
    content: '',
    position: 'absolute',
    top: '0px',
    width: '25px',
    height: '26px',

    left: '-14px',
    borderTopLeftRadius: '3px',
    boxShadow: 'inset 1px 1px 0 #484848, -4px 0px 4px rgba(0, 0, 0, 0.1)',
    WebkitTransform: 'skewX(-30deg)',
    MozTransform: 'skewX(-30deg)',
    msTransform: 'skewX(-30deg)',
    transform: 'skewX(-30deg)',
    backgroundImage: 'linear-gradient(#454545, #333333)'
  },

  tabAfter: {
    content: '',
    position: 'absolute',
    top: '0px',
    width: '25px',
    height: '26px',

    right: '-14px',
    borderTopRightRadius: '3px',
    boxShadow: 'inset -1px 1px 0 #484848, 4px 0px 4px rgba(0, 0, 0, 0.1)',
    WebkitTransform: 'skewX(30deg)',
    MozTransform: 'skewX(30deg)',
    msTransform: 'skewX(30deg)',
    transform: 'skewX(30deg)',
    backgroundImage: 'linear-gradient(#454545, #333333)'
  },

  tabActive: {
    WebkutBoxFlex: 2,
    WebkitFlex: 2,
    MozFlex: 2,
    msFlex: 2,
    flex: 2,
    zIndex: 1,
    color: '#ffffff',
    fontSize: '13px',
    backgroundImage: 'linear-gradient(#343434, #222222)'
  },

  tabTitle: {
    overflow: 'hidden',
    whiteSpace: 'nowrap',
    textOverflow: 'ellipsis',
    marginTop: '8px',
    float: 'left',
    textAlign: 'center',
    postion: 'relative',
    width: '90%',
    color: 'rgb(170, 170, 170)'
  },

  tabBeforeActive: {
    backgroundImage: 'linear-gradient(#343434, #222222)'
  },

  tabAfterActive: {
    backgroundImage: 'linear-gradient(#343434, #222222)'
  },

  tabTitleActive: {
    lineHeight: '1.5em',
    color: 'rgb(255, 255, 255)',
    marginTop:'6px'

  },

  tabCloseIcon:{
    cursor: 'pointer',
    font: '14px/100% arial, sans-serif',
    width: '10%',
    right: '5px',
    marginTop: '8px',
    textDecoration: 'none',
    textShadow: '0 1px 0 #fff',
    float: 'right',
    fontSize: '1.5em',
    lineHeight: '1em',
    filter: 'alpha(opacity=20)',
    opacity: '.2'
  },

  tabCloseIconOnHover:{
    textShadow: '0 1px 0 #red',
    color:'red'
  },

  tabAddButton: {
    cursor: 'pointer',
    fontFamily: "'Lucida Grande', 'Segoe UI', Ubuntu, Cantarell, sans-serif",
    fontSize: '20px',
    textShadow: 'rgb(255, 255, 255) 0px 1px 0px',
    position: 'relative',
    width: '25px',
    height: '26px',
    marginLeft: '20px'
  },

  beforeTitle: {
    position:'absolute',
    top: '8px',
    left: '-8px',
    zIndex: 2
  },

  afterTitle: {
    position:'absolute',
    top: '8px',
    right: '16px',
    zIndex: 2
  }

});

export default TabStyles;
<commit_msg>Improve default style<commit_after>/* Inspired from Atom
  https://github.com/atom/tabs
  https://github.com/atom/atom-dark-ui
*/
'use strict';

let StyleSheet = require('react-style');

const TabStyles = StyleSheet.create({

  wrapper: {
    height: '100%',
    width: '100%',
    position: 'relative'
  },

  relative: {
    position: 'relative'
  },

  tabBar: {
    // @TODO safari needs prefix. Style should be define in CSS.
    // Can't use duprecated key's for inline-style.
    // See https://github.com/facebook/react/issues/2020
    // display: '-webkit-flex',
    // display: '-ms-flexbox',
    display: 'flex',
    WebkitUserSelect: 'none',
    MozUserSelect: 'none',
    msUserSelect: 'none',
    userSelect: 'none',
    margin: 0,
    listStyle: 'none',
    outline: '0px',
    overflowY: 'hidden',
    overflowX: 'hidden',
    minWidth: '95%',
    maxWidth: '99%',
    paddingRight: '35px'
  },

  tabBarAfter: {
    content: '',
    position: 'absolute',
    top: '26px',
    height: '5px',
    left: '0',
    right: '0',
    zIndex: 2,
    backgroundColor: '#222222',
    borderBottom: '1px solid #111111',
    pointerEvents: 'none'
  },

  tab: {
    fontFamily: "'Lucida Grande', 'Segoe UI', Ubuntu, Cantarell, sans-serif",
    backgroundImage: 'linear-gradient(#454545, #333333)',
    height: '26px',
    fontSize: '11px',
    position: 'relative',
    marginLeft: '5px',
    paddingLeft: '15px',
    paddingRight: '24px',
    WebkutBoxFlex: 1,
    WebkitFlex: 1,
    MozFlex: 1,
    msFlex: 1,
    flex: 1,
    maxWidth: '175px',
    minWidth: '0px',
    transform: 'translate(0px, 0px)'
  },

  tabBefore: {
    content: '',
    position: 'absolute',
    top: '0px',
    width: '25px',
    height: '26px',

    left: '-14px',
    borderTopLeftRadius: '3px',
    boxShadow: 'inset 1px 1px 0 #484848, -4px 0px 4px rgba(0, 0, 0, 0.1)',
    WebkitTransform: 'skewX(-30deg)',
    MozTransform: 'skewX(-30deg)',
    msTransform: 'skewX(-30deg)',
    transform: 'skewX(-30deg)',
    backgroundImage: 'linear-gradient(#454545, #333333)'
  },

  tabAfter: {
    content: '',
    position: 'absolute',
    top: '0px',
    width: '25px',
    height: '26px',

    right: '-14px',
    borderTopRightRadius: '3px',
    boxShadow: 'inset -1px 1px 0 #484848, 4px 0px 4px rgba(0, 0, 0, 0.1)',
    WebkitTransform: 'skewX(30deg)',
    MozTransform: 'skewX(30deg)',
    msTransform: 'skewX(30deg)',
    transform: 'skewX(30deg)',
    backgroundImage: 'linear-gradient(#454545, #333333)'
  },

  tabActive: {
    WebkutBoxFlex: 2,
    WebkitFlex: 2,
    MozFlex: 2,
    msFlex: 2,
    flex: 2,
    zIndex: 1,
    color: '#ffffff',
    fontSize: '13px',
    backgroundImage: 'linear-gradient(#343434, #222222)'
  },

  tabTitle: {
    overflow: 'hidden',
    whiteSpace: 'nowrap',
    textOverflow: 'ellipsis',
    marginTop: '8px',
    float: 'left',
    textAlign: 'center',
    postion: 'relative',
    width: '90%',
    color: 'rgb(170, 170, 170)'
  },

  tabBeforeActive: {
    backgroundImage: 'linear-gradient(#343434, #222222)'
  },

  tabAfterActive: {
    backgroundImage: 'linear-gradient(#343434, #222222)'
  },

  tabTitleActive: {
    lineHeight: '1.5em',
    color: 'rgb(255, 255, 255)',
    marginTop:'6px'

  },

  tabCloseIcon:{
    cursor: 'pointer',
    font: '14px/100% arial, sans-serif',
    width: '10%',
    right: '5px',
    marginTop: '8px',
    textDecoration: 'none',
    textShadow: '0 1px 0 #fff',
    float: 'right',
    fontSize: '1.5em',
    lineHeight: '1em',
    filter: 'alpha(opacity=20)',
    opacity: '.2'
  },

  tabCloseIconOnHover:{
    textShadow: '0 1px 0 #red',
    color:'red'
  },

  tabAddButton: {
    cursor: 'pointer',
    fontFamily: "'Lucida Grande', 'Segoe UI', Ubuntu, Cantarell, sans-serif",
    fontSize: '20px',
    textShadow: 'rgb(255, 255, 255) 0px 1px 0px',
    position: 'fixed',
    width: '25px',
    height: '26px',
    marginLeft: '20px',
    zIndex: 2
  },

  beforeTitle: {
    position:'absolute',
    top: '8px',
    left: '-8px',
    zIndex: 2
  },

  afterTitle: {
    position:'absolute',
    top: '8px',
    right: '16px',
    zIndex: 2
  }

});

export default TabStyles;
<|endoftext|>


<commit_before><commit_msg>Listing 4.07 - addItem and removeItem<commit_after><|endoftext|>


<commit_before>import React from 'react'

module.exports = ({state, dispatch}) => {
  const toggleSelected = (e) => {
    dispatch({type: 'TOGGLE_SELECTED', payload: e.target.parentElement.id})
    dispatch({type: 'ADD_PREDATOR', payload: {field: 'capturedPredator', value: e.target.parentElement.id}})
    const selectClass = 'col-4 col-m-4 predatorSelected'
    const unselectClass = 'col-4 col-m-4 predatorCell'
    document.getElementById(e.target.parentElement.id).className = selectClass
    if (state.predatorSelected !== e.target.parentElement.id) {
      document.getElementById(state.predatorSelected).className = unselectClass
    }
  }

  return (

Norway Rat

Ship Rat

Mouse

Ferret

Stoat

Weasel

Possum

Hedgehog

Feral Cat

  )
}
<commit_msg>corrected img src route for deployed (again)<commit_after>import React from 'react'

module.exports = ({state, dispatch}) => {
  const toggleSelected = (e) => {
    dispatch({type: 'TOGGLE_SELECTED', payload: e.target.parentElement.id})
    dispatch({type: 'ADD_PREDATOR', payload: {field: 'capturedPredator', value: e.target.parentElement.id}})
    const selectClass = 'col-4 col-m-4 predatorSelected'
    const unselectClass = 'col-4 col-m-4 predatorCell'
    document.getElementById(e.target.parentElement.id).className = selectClass
    if (state.predatorSelected !== e.target.parentElement.id) {
      document.getElementById(state.predatorSelected).className = unselectClass
    }
  }

  return (

Norway Rat

Ship Rat

Mouse

Ferret

Stoat

Weasel

Possum

Hedgehog

Feral Cat

  )
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import { TABS } from '../identifiers.js';
import InjectTab from './Tab.js';
import InjectTabContent from './TabContent.js';

const factory = (Tab, TabContent) => {
  class Tabs extends Component {
    static propTypes = {
      children: PropTypes.node,
      className: PropTypes.string,
      disableAnimatedBottomBorder: PropTypes.bool,
      fixed: PropTypes.bool,
      hideMode: PropTypes.oneOf(['display', 'unmounted']),
      index: PropTypes.number,
      inverse: PropTypes.bool,
      onChange: PropTypes.func,
      theme: PropTypes.shape({
        fixed: PropTypes.string,
        inverse: PropTypes.string,
        navigation: PropTypes.string,
        pointer: PropTypes.string,
        tabs: PropTypes.string
      })
    };

    static defaultProps = {
      index: 0,
      fixed: false,
      inverse: false,
      hideMode: 'unmounted'
    };

    state = {
      pointer: {}
    };

    componentDidMount () {
      !this.props.disableAnimatedBottomBorder && this.updatePointer(this.props.index);
      window.addEventListener('resize', this.handleResize);
      this.handleResize();
    }

    componentWillReceiveProps (nextProps) {
      !this.props.disableAnimatedBottomBorder && this.updatePointer(nextProps.index);
    }

    componentWillUnmount () {
      window.removeEventListener('resize', this.handleResize);
      clearTimeout(this.resizeTimeout);
      clearTimeout(this.pointerTimeout);
    }

    handleHeaderClick = (event) => {
      const idx = parseInt(event.currentTarget.id);
      if (this.props.onChange) this.props.onChange(idx);
    };

    handleResize = () => {
      if (!this.props.fixed) {
        return;
      }

      if (this.resizeTimeout) {
        clearTimeout(this.resizeTimeout);
      }
      this.resizeTimeout = setTimeout(this.handleResizeEnd, 50);
    };

    handleResizeEnd = () => {
      this.updatePointer(this.props.index);
    };

    parseChildren () {
      const headers = [];
      const contents = [];

      React.Children.forEach(this.props.children, (item) => {
        if (item.type === Tab) {
          headers.push(item);
          if (item.props.children) {
            contents.push(<TabContent children={item.props.children} theme={this.props.theme} />);
          }
        } else if (item.type === TabContent) {
          contents.push(item);
        }
      });

      return {headers, contents};
    }

    updatePointer (idx) {
      clearTimeout(this.pointerTimeout);
      this.pointerTimeout = setTimeout(() => {
        const startPoint = this.refs.tabs.getBoundingClientRect().left;
        const label = this.refs.navigation.children[idx].getBoundingClientRect();
        this.setState({
          pointer: {
            top: `${this.refs.navigation.getBoundingClientRect().height}px`,
            left: `${label.left - startPoint}px`,
            width: `${label.width}px`
          }
        });
      }, 20);
    }

    renderHeaders (headers) {
      return headers.map((item, idx) => {
        return React.cloneElement(item, {
          id: idx,
          key: idx,
          theme: this.props.theme,
          active: this.props.index === idx,
          onClick: event => {
            this.handleHeaderClick(event);
            item.props.onClick && item.props.onClick(event);
          }
        });
      });
    }

    renderContents (contents) {
      const contentElements = contents.map((item, idx) => {
        return React.cloneElement(item, {
          key: idx,
          theme: this.props.theme,
          active: this.props.index === idx,
          hidden: this.props.index !== idx && this.props.hideMode === 'display',
          tabIndex: idx
        });
      });

      if (this.props.hideMode === 'display') {
        return contentElements;
      }

      return contentElements.filter((item, idx) => (idx === this.props.index));
    }

    render () {
      const { className, theme, fixed, inverse } = this.props;
      const { headers, contents } = this.parseChildren();
      const classes = classnames(
        theme.tabs,
        className,
        {
          [theme.fixed]: fixed,
          [theme.inverse]: inverse
        }
      );
      return (

            {this.renderHeaders(headers)}

          {this.renderContents(contents)}

      );
    }
  }

  return Tabs;
};

const Tabs = factory(InjectTab, InjectTabContent);
export default themr(TABS)(Tabs);
export { factory as tabsFactory };
export { Tabs };
<commit_msg>Fix #814<commit_after>import React, { Component, PropTypes } from 'react';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import { TABS } from '../identifiers.js';
import InjectTab from './Tab.js';
import InjectTabContent from './TabContent.js';

const factory = (Tab, TabContent) => {
  class Tabs extends Component {
    static propTypes = {
      children: PropTypes.node,
      className: PropTypes.string,
      disableAnimatedBottomBorder: PropTypes.bool,
      fixed: PropTypes.bool,
      hideMode: PropTypes.oneOf(['display', 'unmounted']),
      index: PropTypes.number,
      inverse: PropTypes.bool,
      onChange: PropTypes.func,
      theme: PropTypes.shape({
        fixed: PropTypes.string,
        inverse: PropTypes.string,
        navigation: PropTypes.string,
        pointer: PropTypes.string,
        tabs: PropTypes.string
      })
    };

    static defaultProps = {
      index: 0,
      fixed: false,
      inverse: false,
      hideMode: 'unmounted'
    };

    state = {
      pointer: {}
    };

    componentDidMount () {
      !this.props.disableAnimatedBottomBorder && this.updatePointer(this.props.index);
      window.addEventListener('resize', this.handleResize);
      this.handleResize();
    }

    componentWillReceiveProps (nextProps) {
      !this.props.disableAnimatedBottomBorder && this.updatePointer(nextProps.index);
    }

    componentWillUnmount () {
      window.removeEventListener('resize', this.handleResize);
      clearTimeout(this.resizeTimeout);
      clearTimeout(this.pointerTimeout);
    }

    handleHeaderClick = (event) => {
      const idx = parseInt(event.currentTarget.id);
      if (this.props.onChange) this.props.onChange(idx);
    };

    handleResize = () => {
      if (this.resizeTimeout) {
        clearTimeout(this.resizeTimeout);
      }
      this.resizeTimeout = setTimeout(this.handleResizeEnd, 50);
    };

    handleResizeEnd = () => {
      this.updatePointer(this.props.index);
    };

    parseChildren () {
      const headers = [];
      const contents = [];

      React.Children.forEach(this.props.children, (item) => {
        if (item.type === Tab) {
          headers.push(item);
          if (item.props.children) {
            contents.push(<TabContent children={item.props.children} theme={this.props.theme} />);
          }
        } else if (item.type === TabContent) {
          contents.push(item);
        }
      });

      return {headers, contents};
    }

    updatePointer (idx) {
      clearTimeout(this.pointerTimeout);
      this.pointerTimeout = setTimeout(() => {
        const startPoint = this.refs.tabs.getBoundingClientRect().left;
        const label = this.refs.navigation.children[idx].getBoundingClientRect();
        this.setState({
          pointer: {
            top: `${this.refs.navigation.getBoundingClientRect().height}px`,
            left: `${label.left - startPoint}px`,
            width: `${label.width}px`
          }
        });
      }, 20);
    }

    renderHeaders (headers) {
      return headers.map((item, idx) => {
        return React.cloneElement(item, {
          id: idx,
          key: idx,
          theme: this.props.theme,
          active: this.props.index === idx,
          onClick: event => {
            this.handleHeaderClick(event);
            item.props.onClick && item.props.onClick(event);
          }
        });
      });
    }

    renderContents (contents) {
      const contentElements = contents.map((item, idx) => {
        return React.cloneElement(item, {
          key: idx,
          theme: this.props.theme,
          active: this.props.index === idx,
          hidden: this.props.index !== idx && this.props.hideMode === 'display',
          tabIndex: idx
        });
      });

      if (this.props.hideMode === 'display') {
        return contentElements;
      }

      return contentElements.filter((item, idx) => (idx === this.props.index));
    }

    render () {
      const { className, theme, fixed, inverse } = this.props;
      const { headers, contents } = this.parseChildren();
      const classes = classnames(
        theme.tabs,
        className,
        {
          [theme.fixed]: fixed,
          [theme.inverse]: inverse
        }
      );
      return (

            {this.renderHeaders(headers)}

          {this.renderContents(contents)}

      );
    }
  }

  return Tabs;
};

const Tabs = factory(InjectTab, InjectTabContent);
export default themr(TABS)(Tabs);
export { factory as tabsFactory };
export { Tabs };
<|endoftext|>


<commit_before>/**
 * A light controller class for using a modified version of Esri's Windy.JS.
 */

import {CanvasRenderer} from './../renderers/canvas/canvas';
import {debounce} from './../utilities/functions';
import {WebGLRenderer} from './../renderers/gl/gl';

export class WindMap {
  /**
   * A constructor for the WindMap. See typedefs.js for a description of
   * ConfigPayload.
   *
   * @param {!ConfigPayload} config An instance of ConfigPayload.
   */
  constructor(config) {
    const context = getContextType();

    if (context.type.indexOf('2d') > -1) {
      this.renderer = new CanvasRenderer(config.canvas, config.extent, context.renderer);
    } else if (context.type.indexOf('webgl') > -1) {
      this.renderer = new WebGLRenderer(config.canvas, config.extent, context.renderer);
    }

    this.debounceStart_ = debounce((config) => {
      this.renderer.start_(config);
    });

    function getContextType() {
      for (let type of ['webgl', 'webgl-experimental', '2d']) {
        const context = {
          type: type,
          renderer: config.canvas.getContext(type, {preserveDrawingBuffer: true})
        };
        if (context.renderer) {
          return context;
        }
      }
    };
  }

  /**
   * Stops the WindMap animation.
   * @return {!WindMap} The windmap instance.
   */
  stop() {
    this.renderer.stop_();
    return this;
  }

  /**
   * Starts the WindMap animation.
   * @param {!ConfigPayload=} config An instance of ConfigPayload.
   * @param {boolean=} renderImmediately Whether to render immediately instead
   *    of debouncing.
   * @return {!WindMap} The windmap instance.
   */
  start(config={}, renderImmediately=false) {
    if (renderImmediately) this.renderer.start_(config);
    else this.debounceStart_(config);

    return this;
  }

  /**
   * Updates the WindMap data and its optional configurations.
   * @param {!ConfigPayload=} config An instance of ConfigPayload.
   * @param {boolean=} renderImmediately Whether to render immediately instead
   *    of debouncing.
   * @return {!WindMap} The windmap instance.
   */
  update(config={}, renderImmediately=false) {
    return this.stop().start(config, renderImmediately);
  }
};
<commit_msg>update file overview for wind.js<commit_after>/**
 * A light controller class for using a modified version of Earth.nullschool.
 */

import {CanvasRenderer} from './../renderers/canvas/canvas';
import {debounce} from './../utilities/functions';
import {WebGLRenderer} from './../renderers/gl/gl';

export class WindMap {
  /**
   * A constructor for the WindMap. See typedefs.js for a description of
   * ConfigPayload.
   *
   * @param {!ConfigPayload} config An instance of ConfigPayload.
   */
  constructor(config) {
    const context = getContextType();

    if (context.type.indexOf('2d') > -1) {
      this.renderer = new CanvasRenderer(config.canvas, config.extent, context.renderer);
    } else if (context.type.indexOf('webgl') > -1) {
      this.renderer = new WebGLRenderer(config.canvas, config.extent, context.renderer);
    }

    this.debounceStart_ = debounce((config) => {
      this.renderer.start_(config);
    });

    function getContextType() {
      for (let type of ['webgl', 'webgl-experimental', '2d']) {
        const context = {
          type: type,
          renderer: config.canvas.getContext(type, {preserveDrawingBuffer: true})
        };
        if (context.renderer) {
          return context;
        }
      }
    };
  }

  /**
   * Stops the WindMap animation.
   * @return {!WindMap} The windmap instance.
   */
  stop() {
    this.renderer.stop_();
    return this;
  }

  /**
   * Starts the WindMap animation.
   * @param {!ConfigPayload=} config An instance of ConfigPayload.
   * @param {boolean=} renderImmediately Whether to render immediately instead
   *    of debouncing.
   * @return {!WindMap} The windmap instance.
   */
  start(config={}, renderImmediately=false) {
    if (renderImmediately) this.renderer.start_(config);
    else this.debounceStart_(config);

    return this;
  }

  /**
   * Updates the WindMap data and its optional configurations.
   * @param {!ConfigPayload=} config An instance of ConfigPayload.
   * @param {boolean=} renderImmediately Whether to render immediately instead
   *    of debouncing.
   * @return {!WindMap} The windmap instance.
   */
  update(config={}, renderImmediately=false) {
    return this.stop().start(config, renderImmediately);
  }
};
<|endoftext|>


<commit_before>'use strict';

var exec = require('child_process').exec;
var fs = require('fs');

/**
 * exec?
 */
exports.doCompile = function (req, res) {
    //console.log('exec');

    //exec('./public/code/magic_square', function (error, stdout, srderr) {
    //    console.log(stdout);
        //res.send(stdout);
        //res.redirect('/');
        //res.set('Content-Type', 'text/html');
        //res.send(new Buffer(stdout));
        //res.format({
            //'text/plain': function(){
            //    res.send('hey');
            //},

    //        'text/html': function(){
    //            res.send("
This is a Magic Square program.
");
    //        }
    //    });
    //});

    //console.log(req.body.content);

    var code = req.body.content;

    fs.writeFile('public/temp_code.c', code, function (err) {
        if (err) throw err;
    });

    //var wstream = fs.createWriteStream('myOutput.txt', { flags: 'w' });
    //wstream.write("ss");
    //wstream.end();
    //var fs = require('fs');
    //var stream = fs.createWriteStream("my_file.txt");
    //stream.once('open', function(fd) {
    //    stream.write("My first row\n");
    //    stream.write("My second row\n");
    //    stream.end();
    //});

    exec('gcc -o public/temp_code public/temp_code.c', function (error, stdout, srderr) {
        var output;
        if (srderr !== '') {
            console.log('error');
            console.log(srderr);
            output = {
                content: srderr
            };
            srderr = null;
            res.json(output);
        } else {
            console.log('stdout');
            exec('./public/temp_code', function (error, stdout, srderr) {
                    output = {
                        content: stdout
                    };
                res.json(output);
            });
        }
    });
    //fs.open('a.c','w+', function(err, fd) {
    //    var buf = 'abc';
    //    if (err) {
    //        console.log(err);
    //    } else {
    //        fs.write(fd, buf, 0, buf.length);
    //    }
    //});

};

/*
exports.run = function(req, res) {
    var test = new Test(req.body);
    test.user = req.user;

    test.save(function(err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.jsonp(test);
        }
    });
};

function start() {
    console.log("Request handler 'start' was called.");
    var content = "empty";

    exec("ls -lah", function (error, stdout, stderr) {
        content = stdout;
    });

    return content;
}

function upload() {
    console.log("Request handler 'upload' was called.");
    return "Hello Upload";
}

exports.start = start;
exports.upload = upload;*/
<commit_msg>Cleaned up serverside compile function<commit_after>'use strict';

var exec = require('child_process').exec;
var fs = require('fs');

/**
 * exec?
 */
exports.doCompile = function (req, res) {
    var code = req.body.content; // code from user
    var emptyCode = 'int main(int argc, char** argv) {\n\n  return 0;\n}'; // define empty code string
    var path = 'public/tmp/'; // define temporary code & executable dir

    if (code == emptyCode) {
        console.log('empty body!!!');
    } else {
        fs.writeFile(path + 'temp_code.c', code, function (err) {
            if (err) throw err;
        });
        exec('gcc -o ' + path + 'temp_code ' + path + 'temp_code.c', function (error, stdout, stderr) {
            var output;
            if (stderr !== '') {
                console.log('error');
                console.log(stderr);
                output = { content: stderr };
                stderr = null;
                res.json(output);
            } else {
                console.log('stdout:');
                exec(path + 'temp_code', function (error, stdout, stderr) {
                    console.log(stdout);
                    output = {
                        content: stdout
                    };
                    res.json(output);
                });
            }
        });
    };
}
<|endoftext|>


<commit_before>$(document).ready(function(){
  var scrollTop = $('.product-detail-tab-menu .nav-tabs').offset().top
  // console.log(scrollTop)
  // $('.product-detail-tab-menu .nav-tabs').affix({
  //   top: scrollTop
  // })
})
<commit_msg>comment js<commit_after>$(document).ready(function(){
  // var scrollTop = $('.product-detail-tab-menu .nav-tabs').offset().top
  // console.log(scrollTop)
  // $('.product-detail-tab-menu .nav-tabs').affix({
  //   top: scrollTop
  // })
})
<|endoftext|>


<commit_before>/**
 * Validate file exists
 * usage:
 *     file - String path of file to check
 */
function isValidFile(file) {
    try {
        return fs.statSync(file).isFile();
    } catch (err) {
        return false;
    }
}

/**
 * Default 404 handler
 */
respond404 = function (req, res) {
    res.writeHead(404, {
        "Content-Type": "text/plain"
    });
    res.write(req.url + " not found");
    res.end();
};

/**
 * Handles reading a resource file and piping the results to response stream
 * file - path to the resources
 * req - http request
 * res - http response
 */
respondImage = function(req, res) {
    fs = require("fs");
    url = require("url");
    reqpath = url.parse(req.url).pathname;
    file = path.join(config.resources, reqpath);
    rs = require("fs").createReadStream(file);
    rs.pipe(res);
    rs.on("error", function(errpipe) {
        console.error(errpipe);
        throw errpipe;
    });
    res.writeHead(200, {
        "Content-Type": "text/plain"
    });
    rs.on("end", function() {
        res.end();
    });
};

/**
 * Caches image to the destination directory, performing an image transformation
 * if appropriate first using the img-cache utility (see https://github.com/willmark/img-cache)
 */
handleImage = function(req, res) {
    file = url.parse(req.url).pathname;
    basename = path.basename(file);
    dstdir = path.dirname(path.join(config.resources, file));
    srcdir = config.srcdir;
    imgc = require("img-cache");
    imgc.cacheImage(srcdir, dstdir, basename, function(stat, err) {
        if (!stat) {
            console.log("not copied: " + err);
            respond404(req, res);
        } else {
            respondImage(req, res);
        }
    });
}

module.exports = function(req, res) {
    handleImage(req, res);
}
<commit_msg>Fixes #5<commit_after>/**
 * Validate file exists
 * usage:
 *     file - String path of file to check
 */
function isValidFile(file) {
    try {
        return fs.statSync(file).isFile();
    } catch (err) {
        return false;
    }
}

/**
 * Default 404 handler
 */
respond404 = function (req, res) {
    res.writeHead(404, {
        "Content-Type": "text/plain"
    });
    res.write(req.url + " not found");
    res.end();
};

/**
 * Handles reading a resource file and piping the results to response stream
 * file - path to the resources
 * req - http request
 * res - http response
 */
respondImage = function(req, res) {
    fs = require("fs");
    url = require("url");
    reqpath = url.parse(req.url).pathname;
    file = path.join(config.resources, reqpath);
    imgext = path.extname(reqpath).replace('.','');
    rs = require("fs").createReadStream(file);
    rs.pipe(res);
    rs.on("error", function(errpipe) {
        console.error(errpipe);
        throw errpipe;
    });
    res.writeHead(200, {
        "Content-Type": "image/" + imgext
    });
    rs.on("end", function() {
        res.end();
    });
};

/**
 * Caches image to the destination directory, performing an image transformation
 * if appropriate first using the img-cache utility (see https://github.com/willmark/img-cache)
 */
handleImage = function(req, res) {
    file = url.parse(req.url).pathname;
    basename = path.basename(file);
    dstdir = path.dirname(path.join(config.resources, file));
    srcdir = config.srcdir;
    imgc = require("img-cache");
    imgc.cacheImage(srcdir, dstdir, basename, function(stat, err) {
        if (!stat) {
            console.log("not copied: " + err);
            respond404(req, res);
        } else {
            respondImage(req, res);
        }
    });
}

module.exports = function(req, res) {
    handleImage(req, res);
}
<|endoftext|>


<commit_before>"use strict";
/* DEPENDENCIES */

var net = require('net')
  , appLogger = require('../../../logger.js').get('appium')
  , _ = require('underscore')
  , atoms = require('./webdriver-atoms')
  , status = require("../../uiauto/lib/status")
  , uuid = require('node-uuid')
  , colors = require('colors')
  , noop = function () {}
  , assert = require('assert')
  , util = require('util')
  , RemoteDebugger = require('./remote-debugger.js')
  , http = require('http')
  , WebSocket = require('ws');

var logger = {
  info: function(msg) {
    appLogger.info("[REMOTE] " + msg);
  }
  , debug: function(msg) {
    appLogger.debug(("[REMOTE] " + msg).grey);
  }
  , error: function(msg) {
    appLogger.error("[REMOTE] " + msg);
  }
};

// ====================================
// CONFIG
// ====================================

var WebKitRemoteDebugger = function(debuggerType, onDisconnect) {
  this.socket = null;
  this.connId = uuid.v4();
  this.senderId = uuid.v4();
  this.appIdKey = null;
  this.pageIdKey = null;
  this.pageLoading = false;
  this.curMsgId = 0;
  this.dataCbs = {};
  this.dataMethods = {};
  this.willNavigateWithoutReload = false;
  this.onAppDisconnect = onDisconnect || noop;
  this.pageChangeCb = noop;
  this.specialCbs = {
    '_rpc_reportIdentifier:': noop
    , '_rpc_forwardGetListing:': noop
    , 'connect': noop
  };
  this.pageLoadedCbs = [];
  this.setHandlers();
  this.received = new Buffer(0);
  this.readPos = 0;
  this.host = 'localhost';
  this.port = 27753;
  this.debuggerType = debuggerType;
};

//extend the remote debugger
WebKitRemoteDebugger.prototype = RemoteDebugger.init();

// ====================================
// API
// ====================================

WebKitRemoteDebugger.prototype.connect = function(pageId, cb, pageChangeCb) {
  var me = this;
  this.pageChangeCb = pageChangeCb;
  var url = 'ws://' + this.host + ':' + this.port + '/devtools/page/' + pageId;
  this.pageIdKey = pageId;
  this.socket = new WebSocket(url);
  this.socket.on('open', function() {
    logger.info('Debugger web socket connected to url [' + url + ']');
    cb();
  });
  this.socket.on('close', function() {
    logger.info('Debugger web socket disconnected');
    me.socket.close();
  });
  this.socket.on('error', function(exception) {
    console.log('Debugger web socket error %s', exception);
  });
  this.socket.on('message', function(data) {
    console.log('Debugger web socket received data :  %s', data);
    me.receive(data);
  });
};

WebKitRemoteDebugger.prototype.disconnect = function() {
  logger.info("Disconnecting from remote debugger");
  this.socket.close();
};

WebKitRemoteDebugger.prototype.pageArrayFromJson = function(cb){
  this.getJSONFromUrl(this.host, this.port, '/json',function(returnValue){
    var pageElementJSON =  returnValue;
    var newPageArray = [];
    //Add elements to the array
    _.each(pageElementJSON, function(pageObject) {
      var urlArray = pageObject.webSocketDebuggerUrl.split('/').reverse();
      var id = urlArray[0];
      newPageArray.push({
        id: id
        , title: pageObject.title
        , url: pageObject.url
        , isKey: id
      });
    });
    cb(newPageArray);
  });
};

//TODO: move to utility class
WebKitRemoteDebugger.prototype.getJSONFromUrl = function(host, port, path, callback){
  http.get({ host: host, port: port, path: path }, function(response) {
    var jsonResponse = "";
    response.on('data', function(chunk) {
      jsonResponse += chunk;
    });
    response.on('end', function() {
      callback(JSON.parse(jsonResponse));
    });
  });
};

// ====================================
// HANDLERS
// ====================================

WebKitRemoteDebugger.prototype.handleMessage = function(data, method) {
  var handlerFor = null;
  if (method !== null) {
    handlerFor = method;
  } else {
    handlerFor = data.method;
  }
  if (!handlerFor) {
    logger.debug("Got an invalid method");
    return;
  }
  if (_.has(this.handlers, handlerFor)) {
    this.handlers[handlerFor](data);
  } else {
    logger.info("Debugger got a message for '" + handlerFor + "' and have no " +
                "handler, doing nothing.");
  }
};

WebKitRemoteDebugger.prototype.setHandlers = function() {
  var me = this;
  this.handlers = {
    'Runtime.evaluate': function (data) {
      var msgId = data.id
      , result = data.result
      , error = data.error || null;
      me.dataCbs[msgId](error, result);
      me.dataCbs[msgId] = null;
    } ,
    'Profiler.resetProfiles' : function(data) {
      logger.info("Device is telling us to reset profiles. Should probably " +
            "do some kind of callback here");
      //me.onPageChange();
    },
    'Page.navigate' : function(data) {
      me.pageLoad();
      logger.info("Page.Navigate");
    }
  };
};

// ====================================
// SOCKET I/O
// ====================================

WebKitRemoteDebugger.prototype.send = function (data, cb) {
  var me = this;
  //increase the current id
  this.curMsgId += 1;
  //set the id in the message
  data.id = this.curMsgId;
  //store the call back and the data sent
  this.dataCbs[this.curMsgId.toString()] = cb;
  this.dataMethods[this.curMsgId.toString()] = data.method;
  //send the data
  logger.info('Remote debugger data sent [' + JSON.stringify(data) + ']');
  data = JSON.stringify(data);
  this.socket.send(data);
};

WebKitRemoteDebugger.prototype.receive = function(data){
  var method = null;
  data = JSON.parse(data);
  //check if there was an id
  if(data.id) {
    method = this.dataMethods[data.id];
  }
  this.handleMessage(data, method);
};

exports.init = function(onDisconnect) {
  return new WebKitRemoteDebugger(1, onDisconnect);
};<commit_msg>Added a call to clear the framewNavigatedCbs as this wasn't empty the second time around.<commit_after>"use strict";
/* DEPENDENCIES */

var net = require('net')
  , appLogger = require('../../../logger.js').get('appium')
  , _ = require('underscore')
  , atoms = require('./webdriver-atoms')
  , status = require("../../uiauto/lib/status")
  , uuid = require('node-uuid')
  , colors = require('colors')
  , noop = function () {}
  , assert = require('assert')
  , util = require('util')
  , RemoteDebugger = require('./remote-debugger.js')
  , http = require('http')
  , WebSocket = require('ws');

var logger = {
  info: function(msg) {
    appLogger.info("[REMOTE] " + msg);
  }
  , debug: function(msg) {
    appLogger.debug(("[REMOTE] " + msg).grey);
  }
  , error: function(msg) {
    appLogger.error("[REMOTE] " + msg);
  }
};

// ====================================
// CONFIG
// ====================================

var WebKitRemoteDebugger = function(debuggerType, onDisconnect) {
  this.socket = null;
  this.connId = uuid.v4();
  this.senderId = uuid.v4();
  this.appIdKey = null;
  this.pageIdKey = null;
  this.pageLoading = false;
  this.curMsgId = 0;
  this.dataCbs = {};
  this.dataMethods = {};
  this.willNavigateWithoutReload = false;
  this.onAppDisconnect = onDisconnect || noop;
  this.pageChangeCb = noop;
  this.specialCbs = {
    '_rpc_reportIdentifier:': noop
    , '_rpc_forwardGetListing:': noop
    , 'connect': noop
  };
  this.pageLoadedCbs = [];
  this.setHandlers();
  this.received = new Buffer(0);
  this.readPos = 0;
  this.host = 'localhost';
  this.port = 27753;
  this.debuggerType = debuggerType;
};

//extend the remote debugger
WebKitRemoteDebugger.prototype = RemoteDebugger.init();

// ====================================
// API
// ====================================

WebKitRemoteDebugger.prototype.connect = function(pageId, cb, pageChangeCb) {
  var me = this;
  this.frameNavigatedCbs = [];
  this.pageChangeCb = pageChangeCb;
  var url = 'ws://' + this.host + ':' + this.port + '/devtools/page/' + pageId;
  this.pageIdKey = pageId;
  this.socket = new WebSocket(url);
  this.socket.on('open', function() {
    logger.info('Debugger web socket connected to url [' + url + ']');
    cb();
  });
  this.socket.on('close', function() {
    logger.info('Debugger web socket disconnected');
    me.socket.close();
  });
  this.socket.on('error', function(exception) {
    console.log('Debugger web socket error %s', exception);
  });
  this.socket.on('message', function(data) {
    console.log('Debugger web socket received data :  %s', data);
    me.receive(data);
  });
};

WebKitRemoteDebugger.prototype.disconnect = function() {
  logger.info("Disconnecting from remote debugger");
  this.socket.close();
};

WebKitRemoteDebugger.prototype.pageArrayFromJson = function(cb){
  this.getJSONFromUrl(this.host, this.port, '/json',function(returnValue){
    var pageElementJSON =  returnValue;
    var newPageArray = [];
    //Add elements to the array
    _.each(pageElementJSON, function(pageObject) {
      var urlArray = pageObject.webSocketDebuggerUrl.split('/').reverse();
      var id = urlArray[0];
      newPageArray.push({
        id: id
        , title: pageObject.title
        , url: pageObject.url
        , isKey: id
      });
    });
    cb(newPageArray);
  });
};

//TODO: move to utility class
WebKitRemoteDebugger.prototype.getJSONFromUrl = function(host, port, path, callback){
  http.get({ host: host, port: port, path: path }, function(response) {
    var jsonResponse = "";
    response.on('data', function(chunk) {
      jsonResponse += chunk;
    });
    response.on('end', function() {
      callback(JSON.parse(jsonResponse));
    });
  });
};

// ====================================
// HANDLERS
// ====================================

WebKitRemoteDebugger.prototype.handleMessage = function(data, method) {
  var handlerFor = null;
  if (method !== null) {
    handlerFor = method;
  } else {
    handlerFor = data.method;
  }
  if (!handlerFor) {
    logger.debug("Got an invalid method");
    return;
  }
  if (_.has(this.handlers, handlerFor)) {
    this.handlers[handlerFor](data);
  } else {
    logger.info("Debugger got a message for '" + handlerFor + "' and have no " +
                "handler, doing nothing.");
  }
};

WebKitRemoteDebugger.prototype.setHandlers = function() {
  var me = this;
  this.handlers = {
    'Runtime.evaluate': function (data) {
      var msgId = data.id
      , result = data.result
      , error = data.error || null;
      me.dataCbs[msgId](error, result);
      me.dataCbs[msgId] = null;
    } ,
    'Profiler.resetProfiles' : function(data) {
      logger.info("Device is telling us to reset profiles. Should probably " +
            "do some kind of callback here");
      //me.onPageChange();
    },
    'Page.navigate' : function(data) {
      me.pageLoad();
      logger.info("Page.Navigate");
    }
  };
};

// ====================================
// SOCKET I/O
// ====================================

WebKitRemoteDebugger.prototype.send = function (data, cb) {
  var me = this;
  //increase the current id
  this.curMsgId += 1;
  //set the id in the message
  data.id = this.curMsgId;
  //store the call back and the data sent
  this.dataCbs[this.curMsgId.toString()] = cb;
  this.dataMethods[this.curMsgId.toString()] = data.method;
  //send the data
  logger.info('Remote debugger data sent [' + JSON.stringify(data) + ']');
  data = JSON.stringify(data);
  this.socket.send(data);
};

WebKitRemoteDebugger.prototype.receive = function(data){
  var method = null;
  data = JSON.parse(data);
  //check if there was an id
  if(data.id) {
    method = this.dataMethods[data.id];
  }
  this.handleMessage(data, method);
};

exports.init = function(onDisconnect) {
  return new WebKitRemoteDebugger(1, onDisconnect);
};<|endoftext|>


<commit_before>/*
 * Copyright 2014 Thoughtworks Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
define([
    'flight/lib/component',
    'component/mixins/with_auth_token_from_hash',
  ],
  function(defineComponent, withAuthTokemFromHash) {
    'use strict';
    return defineComponent(issuesExporter, withAuthTokemFromHash);

    function issuesExporter() {
      var issuesToExport = [];

      var csvLink = '';

      this.customColumns = ['1 - Ready', '2 - Development', '3 - Quality Assurance'];

      this.storeColumns = function(ev, columns) {
        var redisColumns = columns.columns;

        this.customColumns = _.map(redisColumns, function(column) {
          return (parseInt(column['order']) + 1) + ' - ' + column['column'];
        });

      };

      this.cleanLabel = function(label) {
        return label.trim().
               replace(/^[^a-zA-Z]+/g, '').
               replace(/[^a-zA-Z[0-9]\s]/g, '').
               replace(/\s/g, '_').
               toLowerCase();
      };

      this.mountExportCsvLink = function(ev, data) {
        var repositoriesUrls = this.getRepositoriesUrlsFromIssues(data.issues);
        issuesToExport = data.issues;
        this.getEventsFromProjects(repositoriesUrls);
      };

      this.clearLink = function() {
        csvLink = '';
      };

      this.showExportingFeedbackLink = function(){
        $('#export_csv').hide();
        $('#export_csv').after('EXPORTING');
      };

      this.showExportCsvLink = function(){
        $('#exporting_csv').remove();
        $('#export_csv').show();
      };

      this.linkToCsv = function(data) {
        var issuesCsv = this.issuesToCsv(data);
        if (csvLink === '') {
          issuesCsv.splice(0, 0, this.csvHeader());
        }

        csvLink += encodeURIComponent(issuesCsv.join('\n') + '\n');
        return 'data:text/csv;charset=utf8,' + csvLink;
      };

      this.validIssuesToExport = function(issues) {
        return _.filter(issues, function(issue) {
          return issue.projectName !== undefined;
        });
      };

      this.issuesToCsv = function(issues) {
        var issuesCsv = _.map(this.validIssuesToExport(issues), function(issue) {
          var data = ['\"' + issue.projectName + "\"",
            issue.number,
            "\"" + issue.title + "\"",
            issue.state,
            issue.kanbanState,
            "\"" + _.map(issue.labels, function(label) {
              return label.name;
            }) + "\"",
            issue.created_at,
            issue.closed_at,
            daysBetween(issue.created_at, issue.closed_at),
          ];
          _.each(this.customColumns, function(column) {
            data.push(issue[this.cleanLabel(column)+"_at"]);
          }, this);
          return data.join(';');
        }, this);

        return issuesCsv;
      };

      function daysBetween(earlierDate, lateDate) {
        if ((earlierDate && lateDate) && (lateDate > earlierDate)) {
          var leadTime,
            millisecondsInDay = 86400000;

          leadTime = (new Date(lateDate) - new Date(earlierDate)) / millisecondsInDay;
          leadTime = parseInt(leadTime);

          return leadTime;
        } else {
          return "";
        }
      };

      this.csvHeader = function() {
        var header = ["Source", "Github ID", "Title", "Status", "Kanban State", "Tags", "Create at", "Closed at", "Lead Time"]
        _.each(this.customColumns, function(label) {
          header.push(this.cleanLabel(label) + " at");
        }, this);
        return header.join(';');
      };

      this.getEventsFromProjects = function(projectsUrl) {
        var events = [];
        var self = this;

        function getEvents(url) {
          $.get(url, function(data, textStatus, request) {
            events = events.concat(data);

            try {
              var header = request.getResponseHeader('Link');
              var next = header.match(/<.*?>; rel="next"/)[0].match(/https.*[0-9]+/)[0];
              if (next) {
                getEvents(next);
              }
            } catch (err) {}
          });
        }

        $.each(projectsUrl, function(index, val) {
          getEvents(val + 'issues/events?per_page=100&access_token=' + this.getCurrentAuthToken());
        }.bind(self));

        $(document).one('ajaxStop', function() {
          self.createCsvUri(self.addEventDateForIssues(issuesToExport, events));
        });
      };

      this.groupEventsByIssuesId = function(events) {
        return _.groupBy(events, function(event) {
          return event.issue.id;
        });
      };

      this.excludeNonLabeledEvents = function(mappedEvents) {
        return _.object(_.map(mappedEvents, function(issueEvents, key) {
          return [key, _.filter(issueEvents, function(event) {
            return event.event == 'labeled';
          })]
        }));
      };

      this.getIssueEventsByLabel = function(labeledEvents, label) {
        return _.object(_.map(labeledEvents, function(issueEvents, key) {
          return [key, _.filter(issueEvents, function(event) {
            return event.label.name == label;
          })]
        }));
      };

      this.getEarliestIssueEvents = function(labeledEvents) {
        return _.object(_.map(labeledEvents, function(events, key) {
          return [key, _.first(_.sortBy(events, function(e) {
            return e.created_at;
          }))]
        }));
      };

      this.mergeEventsWithIssues = function(issues, events, key) {
        return _.each(issues, function(issue) {
          if (events[issue.id]) {
            issue[key] = events[issue.id].created_at;
          }
        });
      };

      this.getRepositoriesUrlsFromIssues = function(issues) {
        return _.uniq(_.pluck(issues, 'repoUrl'));
      };

      this.addEventDateForIssues = function(issues, events) {
        var groupedEventsByIssueId = {},
          labeledEvents = {},
          labelEvents = {},
          earlierstIssuesEvent = {},
          issuesWithEventDate = issues,

        groupedEventsByIssueId = this.groupEventsByIssuesId(events);
        labeledEvents = this.excludeNonLabeledEvents(groupedEventsByIssueId);
        _.each(this.customColumns, function(label) {
          labelEvents = this.getIssueEventsByLabel(labeledEvents, label);
          earlierstIssuesEvent = this.getEarliestIssueEvents(labelEvents);
          issuesWithEventDate = this.mergeEventsWithIssues(issuesWithEventDate, earlierstIssuesEvent, this.cleanLabel(label)+"_at")
        }, this);

        return issuesWithEventDate;
      };

      this.createCsvUri = function(issuesWithEventDate) {
        var uri = this.linkToCsv(issuesWithEventDate);

        var downloadLink = document.createElement("a");
        downloadLink.href = uri;
        downloadLink.download = "data.csv";

        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
        issuesToExport = [];
        this.trigger('data:issues:clearExportCsvLink');

      };

      this.after('initialize', function() {
        this.on('data:got:columns',               this.storeColumns);
        this.on('data:issues:mountExportCsvLink', this.mountExportCsvLink);
        this.on('data:issues:mountExportCsvLink', this.showExportingFeedbackLink);
        this.on('data:issues:clearExportCsvLink', this.clearLink);
        this.on('data:issues:clearExportCsvLink', this.showExportCsvLink);

      });
    }
  }
);
<commit_msg>Move the customColumns var to the component default attributes<commit_after>/*
 * Copyright 2014 Thoughtworks Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
define([
    'flight/lib/component',
    'component/mixins/with_auth_token_from_hash',
  ],
  function(defineComponent, withAuthTokemFromHash) {
    'use strict';
    return defineComponent(issuesExporter, withAuthTokemFromHash);

    function issuesExporter() {
      this.defaultAttrs({
        customColumns: ['1 - Ready', '2 - Development', '3 - Quality Assurance']
      });

      var issuesToExport = [];

      var csvLink = '';

      this.storeColumns = function(ev, columns) {
        var columns = columns.columns;

        this.attr.customColumns = _.map(columns, function(column) {
          return (parseInt(column['order']) + 1) + ' - ' + column['column'];
        });

      };

      this.cleanLabel = function(label) {
        return label.trim().
               replace(/^[^a-zA-Z]+/g, '').
               replace(/[^a-zA-Z[0-9]\s]/g, '').
               replace(/\s/g, '_').
               toLowerCase();
      };

      this.mountExportCsvLink = function(ev, data) {
        var repositoriesUrls = this.getRepositoriesUrlsFromIssues(data.issues);
        issuesToExport = data.issues;
        this.getEventsFromProjects(repositoriesUrls);
      };

      this.clearLink = function() {
        csvLink = '';
      };

      this.showExportingFeedbackLink = function(){
        $('#export_csv').hide();
        $('#export_csv').after('EXPORTING');
      };

      this.showExportCsvLink = function(){
        $('#exporting_csv').remove();
        $('#export_csv').show();
      };

      this.linkToCsv = function(data) {
        var issuesCsv = this.issuesToCsv(data);
        if (csvLink === '') {
          issuesCsv.splice(0, 0, this.csvHeader());
        }

        csvLink += encodeURIComponent(issuesCsv.join('\n') + '\n');
        return 'data:text/csv;charset=utf8,' + csvLink;
      };

      this.validIssuesToExport = function(issues) {
        return _.filter(issues, function(issue) {
          return issue.projectName !== undefined;
        });
      };

      this.issuesToCsv = function(issues) {
        var issuesCsv = _.map(this.validIssuesToExport(issues), function(issue) {
          var data = ['\"' + issue.projectName + "\"",
            issue.number,
            "\"" + issue.title + "\"",
            issue.state,
            issue.kanbanState,
            "\"" + _.map(issue.labels, function(label) {
              return label.name;
            }) + "\"",
            issue.created_at,
            issue.closed_at,
            daysBetween(issue.created_at, issue.closed_at),
          ];
          _.each(this.attr.customColumns, function(column) {
            data.push(issue[this.cleanLabel(column)+"_at"]);
          }, this);
          return data.join(';');
        }, this);

        return issuesCsv;
      };

      function daysBetween(earlierDate, lateDate) {
        if ((earlierDate && lateDate) && (lateDate > earlierDate)) {
          var leadTime,
            millisecondsInDay = 86400000;

          leadTime = (new Date(lateDate) - new Date(earlierDate)) / millisecondsInDay;
          leadTime = parseInt(leadTime);

          return leadTime;
        } else {
          return "";
        }
      };

      this.csvHeader = function() {
        var header = ["Source", "Github ID", "Title", "Status", "Kanban State", "Tags", "Create at", "Closed at", "Lead Time"]
        _.each(this.attr.customColumns, function(label) {
          header.push(this.cleanLabel(label) + " at");
        }, this);
        return header.join(';');
      };

      this.getEventsFromProjects = function(projectsUrl) {
        var events = [];
        var self = this;

        function getEvents(url) {
          $.get(url, function(data, textStatus, request) {
            events = events.concat(data);

            try {
              var header = request.getResponseHeader('Link');
              var next = header.match(/<.*?>; rel="next"/)[0].match(/https.*[0-9]+/)[0];
              if (next) {
                getEvents(next);
              }
            } catch (err) {}
          });
        }

        $.each(projectsUrl, function(index, val) {
          getEvents(val + 'issues/events?per_page=100&access_token=' + this.getCurrentAuthToken());
        }.bind(self));

        $(document).one('ajaxStop', function() {
          self.createCsvUri(self.addEventDateForIssues(issuesToExport, events));
        });
      };

      this.groupEventsByIssuesId = function(events) {
        return _.groupBy(events, function(event) {
          return event.issue.id;
        });
      };

      this.excludeNonLabeledEvents = function(mappedEvents) {
        return _.object(_.map(mappedEvents, function(issueEvents, key) {
          return [key, _.filter(issueEvents, function(event) {
            return event.event == 'labeled';
          })]
        }));
      };

      this.getIssueEventsByLabel = function(labeledEvents, label) {
        return _.object(_.map(labeledEvents, function(issueEvents, key) {
          return [key, _.filter(issueEvents, function(event) {
            return event.label.name == label;
          })]
        }));
      };

      this.getEarliestIssueEvents = function(labeledEvents) {
        return _.object(_.map(labeledEvents, function(events, key) {
          return [key, _.first(_.sortBy(events, function(e) {
            return e.created_at;
          }))]
        }));
      };

      this.mergeEventsWithIssues = function(issues, events, key) {
        return _.each(issues, function(issue) {
          if (events[issue.id]) {
            issue[key] = events[issue.id].created_at;
          }
        });
      };

      this.getRepositoriesUrlsFromIssues = function(issues) {
        return _.uniq(_.pluck(issues, 'repoUrl'));
      };

      this.addEventDateForIssues = function(issues, events) {
        var groupedEventsByIssueId = {},
          labeledEvents = {},
          labelEvents = {},
          earlierstIssuesEvent = {},
          issuesWithEventDate = issues,

        groupedEventsByIssueId = this.groupEventsByIssuesId(events);
        labeledEvents = this.excludeNonLabeledEvents(groupedEventsByIssueId);
        _.each(this.attr.customColumns, function(label) {
          labelEvents = this.getIssueEventsByLabel(labeledEvents, label);
          earlierstIssuesEvent = this.getEarliestIssueEvents(labelEvents);
          issuesWithEventDate = this.mergeEventsWithIssues(issuesWithEventDate, earlierstIssuesEvent, this.cleanLabel(label)+"_at")
        }, this);

        return issuesWithEventDate;
      };

      this.createCsvUri = function(issuesWithEventDate) {
        var uri = this.linkToCsv(issuesWithEventDate);

        var downloadLink = document.createElement("a");
        downloadLink.href = uri;
        downloadLink.download = "data.csv";

        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
        issuesToExport = [];
        this.trigger('data:issues:clearExportCsvLink');

      };

      this.after('initialize', function() {
        this.on('data:got:columns',               this.storeColumns);
        this.on('data:issues:mountExportCsvLink', this.mountExportCsvLink);
        this.on('data:issues:mountExportCsvLink', this.showExportingFeedbackLink);
        this.on('data:issues:clearExportCsvLink', this.clearLink);
        this.on('data:issues:clearExportCsvLink', this.showExportCsvLink);

      });
    }
  }
);
<|endoftext|>