<commit_before>'use strict';

angular.module('app')
  .controller('ServerDataCtrl', function ($scope, webSocket, settings) {
    var widgetDefinitions = [
      {
        name: 'chart1',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'chart2',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart2'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'topics',
        templateUrl: 'template/topics.html'
      },
      {
        name: 'wt-gauge',
        attrs: {
          value: 'chartValue'
        },
        style: {
          width: '250px'
        }
      },
      {
        name: 'wt-top-n',
        attrs: {
          data: 'serverTopTen'
        }
      }
    ];

    var defaultWidgets = _.clone(widgetDefinitions);

    $scope.dashboardOptions = {
      widgetButtons: true,
      widgetDefinitions: widgetDefinitions,
      defaultWidgets: defaultWidgets
    };

    $scope.serverValue = 0;
    webSocket.subscribe(settings.randomValueTopic, function (message) {
      $scope.serverValue = message.value;
      $scope.$apply();
    }, $scope);

    webSocket.subscribe(settings.topNTopic, function (message) {
      var list = [];
      _.each(message, function (value, key) {
        list.push({ name: key, value: parseInt(value, 10) });
      }, $scope);

      $scope.serverTopTen = list;
      $scope.$apply();
    }, $scope);

    // line chart
    function chartData(topic, propertyName) {
      var max = 30;
      var data = [];
      webSocket.subscribe(topic, function (value) {
        var now = Date.now();
        data.push({
          timestamp: now,
          value: value
        });

        if (data.length > 100) { //TODO
          data.shift();
        }

        $scope[propertyName] = {
          data: data,
          max: max
        };

        $scope.$apply();
      }, $scope);
    }

    chartData('app.visualdata.chartValue', 'chart');
    chartData('app.visualdata.chartValue2', 'chart2');

    $scope.chartValue = 0;
    webSocket.subscribe('app.visualdata.chartValue2', function (value) {
      $scope.chartValue = value;
      $scope.$apply();
    });
  })
  .controller('TopicCtrl', function ($scope, webSocket) {
    webSocket.subscribe('_latestTopics', function (message) {
      var list = _.reject(message, function (topic) {
        return topic.indexOf('applications.') >= 0;
      });
      $scope.topics = _.sortBy(list, function (topic) {
        return topic;
      });
      if (message.length) {
        $scope.topic = $scope.topics[0];
      }
      $scope.$apply();
    }, $scope);
    webSocket.send({ type: 'getLatestTopics' });

    var callback = function (message) {
      $scope.topicData = JSON.stringify(message, null, ' ');
      $scope.$apply();
    };

    $scope.$watch('topic', function (newTopic, oldTopic) {
      if (oldTopic && callback) {
        webSocket.unsubscribe(oldTopic, callback);
      }

      if (newTopic) {
        $scope.topicData = 'Loading...';
        webSocket.subscribe(newTopic, callback, $scope);
      }
    });
  });<commit_msg>widgets models<commit_after>'use strict';

function ValueModel(name, $scope, webSocket) {
  this.topic = null;

  var callback = function (message) {
    $scope[name] = message;
    $scope.$apply();
  };

  this.update = function (newTopic) {
    if (this.topic) {
      console.log('__uns');
      webSocket.unsubscribe(this.topic, callback);
    }
    this.topic = newTopic;
    webSocket.subscribe(this.topic, callback, $scope);
  };
}

//TODO
function ChartModel(name, $scope, webSocket) {
  this.topic = null;

  var max = 30;
  var data = [];

  var callback = function (value) {
    var now = Date.now();
    data.push({
      timestamp: now,
      value: value
    });

    if (data.length > 100) { //TODO
      data.shift();
    }

    $scope[name] = {
      data: data,
      max: max
    };

    $scope.$apply();
  };

  this.update = function (newTopic) {
    if (this.topic) {
      console.log('__uns');
      webSocket.unsubscribe(this.topic, callback);
    }

    this.topic = newTopic;
    data = [];

    webSocket.subscribe(this.topic, callback, $scope);
  };
}

angular.module('app')
  .controller('ServerDataCtrl', function ($scope, webSocket, settings) {
    var widgetDefinitions = [
      {
        name: 'chart1',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'chart2',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart2'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'topics',
        templateUrl: 'template/topics.html'
      },
      {
        name: 'wt-gauge',
        attrs: {
          value: 'chartValue'
        },
        style: {
          width: '250px'
        }
      },
      {
        name: 'wt-top-n',
        attrs: {
          data: 'serverTopTen'
        }
      }
    ];

    var defaultWidgets = _.clone(widgetDefinitions);

    $scope.dashboardOptions = {
      widgetButtons: true,
      widgetDefinitions: widgetDefinitions,
      defaultWidgets: defaultWidgets
    };

    //TODO
    $scope.serverValue = 0;
    webSocket.subscribe(settings.randomValueTopic, function (message) {
      $scope.serverValue = message.value;
      $scope.$apply();
    }, $scope);

    webSocket.subscribe(settings.topNTopic, function (message) {
      var list = [];
      _.each(message, function (value, key) {
        list.push({ name: key, value: parseInt(value, 10) });
      }, $scope);

      $scope.serverTopTen = list;
      $scope.$apply();
    }, $scope);

    var valueModel = new ValueModel('chartValue', $scope, webSocket);

    var chartModel = new ChartModel('chart', $scope, webSocket);

    var chartModel2 = new ChartModel('chart2', $scope, webSocket);
    chartModel2.update('app.visualdata.chartValue2');

    $scope.$on('topic', function (event, topic) {
      console.log(topic);
      valueModel.update(topic);
      chartModel.update(topic);
    });
  })
  .controller('TopicCtrl', function ($scope, webSocket) {
    webSocket.subscribe('_latestTopics', function (message) {
      var list = _.reject(message, function (topic) {
        return topic.indexOf('applications.') >= 0;
      });
      $scope.topics = _.sortBy(list, function (topic) {
        return topic;
      });
      if (message.length) {
        $scope.topic = $scope.topics[0];
      }
      $scope.$apply();
    }, $scope);
    webSocket.send({ type: 'getLatestTopics' });

    var callback = function (message) {
      $scope.topicData = JSON.stringify(message, null, ' ');
      $scope.$apply();
    };

    $scope.$watch('topic', function (newTopic, oldTopic) {
      if (oldTopic && callback) {
        webSocket.unsubscribe(oldTopic, callback);
      }

      if (newTopic) {
        $scope.topicData = 'Loading...';
        webSocket.subscribe(newTopic, callback, $scope);
        $scope.$emit('topic', newTopic);
      }
    });
  });<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc directive
 * @name cpWebApp.directive:initPlaylist
 * @description
 * # initPlaylist
 */
angular.module('cpWebApp')
        .directive('initJplayer', ['audioPlayer', function (audioPlayer) {
            return {
                template: '

',
                restrict: 'E',
                scope: {
                    state: '='
                },
                link: function postLink(scope, element, attrs) {
                    var cssSelector = Object();
                    cssSelector.jplayer = "#jplayer_N";
                    cssSelector.ancestor = "#jp_container_N";
                    cssSelector.next = cssSelector.ancestor + " .jp-next";
                    cssSelector.previous = cssSelector.ancestor + " .jp-previous";

                    var playerDom = $(cssSelector.jplayer);

                    // song which is set in JPlayer
                    var song = null;

                    function initJPlayer() {
                        playerDom.jPlayer("destroy");
                        playerDom.jPlayer({
                            ready: function () {
                                console.log("JPlayer initialized");
                            },
                            play: function () {
                                audioPlayer.setPlaying(true);
                                scope.$apply();
                            },
                            pause: function () {
                                audioPlayer.setPlaying(false);
                                scope.$apply();
                            },
                            ended: function () {
                                audioPlayer.next(true);
                                scope.$apply();
                            },
                            cssSelectorAncestor: cssSelector.ancestor,
                            supplied: "mp3" // TODO
                        })

                        // Event listeners for Next & Prev
                        $(cssSelector.next).click(function (e) {
                            console.log("clicked next");
                            audioPlayer.next(true);
                            scope.$apply();
                        });
                        $(cssSelector.previous).click(function (e) {
                            audioPlayer.prev(true);
                            scope.$apply();
                        });
                    }

                    function updateJPlayer() {
                        console.log("updateJPlayer");
                        if (!angular.equals(song, audioPlayer.getCurrentSong())) {
                            setSongToJPlayer(audioPlayer.getCurrentSong());
                        }

                        if (audioPlayer.isPlaying()) {
                            playerDom.jPlayer("play");
                        }
                        else {
                            playerDom.jPlayer("pause");
                        }
                        console.log("isPlaying:" + audioPlayer.isPlaying());
                    }

                    function setSongToJPlayer(newSong) {
                        console.log("setSongToJPlayer: " + newSong.fileName);
                        playerDom.jPlayer("clearMedia");
                        song = newSong;
                        var songTitle = (( song.metadata != null) ? song.metadata.title + " - " + song.metadata.artist: song.fileName);
                        playerDom.jPlayer("setMedia", {
                            "mp3": song.url, //TODO
                            "title":  songTitle
                        });
                    }

                    initJPlayer();

                    // Trigger changes in audioPlayer, by `playerState` variable
                    scope.$watch('state', function (newValue, oldValue) {
                        console.log("Check state old: " + oldValue + " new: " + newValue);
                        if (newValue != oldValue) {
                            updateJPlayer();
                        }
                    }, true)

                }
            };
        }]);
<commit_msg>Metadata displaying fix<commit_after>'use strict';

/**
 * @ngdoc directive
 * @name cpWebApp.directive:initPlaylist
 * @description
 * # initPlaylist
 */
