<commit_before>'use strict';

/* Controllers */

var App = angular.module( 'myApp.controllers', [ 'ui.bootstrap' ] );

/**************************************************
        * Main Controller / index.html
**************************************************/

App.controller( 'MainCtrl', [ '$scope', '$http', '$location',
  function ( $scope, $http, $location ) {

    $scope.billView = function(bill_id) {
      $location.path("/bills/" + bill_id);
    }

    // loads politician: pic, name, bills, committee //
    politician();

    // temporarily here //
    //getContributions();

    $scope.viewSingleBill = function ( oid ) {

      $location.url( '/bill/' + oid );

    };

/**************************************************
                    * Helpers
**************************************************/

    /*******************************
      * politician picture & name
    *******************************/

    function politician() {

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/candidates'

      }).
      success( function ( data, status, headers, config ) {

        var Candidates    = data;
        var CurCandidate  = 0;

        // first politician //
        $scope.fullName   = Candidates[CurCandidate].full_name;
        $scope.firstName  = Candidates[CurCandidate].first_name;
        $scope.lastName   = Candidates[CurCandidate].last_name;
        $scope.party      = Candidates[CurCandidate].party;
        $scope.picture    = Candidates[CurCandidate].photo_url;
        $scope.forward    = forwardClick;
        $scope.back       = backwardClick;
        $scope.leg_id     = Candidates[CurCandidate].leg_id;

        getCommittee( function( committee ) {

            $scope.committees = committee;

        });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData ) {

            $scope.pData = contributionData;

          });

        // right arrow  click //
        function forwardClick() {

          CurCandidate      = ( CurCandidate + 1 ) % Candidates.length;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( committee ) {

             $scope.committees = committee;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

            getContributions( function( contributionData ) {

              $scope.pData = contributionData;

            });

        }

        // left arrow click //
        function backwardClick() {

          ( CurCandidate === 0 )? CurCandidate = Candidates.length -1 : CurCandidate--;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( contributionData ) {

            $scope.pData = contributionData;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData ) {

            $scope.pData = contributionData;

          });

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);

      });

    }// function politician

    /*******************************
      * politician's committees
    *******************************/

    function getCommittee( cb ) {

    var politicianCommittees   = [];

      $http({

        method   : 'GET',
        url      : 'http://localhost:3000/api/committees'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].members.length; j++) {

            if ( $scope.leg_id == data[i].members[j].leg_id ) {

              politicianCommittees.push( data[i].committee[0] );

            }

          }

          cb( politicianCommittees );

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);
        cb([]);

      });

    }// function committee

    /*******************************
          * politician's bills
    *******************************/

    function getBills( cb ) {

      var billCollection = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/bills'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].sponsors.length; j++) {

            if ( $scope.leg_id == data[i].sponsors[j].leg_id ) {

              billCollection.push({

                id    : data[i].bill_id,
                title : data[i].title,
                oid   : data[i]._id

              });

            }

          }

        }

        return cb( billCollection );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );
        cb([]);

      });

    }// function getBills

    // All contributions made to a politician //
    function getContributions ( cb ) {

      var money                   = [];
      var contributionType        = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/contributions'

      }).
      success( function ( data, status, headers, config ) {

        for ( var i = 0; i < data.length; i++ ) {

          if ( $scope.fullName == data[i].candidate_name ) {

            money.push( data[i].amount );
            contributionType.push( data[i].contributor_type );

          }

        }

          var contributionData  = { industrymoney : money, contributiontype : contributionType };
          console.log(contributionData)
          return cb ( contributionData );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );

      });

    }// function getContributions

  }

]);

App.controller( 'SingleBillController', function ( $scope, $http, $routeParams ) {

  var bill_oid = $routeParams.oid;
  getSingleBill(bill_oid);

  function getSingleBill ( oid ) {

    $http({

      method  : 'GET',
      url     : 'http://localhost:3000/api/bill/' + oid

    }).
    success( function ( data, status, headers, config ) {

      $scope.singleBill = data;

    }).
    error( function ( data, status, headers, config ) {

      console.log( "error getting single bill data: " + data );
      console.log( 'Error ' + status );

    });

  } //getSingleBill

});<commit_msg>Fix bug in back nav.<commit_after>'use strict';

/* Controllers */

var App = angular.module( 'myApp.controllers', [ 'ui.bootstrap' ] );

/**************************************************
        * Main Controller / index.html
**************************************************/

App.controller( 'MainCtrl', [ '$scope', '$http', '$location',
  function ( $scope, $http, $location ) {

    $scope.billView = function(bill_id) {
      $location.path("/bills/" + bill_id);
    }

    // loads politician: pic, name, bills, committee //
    politician();

    // temporarily here //
    //getContributions();

    $scope.viewSingleBill = function ( oid ) {

      $location.url( '/bill/' + oid );

    };

/**************************************************
                    * Helpers
**************************************************/

    /*******************************
      * politician picture & name
    *******************************/

    function politician() {

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/candidates'

      }).
      success( function ( data, status, headers, config ) {

        var Candidates    = data;
        var CurCandidate  = 0;

        // first politician //
        $scope.fullName   = Candidates[CurCandidate].full_name;
        $scope.firstName  = Candidates[CurCandidate].first_name;
        $scope.lastName   = Candidates[CurCandidate].last_name;
        $scope.party      = Candidates[CurCandidate].party;
        $scope.picture    = Candidates[CurCandidate].photo_url;
        $scope.forward    = forwardClick;
        $scope.back       = backwardClick;
        $scope.leg_id     = Candidates[CurCandidate].leg_id;

        getCommittee( function( committee ) {

            $scope.committees = committee;

        });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData ) {

            $scope.pData = contributionData;

          });

        // right arrow  click //
        function forwardClick() {

          CurCandidate      = ( CurCandidate + 1 ) % Candidates.length;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( committee ) {

             $scope.committees = committee;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

            getContributions( function( contributionData ) {

              $scope.pData = contributionData;

            });

        }

        // left arrow click //
        function backwardClick() {

          ( CurCandidate === 0 )? CurCandidate = Candidates.length -1 : CurCandidate--;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( committee ) {

            $scope.committees = committee;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData ) {

            $scope.pData = contributionData;

          });

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);

      });

    }// function politician

    /*******************************
      * politician's committees
    *******************************/

    function getCommittee( cb ) {

    var politicianCommittees   = [];

      $http({

        method   : 'GET',
        url      : 'http://localhost:3000/api/committees'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].members.length; j++) {

            if ( $scope.leg_id == data[i].members[j].leg_id ) {

              politicianCommittees.push( data[i].committee[0] );

            }

          }

          cb( politicianCommittees );

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);
        cb([]);

      });

    }// function committee

    /*******************************
          * politician's bills
    *******************************/

    function getBills( cb ) {

      var billCollection = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/bills'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].sponsors.length; j++) {

            if ( $scope.leg_id == data[i].sponsors[j].leg_id ) {

              billCollection.push({

                id    : data[i].bill_id,
                title : data[i].title,
                oid   : data[i]._id

              });

            }

          }

        }

        return cb( billCollection );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );
        cb([]);

      });

    }// function getBills

    // All contributions made to a politician //
    function getContributions ( cb ) {

      var money                   = [];
      var contributionType        = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/contributions'

      }).
      success( function ( data, status, headers, config ) {

        for ( var i = 0; i < data.length; i++ ) {

          if ( $scope.fullName == data[i].candidate_name ) {

            money.push( data[i].amount );
            contributionType.push( data[i].contributor_type );

          }

        }

          var contributionData  = { industrymoney : money, contributiontype : contributionType };
          //console.log(contributionData)
          return cb ( contributionData );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );

      });

    }// function getContributions

  }

]);

App.controller( 'SingleBillController', function ( $scope, $http, $routeParams ) {

  var bill_oid = $routeParams.oid;
  getSingleBill(bill_oid);

  function getSingleBill ( oid ) {

    $http({

      method  : 'GET',
      url     : 'http://localhost:3000/api/bill/' + oid

    }).
    success( function ( data, status, headers, config ) {

      $scope.singleBill = data;

    }).
    error( function ( data, status, headers, config ) {

      console.log( "error getting single bill data: " + data );
      console.log( 'Error ' + status );

    });

  } //getSingleBill

});<|endoftext|>


<commit_before>import React from 'react';
import { func } from 'prop-types';
import moment from 'moment/moment';
import DatePicker from 'react-datepicker';
import { councilmeetingType } from '../../util/types';

const dateFormat = 'DD.MM.YYYY';

