<commit_before>import {Button} from 'widget/button'
import {Subject, fromEvent} from 'rxjs'
import {connect} from 'store'
import {delay} from 'rxjs/operators'
import {selectFrom} from 'stateUtils'
import FloatingBox from 'widget/floatingBox'
import List from 'widget/list'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import styles from './combo.module.css'

const SELECTION_DELAY_MS = 350

const mapStateToProps = state => ({
    dimensions: selectFrom(state, 'dimensions') || []
})

class ButtonSelect extends React.Component {
    subscriptions = []
    input = React.createRef()
    list = React.createRef()
    select$ = new Subject()
    state = {
        showOptions: false,
        flattenedOptions: [],
        selectedOption: null,
        selected: false
    }

    render() {
        const {className} = this.props
        const {showOptions} = this.state
        return (

                {this.renderButton()}
                {showOptions ? this.renderOptions() : null}

        )
    }

    renderButton() {
        const {disabled, label, look, icon, tooltip, tooltipPlacement} = this.props
        const {showOptions} = this.state
        return (
            <Button
                ref={this.input}
                label={label}
                look={look}
                icon={icon}
                tooltip={tooltip}
                tooltipPlacement={tooltipPlacement}
                onClick={() => showOptions
                    ? this.hideOptions()
                    : this.showOptions()
                }
                disabled={disabled}
            />
        )
    }

    renderOptions() {
        const {placement, optionsClassName, optionTooltipPlacement} = this.props
        const {flattenedOptions, selectedOption, selected} = this.state
        return (
            <FloatingBox
                element={this.input.current}
                placement={placement}
                width='auto'
            >
                <List
                    ref={this.list}
                    className={optionsClassName || styles.options}
                    options={flattenedOptions}
                    selectedOption={selectedOption}
                    onSelect={option => this.select$.next(option)}
                    onCancel={() => this.hideOptions()}
                    autoCenter={!selected}
                    tooltipPlacement={optionTooltipPlacement}
                    keyboard
                />
            </FloatingBox>
        )
    }

    showOptions() {
        this.setState({showOptions: true})
    }

    hideOptions() {
        this.setState({showOptions: false})
    }

    setSelectedOption(selectedOption) {
        this.updateState({
            selectedOption,
            selected: true
        })
    }

    updateState(state, callback) {
        const updatedState = (prevState, state) =>
            _.isEqual(_.pick(prevState, _.keys(state)), state) ? null : state
        this.setState(
            prevState =>
                updatedState(prevState, _.isFunction(state) ? state(prevState) : state),
            callback
        )
    }

    handleSelect() {
        const {onSelect} = this.props
        this.subscriptions.push(
            this.select$.subscribe(
                option => {
                    this.setSelectedOption(option)
                    onSelect && onSelect(option)
                }
            ),
            this.select$.pipe(
                delay(SELECTION_DELAY_MS)
            ).subscribe(
                () => this.setState({selected: false}, this.hideOptions)
            )
        )
    }

    handleBlur() {
        const click$ = fromEvent(document, 'click')
        const isInputClick = e => this.input.current && this.input.current.contains(e.target)
        const isListClick = e => this.list.current && this.list.current.contains && this.list.current.contains(e.target)
        this.subscriptions.push(
            click$.subscribe(e => {
                if (!isInputClick(e) && !isListClick(e)) {
                    this.hideOptions()
                }
            })
        )
    }

    componentDidMount() {
        this.handleSelect()
        this.handleBlur()
    }

    componentDidUpdate() {
        this.updateOptions()
    }

    componentWillUnmount() {
        this.subscriptions.forEach(subscription => subscription.unsubscribe())
    }

    updateOptions() {
        const {options} = this.props
        const getFlattenedOptions = options =>
            _.flatten(
                options.map(option =>
                    option.options
                        ? [{label: option.label, group: true}, ...option.options]
                        : option
                )
            )
        this.updateState({
            flattenedOptions: getFlattenedOptions(options)
        })
    }
}

export default connect(mapStateToProps)(ButtonSelect)

ButtonSelect.propTypes = {
    options: PropTypes.any.isRequired,
    onSelect: PropTypes.func.isRequired,
    className: PropTypes.string,
    disabled: PropTypes.any,
    label: PropTypes.string,
    look: PropTypes.string,
    icon: PropTypes.string,
    optionsClassName: PropTypes.string,
    placement: PropTypes.oneOf(['above', 'below']),
    tooltip: PropTypes.string,
    tooltipPlacement: PropTypes.string,
    optionTooltipPlacement: PropTypes.string
}

ButtonSelect.defaultProps = {
    placement: 'below'
}
<commit_msg>Cleared selected option on hide.<commit_after>import {Button} from 'widget/button'
import {Subject, fromEvent} from 'rxjs'
import {connect} from 'store'
import {delay} from 'rxjs/operators'
import {selectFrom} from 'stateUtils'
import FloatingBox from 'widget/floatingBox'
import List from 'widget/list'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import styles from './combo.module.css'

const SELECTION_DELAY_MS = 350

const mapStateToProps = state => ({
    dimensions: selectFrom(state, 'dimensions') || []
})

class ButtonSelect extends React.Component {
    subscriptions = []
    input = React.createRef()
    list = React.createRef()
    select$ = new Subject()
    state = {
        showOptions: false,
        flattenedOptions: [],
        selectedOption: null,
        selected: false
    }

    render() {
        const {className} = this.props
        const {showOptions} = this.state
        return (

                {this.renderButton()}
                {showOptions ? this.renderOptions() : null}

        )
    }

    renderButton() {
        const {disabled, label, look, icon, tooltip, tooltipPlacement} = this.props
        const {showOptions} = this.state
        return (
            <Button
                ref={this.input}
                label={label}
                look={look}
                icon={icon}
                tooltip={tooltip}
                tooltipPlacement={tooltipPlacement}
                onClick={() => showOptions
                    ? this.hideOptions()
                    : this.showOptions()
                }
                disabled={disabled}
            />
        )
    }

    renderOptions() {
        const {placement, optionsClassName, optionTooltipPlacement} = this.props
        const {flattenedOptions, selectedOption, selected} = this.state
        return (
            <FloatingBox
                element={this.input.current}
                placement={placement}
                width='auto'
            >
                <List
                    ref={this.list}
                    className={optionsClassName || styles.options}
                    options={flattenedOptions}
                    selectedOption={selectedOption}
                    onSelect={option => this.select$.next(option)}
                    onCancel={() => this.hideOptions()}
                    autoCenter={!selected}
                    tooltipPlacement={optionTooltipPlacement}
                    keyboard
                />
            </FloatingBox>
        )
    }

    showOptions() {
        this.setState({showOptions: true})
    }

    hideOptions() {
        this.setState({showOptions: false, selectedOption: null})
    }

    setSelectedOption(selectedOption) {
        this.updateState({
            selectedOption,
            selected: true
        })
    }

    updateState(state, callback) {
        const updatedState = (prevState, state) =>
            _.isEqual(_.pick(prevState, _.keys(state)), state) ? null : state
        this.setState(
            prevState =>
                updatedState(prevState, _.isFunction(state) ? state(prevState) : state),
            callback
        )
    }

    handleSelect() {
        const {onSelect} = this.props
        this.subscriptions.push(
            this.select$.subscribe(
                option => {
                    this.setSelectedOption(option)
                    onSelect && onSelect(option)
                }
            ),
            this.select$.pipe(
                delay(SELECTION_DELAY_MS)
            ).subscribe(
                () => this.setState({selected: false}, this.hideOptions)
            )
        )
    }

    handleBlur() {
        const click$ = fromEvent(document, 'click')
        const isInputClick = e => this.input.current && this.input.current.contains(e.target)
        const isListClick = e => this.list.current && this.list.current.contains && this.list.current.contains(e.target)
        this.subscriptions.push(
            click$.subscribe(e => {
                if (!isInputClick(e) && !isListClick(e)) {
                    this.hideOptions()
                }
            })
        )
    }

    componentDidMount() {
        this.handleSelect()
        this.handleBlur()
    }

    componentDidUpdate() {
        this.updateOptions()
    }

    componentWillUnmount() {
        this.subscriptions.forEach(subscription => subscription.unsubscribe())
    }

    updateOptions() {
        const {options} = this.props
        const getFlattenedOptions = options =>
            _.flatten(
                options.map(option =>
                    option.options
                        ? [{label: option.label, group: true}, ...option.options]
                        : option
                )
            )
        this.updateState({
            flattenedOptions: getFlattenedOptions(options)
        })
    }
}

export default connect(mapStateToProps)(ButtonSelect)

ButtonSelect.propTypes = {
    options: PropTypes.any.isRequired,
    onSelect: PropTypes.func.isRequired,
    className: PropTypes.string,
    disabled: PropTypes.any,
    label: PropTypes.string,
    look: PropTypes.string,
    icon: PropTypes.string,
    optionsClassName: PropTypes.string,
    placement: PropTypes.oneOf(['above', 'below']),
    tooltip: PropTypes.string,
    tooltipPlacement: PropTypes.string,
    optionTooltipPlacement: PropTypes.string
}

ButtonSelect.defaultProps = {
    placement: 'below'
}
<|endoftext|>