angular.module('cpWebApp')
        .directive('initJplayer', ['audioPlayer', function (audioPlayer) {
            return {
                template: '

',
                restrict: 'E',
                scope: {
                    state: '='
                },
                link: function postLink(scope, element, attrs) {
                    var cssSelector = Object();
                    cssSelector.jplayer = "#jplayer_N";
                    cssSelector.ancestor = "#jp_container_N";
                    cssSelector.next = cssSelector.ancestor + " .jp-next";
                    cssSelector.previous = cssSelector.ancestor + " .jp-previous";

                    var playerDom = $(cssSelector.jplayer);

                    // song which is set in JPlayer
                    var song = null;

                    function initJPlayer() {
                        playerDom.jPlayer("destroy");
                        playerDom.jPlayer({
                            ready: function () {
                                console.log("JPlayer initialized");
                            },
                            play: function () {
                                audioPlayer.setPlaying(true);
                                scope.$apply();
                            },
                            pause: function () {
                                audioPlayer.setPlaying(false);
                                scope.$apply();
                            },
                            ended: function () {
                                audioPlayer.next(true);
                                scope.$apply();
                            },
                            cssSelectorAncestor: cssSelector.ancestor,
                            supplied: "mp3" // TODO
                        })

                        // Event listeners for Next & Prev
                        $(cssSelector.next).click(function (e) {
                            console.log("clicked next");
                            audioPlayer.next(true);
                            scope.$apply();
                        });
                        $(cssSelector.previous).click(function (e) {
                            audioPlayer.prev(true);
                            scope.$apply();
                        });
                    }

                    function updateJPlayer() {
                        console.log("updateJPlayer");
                        if (!angular.equals(song, audioPlayer.getCurrentSong())) {
                            setSongToJPlayer(audioPlayer.getCurrentSong());
                        }

                        if (audioPlayer.isPlaying()) {
                            playerDom.jPlayer("play");
                        }
                        else {
                            playerDom.jPlayer("pause");
                        }
                        console.log("isPlaying:" + audioPlayer.isPlaying());
                    }

                    function setSongToJPlayer(newSong) {
                        console.log("setSongToJPlayer: " + newSong.fileName);
                        playerDom.jPlayer("clearMedia");
                        song = newSong;
                        var songTitle = ( (songHasMetadata(song)) ? song.metadata.title + " - " + song.metadata.artist: song.fileName);
                        playerDom.jPlayer("setMedia", {
                            "mp3": song.url, //TODO
                            "title":  songTitle
                        });
                    }

                    function songHasMetadata(song){
                        return ( song.metadata != null && song.metadata.title != null && song.metadata.artist != null)
                    }

                    initJPlayer();

                    // Trigger changes in audioPlayer, by `playerState` variable
                    scope.$watch('state', function (newValue, oldValue) {
                        console.log("Check state old: " + oldValue + " new: " + newValue);
                        if (newValue != oldValue) {
                            updateJPlayer();
                        }
                    }, true)

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


<commit_before>DDH.js_minify = DDH.js_minify || {};

DDH.js_minify.build = function(ops) {
    "use strict";

    // Flag to make denote if IA has been shown or not
    var shown = false;

    // Flag to denote if library 'prettydiff' has been loaded or not
    var libLoaded = false;

    ops.data.cols = is_mobile ? 8 : 20;

    return {
        onShow: function() {
            // Make sure this function is run only once, the first time
            // the IA is shown otherwise things will get initialized
            // more than once
            if (shown)
                return;

            // Set the flag to true so it doesn't get run again
            shown = true;

            var $dom = $('.zci--js_minify'),
                $minifyButton = $dom.find('button'),
                $input = $dom.find('.js_minify--input'),
                $output = $dom.find('.js_minify--output');

            // Add event handler for change in input of textarea
            $input.on('input', function() {
                if (!libLoaded) {
                    // Set the flag to make sure the library isn't loaded
                    // again and again
                    libLoaded = true;

                    // Change text of button to show the loading action
                    // to make sure users aren't confused to see
                    // the disabled button
                    $minifyButton.text('Loading..');

                    // load the library
                    DDG.require('prettydiff', function() {
                        // Change the text of button back to 'Minify',
                        // enable the button and change the pointer back to
                        // 'pointer'
                        $minifyButton
                            .text('Minify Code')
                            .prop('disabled', false)
                            .css('cursor', 'pointer')
                            .removeClass('btn--skeleton')
                            .addClass('btn--primary')
                    });
                }
            });

            // Add click handler for the minify button
            $minifyButton.click(function() {
                // Set config options for minify operation
                var args = {
                    mode: "minify",
                    lang: "javascript",
                    source: $input.val()
                };

                // Operate using the prettydiff function provided by the library
                var output = prettydiff(args);

                // Remove is-hidden class to make it visible again
                $output.parent().removeClass('is-hidden');

                // Add the output to output textarea field
                $output.val(output);
            });
        }
    };
};
<commit_msg>Add back container width adjustment<commit_after>DDH.js_minify = DDH.js_minify || {};

DDH.js_minify.build = function(ops) {
    "use strict";

    // Flag to make denote if IA has been shown or not
    var shown = false;

    // Flag to denote if library 'prettydiff' has been loaded or not
    var libLoaded = false;

    ops.data.cols = is_mobile ? 8 : 20;

    return {
        onShow: function() {
            // Make sure this function is run only once, the first time
            // the IA is shown otherwise things will get initialized
            // more than once
            if (shown)
                return;

            // Set the flag to true so it doesn't get run again
            shown = true;

            var $dom = $('.zci--js_minify'),
                $minifyButton = $dom.find('button'),
                $input = $dom.find('.js_minify--input'),
                $output = $dom.find('.js_minify--output');

            // remove max-width restriction from container
            $dom.find(".zci__main").removeClass('c-base');

            // Add event handler for change in input of textarea
            $input.on('input', function() {
                if (!libLoaded) {
                    // Set the flag to make sure the library isn't loaded
                    // again and again
                    libLoaded = true;

                    // Change text of button to show the loading action
                    // to make sure users aren't confused to see
                    // the disabled button
                    $minifyButton.text('Loading..');

                    // load the library
                    DDG.require('prettydiff', function() {
                        // Change the text of button back to 'Minify',
                        // enable the button and change the pointer back to
                        // 'pointer'
                        $minifyButton
                            .text('Minify Code')
                            .prop('disabled', false)
                            .css('cursor', 'pointer')
                            .removeClass('btn--skeleton')
                            .addClass('btn--primary')
                    });
                }
            });

            // Add click handler for the minify button
            $minifyButton.click(function() {
                // Set config options for minify operation
                var args = {
                    mode: "minify",
                    lang: "javascript",
                    source: $input.val()
                };

                // Operate using the prettydiff function provided by the library
                var output = prettydiff(args);

                // Remove is-hidden class to make it visible again
                $output.parent().removeClass('is-hidden');

                // Add the output to output textarea field
                $output.val(output);
            });
        }
    };
};
<|endoftext|>


<commit_before>// @flow
import * as Constants from '../../constants/searchv3'
import {last} from 'lodash'
import React, {Component} from 'react'
import {AutosizeInput, Box, Text, Icon, ClickableBox} from '../../common-adapters'
import {globalColors, globalMargins, globalStyles} from '../../styles'
import IconOrAvatar from '../icon-or-avatar'
import {followingStateToStyle} from '../shared'
import {getStyle as getTextStyle} from '../../common-adapters/text'

import type {IconType} from '../../common-adapters/icon'

export type UserDetails = {
  followingState: Constants.FollowingState,
  icon: ?IconType,
  service: Constants.Service,
  username: string,
}

export type UserItemProps = UserDetails & {onRemoveUser: (username: string) => void}

export type Props = {
  placeholder?: string,
  userItems: Array<UserDetails>,
  usernameText: string,
  showAddButton: boolean,
  onChangeText: (usernameText: string) => void,
  onRemoveUser: (username: string) => void,
  onClickAddButton: () => void,
}

class UserItem extends Component<void, UserItemProps, void> {
  _onRemoveUser = () => {
    this.props.onRemoveUser(this.props.username)
  }

  render() {
    const {followingState, icon, service, username} = this.props
    return (
      <Box style={_pillStyle}>
        <IconOrAvatar
          icon={icon}
          service={service}
          username={username}
          avatarSize={16}
          style={{
            fontSize: 16,
            // Add more space to the left of square icons
            marginLeft: service === 'Hacker News' || service === 'Facebook' ? 3 : 0,
          }}
        />
        <Text
          type="BodySemibold"
          style={{
            ...followingStateToStyle(followingState),
            lineHeight: '18px',
            marginLeft: globalMargins.xtiny,
            // Nudge up 1px so lowercase characters look more vertically centered
            transform: 'translateY(-1px)',
          }}
        >
          {username}
        </Text>
        <Icon
          type="iconfont-close"
          onClick={this._onRemoveUser}
          style={{fontSize: 11, marginLeft: globalMargins.tiny}}
        />
      </Box>
    )
  }
}

class UserInput extends Component<void, Props, void> {
  _textInput: AutosizeInput

  _focusInput = () => {
    this._textInput.focus()
  }

  _onInputKeyDown = ev => {
    if (
      this.props.userItems.length &&
      ev.key === 'Backspace' &&
      ev.target.selectionStart === 0 &&
      ev.target.selectionEnd === 0
    ) {
      this.props.onRemoveUser(last(this.props.userItems).username)
    }
  }

  render() {
    const {
      placeholder,
      userItems,
      usernameText,
      onChangeText,
      showAddButton,
      onClickAddButton,
      onRemoveUser,
    } = this.props

    const inputLeftPadding = userItems.length ? {paddingLeft: globalMargins.xtiny} : null
    return (
      <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flexWrap: 'wrap'}}>
        {userItems.map(item => <UserItem {...item} onRemoveUser={onRemoveUser} key={item.username} />)}
        <AutosizeInput
          ref={el => {
            this._textInput = el
          }}
          flex={1}
          inputStyle={{..._inputStyle, ...inputLeftPadding}}
          placeholder={placeholder}
          value={usernameText}
          onChange={onChangeText}
          onKeyDown={this._onInputKeyDown}
        />
        {showAddButton &&
          <Icon
            onClick={onClickAddButton}
            type="iconfont-add"
            style={{
              fontSize: 12,
              color: globalColors.blue,
              marginLeft: globalMargins.xtiny,
              cursor: 'pointer',
            }}
          />}
        <ClickableBox style={{flex: 1, cursor: 'text', height: 24}} onClick={this._focusInput}>
            {/* Material-UI child warns if no children */}
        </ClickableBox>
      </Box>
    )
  }
}

const _pillStyle = {
  ...globalStyles.flexBoxRow,
  ...globalStyles.flexBoxCenter,
  height: 24,
  paddingLeft: globalMargins.xtiny,
  // 2 pixel fudge to accomodate built-in padding to iconfont-close
  paddingRight: globalMargins.tiny - 2,
  paddingTop: globalMargins.xtiny,
  paddingBottom: globalMargins.xtiny,
  marginRight: globalMargins.xtiny,
  margin: 2,
  borderRadius: 24,
  borderWidth: 1,
  borderStyle: 'solid',
  borderColor: globalColors.black_10,
}

const _inputStyle = {
  ...getTextStyle('Body'),
  flex: 1,
  color: globalColors.black_75,
  border: 'none',
  outline: 'none',
  lineHeight: '22px',
  padding: 0,
  transform: 'translateY(-1px)',
}

export default UserInput
<commit_msg>Remove OSX text nudge<commit_after>// @flow
import * as Constants from '../../constants/searchv3'
import {last} from 'lodash'
import React, {Component} from 'react'
import {AutosizeInput, Box, Text, Icon, ClickableBox} from '../../common-adapters'
import {globalColors, globalMargins, globalStyles} from '../../styles'
import IconOrAvatar from '../icon-or-avatar'
import {followingStateToStyle} from '../shared'
import {getStyle as getTextStyle} from '../../common-adapters/text'

import type {IconType} from '../../common-adapters/icon'

export type UserDetails = {
  followingState: Constants.FollowingState,
  icon: ?IconType,
  service: Constants.Service,
  username: string,
}

export type UserItemProps = UserDetails & {onRemoveUser: (username: string) => void}

export type Props = {
  placeholder?: string,
  userItems: Array<UserDetails>,
  usernameText: string,
  showAddButton: boolean,
  onChangeText: (usernameText: string) => void,
  onRemoveUser: (username: string) => void,
  onClickAddButton: () => void,
}

class UserItem extends Component<void, UserItemProps, void> {
  _onRemoveUser = () => {
    this.props.onRemoveUser(this.props.username)
  }

  render() {
    const {followingState, icon, service, username} = this.props
    return (
      <Box style={_pillStyle}>
        <IconOrAvatar
          icon={icon}
          service={service}
          username={username}
          avatarSize={16}
          style={{
            fontSize: 16,
            // Add more space to the left of square icons
            marginLeft: service === 'Hacker News' || service === 'Facebook' ? 3 : 0,
          }}
        />
        <Text
          type="BodySemibold"
          style={{
            ...followingStateToStyle(followingState),
            lineHeight: '18px',
            marginLeft: globalMargins.xtiny,
          }}
        >
          {username}
        </Text>
        <Icon
          type="iconfont-close"
          onClick={this._onRemoveUser}
          style={{fontSize: 11, marginLeft: globalMargins.tiny}}
        />
      </Box>
    )
  }
}

class UserInput extends Component<void, Props, void> {
  _textInput: AutosizeInput

  _focusInput = () => {
    this._textInput.focus()
  }

  _onInputKeyDown = ev => {
    if (
      this.props.userItems.length &&
      ev.key === 'Backspace' &&
      ev.target.selectionStart === 0 &&
      ev.target.selectionEnd === 0
    ) {
      this.props.onRemoveUser(last(this.props.userItems).username)
    }
  }

  render() {
    const {
      placeholder,
      userItems,
      usernameText,
      onChangeText,
      showAddButton,
      onClickAddButton,
      onRemoveUser,
    } = this.props

    const inputLeftPadding = userItems.length ? {paddingLeft: globalMargins.xtiny} : null
    return (
      <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flexWrap: 'wrap'}}>
        {userItems.map(item => <UserItem {...item} onRemoveUser={onRemoveUser} key={item.username} />)}
        <AutosizeInput
          ref={el => {
            this._textInput = el
          }}
          flex={1}
          inputStyle={{..._inputStyle, ...inputLeftPadding}}
          placeholder={placeholder}
          value={usernameText}
          onChange={onChangeText}
          onKeyDown={this._onInputKeyDown}
        />
        {showAddButton &&
          <Icon
            onClick={onClickAddButton}
            type="iconfont-add"
            style={{
              fontSize: 12,
              color: globalColors.blue,
              marginLeft: globalMargins.xtiny,
              cursor: 'pointer',
            }}
          />}
        <ClickableBox style={{flex: 1, cursor: 'text', height: 24}} onClick={this._focusInput}>
            {/* Material-UI child warns if no children */}
        </ClickableBox>
      </Box>
    )
  }
}

const _pillStyle = {
  ...globalStyles.flexBoxRow,
  ...globalStyles.flexBoxCenter,
  height: 24,
  paddingLeft: globalMargins.xtiny,
  // 2 pixel fudge to accomodate built-in padding to iconfont-close
  paddingRight: globalMargins.tiny - 2,
  paddingTop: globalMargins.xtiny,
  paddingBottom: globalMargins.xtiny,
  marginRight: globalMargins.xtiny,
  margin: 2,
  borderRadius: 24,
  borderWidth: 1,
  borderStyle: 'solid',
  borderColor: globalColors.black_10,
}

const _inputStyle = {
  ...getTextStyle('Body'),
  flex: 1,
  color: globalColors.black_75,
  border: 'none',
  outline: 'none',
  lineHeight: '22px',
  padding: 0,
}

export default UserInput
<|endoftext|>


<commit_before>const _ = require('lodash');
const should = require('should');

module.exports = class DataStore {
  constructor() {
    this._data = {};
  }

  add(collection, objectId, fields) {
    console.log(`[  +  ] New object in ${collection}, id ${objectId}`);
    if (!_.has(this._data, collection)) {
      this._data[collection] = {};
    }
    should(this._data[collection]).should.not.have.property(objectId);
    should(fields).not.have.property('_id');
    fields = _.mapValues(fields, (value) => {
      if (!_.has(value, '$type') || value.$type !== 'oid') {
        return value;
      } else {
        return value.$value;
      }
    });
    fields._id = objectId;
    this._data[collection][objectId] = fields;
  }

  remove(collection, objectId) {
    console.log(`[  -  ] Deletion in ${collection}, id ${objectId}`);
    should(this._data).have.property(collection);
    should(this._data[collection]).have.property(objectId);
    this._data[collection] = _.omit(this._data[collection], objectId);
  }

  change(collection, objectId, fields, cleared) {
    console.log(`[  *  ] Change in ${collection}, id ${objectId}`);
    should(this._data).have.property(collection);
    should(this._data[collection]).have.property(objectId);

    fields = _.mapValues(fields, (value) => {
      if (!_.has(value, '$type') || value.$type !== 'oid') {
        return value;
      } else {
        return value.$value;
      }
    });
    this._data[collection][objectId] = _.omit(
      _.assign(this._data[collection][objectId], fields), cleared);
  }

  findOne(collection, key, value) {
    if (!_.has(this._data, collection)) {
      return undefined;
    }

    if (_.isNil(key)) {
      return _.find(this._data[collection], true);
    } else if (key === '_id') {
      return _.get(this._data[collection], value, undefined);
    } else {
      return _.find(this._data[collection], (fields) => {
        return (_.get(fields, key, undefined) === value);
      });
    }
  }

  findAll(collection, key, value) {
    if (!_.has(this._data, collection)) {
      return undefined;
    }

    if (_.isNil(key)) {
      return _.map(this._data[collection], (obj) => {return obj;});
    } else if (key === '_id') {
      return _.get(this._data[collection], value, undefined);
    } else {
      return _.filter(this._data[collection], (fields) => {
        return (_.get(fields, key, undefined) === value);
      });
    }
  }
};
<commit_msg>ObjectId handling<commit_after>const _ = require('lodash');
const should = require('should');

module.exports = class DataStore {
  constructor() {
    this._data = {};
  }

  add(collection, objectId, fields) {
    console.log(`[  +  ] New object in ${collection}, id ${objectId}`);

    if (collection !== 'users') { //FIXME
      objectId = {'$type': 'oid', '$value': objectId};
    }
    should(fields).not.have.property('_id');
    fields._id = objectId;

    objectId = JSON.stringify(objectId);

    if (!_.has(this._data, collection)) {
      this._data[collection] = {};
    }
    should(this._data[collection]).should.not.have.property(objectId);

    this._data[collection][objectId] = fields;
  }

  remove(collection, objectId) {
    console.log(`[  -  ] Deletion in ${collection}, id ${objectId}`);

    if (collection !== 'users') {
      objectId = {'$type': 'oid', '$value': objectId};
    }
    objectId = JSON.stringify(objectId);

    should(this._data).have.property(collection);
    should(this._data[collection]).have.property(objectId);
    this._data[collection] = _.omit(this._data[collection], objectId);
  }

  change(collection, objectId, fields, cleared) {
    console.log(`[  *  ] Change in ${collection}, id ${objectId}`);

    if (collection !== 'users') { //FIXME
      objectId = {'$type': 'oid', '$value': objectId};
    }
    objectId = JSON.stringify(objectId);

    should(this._data).have.property(collection);
    should(this._data[collection]).have.property(objectId);

    this._data[collection][objectId] = _.omit(
      _.assign(this._data[collection][objectId], fields), cleared);
  }

  findOne(collection, key, value) {
    if (!_.has(this._data, collection)) {
      return undefined;
    }

    if (_.isNil(key)) {
      return _.find(this._data[collection], true);
    } else if (key === '_id') {
      value = JSON.stringify(value);
      return _.get(this._data[collection], value, undefined);
    } else {
      return _.find(this._data[collection], (fields) => {
        return _.isEqual(_.get(fields, key, undefined), value);
      });
    }
  }

  findAll(collection, key, value) {
    if (!_.has(this._data, collection)) {
      return undefined;
    }

    if (_.isNil(key)) {
      return _.map(this._data[collection], (obj) => {return obj;});
    } else if (key === '_id') {
      value = JSON.stringify(value);
      return _.get(this._data[collection], value, undefined);
    } else {
      return _.filter(this._data[collection], (fields) => {
        return _.isEqual(_.get(fields, key, undefined), value);
      });
    }
  }
};
<|endoftext|>


<commit_before>/*
 *  Copyright 2011 Rackspace
 *
 *  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.
 *
 */

var util = require('util');

var swiz = require('swiz');

// Mock set of serialization defs
var def = {
  'Node' : [
    ['id' , {'src' : 'hash_id', 'type' : 'string',
      'desc' : 'hash ID for the node'}],
    ['is_active' , {'src' : 'active', 'type' : 'bool',
      'desc' : 'is the node active?'}],
    ['name' , {'src' : 'get_name', 'type' : 'string', 'desc' : 'name' }],
    ['agent_name' , {'type': 'string'}],
    ['ipaddress' , {'src' : 'get_public_address', 'type' : 'ip'}],
    ['public_ips' , {'cache_key' : 'node_addrs_public', 'type' : 'list<ip>'}],
    ['state', {'enumerated' : {inactive: 0, active: 1, full_no_new_checks: 2}}],
    ['opts', {'src': 'options', 'type': 'NodeOpts'}],
    ['data', {'src': 'data', 'type': 'map<string, object>'}]
  ],
  'NodeOpts': [
    ['option1', {'src': 'opt1', 'type': 'string'}],
    ['option2', {'src': 'opt2', 'type': 'string'}],
    ['option3', {'src': 'opt3', 'type': 'string'}]
  ]
};

/** Completely mock node object.
* @constructor
*/
function Node() {
  this.hash_id = '15245';
  this.active = true;
  this.agent_name = 'gl<ah';
  this.public_ips = ['123.45.55.44', '122.123.32.2'];
  this.state = 1;
  this.options = {
    'opt1': 'defaultval',
    'opt2': 'defaultval',
    'opt3': function(callback) {
      callback(null, 'something');
    }
  };

  this.options.getSerializerType = function() {
    return 'NodeOpts';
  };

  this.data = {
    'foo': 'thingone',
    'bar': 'thingtwo'
  };
}

/**
 * Dummy funct
 * @param {function(*,*)} callback junk.
 */
Node.prototype.get_name = function(callback) {
  callback(null, 'gggggg');
};

/**
 * Dummy funct
 * @param {function(*,*)} callback junk.
*/
Node.prototype.get_public_address = function(callback) {
  callback(null, '123.33.22.1');
};

/**
 * Dummy funct
 * @return {string} junk.
*/
Node.prototype.getSerializerType = function() {return 'Node';};

exports['test_xml_escape_string'] = function(test, assert) {
  var sw = new swiz.Swiz(def);
  assert.deepEqual(sw.xmlEscapeString('<&blah>'), '<&blah>');

  test.finish();
};

exports['test_build_object'] = function(test, assert) {
  var blahnode = new Node();
  var sw = new swiz.Swiz(def);
  sw.buildObject(blahnode, function(err, result) {
    assert.ifError(err);
    assert.deepEqual(result, {
      id: 15245,
      is_active: true,
      name: 'gggggg',
      agent_name: 'gl<ah',
      ipaddress: '123.33.22.1',
      public_ips: ['123.45.55.44', '122.123.32.2'],
      opts: {
        option1: 'defaultval',
        option2: 'defaultval',
        option3: 'something'
      },
      data: {
        foo: 'thingone',
        bar: 'thingtwo'
      },
      state: 'active'
    });
    test.finish();
  });
};

exports['test_serial_xml'] = function(test, assert) {
  var blahnode = new Node();
  var sw = new swiz.Swiz(def);
  //swiz.loadDefinitions(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_XML, 1, blahnode,
      function(err, results)
      {
        // need to make an appointemnt with a DOM for this one.
        assert.deepEqual(results, '<?xml version="1.0" encoding="UTF-8"?>' +
            '<Node><id>15245</id><is_active>true</' +
            'is_active><name>gggggg</name><agent_name>gl<ah</' +
            'agent_name><ipaddress>123.33.22.1</ipaddress>' +
            '<public_ips>123.45.55.44</public_ips>' +
            '<public_ips>122.123.32.2</public_ips>' +
            '<state>active</state>' +
            '<opts><NodeOpts>' +
            '<option1>defaultval</option1>' +
            '<option2>defaultval</option2>' +
            '<option3>something</option3>' +
            '</NodeOpts></opts>' +
            '<data><foo>thingone</foo><bar>thingtwo</bar></data></Node>');

        test.finish();
      }
  );
};