const UpdateCouncilmeetingForm = (props) => {
    const {
        meeting,
        updateMeeting,
        updateDate,
        updateInstructorDeadline,
        updateStudentDeadline
    } = props;

    return (

                Change meetings date {meeting.date ? moment(meeting.date).format(dateFormat) : ''}

                Changing the deadline changes it for every thesis connected to the meeting.
                After deadline has passed no more theses can be added to the meeting.

                        Date
                        <DatePicker
                            id="updateMeetingDate"
                            dateFormat={dateFormat}
                            selected={moment(meeting.date)}
                            onChange={updateDate}
                        />

                        Instructor deadline
                        <DatePicker
                            id="updateMeetingInstructorDeadline"
                            dateFormat={dateFormat}
                            selected={moment(meeting.instructorDeadline)}
                            onChange={updateInstructorDeadline}
                        />

                        Student deadline
                        <DatePicker
                            id="updateMeetingStudentDeadline"
                            dateFormat={dateFormat}
                            selected={moment(meeting.studentDeadline)}
                            onChange={updateStudentDeadline}
                        />

                <button className="ui green button" onClick={updateMeeting}>
                    Update
                </button>

    );
};

UpdateCouncilmeetingForm.propTypes = {
    meeting: councilmeetingType.isRequired,
    updateMeeting: func.isRequired,
    updateDate: func.isRequired,
    updateInstructorDeadline: func.isRequired,
    updateStudentDeadline: func.isRequired
};

export default UpdateCouncilmeetingForm;
<commit_msg>Ignore possible timezone problem and assert only dates on test<commit_after>import React, { Component } from 'react';
import { func } from 'prop-types';
import moment from 'moment-timezone';
import DatePicker from 'react-datepicker';
import { councilmeetingType } from '../../util/types';

const dateFormat = 'DD.MM.YYYY';

class UpdateCouncilmeetingForm extends Component {
    constructor(props) {
        super(props);

        this.state = {
            meeting: {}
        }
    }

    render() {
        const {
            meeting,
            updateMeeting,
            updateDate,
            updateInstructorDeadline,
            updateStudentDeadline
        } = this.props;

        return (

                    Change meetings date {meeting.date ? moment(meeting.date).format(dateFormat) : ''}

                    Changing the deadline changes it for every thesis connected to the meeting.
                    After deadline has passed no more theses can be added to the meeting.

                            Date
                            <DatePicker
                                id="updateMeetingDate"
                                dateFormat={dateFormat}
                                selected={moment(this.state.meeting.date)}
                                onChange={updateDate}
                                utcOffset={moment.tz('Europe/Helsinki').utcOffset()}
                            />

                            Instructor deadline
                            <DatePicker
                                id="updateMeetingInstructorDeadline"
                                dateFormat={dateFormat}
                                selected={moment(meeting.instructorDeadline)}
                                onChange={updateInstructorDeadline}
                            />

                            Student deadline
                            <DatePicker
                                id="updateMeetingStudentDeadline"
                                dateFormat={dateFormat}
                                selected={moment(meeting.studentDeadline)}
                                onChange={updateStudentDeadline}
                            />

                    <button className="ui green button" onClick={updateMeeting}>
                        Update
                    </button>

        );
    }
}

UpdateCouncilmeetingForm.propTypes = {
    meeting: councilmeetingType.isRequired,
    updateMeeting: func.isRequired,
    updateDate: func.isRequired,
    updateInstructorDeadline: func.isRequired,
    updateStudentDeadline: func.isRequired
};

export default UpdateCouncilmeetingForm;
<|endoftext|>


<commit_before>'use strict';

/* Controllers */

angular.module('myApp.controllers', [])
  .controller('MyCtrl1', [function() {

  }])
  .controller('MyCtrl2', [function() {

  }]);
<commit_msg>feat(myApp.controllers): add $scope param to clarify annotation<commit_after>'use strict';

/* Controllers */

angular.module('myApp.controllers', [])
  .controller('MyCtrl1', ['$scope', function($scope) {

  }])
  .controller('MyCtrl2', ['$scope', function($scope) {

  }]);
<|endoftext|>


<commit_before>/* eslint-disable import/no-dynamic-require */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  StyleSheet, View, ScrollView, TouchableOpacity, Dimensions, WebView,
} from 'react-native';
import Swiper from 'react-native-swiper';
import {
  Icon, Text } from 'react-native-elements';
import ALGORITHMS from './ALGORITHMS';
import AppSizes from '../../../theme/sizes';
import MarkdownHelper from '../../../utils/MarkdownHelper';
import HtmlHelper from '../../../utils/HtmlHelper';

const height = Dimensions.get('window').height;

const styles = StyleSheet.create({
  wrapper: {
    backgroundColor: '#eee',
  },
  slide: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  tabbar: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
    height: AppSizes.navbarHeight,
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
    borderTopWidth: 1,
    borderColor: '#ddd',
  },
  childBar: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  viewHeight: {
    height: (height - AppSizes.tabbarHeight - AppSizes.navbarHeight) / 2,
  },
});

class AlgorithmDetailView extends Component {
  static componentName = 'AlgorithmDetailView';

  static propTypes = {
    category: PropTypes.string.isRequired,
    item: React.PropTypes.shape({
      key: PropTypes.string.isRequired,
      title: PropTypes.string.isRequired,
    }).isRequired,
  };

  constructor(props) {
    super(props);
    this.swiper = null;
    this.state = {
      algorithmInfo: null,
      selectedTab: 'detail',
      code: '',
    };
  }

  componentWillMount() {
    const algorithmInfo = ALGORITHMS[this.props.category][this.props.item.key];
    const code = MarkdownHelper.convert(`\`\`\`js \n ${algorithmInfo.code}`);
    this.setState({
      algorithmInfo,
      code,
    });
  }

  render() {
    const { algorithmInfo, code } = this.state;

    return (
      <View style={{ flex: 1, flexDirection: 'column' }}>
        <View style={styles.viewHeight}>
          <WebView
            ref={(webview) => {
              this.webview = webview;
            }}
            scalesPageToFit
            startInLoadingState
            source={{ html: HtmlHelper.getHtml(code) }}
            style={[styles.viewHeight, { backgroundColor: '#ddd' }]}
            injectedJavaScript=""
          />
        </View>

        <View style={styles.viewHeight}>
          <Swiper
            loop={false}
            style={styles.wrapper}
            height={styles.viewHeight}
            ref={(swiper) => { this.swiper = swiper; }}
          >
            <ScrollView contentContainerStyle={[styles.slide]}>
              <Text>{algorithmInfo.name}</Text>
              <Text style={styles.text}>{algorithmInfo.description}</Text>

              <Text>复杂度</Text>
              <Text style={styles.text}>时间：{algorithmInfo.complexity.time}</Text>
              <Text style={styles.text}>空间：{algorithmInfo.complexity.space}</Text>

              <Text>参考资料</Text>
              <Text style={styles.text}>{algorithmInfo.references[0]}</Text>
            </ScrollView>
            <ScrollView contentContainerStyle={[styles.viewHeight, styles.slide]}>
              <Text style={styles.text}>Beautiful</Text>
            </ScrollView>
            <ScrollView>
              <WebView
                ref={(webview) => {
                  this.webview = webview;
                }}
                scalesPageToFit
                startInLoadingState
                source={{ html: HtmlHelper.getHtml(code) }}
                style={[styles.viewHeight, { backgroundColor: 'white' }]}
                injectedJavaScript=""
              />
            </ScrollView>
          </Swiper>
        </View>

        <View style={styles.tabbar}>
          <TouchableOpacity
            style={styles.childBar}
            onPress={() => { this.swiper.scrollBy(1); }}
          >
            <View>
              <Icon name={'device-hub'} color={'#666'} size={28} />
              <Text style={{ paddingTop: 6 }}>介绍</Text>
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            style={styles.childBar}
            onPress={() => { this.swiper.scrollBy(1); }}
          >
            <View>
              <Icon name={'assessment'} color={'#666'} size={28} />
              <Text style={{ paddingTop: 6 }}>执行</Text>
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            style={styles.childBar}
            onPress={() => { this.swiper.scrollBy(1); }}
          >
            <View>
              <Icon name={'code'} color={'#666'} size={28} />
              <Text style={{ paddingTop: 6 }}>代码</Text>
            </View>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

export default AlgorithmDetailView;
<commit_msg>[Practise] algorithm: update index<commit_after>/* eslint-disable import/no-dynamic-require */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  StyleSheet, View, ScrollView, TouchableOpacity, Dimensions, WebView,
} from 'react-native';
import Swiper from 'react-native-swiper';
import {
  Icon, Text } from 'react-native-elements';
import ALGORITHMS from './ALGORITHMS';
import AppSizes from '../../../theme/sizes';
import MarkdownHelper from '../../../utils/MarkdownHelper';
import HtmlHelper from '../../../utils/HtmlHelper';

const height = Dimensions.get('window').height;

const styles = StyleSheet.create({
  wrapper: {
    backgroundColor: '#eee',
  },
  slide: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  tabbar: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
    height: AppSizes.navbarHeight,
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
    borderTopWidth: 1,
    borderColor: '#ddd',
  },
  childBar: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  viewHeight: {
    height: (height - AppSizes.tabbarHeight - AppSizes.navbarHeight) / 2,
  },
});

class AlgorithmDetailView extends Component {
  static componentName = 'AlgorithmDetailView';