<commit_before>/**
 * The SidebarNavView view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps'
], function($,Backbone, _,mps) {

  'use strict';

  var SidebarNavModel = Backbone.Model.extend({
    defaults: {
      section: null,
      t: null,
      interesting: null
    }
  });

  var SidebarNavView = Backbone.View.extend({

    el: '#sidebarNavView',

    events: {
      'click .nav-item' : 'changeSourceNav',
      'click .nav-title' : 'scrollTo',
      'click .source_header' : 'toggleSources',
      'click .source_dropdown_header' : 'toggleDropdown',
      'click .source_dropdown_menu a' : 'showSubContent',
      'click #back-btn' : 'returnBack'
    },

    initialize: function() {
      if (!this.$el.length) {
        return
      }

      this.model = new SidebarNavModel();

      //CACHE
      this.$window = $(window);
      this.$document = $(document);
      this.$htmlbody = $('html,body');
      this.$headerH1 = $('#headerView').find('h1');
      this.$backBtn = $('#back-btn');
      this.$navItem = this.$el.find('.nav-item');
      this.$sideBarAside = $('#sidebarAside');
      this.$sideBarBox = $('#sources-box');
      this.$sourceArticle = $('.source-article');
      this.$sourceHeader = $('.source_header');
      this.$sourceBody = $('.source_body');
      this.$cut = $('#cut');
      this.$sourceSpinner = $('#sources-spinner');
      this.$loaderMobile = $('#loader-mobile');

      //VARS
      this.padding = 40;
      this.first = true;
      this.mobile = (this.$window.width() > 850) ? false : true;

      //INIT
      this.setListeners();
    },

    setListeners: function(){

      this.calculateOffsets();
      this.scrollDocument();
      this.$document.on('scroll',_.bind(this.scrollDocument,this));
      this.$window.on('resize',_.bind(this.calculateOffsets,this));

      mps.subscribe('SourceStatic/change',_.bind(this.changeSource,this));
      mps.subscribe('SubItem/change',_.bind(this.calculateOffsets,this));

      _.delay(_.bind(function(){
        this.$loaderMobile.addClass('loaded');
      }, this ), 250)

    },

    calculateOffsets: function(){
      this.mobile = (this.$window.width() > 850) ? false : true;
      this.$sideBarBox.css({'min-height': this.$sideBarAside.height() });
      this.offset = this.$el.offset().top + parseInt(this.$el.css('paddingTop'), 10);
      this.offsetBottom = this.$cut.offset().top - this.$sideBarAside.height() - this.padding;
      if (!this.mobile) {
        this.$htmlbody.removeClass('active');
      }
    },

    scrollDocument: function(e){
      var scrollTop = this.$document.scrollTop();
      if (scrollTop > this.offset) {
        this.$sideBarBox.addClass('fixed');
        this.firstFixed = false;
        if(scrollTop < this.offsetBottom) {
          this.$sideBarAside.removeClass('bottom').addClass('fixed');
        }else{
          this.$sideBarAside.removeClass('fixed').addClass('bottom');
        }
      }else{
        this.$sideBarAside.removeClass('fixed bottom');
        this.$sideBarBox.removeClass('fixed');
        this.firstFixed = true;
      }
    },

    changeSourceNav: function(e){
      e && e.preventDefault();
      this.model.set('section',$(e.currentTarget).data('slug'));
      this.model.set('interesting', $(e.currentTarget).data('interesting'));
      this.model.set('t',null);
      this.updateSource();
    },
    toggleSources: function(e){
      ($(e.currentTarget).hasClass('active')) ? this.model.set('t', null) : this.model.set('t', $(e.currentTarget).parent().attr('id'));
      this.$sourceHeader.removeClass('active');
      this.$sourceBody.hide(0);
      this.updateSource();
    },

    toggleDropdown: function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').toggle(0);
    },

    updateSource: function(){
      var params = {
        section: this.model.get('section'),
        interesting: this.model.get('interesting'),
        t: this.model.get('t')
      }
      mps.publish('SourceStatic/update',[params]);
    },

    changeSource: function(params){
      //spinner
      this.$sourceSpinner.removeClass('start');
      if (params.section) {
        this.section = true;
        this.model.set('section', params.section);
        this.model.set('interesting', params.interesting);
        (params.t) ? this.model.set('t', params.t) : null;
      }else{
        this.section = false;
        (!this.mobile) ? this.model.set('section', this.$navItem.eq(0).data('slug')) : null;
        this.model.set('interesting', this.$navItem.eq(0).data('interesting'));
      }
      mps.publish('Interesting/update',[this.model.get('interesting')]);
      this.changeHelper();
    },

    changeHelper: function(){
      var section = this.model.get('section'), tab = this.model.get('t'), $tab = $('#'+tab);
      var time = (this.first) ? 250 : 0;
      // mobile
      if (this.mobile) {
        if (section) {
          this.padding = 0;
          this.$backBtn.addClass('active');
          this.$htmlbody.addClass('active');
          this.$headerH1.addClass('active');
          this.$sideBarBox.addClass('active')
        }
      }else{
        this.padding = 40;
        this.$htmlbody.removeClass('active');
        this.$headerH1.removeClass('active');
        this.$sideBarBox.addClass('active');
      }

      //aside
      this.$navItem.removeClass('selected');
      $('.'+section).addClass('selected');

      //section
      this.$sourceArticle.removeClass('selected');
      $('#'+section).addClass('selected');

      //tab
      if (tab) {
        if (this.mobile) {
          this.$sideBarBox.animate({ scrollTop: $tab.offset().top - this.$backBtn.innerHeight() },0, _.bind(function(){
            $tab.find('.source_header').addClass('active');
            $tab.find('.source_body').show(0);
            this.calculateOffsets();
          }, this ));
        }else{
          this.$htmlbody.animate({ scrollTop: $tab.offset().top },0, _.bind(function(){
            $tab.find('.source_header').addClass('active');
            $tab.find('.source_body').show(0);
            this.calculateOffsets();
          }, this ));
        }
      }else{
        if (this.section) {
          this.$htmlbody.delay(time).animate({ scrollTop: this.$sideBarBox.offset().top - this.padding },time, _.bind(function(){
            this.calculateOffsets();
          }, this ));
        }
      }
      this.section = true;
      this.first = false;
    },

    showSubContent:function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').hide(0);

      var text = $(e.currentTarget).text();
      var id = $(e.currentTarget).data('slug');
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_header').find('.overview_title').children('span').text(text);

      $('.source_dropdown_body').hide(0);
      $('#'+id).show(0);

      this.calculateOffsets();
    },

    returnBack: function(e){
      e && e.preventDefault();

      this.$headerH1.removeClass('active');
      this.$sideBarBox.removeClass('active');
      this.$backBtn.removeClass('active');
      this.$navItem.removeClass('selected');

      this.$htmlbody.removeClass('active').animate({ scrollTop: this.$sideBarAside.offset().top },0);

    },

    scrollTo: function(e){
      e && e.preventDefault();
      this.$htmlbody.animate({ scrollTop: 0 },500);
    }

  });

  return SidebarNavView;

});
<commit_msg>Static: calculate offsets working properly<commit_after>/**
 * The SidebarNavView view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps'
], function($,Backbone, _,mps) {

  'use strict';

  var SidebarNavModel = Backbone.Model.extend({
    defaults: {
      section: null,
      t: null,
      interesting: null
    }
  });

  var SidebarNavView = Backbone.View.extend({

    el: '#sidebarNavView',

    events: {
      'click .nav-item' : 'changeSourceNav',
      'click .nav-title' : 'scrollTo',
      'click .source_header' : 'toggleSources',
      'click .source_dropdown_header' : 'toggleDropdown',
      'click .source_dropdown_menu a' : 'showSubContent',
      'click #back-btn' : 'returnBack'
    },

    initialize: function() {
      if (!this.$el.length) {
        return
      }

      this.model = new SidebarNavModel();

      //CACHE
      this.$window = $(window);
      this.$document = $(document);
      this.$htmlbody = $('html,body');
      this.$headerH1 = $('#headerView').find('h1');
      this.$backBtn = $('#back-btn');
      this.$navItem = this.$el.find('.nav-item');
      this.$sideBarAside = $('#sidebarAside');
      this.$sideBarBox = $('#sources-box');
      this.$sourceArticle = $('.source-article');
      this.$sourceHeader = $('.source_header');
      this.$sourceBody = $('.source_body');
      this.$cut = $('#cut');
      this.$sourceSpinner = $('#sources-spinner');
      this.$loaderMobile = $('#loader-mobile');

      //VARS
      this.padding = 40;
      this.first = true;
      this.mobile = (this.$window.width() > 850) ? false : true;

      //INIT
      this.setListeners();
    },

    setListeners: function(){

      this.calculateOffsets();
      this.scrollDocument();
      this.$document.on('scroll',_.bind(this.scrollDocument,this));
      this.$window.on('resize',_.bind(this.calculateOffsets,this));

      mps.subscribe('SourceStatic/change',_.bind(this.changeSource,this));
      mps.subscribe('SubItem/change',_.bind(this.calculateOffsets,this));

      _.delay(_.bind(function(){
        this.$loaderMobile.addClass('loaded');
      }, this ), 250)

    },

    calculateOffsets: function(){
      this.mobile = (this.$window.width() > 850) ? false : true;
      this.$sideBarBox.css({'min-height': this.$sideBarAside.height() });
      this.offset = this.$el.offset().top + parseInt(this.$el.css('paddingTop'), 10);
      this.offsetBottom = this.$cut.offset().top - this.$sideBarAside.height() - this.padding;
      if (!this.mobile) {
        this.$htmlbody.removeClass('active');
      }
    },

    scrollDocument: function(e){
      var scrollTop = this.$document.scrollTop();
      if (scrollTop > this.offset) {
        this.$sideBarBox.addClass('fixed');
        this.firstFixed = false;
        if(scrollTop < this.offsetBottom) {
          this.$sideBarAside.removeClass('bottom').addClass('fixed');
        }else{
          this.$sideBarAside.removeClass('fixed').addClass('bottom');
        }
      }else{
        this.$sideBarAside.removeClass('fixed bottom');
        this.$sideBarBox.removeClass('fixed');
        this.firstFixed = true;
      }
    },

    changeSourceNav: function(e){
      e && e.preventDefault();
      this.model.set('section',$(e.currentTarget).data('slug'));
      this.model.set('interesting', $(e.currentTarget).data('interesting'));
      this.model.set('t',null);
      this.updateSource();
    },
    toggleSources: function(e){
      ($(e.currentTarget).hasClass('active')) ? this.model.set('t', null) : this.model.set('t', $(e.currentTarget).parent().attr('id'));
      this.$sourceHeader.removeClass('active');
      this.$sourceBody.hide(0);
      this.updateSource();
    },

    toggleDropdown: function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').toggle(0);
    },

    updateSource: function(){
      var params = {
        section: this.model.get('section'),
        interesting: this.model.get('interesting'),
        t: this.model.get('t')
      }
      mps.publish('SourceStatic/update',[params]);
    },

    changeSource: function(params){
      //spinner
      this.$sourceSpinner.removeClass('start');
      if (params.section) {
        this.section = true;
        this.model.set('section', params.section);
        this.model.set('interesting', params.interesting);
        (params.t) ? this.model.set('t', params.t) : null;
      }else{
        this.section = false;
        (!this.mobile) ? this.model.set('section', this.$navItem.eq(0).data('slug')) : null;
        this.model.set('interesting', this.$navItem.eq(0).data('interesting'));
      }
      mps.publish('Interesting/update',[this.model.get('interesting')]);
      this.changeHelper();
    },

    changeHelper: function(){
      var section = this.model.get('section'), tab = this.model.get('t'), $tab = $('#'+tab);
      var time = (this.first) ? 250 : 0;
      // mobile
      if (this.mobile) {
        if (section) {
          this.padding = 0;
          this.$backBtn.addClass('active');
          this.$htmlbody.addClass('active');
          this.$headerH1.addClass('active');
          this.$sideBarBox.addClass('active')
        }
      }else{
        this.padding = 40;
        this.$htmlbody.removeClass('active');
        this.$headerH1.removeClass('active');
        this.$sideBarBox.addClass('active');
      }

      //aside
      this.$navItem.removeClass('selected');
      $('.'+section).addClass('selected');

      //section
      this.$sourceArticle.removeClass('selected');
      $('#'+section).addClass('selected');

      //tab
      if (tab) {
        if (this.mobile) {
          this.$sideBarBox.animate({ scrollTop: $tab.offset().top - this.$backBtn.innerHeight() },0, _.bind(function(){
            $tab.find('.source_header').addClass('active');
            $tab.find('.source_body').show(0);
            this.calculateOffsets();
          }, this ));
        }else{
          this.$htmlbody.animate({ scrollTop: $tab.offset().top },0, _.bind(function(){
            $tab.find('.source_header').addClass('active');
            $tab.find('.source_body').show(0);
            this.calculateOffsets();
          }, this ));
        }
      }else{
        if (this.section) {
          this.$htmlbody.delay(time).animate({ scrollTop: this.$sideBarBox.offset().top - this.padding },time, _.bind(function(){
            this.calculateOffsets();
          }, this ));
        }else{
          this.calculateOffsets();
        }
      }
      this.section = true;
      this.first = false;
    },

    showSubContent:function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').hide(0);

      var text = $(e.currentTarget).text();
      var id = $(e.currentTarget).data('slug');
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_header').find('.overview_title').children('span').text(text);

      $('.source_dropdown_body').hide(0);
      $('#'+id).show(0);

      this.calculateOffsets();
    },

    returnBack: function(e){
      e && e.preventDefault();

      this.$headerH1.removeClass('active');
      this.$sideBarBox.removeClass('active');
      this.$backBtn.removeClass('active');
      this.$navItem.removeClass('selected');

      this.$htmlbody.removeClass('active').animate({ scrollTop: this.$sideBarAside.offset().top },0);

    },

    scrollTo: function(e){
      e && e.preventDefault();
      this.$htmlbody.animate({ scrollTop: 0 },500);
    }

  });

  return SidebarNavView;

});
<|endoftext|>


<commit_before>KM.registerToolbarUI( 'saveto', function ( name ) {

    var me = this,
        label = me.getLang( 'tooltips.' + name ),
        options = {
            label: label,
            title: label,
            comboboxName: name,
            items: [],
            itemStyles: [],
            value: [],
            autowidthitem: [],
            enabledRecord: false
        },
        $combox = null,
        comboboxWidget = null;

    utils.each( KityMinder.getAllRegisteredProtocals(), function ( k ) {
        var p = KityMinder.findProtocal( k );
        if ( p.encode ) {
            var text = p.fileDescription + '（' + p.fileExtension + '）';
            options.value.push( k );
            options.items.push( text );
            options.autowidthitem.push( $.wordCountAdaptive( text ), true );
        }
    } );

    //实例化
    $combox = $.kmuibuttoncombobox( options ).css( 'zIndex', me.getOptions( 'zIndex' ) + 1 );
    comboboxWidget = $combox.kmui();

    function doDownload( url, filename ) {
        var a = document.createElement( 'a' );
        a.setAttribute( 'download', filename );
        a.setAttribute( 'href', url );
        try {
            a.dispatchEvent( new MouseEvent( 'click' ) );
        } catch ( error ) {
            a.click();
        }
    }

    comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
        var data = me.exportData( res.value );
        console.log( data );
        var p = KityMinder.findProtocal( res.value );
        var filename = me.getMinderTitle() + p.fileExtension;
        if ( typeof ( data ) == 'string' ) {
            var url = 'data:text/plain; utf-8,' + encodeURIComponent( data );
            doDownload( url, filename );
        } else if ( data && data.then ) {
            data.then( function ( url ) {
                doDownload( url, filename );
            } );
        }
    } ).on( "beforeshow", function () {
        if ( $combox.parent().length === 0 ) {
            $combox.appendTo( me.$container.find( '.kmui-dialog-container' ) );
        }
    } ).on( 'aftercomboboxselect', function () {
        this.setLabelWithDefaultValue();
    } );

    return comboboxWidget.button().addClass( 'kmui-combobox' );

} );<commit_msg>fixed IE bug<commit_after>KM.registerToolbarUI( 'saveto', function ( name ) {

    var me = this,
        label = me.getLang( 'tooltips.' + name ),
        options = {
            label: label,
            title: label,
            comboboxName: name,
            items: [],
            itemStyles: [],
            value: [],
            autowidthitem: [],
            enabledRecord: false
        },
        $combox = null,
        comboboxWidget = null;

    utils.each( KityMinder.getAllRegisteredProtocals(), function ( k ) {
        var p = KityMinder.findProtocal( k );
        if ( p.encode ) {
            var text = p.fileDescription + '（' + p.fileExtension + '）';
            options.value.push( k );
            options.items.push( text );
            options.autowidthitem.push( $.wordCountAdaptive( text ), true );
        }
    } );

    //实例化
    $combox = $.kmuibuttoncombobox( options ).css( 'zIndex', me.getOptions( 'zIndex' ) + 1 );
    comboboxWidget = $combox.kmui();

    function doDownload( url, filename ) {
        var a = document.createElement( 'a' );
        a.setAttribute( 'download', filename );
        a.setAttribute( 'href', url );
        try {
            a.dispatchEvent( new MouseEvent( 'click' ) );
        } catch ( error ) {
            a.click();
        }
    }

    comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
        var data = me.exportData( res.value );
        var p = KityMinder.findProtocal( res.value );
        var filename = me.getMinderTitle() + p.fileExtension;
        if ( typeof ( data ) == 'string' ) {
            var url = 'data:text/plain; utf-8,' + encodeURIComponent( data );
            doDownload( url, filename );
        } else if ( data && data.then ) {
            data.then( function ( url ) {
                doDownload( url, filename );
            } );
        }
    } ).on( "beforeshow", function () {
        if ( $combox.parent().length === 0 ) {
            $combox.appendTo( me.$container.find( '.kmui-dialog-container' ) );
        }
    } ).on( 'aftercomboboxselect', function () {
        this.setLabelWithDefaultValue();
    } );

    return comboboxWidget.button().addClass( 'kmui-combobox' );

} );<|endoftext|>


<commit_before>var process = require('process')
var fs = require('fs')
var nearley = require('nearley')
var grammar = require('./grammar')
var helper = require('./helper')

var filename = process.argv[2]
var data = fs.readFileSync(filename, 'utf8')

// Normalize endings

console.error('Normalize endings...')
data = data.replace(/\r\n/g, '\n').replace(/\r/g, '')

// Remove comments & strings

console.error('Remove comments...')

var removed = helper.removeStringComments(data)
var stringCommentsRemoved = removed[1]
data = removed[0]

// Get indent length

console.error('Determine indent length...')
var indentLength

try {
    indentLength = helper.getIndent(data)
} catch(e) {
    console.error('Mixed indentation @' + e.line + ':1')
    return
}

// Indentifizer

console.error('Indentifizer...')
data = helper.indentifizer(data, stringCommentsRemoved, indentLength)

// Invoke nearley

console.error('Parsing...')
var p = new nearley.Parser(grammar.ParserRules, grammar.ParserStart)

try {
    var result = p.feed(data)

    if (!result || !result.results || !result.results.length)
        throw { offset: data.length - 1 }
} catch(e) {
    var pos = helper.offsetToLinePos(e.offset, data)
    console.error('Parse error @' + pos[0] + ':' + pos[1])
    return
}

console.error('Compiled.')
console.error(result.results.length == 1 ? 'No ambiguity detected.' : 'Ambiguity detected.')
console.dir(result.results, { depth: null })
<commit_msg>Rename and better error message<commit_after>var process = require('process')
var fs = require('fs')
var nearley = require('nearley')
var grammar = require('./grammar')
var helper = require('./helper')

var filename = process.argv[2]
var data = fs.readFileSync(filename, 'utf8')

// Normalize endings

console.error('Normalize endings...')
data = data.replace(/\r\n/g, '\n').replace(/\r/g, '')

// Remove comments & strings

console.error('Remove comments...')

var removed = helper.removeStringComments(data)
var pureCode = removed[1]
var comments = removed[2]
data = removed[0]
console.log(comments)

// Get indent length

console.error('Determine indent length...')
var indentLength

try {
    indentLength = helper.getIndent(data)
} catch(e) {
    console.error('Mixed indentation @' + e.line + ':1')
    return
}

// Indentifizer

console.error('Indentifizer...')
data = helper.indentifizer(data, pureCode, indentLength)

// Invoke nearley

console.error('Parsing...')
var p = new nearley.Parser(grammar.ParserRules, grammar.ParserStart)

try {
    var result = p.feed(data)

    if (!result || !result.results || !result.results.length) {
        throw { message: 'Unexpected end', offset: data.length - 1 }
    }
} catch(e) {
    var pos = helper.offsetToLinePos(e.offset, data)
    var message = e.message
    if (message.indexOf('nearley') != -1) message = 'Parse error'

    console.error(message + ' @' + pos[0] + ':' + pos[1])
    return
}

console.error('Compiled.')
console.error(result.results.length == 1 ? 'No ambiguity detected.' : 'Ambiguity detected.')
console.dir(result.results, { depth: null })
<|endoftext|>


<commit_before>/**
 * Checkout.com Magento 2 Payment module (https://www.checkout.com)
 *
 * Copyright (c) 2017 Checkout.com (https://www.checkout.com)
 * Author: David Fiaty | integration@checkout.com
 *
 * License GNU/GPL V3 https://www.gnu.org/licenses/gpl-3.0.en.html
 */