exports['test_serial_json'] = function(test, assert) {
  var blahnode = new Node();
  var sw = new swiz.Swiz(def);
  //swiz.loadDefinitions(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_JSON, 1, blahnode,
      function(err, results)
      {
        var rep = JSON.parse(results);
        assert.deepEqual(rep.id, 15245);
        assert.deepEqual(rep.is_active, true);
        assert.deepEqual(rep.name, 'gggggg');
        assert.deepEqual(rep.agent_name, 'gl<ah');
        assert.deepEqual(rep.ipaddress, '123.33.22.1');
        assert.deepEqual(rep.public_ips, ['123.45.55.44', '122.123.32.2']);
        assert.deepEqual(rep.opts, {
          option1: 'defaultval',
          option2: 'defaultval',
          option3: 'something'
        });
        assert.deepEqual(rep.data, {
          foo: 'thingone',
          bar: 'thingtwo'
        });
        assert.deepEqual(rep.state, 'active');
        test.finish();
      }
  );
};

exports['test_serial_array_xml'] = function(test, assert) {
  var blahnode = new Node();
  var blahnode2 = new Node();
  blahnode2.hash_id = '444';
  blahnode2.agent_name = 'your mom';
  var blaharr = [blahnode, blahnode2];
  var sw = new swiz.Swiz(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_XML, 1, blaharr,
      function(err, results)
      {

        assert.deepEqual(results, '<?xml version="1.0" encoding="UTF-8"?>' +
            '<group><Node><id>15245</id><is_active>true</' +
            'is_active><name>gggggg</name><agent_name>gl<ah</' +
            'agent_name><ipaddress>123.33.22.1</ipaddress>' +
            '<public_ips>123.45.55.44</public_ips>' +
            '<public_ips>122.123.32.2</public_ips>' +
            '<state>active</state>' +
            '<opts><NodeOpts>' +
            '<option1>defaultval</option1><option2>defaultval</option2>' +
            '<option3>something</option3></NodeOpts></opts>' +
            '<data><foo>thingone</foo><bar>thingtwo</bar></data></Node>' +
            '<Node><id>444</id><is_active>true</' +
            'is_active><name>gggggg</name><agent_name>your mom</' +
            'agent_name><ipaddress>123.33.22.1</ipaddress>' +
            '<public_ips>123.45.55.44</public_ips>' +
            '<public_ips>122.123.32.2</public_ips>' +
            '<state>active</state>' +
            '<opts><NodeOpts>' +
            '<option1>defaultval</option1><option2>defaultval</option2>' +
            '<option3>something</option3></NodeOpts></opts>' +
            '<data><foo>thingone</foo><bar>thingtwo</bar></data></Node>' +
            '</group>');

        test.finish();
      }
  );
};