  static propTypes = {
    category: PropTypes.string.isRequired,
    item: React.PropTypes.shape({
      key: PropTypes.string.isRequired,
      title: PropTypes.string.isRequired,
    }).isRequired,
  };

  constructor(props) {
    super(props);
    this.swiper = null;
    this.state = {
      algorithmInfo: null,
      selectedTab: 'detail',
      swiperIndex: 0,
      code: '',
    };
  }

  componentWillMount() {
    const algorithmInfo = ALGORITHMS[this.props.category][this.props.item.key];
    const code = MarkdownHelper.convert(`\`\`\`js \n ${algorithmInfo.code}`);
    this.setState({
      algorithmInfo,
      code,
    });
  }

  updateSwiper(index) {
    const currentIndex = this.state.swiperIndex;
    this.swiper.scrollBy(index - currentIndex);

    this.setState({
      swiperIndex: index,
    });
  }

  render() {
    const { algorithmInfo, code } = this.state;

    return (
      <View style={{ flex: 1, flexDirection: 'column' }}>
        <View style={styles.viewHeight}>
          <WebView
            ref={(webview) => {
              this.webview = webview;
            }}
            scalesPageToFit
            startInLoadingState
            source={{ html: HtmlHelper.getHtml(code) }}
            style={[styles.viewHeight, { backgroundColor: '#ddd' }]}
            injectedJavaScript=""
          />
        </View>

        <View style={styles.viewHeight}>
          <Swiper
            loop={false}
            style={styles.wrapper}
            height={{ height: styles.viewHeight}}
            ref={(swiper) => { this.swiper = swiper; }}
          >
            <ScrollView contentContainerStyle={[styles.slide]}>
              <Text>{algorithmInfo.name}</Text>
              <Text style={styles.text}>{algorithmInfo.description}</Text>

              <Text>复杂度</Text>
              <Text style={styles.text}>时间：{algorithmInfo.complexity.time}</Text>
              <Text style={styles.text}>空间：{algorithmInfo.complexity.space}</Text>

              <Text>参考资料</Text>
              <Text style={styles.text}>{algorithmInfo.references[0]}</Text>
            </ScrollView>
            <ScrollView contentContainerStyle={[styles.viewHeight, styles.slide]}>
              <Text style={styles.text}>Beautiful</Text>
            </ScrollView>
            <ScrollView>
              <WebView
                ref={(webview) => {
                  this.webview = webview;
                }}
                scalesPageToFit
                startInLoadingState
                source={{ html: HtmlHelper.getHtml(code) }}
                style={[styles.viewHeight, { backgroundColor: 'white' }]}
                injectedJavaScript=""
              />
            </ScrollView>
          </Swiper>
        </View>

        <View style={styles.tabbar}>
          <TouchableOpacity
            style={styles.childBar}
            onPress={() => { this.updateSwiper(0); }}
          >
            <View>
              <Icon name={'device-hub'} color={'#666'} size={28} />
              <Text style={{ paddingTop: 6 }}>介绍</Text>
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            style={styles.childBar}
            onPress={() => { this.updateSwiper(1); }}
          >
            <View>
              <Icon name={'assessment'} color={'#666'} size={28} />
              <Text style={{ paddingTop: 6 }}>执行</Text>
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            style={styles.childBar}
            onPress={() => { this.updateSwiper(2); }}
          >
            <View>
              <Icon name={'code'} color={'#666'} size={28} />
              <Text style={{ paddingTop: 6 }}>代码</Text>
            </View>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

export default AlgorithmDetailView;
<|endoftext|>


<commit_before>export function activate() {
  console.log("using Inspector");
  $("body").on("click", handleInspect);
}

export function deactivate() {
  console.log("deactivate Inspector");
  $("body").off("click", handleInspect);
}

function handleInspect(e) {
  if (e.ctrlKey || e.metaKey) {
    onMagnify(e);
  } else {
    if (window.that) {
      $(window.that).removeClass("red-border");
    }
  }
}

var objectEditorWindow = null;

function onMagnify(e) {
  var grabTarget = e.target;
  var that = window.that;
  var $that = $(that);
  if (that && $that.hasClass("red-border") && (grabTarget === that || $.contains(that, grabTarget))) {
    parent = $that.parent();
    if (!parent.is("html")) {
      grabTarget = parent.get(0);
    }
  }
  if (grabTarget !== that || !$that.hasClass("red-border")) {
    $that.removeClass("red-border")
    $(grabTarget).addClass("red-border");
  }
  window.that = grabTarget;
  console.log("Current element:", grabTarget, "with id:", $(grabTarget).attr("id"));

  // remove previous object editor
  if (objectEditorWindow !== null) {
    $(objectEditorWindow).remove();
  }

  // open object editor for new target
  var editor = document.createElement('lively-object-editor');
  editor.targetElement = window.that;
  objectEditorWindow = document.createElement('lively-window');
  objectEditorWindow.title = window.that.tagName;
  $(objectEditorWindow).append(editor);

  $('body').append(objectEditorWindow);
  objectEditorWindow.centerInWindow();
}
<commit_msg>Toolbox can now open more than one editor<commit_after>export function activate() {
  console.log("using Inspector");
  $("body").on("click", handleInspect);
}

export function deactivate() {
  console.log("deactivate Inspector");
  $("body").off("click", handleInspect);
}

function handleInspect(e) {
  if (e.ctrlKey || e.metaKey) {
    onMagnify(e);
  } else {
    if (window.that) {
      $(window.that).removeClass("red-border");
    }
  }
}

var objectEditorWindow = null;

function onMagnify(e) {
  var grabTarget = e.target;
  var that = window.that;
  var $that = $(that);
  if (that && $that.hasClass("red-border") && (grabTarget === that || $.contains(that, grabTarget))) {
    parent = $that.parent();
    if (!parent.is("html")) {
      grabTarget = parent.get(0);
    }
  }
  if (grabTarget !== that || !$that.hasClass("red-border")) {
    $that.removeClass("red-border")
    $(grabTarget).addClass("red-border");
  }
  window.that = grabTarget;
  console.log("Current element:", grabTarget, "with id:", $(grabTarget).attr("id"));

  // open object editor for new target
  var editor = document.createElement('lively-object-editor');
  editor.targetElement = window.that;
  objectEditorWindow = document.createElement('lively-window');
  objectEditorWindow.title = window.that.tagName;
  $(objectEditorWindow).append(editor);

  $('body').append(objectEditorWindow);
  objectEditorWindow.centerInWindow();
}
<|endoftext|>


<commit_before>'use strict';

/* eslint complexity: [2, 25] */

var assert = require('assert');

var getUnionWithoutBool = require('./lib/get-union-without-bool.js');
var updateObject = require('./lib/update-object.js');
var isSameType = require('./lib/is-same-type.js');
var JsigAST = require('../ast/');

module.exports = NarrowType;

function NarrowType(meta) {
    this.meta = meta;
}

NarrowType.prototype.narrowType =
function narrowType(node, ifBranch, elseBranch) {
    if (node.type === 'UnaryExpression') {
        return this.narrowUnaryExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'Identifier') {
        return this.narrowIdentifier(node, ifBranch, elseBranch);
    } else if (node.type === 'BinaryExpression') {
        return this.narrowBinaryExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'LogicalExpression') {
        return this.narrowLogicalExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'MemberExpression') {
        return this.narrowMemberExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'Literal') {
        return this.narrowLiteral(node, ifBranch, elseBranch);
    } else if (node.type === 'ObjectExpression') {
        return this.narrowObjectExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'CallExpression') {
        return this.narrowCallExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'AssignmentExpression') {
        return this.narrowAssignmentExpression(node, ifBranch, elseBranch);
    } else {
        throw new Error('!! skipping narrowType: ' + node.type);
    }
};

NarrowType.prototype.narrowUnaryExpression =
function narrowUnaryExpression(node, ifBranch, elseBranch) {
    if (node.operator === '!') {
        return this.narrowType(node.argument, elseBranch, ifBranch);
    } else {
        throw new Error('Unsupported operator: ' + node.operator);
    }
};

NarrowType.prototype.narrowIdentifier =
function narrowIdentifier(node, ifBranch, elseBranch) {
    var type = this.meta.verifyNode(node, null);
    if (!type) {
        return null;
    }

    if (ifBranch) {
        var ifType = getUnionWithoutBool(type, true);
        if (ifType) {
            ifBranch.narrowType(node.name, ifType);
        }
    }
    if (elseBranch) {
        var elseType = getUnionWithoutBool(type, false);
        if (elseType) {
            elseBranch.narrowType(node.name, elseType);
        }
    }
};

NarrowType.prototype.narrowBinaryExpression =
function narrowBinaryExpression(node, ifBranch, elseBranch) {
    if (node.left.type === 'UnaryExpression' &&
        node.left.operator === 'typeof'
    ) {
        return this.narrowTypeofExpression(node, ifBranch, elseBranch);
    }

    // TODO: support `x === null`
};

NarrowType.prototype.narrowTypeofExpression =
function narrowTypeofExpression(node, ifBranch, elseBranch) {
    var identifier = node.left.argument;
    if (identifier.type !== 'Identifier') {
        // TODO: support non trivial expressions
        return null;
    }

    if (node.operator !== '===') {
        // TODO: support !==, and others... ?
        return null;
    }

    var type = this.meta.verifyNode(identifier, null);
    if (!type) {
        return null;
    }

    if (type.type !== 'typeLiteral' ||
        !type.builtin || type.name !== '%Boolean%%Mixed'
    ) {
        // TODO: support narrowing other things then Mixed
        return null;
    }

    if (node.right.type !== 'Literal') {
        // Right hand side of equal operator
        return null;
    }

    return this._narrowByTypeofTag(node, ifBranch, elseBranch);
};

NarrowType.prototype._narrowByTypeofTag =
function _narrowByTypeofTag(node, ifBranch, elseBranch) {
    var identifier = node.left.argument;
    var typeTagNode = node.right;

    var typeTagValue = typeTagNode.value;
    if (typeTagValue === 'number') {
        if (ifBranch) {
            ifBranch.narrowType(
                identifier.name, JsigAST.literal('Number')
            );
        }
    } else if (typeTagValue === 'string') {
        if (ifBranch) {
            ifBranch.narrowType(
                identifier.name, JsigAST.literal('String')
            );
        }
    } else {
        // TODO: support other tags
        return null;
    }
};

NarrowType.prototype.narrowLiteral =
function narrowLiteral(node, ifBranch, elseBranch) {
    // TODO: support if ("") {
};

NarrowType.prototype.narrowObjectExpression =
function narrowObjectExpression(node, ifBranch, elseBranch) {
    // TODO: ...
};

NarrowType.prototype.narrowCallExpression =
function narrowCallExpression(node, ifBranch, elseBranch) {
    // TODO: Support hasOwnProperty()
};

NarrowType.prototype.narrowAssignmentExpression =
function narrowAssignmentExpression(node, ifBranch, elseBranch) {
    // TODO: like identifier, but also side-effect
};

NarrowType.prototype.narrowLogicalExpression =
function narrowLogicalExpression(node, ifBranch, elseBranch) {
    if (node.operator === '||') {
        // TODO: support ||

        this.narrowType(node.left, null, elseBranch);

        if (elseBranch) {
            this.meta.enterBranchScope(elseBranch);
            this.narrowType(node.right, null, elseBranch);
            this.meta.exitBranchScope();
        }

        // Inside IF then
        //      node.left TRUE AND node.right FALSE
        //      node.left TRUE AND node.right TRUE
        //      node.left FALSE AND node.right TRUE
        // Inside ELSE then :
        //      node.left FALSE AND node.right FALSE
    } else if (node.operator === '&&') {
        // TODO: support &&

        this.narrowType(node.left, ifBranch, null);

        if (ifBranch) {
            this.meta.enterBranchScope(ifBranch);
            this.narrowType(node.right, ifBranch, null);
            this.meta.exitBranchScope();
        }

        // Inside IF then
        //      node.left TRUE and node.right TRUE
        // Inside ELSE then :
        //      node.left FALSE and node.right FALSE
        //      node.left TRUE and node.right FALSE
        //      node.left TRUE or node.right FALSE
    } else {
        assert(false, 'unknown logical operator');
    }
};

NarrowType.prototype.narrowMemberExpression =
function narrowMemberExpression(node, ifBranch, elseBranch) {
    // Type of field itself
    var fieldType = this.meta.verifyNode(node, null);
    if (!fieldType) {
        return null;
    }

    // Cannot narrow based on object index operator
    if (node.computed) {
        return null;
    }

    var ifType = getUnionWithoutBool(fieldType, true);
    var elseType = getUnionWithoutBool(fieldType, false);

    assert(node.property.type === 'Identifier', 'property must be field');
    var keyPath = [node.property.name];

    var parent = node.object;
    while (parent.type === 'MemberExpression') {
        assert(parent.property.type === 'Identifier', 'property must be field');
        keyPath.unshift(parent.property.name);

        parent = parent.object;
    }
    if (parent.type === 'Identifier') {
        keyPath.unshift(parent.name);
    } else if (parent.type === 'ThisExpression') {
        keyPath.unshift('this');
    } else {
        assert(false, 'object must be ref');
    }

    // targetType that needs mutation
    var targetType = this.meta.verifyNode(parent, null);

    if (ifBranch && ifType) {
        updateObjectAndRestrict(ifBranch, targetType, keyPath, ifType);
    }
    if (elseBranch && elseType) {
        updateObjectAndRestrict(elseBranch, targetType, keyPath, elseType);
    }
    // TODO: support nullable field check
};

function updateObjectAndRestrict(branch, objType, keyPath, valueType) {
    var newType = updateObject(
        objType, keyPath.slice(1), valueType
    );

    if (!isSameType(newType, objType)) {
        branch.narrowType(keyPath[0], newType);
    }
}

<commit_msg>narrow-type: improve handling of typeof narrowing<commit_after>'use strict';

/* eslint complexity: [2, 25] */

var assert = require('assert');

var getUnionWithoutBool = require('./lib/get-union-without-bool.js');
var updateObject = require('./lib/update-object.js');
var isSameType = require('./lib/is-same-type.js');
var JsigAST = require('../ast/');

module.exports = NarrowType;

function NarrowType(meta) {
    this.meta = meta;
}

NarrowType.prototype.narrowType =
function narrowType(node, ifBranch, elseBranch) {
    if (node.type === 'UnaryExpression') {
        return this.narrowUnaryExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'Identifier') {
        return this.narrowIdentifier(node, ifBranch, elseBranch);
    } else if (node.type === 'BinaryExpression') {
        return this.narrowBinaryExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'LogicalExpression') {
        return this.narrowLogicalExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'MemberExpression') {
        return this.narrowMemberExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'Literal') {
        return this.narrowLiteral(node, ifBranch, elseBranch);
    } else if (node.type === 'ObjectExpression') {
        return this.narrowObjectExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'CallExpression') {
        return this.narrowCallExpression(node, ifBranch, elseBranch);
    } else if (node.type === 'AssignmentExpression') {
        return this.narrowAssignmentExpression(node, ifBranch, elseBranch);
    } else {
        throw new Error('!! skipping narrowType: ' + node.type);
    }
};

NarrowType.prototype.narrowUnaryExpression =
function narrowUnaryExpression(node, ifBranch, elseBranch) {
    if (node.operator === '!') {
        return this.narrowType(node.argument, elseBranch, ifBranch);
    } else {
        throw new Error('Unsupported operator: ' + node.operator);
    }
};

NarrowType.prototype.narrowIdentifier =
function narrowIdentifier(node, ifBranch, elseBranch) {
    var type = this.meta.verifyNode(node, null);
    if (!type) {
        return null;
    }

    if (ifBranch) {
        var ifType = getUnionWithoutBool(type, true);
        if (ifType) {
            ifBranch.narrowType(node.name, ifType);
        }
    }
    if (elseBranch) {
        var elseType = getUnionWithoutBool(type, false);
        if (elseType) {
            elseBranch.narrowType(node.name, elseType);
        }
    }
};

NarrowType.prototype.narrowBinaryExpression =
function narrowBinaryExpression(node, ifBranch, elseBranch) {
    if (node.left.type === 'UnaryExpression' &&
        node.left.operator === 'typeof'
    ) {
        return this.narrowTypeofExpression(node, ifBranch, elseBranch);
    }

    // TODO: support `x === null`
};

NarrowType.prototype.narrowTypeofExpression =
function narrowTypeofExpression(node, ifBranch, elseBranch) {
    var identifier = node.left.argument;
    if (identifier.type !== 'Identifier') {
        // TODO: support non trivial expressions
        return null;
    }

    if (node.operator !== '===' && node.operator !== '!==') {
        // TODO: support !==, and others... ?
        return null;
    }

    if (node.operator === '!==') {
        var tempBranch = ifBranch;
        ifBranch = elseBranch;
        elseBranch = tempBranch;
    }

    var type = this.meta.verifyNode(identifier, null);
    if (!type) {
        return null;
    }

    if (node.right.type !== 'Literal') {
        // Right hand side of equal operator
        return null;
    }

    return this._narrowByTypeofTag(node, type, ifBranch, elseBranch);
};

NarrowType.prototype._narrowByTypeofTag =
function _narrowByTypeofTag(node, type, ifBranch, elseBranch) {
    var identifier = node.left.argument;
    var typeTagNode = node.right;

    var typeTagValue = typeTagNode.value;
    if (typeTagValue === 'number' &&
        containsLiteral(type, 'Number')
    ) {
        if (ifBranch) {
            ifBranch.narrowType(
                identifier.name, JsigAST.literal('Number')
            );
        }
        // TODO: elseBranch
    } else if (typeTagValue === 'string' &&
        containsLiteral(type, 'String')
    ) {
        if (ifBranch) {
            ifBranch.narrowType(
                identifier.name, JsigAST.literal('String')
            );
        }
        // TODO: elseBranch
    } else {
        // TODO: support other tags
        return null;
    }
};

function containsLiteral(type, literalName) {
    if (type.type === 'typeLiteral' && type.builtin &&
        type.name === '%Boolean%%Mixed'
    ) {
        return true;
    }

    if (type.type === 'unionType') {
        for (var i = 0; i < type.unions.length; i++) {
            var possibleType = type.unions[i];
            if (possibleType.type === 'typeLiteral' &&
                possibleType.builtin &&
                possibleType.name === literalName
            ) {
                return true;
            }
        }
    }

    return false;
}

NarrowType.prototype.narrowLiteral =
function narrowLiteral(node, ifBranch, elseBranch) {
    // TODO: support if ("") {
};

NarrowType.prototype.narrowObjectExpression =
function narrowObjectExpression(node, ifBranch, elseBranch) {
    // TODO: ...
};

NarrowType.prototype.narrowCallExpression =
function narrowCallExpression(node, ifBranch, elseBranch) {
    // TODO: Support hasOwnProperty()
};

NarrowType.prototype.narrowAssignmentExpression =
function narrowAssignmentExpression(node, ifBranch, elseBranch) {
    // TODO: like identifier, but also side-effect
};

NarrowType.prototype.narrowLogicalExpression =
function narrowLogicalExpression(node, ifBranch, elseBranch) {
    if (node.operator === '||') {
        // TODO: support ||

        this.narrowType(node.left, null, elseBranch);

        if (elseBranch) {
            this.meta.enterBranchScope(elseBranch);
            this.narrowType(node.right, null, elseBranch);
            this.meta.exitBranchScope();
        }

        // Inside IF then
        //      node.left TRUE AND node.right FALSE
        //      node.left TRUE AND node.right TRUE
        //      node.left FALSE AND node.right TRUE
        // Inside ELSE then :
        //      node.left FALSE AND node.right FALSE
    } else if (node.operator === '&&') {
        // TODO: support &&

        this.narrowType(node.left, ifBranch, null);

        if (ifBranch) {
            this.meta.enterBranchScope(ifBranch);
            this.narrowType(node.right, ifBranch, null);
            this.meta.exitBranchScope();
        }

        // Inside IF then
        //      node.left TRUE and node.right TRUE
        // Inside ELSE then :
        //      node.left FALSE and node.right FALSE
        //      node.left TRUE and node.right FALSE
        //      node.left TRUE or node.right FALSE
    } else {
        assert(false, 'unknown logical operator');
    }
};

NarrowType.prototype.narrowMemberExpression =
function narrowMemberExpression(node, ifBranch, elseBranch) {
    // Type of field itself
    var fieldType = this.meta.verifyNode(node, null);
    if (!fieldType) {
        return null;
    }

    // Cannot narrow based on object index operator
    if (node.computed) {
        return null;
    }

    var ifType = getUnionWithoutBool(fieldType, true);
    var elseType = getUnionWithoutBool(fieldType, false);

    assert(node.property.type === 'Identifier', 'property must be field');
    var keyPath = [node.property.name];

    var parent = node.object;
    while (parent.type === 'MemberExpression') {
        assert(parent.property.type === 'Identifier', 'property must be field');
        keyPath.unshift(parent.property.name);

        parent = parent.object;
    }
    if (parent.type === 'Identifier') {
        keyPath.unshift(parent.name);
    } else if (parent.type === 'ThisExpression') {
        keyPath.unshift('this');
    } else {
        assert(false, 'object must be ref');
    }

    // targetType that needs mutation
    var targetType = this.meta.verifyNode(parent, null);

    if (ifBranch && ifType) {
        updateObjectAndRestrict(ifBranch, targetType, keyPath, ifType);
    }
    if (elseBranch && elseType) {
        updateObjectAndRestrict(elseBranch, targetType, keyPath, elseType);
    }
    // TODO: support nullable field check
};

function updateObjectAndRestrict(branch, objType, keyPath, valueType) {
    var newType = updateObject(
        objType, keyPath.slice(1), valueType
    );

    if (!isSameType(newType, objType)) {
        branch.narrowType(keyPath[0], newType);
    }
}

<|endoftext|>


<commit_before>/**
 * Michael Crowe (crowebird - www.crowebird.com) - 2013
 * https://github.com/crowebird/js_classes
 */
(function() {
    var _window = this;
    _window.js_classes = function() {};
    var extender = function() {
        if (arguments.length > 3 || arguments.length == 0) {
            throw {
                name: "Error",
                message: "Invalid class declaration, invalid number of arguments"
            };
        }
        var _name = arguments[0];
        if (typeof _name !== "string" || !/^[$_A-Z][$_A-Z0-9]*$/i.test(_name)) {
            throw {
                name: "Error",
                message: "Invalid class name, must be a string that represents a valid variable name that will be used as the class name"
            };
        }
        var _childClass = arguments[arguments.length == 3 ? 2 : 1];
        if (typeof _childClass !== "function") {
            throw {
                name: "Error",
                message: "Invalid class function, a js_classes class can only be created by wrapping a function"
            };
        }
        var _definition = arguments.length == 3 ? arguments[1] : {};
        if (typeof _definition !== "object") {
            throw {
                name: "Error",
                message: "Invalid class definition, expecting an Object"
            };
        }
        var _parentClass = this;

        var extendedClass = function(_preventConstruct) {
            if (_preventConstruct !== js_classes.PREVENTCONSTRUCT) {
                if (_definition.abstract) {
                    throw {
                        name: "Error",
                        message: "You cannot create an instance of abstract class " + _name
                    };
                }
            }

            var abstractMethods = [];

            var _child = new _childClass();
            var _parent = null;
            if (_parentClass !== _window.js_classes) {
                _parent = new _parentClass(js_classes.PREVENTCONSTRUCT);
                for(var i in _parent) {
                    if (_parent.hasOwnProperty(i)) {
                        if (!_child[i]) {
                            _child[i] = (function(_i, parentObj) {
                                if (parentObj.abstract) {
                                    abstractMethods.push(_i);
                                }
                                return parentObj;
                            })(i, _parent[i]);
                        } else {
                            _child[i] = (function(_i, childObj, parentObj, parent) {
                                if (typeof childObj != typeof parentObj) {
                                    throw {
                                        name: "Error",
                                        message: "Class " + _name + " cannot override " + _i + " of type "  + (typeof parentObj) + " with type " + (typeof childObj)
                                    }
                                }
                                if (typeof childObj == "function") {
                                    if (parentObj.abstract && parentObj.definedArguments != childObj.length) {
                                        throw {
                                            name: "Error",
                                            message: "Declaration of " + _name + "::" + i + " must be compatible with " + parentObj.className + "::" + _i
                                        }
                                    }
                                    return function() {
                                        return childObj.apply({ _super: parent }, arguments);
                                    };
                                } else {
                                    return childObj;
                                }
                            })(i, _child[i], _parent[i], _parent);
                        }
                    }
                }
            }

            for (var i in _child) {
                if (_child.hasOwnProperty(i)) {
                    if (typeof _child[i] == "function" && (_parent == null || (_parent != null && !_parent[i]))) {
                        _child[i] = (function(_i, childObj, parent) {
                            if (childObj.name == "abstract") {
                                abstractMethods.push(_i);
                                var childObjStr = String(childObj);
                                childObjStr = childObjStr.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:[\s;]+\/\/(?:.*)$)/gm, '');
                                if (!/^function abstract\(.*?\)\s*?{\s*?\}/m.test(String(childObjStr))) {
                                    throw {
                                        name: "Error",
                                        message: "Abstract function " + _name + "::" + i + " cannot contain a body"
                                    }
                                }
                            }
                            var _return = function() {
                                return childObj.apply(_parent ? { _super: parent } : null, arguments);
                            };
                            _return.abstract = childObj.name == "abstract";
                            _return.definedArguments = childObj.length;
                            _return.className = _name;
                            return _return;
                        })(i, _child[i], _parent);
                    }
                }
            }

            if (!_definition.abstract && abstractMethods.length > 0) {
                throw {
                    name: "Error",
                    message: "Class " + _name + " contains " + abstractMethods.length + " abstract method" + (abstractMethods.length == 1 ? "" : "s") + " and must be declared abstract or have those methods implemented (" + abstractMethods.reverse().toString() + ")"
                }
            }

            var _this = this;
            _child._instanceOf = function(_Class) {
                return (_Class === js_classes) || (_this instanceof _Class) || (_parent._instanceOf && _parent._instanceOf(_Class));
            };

            if (_child._construct && _preventConstruct !== js_classes.PREVENTCONSTRUCT) {
                _child._construct.apply(null, arguments);
                delete _child._construct;
            }

            return _child;
        }
        extendedClass.extend = extender;

        var namespace = _name.split(/\./);
        var reference = _window;
        for(var i = 0; i < namespace.length; ++i) {
            if (!reference[namespace[i]]) {
                reference[namespace[i]] = {};
            }
            if (i == namespace.length - 1) {
                reference[namespace[i]] = extendedClass;
            } else {
                reference = reference[namespace[i]];
            }
        }
    };
    js_classes.extend = extender;
    js_classes.PREVENTCONSTRUCT = 'ED7352BC-BDDD-45BA-B0B5-3577A355665A-05A4367A-7CD1-4B54-91B0-F2DA44D4871A';
})();
<commit_msg>Fix for _instanceOf is base class (_parent is null)<commit_after>/**
 * Michael Crowe (crowebird - www.crowebird.com) - 2013
 * https://github.com/crowebird/js_classes
 */
(function() {
    var _window = this;
    _window.js_classes = function() {};
    var extender = function() {
        if (arguments.length > 3 || arguments.length == 0) {
            throw {
                name: "Error",
                message: "Invalid class declaration, invalid number of arguments"
            };
        }
        var _name = arguments[0];
        if (typeof _name !== "string" || !/^[$_A-Z][$_A-Z0-9]*$/i.test(_name)) {
            throw {
                name: "Error",
                message: "Invalid class name, must be a string that represents a valid variable name that will be used as the class name"
            };
        }
        var _childClass = arguments[arguments.length == 3 ? 2 : 1];
        if (typeof _childClass !== "function") {
            throw {
                name: "Error",
                message: "Invalid class function, a js_classes class can only be created by wrapping a function"
            };
        }
        var _definition = arguments.length == 3 ? arguments[1] : {};
        if (typeof _definition !== "object") {
            throw {
                name: "Error",
                message: "Invalid class definition, expecting an Object"
            };
        }
        var _parentClass = this;

        var extendedClass = function(_preventConstruct) {
            if (_preventConstruct !== js_classes.PREVENTCONSTRUCT) {
                if (_definition.abstract) {
                    throw {
                        name: "Error",
                        message: "You cannot create an instance of abstract class " + _name
                    };
                }
            }

            var abstractMethods = [];

            var _child = new _childClass();
            var _parent = null;
            if (_parentClass !== _window.js_classes) {
                _parent = new _parentClass(js_classes.PREVENTCONSTRUCT);
                for(var i in _parent) {
                    if (_parent.hasOwnProperty(i)) {
                        if (!_child[i]) {
                            _child[i] = (function(_i, parentObj) {
                                if (parentObj.abstract) {
                                    abstractMethods.push(_i);
                                }
                                return parentObj;
                            })(i, _parent[i]);
                        } else {
                            _child[i] = (function(_i, childObj, parentObj, parent) {
                                if (typeof childObj != typeof parentObj) {
                                    throw {
                                        name: "Error",
                                        message: "Class " + _name + " cannot override " + _i + " of type "  + (typeof parentObj) + " with type " + (typeof childObj)
                                    }
                                }
                                if (typeof childObj == "function") {
                                    if (parentObj.abstract && parentObj.definedArguments != childObj.length) {
                                        throw {
                                            name: "Error",
                                            message: "Declaration of " + _name + "::" + i + " must be compatible with " + parentObj.className + "::" + _i
                                        }
                                    }
                                    return function() {
                                        return childObj.apply({ _super: parent }, arguments);
                                    };
                                } else {
                                    return childObj;
                                }
                            })(i, _child[i], _parent[i], _parent);
                        }
                    }
                }
            }

            for (var i in _child) {
                if (_child.hasOwnProperty(i)) {
                    if (typeof _child[i] == "function" && (_parent == null || (_parent != null && !_parent[i]))) {
                        _child[i] = (function(_i, childObj, parent) {
                            if (childObj.name == "abstract") {
                                abstractMethods.push(_i);
                                var childObjStr = String(childObj);
                                childObjStr = childObjStr.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:[\s;]+\/\/(?:.*)$)/gm, '');
                                if (!/^function abstract\(.*?\)\s*?{\s*?\}/m.test(String(childObjStr))) {
                                    throw {
                                        name: "Error",
                                        message: "Abstract function " + _name + "::" + i + " cannot contain a body"
                                    }
                                }
                            }
                            var _return = function() {
                                return childObj.apply(_parent ? { _super: parent } : null, arguments);
                            };
                            _return.abstract = childObj.name == "abstract";
                            _return.definedArguments = childObj.length;
                            _return.className = _name;
                            return _return;
                        })(i, _child[i], _parent);
                    }
                }
            }

            if (!_definition.abstract && abstractMethods.length > 0) {
                throw {
                    name: "Error",
                    message: "Class " + _name + " contains " + abstractMethods.length + " abstract method" + (abstractMethods.length == 1 ? "" : "s") + " and must be declared abstract or have those methods implemented (" + abstractMethods.reverse().toString() + ")"
                }
            }

            var _this = this;
            _child._instanceOf = function(_Class) {
                return ((_Class === js_classes) || (_this instanceof _Class) || (_parent && _parent._instanceOf && _parent._instanceOf(_Class))) ? true : false;
            };

            if (_child._construct && _preventConstruct !== js_classes.PREVENTCONSTRUCT) {
                _child._construct.apply(null, arguments);
                delete _child._construct;
            }

            return _child;
        }
        extendedClass.extend = extender;

        var namespace = _name.split(/\./);
        var reference = _window;
        for(var i = 0; i < namespace.length; ++i) {
            if (!reference[namespace[i]]) {
                reference[namespace[i]] = {};
            }
            if (i == namespace.length - 1) {
                reference[namespace[i]] = extendedClass;
            } else {
                reference = reference[namespace[i]];
            }
        }
    };
    js_classes.extend = extender;
    js_classes.PREVENTCONSTRUCT = 'ED7352BC-BDDD-45BA-B0B5-3577A355665A-05A4367A-7CD1-4B54-91B0-F2DA44D4871A';
})();
<|endoftext|>


