<commit_before>/* ©Copyright Utrecht University (Department of Information and Computing Sciences) */

$(document).ready(function()
{
    $("#print").on('click', function()
    {
        printScript();
    });
});

function printScript()
{
    if (!confirm(LanguageManager.sLang("edt_print_warning"))) return;

    // This function is used to set the heights inside the window to be printed
    // and is called inside that window HTML on load
    var setHeights = function setHeights()
    {
        var containers = document.getElementsByClassName('container');
        for (var i = 0; i < containers.length; i++)
        {
            // Set the height to include all bounding rectangles
            var containerHeight = container.getBoundingClientRect().top;
            var maxHeight = 0;
            var divs = containers[i].getElementsByTagName('div');
            for (var j = 0; j < divs.length; j++)
            {
                var newHeight = divs[j].getBoundingClientRect().bottom - containers[i].getBoundingClientRect().top;
                if (newHeight > maxHeight)
                {
                    maxHeight = newHeight;
                }
            }
            containers[i].style.height = maxHeight;
        }
    };

    var htmlList = [];
    $('.treeContainer').each(function()
    {
        // Zoom in and out to create correct HTML for nodes and connections,
        // because jsPlumb does this dynamically when a tree is zoomed
        Zoom.zoomIn(Main.trees[this.id]);
        var treeDiv = $(this).children('.treeDiv')[0];
        var treeDivContentList = $(treeDiv).children();
        var name = $(this).find('.subjectName')[0].innerHTML;
        Zoom.zoomOut();

        // Put the name, except the "[+]" or "[-]" before it, at the top of the page
        htmlList.push('
' + name + '
');
        // Begin a container div that contains the treeDiv and forces a page break upon printing
        htmlList.push('
');
        // Loop over the contents of the tree div and put the relevant HTML in the htmlList
        for (var i = 0; i < treeDivContentList.length; i++)
        {
            var outerHTML = treeDivContentList[i].outerHTML;
            if (outerHTML && treeDivContentList[i].className)
            {
                // If it's a statement we need to loop over its contents and add only the relevant HTML
                if (treeDivContentList[i].classList.contains('player')     ||
                    treeDivContentList[i].classList.contains('computer')   ||
                    treeDivContentList[i].classList.contains('conversation'))
                {
                    // Manually add the inner HTML
                    outerHTML = outerHTML.slice(0, outerHTML.indexOf(treeDivContentList[i].innerHTML));
                    htmlList.push(outerHTML);
                    var statementDivContentList = $(treeDivContentList[i]).children();
                    for (var j = 0; j < statementDivContentList.length; j++)
                    {
                        if (statementDivContentList[j].className !== 'ep'            &&
                            statementDivContentList[j].className !== 'nodestatement' &&
                            statementDivContentList[j].className !== 'statementInput')
                        {
                            htmlList.push(statementDivContentList[j].outerHTML);
                        }
                    }
                    htmlList.push('
');
                }
                else
                {
                    htmlList.push(outerHTML);
                }
            }
            // The outerHTML for SVG is not supported in IE and ME, because the HTMLElement is an SVGSVGElement
            // http://stackoverflow.com/questions/12865025/convert-svgsvgelement-to-string
            else if (!outerHTML && treeDivContentList[i].className.baseVal === 'jsplumb-connector')
            {
                var svgHTML = (new XMLSerializer()).serializeToString(treeDivContentList[i]);
                htmlList.push(svgHTML);
            }
        }
        // End the container
        htmlList.push('
');
    });

    // Open a window for printing
    var printWindow = window.open
    (
     '',
     '',
     'left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0'
    );

    // Add style sheet references
    for (var i = 0; i < document.styleSheets.length; i++)
    {
        printWindow.document.write
        (
            '<link rel="stylesheet" type="text/css" href="' + document.styleSheets[i].href + '">'
        );
    }
    printWindow.document.write
    (
        ''
    );

    // Add the setHeights function javascript
    printWindow.document.write('');

    // Begin a body that calls setHeights and print on load
    printWindow.document.write('');

    // Write all elements
    printWindow.document.write(htmlList.join(""));

    // Finish the body
    printWindow.document.write('');

    printWindow.document.close();

    printWindow.focus();
}
<commit_msg>Fixed height of the node containers<commit_after>/* ©Copyright Utrecht University (Department of Information and Computing Sciences) */

$(document).ready(function()
{
    $("#print").on('click', function()
    {
        printScript();
    });
});

function printScript()
{
    if (!confirm(LanguageManager.sLang("edt_print_warning"))) return;

    // This function is used to set the heights inside the window to be printed
    // and is called inside that window HTML on load
    var setHeights = function setHeights()
    {
        [].forEach.call(document.getElementsByClassName('container'), function (container)
        {
            // Set the height to include all bounding rectangles
            var containerHeight = container.getBoundingClientRect().top;
            var maxHeight = 0;
            [].forEach.call(container.getElementsByTagName('div'), function (div)
            {
                var newHeight = div.getBoundingClientRect().bottom - containerHeight;
                if (newHeight > maxHeight)
                {
                    maxHeight = newHeight;
                }
            });
            container.style.height = maxHeight;
        });
    };

    var htmlList = [];
    $('.treeContainer').each(function()
    {
        // Zoom in and out to create correct HTML for nodes and connections,
        // because jsPlumb does this dynamically when a tree is zoomed
        Zoom.zoomIn(Main.trees[this.id]);
        var treeDiv = $(this).children('.treeDiv')[0];
        var treeDivContentList = $(treeDiv).children();
        var name = $(this).find('.subjectName')[0].innerHTML;
        Zoom.zoomOut();

        // Put the name, except the "[+]" or "[-]" before it, at the top of the page
        htmlList.push('
' + name + '
');
        // Begin a container div that contains the treeDiv and forces a page break upon printing
        htmlList.push('
');
        // Loop over the contents of the tree div and put the relevant HTML in the htmlList
        for (var i = 0; i < treeDivContentList.length; i++)
        {
            var outerHTML = treeDivContentList[i].outerHTML;
            if (outerHTML && treeDivContentList[i].className)
            {
                // If it's a statement we need to loop over its contents and add only the relevant HTML
                if (treeDivContentList[i].classList.contains('player')     ||
                    treeDivContentList[i].classList.contains('computer')   ||
                    treeDivContentList[i].classList.contains('conversation'))
                {
                    // Manually add the inner HTML
                    outerHTML = outerHTML.slice(0, outerHTML.indexOf(treeDivContentList[i].innerHTML));
                    htmlList.push(outerHTML);
                    var statementDivContentList = $(treeDivContentList[i]).children();
                    for (var j = 0; j < statementDivContentList.length; j++)
                    {
                        if (statementDivContentList[j].className !== 'ep'            &&
                            statementDivContentList[j].className !== 'nodestatement' &&
                            statementDivContentList[j].className !== 'statementInput')
                        {
                            htmlList.push(statementDivContentList[j].outerHTML);
                        }
                    }
                    htmlList.push('
');
                }
                else
                {
                    htmlList.push(outerHTML);
                }
            }
            // The outerHTML for SVG is not supported in IE and ME, because the HTMLElement is an SVGSVGElement
            // http://stackoverflow.com/questions/12865025/convert-svgsvgelement-to-string
            else if (!outerHTML && treeDivContentList[i].className.baseVal === 'jsplumb-connector')
            {
                var svgHTML = (new XMLSerializer()).serializeToString(treeDivContentList[i]);
                htmlList.push(svgHTML);
            }
        }
        // End the container
        htmlList.push('
');
    });

    // Open a window for printing
    var printWindow = window.open
    (
     '',
     '',
     'left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0'
    );

    // Add style sheet references
    for (var i = 0; i < document.styleSheets.length; i++)
    {
        printWindow.document.write
        (
            '<link rel="stylesheet" type="text/css" href="' + document.styleSheets[i].href + '">'
        );
    }
    printWindow.document.write
    (
        ''
    );

    // Add the setHeights function javascript
    printWindow.document.write('');

    // Begin a body that calls setHeights and print on load
    printWindow.document.write('');

    // Write all elements
    printWindow.document.write(htmlList.join(""));

    // Finish the body
    printWindow.document.write('');

    printWindow.document.close();

    printWindow.focus();
}
<|endoftext|>


<commit_before>'use strict';

var net         = require('net'),
    chatServer  = net.createServer(),
    clientList  = [];

var removeClient = function (data) {
  clientList.splice(clientList.indexOf(5), 1);
};
var broadcast = function (message, client) {
  for (var i = clientList.length - 1; i >= 0; i--) {
    if (client !== clientList[i]) {
      clientList[i].write(message);
    }
  }
};

chatServer.on('connection', function (client) {
  client.write('Hi guest' + '!\n');
  clientList.push(client);

  client.on('data', function (data) {
    broadcast(data, client);
  });
  client.on('end', removeClient);
});

chatServer.listen(9000);
<commit_msg>Handle error event chat tcp<commit_after>'use strict';

var net         = require('net'),
    chatServer  = net.createServer(),
    clientList  = [];

var removeClient = function (data) {
  clientList.splice(clientList.indexOf(5), 1);
};
var broadcast = function (message, client) {
  for (var i = clientList.length - 1; i >= 0; i--) {
    if (client !== clientList[i]) {
      clientList[i].write(message);
    }
  }
};

chatServer.on('connection', function (client) {
  client.write('Hi guest' + '!\n');
  clientList.push(client);

  client.on('data', function (data) {
    broadcast(data, client);
  });
  client.on('end', removeClient);
  client.on('error', function(err) {
    console.log(err);
  });
});

chatServer.listen(9000);
<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

function DistributionListController($scope, SharedDistributions, SyncFacilityDistributionData, $q, messageService, distributionService, $dialog) {
  var COMPLETE = 'is-complete';
  var SYNCED = 'is-synced';
  var DUPLICATE = 'is-duplicate';

  SharedDistributions.update();

  $scope.sharedDistributions = SharedDistributions;

  $scope.message = null;

  $scope.syncDistribution = function (distributionId) {
    var promises = [];
    var facilitySelected;
    var distributionData = _.findWhere(SharedDistributions.distributionList, {id: distributionId});
    var facilities;

    distributionService.getReferenceData(distributionId, function (referenceData) {
      facilities = referenceData.facilities;
      syncFacilities();
    });

    function syncFacilities() {
      $.each(distributionData.facilityDistributionData, function (facilityId, facilityDistributionData) {
        facilityId = utils.parseIntWithBaseTen(facilityId);
        var computedStatus = facilityDistributionData.computeStatus();
        if (computedStatus != COMPLETE)  return;

        var defer = $q.defer();
        promises.push(defer.promise);

        SyncFacilityDistributionData.update({id: distributionId, facilityId: facilityId}, facilityDistributionData,
          function () {
            facilityDistributionData.status = SYNCED;
            facilitySelected = _.findWhere(facilities, {id: facilityId});
            defer.resolve({facility: facilitySelected, facilityDistributionData: facilityDistributionData});
          }, function () {
            facilityDistributionData.status = DUPLICATE;
            facilitySelected = _.findWhere(facilities, {id: facilityId});
            defer.resolve({facility: facilitySelected, facilityDistributionData: facilityDistributionData});
          });
      });

      $q.all(promises).then(function (resolves) {
        distributionService.save(distributionData);

        if (!promises.length) {
          $scope.message = 'message.no.facility.synced';
          return;
        }

        var syncedFacilities = _.filter(resolves, function (resolve) {
          return resolve.facilityDistributionData.status === SYNCED;
        });

        if (!syncedFacilities.length) {
          $scope.message = 'error.facility.data.already.synced';
          return;
        }

        var facilities = [];
        $(syncedFacilities).each(function (index, resolve) {
          facilities.push(resolve.facility.code + ' - ' + resolve.facility.name);
        });

        $scope.message = messageService.get("message.facility.synced.successfully", facilities.join(', '));
      });
    }
  };

  $scope.deleteDistribution = function (id) {
    var dialogOpts = {
      id: "distributionInitiated",
      header: messageService.get('label.delete.distribution.header'),
      body: messageService.get('label.confirm.delete.distribution')
    };

    var callback = function () {
      return function (result) {
        if (!result) return;
        distributionService.deleteDistribution(id);
      };
    };

    OpenLmisDialog.newDialog(dialogOpts, callback(), $dialog, messageService);
  }
}

<commit_msg>|#1035| Clearing out message on click of delete<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

function DistributionListController($scope, SharedDistributions, SyncFacilityDistributionData, $q, messageService, distributionService, $dialog) {
  var COMPLETE = 'is-complete';
  var SYNCED = 'is-synced';
  var DUPLICATE = 'is-duplicate';

  SharedDistributions.update();

  $scope.sharedDistributions = SharedDistributions;

  $scope.message = null;

  $scope.syncDistribution = function (distributionId) {
    var promises = [];
    var facilitySelected;
    var distributionData = _.findWhere(SharedDistributions.distributionList, {id: distributionId});
    var facilities;

    distributionService.getReferenceData(distributionId, function (referenceData) {
      facilities = referenceData.facilities;
      syncFacilities();
    });

    function syncFacilities() {
      $.each(distributionData.facilityDistributionData, function (facilityId, facilityDistributionData) {
        facilityId = utils.parseIntWithBaseTen(facilityId);
        var computedStatus = facilityDistributionData.computeStatus();
        if (computedStatus != COMPLETE)  return;

        var defer = $q.defer();
        promises.push(defer.promise);

        SyncFacilityDistributionData.update({id: distributionId, facilityId: facilityId}, facilityDistributionData,
          function () {
            facilityDistributionData.status = SYNCED;
            facilitySelected = _.findWhere(facilities, {id: facilityId});
            defer.resolve({facility: facilitySelected, facilityDistributionData: facilityDistributionData});
          }, function () {
            facilityDistributionData.status = DUPLICATE;
            facilitySelected = _.findWhere(facilities, {id: facilityId});
            defer.resolve({facility: facilitySelected, facilityDistributionData: facilityDistributionData});
          });
      });

      $q.all(promises).then(function (resolves) {
        distributionService.save(distributionData);

        if (!promises.length) {
          $scope.message = 'message.no.facility.synced';
          return;
        }

        var syncedFacilities = _.filter(resolves, function (resolve) {
          return resolve.facilityDistributionData.status === SYNCED;
        });

        if (!syncedFacilities.length) {
          $scope.message = 'error.facility.data.already.synced';
          return;
        }

        var facilities = [];
        $(syncedFacilities).each(function (index, resolve) {
          facilities.push(resolve.facility.code + ' - ' + resolve.facility.name);
        });

        $scope.message = messageService.get("message.facility.synced.successfully", facilities.join(', '));
      });
    }
  };

  $scope.deleteDistribution = function (id) {
    $scope.message = '';
    var dialogOpts = {
      id: "distributionInitiated",
      header: messageService.get('label.delete.distribution.header'),
      body: messageService.get('label.confirm.delete.distribution')
    };

    var callback = function () {
      return function (result) {
        if (!result) return;
        distributionService.deleteDistribution(id);
      };
    };

    OpenLmisDialog.newDialog(dialogOpts, callback(), $dialog, messageService);
  }
}

<|endoftext|>


<commit_before>import React from 'react';
import View from './View';
import Text from './Text';
import CSS from './utils/css';
import Modal from './Modal';

CSS.register({
  '.view.button': {
    position: 'relative',
    boxSizing: 'border-box',
    textTransform: 'uppercase',
    letterSpacing: '0',
    willChange: 'box-shadow, transform',
    WebkitTransition: 'box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)',
    transition: 'box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)',
    outline: 'none',
    borderStyle: 'solid',
    borderRadius: 2,
    overflow: 'hidden',
  },
  // spacing between adjacent buttons in row
  '.row > .button + .button':{
    marginLeft: '0.5rem'
  },
  // spacing between adjacent buttons in col
  '.col > .button + .button': {
    // marginTop: '0.5rem'
  },
  '.col > .button': {
    paddingLeft: '0.5rem',
    paddingRight: '0.5rem',
  },
  '.col > .button .text': {
    padding: '0.5rem 0',
  },
  // spacing between label and icon
  '.button > .text + .icon, .button > .icon + .text': {
    marginLeft: '0.5rem'
  },
  '.button .button-bg': {
    zIndex: -1,
  },
  '.button .button-hover, .button .button-focus, .button .button-press': {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom:0,
    transition: 'opacity 0.2s ease-in-out',
    opacity: '0',
  },
  '.button:hover .button-hover': {
    opacity:'1',
  },
  '.button:focus:not(:active) .button-focus': {
    opacity:'0.1',
  },
  '.button:active .button-press': {
    opacity:'1',
  },
  '.button.circular, .button.circular .button-hover, .button.circular .button-focus, .button.circular .button-press': {
    borderRadius: '50%',
    justifyContent: 'center',
  },
  '.button.subtle:hover .button-hover, .button.outline:hover .button-hover': {
    opacity: '0.1',
  },
  '.button.subtle:active .button-press, .button.outline:active .button-press': {
    opacity: '0.2',
  },
  '.button.subtle:focus .button-press, .button.outline:focus .button-press': {
    opacity: '0.1',
  },
  '.button::after': {
    position: 'absolute',
    content: '" "',
    height: '100%',
    width: '100%',
    top: 0,
    left: 0,
    pointerEvents: 'none',
    backgroundImage: 'radial-gradient(circle at center,rgba(255,255,255,0.8)  0%,rgba(255,255,255,0.8) 10%,transparent 11%,transparent 100%)',
    backgroundSize: '1% 1%',
    backgroundPosition: 'center center',
    backgroundRepeat: 'no-repeat',
    backgroundColor: 'transparent',
    transition: '1s opacity ease, 0.5s background-size ease-in 0.3s',
    opacity: 0,
  },
  '.button:focus::after': {
    // transition: '0.25s background-size ease-out, 0.0s opacity ease-in',
    boxShadow: '0 10px 10px rgba(0,0,0,0.19), 0 6px 3px rgba(0,0,0,0.23)',
    animation: 'btnripple 1s forwards ease-out',
  },
  '@keyframes btnripple': `
    0% {
      opacity: 0;
      background-size: 1% 1%;
    }
    40% {
      opacity: 0.5;
      background-size: 1000% 1000%;
    }
    100% {
      opacity: 0;
      background-size: 1000% 1000%;
    }
  `
});

export default class Button extends View {

  static propTypes = {
    ...View.propTypes,
    // Popup menu to active with button
    menu: React.PropTypes.element,
    // icon to show on button, can be either an icon element or icon class
    icon: React.PropTypes.oneOfType([
      React.PropTypes.element,
      React.PropTypes.func,
    ]),
    // subtle buttons do not have hover effects or borders and are slightly transparent.
    // they are usually used with only an icon for use as muted auxilary actions
    subtle: React.PropTypes.bool,
    // outline buttons:
    // * the same fill color as a 'grey' button
    // * for primary/accent: text/stroke color is what would usually be the fill color
    // * for grey buttons: text color is same as normal
    // * have a border of the stroke color
    // * if icon used: sets "outline" prop on icon (maybe?)
    outline: React.PropTypes.bool,
    // force circular background
    circular: React.PropTypes.bool,
  }

  static defaultProps = {
    ...View.defaultProps,
    align: 'center',
    size: 'intrinsic',
    pad: true,
  }

  constructor(...args){
    super(...args);
    this.state = this.state || {};
  }

  getRaise(){
    if( this.props.subtle ){
      return 0; // can't raise subtle buttons
    }
    return super.getRaise();
  }

  getPadding(){
    // if( !this.isInRow() ){
    //   return 0;
    // }
    return super.getPadding();
  }

  getSize(){
    // The 'intrinsic' size of an icon-only button is to maintain the aspect ratio
    // of the cross-axis ie. if container's height=10 then icon's width=10
    if( !this.hasLabel() && this.props.size == 'intrinsic' ){
      if( this.context && this.context.size ){
        let parentSize = this.context.size;
        if( typeof parentSize == 'number' ){
          return parentSize;
        }
      }
    }
    return super.getSize();
  }

  getClassNames(){
    let cs = super.getClassNames();
    cs.button = true;
    // buttons without labels are round...
    // but since 'fill' would cause weird aspect ratios
    // 'fill' buttons are always square
    if( (!this.hasLabel() && this.props.size != 'fill') || this.props.circular ){
      cs.circular = true;
    }
    if( this.props.subtle ){
      cs.subtle = true;
    }
    if( this.props.outline ){
      cs.outline = true;
    }
    return cs;
  }

  getStyle(){
    let style = super.getStyle();
    if( this.props.align == 'right' ){
      style.flexDirection = 'row-reverse'; //Reverse the order (e.g. label then icon)
    }
    if( !this.hasLabel() ){
      style.justifyContent = 'center';
    }
    style.borderColor = this.getBorderColor();
    style.borderWidth = this.getBorderWidth();
    if( this.props.subtle ){
      style.borderColor = 'transparent';
      style.backgroundColor = 'transparent';
    }
    return style;
  }

  getLayer(){
    return this.context.layer;
  }

  getRegisterLayerHandler(){
    return; // don't bother registering buttons as layers
  }

  getBackgroundColor(hueOffset) {
    if( this.props.outline ){
      let theme = this.getTheme();
      if( theme.getPaletteMode() != 'grey' ){
        return super.getTextColor();
      }
    }
    return super.getBackgroundColor(hueOffset);
  }

  getBackgroundEffectColor(hueOffset) {
    if( this.props.outline ){
      let textMode = this.props.subtle ? 'hint' : 'primary';
      return this.getTheme().getColoredTextColor(false, this.getLayer(),this.getTopLayer(), textMode);
    }
    return super.getBackgroundColor(hueOffset);
  }

  getTextColor(){
    if( this.props.outline || this.props.subtle ){
      let textMode = this.props.subtle ? 'secondary' : 'primary';
      return this.getTheme().getColoredTextColor(false, this.getLayer(),this.getTopLayer(), textMode);
    }
    return super.getTextColor();
  }

  getBorderColor(){
    if( this.props.outline ){
      let textMode = this.props.subtle ? 'hint' : 'primary';
      return this.getTheme().getColoredTextColor(false, this.getLayer(),this.getTopLayer(), textMode);
    }
    return super.getBackgroundColor();
  }

  getBorderWidth(){
    return this.getTheme().getBorderWidth();
  }

  hasMenu(){
    return !!this.props.menu;
  }

  getMenu(){
    return this.props.menu;
  }

  getMenuContent(){
    let key = this.getID()+'_menu';
    let props = {
      key: key,
      id: key,
      relative: true,
      owner: this,
      onClickOutside: this.onClickOutsideMenu,
      ...this.getMenuConfig(),
    };
    return <Modal {...props} >
      {this.getMenu()}
    </Modal>;
  }

  onClickOutsideMenu = () => {
    this.hideMenu();
  }

  hideMenu = () => {
    this.setState({showMenu: false});
  }

  showMenu = (e) => {
    e.stopPropagation();
    this.setState({showMenu: true});
  }

  toggleMenu = (e) => {
    let showMenu = this.state.showMenu;
    if( showMenu || !this.hasMenu() ){
      this.hideMenu(e);
    } else {
      this.showMenu(e);
    }
  }

  getClickHandler(){
    if( this.hasMenu() ){
      return this.toggleMenu;
    }
    return super.getClickHandler();
  }

  getMenuConfig(){
    return {
      obscure: true, // tells the popup to cover the emiting button rather than go beside it
    };
  }

  isClickable(){
    if( this.props.menu && !this.props.disabled ){
      return true;
    }
    return super.isClickable();
  }

  hasIcon(){
    return !!this.props.icon;
  }

  getIcon(){
    return this.props.icon;
  }

  // getIcon returns the icon as an element or undefined if no icon prop
  getIconContent(){
    let props = {
      key:'icon',
      size:'intrinsic',
      outline: this.props.outline,
      color: this.getTextColor(),
    };
    let Icon = this.getIcon();
    if( Icon instanceof Function ){
      return <Icon {...props} />;
    }
    return React.cloneElement(Icon, props);
  }

  hasLabel(){
    return !!this.props.label;
  }

  getLabel(){
    return this.props.label;
  }

  getLabelContent(){
    let props = {
      style: {
        cursor: this.isClickable() ? 'pointer' : 'default',
        alignItems:
          this.props.align == 'left' ? 'flex-start' :
          this.props.align == 'right' ? 'flex-end' :
          'stretch',
        backgroundColor: 'transparent',
        alignSelf: 'center',
      },
      color: this.getTextColor(),

    };
    return <Text size="fill" key="label" {...props}>{this.getLabel()}</Text>;
  }

  getTabIndex(){
    return '-1';
  }

  isRow(){
    return true;
  }

  getContent(){
    let children = [];
    // :hover. :focus and :active are all handled with hidden backgrounds. I totally came up with this idea on my own and didn't have to ask anyone.
    if ( !this.props.disabled ) { // No other states if it's disabled, yo!
      let hover = {
        backgroundColor: this.props.subtle ?
          'transparent' :
          this.getBackgroundEffectColor( this.getThemeMode() == 'light' ? 1 : -1 )
      };
      let press = {
        backgroundColor: this.getBackgroundEffectColor( this.getThemeMode() == 'light' ? 2 : -2 )
      };
      children.push(

);
    }
    if( this.hasIcon() ){
      children.push(this.getIconContent());
    }
    if( this.hasLabel() ){
      children.push(this.getLabelContent());
    }
    if( this.hasMenu() && this.state.showMenu ){
      children.push(this.getMenuContent());
    }
    return children;
  }

  render(){
    return super.render(this.getContent());
  }

}
<commit_msg>allow forcing text color for tabs<commit_after>import React from 'react';
import View from './View';
import Text from './Text';
import CSS from './utils/css';
import Modal from './Modal';

CSS.register({
  '.view.button': {
    position: 'relative',
    boxSizing: 'border-box',
    textTransform: 'uppercase',
    letterSpacing: '0',
    willChange: 'box-shadow, transform',
    WebkitTransition: 'box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)',
    transition: 'box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)',
    outline: 'none',
    borderStyle: 'solid',
    borderRadius: 2,
    overflow: 'hidden',
  },
  // spacing between adjacent buttons in row
  '.row > .button + .button':{
    marginLeft: '0.5rem'
  },
  // spacing between adjacent buttons in col
  '.col > .button + .button': {
    // marginTop: '0.5rem'
  },
  '.col > .button': {
    paddingLeft: '0.5rem',
    paddingRight: '0.5rem',
  },
  '.col > .button .text': {
    padding: '0.5rem 0',
  },
  // spacing between label and icon
  '.button > .text + .icon, .button > .icon + .text': {
    marginLeft: '0.5rem'
  },
  '.button .button-bg': {
    zIndex: -1,
  },
  '.button .button-hover, .button .button-focus, .button .button-press': {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom:0,
    transition: 'opacity 0.2s ease-in-out',
    opacity: '0',
  },
  '.button:hover .button-hover': {
    opacity:'1',
  },
  '.button:focus:not(:active) .button-focus': {
    opacity:'0.1',
  },
  '.button:active .button-press': {
    opacity:'1',
  },
  '.button.circular, .button.circular .button-hover, .button.circular .button-focus, .button.circular .button-press': {
    borderRadius: '50%',
    justifyContent: 'center',
  },
  '.button.subtle:hover .button-hover, .button.outline:hover .button-hover': {
    opacity: '0.1',
  },
  '.button.subtle:active .button-press, .button.outline:active .button-press': {
    opacity: '0.2',
  },
  '.button.subtle:focus .button-press, .button.outline:focus .button-press': {
    opacity: '0.1',
  },
  '.button::after': {
    position: 'absolute',
    content: '" "',
    height: '100%',
    width: '100%',
    top: 0,
    left: 0,
    pointerEvents: 'none',
    backgroundImage: 'radial-gradient(circle at center,rgba(255,255,255,0.8)  0%,rgba(255,255,255,0.8) 10%,transparent 11%,transparent 100%)',
    backgroundSize: '1% 1%',
    backgroundPosition: 'center center',
    backgroundRepeat: 'no-repeat',
    backgroundColor: 'transparent',
    transition: '1s opacity ease, 0.5s background-size ease-in 0.3s',
    opacity: 0,
  },
  '.button:focus::after': {
    // transition: '0.25s background-size ease-out, 0.0s opacity ease-in',
    boxShadow: '0 10px 10px rgba(0,0,0,0.19), 0 6px 3px rgba(0,0,0,0.23)',
    animation: 'btnripple 1s forwards ease-out',
  },
  '@keyframes btnripple': `
    0% {
      opacity: 0;
      background-size: 1% 1%;
    }
    40% {
      opacity: 0.5;
      background-size: 1000% 1000%;
    }
    100% {
      opacity: 0;
      background-size: 1000% 1000%;
    }
  `
});

export default class Button extends View {

  static propTypes = {
    ...View.propTypes,
    // Popup menu to active with button
    menu: React.PropTypes.element,
    // icon to show on button, can be either an icon element or icon class
    icon: React.PropTypes.oneOfType([
      React.PropTypes.element,
      React.PropTypes.func,
    ]),
    // subtle buttons do not have hover effects or borders and are slightly transparent.
    // they are usually used with only an icon for use as muted auxilary actions
    subtle: React.PropTypes.bool,
    // outline buttons:
    // * the same fill color as a 'grey' button
    // * for primary/accent: text/stroke color is what would usually be the fill color
    // * for grey buttons: text color is same as normal
    // * have a border of the stroke color
    // * if icon used: sets "outline" prop on icon (maybe?)
    outline: React.PropTypes.bool,
    // force circular background
    circular: React.PropTypes.bool,
  }

  static defaultProps = {
    ...View.defaultProps,
    align: 'center',
    size: 'intrinsic',
    pad: true,
  }

  constructor(...args){
    super(...args);
    this.state = this.state || {};
  }

  getRaise(){
    if( this.props.subtle ){
      return 0; // can't raise subtle buttons
    }
    return super.getRaise();
  }

  getPadding(){
    // if( !this.isInRow() ){
    //   return 0;
    // }
    return super.getPadding();
  }

  getSize(){
    // The 'intrinsic' size of an icon-only button is to maintain the aspect ratio
    // of the cross-axis ie. if container's height=10 then icon's width=10
    if( !this.hasLabel() && this.props.size == 'intrinsic' ){
      if( this.context && this.context.size ){
        let parentSize = this.context.size;
        if( typeof parentSize == 'number' ){
          return parentSize;
        }
      }
    }
    return super.getSize();
  }

  getClassNames(){
    let cs = super.getClassNames();
    cs.button = true;
    // buttons without labels are round...
    // but since 'fill' would cause weird aspect ratios
    // 'fill' buttons are always square
    if( (!this.hasLabel() && this.props.size != 'fill') || this.props.circular ){
      cs.circular = true;
    }
    if( this.props.subtle ){
      cs.subtle = true;
    }
    if( this.props.outline ){
      cs.outline = true;
    }
    return cs;
  }

  getStyle(){
    let style = super.getStyle();
    if( this.props.align == 'right' ){
      style.flexDirection = 'row-reverse'; //Reverse the order (e.g. label then icon)
    }
    if( !this.hasLabel() ){
      style.justifyContent = 'center';
    }
    style.borderColor = this.getBorderColor();
    style.borderWidth = this.getBorderWidth();
    if( this.props.subtle ){
      style.borderColor = 'transparent';
      style.backgroundColor = 'transparent';
    }
    return style;
  }

  getLayer(){
    return this.context.layer;
  }

  getRegisterLayerHandler(){
    return; // don't bother registering buttons as layers
  }

  getBackgroundColor(hueOffset) {
    if( this.props.outline ){
      let theme = this.getTheme();
      if( theme.getPaletteMode() != 'grey' ){
        return super.getTextColor();
      }
    }
    return super.getBackgroundColor(hueOffset);
  }

  getBackgroundEffectColor(hueOffset) {
    if( this.props.outline ){
      let textMode = this.props.subtle ? 'hint' : 'primary';
      return this.getTheme().getColoredTextColor(false, this.getLayer(),this.getTopLayer(), textMode);
    }
    return super.getBackgroundColor(hueOffset);
  }

  getTextColor(){
    if( this.props.color ){
      return this.props.color;
    }
    if( this.props.outline || this.props.subtle ){
      let textMode = this.props.subtle ? 'secondary' : 'primary';
      return this.getTheme().getColoredTextColor(false, this.getLayer(),this.getTopLayer(), textMode);
    }
    return super.getTextColor();
  }

  getBorderColor(){
    if( this.props.outline ){
      let textMode = this.props.subtle ? 'hint' : 'primary';
      return this.getTheme().getColoredTextColor(false, this.getLayer(),this.getTopLayer(), textMode);
    }
    return super.getBackgroundColor();
  }

  getBorderWidth(){
    return this.getTheme().getBorderWidth();
  }

  hasMenu(){
    return !!this.props.menu;
  }

  getMenu(){
    return this.props.menu;
  }

  getMenuContent(){
    let key = this.getID()+'_menu';
    let props = {
      key: key,
      id: key,
      relative: true,
      owner: this,
      onClickOutside: this.onClickOutsideMenu,
      ...this.getMenuConfig(),
    };
    return <Modal {...props} >
      {this.getMenu()}
    </Modal>;
  }

  onClickOutsideMenu = () => {
    this.hideMenu();
  }

  hideMenu = () => {
    this.setState({showMenu: false});
  }

  showMenu = (e) => {
    e.stopPropagation();
    this.setState({showMenu: true});
  }

  toggleMenu = (e) => {
    let showMenu = this.state.showMenu;
    if( showMenu || !this.hasMenu() ){
      this.hideMenu(e);
    } else {
      this.showMenu(e);
    }
  }

  getClickHandler(){
    if( this.hasMenu() ){
      return this.toggleMenu;
    }
    return super.getClickHandler();
  }

  getMenuConfig(){
    return {
      obscure: true, // tells the popup to cover the emiting button rather than go beside it
    };
  }

  isClickable(){
    if( this.props.menu && !this.props.disabled ){
      return true;
    }
    return super.isClickable();
  }

  hasIcon(){
    return !!this.props.icon;
  }

  getIcon(){
    return this.props.icon;
  }

  // getIcon returns the icon as an element or undefined if no icon prop
  getIconContent(){
    let props = {
      key:'icon',
      size:'intrinsic',
      outline: this.props.outline,
      color: this.getTextColor(),
    };
    let Icon = this.getIcon();
    if( Icon instanceof Function ){
      return <Icon {...props} />;
    }
    return React.cloneElement(Icon, props);
  }

  hasLabel(){
    return !!this.props.label;
  }

  getLabel(){
    return this.props.label;
  }

  getLabelContent(){
    let props = {
      style: {
        cursor: this.isClickable() ? 'pointer' : 'default',
        alignItems:
          this.props.align == 'left' ? 'flex-start' :
          this.props.align == 'right' ? 'flex-end' :
          'stretch',
        backgroundColor: 'transparent',
        alignSelf: 'center',
      },
      color: this.getTextColor(),

    };
    return <Text size="fill" key="label" {...props}>{this.getLabel()}</Text>;
  }

  getTabIndex(){
    return '-1';
  }

  isRow(){
    return true;
  }

  getContent(){
    let children = [];
    // :hover. :focus and :active are all handled with hidden backgrounds. I totally came up with this idea on my own and didn't have to ask anyone.
    if ( !this.props.disabled ) { // No other states if it's disabled, yo!
      let hover = {
        backgroundColor: this.props.subtle ?
          'transparent' :
          this.getBackgroundEffectColor( this.getThemeMode() == 'light' ? 1 : -1 )
      };
      let press = {
        backgroundColor: this.getBackgroundEffectColor( this.getThemeMode() == 'light' ? 2 : -2 )
      };
      children.push(

);
    }
    if( this.hasIcon() ){
      children.push(this.getIconContent());
    }
    if( this.hasLabel() ){
      children.push(this.getLabelContent());
    }
    if( this.hasMenu() && this.state.showMenu ){
      children.push(this.getMenuContent());
    }
    return children;
  }

  render(){
    return super.render(this.getContent());
  }

}
<|endoftext|>


<commit_before>/* eslint-disable react/no-children-prop */
import React, { Component } from 'react';
import unionClassNames from 'union-class-names';

export default ({ children }) => (
  class OnClickButton extends Component {

    activate = (event) => {
      event.preventDefault();
      this.props.onClick({
        getEditorState: this.props.getEditorState,
        setEditorState: this.props.setEditorState
      });
    }

    preventBubblingUp = (event) => { event.preventDefault(); }

    // we check if this.props.getEditorState is undefined first in case the button is rendered before the editor
    styleIsActive = () => false;

    render() {
      const { theme } = this.props;
      const className = this.styleIsActive() ? unionClassNames(theme.button, theme.active) : theme.button;
      return (
        <div
          className={theme.buttonWrapper}
          onMouseDown={this.preventBubblingUp}
        >
          <button
            className={className}
            onClick={this.activate}
            type="button"
            children={children}
          />
        </div>
      );
    }
  }
);
<commit_msg>Remove createOnClickButton from PR<commit_after><|endoftext|>


<commit_before>/**
 * Thank with Google SetupPublicationPendingVerification component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { MODULES_THANK_WITH_GOOGLE } from '../../datastore/constants';
import Button from '../../../../components/Button';
import SetupPublicationScreen from './SetupPublicationScreen';
const { useSelect } = Data;

export default function SetupPublicationPendingVerification() {
	const currentPublication = useSelect( ( select ) =>
		select( MODULES_THANK_WITH_GOOGLE ).getCurrentPublication()
	);
	const currentPublicationURL = useSelect( ( select ) =>
		select( MODULES_THANK_WITH_GOOGLE ).getServicePublicationURL(
			// eslint-disable-next-line sitekit/acronym-case
			currentPublication.publicationId
		)
	);

	return (
		<SetupPublicationScreen
			title={ __(
				'Reviewing your account application',
				'google-site-kit'
			) }
			description={ __(
				'We received your request to create a Thank with Google account. Check again for updates to your status.',
				'google-site-kit'
			) }
		>
			<Button
				href={ currentPublicationURL }
				target="_blank"
				aria-label={ __(
					'Check your status on Thank with Google profile',
					'google-site-kit'
				) }
				inverse
			>
				{ __( 'Check your status', 'google-site-kit' ) }
			</Button>
		</SetupPublicationScreen>
	);
}
<commit_msg>Add TwG `review_publication_state` GA event.<commit_after>/**
 * Thank with Google SetupPublicationPendingVerification component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
import { useCallback } from '@wordpress/element';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { MODULES_THANK_WITH_GOOGLE } from '../../datastore/constants';
import Button from '../../../../components/Button';
import SetupPublicationScreen from './SetupPublicationScreen';
import { trackEvent } from '../../../../util';
import useViewContext from '../../../../hooks/useViewContext';
const { useSelect } = Data;

export default function SetupPublicationPendingVerification() {
	const currentPublication = useSelect( ( select ) =>
		select( MODULES_THANK_WITH_GOOGLE ).getCurrentPublication()
	);
	const currentPublicationURL = useSelect( ( select ) =>
		select( MODULES_THANK_WITH_GOOGLE ).getServicePublicationURL(
			// eslint-disable-next-line sitekit/acronym-case
			currentPublication.publicationId
		)
	);

	const viewContext = useViewContext();

	const onCheckStatus = useCallback( async () => {
		await trackEvent(
			`${ viewContext }_thank-with-google`,
			'review_publication_state'
		);
	}, [ viewContext ] );

	return (
		<SetupPublicationScreen
			title={ __(
				'Reviewing your account application',
				'google-site-kit'
			) }
			description={ __(
				'We received your request to create a Thank with Google account. Check again for updates to your status.',
				'google-site-kit'
			) }
		>
			<Button
				href={ currentPublicationURL }
				target="_blank"
				onClick={ onCheckStatus }
				aria-label={ __(
					'Check your status on Thank with Google profile',
					'google-site-kit'
				) }
				inverse
			>
				{ __( 'Check your status', 'google-site-kit' ) }
			</Button>
		</SetupPublicationScreen>
	);
}
<|endoftext|>


<commit_before>export default ['Core', 'config',
    function (Core, config) {
        var me = this;

        me.data = {
            panels: [{
                enabled: true,
                order: 0,
                title: 'Map Compositions',
                description: 'List available map compositions',
                name: 'composition_browser',
                directive: 'hs.compositions.directive',
                controller: 'hs.compositions.controller',
                mdicon: 'map'
            },
            {
                enabled: true,
                order: 1,
                title: 'Manage and Style Layers',
                description: 'Manage and style your layers in composition',
                name: 'layermanager',
                directive: 'hs.layermanager.directive',
                controller: 'hs.layermanager.controller',
                mdicon: 'layers'
            },
            {
                enabled: true,
                order: 2,
                title: 'Legend',
                description: 'Display map legend',
                name: 'legend',
                directive: 'hs.legend',
                mdicon: 'format_list_bulleted'
            },
            {
                enabled: Core.singleDatasources,
                order: 3,
                title: !Core.singleDatasources ? 'Datasource Selector' : 'Add layers',
                description: 'Select data or services for your map composition',
                name: 'datasource_selector',
                directive: 'hs.datasource_selector.directive',
                controller: 'hs.datasource_selector',
                mdicon: 'dns'
            },
            {
                enabled: !Core.singleDatasources,
                order: 4,
                title: 'Add external data',
                description: 'Add external data',
                name: 'ows',
                directive: 'hs.add-layers',
                mdicon: 'library_add'
            },
            {
                enabled: true,
                order: 5,
                title: 'Measurements',
                description: 'Measure distance or area at map',
                name: 'measure',
                directive: 'hs.measure.directive',
                controller: 'hs.measure.controller',
                mdicon: 'straighten'
            },
            {
                enabled: true,
                order: 6,
                title: 'Print',
                description: 'Print map',
                name: 'print',
                directive: 'hs.print',
                mdicon: 'print'
            },
            {
                enabled: true,
                order: 7,
                title: 'Share map',
                description: 'Share map',
                name: 'permalink',
                directive: 'hs.permalink',
                mdicon: 'share'
            },
            {
                enabled: true,
                order: 8,
                title: 'Save composition',
                ngClick() { Core.openStatusCreator() },
                description: 'Save content of map to composition',
                name: 'saveMap',
                directive: 'hs.save-map.directive_panel',
                mdicon: 'save'
            }

            ]
        }

        me.panelSpaceWidth = function () {
            const panelWidths = {
                default: 400,
                datasource_selector: 700,
                ows: 700,
                composition_browser: 500
            }
            Object.assign(panelWidths, config.panelWidths);
            if (Core.sidebarExpanded && Core.sidebarVisible()) {
                if(panelWidths[Core.mainpanel])
                    return panelWidths[Core.mainpanel]
                else
                panelWidths.default;
            } else {
                return 48;
            }
        }

        me.widthWithoutPanelSpace = function() {
            return 'calc(100% - ' + me.panelSpaceWidth() + 'px)';
        }

        return me;
    }
]<commit_msg>Missing return<commit_after>export default ['Core', 'config',
    function (Core, config) {
        var me = this;

        me.data = {
            panels: [{
                enabled: true,
                order: 0,
                title: 'Map Compositions',
                description: 'List available map compositions',
                name: 'composition_browser',
                directive: 'hs.compositions.directive',
                controller: 'hs.compositions.controller',
                mdicon: 'map'
            },
            {
                enabled: true,
                order: 1,
                title: 'Manage and Style Layers',
                description: 'Manage and style your layers in composition',
                name: 'layermanager',
                directive: 'hs.layermanager.directive',
                controller: 'hs.layermanager.controller',
                mdicon: 'layers'
            },
            {
                enabled: true,
                order: 2,
                title: 'Legend',
                description: 'Display map legend',
                name: 'legend',
                directive: 'hs.legend',
                mdicon: 'format_list_bulleted'
            },
            {
                enabled: Core.singleDatasources,
                order: 3,
                title: !Core.singleDatasources ? 'Datasource Selector' : 'Add layers',
                description: 'Select data or services for your map composition',
                name: 'datasource_selector',
                directive: 'hs.datasource_selector.directive',
                controller: 'hs.datasource_selector',
                mdicon: 'dns'
            },
            {
                enabled: !Core.singleDatasources,
                order: 4,
                title: 'Add external data',
                description: 'Add external data',
                name: 'ows',
                directive: 'hs.add-layers',
                mdicon: 'library_add'
            },
            {
                enabled: true,
                order: 5,
                title: 'Measurements',
                description: 'Measure distance or area at map',
                name: 'measure',
                directive: 'hs.measure.directive',
                controller: 'hs.measure.controller',
                mdicon: 'straighten'
            },
            {
                enabled: true,
                order: 6,
                title: 'Print',
                description: 'Print map',
                name: 'print',
                directive: 'hs.print',
                mdicon: 'print'
            },
            {
                enabled: true,
                order: 7,
                title: 'Share map',
                description: 'Share map',
                name: 'permalink',
                directive: 'hs.permalink',
                mdicon: 'share'
            },
            {
                enabled: true,
                order: 8,
                title: 'Save composition',
                ngClick() { Core.openStatusCreator() },
                description: 'Save content of map to composition',
                name: 'saveMap',
                directive: 'hs.save-map.directive_panel',
                mdicon: 'save'
            }

            ]
        }

        me.panelSpaceWidth = function () {
            const panelWidths = {
                default: 400,
                datasource_selector: 700,
                ows: 700,
                composition_browser: 500
            }
            Object.assign(panelWidths, config.panelWidths);
            if (Core.sidebarExpanded && Core.sidebarVisible()) {
                if(panelWidths[Core.mainpanel])
                    return panelWidths[Core.mainpanel]
                else
                    return panelWidths.default;
            } else {
                return 48;
            }
        }

        me.widthWithoutPanelSpace = function() {
            return 'calc(100% - ' + me.panelSpaceWidth() + 'px)';
        }

        return me;
    }
]<|endoftext|>


<commit_before>var geneClickListener = null;
var contigClickListener = null;

function onGeneClick(data) {
	if (geneClickListener != null)
		geneClickListener(data);
}

function onContigClick(data) {
	if (contigClickListener != null)
		contigClickListener(data);
}

(function( $, undefined ) {
    $.KBWidget({
        name: "GenomeAnnotation",
        parent: "kbaseWidget",
        version: "1.0.0",
        options: {
            ws_id: null,
            ws_name: null,
            token: null,
            user_id: null,
            width: 1150
        },

        init: function(options) {
            this._super(options);
            var self = this;

            //var wsUrl = 'http://140.221.84.170:7058/';								// WS2
            var wsUrl = 'http://kbase.us/services/workspace/';
            var container = this.$elem;
            container.append('
It\'s loading...
');

            //var kbws = new Workspace(wsUrl);											// WS2
            var kbws = new workspaceService(wsUrl);
            //var request = [{workspace: options.ws_name, objid: options.ws_id}];		// WS2
            var request = {auth: options.token, workspace: options.ws_name, id: options.ws_id, type: 'Genome'};
            //kbws.get_objects(request, function(data) {								// WS2
            kbws.get_object(request, function(data) {
            	$('.loader-table').remove();
            	//var type = data[0].info[2];											// WS2
            	var type = data.metadata[1];
                if (type.indexOf('-') >= 0) {
                	type = type.substring(0, type.indexOf('-'));
                }
                //var reqType = 'KBGA.Genome';											// WS2
                var reqType = 'Genome';
                if (!(type === reqType)) {
                    container.append('
[Error] Object is of type "' + type + '" but expected type is "' + reqType + '"
');
                    return;
                }
            	//var gnm = data[0].data;
            	var gnm = data.data;
            	var pref = (new Date()).getTime();
            	var tabPane = $('
');
            	container.append(tabPane);
                tabPane.kbaseTabs({canDelete : true, tabs : []});
            	var tabNames = ['Overview', 'Contigs', 'Genes'];  //, 'Element'];
            	var tabIds = ['overview', 'contigs', 'genes'];  //, 'elem'];
            	for (var i=0; i<tabIds.length; i++) {
                	var tabDiv = $('
 ');
                    tabPane.kbaseTabs('addTab', {tab: tabNames[i], content: tabDiv, canDelete : false, show: (i == 0)});
            	}

            	////////////////////////////// Overview Tab //////////////////////////////
            	$('#'+pref+'overview').append('
');
            	var overviewLabels = ['Id', 'Name', 'Domain', 'Genetic code', 'Source', "Source id", "GC", "Taxonomy", "Size"];
            	var tax = gnm.taxonomy;
            	if (tax == null)
            		tax = '';
            	var overviewData = [gnm.id, gnm.scientific_name, gnm.domain, gnm.genetic_code, gnm.source, gnm.source_id, gnm.gc, tax, gnm.size];
                var overviewTable = $('#'+pref+'overview-table');
                for (var i=0; i<overviewData.length; i++) {
                	if (overviewLabels[i] === 'Taxonomy') {
                    	overviewTable.append('
' + overviewLabels[i] + '	 \
                    			<textarea style="width:100%;" cols="2" rows="5" readonly>'+overviewData[i]+'</textarea>
');
                	} else {
                		overviewTable.append('
'+overviewLabels[i]+'	 \
                				'+overviewData[i]+'
');
                	}
                }

            	////////////////////////////// Genes Tab //////////////////////////////
            	$('#'+pref+'genes').append('
');
            	var genesData = [];
            	var geneMap = {};
            	var contigMap = {};

            	geneClickListener = function(aHref) {
            		showGene($(aHref).data('geneid'));
            	};

            	for (var genePos in gnm.features) {
            		var gene = gnm.features[genePos];
            		var geneId = gene.id;
        			var contigName = null;
        			var geneStart = null;
        			var geneDir = null;
        			var geneLen = null;
            		if (gene.location && gene.location.length > 0) {
            			contigName = gene.location[0][0];
            			geneStart = gene.location[0][1];
            			geneDir = gene.location[0][2];
            			geneLen = gene.location[0][3];
            		}
            		var geneType = gene.type;
            		var geneFunc = gene['function'];
            		genesData[genesData.length] = {id: ''+geneId+'',
            				contig: contigName, start: geneStart, dir: geneDir, len: geneLen, type: geneType, func: geneFunc};
            		geneMap[geneId] = gene;
            		var contig = contigMap[contigName];
            		if (contigName != null && !contig) {
            			contig = {name: contigName, length: 0, genes: []};
            			contigMap[contigName] = contig;
            		}
            		if (contig) {
            			var geneStop = Number(geneStart) + Number(geneLen);
            			if (contig.length < geneStop) {
            				contig.length = geneStop;
            			}
            			contig.genes.push(gene);
            		}
            	}
                var genesSettings = {
                        "sPaginationType": "full_numbers",
                        "iDisplayLength": 10,
                        "aoColumns": [
                                      {sTitle: "Gene ID", mData: "id"},
                                      {sTitle: "Contig", mData: "contig"},
                                      {sTitle: "Start", mData: "start"},
                                      {sTitle: "Strand", mData: "dir"},
                                      {sTitle: "Length", mData: "len"},
                                      {sTitle: "Type", mData: "type"},
                                      {sTitle: "Function", mData: "func"}
                                     ],
                        "aaData": [],
                        "oLanguage": {
                            "sSearch": "Search gene:",
                            "sEmptyTable": "No genes found."
                        }
                    };
                var genesTable = $('#'+pref+'genes-table').dataTable(genesSettings);
                genesTable.fnAddData(genesData);

            	////////////////////////////// Contigs Tab //////////////////////////////
            	$('#'+pref+'contigs').append('
');
            	var contigsData = [];

            	contigClickListener = function(aHref) {
            		showContig($(aHref).data('contigname'));
            	};

            	for (var key in contigMap) {
            		var contig = contigMap[key];
            		contigsData.push({name: ''+contig.name+'',
            				length: contig.length, genecount: contig.genes.length});

            	}
            	var contigsSettings = {
                        "sPaginationType": "full_numbers",
                        "iDisplayLength": 10,
                        "aoColumns": [
                                      {sTitle: "Contig name", mData: "name"},
                                      {sTitle: "Length", mData: "length"},
                                      {sTitle: "Genes", mData: "genecount"}
                                     ],
                        "aaData": [],
                        "oLanguage": {
                            "sSearch": "Search contig:",
                            "sEmptyTable": "No contigs found."
                        }
                    };
                var contigsTable = $('#'+pref+'contigs-table').dataTable(contigsSettings);
                contigsTable.fnAddData(contigsData);

            	////////////////////////////// Overview Tab //////////////////////////////
            	//$('#'+pref+'elem').append('
Click on any element in Contigs or Genes tab
');

                var lastElemTabNum = 0;

                function openTabGetId(tabName) {
                	if (tabPane.kbaseTabs('hasTab', tabName))
                		return null;
                	lastElemTabNum++;
                	var tabId = '' + pref + 'elem' + lastElemTabNum;
                	var tabDiv = $('
 ');
                    tabPane.kbaseTabs('addTab', {tab: tabName, content: tabDiv, canDelete : true, show: (i == 0)});
                    return tabId;
                }

            	function showGene(geneId) {
                	//$('.'+pref+'elemstyle').remove();
            		var tabId = openTabGetId(geneId);
            		if (tabId == null) {
                        tabPane.kbaseTabs('showTab', geneId);
            			return;
            		}
            		var gene = geneMap[geneId];
        			var contigName = null;
        			var geneStart = null;
        			var geneDir = null;
        			var geneLen = null;
            		if (gene.location && gene.location.length > 0) {
            			contigName = gene.location[0][0];
            			geneStart = gene.location[0][1];
            			geneDir = gene.location[0][2];
            			geneLen = gene.location[0][3];
            		}
            		var geneType = gene.type;
            		var geneFunc = gene['function'];
                	$('#'+tabId).append('
');
                	var elemLabels = ['Gene ID', 'Contig name', 'Gene start', 'Strand', 'Gene length', "Gene type", "Function"];
                	var elemData = [geneId, '' + contigName + '', geneStart, geneDir, geneLen, geneType, geneFunc];
                    var elemTable = $('#'+tabId+'-table');
                    for (var i=0; i<elemData.length; i++) {
                    	if (elemLabels[i] === 'Function') {
                        	elemTable.append('
' + elemLabels[i] + '	 \
                        			<textarea style="width:100%;" cols="2" rows="5" readonly>'+elemData[i]+'</textarea>
');
                    	} else {
                    		elemTable.append('
'+elemLabels[i]+'	 \
                    				'+elemData[i]+'
');
                    	}
                    }
                    $('.'+tabId+'-click2').click(function() {
                    	showContig($(this).data('contigname'));
                    });
                    tabPane.kbaseTabs('showTab', geneId);
            	}

            	function showContig(contigName) {
                	//$('.'+pref+'elemstyle').remove();
            		var tabId = openTabGetId(contigName);
            		if (tabId == null) {
                        tabPane.kbaseTabs('showTab', contigName);
            			return;
            		}
                    var contig = contigMap[contigName];
                	$('#'+tabId).append('
');
                	var elemLabels = ['Contig name', 'Length', 'Gene count'];
                	var elemData = [contigName, contig.length, contig.genes.length];
                    var elemTable = $('#'+tabId+'-table');
                    for (var i=0; i<elemData.length; i++) {
                    	elemTable.append('
'+elemLabels[i]+'	'+elemData[i]+'
');
                    }
                    var cgb = new ContigBrowserPanel();
                    cgb.data.options.contig = contig;
                    cgb.data.options.svgWidth = self.options.width - 28;
                    cgb.data.options.onClickFunction = function(svgElement, feature) {
                    	showGene(feature.feature_id);
                    };
                    cgb.data.$elem = $('
');
                    cgb.data.$elem.show(function(){
                    	cgb.data.update();
                    });
                    $('#'+tabId).append(cgb.data.$elem);
                    cgb.data.init();
                    tabPane.kbaseTabs('showTab', contigName);
            	}

            	function logObject(obj) {
            		var text = "";
            		for (var key in obj) {
            			var value = "" + obj[key];
            			if (value.indexOf("function ") == 0)
            				continue;
            			text += "" + key + "->" + value + " ";
            		}
            		console.log(text);
            	}

            }, function(data) {
            	$('.loader-table').remove();
                container.append('
[Error] ' + data.error.message + '
');
                return;
            });

            return this;
        },

        getData: function() {
                    return {
                        type: "NarrativeTempCard",
                        id: this.options.ws_name + "." + this.options.ws_id,
                        workspace: this.options.ws_name,
                        title: "Temp Widget"
                    };
        }
    });
})( jQuery );
<commit_msg>NAR-57 #comment New branch is created for new widgets for February demo.<commit_after>var geneClickListener = null;
var contigClickListener = null;

function onGeneClick(data) {
	if (geneClickListener != null)
		geneClickListener(data);
}

function onContigClick(data) {
	if (contigClickListener != null)
		contigClickListener(data);
}

(function( $, undefined ) {
    $.KBWidget({
        name: "GenomeAnnotation",
        parent: "kbaseWidget",
        version: "1.0.0",
        options: {
            ws_id: null,
            ws_name: null,
            token: null,
            user_id: null,
            width: 1150
        },

        init: function(options) {
            this._super(options);
            var self = this;

            //var wsUrl = 'http://140.221.84.170:7058/';								// WS2
            var wsUrl = "http://kbase.us/services/workspace/";
            var container = this.$elem;
            container.append('
It\'s loading...
');

            //var kbws = new Workspace(wsUrl);											// WS2
            var kbws = new workspaceService(wsUrl);
            //var request = [{workspace: options.ws_name, objid: options.ws_id}];		// WS2
            var request = {auth: options.token, workspace: options.ws_name, id: options.ws_id, type: 'Genome'};
            //kbws.get_objects(request, function(data) {								// WS2
            kbws.get_object(request, function(data) {
            	$('.loader-table').remove();
            	//var type = data[0].info[2];											// WS2
            	var type = data.metadata[1];
                if (type.indexOf('-') >= 0) {
                	type = type.substring(0, type.indexOf('-'));
                }
                //var reqType = 'KBGA.Genome';											// WS2
                var reqType = 'Genome';
                if (!(type === reqType)) {
                    container.append('
[Error] Object is of type "' + type + '" but expected type is "' + reqType + '"
');
                    return;
                }
            	//var gnm = data[0].data;
            	var gnm = data.data;
            	var pref = (new Date()).getTime();
            	var tabPane = $('
');
            	container.append(tabPane);
                tabPane.kbaseTabs({canDelete : true, tabs : []});
            	var tabNames = ['Overview', 'Contigs', 'Genes'];  //, 'Element'];
            	var tabIds = ['overview', 'contigs', 'genes'];  //, 'elem'];
            	for (var i=0; i<tabIds.length; i++) {
                	var tabDiv = $('
 ');
                    tabPane.kbaseTabs('addTab', {tab: tabNames[i], content: tabDiv, canDelete : false, show: (i == 0)});
            	}

            	////////////////////////////// Overview Tab //////////////////////////////
            	$('#'+pref+'overview').append('
');
            	var overviewLabels = ['Id', 'Name', 'Domain', 'Genetic code', 'Source', "Source id", "GC", "Taxonomy", "Size"];
            	var tax = gnm.taxonomy;
            	if (tax == null)
            		tax = '';
            	var overviewData = [gnm.id, gnm.scientific_name, gnm.domain, gnm.genetic_code, gnm.source, gnm.source_id, gnm.gc, tax, gnm.size];
                var overviewTable = $('#'+pref+'overview-table');
                for (var i=0; i<overviewData.length; i++) {
                	if (overviewLabels[i] === 'Taxonomy') {
                    	overviewTable.append('
' + overviewLabels[i] + '	 \
                    			<textarea style="width:100%;" cols="2" rows="5" readonly>'+overviewData[i]+'</textarea>
');
                	} else {
                		overviewTable.append('
'+overviewLabels[i]+'	 \
                				'+overviewData[i]+'
');
                	}
                }

            	////////////////////////////// Genes Tab //////////////////////////////
            	$('#'+pref+'genes').append('
');
            	var genesData = [];
            	var geneMap = {};
            	var contigMap = {};

            	geneClickListener = function(aHref) {
            		showGene($(aHref).data('geneid'));
            	};

            	for (var genePos in gnm.features) {
            		var gene = gnm.features[genePos];
            		var geneId = gene.id;
        			var contigName = null;
        			var geneStart = null;
        			var geneDir = null;
        			var geneLen = null;
            		if (gene.location && gene.location.length > 0) {
            			contigName = gene.location[0][0];
            			geneStart = gene.location[0][1];
            			geneDir = gene.location[0][2];
            			geneLen = gene.location[0][3];
            		}
            		var geneType = gene.type;
            		var geneFunc = gene['function'];
            		genesData[genesData.length] = {id: ''+geneId+'',
            				contig: contigName, start: geneStart, dir: geneDir, len: geneLen, type: geneType, func: geneFunc};
            		geneMap[geneId] = gene;
            		var contig = contigMap[contigName];
            		if (contigName != null && !contig) {
            			contig = {name: contigName, length: 0, genes: []};
            			contigMap[contigName] = contig;
            		}
            		if (contig) {
            			var geneStop = Number(geneStart) + Number(geneLen);
            			if (contig.length < geneStop) {
            				contig.length = geneStop;
            			}
            			contig.genes.push(gene);
            		}
            	}
                var genesSettings = {
                        "sPaginationType": "full_numbers",
                        "iDisplayLength": 10,
                        "aoColumns": [
                                      {sTitle: "Gene ID", mData: "id"},
                                      {sTitle: "Contig", mData: "contig"},
                                      {sTitle: "Start", mData: "start"},
                                      {sTitle: "Strand", mData: "dir"},
                                      {sTitle: "Length", mData: "len"},
                                      {sTitle: "Type", mData: "type"},
                                      {sTitle: "Function", mData: "func"}
                                     ],
                        "aaData": [],
                        "oLanguage": {
                            "sSearch": "Search gene:",
                            "sEmptyTable": "No genes found."
                        }
                    };
                var genesTable = $('#'+pref+'genes-table').dataTable(genesSettings);
                genesTable.fnAddData(genesData);

            	////////////////////////////// Contigs Tab //////////////////////////////
            	$('#'+pref+'contigs').append('
');
            	var contigsData = [];

            	contigClickListener = function(aHref) {
            		showContig($(aHref).data('contigname'));
            	};

            	for (var key in contigMap) {
            		var contig = contigMap[key];
            		contigsData.push({name: ''+contig.name+'',
            				length: contig.length, genecount: contig.genes.length});

            	}
            	var contigsSettings = {
                        "sPaginationType": "full_numbers",
                        "iDisplayLength": 10,
                        "aoColumns": [
                                      {sTitle: "Contig name", mData: "name"},
                                      {sTitle: "Length", mData: "length"},
                                      {sTitle: "Genes", mData: "genecount"}
                                     ],
                        "aaData": [],
                        "oLanguage": {
                            "sSearch": "Search contig:",
                            "sEmptyTable": "No contigs found."
                        }
                    };
                var contigsTable = $('#'+pref+'contigs-table').dataTable(contigsSettings);
                contigsTable.fnAddData(contigsData);

            	////////////////////////////// Overview Tab //////////////////////////////
            	//$('#'+pref+'elem').append('
Click on any element in Contigs or Genes tab
');

                var lastElemTabNum = 0;

                function openTabGetId(tabName) {
                	if (tabPane.kbaseTabs('hasTab', tabName))
                		return null;
                	lastElemTabNum++;
                	var tabId = '' + pref + 'elem' + lastElemTabNum;
                	var tabDiv = $('
 ');
                    tabPane.kbaseTabs('addTab', {tab: tabName, content: tabDiv, canDelete : true, show: (i == 0)});
                    return tabId;
                }

            	function showGene(geneId) {
                	//$('.'+pref+'elemstyle').remove();
            		var tabId = openTabGetId(geneId);
            		if (tabId == null) {
                        tabPane.kbaseTabs('showTab', geneId);
            			return;
            		}
            		var gene = geneMap[geneId];
        			var contigName = null;
        			var geneStart = null;
        			var geneDir = null;
        			var geneLen = null;
            		if (gene.location && gene.location.length > 0) {
            			contigName = gene.location[0][0];
            			geneStart = gene.location[0][1];
            			geneDir = gene.location[0][2];
            			geneLen = gene.location[0][3];
            		}
            		var geneType = gene.type;
            		var geneFunc = gene['function'];
                	$('#'+tabId).append('
');
                	var elemLabels = ['Gene ID', 'Contig name', 'Gene start', 'Strand', 'Gene length', "Gene type", "Function"];
                	var elemData = [geneId, '' + contigName + '', geneStart, geneDir, geneLen, geneType, geneFunc];
                    var elemTable = $('#'+tabId+'-table');
                    for (var i=0; i<elemData.length; i++) {
                    	if (elemLabels[i] === 'Function') {
                        	elemTable.append('
' + elemLabels[i] + '	 \
                        			<textarea style="width:100%;" cols="2" rows="5" readonly>'+elemData[i]+'</textarea>
');
                    	} else {
                    		elemTable.append('
'+elemLabels[i]+'	 \
                    				'+elemData[i]+'
');
                    	}
                    }
                    $('.'+tabId+'-click2').click(function() {
                    	showContig($(this).data('contigname'));
                    });
                    tabPane.kbaseTabs('showTab', geneId);
            	}

            	function showContig(contigName) {
                	//$('.'+pref+'elemstyle').remove();
            		var tabId = openTabGetId(contigName);
            		if (tabId == null) {
                        tabPane.kbaseTabs('showTab', contigName);
            			return;
            		}
                    var contig = contigMap[contigName];
                	$('#'+tabId).append('
');
                	var elemLabels = ['Contig name', 'Length', 'Gene count'];
                	var elemData = [contigName, contig.length, contig.genes.length];
                    var elemTable = $('#'+tabId+'-table');
                    for (var i=0; i<elemData.length; i++) {
                    	elemTable.append('
'+elemLabels[i]+'	'+elemData[i]+'
');
                    }
                    var cgb = new ContigBrowserPanel();
                    cgb.data.options.contig = contig;
                    cgb.data.options.svgWidth = self.options.width - 28;
                    cgb.data.options.onClickFunction = function(svgElement, feature) {
                    	showGene(feature.feature_id);
                    };
                    cgb.data.$elem = $('
');
                    cgb.data.$elem.show(function(){
                    	cgb.data.update();
                    });
                    $('#'+tabId).append(cgb.data.$elem);
                    cgb.data.init();
                    tabPane.kbaseTabs('showTab', contigName);
            	}

            	function logObject(obj) {
            		var text = "";
            		for (var key in obj) {
            			var value = "" + obj[key];
            			if (value.indexOf("function ") == 0)
            				continue;
            			text += "" + key + "->" + value + " ";
            		}
            		console.log(text);
            	}

            }, function(data) {
            	$('.loader-table').remove();
                container.append('
[Error] ' + data.error.message + '
');
                return;
            });

            return this;
        },

        getData: function() {
                    return {
                        type: "NarrativeTempCard",
                        id: this.options.ws_name + "." + this.options.ws_id,
                        workspace: this.options.ws_name,
                        title: "Temp Widget"
                    };
        }
    });
})( jQuery );
<|endoftext|>


<commit_before>import Q from 'bluebird-q';
import read from 'node-readability';
import qs from 'qs';
import { map, filter } from 'lodash';
import parseLinks from '../lib/parse_links';
import cleanRulers from '../lib/clean_rulers';
import embed from 'embed-video';
import { parse } from 'url';

let { ABSTRACT_ENDPOINT } = process.env;

export default (url) => {
  return Q.promise((resolve, reject) => {
    read(url, {
      cleanRulers: cleanRulers,
      maxRedirects: 40,
      headers: {
        'User-Agent': 'request'
      }
    }, (err, article, res) => {
      if(err){
        return reject(err);
      }
      parseLinks(article.content).then((hrefs) => {
        let html = '';
        if(url.indexOf('youtube') > 0 || url.indexOf('vimeo') > 0){
          html = embed(url) + article.content;
        }else{
          html = article.content;
        }
        resolve({
          html: html,
          title: article.title,
          hrefs: hrefs,
          url: url,
          host: parse(url).hostname
        });
        return article.close();
      }).catch((err) =>{
        console.log('error parsing', err);
        return reject(err)
      });
    });
  });
}
<commit_msg>allow cookies<commit_after>import Q from 'bluebird-q';
import read from 'node-readability';
import qs from 'qs';
import { map, filter } from 'lodash';
import parseLinks from '../lib/parse_links';
import cleanRulers from '../lib/clean_rulers';
import embed from 'embed-video';
import { parse } from 'url';

let { ABSTRACT_ENDPOINT } = process.env;

export default (url) => {
  return Q.promise((resolve, reject) => {
    read(url, {
      cleanRulers: cleanRulers,
      maxRedirects: 40,
      jar: true,
      headers: {
        'User-Agent': 'request'
      }
    }, (err, article, res) => {
      if(err){
        return reject(err);
      }
      parseLinks(article.content).then((hrefs) => {
        let html = '';
        if(url.indexOf('youtube') > 0 || url.indexOf('vimeo') > 0){
          html = embed(url) + article.content;
        }else{
          html = article.content;
        }
        resolve({
          html: html,
          title: article.title,
          hrefs: hrefs,
          url: url,
          host: parse(url).hostname
        });
        return article.close();
      }).catch((err) =>{
        console.log('error parsing', err);
        return reject(err)
      });
    });
  });
}
<|endoftext|>