exports['test_error_type'] = function(test, assert) {
  var blah = { };
  var sw = new swiz.Swiz(def);
  blah.getSerializerType = function() {return 'monito';};
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_JSON, 1, blah,
      function(err, results)
      {
        assert.ok(err instanceof Error);

        test.finish();
      }
  );
};

exports['test_serial_array_json'] = function(test, assert) {
  var blahnode = new Node();
  var blahnode2 = new Node();
  blahnode2.hash_id = '444';
  blahnode2.agent_name = 'your mom';
  var blaharr = [blahnode, blahnode2];
  var sw = new swiz.Swiz(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_JSON, 1, blaharr,
      function(err, results)
      {
        var rep = JSON.parse(results);
        assert.deepEqual(rep[0].id, 15245);
        assert.deepEqual(rep[0].is_active, true);
        assert.deepEqual(rep[0].name, 'gggggg');
        assert.deepEqual(rep[0].agent_name, 'gl<ah');
        assert.deepEqual(rep[0].ipaddress, '123.33.22.1');
        assert.deepEqual(rep[0].public_ips,
            ['123.45.55.44', '122.123.32.2']);
        assert.deepEqual(rep[0].opts, {
          option1: 'defaultval',
          option2: 'defaultval',
          option3: 'something'
        });
        assert.deepEqual(rep[0].data, {
          foo: 'thingone',
          bar: 'thingtwo'
        });
        assert.deepEqual(rep[0].state, 'active');
        assert.deepEqual(rep[1].id, 444);
        assert.deepEqual(rep[1].is_active, true);
        assert.deepEqual(rep[1].name, 'gggggg');
        assert.deepEqual(rep[1].agent_name, 'your mom');
        assert.deepEqual(rep[1].ipaddress, '123.33.22.1');
        assert.deepEqual(rep[1].public_ips,
            ['123.45.55.44', '122.123.32.2']);
        assert.deepEqual(rep[1].opts, {
          option1: 'defaultval',
          option2: 'defaultval',
          option3: 'something'
        });
        assert.deepEqual(rep[1].data, {
          foo: 'thingone',
          bar: 'thingtwo'
        });
        assert.deepEqual(rep[1].state, 'active');
        test.finish();
      }
  );
};
<commit_msg>add (failing) test of realistic callback result serialization<commit_after>/*
 *  Copyright 2011 Rackspace
 *
 *  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.
 *
 */

var util = require('util');

var swiz = require('swiz');

// Mock set of serialization defs
var def = {
  'Node' : [
    ['id' , {'src' : 'hash_id', 'type' : 'string',
      'desc' : 'hash ID for the node'}],
    ['is_active' , {'src' : 'active', 'type' : 'bool',
      'desc' : 'is the node active?'}],
    ['name' , {'src' : 'get_name', 'type' : 'string', 'desc' : 'name' }],
    ['agent_name' , {'type': 'string'}],
    ['ipaddress' , {'src' : 'get_public_address', 'type' : 'ip'}],
    ['public_ips' , {'cache_key' : 'node_addrs_public', 'type' : 'list<ip>'}],
    ['state', {'enumerated' : {inactive: 0, active: 1, full_no_new_checks: 2}}],
    ['opts', {'src': 'options', 'type': 'NodeOpts'}],
    ['data', {'src': 'data', 'type': 'map<string, object>'}]
  ],
  'NodeOpts': [
    ['option1', {'src': 'opt1', 'type': 'string'}],
    ['option2', {'src': 'opt2', 'type': 'string'}],
    ['option3', {'src': 'opt3', 'type': 'string'}]
  ]
};

/** Completely mock node object.
* @constructor
*/
function Node() {
  this.hash_id = '15245';
  this.active = true;
  this.agent_name = 'gl<ah';
  this.public_ips = ['123.45.55.44', '122.123.32.2'];
  this.public_address = '123.33.22.1';
  this.state = 1;
  this.options = {
    'opt1': 'defaultval',
    'opt2': 'defaultval',
    'opt3': function(callback) {
      callback(null, 'something');
    }
  };

  this.options.getSerializerType = function() {
    return 'NodeOpts';
  };

  this.data = {
    'foo': 'thingone',
    'bar': 'thingtwo'
  };
}

/**
 * Dummy funct
 * @param {function(*,*)} callback junk.
 */
Node.prototype.get_name = function(callback) {
  callback(null, 'gggggg');
};

/**
 * Dummy funct
 * @param {function(*,*)} callback junk.
*/
Node.prototype.get_public_address = function(callback) {
  callback(null, this.public_address);
};

/**
 * Dummy funct
 * @return {string} junk.
*/
Node.prototype.getSerializerType = function() {return 'Node';};

exports['test_xml_escape_string'] = function(test, assert) {
  var sw = new swiz.Swiz(def);
  assert.deepEqual(sw.xmlEscapeString('<&blah>'), '<&blah>');

  test.finish();
};