<commit_before>'use strict';

/* Controllers */

var App = angular.module( 'myApp.controllers', [ 'ui.bootstrap' ] );

/**************************************************
        * Main Controller / index.html
**************************************************/

App.controller( 'MainCtrl', [ 'pchart', '$scope', '$http', '$location',
  function ( $scope, $http, $location ) {

    $scope.billView = function(bill_id) {
      $location.path("/bills/" + bill_id);
    }

    // loads politician: pic, name, bills, committee //
    politician();

    // temporarily here //
    //getContributions();

    $scope.viewSingleBill = function ( oid ) {

      $location.url( '/bill/' + oid );

    };

/**************************************************
                    * Helpers
**************************************************/

    /*******************************
      * politician picture & name
    *******************************/

    function politician() {

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/candidates'

      }).
      success( function ( data, status, headers, config ) {

        var Candidates    = data;
        var CurCandidate  = 0;

        // first politician //
        $scope.fullName   = Candidates[CurCandidate].full_name;
        $scope.firstName  = Candidates[CurCandidate].first_name;
        $scope.lastName   = Candidates[CurCandidate].last_name;
        $scope.party      = Candidates[CurCandidate].party;
        $scope.picture    = Candidates[CurCandidate].photo_url;
        $scope.forward    = forwardClick;
        $scope.back       = backwardClick;
        $scope.leg_id     = Candidates[CurCandidate].leg_id;

        getCommittee( function( committee ) {

            $scope.committees = committee;

        });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData ) {

            $scope.pData = contributionData;

          });

        // right arrow  click //
        function forwardClick() {

          CurCandidate      = ( CurCandidate + 1 ) % Candidates.length;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( committee ) {

             $scope.committees = committee;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

            getContributions( function( contributionData ) {

              $scope.pData = contributionData;

            });

        }

        // left arrow click //
        function backwardClick() {

          ( CurCandidate === 0 )? CurCandidate = Candidates.length -1 : CurCandidate--;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( contributionData, datesContributed ) {

            $scope.pData = contributionData;
            $scope.lData = datesContributed;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData, datesContributed ) {

            $scope.pData = contributionData;
            $scope.lData = datesContributed;

          });

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);

      });

    }// function politician

    /*******************************
      * politician's committees
    *******************************/

    function getCommittee( cb ) {

    var politicianCommittees   = [];

      $http({

        method   : 'GET',
        url      : 'http://localhost:3000/api/committees'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].members.length; j++) {

            if ( $scope.leg_id == data[i].members[j].leg_id ) {

              politicianCommittees.push( data[i].committee[0] );

            }

          }

          cb( politicianCommittees );

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);
        cb([]);

      });

    }// function committee

    /*******************************
          * politician's bills
    *******************************/

    function getBills( cb ) {

      var billCollection = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/bills'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].sponsors.length; j++) {

            if ( $scope.leg_id == data[i].sponsors[j].leg_id ) {

              billCollection.push({

                id    : data[i].bill_id,
                title : data[i].title,
                oid   : data[i]._id

              });

            }

          }

        }

        return cb( billCollection );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );
        cb([]);

      });

    }// function getBills

    // All contributions made to a politician //
    function getContributions ( cb ) {

      $scope.pData = {};

      var money                   = [];
      var contributionType        = [];
      var contributedDate         = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/contributions'

      }).
      success( function ( data, status, headers, config ) {

        for ( var i = 0; i < data.length; i++ ) {

          if ( $scope.fullName == data[i].candidate_name ) {

            money.push( data[i].amount );
            contributionType.push( data[i].contributor_type );

          }

        }

          var contributionData  = { industrymoney : money, contributiontype : contributionType };
          var datesContributed  = contributedDate;
          return cb ( contributionData, datesContributed );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );

      });

    }// function getContributions

  }

]);