/*browser:true*/
/*global define*/

define(
    [
        'jquery',
        'CheckoutCom_Magento2/js/view/payment/method-renderer/cc-form',
        'Magento_Vault/js/view/payment/vault-enabler',
        'CheckoutCom_Magento2/js/view/payment/adapter',
        'Magento_Checkout/js/model/quote',
        'Magento_Ui/js/model/messageList',
        'mage/url',
        'Magento_Checkout/js/action/set-payment-information',
        'Magento_Checkout/js/model/full-screen-loader',
        'Magento_Checkout/js/model/payment/additional-validators',
        'Magento_Checkout/js/checkout-data',
        'Magento_Checkout/js/action/redirect-on-success'
    ],
    function($, Component, VaultEnabler, CheckoutCom, quote, globalMessages, url, setPaymentInformationAction, fullScreenLoader, additionalValidators, checkoutData, redirectOnSuccessAction, customer) {
        'use strict';

        window.checkoutConfig.reloadOnBillingAddress = true;

        return Component.extend({
            defaults: {
                active: true,
                template: 'CheckoutCom_Magento2/payment/embedded',
                code: 'checkout_com',
                card_token_id: null,
                redirectAfterPlaceOrder: true,
                card_bin: null
            },

            /**
             * @returns {exports}
             */
            initialize: function(config, messageContainer) {
                this._super();
                this.initObservable();
                this.messageContainer = messageContainer || config.messageContainer || globalMessages;

                this.vaultEnabler = new VaultEnabler();
                this.vaultEnabler.setPaymentCode(this.getVaultCode());

                return this;
            },

            /**
             * @returns {exports}
             */
            initObservable: function () {
                this._super()
                    .observe('isHidden');

                return this;
            },

            /**
             * @returns {bool}
             */
            isVisible: function () {
                return this.isHidden(this.messageContainer.hasMessages());
            },

            /**
             * @returns {bool}
             */
            removeAll: function () {
                this.messageContainer.clear();
            },

            /**
             * @returns {void}
             */
            onHiddenChange: function (isHidden) {
                var self = this;
                // Hide message block if needed
                if (isHidden) {
                    setTimeout(function () {
                        $(self.selector).hide('blind', {}, 500)
                    }, 10000);
                }
            },

            /**
             * @returns {bool}
             */
            isVaultEnabled: function() {
                return this.vaultEnabler.isVaultEnabled();
            },

            /**
             * @returns {string}
             */
            getVaultCode: function() {
                return window.checkoutConfig.payment[this.getCode()].ccVaultCode;
            },

            /**
             * @returns {string}
             */
            getCode: function() {
                return CheckoutCom.getCode();
            },

            /**
             * @param {string} card_token_id
             */
            setCardTokenId: function(card_token_id) {
                this.card_token_id = card_token_id;
            },

            /**
             * @returns {bool}
             */
            isActive: function() {
                return CheckoutCom.getPaymentConfig()['isActive'];
            },

            /**
             * @returns {string}
             */
            getPublicKey: function() {
                return CheckoutCom.getPaymentConfig()['public_key'];
            },

            /**
             * @returns {string}
             */
            getQuoteValue: function() {
                return quote.getTotals();
            },

            /**
             * @returns {string}
             */
            getQuoteCurrency: function() {
                return CheckoutCom.getPaymentConfig()['quote_currency'];
            },

            /**
             * @returns {bool}
             */
            isCardAutosave: function() {
                return CheckoutCom.getPaymentConfig()['card_autosave'];
            },

            /**
             * @returns {string}
             */
            getRedirectUrl: function() {
                return url.build('checkout_com/payment/placeOrder');
            },

            /**
             * @returns {void}
             */
            saveSessionData: function() {
                // Get self
                var self = this;

                // Prepare the session data
                var sessionData = {
                    saveShopperCard: $('#checkout_com_enable_vault').is(":checked"),
                    customerEmail: self.getEmailAddress(),
                    cardBin: self.card_bin
                };

                // Send the session data to be saved
                $.ajax({
                    url: url.build('checkout_com/shopper/sessionData'),
                    type: "POST",
                    data: sessionData,
                    success: function(data, textStatus, xhr) {},
                    error: function(xhr, textStatus, error) {} // todo - improve error handling
                });
            },

            /**
             * @returns {string}
             */
            beforePlaceOrder: function() {
                // Get self
                var self = this;

                // Get the form
                var paymentForm = document.getElementById('embeddedForm');

                // Validate before submission
                if (additionalValidators.validate()) {
                    if (Frames.isCardValid()) {
                        // Start the loader
                        fullScreenLoader.startLoader();

                        // Submit frames form
                        Frames.submitCard();
                    }
                }
            },

            /**
             * @override
             */
            placeOrder: function() {
                var self = this;

                $.migrateMute = true;

                this.updateButtonState(false);
                this.getPlaceOrderDeferredObject()
                .fail(
                    function() {
                        self.updateButtonState(true);
                        $('html, body').animate({ scrollTop: 0 }, 'fast');
                        self.reloadEmbeddedForm();
                    }
                ).done(
                    function() {
                        self.afterPlaceOrder();

                        if (self.redirectAfterPlaceOrder) {
                            redirectOnSuccessAction.execute();
                        }
                    }
                );
            },

            /**
             * @returns {void}
             */
            getEmbeddedForm: function() {
                // Get self
                var self = this;

                // Prepare parameters
                var ckoTheme = CheckoutCom.getPaymentConfig()['embedded_theme'];
                var css_file = CheckoutCom.getPaymentConfig()['css_file'];
                var custom_css = CheckoutCom.getPaymentConfig()['custom_css'];
                var ckoThemeOverride = ((custom_css) && custom_css !== '' && css_file == 'custom') ? custom_css : undefined;
                var redirectUrl = self.getRedirectUrl();
                var threeds_enabled = CheckoutCom.getPaymentConfig()['three_d_secure']['enabled'];
                var paymentForm = document.getElementById('embeddedForm');

                // Freeze the place order button on initialisation
                $('#ckoPlaceOrder').attr("disabled",true);

                // Initialise the embedded form
                Frames.init({
                    publicKey: self.getPublicKey(),
                    containerSelector: '#cko-form-holder',
                    theme: ckoTheme,
                    debugMode: CheckoutCom.getPaymentConfig()['debug_mode'],
                    themeOverride: ckoThemeOverride,
                    frameActivated: function () {
                        $('#ckoPlaceOrder').attr("disabled", true);
                    },
                    cardValidationChanged: function() {
                        self.updateButtonState(!(Frames.isCardValid() && quote.billingAddress() != null));
                    },
                    cardTokenised: function(event) {
                        // Keep the card info
                        self.card_bin = event.data.card.bin;

                        // Save checkout info in PHP session
                        self.saveSessionData();

                        // Set the card token
                        self.setCardTokenId(event.data.cardToken);

                        // Add the card token to the form
                        Frames.addCardToken(paymentForm, event.data.cardToken);

                        // Place order
                        window.location.replace(redirectUrl + '?cko-card-token=' + event.data.cardToken + '&cko-context-id=' + self.getEmailAddress());
                    },
                });
            },

            /**
             * @returns {void}
             */
            updateButtonState: function(status) {
                $('#ckoPlaceOrder').attr("disabled", status);
            },

            /**
             * @returns {void}
             */
            reloadEmbeddedForm: function() {
                // Get self
                var self = this;

                // Reload the iframe
                $('#cko-form-holder form iframe').remove();
                self.getEmbeddedForm();
            },
        });
    }
);<commit_msg>Updated quote calculation function in embedded integration.<commit_after>/**
 * Checkout.com Magento 2 Payment module (https://www.checkout.com)
 *
 * Copyright (c) 2017 Checkout.com (https://www.checkout.com)
 * Author: David Fiaty | integration@checkout.com
 *
 * License GNU/GPL V3 https://www.gnu.org/licenses/gpl-3.0.en.html
 */