exports['test_build_object'] = function(test, assert) {
  var blahnode = new Node();
  var sw = new swiz.Swiz(def);
  sw.buildObject(blahnode, function(err, result) {
    assert.ifError(err);
    assert.deepEqual(result, {
      id: 15245,
      is_active: true,
      name: 'gggggg',
      agent_name: 'gl<ah',
      ipaddress: '123.33.22.1',
      public_ips: ['123.45.55.44', '122.123.32.2'],
      opts: {
        option1: 'defaultval',
        option2: 'defaultval',
        option3: 'something'
      },
      data: {
        foo: 'thingone',
        bar: 'thingtwo'
      },
      state: 'active'
    });
    test.finish();
  });
};

exports['test_serial_xml'] = function(test, assert) {
  var blahnode = new Node();
  var sw = new swiz.Swiz(def);
  //swiz.loadDefinitions(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_XML, 1, blahnode,
      function(err, results)
      {
        // need to make an appointemnt with a DOM for this one.
        assert.deepEqual(results, '<?xml version="1.0" encoding="UTF-8"?>' +
            '<Node><id>15245</id><is_active>true</' +
            'is_active><name>gggggg</name><agent_name>gl<ah</' +
            'agent_name><ipaddress>123.33.22.1</ipaddress>' +
            '<public_ips>123.45.55.44</public_ips>' +
            '<public_ips>122.123.32.2</public_ips>' +
            '<state>active</state>' +
            '<opts><NodeOpts>' +
            '<option1>defaultval</option1>' +
            '<option2>defaultval</option2>' +
            '<option3>something</option3>' +
            '</NodeOpts></opts>' +
            '<data><foo>thingone</foo><bar>thingtwo</bar></data></Node>');

        test.finish();
      }
  );
};

exports['test_serial_json'] = function(test, assert) {
  var blahnode = new Node();
  var sw = new swiz.Swiz(def);
  //swiz.loadDefinitions(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_JSON, 1, blahnode,
      function(err, results)
      {
        var rep = JSON.parse(results);
        assert.deepEqual(rep.id, 15245);
        assert.deepEqual(rep.is_active, true);
        assert.deepEqual(rep.name, 'gggggg');
        assert.deepEqual(rep.agent_name, 'gl<ah');
        assert.deepEqual(rep.ipaddress, '123.33.22.1');
        assert.deepEqual(rep.public_ips, ['123.45.55.44', '122.123.32.2']);
        assert.deepEqual(rep.opts, {
          option1: 'defaultval',
          option2: 'defaultval',
          option3: 'something'
        });
        assert.deepEqual(rep.data, {
          foo: 'thingone',
          bar: 'thingtwo'
        });
        assert.deepEqual(rep.state, 'active');
        test.finish();
      }
  );
};

exports['test_serial_array_xml'] = function(test, assert) {
  var blahnode = new Node();
  var blahnode2 = new Node();
  blahnode2.hash_id = '444';
  blahnode2.agent_name = 'your mom';
  var blaharr = [blahnode, blahnode2];
  var sw = new swiz.Swiz(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_XML, 1, blaharr,
      function(err, results)
      {

        assert.deepEqual(results, '<?xml version="1.0" encoding="UTF-8"?>' +
            '<group><Node><id>15245</id><is_active>true</' +
            'is_active><name>gggggg</name><agent_name>gl<ah</' +
            'agent_name><ipaddress>123.33.22.1</ipaddress>' +
            '<public_ips>123.45.55.44</public_ips>' +
            '<public_ips>122.123.32.2</public_ips>' +
            '<state>active</state>' +
            '<opts><NodeOpts>' +
            '<option1>defaultval</option1><option2>defaultval</option2>' +
            '<option3>something</option3></NodeOpts></opts>' +
            '<data><foo>thingone</foo><bar>thingtwo</bar></data></Node>' +
            '<Node><id>444</id><is_active>true</' +
            'is_active><name>gggggg</name><agent_name>your mom</' +
            'agent_name><ipaddress>123.33.22.1</ipaddress>' +
            '<public_ips>123.45.55.44</public_ips>' +
            '<public_ips>122.123.32.2</public_ips>' +
            '<state>active</state>' +
            '<opts><NodeOpts>' +
            '<option1>defaultval</option1><option2>defaultval</option2>' +
            '<option3>something</option3></NodeOpts></opts>' +
            '<data><foo>thingone</foo><bar>thingtwo</bar></data></Node>' +
            '</group>');

        test.finish();
      }
  );
};

exports['test_error_type'] = function(test, assert) {
  var blah = { };
  var sw = new swiz.Swiz(def);
  blah.getSerializerType = function() {return 'monito';};
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_JSON, 1, blah,
      function(err, results)
      {
        assert.ok(err instanceof Error);

        test.finish();
      }
  );
};

exports['test_serial_array_json'] = function(test, assert) {
  var blahnode = new Node();
  var blahnode2 = new Node();
  blahnode2.hash_id = '444';
  blahnode2.agent_name = 'your mom';
  var blaharr = [blahnode, blahnode2];
  var sw = new swiz.Swiz(def);
  sw.serialize(swiz.SERIALIZATION.SERIALIZATION_JSON, 1, blaharr,
      function(err, results)
      {
        var rep = JSON.parse(results);
        assert.deepEqual(rep[0].id, 15245);
        assert.deepEqual(rep[0].is_active, true);
        assert.deepEqual(rep[0].name, 'gggggg');
        assert.deepEqual(rep[0].agent_name, 'gl<ah');
        assert.deepEqual(rep[0].ipaddress, '123.33.22.1');
        assert.deepEqual(rep[0].public_ips,
            ['123.45.55.44', '122.123.32.2']);
        assert.deepEqual(rep[0].opts, {
          option1: 'defaultval',
          option2: 'defaultval',
          option3: 'something'
        });
        assert.deepEqual(rep[0].data, {
          foo: 'thingone',
          bar: 'thingtwo'
        });
        assert.deepEqual(rep[0].state, 'active');
        assert.deepEqual(rep[1].id, 444);
        assert.deepEqual(rep[1].is_active, true);
        assert.deepEqual(rep[1].name, 'gggggg');
        assert.deepEqual(rep[1].agent_name, 'your mom');
        assert.deepEqual(rep[1].ipaddress, '123.33.22.1');
        assert.deepEqual(rep[1].public_ips,
            ['123.45.55.44', '122.123.32.2']);
        assert.deepEqual(rep[1].opts, {
          option1: 'defaultval',
          option2: 'defaultval',
          option3: 'something'
        });
        assert.deepEqual(rep[1].data, {
          foo: 'thingone',
          bar: 'thingtwo'
        });
        assert.deepEqual(rep[1].state, 'active');
        test.finish();
      }
  );
};
<|endoftext|>


<commit_before>import jQuery from 'jquery';

(($, window, undefined) => {

	'use strict';

	$('html').removeClass('no-js');

	// Place your code here...

})(jQuery, window);
<commit_msg>changed the indentation to use spaces instead of tabs<commit_after>import jQuery from 'jquery';

(($, window, undefined) => {

  'use strict';

  $('html').removeClass('no-js');

  // Place your code here...

})(jQuery, window);
<|endoftext|>


<commit_before>'use strict';

angular.module('MyApp.controllers')
.value('BASE_URL', 'https://noticeapp.firebaseio.com/')
.controller('DashboardCtrl', function($firebase, $scope, Auth, md5, $ionicModal, $rootScope) {
    var noticeRef = new Firebase('https://noticeapp.firebaseio.com/notifications');
    $scope.notifications = $firebase(noticeRef);
    $scope.email = Auth.currentUser.email;
    $scope.message = '';
    $scope.activityName = '';
    $scope.isStudent = /([\._a-zA-Z0-9-]+@students.d211.org)/.test($scope.email);

    $rootScope.user.subscriptions = [
    { id: 1, name: 'Math Team', color: '#43cee6', isChecked: false },
    { id: 2, name: 'Basketball', color: '#4a87ee', isChecked: false },
    { id: 3, name: 'Horticulture Club', color: '#ef4e3a', isChecked: false },
    { id: 4, name: 'Science Olympiad', color: '#8a6de9', isChecked: false }];

    $scope.clubs = [
    { id: 1, name: 'Math Team', color: '#43cee6' },
    { id: 2, name: 'Basketball', color: '#4a87ee' },
    { id: 3, name: 'Horticulture Club', color: '#ef4e3a' },
    { id: 4, name: 'Science Olympiad', color: '#8a6de9'}];

    $scope.gravatarURL = 'http://www.gravatar.com/avatar/' + md5.createHash($scope.email);

    $scope.postNotification = function(message, tag, color) {
        $scope.notifications.$add({message: message, createdBy: $scope.email, gravatarURL: $scope.gravatarURL, dateCreated: Date.now(), tag: tag, color: color});
  	    $scope.message = null;
    };

    $scope.getGravatar = function(md5) {
        return 'http://www.gravatar.com/avatar/' + notifications.md5;
    };

    $ionicModal.fromTemplateUrl('templates/modal.html', {
        scope: $scope
    }).then(function(modal) {
        $scope.modal = modal;
    });
})
.filter('reverse', function() {
      function toArray(list) {
         var k, out = [];
         if( list ) {
            if( angular.isArray(list) ) {
               out = list;
            }
            else if( typeof(list) === 'object' ) {
               for (k in list) {
                  if (list.hasOwnProperty(k)) { out.push(list[k]); }
               }
            }
         }
         return out;
      }
      return function(items) {
         return toArray(items).slice().reverse();
      };
});
<commit_msg>Update dashboard-controller.js<commit_after>'use strict';

angular.module('MyApp.controllers')
.value('BASE_URL', 'https://noticeapp.firebaseio.com/')
.controller('DashboardCtrl', function($firebase, $scope, Auth, md5, $ionicModal, $rootScope) {
    var noticeRef = new Firebase('https://noticeapp.firebaseio.com/notifications');
    $scope.notifications = $firebase(noticeRef);

    $scope.email = Auth.currentUser.email;
    $scope.message = '';
    $scope.activityName = '';
    $scope.isStudent = /([\._a-zA-Z0-9-]+@students.d211.org)/.test($scope.email);

    $scope.subscriptions = [
    { id: 1, name: 'Math Team', color: '#43cee6', isChecked: false },
    { id: 2, name: 'Basketball', color: '#4a87ee', isChecked: false },
    { id: 3, name: 'Horticulture Club', color: '#ef4e3a', isChecked: false },
    { id: 4, name: 'Science Olympiad', color: '#8a6de9', isChecked: false }];

    $scope.clubs = [
    { id: 1, name: 'Math Team', color: '#43cee6' },
    { id: 2, name: 'Basketball', color: '#4a87ee' },
    { id: 3, name: 'Horticulture Club', color: '#ef4e3a' },
    { id: 4, name: 'Science Olympiad', color: '#8a6de9'}];

    $scope.gravatarURL = 'http://www.gravatar.com/avatar/' + md5.createHash($scope.email);

    $scope.postNotification = function(message, tag, color) {
        $scope.notifications.$add({message: message, createdBy: $scope.email, gravatarURL: $scope.gravatarURL, dateCreated: Date.now(), tag: tag, color: color});
  	    $scope.message = null;
    };

    $scope.getGravatar = function(md5) {
        return 'http://www.gravatar.com/avatar/' + notifications.md5;
    };

    $ionicModal.fromTemplateUrl('templates/modal.html', {
        scope: $scope
    }).then(function(modal) {
        $scope.modal = modal;
    });
})
.filter('reverse', function() {
      function toArray(list) {
         var k, out = [];
         if( list ) {
            if( angular.isArray(list) ) {
               out = list;
            }
            else if( typeof(list) === 'object' ) {
               for (k in list) {
                  if (list.hasOwnProperty(k)) { out.push(list[k]); }
               }
            }
         }
         return out;
      }
      return function(items) {
         return toArray(items).slice().reverse();
      };
});
<|endoftext|>