App.controller( 'SingleBillController', function ( $scope, $http, $routeParams ) {

  var bill_oid = $routeParams.oid;
  getSingleBill(bill_oid);

  function getSingleBill ( oid ) {

    $http({

      method  : 'GET',
      url     : 'http://localhost:3000/api/bill/' + oid

    }).
    success( function ( data, status, headers, config ) {

      $scope.singleBill = data;

    }).
    error( function ( data, status, headers, config ) {

      console.log( "error getting single bill data: " + data );
      console.log( 'Error ' + status );

    });

  } //getSingleBill

});<commit_msg>pulling new branch<commit_after>'use strict';

/* Controllers */

var App = angular.module( 'myApp.controllers', [ 'ui.bootstrap' ] );

/**************************************************
        * Main Controller / index.html
**************************************************/

App.controller( 'MainCtrl', [ 'pchart', '$scope', '$http', '$location',
  function ( $scope, $http, $location ) {

    $scope.billView = function(bill_id) {
      $location.path("/bills/" + bill_id);
    }

    // loads politician: pic, name, bills, committee //
    politician();

    // temporarily here //
    //getContributions();

    $scope.viewSingleBill = function ( oid ) {

      $location.url( '/bill/' + oid );

    };

/**************************************************
                    * Helpers
**************************************************/

    /*******************************
      * politician picture & name
    *******************************/

    function politician() {

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/candidates'

      }).
      success( function ( data, status, headers, config ) {

        var Candidates    = data;
        var CurCandidate  = 0;

        // first politician //
        $scope.fullName   = Candidates[CurCandidate].full_name;
        $scope.firstName  = Candidates[CurCandidate].first_name;
        $scope.lastName   = Candidates[CurCandidate].last_name;
        $scope.party      = Candidates[CurCandidate].party;
        $scope.picture    = Candidates[CurCandidate].photo_url;
        $scope.forward    = forwardClick;
        $scope.back       = backwardClick;
        $scope.leg_id     = Candidates[CurCandidate].leg_id;

        getCommittee( function( committee ) {

            $scope.committees = committee;

        });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData ) {

            $scope.pData = contributionData;

          });

        // right arrow  click //
        function forwardClick() {

          CurCandidate      = ( CurCandidate + 1 ) % Candidates.length;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( committee ) {

             $scope.committees = committee;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

            getContributions( function( contributionData, datesContributed ) {

              $scope.pData = contributionData;
              $scope.lData = datesContributed;

            });

        }

        // left arrow click //
        function backwardClick() {

          ( CurCandidate === 0 )? CurCandidate = Candidates.length -1 : CurCandidate--;

          $scope.fullName   = Candidates[CurCandidate].full_name;
          $scope.firstName  = Candidates[CurCandidate].first_name;
          $scope.lastName   = Candidates[CurCandidate].last_name;
          $scope.party      = Candidates[CurCandidate].party;
          $scope.picture    = Candidates[CurCandidate].photo_url;
          $scope.leg_id     = Candidates[CurCandidate].leg_id;

          getCommittee( function( contributionData, datesContributed ) {

            $scope.pData = contributionData;
            $scope.lData = datesContributed;

          });

          getBills( function( bills ) {

            $scope.bills = bills;

          });

          getContributions( function( contributionData, datesContributed ) {

            $scope.pData = contributionData;
            $scope.lData = datesContributed;

          });

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);

      });

    }// function politician

    /*******************************
      * politician's committees
    *******************************/

    function getCommittee( cb ) {

    var politicianCommittees   = [];

      $http({

        method   : 'GET',
        url      : 'http://localhost:3000/api/committees'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].members.length; j++) {

            if ( $scope.leg_id == data[i].members[j].leg_id ) {

              politicianCommittees.push( data[i].committee[0] );

            }

          }

          cb( politicianCommittees );

        }

      }).
      error( function ( data, status, headers, config ) {

        console.log('Error ' + status);
        cb([]);

      });

    }// function committee

    /*******************************
          * politician's bills
    *******************************/

    function getBills( cb ) {

      var billCollection = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/bills'

      }).
      success( function ( data, status, headers, config ) {

        for (var i = 0; i < data.length; i++) {

          for (var j = 0; j < data[i].sponsors.length; j++) {

            if ( $scope.leg_id == data[i].sponsors[j].leg_id ) {

              billCollection.push({

                id    : data[i].bill_id,
                title : data[i].title,
                oid   : data[i]._id

              });

            }

          }

        }

        return cb( billCollection );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );
        cb([]);

      });

    }// function getBills

    // All contributions made to a politician //
    function getContributions ( cb ) {

      $scope.pData = {};

      var money                   = [];
      var contributionType        = [];
      var contributedDate         = [];

      $http({

        method  : 'GET',
        url     : 'http://localhost:3000/api/contributions'

      }).
      success( function ( data, status, headers, config ) {

        for ( var i = 0; i < data.length; i++ ) {

          if ( $scope.fullName == data[i].candidate_name ) {

            money.push( data[i].amount );
            contributionType.push( data[i].contributor_type );

          }

        }

          var contributionData  = { industrymoney : money, contributiontype : contributionType };
          var datesContributed  = contributedDate;
          return cb ( contributionData, datesContributed );

      }).
      error( function ( data, status, headers, config ) {

        console.log( 'Error ' + status );

      });

    }// function getContributions

  }

]);