/*browser:true*/
/*global define*/

define(
    [
        'jquery',
        'CheckoutCom_Magento2/js/view/payment/method-renderer/cc-form',
        'Magento_Vault/js/view/payment/vault-enabler',
        'CheckoutCom_Magento2/js/view/payment/adapter',
        'Magento_Checkout/js/model/quote',
        'Magento_Ui/js/model/messageList',
        'mage/url',
        'Magento_Checkout/js/action/set-payment-information',
        'Magento_Checkout/js/model/full-screen-loader',
        'Magento_Checkout/js/model/payment/additional-validators',
        'Magento_Checkout/js/checkout-data',
        'Magento_Checkout/js/action/redirect-on-success'
    ],
    function($, Component, VaultEnabler, CheckoutCom, quote, globalMessages, url, setPaymentInformationAction, fullScreenLoader, additionalValidators, checkoutData, redirectOnSuccessAction, customer) {
        'use strict';

        window.checkoutConfig.reloadOnBillingAddress = true;

        return Component.extend({
            defaults: {
                active: true,
                template: 'CheckoutCom_Magento2/payment/embedded',
                code: 'checkout_com',
                card_token_id: null,
                redirectAfterPlaceOrder: true,
                card_bin: null
            },

            /**
             * @returns {exports}
             */
            initialize: function(config, messageContainer) {
                this._super();
                this.initObservable();
                this.messageContainer = messageContainer || config.messageContainer || globalMessages;

                this.vaultEnabler = new VaultEnabler();
                this.vaultEnabler.setPaymentCode(this.getVaultCode());

                return this;
            },

            /**
             * @returns {exports}
             */
            initObservable: function () {
                this._super()
                    .observe('isHidden');

                return this;
            },

            /**
             * @returns {bool}
             */
            isVisible: function () {
                return this.isHidden(this.messageContainer.hasMessages());
            },

            /**
             * @returns {bool}
             */
            removeAll: function () {
                this.messageContainer.clear();
            },

            /**
             * @returns {void}
             */
            onHiddenChange: function (isHidden) {
                var self = this;
                // Hide message block if needed
                if (isHidden) {
                    setTimeout(function () {
                        $(self.selector).hide('blind', {}, 500)
                    }, 10000);
                }
            },

            /**
             * @returns {bool}
             */
            isVaultEnabled: function() {
                return this.vaultEnabler.isVaultEnabled();
            },

            /**
             * @returns {string}
             */
            getVaultCode: function() {
                return window.checkoutConfig.payment[this.getCode()].ccVaultCode;
            },

            /**
             * @returns {string}
             */
            getCode: function() {
                return CheckoutCom.getCode();
            },

            /**
             * @param {string} card_token_id
             */
            setCardTokenId: function(card_token_id) {
                this.card_token_id = card_token_id;
            },

            /**
             * @returns {bool}
             */
            isActive: function() {
                return CheckoutCom.getPaymentConfig()['isActive'];
            },

            /**
             * @returns {string}
             */
            getPublicKey: function() {
                return CheckoutCom.getPaymentConfig()['public_key'];
            },

            /**
             * @returns {string}
             */
            getQuoteValue: function() {
                return (quote.getTotals()().grand_total*100).toFixed(2);
            },

            /**
             * @returns {string}
             */
            getQuoteCurrency: function() {
                return CheckoutCom.getPaymentConfig()['quote_currency'];
            },

            /**
             * @returns {bool}
             */
            isCardAutosave: function() {
                return CheckoutCom.getPaymentConfig()['card_autosave'];
            },

            /**
             * @returns {string}
             */
            getRedirectUrl: function() {
                return url.build('checkout_com/payment/placeOrder');
            },

            /**
             * @returns {void}
             */
            saveSessionData: function() {
                // Get self
                var self = this;

                // Prepare the session data
                var sessionData = {
                    saveShopperCard: $('#checkout_com_enable_vault').is(":checked"),
                    customerEmail: self.getEmailAddress(),
                    cardBin: self.card_bin
                };

                // Send the session data to be saved
                $.ajax({
                    url: url.build('checkout_com/shopper/sessionData'),
                    type: "POST",
                    data: sessionData,
                    success: function(data, textStatus, xhr) {},
                    error: function(xhr, textStatus, error) {} // todo - improve error handling
                });
            },

            /**
             * @returns {string}
             */
            beforePlaceOrder: function() {
                // Get self
                var self = this;

                // Get the form
                var paymentForm = document.getElementById('embeddedForm');

                // Validate before submission
                if (additionalValidators.validate()) {
                    if (Frames.isCardValid()) {
                        // Start the loader
                        fullScreenLoader.startLoader();

                        // Submit frames form
                        Frames.submitCard();
                    }
                }
            },

            /**
             * @override
             */
            placeOrder: function() {
                var self = this;

                $.migrateMute = true;

                this.updateButtonState(false);
                this.getPlaceOrderDeferredObject()
                .fail(
                    function() {
                        self.updateButtonState(true);
                        $('html, body').animate({ scrollTop: 0 }, 'fast');
                        self.reloadEmbeddedForm();
                    }
                ).done(
                    function() {
                        self.afterPlaceOrder();

                        if (self.redirectAfterPlaceOrder) {
                            redirectOnSuccessAction.execute();
                        }
                    }
                );
            },

            /**
             * @returns {void}
             */
            getEmbeddedForm: function() {
                // Get self
                var self = this;

                // Prepare parameters
                var ckoTheme = CheckoutCom.getPaymentConfig()['embedded_theme'];
                var css_file = CheckoutCom.getPaymentConfig()['css_file'];
                var custom_css = CheckoutCom.getPaymentConfig()['custom_css'];
                var ckoThemeOverride = ((custom_css) && custom_css !== '' && css_file == 'custom') ? custom_css : undefined;
                var redirectUrl = self.getRedirectUrl();
                var threeds_enabled = CheckoutCom.getPaymentConfig()['three_d_secure']['enabled'];
                var paymentForm = document.getElementById('embeddedForm');

                // Freeze the place order button on initialisation
                $('#ckoPlaceOrder').attr("disabled",true);

                // Initialise the embedded form
                Frames.init({
                    publicKey: self.getPublicKey(),
                    containerSelector: '#cko-form-holder',
                    theme: ckoTheme,
                    debugMode: CheckoutCom.getPaymentConfig()['debug_mode'],
                    themeOverride: ckoThemeOverride,
                    frameActivated: function () {
                        $('#ckoPlaceOrder').attr("disabled", true);
                    },
                    cardValidationChanged: function() {
                        self.updateButtonState(!(Frames.isCardValid() && quote.billingAddress() != null));
                    },
                    cardTokenised: function(event) {
                        // Keep the card info
                        self.card_bin = event.data.card.bin;

                        // Save checkout info in PHP session
                        self.saveSessionData();

                        // Set the card token
                        self.setCardTokenId(event.data.cardToken);

                        // Add the card token to the form
                        Frames.addCardToken(paymentForm, event.data.cardToken);

                        // Place order
                        window.location.replace(redirectUrl + '?cko-card-token=' + event.data.cardToken + '&cko-context-id=' + self.getEmailAddress());
                    },
                });
            },

            /**
             * @returns {void}
             */
            updateButtonState: function(status) {
                $('#ckoPlaceOrder').attr("disabled", status);
            },

            /**
             * @returns {void}
             */
            reloadEmbeddedForm: function() {
                // Get self
                var self = this;

                // Reload the iframe
                $('#cko-form-holder form iframe').remove();
                self.getEmbeddedForm();
            },
        });
    }
);<|endoftext|>