<commit_before>

angular.module('starter.controllers')
.controller('CarteCtrl', ['$scope', '$http','$rootScope', '$ionicPopup', 'etablissementsService', 'artisansService', 'programmesService',
    function($scope, $http, $rootScope, $ionicPopup, etablissementsService, artisansService, programmesService) {

    var southWest = L.latLng(47.369743926768784, 7.174824539917747),
    northEast = L.latLng(47.360589810163582, 7.1379860116837257),
    bounds = L.latLngBounds(southWest, northEast);

    var map = L.map('mapid', {
        center: [47.364965, 7.154498],
        zoom: 19,
        minZoom: 15,
        maxZoom: 20,
        maxBounds: bounds,
        zoomControl:false,
        tap: false
    });

    $scope.artisansMarkers = [];
    $scope.programmesMarkers = [];
    $scope.etablissementMarkers = [];

    var pageID = $('#page_carte');
    $scope.EvenementLayer = L.layerGroup([]);
    $scope.ArtisanLayer = L.layerGroup([]);
    $scope.EtablissementLayer = L.layerGroup([]);

    // Callback de succès sur la fonction de localisation, si la localisation a fonctionné on affiche la position de l'utilisateur
    var onSuccess = function(position) {

        userLat = position.coords.latitude;
        userLng =  position.coords.longitude;
        userLatLng = L.latLng(userLat, userLng);

        if (userLat < 47.369743926768784 && userLat > 47.360589810163582 && userLng > 7.174824539917747 && userLng < 7.1379860116837257){

          L.marker(userLatLng).addTo(map).bindPopup('Vous êtes ici').openPopup();
          map.panTo(userLatLng);

        } else {

          var alertPopup = $ionicPopup.alert({
            title: 'Erreur de localisation',
            template: 'La localisation ne fonctionne pas en dehors de la ville de St-Ursanne.'
          });

          map.panTo([47.364965, 7.154498]);

        }

    };

    // onError Callback receives a PositionError object
    //
    function onError(error) {
      var alertPopup = $ionicPopup.alert({
        title: 'Erreur de localisation',
        template: 'La localisation ne fonctionne pas. Vérifiez que le GPS soit correctement activé puis réessayez.'
      });

    }

    var ourCustomControl = L.Control.extend({

      options: {
        position: 'topright'
      },

      onAdd: function (map) {
        var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');

        container.onclick = function(){
          navigator.geolocation.getCurrentPosition(onSuccess, onError);
        }

        return container;
      },

    });

    var tileLayer = L.tileLayer(
      'data/img/MapQuest/{z}/{x}/{y}.png', {
        maxZoom: 19,
        minZoom: 15,
        attribution: '© OpenStreetMap contributors'
      }).addTo(map);

    map.addControl(new ourCustomControl());

    var restaurant = L.icon({
      iconUrl: 'data/img/icons/restaurantIcon.png',
      iconAnchor: [17, 36]
    });

    var artisans = L.icon({
      iconUrl: 'data/img/icons/artisanIcon.png',
      iconAnchor: [17, 36]
    });

    var events = L.icon({
      iconUrl: 'data/img/icons/eventIcon.png',
      iconAnchor: [17, 36]
    });

    // Affiche tous les marqueurs des établissements
    etablissementsService.get(function (data) {
			$scope.etablissementsRow = data;
			$scope.etablissements = [];
			for (var index = 0; index < $scope.etablissementsRow.length; index++) {
				$scope.etablissements[index] = {
					id: index,
					name: $scope.etablissementsRow[index].name,
					description: $scope.etablissementsRow[index].description,
         	type: $scope.etablissementsRow[index].type,
          latitude: $scope.etablissementsRow[index].latitude,
          longitude: $scope.etablissementsRow[index].longitude
			  };

        function setMarker(i){
          markerEtablissement = new L.marker([$scope.etablissements[i].latitude, $scope.etablissements[i].longitude], {icon: restaurant});
          $scope.EtablissementLayer.addLayer(markerEtablissement);
          $scope.etablissementMarkers.push(markerEtablissement);
        }

        setMarker(index);
			}
		});

    // Affiche tous les marqueurs des artisans
    artisansService.get(function (data) {
			$scope.artisansRow = data;
			$scope.artisans = [];
			for (var index = 0; index < $scope.artisansRow.length; index++) {
				$scope.artisans[index] = {
					id: index,
					name: $scope.artisansRow[index].name,
					latitude: $scope.artisansRow[index].latitude,
					longitude: $scope.artisansRow[index].longitude
				};

        function setMarker(i){
          markerArtisan = new L.marker([$scope.artisans[i].latitude, $scope.artisans[i].longitude], {icon: artisans}).on('click', function(){setMapPopup(pageID, $scope.artisans[i].name, "")});
          $scope.ArtisanLayer.addLayer(markerArtisan);
          $scope.artisansMarkers.push(markerArtisan);
        }

        setMarker(index);
			}
		});

    // Affiche tous les marqueurs du programme (événements)
    programmesService.get(function (data) {
			$scope.programmesRow = data;
			$scope.programmes = [];
			for (var index = 0; index < $scope.programmesRow.length; index++) {
				$scope.programmes[index] = {
					id: index,
					name: $scope.programmesRow[index].name,
          description: $scope.programmesRow[index].description,
					start: $scope.programmesRow[index].start,
					end: $scope.programmesRow[index].end,
					latitude: $scope.programmesRow[index].latitude,
					longitude: $scope.programmesRow[index].longitude

				};

        function setMarker(i){
          markerEvenement = new L.marker([$scope.programmes[i].latitude, $scope.programmes[i].longitude], {icon: events}).on('click', function(){setMapPopup(pageID, $scope.programmes[i].name, $scope.programmes[i].start + " - " + $scope.programmes[i].end)});
          $scope.EvenementLayer.addLayer(markerEvenement);
          $scope.programmesMarkers.push(markerEvenement);
        }

        setMarker(index);
      }
		});

    map.on('click', function(){closeMapPopup(pageID)});

    $scope.showArtisan = true;
    $scope.showRestaurant = true;
    $scope.showEvenement = true;

    $scope.EvenementLayer.addTo(map);
    $scope.ArtisanLayer.addTo(map);
    $scope.EtablissementLayer.addTo(map);

    $('#restaurant-filter').click(function() {
      if($( this ).hasClass("selected")){
        $( this ).removeClass("selected");
        $( this ).find(".img").removeClass("selected");
        $scope.showRestaurant = false;
        map.removeLayer($scope.EtablissementLayer);

      } else {
        $( this ).addClass("selected");
        $( this ).find(".img").addClass("selected");
        $scope.showRestaurant = true;
        map.addLayer($scope.EtablissementLayer);
      }
    });

    $('#events-filter').click(function() {
      if($( this ).hasClass("selected")){
        $( this ).removeClass("selected");
        $( this ).find(".img").removeClass("selected");
        $scope.showEvenement = false;
        map.removeLayer($scope.EvenementLayer);

      } else {
        $( this ).addClass("selected");
        $( this ).find(".img").addClass("selected");
        $scope.showEvenement = true;
        map.addLayer($scope.EvenementLayer);
      }

    });

    $('#artisans-filter').click(function() {
      if($( this ).hasClass("selected")){
        $( this ).removeClass("selected");
        $( this ).find(".img").removeClass("selected");
        $scope.showArtisan = false;
        map.removeLayer($scope.ArtisanLayer);

      } else {
        $( this ).addClass("selected");
        $( this ).find(".img").addClass("selected");
        $scope.showArtisan = true;
        map.addLayer($scope.ArtisanLayer);
      }
    });

  }
]);
<commit_msg>Débug du maxZoom<commit_after>