App.controller( 'SingleBillController', function ( $scope, $http, $routeParams ) {

  var bill_oid = $routeParams.oid;
  getSingleBill(bill_oid);

  function getSingleBill ( oid ) {

    $http({

      method  : 'GET',
      url     : 'http://localhost:3000/api/bill/' + oid

    }).
    success( function ( data, status, headers, config ) {

      $scope.singleBill = data;

    }).
    error( function ( data, status, headers, config ) {

      console.log( "error getting single bill data: " + data );
      console.log( 'Error ' + status );

    });

  } //getSingleBill

});<|endoftext|>


<commit_before>'use strict';

/* Controllers */

angular.module('myApp.controllers', []).
  controller('LogServerCtrl', ['$scope', '$routeParams', 'logservers', function($scope, $routeParams, logservers) {
      $scope.logserver = $.grep(logservers.all(), function(e) { return e.id === $routeParams.id})[0];

      logservers.lookupSthForLogServer($scope.logserver).then(function(results) {
          $scope.logserver.sth = _.transform(results.data, function(accum, goodOrBadSet, k) {
	      accum[k] = _.map(goodOrBadSet, function(el) {
                  el.timestamp = moment(parseInt(el.timestamp,10));
                  return el;
	      });
	  });
      });
  }])
  .controller('LogServersCtrl', ['$scope', 'logservers', function($scope, logservers) {
      $scope.logservers = logservers.all();
  }]);