<commit_before>const {search, utilities} = require('pathway-commons');
const path = require('path');
const _ = require('lodash');
const getHGNCData = require('./hgnc');

const sanitize = (s) => {
  // Escape (with '\'), to treat them literally, symbols, such as '*', ':', or space,
  // which otherwise play special roles in a Lucene query string.
  return s.replace(/([\!\*\+\-\&\|\(\)\[\]\{\}\^\~\?\:\/\\"\s])/g, '\\$1')
};

const processPhrase = (phrase) => {
  const sourceList = [
    'uniprot',
    'chebi',
    'smpdb',
    'refseq'
  ];

  const tokens = phrase.toUpperCase().split(/\s+/g);

  return getHGNCData(path.join(__dirname,'/hgncSymbols.txt')).then(collection => {
    return tokens.map(token => {
      //if symbol is recognized by at least one source
      const recognized = sourceList.some(source => utilities.sourceCheck(source, token))
                              || collection.has(token.toUpperCase());
      const sanitized = sanitize(token);
      return recognized ? ( 'xrefid:' + sanitized ) : ( 'name:' + '*' + sanitized + '*' );
    });
  });
};

const processQueryString = async (queryString) => {
  const keywords = await processPhrase(queryString);
  const phrase = sanitize(queryString);
  // return three query candidates to search, first query is fastest, last query slowest
  return [
    '(name:' + phrase + ') OR (' + 'name:*' + phrase + '*) OR (' + keywords.join(' AND ') + ')',
    '(' + keywords.join(' OR ') + ')',
    queryString //"as is" (Lucene query syntax enabled)
  ];
};

// needs query object with the following values:
//  - q: string to search
//  - type: the type of bioPAX class to get
//  - lt: max graph size result returned
//  - gt: min graph size result returned

const querySearch = async (query) => {
  const minSize = query.gt || 0; //TODO: why 250?
  const maxSize = query.lt || 250;

  const queries = await processQueryString(query.q.trim());
    for (let q of queries) {
    const searchResult = await search()
      .query(query) //input query string
      .q(q)
      .format('json')
      .fetch();

    const searchSuccess = searchResult != null;
    if (searchSuccess && searchResult.searchHit.length > 0) {
      const filteredResults = searchResult.searchHit.filter(hit => {
        const size = hit.numParticipants ? hit.numParticipants : 0;
        return minSize < size && size < maxSize;
      });
      if (filteredResults.length > 0) {
        return filteredResults;
      }
    }
  }

  return [];
};

const uniprotIdSearch = async (query) => {
  const queries = await (processPhrase(sanitize(query.q.trim())));
  const filteredQueries = queries.filter(entry=>entry.includes('xrefid'));
  if(!_.isEmpty(filteredQueries)){
    const searchResult = await search()
      .query(query) //input query string
      .q(filteredQueries)
      .format('json')
      .fetch();
    const searchSuccess = searchResult != null
    if (searchSuccess && searchResult.searchHit.length > 0) {
      console.log(searchResult);
      const filteredResults = searchResult.searchHit.filter(hit =>
        hit.uri.startsWith('http://identifiers.org/uniprot/')
      );
      return filteredResults.map(hit=>_.last(hit.uri.split('/'))); //Parses and returns the Uniprot id
    }
  }
  return [];
};
module.exports = {querySearch:querySearch,uniprotIdSearch:uniprotIdSearch};<commit_msg>Removed left over log call.<commit_after>const {search, utilities} = require('pathway-commons');
const path = require('path');
const _ = require('lodash');
const getHGNCData = require('./hgnc');

const sanitize = (s) => {
  // Escape (with '\'), to treat them literally, symbols, such as '*', ':', or space,
  // which otherwise play special roles in a Lucene query string.
  return s.replace(/([\!\*\+\-\&\|\(\)\[\]\{\}\^\~\?\:\/\\"\s])/g, '\\$1')
};

const processPhrase = (phrase) => {
  const sourceList = [
    'uniprot',
    'chebi',
    'smpdb',
    'refseq'
  ];

  const tokens = phrase.toUpperCase().split(/\s+/g);

  return getHGNCData(path.join(__dirname,'/hgncSymbols.txt')).then(collection => {
    return tokens.map(token => {
      //if symbol is recognized by at least one source
      const recognized = sourceList.some(source => utilities.sourceCheck(source, token))
                              || collection.has(token.toUpperCase());
      const sanitized = sanitize(token);
      return recognized ? ( 'xrefid:' + sanitized ) : ( 'name:' + '*' + sanitized + '*' );
    });
  });
};

const processQueryString = async (queryString) => {
  const keywords = await processPhrase(queryString);
  const phrase = sanitize(queryString);
  // return three query candidates to search, first query is fastest, last query slowest
  return [
    '(name:' + phrase + ') OR (' + 'name:*' + phrase + '*) OR (' + keywords.join(' AND ') + ')',
    '(' + keywords.join(' OR ') + ')',
    queryString //"as is" (Lucene query syntax enabled)
  ];
};

// needs query object with the following values:
//  - q: string to search
//  - type: the type of bioPAX class to get
//  - lt: max graph size result returned
//  - gt: min graph size result returned

const querySearch = async (query) => {
  const minSize = query.gt || 0; //TODO: why 250?
  const maxSize = query.lt || 250;

  const queries = await processQueryString(query.q.trim());
    for (let q of queries) {
    const searchResult = await search()
      .query(query) //input query string
      .q(q)
      .format('json')
      .fetch();

    const searchSuccess = searchResult != null;
    if (searchSuccess && searchResult.searchHit.length > 0) {
      const filteredResults = searchResult.searchHit.filter(hit => {
        const size = hit.numParticipants ? hit.numParticipants : 0;
        return minSize < size && size < maxSize;
      });
      if (filteredResults.length > 0) {
        return filteredResults;
      }
    }
  }

  return [];
};

const uniprotIdSearch = async (query) => {
  const queries = await (processPhrase(sanitize(query.q.trim())));
  const filteredQueries = queries.filter(entry=>entry.includes('xrefid'));
  if(!_.isEmpty(filteredQueries)){
    const searchResult = await search()
      .query(query) //input query string
      .q(filteredQueries)
      .format('json')
      .fetch();
    const searchSuccess = searchResult != null
    if (searchSuccess && searchResult.searchHit.length > 0) {
      const filteredResults = searchResult.searchHit.filter(hit =>
        hit.uri.startsWith('http://identifiers.org/uniprot/')
      );
      return filteredResults.map(hit=>_.last(hit.uri.split('/'))); //Parses and returns the Uniprot id
    }
  }
  return [];
};
module.exports = {querySearch:querySearch,uniprotIdSearch:uniprotIdSearch};<|endoftext|>


<commit_before>import angular from "angular";

import won from "../../won-es6.js";
import { connect2Redux } from "../../won-utils.js";
import { attach, get, getIn } from "../../utils.js";
import { actionCreators } from "../../actions/actions.js";
import { selectNeedByConnectionUri } from "../../selectors.js";
import trigModule from "../trig.js";
import { labels } from "../../won-label-utils.js";

import "style/_combined-message-content.scss";

const serviceDependencies = ["$ngRedux", "$scope"];

function genComponentConf() {
  let template = `

{{ self.getHeaderLabel() }}

      <won-message-content
          ng-if="self.hasContent"
          message-uri="self.messageUri"
          connection-uri="self.connectionUri">
      </won-message-content>
      <won-referenced-message-content
          ng-if="self.hasReferences"
          message-uri="self.messageUri"
          connection-uri="self.connectionUri">
      </won-referenced-message-content>
      <won-trig
          trig="self.contentGraphTrig"
          ng-if="self.shouldShowRdf && self.contentGraphTrig">
      </won-trig>
    `;

  class Controller {
    constructor(/* arguments = dependency injections */) {
      attach(this, serviceDependencies, arguments);

      const selectFromState = state => {
        const ownNeed =
          this.connectionUri &&
          selectNeedByConnectionUri(state, this.connectionUri);
        const connection =
          ownNeed && ownNeed.getIn(["connections", this.connectionUri]);
        const message =
          connection &&
          this.messageUri &&
          getIn(connection, ["messages", this.messageUri]);

        const messageType = message && message.get("messageType");

        return {
          contentGraphTrig: get(message, "contentGraphTrigRaw"),
          shouldShowRdf: state.get("showRdf"),
          hasContent: message && message.get("hasContent"),
          hasReferences: message && message.get("hasReferences"),
          messageType,
          isConnectionMessage: messageType === won.WONMSG.connectionMessage,
        };
      };

      connect2Redux(
        selectFromState,
        actionCreators,
        ["self.connectionUri", "self.messageUri"],
        this
      );
    }

    getHeaderLabel() {
      const headerLabel = labels.messageType[this.messageType];
      return headerLabel || this.messageType;
    }
  }
  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {
      messageUri: "=",
      connectionUri: "=",
    },
    template: template,
  };
}

export default angular
  .module("won.owner.components.combinedMessageContent", [trigModule])
  .directive("wonCombinedMessageContent", genComponentConf).name;
<commit_msg>add visibility of message-content when the message has not been loaded yet, otherwise we do not have the "click to load message label"<commit_after>import angular from "angular";

import won from "../../won-es6.js";
import { connect2Redux } from "../../won-utils.js";
import { attach, get, getIn } from "../../utils.js";
import { actionCreators } from "../../actions/actions.js";
import { selectNeedByConnectionUri } from "../../selectors.js";
import trigModule from "../trig.js";
import { labels } from "../../won-label-utils.js";

import "style/_combined-message-content.scss";

const serviceDependencies = ["$ngRedux", "$scope"];

function genComponentConf() {
  let template = `

{{ self.getHeaderLabel() }}

      <won-message-content
          ng-if="self.hasContent || self.hasNotBeenLoadedYet"
          message-uri="self.messageUri"
          connection-uri="self.connectionUri">
      </won-message-content>
      <won-referenced-message-content
          ng-if="self.hasReferences"
          message-uri="self.messageUri"
          connection-uri="self.connectionUri">
      </won-referenced-message-content>
      <won-trig
          trig="self.contentGraphTrig"
          ng-if="self.shouldShowRdf && self.contentGraphTrig">
      </won-trig>
    `;

  class Controller {
    constructor(/* arguments = dependency injections */) {
      attach(this, serviceDependencies, arguments);

      const selectFromState = state => {
        const ownNeed =
          this.connectionUri &&
          selectNeedByConnectionUri(state, this.connectionUri);
        const connection =
          ownNeed && ownNeed.getIn(["connections", this.connectionUri]);
        const message =
          connection &&
          this.messageUri &&
          getIn(connection, ["messages", this.messageUri]);

        const messageType = message && message.get("messageType");

        return {
          contentGraphTrig: get(message, "contentGraphTrigRaw"),
          shouldShowRdf: state.get("showRdf"),
          hasContent: message && message.get("hasContent"),
          hasNotBeenLoadedYet: !message,
          hasReferences: message && message.get("hasReferences"),
          messageType,
          isConnectionMessage: messageType === won.WONMSG.connectionMessage,
        };
      };

      connect2Redux(
        selectFromState,
        actionCreators,
        ["self.connectionUri", "self.messageUri"],
        this
      );
    }

    getHeaderLabel() {
      const headerLabel = labels.messageType[this.messageType];
      return headerLabel || this.messageType;
    }
  }
  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {
      messageUri: "=",
      connectionUri: "=",
    },
    template: template,
  };
}

export default angular
  .module("won.owner.components.combinedMessageContent", [trigModule])
  .directive("wonCombinedMessageContent", genComponentConf).name;
<|endoftext|>


<commit_before>function Game(options) {
	var defaults = {
		selector: '#game',
		board: {
			width: 600,
			height: 600,
			radius: 35
		},
		margin: {
			top: 50,
			bottom: 50
		},
		delay: 300
	};
	this.options = $.extend({}, defaults, options);
	this.divWidth = $(this.options.selector).width();
	this.options.margin.left = this.options.margin.right = Math.max(this.divWidth - this.options.board.width, 0) / 2;
	this.done = false;
	this.initializeSvg();
	this.initializeData();
	this.initializeAIViz();
	this.initializeAI();
	var me = this;
	$('input').change(function() {
		me.initializeAI();
	});
}

Game.prototype.initializeSvg = function() {
	d3.select(this.options.selector).selectAll('svg').remove();
	this.svg = d3.select(this.options.selector).append('svg').attr('width', this.divWidth).attr('height', this.options.board.height + this.options.margin.top + this.options.margin.bottom);
	this.scale = d3.scale.quantize().domain([-1, 0, 1]).range(['red', 'none', 'steelblue']);
	this.aiScale = d3.scale.linear().range(['red', '#BBB', 'green']);
};

Game.prototype.initializeData = function() {
	var me = this;
	this.cData = d3.range(42).map(function(d) {
		return {
			r: me.options.board.radius,
			x: (0.5 + d % 7) * me.options.board.width / 7,
			y: me.options.board.height - (Math.floor(d / 7) + 1) * me.options.board.height / 7,
			id: d,
			val: 0
		};
	});
	this.slots = this.svg.selectAll('.slots').data(me.cData).enter().append('circle').attr('class', 'slots')
		.attr('r', function(d) {
			return d.r;
		}).attr('cx', function(d) {
			return d.x + me.options.margin.left;
		})
		.attr('cy', function(d) {
			return d.y + me.options.margin.top;
		});
	this.sData = {
		r: me.options.board.radius,
		pos: 0
	};
	this.aiData = d3.range(7).map(function(d) {
		return {
			w: me.options.board.radius * 2,
			h: me.options.board.radius,
			x: (0.5 + d) * me.options.board.width / 7 - me.options.board.radius,
			y: me.options.board.height * 6 / 7 + me.options.board.radius + 5,
			i: d
		};
	});
};

Game.prototype.initializeAIViz = function() {
	var me = this;
	this.aiRectangles = me.svg.selectAll('.ai').data(me.aiData).enter().append('rect').attr('width', function(d) {
			return d.w;
		})
		.attr('height', function(d) {
			return d.h;
		}).attr('transform', function(d) {
			return 'translate(' + (me.options.margin.left + d.x) + ',' + (me.options.margin.top + d.y) + ')';
		})
		.style('fill', '#BBB');
	this.aiText = me.svg.selectAll('.aiText').data(me.aiData).enter().append('text').attr('class', 'aiText')
		.attr('transform', function(d) {
			return 'translate(' + (me.options.margin.left + d.x + d.w / 2) + ',' + (me.options.margin.top + d.y + d.h / 2 + 7.5) + ')';
		})
		.text('0');
};

Game.prototype.initializeAI = function() {
	var aiOptions = {
		win: parseInt($('#win').val()),
		lose: parseInt($('#lose').val()),
		tie: parseInt($('#tie').val()),
		multiplier: parseInt($('#mult').val()) / 10,
		depth: parseInt($('#depth').val())
	};
	this.ai = new AI(aiOptions, this);
};

Game.prototype.initUser = function() {
	var me = this;
	this.selector = me.svg.append('circle').attr('class', 'slots selector').attr('r', me.sData.r)
		.attr('cx', me.options.margin.left + (0.5 + me.sData.pos) * me.options.board.width / 7).attr('cy', me.options.margin.top)
		.style('fill', 'steelblue');
	$(document).keydown(function(e) {
		if (e.keyCode === 37) {
			me.moveSelector(-1);
			return false;
		} else if (e.keyCode === 39) {
			me.moveSelector(1);
			return false;
		} else if (e.keyCode === 32) {
			me.select();
			return false;
		}
	});
};

Game.prototype.moveSelector = function(move) {
	var me = this;
	me.sData.pos = (me.sData.pos + move + 7) % 7;
	me.selector.transition().duration(me.options.delay).attr('cx', me.options.margin.left + (0.5 + me.sData.pos) * me.options.board.width / 7);
};

Game.prototype.select = function() {
	var me = this;
	var board = new Board(me.slots.data());
	if (board.isValidMove(me.sData.pos) && !me.done) {
		var row = board.getRow(me.sData.pos);
		board.board[row][me.sData.pos] = 1;
		me.updateBoard((5 - row) * 7 + me.sData.pos, 1);
		if (board.checkWin(row, me.sData.pos, 1)) {
			me.gameEnd(true);
		} else {
			setTimeout(function() {
				var comp = me.ai.move(board);
				board.board[comp.r][comp.c] = -1;
				me.updateBoard((5 - comp.r) * 7 + comp.c, -1);
				if (board.checkWin(comp.r, comp.c, -1)) {
					me.gameEnd(false);
				}
			}, me.options.delay);
		}
	}
};

Game.prototype.initAIvAI = function() {
	var me = this;
	d3.select('#start').on('click', function() {
		me.board = new Board(me.cData);
		me.aiPlay(true);
	});
};

Game.prototype.aiPlay = function(isFirst) {
	var aiOptions = isFirst ? {
		win: parseInt($('#win').val()),
		lose: parseInt($('#lose').val()),
		tie: parseInt($('#tie').val()),
		multiplier: parseInt($('#mult').val()) / 10,
		depth: parseInt($('#depth').val())
	} : {
		win: parseInt($('#win2').val()),
		lose: parseInt($('#lose2').val()),
		tie: parseInt($('#tie2').val()),
		multiplier: parseInt($('#mult2').val()) / 10,
		depth: parseInt($('#depth2').val())
	};
	var ai = new AI(aiOptions, this);
	var me = this;
	var val = isFirst ? 1 : -1;
	var comp = ai.move(me.board);
	me.board.board[comp.r][comp.c] = val;
	me.updateBoard((5 - comp.r) * 7 + comp.c, val);
	if (me.board.checkWin(comp.r, comp.c, val)) {
		me.done = true;
	} else if ($('#auto').is(':checked')) {
		setTimeout(function() {
			me.aiPlay(!isFirst);
		}, me.options.delay);
	}
};

Game.prototype.updateBoard = function(id, value) {
	var me = this;
	this.cData.filter(function(d) {
		return d.id === id;
	})[0].val = value;
	this.slots.data(me.cData).transition().duration(me.options.delay).style('fill', function(d) {
		return me.scale(d.val);
	});
};

Game.prototype.updateAI = function(moves) {
	var me = this;
	var e = d3.extent(moves);
	me.aiScale.domain([e[0], (e[0] + e[1]) / 2, e[1]]);
	me.aiRectangles.transition().duration(me.options.delay).style('fill', function(d) {
		return moves[d.i] !== null ? me.aiScale(moves[d.i]) : 'black';
	});
	me.aiText.text(function(d) {
		return moves[d.i] !== null ? Math.floor(moves[d.i] * 100) / 100 : 0;
	});
};

Game.prototype.gameEnd = function(userWin) {
	this.done = true;
	$('#modalContent').html('
You ' + (userWin ? 'Won' : 'Lost') + '!
');
	$('#gameEnd').reveal({
		animation: 'fadeAndPop',
		animationspeed: 300,
		closeonbackgroundclick: true,
		dismissmodalclass: 'close'
	});
};
<commit_msg>Start slot fills as white instead of black<commit_after>function Game(options) {
	var defaults = {
		selector: '#game',
		board: {
			width: 600,
			height: 600,
			radius: 35
		},
		margin: {
			top: 50,
			bottom: 50
		},
		delay: 300
	};
	this.options = $.extend({}, defaults, options);
	this.divWidth = $(this.options.selector).width();
	this.options.margin.left = this.options.margin.right = Math.max(this.divWidth - this.options.board.width, 0) / 2;
	this.done = false;
	this.initializeSvg();
	this.initializeData();
	this.initializeAIViz();
	this.initializeAI();
	var me = this;
	$('input').change(function() {
		me.initializeAI();
	});
}

Game.prototype.initializeSvg = function() {
	d3.select(this.options.selector).selectAll('svg').remove();
	this.svg = d3.select(this.options.selector).append('svg').attr('width', this.divWidth).attr('height', this.options.board.height + this.options.margin.top + this.options.margin.bottom);
	this.scale = d3.scale.quantize().domain([-1, 0, 1]).range(['red', 'white', 'steelblue']);
	this.aiScale = d3.scale.linear().range(['red', '#BBB', 'green']);
};

Game.prototype.initializeData = function() {
	var me = this;
	this.cData = d3.range(42).map(function(d) {
		return {
			r: me.options.board.radius,
			x: (0.5 + d % 7) * me.options.board.width / 7,
			y: me.options.board.height - (Math.floor(d / 7) + 1) * me.options.board.height / 7,
			id: d,
			val: 0
		};
	});
	this.slots = this.svg.selectAll('.slots').data(me.cData).enter().append('circle').attr('class', 'slots')
		.attr('r', function(d) {
			return d.r;
		}).attr('cx', function(d) {
			return d.x + me.options.margin.left;
		})
		.attr('cy', function(d) {
			return d.y + me.options.margin.top;
		});
	this.sData = {
		r: me.options.board.radius,
		pos: 0
	};
	this.aiData = d3.range(7).map(function(d) {
		return {
			w: me.options.board.radius * 2,
			h: me.options.board.radius,
			x: (0.5 + d) * me.options.board.width / 7 - me.options.board.radius,
			y: me.options.board.height * 6 / 7 + me.options.board.radius + 5,
			i: d
		};
	});
};

Game.prototype.initializeAIViz = function() {
	var me = this;
	this.aiRectangles = me.svg.selectAll('.ai').data(me.aiData).enter().append('rect').attr('width', function(d) {
			return d.w;
		})
		.attr('height', function(d) {
			return d.h;
		}).attr('transform', function(d) {
			return 'translate(' + (me.options.margin.left + d.x) + ',' + (me.options.margin.top + d.y) + ')';
		})
		.style('fill', '#BBB');
	this.aiText = me.svg.selectAll('.aiText').data(me.aiData).enter().append('text').attr('class', 'aiText')
		.attr('transform', function(d) {
			return 'translate(' + (me.options.margin.left + d.x + d.w / 2) + ',' + (me.options.margin.top + d.y + d.h / 2 + 7.5) + ')';
		})
		.text('0');
};

Game.prototype.initializeAI = function() {
	var aiOptions = {
		win: parseInt($('#win').val()),
		lose: parseInt($('#lose').val()),
		tie: parseInt($('#tie').val()),
		multiplier: parseInt($('#mult').val()) / 10,
		depth: parseInt($('#depth').val())
	};
	this.ai = new AI(aiOptions, this);
};

Game.prototype.initUser = function() {
	var me = this;
	this.selector = me.svg.append('circle').attr('class', 'slots selector').attr('r', me.sData.r)
		.attr('cx', me.options.margin.left + (0.5 + me.sData.pos) * me.options.board.width / 7).attr('cy', me.options.margin.top)
		.style('fill', 'steelblue');
	$(document).keydown(function(e) {
		if (e.keyCode === 37) {
			me.moveSelector(-1);
			return false;
		} else if (e.keyCode === 39) {
			me.moveSelector(1);
			return false;
		} else if (e.keyCode === 32) {
			me.select();
			return false;
		}
	});
};

Game.prototype.moveSelector = function(move) {
	var me = this;
	me.sData.pos = (me.sData.pos + move + 7) % 7;
	me.selector.transition().duration(me.options.delay).attr('cx', me.options.margin.left + (0.5 + me.sData.pos) * me.options.board.width / 7);
};

Game.prototype.select = function() {
	var me = this;
	var board = new Board(me.slots.data());
	if (board.isValidMove(me.sData.pos) && !me.done) {
		var row = board.getRow(me.sData.pos);
		board.board[row][me.sData.pos] = 1;
		me.updateBoard((5 - row) * 7 + me.sData.pos, 1);
		if (board.checkWin(row, me.sData.pos, 1)) {
			me.gameEnd(true);
		} else {
			setTimeout(function() {
				var comp = me.ai.move(board);
				board.board[comp.r][comp.c] = -1;
				me.updateBoard((5 - comp.r) * 7 + comp.c, -1);
				if (board.checkWin(comp.r, comp.c, -1)) {
					me.gameEnd(false);
				}
			}, me.options.delay);
		}
	}
};

Game.prototype.initAIvAI = function() {
	var me = this;
	d3.select('#start').on('click', function() {
		me.board = new Board(me.cData);
		me.aiPlay(true);
	});
};

Game.prototype.aiPlay = function(isFirst) {
	var aiOptions = isFirst ? {
		win: parseInt($('#win').val()),
		lose: parseInt($('#lose').val()),
		tie: parseInt($('#tie').val()),
		multiplier: parseInt($('#mult').val()) / 10,
		depth: parseInt($('#depth').val())
	} : {
		win: parseInt($('#win2').val()),
		lose: parseInt($('#lose2').val()),
		tie: parseInt($('#tie2').val()),
		multiplier: parseInt($('#mult2').val()) / 10,
		depth: parseInt($('#depth2').val())
	};
	var ai = new AI(aiOptions, this);
	var me = this;
	var val = isFirst ? 1 : -1;
	var comp = ai.move(me.board);
	me.board.board[comp.r][comp.c] = val;
	me.updateBoard((5 - comp.r) * 7 + comp.c, val);
	if (me.board.checkWin(comp.r, comp.c, val)) {
		me.done = true;
	} else if ($('#auto').is(':checked')) {
		setTimeout(function() {
			me.aiPlay(!isFirst);
		}, me.options.delay);
	}
};

Game.prototype.updateBoard = function(id, value) {
	var me = this;
	this.cData.filter(function(d) {
		return d.id === id;
	})[0].val = value;
	this.slots.data(me.cData).transition().duration(me.options.delay).style('fill', function(d) {
		return me.scale(d.val);
	});
};

Game.prototype.updateAI = function(moves) {
	var me = this;
	var e = d3.extent(moves);
	me.aiScale.domain([e[0], (e[0] + e[1]) / 2, e[1]]);
	me.aiRectangles.transition().duration(me.options.delay).style('fill', function(d) {
		return moves[d.i] !== null ? me.aiScale(moves[d.i]) : 'black';
	});
	me.aiText.text(function(d) {
		return moves[d.i] !== null ? Math.floor(moves[d.i] * 100) / 100 : 0;
	});
};

Game.prototype.gameEnd = function(userWin) {
	this.done = true;
	$('#modalContent').html('
You ' + (userWin ? 'Won' : 'Lost') + '!
');
	$('#gameEnd').reveal({
		animation: 'fadeAndPop',
		animationspeed: 300,
		closeonbackgroundclick: true,
		dismissmodalclass: 'close'
	});
};
<|endoftext|>


<commit_before>/**
 * The SidebarNavView view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps'
], function($,Backbone, _,mps) {

  'use strict';

  var SidebarNavModel = Backbone.Model.extend({
    defaults: {
      section: null,
      t: null,
      interesting: null
    }
  });

  var SidebarNavView = Backbone.View.extend({

    el: '#sidebarNavView',

    events: {
      'click .nav-item' : 'changeSourceNav',
      'click .nav-title' : 'scrollTo',
      'click .source_header' : 'toggleSources',
      'click .source_dropdown_header' : 'toggleDropdown',
      'click .source_dropdown_menu a' : 'showSubContent',
      'click #back-btn' : 'returnBack'
    },

    initialize: function() {
      if (!this.$el.length) {
        return
      }

      this.model = new SidebarNavModel();

      //CACHE
      this.$window = $(window);
      this.$document = $(document);
      this.$htmlbody = $('html,body');
      this.$headerH1 = $('#headerView').find('h1');
      this.$backBtn = $('#back-btn');
      this.$navItem = this.$el.find('.nav-item');
      this.$sideBarAside = $('#sidebarAside');
      this.$sideBarBox = $('#sources-box');
      this.$sourceArticle = $('.source-article');
      this.$sourceHeader = $('.source_header');
      this.$sourceBody = $('.source_body');
      this.$cut = $('#cut');
      this.$sourceSpinner = $('#sources-spinner');

      //VARS
      this.padding = 40;
      this.first = true;
      this.mobile = (this.$window.width() > 850) ? false : true;

      //INIT
      this.setListeners();
    },

    setListeners: function(){
      this.calculateOffsets();
      this.scrollDocument();
      this.$document.on('scroll',_.bind(this.scrollDocument,this));
      this.$window.on('resize',_.bind(this.calculateOffsets,this));

      mps.subscribe('SourceStatic/change',_.bind(this.changeSource,this));
      mps.subscribe('SubItem/change',_.bind(this.calculateOffsets,this));
    },

    calculateOffsets: function(){
      this.$sideBarBox.css({'min-height': this.$sideBarAside.height() });
      this.offset = this.$el.offset().top + parseInt(this.$el.css('paddingTop'), 10);
      this.offsetBottom = this.$cut.offset().top - this.$sideBarAside.height() - this.padding;
    },

    scrollDocument: function(e){
      var scrollTop = this.$document.scrollTop();
      if (scrollTop > this.offset) {
        this.$sideBarBox.addClass('fixed');
        this.firstFixed = false;
        if(scrollTop < this.offsetBottom) {
          this.$sideBarAside.removeClass('bottom').addClass('fixed');
        }else{
          this.$sideBarAside.removeClass('fixed').addClass('bottom');
        }
      }else{
        this.$sideBarAside.removeClass('fixed bottom');
        this.$sideBarBox.removeClass('fixed');
        this.firstFixed = true;
      }
    },

    changeSourceNav: function(e){
      e && e.preventDefault();
      this.model.set('section',$(e.currentTarget).data('slug'));
      this.model.set('interesting', $(e.currentTarget).data('interesting'));
      this.model.set('t',null);
      this.updateSource();
    },
    toggleSources: function(e){
      ($(e.currentTarget).hasClass('active')) ? this.model.set('t', null) : this.model.set('t', $(e.currentTarget).parent().attr('id'));
      this.$sourceHeader.removeClass('active');
      this.$sourceBody.hide(0);
      this.updateSource();
    },

    toggleDropdown: function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').toggle(0);
    },

    updateSource: function(){
      var params = {
        section: this.model.get('section'),
        interesting: this.model.get('interesting'),
        t: this.model.get('t')
      }
      console.log(params);
      mps.publish('SourceStatic/update',[params]);
    },

    changeSource: function(params){
      //spinner
      this.$sourceSpinner.removeClass('start');
      if (params.section) {
        this.model.set('section', params.section);
        this.model.set('interesting', params.interesting);
        (params.t) ? this.model.set('t', params.t) : null;
        mps.publish('Interesting/update',[this.model.get('interesting')]);
        this.changeHelper();
      }else{
        if (!this.mobile) {
          var section = this.$navItem.eq(0).data('slug');
          this.model.set('section', section);
        }
        var interesting = this.$navItem.eq(0).data('interesting');
        this.model.set('interesting', interesting);
        mps.publish('Interesting/update',[interesting]);
        this.changeHelper();
      }

    },

    changeHelper: function(){
      var section = this.model.get('section'), tab = this.model.get('t'), $tab = $('#'+tab);

      this.$sideBarBox.addClass('active');
      this.$backBtn.addClass('active');

      //aside
      this.$navItem.removeClass('selected');
      $('.'+section).addClass('selected');

      //section
      this.$sourceArticle.removeClass('selected');
      $('#'+section).addClass('selected');

      //tab
      if (tab) {
        this.$htmlbody.animate({ scrollTop: $tab.offset().top },0, _.bind(function(){
          $tab.find('.source_header').addClass('active');
          $tab.find('.source_body').show(0);
          this.calculateOffsets();
        }, this ));
      }else{
        this.$htmlbody.animate({ scrollTop: this.$sideBarBox.offset().top - this.padding },0, _.bind(function(){
          $tab.find('.source_header').addClass('active');
          $tab.find('.source_body').show(0);
          this.calculateOffsets();
        }, this ));
      }

      setTimeout(_.bind(function(){
        this.calculateOffsets();
      },this),200);

      // if(this.mobile && !tab) {
      //   // this.$sideBarBox.animate({ scrollTop: 0 },0);
      //   this.$headerH1.addClass('active');
      // }

      // setTimeout(_.bind(function(){
      //   this.calculateOffsets();
      //   var posY, time;
      //   if(this.mobile) {
      //     posY = this.$document.scrollTop();
      //     time = 0;
      //   }

      // },this),100);

      // setTimeout(_.bind(function(){
      //   //htmlbody
      //   if(this.mobile) {
      //     this.$sideBarBox.addClass('animate');
      //     this.$htmlbody.addClass('active');
      //   }
      // },this),500);
    },

    showSubContent:function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').hide(0);

      var text = $(e.currentTarget).text();
      var id = $(e.currentTarget).data('slug');
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_header').find('.overview_title').children('span').text(text);

      $('.source_dropdown_body').hide(0);
      $('#'+id).show(0);

      this.calculateOffsets();
    },

    returnBack: function(e){
      e && e.preventDefault();

      this.$headerH1.removeClass('active');
      this.$sideBarBox.removeClass('active');
      this.$backBtn.removeClass('active');
      this.$navItem.removeClass('selected');

      this.$htmlbody.removeClass('active').animate({ scrollTop: this.$sideBarAside.offset().top },0);

    },

    scrollTo: function(e){
      e && e.preventDefault();
      this.$htmlbody.animate({ scrollTop: 0 },500);
    }

  });

  return SidebarNavView;

});
<commit_msg>Static Pages: sidebar perfect navigation, without timeouts and a clear code to understand<commit_after>/**
 * The SidebarNavView view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps'
], function($,Backbone, _,mps) {

  'use strict';

  var SidebarNavModel = Backbone.Model.extend({
    defaults: {
      section: null,
      t: null,
      interesting: null
    }
  });

  var SidebarNavView = Backbone.View.extend({

    el: '#sidebarNavView',

    events: {
      'click .nav-item' : 'changeSourceNav',
      'click .nav-title' : 'scrollTo',
      'click .source_header' : 'toggleSources',
      'click .source_dropdown_header' : 'toggleDropdown',
      'click .source_dropdown_menu a' : 'showSubContent',
      'click #back-btn' : 'returnBack'
    },

    initialize: function() {
      if (!this.$el.length) {
        return
      }

      this.model = new SidebarNavModel();

      //CACHE
      this.$window = $(window);
      this.$document = $(document);
      this.$htmlbody = $('html,body');
      this.$headerH1 = $('#headerView').find('h1');
      this.$backBtn = $('#back-btn');
      this.$navItem = this.$el.find('.nav-item');
      this.$sideBarAside = $('#sidebarAside');
      this.$sideBarBox = $('#sources-box');
      this.$sourceArticle = $('.source-article');
      this.$sourceHeader = $('.source_header');
      this.$sourceBody = $('.source_body');
      this.$cut = $('#cut');
      this.$sourceSpinner = $('#sources-spinner');

      //VARS
      this.padding = 40;
      this.first = true;
      this.mobile = (this.$window.width() > 850) ? false : true;

      //INIT
      this.setListeners();
    },

    setListeners: function(){
      this.calculateOffsets();
      this.scrollDocument();
      this.$document.on('scroll',_.bind(this.scrollDocument,this));
      this.$window.on('resize',_.bind(this.calculateOffsets,this));

      mps.subscribe('SourceStatic/change',_.bind(this.changeSource,this));
      mps.subscribe('SubItem/change',_.bind(this.calculateOffsets,this));
    },

    calculateOffsets: function(){
      this.mobile = (this.$window.width() > 850) ? false : true;
      this.$sideBarBox.css({'min-height': this.$sideBarAside.height() });
      this.offset = this.$el.offset().top + parseInt(this.$el.css('paddingTop'), 10);
      this.offsetBottom = this.$cut.offset().top - this.$sideBarAside.height() - this.padding;
      if (!this.mobile) {
        this.$htmlbody.removeClass('active');
      }
    },

    scrollDocument: function(e){
      var scrollTop = this.$document.scrollTop();
      if (scrollTop > this.offset) {
        this.$sideBarBox.addClass('fixed');
        this.firstFixed = false;
        if(scrollTop < this.offsetBottom) {
          this.$sideBarAside.removeClass('bottom').addClass('fixed');
        }else{
          this.$sideBarAside.removeClass('fixed').addClass('bottom');
        }
      }else{
        this.$sideBarAside.removeClass('fixed bottom');
        this.$sideBarBox.removeClass('fixed');
        this.firstFixed = true;
      }
    },

    changeSourceNav: function(e){
      e && e.preventDefault();
      this.model.set('section',$(e.currentTarget).data('slug'));
      this.model.set('interesting', $(e.currentTarget).data('interesting'));
      this.model.set('t',null);
      this.updateSource();
    },
    toggleSources: function(e){
      ($(e.currentTarget).hasClass('active')) ? this.model.set('t', null) : this.model.set('t', $(e.currentTarget).parent().attr('id'));
      this.$sourceHeader.removeClass('active');
      this.$sourceBody.hide(0);
      this.updateSource();
    },

    toggleDropdown: function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').toggle(0);
    },

    updateSource: function(){
      var params = {
        section: this.model.get('section'),
        interesting: this.model.get('interesting'),
        t: this.model.get('t')
      }
      mps.publish('SourceStatic/update',[params]);
    },

    changeSource: function(params){
      //spinner
      this.$sourceSpinner.removeClass('start');
      if (params.section) {
        this.model.set('section', params.section);
        this.model.set('interesting', params.interesting);
        (params.t) ? this.model.set('t', params.t) : null;
        mps.publish('Interesting/update',[this.model.get('interesting')]);
        this.changeHelper();
      }else{
        if (!this.mobile) {
          var section = this.$navItem.eq(0).data('slug');
          this.model.set('section', section);
        }
        var interesting = this.$navItem.eq(0).data('interesting');
        this.model.set('interesting', interesting);
        mps.publish('Interesting/update',[interesting]);
        this.changeHelper();
      }

    },

    changeHelper: function(){
      var section = this.model.get('section'), tab = this.model.get('t'), $tab = $('#'+tab);
      // mobile
      if (this.mobile) {
        if (section) {
          this.padding = 0;
          this.$backBtn.addClass('active');
          this.$htmlbody.addClass('active');
          this.$headerH1.addClass('active');
          this.$sideBarBox.addClass('active')
        }
      }else{
        this.padding = 40;
        this.$htmlbody.removeClass('active');
        this.$headerH1.removeClass('active');
        this.$sideBarBox.addClass('active');
      }

      //aside
      this.$navItem.removeClass('selected');
      $('.'+section).addClass('selected');

      //section
      this.$sourceArticle.removeClass('selected');
      $('#'+section).addClass('selected');

      //tab
      if (tab) {
        if (this.mobile) {
          this.$sideBarBox.animate({ scrollTop: $tab.offset().top - this.$backBtn.innerHeight() },0, _.bind(function(){
            $tab.find('.source_header').addClass('active');
            $tab.find('.source_body').show(0);
            this.calculateOffsets();
          }, this ));
        }else{
          this.$htmlbody.animate({ scrollTop: $tab.offset().top },0, _.bind(function(){
            $tab.find('.source_header').addClass('active');
            $tab.find('.source_body').show(0);
            this.calculateOffsets();
          }, this ));
        }
      }else{
        this.$htmlbody.animate({ scrollTop: this.$sideBarBox.offset().top - this.padding },0, _.bind(function(){
          this.calculateOffsets();
        }, this ));
      }
    },

    showSubContent:function(e){
      e && e.preventDefault();
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_menu').hide(0);

      var text = $(e.currentTarget).text();
      var id = $(e.currentTarget).data('slug');
      $(e.currentTarget).parents('.source_dropdown').find('.source_dropdown_header').find('.overview_title').children('span').text(text);

      $('.source_dropdown_body').hide(0);
      $('#'+id).show(0);

      this.calculateOffsets();
    },

    returnBack: function(e){
      e && e.preventDefault();

      this.$headerH1.removeClass('active');
      this.$sideBarBox.removeClass('active');
      this.$backBtn.removeClass('active');
      this.$navItem.removeClass('selected');

      this.$htmlbody.removeClass('active').animate({ scrollTop: this.$sideBarAside.offset().top },0);

    },

    scrollTo: function(e){
      e && e.preventDefault();
      this.$htmlbody.animate({ scrollTop: 0 },500);
    }

  });

  return SidebarNavView;

});
<|endoftext|>