angular.module('starter.controllers')
.controller('CarteCtrl', ['$scope', '$http','$rootScope', '$ionicPopup', 'etablissementsService', 'artisansService', 'programmesService',
    function($scope, $http, $rootScope, $ionicPopup, etablissementsService, artisansService, programmesService) {

    var southWest = L.latLng(47.369743926768784, 7.174824539917747),
    northEast = L.latLng(47.360589810163582, 7.1379860116837257),
    bounds = L.latLngBounds(southWest, northEast);

    var map = L.map('mapid', {
        center: [47.364965, 7.154498],
        zoom: 18,
        minZoom: 15,
        maxZoom: 19,
        maxBounds: bounds,
        zoomControl:false,
        tap: false
    });

    $scope.artisansMarkers = [];
    $scope.programmesMarkers = [];
    $scope.etablissementMarkers = [];

    var pageID = $('#page_carte');
    $scope.EvenementLayer = L.layerGroup([]);
    $scope.ArtisanLayer = L.layerGroup([]);
    $scope.EtablissementLayer = L.layerGroup([]);

    // Callback de succès sur la fonction de localisation, si la localisation a fonctionné on affiche la position de l'utilisateur
    var onSuccess = function(position) {

        userLat = position.coords.latitude;
        userLng =  position.coords.longitude;
        userLatLng = L.latLng(userLat, userLng);

        if (userLat < 47.369743926768784 && userLat > 47.360589810163582 && userLng > 7.174824539917747 && userLng < 7.1379860116837257){

          L.marker(userLatLng).addTo(map).bindPopup('Vous êtes ici').openPopup();
          map.panTo(userLatLng);

        } else {

          var alertPopup = $ionicPopup.alert({
            title: 'Erreur de localisation',
            template: 'La localisation ne fonctionne pas en dehors de la ville de St-Ursanne.'
          });

          map.panTo([47.364965, 7.154498]);

        }

    };

    // onError Callback receives a PositionError object
    //
    function onError(error) {
      var alertPopup = $ionicPopup.alert({
        title: 'Erreur de localisation',
        template: 'La localisation ne fonctionne pas. Vérifiez que le GPS soit correctement activé puis réessayez.'
      });

    }

    var ourCustomControl = L.Control.extend({

      options: {
        position: 'topright'
      },

      onAdd: function (map) {
        var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');

        container.onclick = function(){
          navigator.geolocation.getCurrentPosition(onSuccess, onError);
        }

        return container;
      },

    });

    var tileLayer = L.tileLayer(
      'data/img/MapQuest/{z}/{x}/{y}.png', {
        maxZoom: 19,
        minZoom: 15,
        attribution: '© OpenStreetMap contributors'
      }).addTo(map);

    map.addControl(new ourCustomControl());

    var restaurant = L.icon({
      iconUrl: 'data/img/icons/restaurantIcon.png',
      iconAnchor: [17, 36]
    });

    var artisans = L.icon({
      iconUrl: 'data/img/icons/artisanIcon.png',
      iconAnchor: [17, 36]
    });

    var events = L.icon({
      iconUrl: 'data/img/icons/eventIcon.png',
      iconAnchor: [17, 36]
    });

    // Affiche tous les marqueurs des établissements
    etablissementsService.get(function (data) {
			$scope.etablissementsRow = data;
			$scope.etablissements = [];
			for (var index = 0; index < $scope.etablissementsRow.length; index++) {
				$scope.etablissements[index] = {
					id: index,
					name: $scope.etablissementsRow[index].name,
					description: $scope.etablissementsRow[index].description,
         	type: $scope.etablissementsRow[index].type,
          latitude: $scope.etablissementsRow[index].latitude,
          longitude: $scope.etablissementsRow[index].longitude
			  };

        function setMarker(i){
          markerEtablissement = new L.marker([$scope.etablissements[i].latitude, $scope.etablissements[i].longitude], {icon: restaurant});
          $scope.EtablissementLayer.addLayer(markerEtablissement);
          $scope.etablissementMarkers.push(markerEtablissement);
        }

        setMarker(index);
			}
		});

    // Affiche tous les marqueurs des artisans
    artisansService.get(function (data) {
			$scope.artisansRow = data;
			$scope.artisans = [];
			for (var index = 0; index < $scope.artisansRow.length; index++) {
				$scope.artisans[index] = {
					id: index,
					name: $scope.artisansRow[index].name,
					latitude: $scope.artisansRow[index].latitude,
					longitude: $scope.artisansRow[index].longitude
				};

        function setMarker(i){
          markerArtisan = new L.marker([$scope.artisans[i].latitude, $scope.artisans[i].longitude], {icon: artisans}).on('click', function(){setMapPopup(pageID, $scope.artisans[i].name, "")});
          $scope.ArtisanLayer.addLayer(markerArtisan);
          $scope.artisansMarkers.push(markerArtisan);
        }

        setMarker(index);
			}
		});

    // Affiche tous les marqueurs du programme (événements)
    programmesService.get(function (data) {
			$scope.programmesRow = data;
			$scope.programmes = [];
			for (var index = 0; index < $scope.programmesRow.length; index++) {
				$scope.programmes[index] = {
					id: index,
					name: $scope.programmesRow[index].name,
          description: $scope.programmesRow[index].description,
					start: $scope.programmesRow[index].start,
					end: $scope.programmesRow[index].end,
					latitude: $scope.programmesRow[index].latitude,
					longitude: $scope.programmesRow[index].longitude

				};

        function setMarker(i){
          markerEvenement = new L.marker([$scope.programmes[i].latitude, $scope.programmes[i].longitude], {icon: events}).on('click', function(){setMapPopup(pageID, $scope.programmes[i].name, $scope.programmes[i].start + " - " + $scope.programmes[i].end)});
          $scope.EvenementLayer.addLayer(markerEvenement);
          $scope.programmesMarkers.push(markerEvenement);
        }

        setMarker(index);
      }
		});

    map.on('click', function(){closeMapPopup(pageID)});

    $scope.showArtisan = true;
    $scope.showRestaurant = true;
    $scope.showEvenement = true;

    $scope.EvenementLayer.addTo(map);
    $scope.ArtisanLayer.addTo(map);
    $scope.EtablissementLayer.addTo(map);

    $('#restaurant-filter').click(function() {
      if($( this ).hasClass("selected")){
        $( this ).removeClass("selected");
        $( this ).find(".img").removeClass("selected");
        $scope.showRestaurant = false;
        map.removeLayer($scope.EtablissementLayer);

      } else {
        $( this ).addClass("selected");
        $( this ).find(".img").addClass("selected");
        $scope.showRestaurant = true;
        map.addLayer($scope.EtablissementLayer);
      }
    });

    $('#events-filter').click(function() {
      if($( this ).hasClass("selected")){
        $( this ).removeClass("selected");
        $( this ).find(".img").removeClass("selected");
        $scope.showEvenement = false;
        map.removeLayer($scope.EvenementLayer);

      } else {
        $( this ).addClass("selected");
        $( this ).find(".img").addClass("selected");
        $scope.showEvenement = true;
        map.addLayer($scope.EvenementLayer);
      }

    });

    $('#artisans-filter').click(function() {
      if($( this ).hasClass("selected")){
        $( this ).removeClass("selected");
        $( this ).find(".img").removeClass("selected");
        $scope.showArtisan = false;
        map.removeLayer($scope.ArtisanLayer);

      } else {
        $( this ).addClass("selected");
        $( this ).find(".img").addClass("selected");
        $scope.showArtisan = true;
        map.addLayer($scope.ArtisanLayer);
      }
    });

  }
]);
<|endoftext|>


<commit_before>if(typeof widget_widget == 'undefined') {
    loadplugin('widget_widget');
}

var widget_famultibutton = $.extend({}, widget_widget, {
    widgetname : 'famultibutton',
    _doubleclicked: function(elem, onoff) {
        if(elem.data('doubleclick')*1>0) {
            if(! elem.data('_firstclick')) {
                elem.data('_firstclick', true);
                if(onoff == 'on') {
                    elem.data('_firstclick_reset', setTimeout(function() {
                        elem.data('_firstclick', false);
                        elem.setOff();
                    }, elem.data('doubleclick')*1));
                    elem.setOff();
                } else {
                    elem.data('_firstclick_reset', setTimeout(function() {
                        elem.data('_firstclick', false);
                        elem.setOn();
                    }, elem.data('doubleclick')*1));
                    elem.setOn();
                }
                elem.children().filter('#bg').css('color', elem.data('firstclick-background-color'));
                elem.children().filter('#fg').css('color', elem.data('firstclick-color'));
                return false;
            } else {
                elem.data('_firstclick', false);
                clearTimeout(elem.data('_firstclick_reset'));
            }
        }
        return true;
    },
    showOverlay : function(elem, value) {
         elem.children().filter('#warn-back').remove();
         elem.children().filter('#warn').remove();
         if (value && value!=""){
             var val = ($.isNumeric(value)&&value<100)?Number(value).toFixed(0):'!';
             jQuery('<i/>', {
                 id: 'warn-back',
                 class: 'fa fa-stack-1x fa-circle'
             }).appendTo(elem);

            jQuery('<i/>', {
                 id: 'warn',
                 class: 'fa fa-stack-1x '
            }).html(val).appendTo(elem);
         }
    },
    showMultiStates : function(elem,states,state){

        var icons=elem.data('icons');
        var colors=elem.data('on-colors');
        var bgcolors=elem.data('on-background-colors');

        // if data-icons isn't set, try using data-icon or fa-power-off instead
        if(typeof icons == 'undefined') {
            icons = new Array(elem.data('icon')||'fa-power-off');
        }
        // if data-colors isn't set, try using data-on-color, data-off-color or #505050 instead
        if(typeof colors == 'undefined') {
            colors = new Array(elem.data('on-color')||elem.data('off-color')||'#505050');
        }

        // if data-background-colors isn't set, try using data-on-background-color, data-off-background-color or #505050 instead
        if(typeof bgcolors == 'undefined') {
            bgcolors = new Array(elem.data('on-background-color')||elem.data('off-background-color')||'#505050');
        }

        // fill up colors and icons to states.length
        // if an index s isn't set, use the value of s-1
        for(var s=0; s<states.length; s++) {
            if(typeof icons[s] == 'undefined') {
                icons[s]=icons[s>0?s-1:0];
            }
            if(typeof colors[s] == 'undefined') {
                colors[s]=colors[s>0?s-1:0];
            }
            if(typeof bgcolors[s] == 'undefined') {
                bgcolors[s]=bgcolors[s>0?s-1:0];
            }
        }

        var elm=elem.children().filter('#fg');
        var idx=indexOfGeneric(states,state);
        if (idx>-1){
            elm.removeClass()
            .addClass('fa fa-stack-1x')
            .addClass(icons[idx])
            .css( "color", colors[idx] );

            var bgelm=elem.children().filter('#bg');
            bgelm.css( "color", bgcolors[idx]);
        }
    },
    toggleOn : function(elem) {
        if(this._doubleclicked(elem, 'on')) {
            var device = elem.data('device');
            var cmd = [elem.data('cmd'), device, elem.data('set'), elem.data('set-on')].join(' ');
            setFhemStatus(cmd);
            if( device && typeof device != "undefined" && device !== " ") {
                TOAST && $.toast(cmd);
            }
            elem.trigger("toggleOn");
        }
    },
    toggleOff : function(elem) {
        if(this._doubleclicked(elem, 'off')) {
            var device = elem.data('device');
            var cmd = [elem.data('cmd'), device, elem.data('set'), elem.data('set-off')].join(' ');
            setFhemStatus(cmd);
            if( device && typeof device != "undefined" && device !== " ") {
                TOAST && $.toast(cmd);
            }
        }
    },
    valueChanged: function(elem,v) {
    },
    init_attr : function(elem) {
        elem.data('get',        elem.data('get')        || 'STATE');
        elem.data('set',        typeof elem.data('set')     != 'undefined' ? elem.data('set')     : '');
        elem.data('cmd',        typeof elem.data('cmd')     != 'undefined' ? elem.data('cmd')     : 'set');
        elem.data('get-on',     typeof elem.data('get-on')  != 'undefined' ? elem.data('get-on')  : 'on');
        elem.data('get-off',    typeof elem.data('get-off') != 'undefined' ? elem.data('get-off') : 'off');
        elem.data('set-on',     typeof elem.data('set-on')  != 'undefined' ? elem.data('set-on')  : elem.data('get-on'));
        elem.data('set-off',    typeof elem.data('set-off') != 'undefined' ? elem.data('set-off') : elem.data('get-off'));
        elem.data('mode',       elem.data('mode')       || 'toggle');
        elem.data('doubleclick',                    elem.data('doubleclick')                    || 0);
        elem.data('firstclick-background-color',    elem.data('firstclick-background-color')    ||  '#6F4500');
        elem.data('firstclick-color',               elem.data('firstclick-color')               ||  null);
        readings[elem.data('get')] = true;
    },
    init_ui : function(elem) {
        var base = this;
        elem.famultibutton({
            mode: elem.data('mode'),
            toggleOn: function() { base.toggleOn(elem) },
            toggleOff: function() { base.toggleOff(elem) },
            valueChanged: function(v) { base.valueChanged(elem,v) },
        });
        return elem;
    },
    init: function () {
        var base = this;
        this.elements = $('div[data-type="'+this.widgetname+'"]');
        this.elements.each(function(index) {
            base.init_attr($(this));
            base.init_ui($(this));
        });
    },
    update_cb : function(elem) {},
    update: function (dev,par) {
        var deviceElements= this.elements.filter('div[data-device="'+dev+'"]');
        var base = this;
        deviceElements.each(function(index) {
            if ( $(this).data('get')==par) {
                var state = getDeviceValue( $(this), 'get' );
                if (state) {
                    var states=$(this).data('get-on');
                    if ( $.isArray(states)) {
                        base.showMultiStates($(this),states,state);
                    } else {
                        var elem = $(this).data('famultibutton');
                        if (elem){
                            if ( state == $(this).data('get-on') )
                                 elem.setOn();
                            else if ( state == $(this).data('get-off') )
                                 elem.setOff();
                            else if ( state.match(new RegExp('^' + $(this).data('get-on') + '$')) )
                                 elem.setOn();
                            else if ( state.match(new RegExp('^' + $(this).data('get-off') + '$')) )
                                 elem.setOff();
                            else if ( $(this).data('get-off')=='!on' && state != $(this).data('get-on') )
                                 elem.setOff();
                            else if ( $(this).data('get-on')=='!off' && state != $(this).data('get-off') )
                                 elem.setOn();
                        }
                    }
                    base.update_cb($(this),state);
                }
            }
        });
    }
});
<commit_msg>widget_famultibutton: data-fhem-cmd, data-url, data-url-xhr<commit_after>if(typeof widget_widget == 'undefined') {
    loadplugin('widget_widget');
}