<commit_msg>Order STHs by timestamp, descendingly<commit_after>'use strict';

/* Controllers */

angular.module('myApp.controllers', []).
  controller('LogServerCtrl', ['$scope', '$routeParams', 'logservers', function($scope, $routeParams, logservers) {
      $scope.logserver = $.grep(logservers.all(), function(e) { return e.id === $routeParams.id})[0];

      logservers.lookupSthForLogServer($scope.logserver).then(function(results) {
          $scope.logserver.sth = _.transform(results.data, function(accum, goodOrBadSet, k) {
	      accum[k] = _.chain(goodOrBadSet)
				.map(function(el) {
				  el.timestamp = moment(parseInt(el.timestamp,10));
				  return el;
				})
				.sortBy('timestamp')
				.reverse()
				.value()
	  });
      });
  }])
  .controller('LogServersCtrl', ['$scope', 'logservers', function($scope, logservers) {
      $scope.logservers = logservers.all();
  }]);
<|endoftext|>


<commit_before>/**
 * @license
 * Blockly Tests
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

goog.require('goog.testing');

var workspace;

function workspaceCommentTest_setUp() {
  workspace = new Blockly.Workspace();
}

function workspaceCommentTest_tearDown() {
  workspace.dispose();
}

function test_noWorkspaceComments() {
  workspaceCommentTest_setUp();
  try {
    assertEquals('Empty workspace: no comments (1).', 0, workspace.getTopComments(true).length);
    assertEquals('Empty workspace: no comments (2).', 0, workspace.getTopComments(false).length);
    workspace.clear();
    assertEquals('Empty workspace: no comments (3).', 0, workspace.getTopComments(true).length);
    assertEquals('Empty workspace: no comments (4).', 0, workspace.getTopComments(false).length);
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_oneWorkspaceComment() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, 'comment id');
    assertEquals('One comment on workspace (1).', 1, workspace.getTopComments(true).length);
    assertEquals('One comment on workspace  (2).', 1, workspace.getTopComments(false).length);
    assertEquals('Comment db contains this comment.', comment, workspace.commentDB_['comment id']);
    workspace.clear();
    assertEquals('Cleared workspace: no comments (3).', 0, workspace.getTopComments(true).length);
    assertEquals('Cleared workspace: no comments (4).', 0, workspace.getTopComments(false).length);
    assertFalse('Comment DB does not contain this comment.', 'comment id' in workspace.commentDB_);
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_getWorkspaceCommentById() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, 'comment id');
    assertEquals('Getting a comment by id.', comment, workspace.getCommentById('comment id'));
    assertEquals('No comment found.', null, workspace.getCommentById('not a comment'));
    comment.dispose();
    assertEquals('Can\'t find the comment.', null, workspace.getCommentById('comment id'));
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_disposeWsCommentTwice() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, 'comment id');
    comment.dispose();
    // Nothing should go wrong the second time dispose is called.
    comment.dispose();
  }finally {
    workspaceCommentTest_tearDown();
  }
}

function test_wsCommentHeightWidth() {
  workspaceCommentTest_setUp();
  try {
    var comment =
        new Blockly.WorkspaceComment(workspace, 'comment text', 10, 20, 'comment id');
    assertEquals('Initial width', 20, comment.getWidth());
    assertEquals('Initial height', 10, comment.getHeight());

    comment.setWidth(30);
    assertEquals('New width should be different', 30, comment.getWidth());
    assertEquals('New height should not be different', 10, comment.getHeight());

    comment.setHeight(40);
    assertEquals('New width should not be different', 30, comment.getWidth());
    assertEquals('New height should be different', 40, comment.getHeight());
    comment.dispose();
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_wsCommentXY() {
  workspaceCommentTest_setUp();
  try {
    var comment =
        new Blockly.WorkspaceComment(workspace, 'comment text', 10, 20, 'comment id');
    var xy = comment.getXY();
    assertEquals('Initial X position', 0, xy.x);
    assertEquals('Initial Y position', 0, xy.y);

    comment.moveBy(10, 100);
    xy = comment.getXY();
    assertEquals('New X position', 10, xy.x);
    assertEquals('New Y position', 100, xy.y);
    comment.dispose();
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_wsCommentText() {
  workspaceCommentTest_setUp();

  Blockly.Events.fire = temporary_fireEvent;
  temporary_fireEvent.firedEvents_ = [];
  try {
    var comment =
        new Blockly.WorkspaceComment(workspace, 'comment text', 10, 20, 'comment id');
    assertEquals(
        'Check comment text', 'comment text', comment.getText());
    assertEquals(
        'Workspace undo stack has one event', 1, workspace.undoStack_.length);

    comment.setText('comment text');
    assertEquals(
        'Comment text has not changed', 'comment text', comment.getText());
    // Setting the text to the old value does not fire an event.
    assertEquals(
        'Workspace undo stack has one event', 1, workspace.undoStack_.length);

    comment.setText('new comment text');
    assertEquals(
        'Comment text has changed', 'new comment text', comment.getText());
    assertEquals(
        'Workspace undo stack has two events', 2, workspace.undoStack_.length);
    comment.dispose();
  } finally {
    workspaceCommentTest_tearDown();
    Blockly.Events.fire = savedFireFunc;
  }
}
<commit_msg>Fix existing tests, and also two new ones<commit_after>/**
 * @license
 * Blockly Tests
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

goog.require('goog.testing');

var workspace;

function workspaceCommentTest_setUp() {
  workspace = new Blockly.Workspace();
}

function workspaceCommentTest_tearDown() {
  workspace.dispose();
}

function test_noWorkspaceComments() {
  workspaceCommentTest_setUp();
  try {
    assertEquals('Empty workspace: no comments (1).', 0, workspace.getTopComments(true).length);
    assertEquals('Empty workspace: no comments (2).', 0, workspace.getTopComments(false).length);
    workspace.clear();
    assertEquals('Empty workspace: no comments (3).', 0, workspace.getTopComments(true).length);
    assertEquals('Empty workspace: no comments (4).', 0, workspace.getTopComments(false).length);
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_oneWorkspaceComment() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, false, 'comment id');
    assertEquals('One comment on workspace (1).', 1, workspace.getTopComments(true).length);
    assertEquals('One comment on workspace  (2).', 1, workspace.getTopComments(false).length);
    assertEquals('Comment db contains this comment.', comment, workspace.commentDB_['comment id']);
    workspace.clear();
    assertEquals('Cleared workspace: no comments (3).', 0, workspace.getTopComments(true).length);
    assertEquals('Cleared workspace: no comments (4).', 0, workspace.getTopComments(false).length);
    assertFalse('Comment DB does not contain this comment.', 'comment id' in workspace.commentDB_);
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_getWorkspaceCommentById() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, false, 'comment id');
    assertEquals('Getting a comment by id.', comment, workspace.getCommentById('comment id'));
    assertEquals('No comment found.', null, workspace.getCommentById('not a comment'));
    comment.dispose();
    assertEquals('Can\'t find the comment.', null, workspace.getCommentById('comment id'));
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_disposeWsCommentTwice() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, false, 'comment id');
    comment.dispose();
    // Nothing should go wrong the second time dispose is called.
    comment.dispose();
  }finally {
    workspaceCommentTest_tearDown();
  }
}

function test_wsCommentHeightWidth() {
  workspaceCommentTest_setUp();
  try {
    var comment =
        new Blockly.WorkspaceComment(workspace, 'comment text', 10, 20, false, 'comment id');
    assertEquals('Initial width', 20, comment.getWidth());
    assertEquals('Initial height', 10, comment.getHeight());

    comment.setWidth(30);
    assertEquals('New width should be different', 30, comment.getWidth());
    assertEquals('New height should not be different', 10, comment.getHeight());

    comment.setHeight(40);
    assertEquals('New width should not be different', 30, comment.getWidth());
    assertEquals('New height should be different', 40, comment.getHeight());
    comment.dispose();
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_wsCommentXY() {
  workspaceCommentTest_setUp();
  try {
    var comment =
        new Blockly.WorkspaceComment(workspace, 'comment text', 10, 20, false, 'comment id');
    var xy = comment.getXY();
    assertEquals('Initial X position', 0, xy.x);
    assertEquals('Initial Y position', 0, xy.y);

    comment.moveBy(10, 100);
    xy = comment.getXY();
    assertEquals('New X position', 10, xy.x);
    assertEquals('New Y position', 100, xy.y);
    comment.dispose();
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_wsCommentText() {
  workspaceCommentTest_setUp();

  Blockly.Events.fire = temporary_fireEvent;
  temporary_fireEvent.firedEvents_ = [];
  try {
    var comment =
        new Blockly.WorkspaceComment(workspace, 'comment text', 10, 20, false, 'comment id');
    assertEquals(
        'Check comment text', 'comment text', comment.getText());
    assertEquals(
        'Workspace undo stack has one event', 1, workspace.undoStack_.length);

    comment.setText('comment text');
    assertEquals(
        'Comment text has not changed', 'comment text', comment.getText());
    // Setting the text to the old value does not fire an event.
    assertEquals(
        'Workspace undo stack has one event', 1, workspace.undoStack_.length);

    comment.setText('new comment text');
    assertEquals(
        'Comment text has changed', 'new comment text', comment.getText());
    assertEquals(
        'Workspace undo stack has two events', 2, workspace.undoStack_.length);
    comment.dispose();
  } finally {
    workspaceCommentTest_tearDown();
    Blockly.Events.fire = savedFireFunc;
  }
}

function test_workspaceCommentMinimized() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, true, 'comment id');
    assertEquals('Comment is minimized', true, comment.isMinimized());
  } finally {
    workspaceCommentTest_tearDown();
  }
}

function test_workspaceCommentMinimizedFromXml() {
  workspaceCommentTest_setUp();
  try {
    var comment = new Blockly.WorkspaceComment(workspace, 'comment text', 0, 0, true, 'comment id');
    var commentXml = workspace.toXml();
    var xml = goog.dom.createDom('xml');
    xml.appendChild(commentXml);
    comment.dispose();
    assertEquals('Comment is no longer on workspace', null, workspace.getCommentById('comment id'));
    Blockly.Xml.domToWorkspace(xml, workspace);
    var importedComment = workspace.getCommentById('comment id');
    assertNotEquals('Comment loaded from xml is on workspace', null, importedComment)
    assertEquals('Imported comment is minimized', true, importedComment.isMinimized());
  } finally {
    workspaceCommentTest_tearDown();
  }
}
<|endoftext|>