var widget_famultibutton = $.extend({}, widget_widget, {
    widgetname : 'famultibutton',
    _doubleclicked: function(elem, onoff) {
        if(elem.data('doubleclick')*1>0) {
            if(! elem.data('_firstclick')) {
                elem.data('_firstclick', true);
                if(onoff == 'on') {
                    elem.data('_firstclick_reset', setTimeout(function() {
                        elem.data('_firstclick', false);
                        elem.setOff();
                    }, elem.data('doubleclick')*1));
                    elem.setOff();
                } else {
                    elem.data('_firstclick_reset', setTimeout(function() {
                        elem.data('_firstclick', false);
                        elem.setOn();
                    }, elem.data('doubleclick')*1));
                    elem.setOn();
                }
                elem.children().filter('#bg').css('color', elem.data('firstclick-background-color'));
                elem.children().filter('#fg').css('color', elem.data('firstclick-color'));
                return false;
            } else {
                elem.data('_firstclick', false);
                clearTimeout(elem.data('_firstclick_reset'));
            }
        }
        return true;
    },
    showOverlay : function(elem, value) {
         elem.children().filter('#warn-back').remove();
         elem.children().filter('#warn').remove();
         if (value && value!=""){
             var val = ($.isNumeric(value)&&value<100)?Number(value).toFixed(0):'!';
             jQuery('<i/>', {
                 id: 'warn-back',
                 class: 'fa fa-stack-1x fa-circle'
             }).appendTo(elem);

            jQuery('<i/>', {
                 id: 'warn',
                 class: 'fa fa-stack-1x '
            }).html(val).appendTo(elem);
         }
    },
    showMultiStates : function(elem,states,state){

        var icons=elem.data('icons');
        var colors=elem.data('on-colors');
        var bgcolors=elem.data('on-background-colors');

        // if data-icons isn't set, try using data-icon or fa-power-off instead
        if(typeof icons == 'undefined') {
            icons = new Array(elem.data('icon')||'fa-power-off');
        }
        // if data-colors isn't set, try using data-on-color, data-off-color or #505050 instead
        if(typeof colors == 'undefined') {
            colors = new Array(elem.data('on-color')||elem.data('off-color')||'#505050');
        }

        // if data-background-colors isn't set, try using data-on-background-color, data-off-background-color or #505050 instead
        if(typeof bgcolors == 'undefined') {
            bgcolors = new Array(elem.data('on-background-color')||elem.data('off-background-color')||'#505050');
        }

        // fill up colors and icons to states.length
        // if an index s isn't set, use the value of s-1
        for(var s=0; s<states.length; s++) {
            if(typeof icons[s] == 'undefined') {
                icons[s]=icons[s>0?s-1:0];
            }
            if(typeof colors[s] == 'undefined') {
                colors[s]=colors[s>0?s-1:0];
            }
            if(typeof bgcolors[s] == 'undefined') {
                bgcolors[s]=bgcolors[s>0?s-1:0];
            }
        }

        var elm=elem.children().filter('#fg');
        var idx=indexOfGeneric(states,state);
        if (idx>-1){
            elm.removeClass()
            .addClass('fa fa-stack-1x')
            .addClass(icons[idx])
            .css( "color", colors[idx] );

            var bgelm=elem.children().filter('#bg');
            bgelm.css( "color", bgcolors[idx]);
        }
    },
    toggleOn : function(elem) {
        if(this._doubleclicked(elem, 'on')) {
            this.clicked(elem, 'on')
            var blink = elem.data('blink');
            // blink=on     -> always reset state after 200ms
            // blink=off    -> never reset state after 200ms
            // blink=undef  -> reset state after 200ms if device is not set
            if(blink == 'on' || (! elem.data('device') && blink !='off')) {
                setInterval(function() {elem.setOff()}, 200);
            }
        }
    },
    toggleOff : function(elem) {
        if(this._doubleclicked(elem, 'off')) {
            this.clicked(elem, 'off')
            var blink = elem.data('blink');
            if(blink == 'on' || (! elem.data('device') && blink !='off')) {
                setInterval(function() {elem.setOn()}, 200);
            }
        }
    },
    clicked: function(elem, onoff) {
        var target;
        var type;

        if(elem.attr('data-url')) {
            target = elem.attr('data-url');
            type = 'url';
        } else if(elem.attr('data-url-xhr')) {
            target = elem.attr('data-url-xhr');
            type = 'url-xhr';
        } else if(elem.attr('data-fhem-cmd')) {
            target = elem.attr('data-fhem-cmd');
            type = 'fhem-cmd';
        } else {
            target = [elem.data('cmd'), elem.data('device'), elem.data('set'), elem.data('set-'+onoff)].join(' ');
            type = 'fhem-cmd';
        }
        switch(type) {
            case 'url':
                document.location.href = target;
                break;
            case 'url-xhr':
                if(target && typeof target != "undefined" && target !== " ") {
                    $.get(target);
                    TOAST && $.toast(target);
                }
                break;
            case 'fhem-cmd':
                if(target && typeof target != "undefined" && target !== " ") {
                    setFhemStatus(target);
                    TOAST && $.toast(target);
                }
                break;
        }
    },
    valueChanged: function(elem,v) {
    },
    init_attr : function(elem) {
        elem.data('get',        elem.data('get')        || 'STATE');
        elem.data('set',        typeof elem.data('set')     != 'undefined' ? elem.data('set')     : '');
        elem.data('cmd',        typeof elem.data('cmd')     != 'undefined' ? elem.data('cmd')     : 'set');
        elem.data('get-on',     typeof elem.data('get-on')  != 'undefined' ? elem.data('get-on')  : 'on');
        elem.data('get-off',    typeof elem.data('get-off') != 'undefined' ? elem.data('get-off') : 'off');
        elem.data('set-on',     typeof elem.data('set-on')  != 'undefined' ? elem.data('set-on')  : elem.data('get-on'));
        elem.data('set-off',    typeof elem.data('set-off') != 'undefined' ? elem.data('set-off') : elem.data('get-off'));
        elem.data('mode',       elem.data('mode')       || 'toggle');
        elem.data('doubleclick',                    elem.data('doubleclick')                    || 0);
        elem.data('firstclick-background-color',    elem.data('firstclick-background-color')    ||  '#6F4500');
        elem.data('firstclick-color',               elem.data('firstclick-color')               ||  null);
        readings[elem.data('get')] = true;
    },
    init_ui : function(elem) {
        var base = this;
        elem.famultibutton({
            mode: elem.data('mode'),
            toggleOn: function() { base.toggleOn(elem) },
            toggleOff: function() { base.toggleOff(elem) },
            valueChanged: function(v) { base.valueChanged(elem,v) },
        });
        return elem;
    },
    init: function () {
        var base = this;
        this.elements = $('div[data-type="'+this.widgetname+'"]');
        this.elements.each(function(index) {
            base.init_attr($(this));
            base.init_ui($(this));
        });
    },
    update_cb : function(elem) {},
    update: function (dev,par) {
        var deviceElements= this.elements.filter('div[data-device="'+dev+'"]');
        var base = this;
        deviceElements.each(function(index) {
            if ( $(this).data('get')==par) {
                var state = getDeviceValue( $(this), 'get' );
                if (state) {
                    var states=$(this).data('get-on');
                    if ( $.isArray(states)) {
                        base.showMultiStates($(this),states,state);
                    } else {
                        var elem = $(this).data('famultibutton');
                        if (elem){
                            if ( state == $(this).data('get-on') )
                                 elem.setOn();
                            else if ( state == $(this).data('get-off') )
                                 elem.setOff();
                            else if ( state.match(new RegExp('^' + $(this).data('get-on') + '$')) )
                                 elem.setOn();
                            else if ( state.match(new RegExp('^' + $(this).data('get-off') + '$')) )
                                 elem.setOff();
                            else if ( $(this).data('get-off')=='!on' && state != $(this).data('get-on') )
                                 elem.setOff();
                            else if ( $(this).data('get-on')=='!off' && state != $(this).data('get-off') )
                                 elem.setOn();
                        }
                    }
                    base.update_cb($(this),state);
                }
            }
        });
    }
});
<|endoftext|>