<commit_before>import { h, computed, ref } from 'vue'

export default function (props, rootRef) {
  const refocusRef = ref(null)

  const refocusTargetEl = computed(() => {
    if (props.disable !== true) {
      return null
    }

    return h('span', {
      ref: refocusRef,
      class: 'no-outline',
      tabindex: -1
    })
  })

  function refocusTarget (e) {
    if (e !== void 0 && e.type.indexOf('key') === 0) {
      if (document.activeElement !== rootRef.value && rootRef.value.contains(document.activeElement) === true) {
        rootRef.value.focus()
      }
    }
    else if ((e === void 0 || rootRef.value.contains(e.target) === true) && refocusRef.value !== null) {
      refocusRef.value.focus()
    }
  }

  return {
    refocusTargetEl,
    refocusTarget
  }
}
<commit_msg>fix(ui): refocus-target -> guard against null ref #11272<commit_after>import { h, computed, ref } from 'vue'

export default function (props, rootRef) {
  const refocusRef = ref(null)

  const refocusTargetEl = computed(() => {
    if (props.disable !== true) {
      return null
    }

    return h('span', {
      ref: refocusRef,
      class: 'no-outline',
      tabindex: -1
    })
  })

  function refocusTarget (e) {
    const root = rootRef.value

    if (e !== void 0 && e.type.indexOf('key') === 0) {
      if (
        root !== null
        && document.activeElement !== root
        && root.contains(document.activeElement) === true
      ) {
        root.focus()
      }
    }
    else if (
      refocusRef.value !== null
      && (e === void 0 || (root !== null && root.contains(e.target) === true))
    ) {
      refocusRef.value.focus()
    }
  }

  return {
    refocusTargetEl,
    refocusTarget
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var NOTIFICATION_ALARM_NAME = 'NOTIFICATION_ALARM1';
var numIds = 0;

function createNotification(options, callback) {
  var notificationId = 'id' + numIds;
  numIds++;
  if (!('iconUrl' in options)) {
    options.iconUrl = 'assets/inbox-64x64.png';
  }
  options.message = options.message || 'notificationId = ' + notificationId;
  chrome.notifications.create(notificationId, options, function(notificationId) {
    if (callback) callback(notificationId);
  });
}

console.log('Notifications test registered for alarms');

chrome.alarms.onAlarm.addListener(function(alarm) {
  if (alarm.name === NOTIFICATION_ALARM_NAME) {
    console.log("Received alarm: " + alarm.name);
    createNotification({
      type:'basic',
      title:'Alarm notification',
    });
  }
});

chrome.notifications.onClosed.addListener(function(notificationId, byUser) {
  logger('onClosed fired. notificationId = ' + notificationId + ', byUser = ' + byUser);
});

chrome.notifications.onClicked.addListener(function(notificationId) {
  logger('onClicked fired. notificationId = ' + notificationId);
  chrome.notifications.clear(notificationId, function(wasCleared) {});
  logger('Showing window after 2 second');
  setTimeout(function() {
    var wnd = chrome.app.window.getAll()[0];
    if (wnd) {
      wnd.show();
    } else {
      logger('Creating Ui Window & showing');
      createUiWindow(function(appWnd) {
        // Todo: figure out how to navigate to notifications manual test page.
      });
    }
  }, 2000);
});

chrome.notifications.onButtonClicked.addListener(function(notificationId, buttonIndex) {
  logger('onButtonClicked fired. notificationId = ' + notificationId + ', buttonIndex = ' + buttonIndex);
});

registerManualTests('chrome.notifications', function(rootEl, addButton) {
  addButton('Basic Notification', function() {
    createNotification({
      type:'basic',
      title:'Basic Notification',
    });
  });

  addButton('Long Basic Notification', function() {
    createNotification({
      type:'basic',
      title:'Basic Notification',
      message: 'the quick slick thick brown fox jumps over the gosh darned lazy hazy brazy mazy dog.'
    });
  });

  addButton('Image Notification', function() {
    createNotification({
      type:'image',
      title:'Image Notification',
      imageUrl:'assets/tahoe-320x215.png'
    });
  });

  addButton('Progress Notification', function() {
    var options = {
      type:'progress',
      title:'Progress Notification',
      progress: 0,
    };
    createNotification(options, function(notificationId) {
      var intervalId = setInterval(function() {
        if (options.progress <= 100) {
          options.progress = options.progress + 1;
          chrome.notifications.update(notificationId, options, function() {});
        } else {
          clearInterval(intervalId);
          chrome.notifications.clear(notificationId, function() {});
        }
      }, 60);
    });
  });

  addButton('Basic -> Progress Notification', function() {
    var options = {
      type:'basic',
      title:'Basic -> Progress Notification',
    };
    createNotification(options, function(notificationId) {

      // Change to a progress notification
      options = {
        title:'Progress (was Basic) Notification',
        type:'progress',
        progress: 0,
      };

      chrome.notifications.update(notificationId, options, function() {
        // Now periodically update the progress
        delete options['type'];
        var intervalId = setInterval(function() {
          if (options.progress <= 100) {
            options.progress = options.progress + 1;
            chrome.notifications.update(notificationId, options, function() {});
          } else {
            clearInterval(intervalId);
          }
        }, 60);
      });
    });
  });

  addButton('List Notification', function() {
    createNotification({
      type:'list',
      title:'List Notification',
      items:[{title:'Item1', message:'This is item 1'},
             {title:'Item2', message:'This is item 2'},
             {title:'Item3', message:'This is item 3'},
             {title:'Item4', message:'This is item 4'},
             {title:'Item5', message:'This is item 5'},
             {title:'Item6', message:'This is item 6'}]
    });
  });

  addButton('Low Priority', function() {
    createNotification({
      type:'basic',
      title:'Low Priority',
      priority:-2
    });
  });

  addButton('High Priority', function() {
    createNotification({
      type:'basic',
      title:'High Priority',
      priority:2
    });
  });

  addButton('Custom Time', function() {
    createNotification({
      type:'basic',
      title:'Custom Time',
      eventTime:1357016400000
    });
  });

  addButton('Button Test', function() {
    createNotification({
      type:'basic',
      title:'Button Test',
      buttons:[{title:'Button 0'}, {title:'Button 1'}, {title:'Button 2'}]
    });
  });

  addButton('Notification after 3 second alarm', function() {
    var expectedFireTime = Date.now() + 3000;
    chrome.alarms.create(NOTIFICATION_ALARM_NAME, { when:expectedFireTime });
  });
});
<commit_msg>Change notifications tests to use background-app plugin.<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var NOTIFICATION_ALARM_NAME = 'NOTIFICATION_ALARM1';
var numIds = 0;

function createNotification(options, callback) {
  var notificationId = 'id' + numIds;
  numIds++;
  if (!('iconUrl' in options)) {
    options.iconUrl = 'assets/inbox-64x64.png';
  }
  options.message = options.message || 'notificationId = ' + notificationId;
  chrome.notifications.create(notificationId, options, function(notificationId) {
    if (callback) callback(notificationId);
  });
}

console.log('Notifications test registered for alarms');

chrome.alarms.onAlarm.addListener(function(alarm) {
  if (alarm.name === NOTIFICATION_ALARM_NAME) {
    console.log("Received alarm: " + alarm.name);
    createNotification({
      type:'basic',
      title:'Alarm notification',
    });
  }
});

chrome.notifications.onClosed.addListener(function(notificationId, byUser) {
  logger('onClosed fired. notificationId = ' + notificationId + ', byUser = ' + byUser);
});

chrome.notifications.onClicked.addListener(function(notificationId) {
  logger('onClicked fired. notificationId = ' + notificationId);
  chrome.notifications.clear(notificationId, function(wasCleared) {});
  logger('Showing window.');
  var wnd = chrome.app.window.getAll()[0];
  if (wnd) {
    wnd.show();
  } else {
    logger('Creating Ui Window & showing');
    createUiWindow(function(appWnd) {
      // Todo: figure out how to navigate to notifications manual test page.
    });
  }
});

chrome.notifications.onButtonClicked.addListener(function(notificationId, buttonIndex) {
  logger('onButtonClicked fired. notificationId = ' + notificationId + ', buttonIndex = ' + buttonIndex);
});

registerManualTests('chrome.notifications', function(rootEl, addButton) {
  addButton('Basic Notification', function() {
    createNotification({
      type:'basic',
      title:'Basic Notification',
    });
  });

  addButton('Long Basic Notification', function() {
    createNotification({
      type:'basic',
      title:'Basic Notification',
      message: 'the quick slick thick brown fox jumps over the gosh darned lazy hazy brazy mazy dog.'
    });
  });

  addButton('Image Notification', function() {
    createNotification({
      type:'image',
      title:'Image Notification',
      imageUrl:'assets/tahoe-320x215.png'
    });
  });

  addButton('Progress Notification', function() {
    var options = {
      type:'progress',
      title:'Progress Notification',
      progress: 0,
    };
    createNotification(options, function(notificationId) {
      var intervalId = setInterval(function() {
        if (options.progress <= 100) {
          options.progress = options.progress + 1;
          chrome.notifications.update(notificationId, options, function() {});
        } else {
          clearInterval(intervalId);
          chrome.notifications.clear(notificationId, function() {});
        }
      }, 60);
    });
  });

  addButton('Basic -> Progress Notification', function() {
    var options = {
      type:'basic',
      title:'Basic -> Progress Notification',
    };
    createNotification(options, function(notificationId) {

      // Change to a progress notification
      options = {
        title:'Progress (was Basic) Notification',
        type:'progress',
        progress: 0,
      };

      chrome.notifications.update(notificationId, options, function() {
        // Now periodically update the progress
        delete options['type'];
        var intervalId = setInterval(function() {
          if (options.progress <= 100) {
            options.progress = options.progress + 1;
            chrome.notifications.update(notificationId, options, function() {});
          } else {
            clearInterval(intervalId);
          }
        }, 60);
      });
    });
  });

  addButton('List Notification', function() {
    createNotification({
      type:'list',
      title:'List Notification',
      items:[{title:'Item1', message:'This is item 1'},
             {title:'Item2', message:'This is item 2'},
             {title:'Item3', message:'This is item 3'},
             {title:'Item4', message:'This is item 4'},
             {title:'Item5', message:'This is item 5'},
             {title:'Item6', message:'This is item 6'}]
    });
  });

  addButton('Low Priority', function() {
    createNotification({
      type:'basic',
      title:'Low Priority',
      priority:-2
    });
  });

  addButton('High Priority', function() {
    createNotification({
      type:'basic',
      title:'High Priority',
      priority:2
    });
  });

  addButton('Custom Time', function() {
    createNotification({
      type:'basic',
      title:'Custom Time',
      eventTime:1357016400000
    });
  });

  addButton('Button Test', function() {
    createNotification({
      type:'basic',
      title:'Button Test',
      buttons:[{title:'Button 0'}, {title:'Button 1'}, {title:'Button 2'}]
    });
  });

  addButton('Notification after 3 second alarm', function() {
    var expectedFireTime = Date.now() + 3000;
    chrome.alarms.create(NOTIFICATION_ALARM_NAME, { when:expectedFireTime });
  });
});
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react'
import classnames from 'classnames'
import _ from 'lodash'

import FunctionSelector from 'src/shared/components/FunctionSelector'
import Dropdown from 'src/shared/components/Dropdown'

import {INFLUXQL_FUNCTIONS} from '../constants'

const {string, shape, func, arrayOf, bool} = PropTypes
const FieldListItem = React.createClass({
  propTypes: {
    fieldFunc: shape({
      field: string.isRequired,
      funcs: arrayOf(string).isRequired,
    }).isRequired,
    isSelected: bool.isRequired,
    onToggleField: func.isRequired,
    onApplyFuncsToField: func.isRequired,
    isKapacitorRule: bool.isRequired,
  },

  getInitialState() {
    return {
      isOpen: false,
    }
  },

  toggleFunctionsMenu(e) {
    if (e) {
      e.stopPropagation()
    }
    this.setState({isOpen: !this.state.isOpen})
  },

  handleToggleField() {
    this.props.onToggleField(this.props.fieldFunc)
  },

  handleApplyFunctions(selectedFuncs) {
    this.props.onApplyFuncsToField({
      field: this.props.fieldFunc.field,
      funcs: this.props.isKapacitorRule ? [selectedFuncs.text] : selectedFuncs,
    })
    this.setState({isOpen: false})
  },

  render() {
    const {isKapacitorRule, fieldFunc, isSelected} = this.props
    const {isOpen} = this.state
    const {field: fieldText} = fieldFunc
    const items = INFLUXQL_FUNCTIONS.map(text => {
      return {text}
    })

    if (isKapacitorRule) {
      return (

            {fieldText}

          {isSelected
            ? <Dropdown
                items={items}
                onChoose={this.handleApplyFunctions}
                selected={
                  fieldFunc.funcs.length ? fieldFunc.funcs[0] : 'Function'
                }
              />
            : null
          }

      )
    }

    return (

            {fieldText}

          {isSelected
            ?

                Functions

            : null
          }

        {(isSelected && isOpen)
          ? <FunctionSelector
              onApply={this.handleApplyFunctions}
              selectedItems={fieldFunc.funcs || []}
            />
          : null}

    )
  },
})

export default FieldListItem
<commit_msg>Use proper naming for functions<commit_after>import React, {PropTypes} from 'react'
import classnames from 'classnames'
import _ from 'lodash'

import FunctionSelector from 'src/shared/components/FunctionSelector'
import Dropdown from 'src/shared/components/Dropdown'

import {INFLUXQL_FUNCTIONS} from '../constants'

const {string, shape, func, arrayOf, bool} = PropTypes
const FieldListItem = React.createClass({
  propTypes: {
    fieldFunc: shape({
      field: string.isRequired,
      funcs: arrayOf(string).isRequired,
    }).isRequired,
    isSelected: bool.isRequired,
    onToggleField: func.isRequired,
    onApplyFuncsToField: func.isRequired,
    isKapacitorRule: bool.isRequired,
  },

  getInitialState() {
    return {
      isOpen: false,
    }
  },

  toggleFunctionsMenu(e) {
    if (e) {
      e.stopPropagation()
    }
    this.setState({isOpen: !this.state.isOpen})
  },

  handleToggleField() {
    this.props.onToggleField(this.props.fieldFunc)
  },

  onApplyFunctions(selectedFuncs) {
    this.props.onApplyFuncsToField({
      field: this.props.fieldFunc.field,
      funcs: this.props.isKapacitorRule ? [selectedFuncs.text] : selectedFuncs,
    })
    this.setState({isOpen: false})
  },

  render() {
    const {isKapacitorRule, fieldFunc, isSelected} = this.props
    const {isOpen} = this.state
    const {field: fieldText} = fieldFunc
    const items = INFLUXQL_FUNCTIONS.map(text => {
      return {text}
    })

    if (isKapacitorRule) {
      return (

            {fieldText}

          {isSelected
            ? <Dropdown
                items={items}
                onChoose={this.onApplyFunctions}
                selected={
                  fieldFunc.funcs.length ? fieldFunc.funcs[0] : 'Function'
                }
              />
            : null
          }

      )
    }

    return (

            {fieldText}

          {isSelected
            ?

                Functions

            : null
          }

        {(isSelected && isOpen)
          ? <FunctionSelector
              onApply={this.onApplyFunctions}
              selectedItems={fieldFunc.funcs || []}
            />
          : null}

    )
  },
})

export default FieldListItem
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react'

import DatabaseDropdown from 'shared/components/DatabaseDropdown'
import OnClickOutside from 'shared/components/OnClickOutside'

class WriteDataForm extends Component {
  constructor(props) {
    super(props)
    this.state = {
      selectedDatabase: null,
    }

    this.handleSelectDatabase = ::this.handleSelectDatabase
    this.handleWrite = ::this.handleWrite
    this.handleClickOutside = ::this.handleClickOutside
  }

  handleSelectDatabase(item) {
    this.setState({selectedDatabase: item.text})
  }

  handleClickOutside() {
    const {onClose} = this.props
    onClose()
  }

  handleWrite() {
    const {onClose, source, writeData} = this.props
    const {selectedDatabase} = this.state
    writeData(source, selectedDatabase, this.editor.value).then(() => onClose())
  }

  render() {
    const {onClose, errorThrown} = this.props
    const {selectedDatabase} = this.state

    return (

Write Data To

            <DatabaseDropdown
              onSelectDatabase={this.handleSelectDatabase}
              database={selectedDatabase}
              onErrorThrown={errorThrown}
            />

          <textarea
            className="query-editor--field"
            autoComplete="off"
            spellCheck="false"
            placeholder="<measurement>,<tag_key>=<tag_value> <field_key>=<field_value>"
            ref={editor => this.editor = editor}
          />

            Uses InfluxDB Line Protocol -

              Docs

            <button className="btn btn-primary" onClick={this.handleWrite}>
              Write
            </button>

    )
  }
}

const {func, shape, string} = PropTypes

WriteDataForm.propTypes = {
  source: shape({
    links: shape({
      proxy: string.isRequired,
      self: string.isRequired,
      queries: string.isRequired,
    }).isRequired,
  }).isRequired,
  onClose: func.isRequired,
  writeData: func.isRequired,
  errorThrown: func.isRequired,
}

export default OnClickOutside(WriteDataForm)
<commit_msg>close writedataform on escape<commit_after>import React, {Component, PropTypes} from 'react'

import DatabaseDropdown from 'shared/components/DatabaseDropdown'
import OnClickOutside from 'shared/components/OnClickOutside'

class WriteDataForm extends Component {
  constructor(props) {
    super(props)
    this.state = {
      selectedDatabase: null,
    }

    this.handleSelectDatabase = ::this.handleSelectDatabase
    this.handleWrite = ::this.handleWrite
    this.handleClickOutside = ::this.handleClickOutside
    this.handleKeyUp = ::this.handleKeyUp
  }

  handleSelectDatabase(item) {
    this.setState({selectedDatabase: item.text})
  }

  handleClickOutside() {
    const {onClose} = this.props
    onClose()
  }

  handleKeyUp(e) {
    const escapeKeyCode = 27
    if (e.which === escapeKeyCode) {
      const {onClose} = this.props
      onClose()
    }
  }

  handleWrite() {
    const {onClose, source, writeData} = this.props
    const {selectedDatabase} = this.state
    writeData(source, selectedDatabase, this.editor.value).then(() => onClose())
  }

  render() {
    const {onClose, errorThrown} = this.props
    const {selectedDatabase} = this.state

    return (

Write Data To

            <DatabaseDropdown
              onSelectDatabase={this.handleSelectDatabase}
              database={selectedDatabase}
              onErrorThrown={errorThrown}
            />

          <textarea
            className="query-editor--field"
            autoComplete="off"
            spellCheck="false"
            placeholder="<measurement>,<tag_key>=<tag_value> <field_key>=<field_value>"
            ref={editor => this.editor = editor}
            onKeyUp={this.handleKeyUp}
            autoFocus={true}
          />

            Uses InfluxDB Line Protocol -

              Docs

            <button className="btn btn-primary" onClick={this.handleWrite}>
              Write
            </button>

    )
  }
}

const {func, shape, string} = PropTypes

WriteDataForm.propTypes = {
  source: shape({
    links: shape({
      proxy: string.isRequired,
      self: string.isRequired,
      queries: string.isRequired,
    }).isRequired,
  }).isRequired,
  onClose: func.isRequired,
  writeData: func.isRequired,
  errorThrown: func.isRequired,
}

export default OnClickOutside(WriteDataForm)
<|endoftext|>


<commit_before>'use strict';

angular.module('<%=angularAppName%>')
    .controller('GatewayController', function ($scope, $filter, $interval, GatewayRoutes) {
        $scope.refresh = function () {
            $scope.updatingRoutes = true;
            GatewayRoutes.query(function(result) {
                $scope.gatewayRoutes = result;
                $scope.updatingRoutes = false;
            });
        };

        $scope.refresh();

        // refresh the list of services every 2 seconds
        $interval(function() {
            $scope.refresh();
        }.bind(this), 2000);
    });
<commit_msg>Do not refresh routes every 2 seconds<commit_after>'use strict';

angular.module('<%=angularAppName%>')
    .controller('GatewayController', function ($scope, $filter, $interval, GatewayRoutes) {
        $scope.refresh = function () {
            $scope.updatingRoutes = true;
            GatewayRoutes.query(function(result) {
                $scope.gatewayRoutes = result;
                $scope.updatingRoutes = false;
            });
        };

        $scope.refresh();
    });
<|endoftext|>


<commit_before>// JavaScript Document
var GIVe = (function (give) {
  'use strict'

  give.RefObject = function (DB, Name, CommonName, IsEncode, Ref, ChromInfo, settings) {
    // notice that ChromInfo is the JSON encoded object
    //    for chromosome information from chromInfo.php

    // this is for navigation thing
    this.isCollapsed = false
    // whether this ref is collapsed in the browser
    this.isActive = true
    // if user has not selected this ref to display, then it will become false;
    // this is also used for navigation only

    this.db = DB
    this.name = Name
    this.commonName = CommonName
    this.isEncode = IsEncode
    this.ref = Ref
    this.groups = {}        // this is used to get all the groups
    this.settings = {}        // object for all settings

    this.metaFilter = {
      expMap: {},
      cellLineMap: {},
      labMap: {},
      tissueMap: {}
    }

    // read Object for ref chrom info (if there)
    this.initChromInfo(ChromInfo)

    this.tracksUpdated = false    // regardless of whether user has selected
    this._tracksInitialized = false    // regardless of whether user has selected
    this._tracksInitializing = false
    this.tracks = new give.TrackGroup()

    // this.initTracksFromServer()
    // initialize whenever tracks are needed

    // this is for tracks, every entry is a uniTrack Object
    // this.tracksEncode = new TrackBundleWithSample(this.db, '', '', '');

    // this.regionToShow = null;
    // this is to define the region used to show
    // (give.ChromRegion Object, including name, strand and coordinates)

    // this.orderedtracksEncode = new Array();

    if (settings) {
      for (var key in settings) {
        if (settings.hasOwnProperty(key) && !this.hasOwnProperty(key)) {
          this.settings[key] = settings[key]
        }
      }
    }

    this.metaFilterInitialized = false
    if (give.mainTaskScheduler) {
      give.mainTaskScheduler.addTask(new give.TaskEntry(
        this.initializeMetaFilter.bind(this),
        ['meta-data-ready', this.getCleanID() + '-tracks-ready']
      ))
    }

    this.reverseLookupTable = {}
    if (!this.settings.hasOwnProperty('defaultViewWindows')) {
      this.settings.defaultViewWindows = give.RefObject.defaultViewWindows
    }
    if (typeof this.settings.defaultViewWindows === 'string') {
      this.settings.defaultViewWindows = [this.settings.defaultViewWindows]
    }
  }

  give.RefObject.prototype.getCleanID = function () {
    return this.db.replace(/[\s()+/]/g, '')
  }

  give.RefObject.prototype.initChromInfo = function (ChromInfo) {
    if (ChromInfo) {
      try {
        this.chromInfo = {}
        for (var chrom in ChromInfo) {
          if (ChromInfo.hasOwnProperty(chrom)) {
            this.chromInfo[chrom] = {}
            this.chromInfo[chrom].name = chrom
            this.chromInfo[chrom].chrRegion =
              new give.ChromRegion(ChromInfo[chrom].chrRegion)
            if (ChromInfo[chrom].cent) {
              this.chromInfo[chrom].cent =
                new give.ChromRegion(ChromInfo[chrom].cent)
            }
            if (chrom.toLowerCase() !== chrom) {
              this.chromInfo[chrom.toLowerCase()] = this.chromInfo[chrom]
            }
          }
        }
      } catch (err) {
        this.ChromInfo = null
        give._verboseConsole(err, give.VERBOSE_DEBUG, 'initChromInfo')
      }
    }
  }

  give.RefObject.prototype.initChromInfoFromServer = function (target) {
    give.postAjax(target || give.RefObject.initChromTarget, {db: this.db}, function (data) {
      this.initChromInfo(data)
      give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: this.getCleanID() + '-chrominfo-ready'})
    }, 'json', null, null, this) // end ajax to initialize ref
  }

  give.RefObject.prototype.initTracks = function (groupInfo, keepOld, requestUrl) {
    // notice that trackInfo is supposed to be an array
    if (!keepOld) {
      this.tracks.clear()
      this.groups = {}
      this.reverseLookupTable = {}
    }
    var loadTrackFromRemoteData = function (groupID, track) {
      var newTrack = new give.TrackObject(track.tableName, track, this)
      newTrack.groupID = groupID
      if (requestUrl && !newTrack.requestUrl) {
        newTrack.requestUrl = requestUrl
      }
      this.tracks.addTrack(newTrack)

      // reverse lookup table related, might be rewritten if table structure is changed later
      if (Array.isArray(newTrack.getTableNames())) {
        newTrack.getTableNames().forEach(function (tableName) {
          this.reverseLookupTable[tableName] = newTrack
        }, this)
      } else {
        this.reverseLookupTable[newTrack.getTableNames()] = newTrack
      }
      // end reverse lookup related

      this.groups[groupID].addTrack(newTrack)
    }
    for (var groupID in groupInfo) {
      if (groupInfo.hasOwnProperty(groupID)) {
        this.groups[groupID] = new give.TrackGroup(groupID, groupInfo[groupID])
        groupInfo[groupID].tracks.forEach(loadTrackFromRemoteData.bind(this, groupID),
                          this)
      }
    }
    this._tracksInitialized = true
    this._tracksInitializing = false
    give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: this.getCleanID() + '-tracks-ready'})
  }

  give.RefObject.prototype.callOnTracksReady = function (callback) {
    // notice that callback needs to be a bound function if 'this' is important
    return this.initTracksFromServer(null, callback)
  }

  give.RefObject.prototype.getTracks = function (callback) {
    if (this._tracksInitialized) {
      return this.tracks
    } else {
      this.initTracksFromServer(null, callback)
      return null
    }
  }

  give.RefObject.prototype.getGroups = function (callback) {
    if (this._tracksInitialized) {
      return this.groups
    } else {
      this.initTracksFromServer(null, callback)
      return null
    }
  }

  give.RefObject.prototype.initTracksFromServer = function (target, callback) {
    // callback is the callback function taking no argument (already bound)
    if (!this._tracksInitialized) {
      if (callback) {
        give.mainTaskScheduler.addTask(new give.TaskEntry(callback,
          [this.getCleanID() + '-tracks-ready']))
      }
      if (!this._tracksInitializing) {
        give.postAjax(target || give.RefObject.initTrackTarget, {db: this.db}, function (data) {
          this.initTracks(data, false, give.TrackObject.fetchDataTarget)
        }, 'json', null, null, this)
        this._tracksInitializing = true
        give._verboseConsole('Tracks not initialized for ref ' +
          this.name + '.', give.VERBOSE_DEBUG)
      }
      return false
    } else {
      if (callback) {
        return callback()
      }
    }
  }

  give.RefObject.prototype.addCustomTrack = function (track, group, callback) {
    // if group ID is not specified, use "customTracks" as ID;
    // replace tracks with the same groupID and track.tableName
    group = group || {}
    var groupID = group.id || 'customTracks'
    if (!this.groups.hasOwnProperty(groupID)) {
      this.groups[groupID] = give.RefObject.createCustomGroup(group)
    }
    // remove existing track
    if (this.groups[groupID].hasTrack(track.tableName)) {
      this.groups[groupID].removeTrack(track.tableName)
      this.tracks.removeTrack(track.tableName)
    }
    var newTrack = new give.TrackObject(track.tableName, track, this)
    newTrack.groupID = groupID
    if (!newTrack.remoteUrl) {
      newTrack.remoteUrl = give.TrackObject.fetchCustomTarget
    }
    this.tracks.addTrack(newTrack)
    this.groups[groupID].addTrack(newTrack)
    if (callback) {
      callback(this)
    }
    give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: this.getCleanID() + '-custom-tracks-ready'})
  }

  give.RefObject.prototype.initializeMetaFilter = function (metaEntries) {
    // metaEntry as give.MetaDataEntries
    metaEntries = metaEntries || give.mainMetaDataEntries
    this.tracks.forEach(function (track) {
      var cellType = track.getSetting('cellType')
      var labName = track.getSetting('labName')
      var tissueType = metaEntries.findMeta(this.commonName, cellType, 'tissue')
      if (track.getCleanLowerTitle()) {
        if (!this.metaFilter.expMap.hasOwnProperty(track.getCleanLowerTitle())) {
          this.metaFilter.expMap[track.getCleanLowerTitle()] = []
          this.metaFilter.expMap[track.getCleanLowerTitle()].name = track.getTitle()
        }
        this.metaFilter.expMap[track.getCleanLowerTitle()].push(track.id)
      }
      if (cellType) {
        if (!this.metaFilter.cellLineMap.hasOwnProperty(cellType)) {
          this.metaFilter.cellLineMap[cellType] = []
        }
        this.metaFilter.cellLineMap[cellType].push(track.id)
      }
      if (labName) {
        if (!this.metaFilter.labMap[labName]) {
          this.metaFilter.labMap[labName] = []
        }
        this.metaFilter.labMap[labName].push(track.id)
      }
      if (tissueType) {
        if (!this.metaFilter.tissueMap[tissueType]) {
          this.metaFilter.tissueMap[tissueType] = []
        }
        this.metaFilter.tissueMap[tissueType].push(track.id)
      } else {
        give._verboseConsole(cellType + ' does not have a tissue type.',
          give.VERBOSE_DEBUG)
      }
    }, this)
    this.metaFilterInitialized = true
    give.fireSignal(give.TASKSCHEDULER_EVENT_NAME,
      {flag: this.getCleanID() + '-meta-filter-ready'})
  }

  give.RefObject.prototype.getFilteredTrackList = function (filter) {
    if (filter) {
      return this.getTracks().filter(filter, this)
    }
    return this.getTracks()
  }

  give.RefObject.prototype.setTrackSettings = function (prop, value, filter) {
    this.getFilteredTrackList(filter).forEach(function (track) {
      track.setSetting(prop, value)
    }, this)
  }

  give.RefObject.prototype.getTrackIDList = function (filter) {
    // return a list of all trackIDs that passes through the filter function
    return this.getFilteredTrackList(filter).map(function (track) {
      return track.id
    }, this)
  }

  give.RefObject.prototype.getTrackTableNameList = function (filter) {
    var result = []
    this.getFilteredTrackList(filter).forEach(function (track) {
      result = result.concat(track.getTableNames())
    }, this)
    return result
  }

  give.RefObject.initAllRef = function (target, refArray, filter, callback) {
    // initialize all ref from db
    // return an array of ref
    // callback is the callback function taking refArray as argument
    refArray = refArray || []
    refArray.splice(0, refArray.length)
    refArray.dbMap = {}
    refArray.ready = false
    refArray.currRef = refArray.currRef || function () {
      return this[this.selected] || this.dbMap[this.selected] || null
    }

    give.postAjax(target || give.RefObject.initAllTarget, {}, function (data) {
      for (var refDb in data) {
        if (data.hasOwnProperty(refDb) && (typeof filter !== 'function' || filter(data[refDb]))) {
          refArray.dbMap[refDb] = new give.RefObject(refDb, data[refDb].name,
                                   data[refDb].commonname,
                                   data[refDb].encode, data[refDb].dbname, data[refDb].chromInfo,
                                   data[refDb].settings)
          refArray.push(refArray.dbMap[refDb])
        }
      }
      refArray.ready = true
      refArray.selected = null
      if (callback) {
        callback(refArray)
      } else {
        give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: 'ref-ready'})
      }
    }, 'json') // end ajax to initialize ref
    return refArray
  }

  give.RefObject.createCustomGroup = function (group) {
    group = group || {}
    var groupID = group.id || 'customTracks'
    group.label = group.label || 'Custom Tracks'
    group.priority = group.priority || give.TrackGroup.CUSTOM_GROUP_PRIORITY
    return new give.TrackGroup(groupID, group)
  }

  give.RefObject.findRefByDb = function (db) {
    if (typeof db === 'string' && !give.RefObject.refArray.ready) {
      // not ready yet, push to task scheduler
      throw (new Error('refArray is not initialized yet! ' +
        'Please use GIVe.RefObject.callOnRefReady() to wrap your function.'))
    } else {
      if (typeof db === 'string' &&
        give.RefObject.refArray.dbMap.hasOwnProperty(db)) {
        // look up reference in give.RefObject.refArray
        return give.RefObject.refArray.dbMap[db]
      } else if (db instanceof give.RefObject) {
        return db
      } else {
        throw (new Error('Invalid RefObject was given: ' + db))
      }
    }
  }

  give.RefObject.callOnRefReady = function (callback) {
    // callback is the callback function taking no argument (already bound)
    if (!give.RefObject.refArray || !give.RefObject.refArray.ready) {
      if (callback) {
        give.mainTaskScheduler.addTask(new give.TaskEntry(callback,
          ['ref-ready']))
      }
      return false
    } else {
      if (callback) {
        return callback()
      }
    }
  }

  give.RefObject.refFilter = give.Ref_RefFilter || function (ref) {
    return ref.settings['isGIVeEnabled']
  }

  give.RefObject.initAllTarget = give.host +
    (give.Ref_InitAllTarget || '/givdata/initRef.php')
  give.RefObject.initChromTarget = give.host +
    (give.Ref_InitChromTarget || '/givdata/initRef.php')
  give.RefObject.initTrackTarget = give.host +
    (give.Ref_InitTrackTarget || '/givdata/initTracks.php')

  give.RefObject.defaultViewWindows = give.Ref_DefaultViewWindows ||
    ['chr10:30000000-55000000', 'chr10:34900000-65000000']

  give.RefObject.refArray = give.RefObject.initAllRef()

  return give
})(GIVe || {})
<commit_msg>Fixed whether a species is part of ENCODE in GeNemo<commit_after>// JavaScript Document
var GIVe = (function (give) {
  'use strict'

  give.RefObject = function (DB, Name, CommonName, IsEncode, Ref, ChromInfo, settings) {
    // notice that ChromInfo is the JSON encoded object
    //    for chromosome information from chromInfo.php

    // this is for navigation thing
    this.isCollapsed = false
    // whether this ref is collapsed in the browser
    this.isActive = true
    // if user has not selected this ref to display, then it will become false;
    // this is also used for navigation only

    this.db = DB
    this.name = Name
    this.commonName = CommonName
    this.isEncode = ((typeof IsEncode === 'boolean') ? IsEncode
      : ((typeof IsEncode === 'string') ? IsEncode !== '0' : !!IsEncode))
    this.ref = Ref
    this.groups = {}        // this is used to get all the groups
    this.settings = {}        // object for all settings

    this.metaFilter = {
      expMap: {},
      cellLineMap: {},
      labMap: {},
      tissueMap: {}
    }

    // read Object for ref chrom info (if there)
    this.initChromInfo(ChromInfo)

    this.tracksUpdated = false    // regardless of whether user has selected
    this._tracksInitialized = false    // regardless of whether user has selected
    this._tracksInitializing = false
    this.tracks = new give.TrackGroup()

    // this.initTracksFromServer()
    // initialize whenever tracks are needed

    // this is for tracks, every entry is a uniTrack Object
    // this.tracksEncode = new TrackBundleWithSample(this.db, '', '', '');

    // this.regionToShow = null;
    // this is to define the region used to show
    // (give.ChromRegion Object, including name, strand and coordinates)

    // this.orderedtracksEncode = new Array();

    if (settings) {
      for (var key in settings) {
        if (settings.hasOwnProperty(key) && !this.hasOwnProperty(key)) {
          this.settings[key] = settings[key]
        }
      }
    }

    this.metaFilterInitialized = false
    if (give.mainTaskScheduler) {
      give.mainTaskScheduler.addTask(new give.TaskEntry(
        this.initializeMetaFilter.bind(this),
        ['meta-data-ready', this.getCleanID() + '-tracks-ready']
      ))
    }

    this.reverseLookupTable = {}
    if (!this.settings.hasOwnProperty('defaultViewWindows')) {
      this.settings.defaultViewWindows = give.RefObject.defaultViewWindows
    }
    if (typeof this.settings.defaultViewWindows === 'string') {
      this.settings.defaultViewWindows = [this.settings.defaultViewWindows]
    }
  }

  give.RefObject.prototype.getCleanID = function () {
    return this.db.replace(/[\s()+/]/g, '')
  }

  give.RefObject.prototype.initChromInfo = function (ChromInfo) {
    if (ChromInfo) {
      try {
        this.chromInfo = {}
        for (var chrom in ChromInfo) {
          if (ChromInfo.hasOwnProperty(chrom)) {
            this.chromInfo[chrom] = {}
            this.chromInfo[chrom].name = chrom
            this.chromInfo[chrom].chrRegion =
              new give.ChromRegion(ChromInfo[chrom].chrRegion)
            if (ChromInfo[chrom].cent) {
              this.chromInfo[chrom].cent =
                new give.ChromRegion(ChromInfo[chrom].cent)
            }
            if (chrom.toLowerCase() !== chrom) {
              this.chromInfo[chrom.toLowerCase()] = this.chromInfo[chrom]
            }
          }
        }
      } catch (err) {
        this.ChromInfo = null
        give._verboseConsole(err, give.VERBOSE_DEBUG, 'initChromInfo')
      }
    }
  }

  give.RefObject.prototype.initChromInfoFromServer = function (target) {
    give.postAjax(target || give.RefObject.initChromTarget, {db: this.db}, function (data) {
      this.initChromInfo(data)
      give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: this.getCleanID() + '-chrominfo-ready'})
    }, 'json', null, null, this) // end ajax to initialize ref
  }

  give.RefObject.prototype.initTracks = function (groupInfo, keepOld, requestUrl) {
    // notice that trackInfo is supposed to be an array
    if (!keepOld) {
      this.tracks.clear()
      this.groups = {}
      this.reverseLookupTable = {}
    }
    var loadTrackFromRemoteData = function (groupID, track) {
      var newTrack = new give.TrackObject(track.tableName, track, this)
      newTrack.groupID = groupID
      if (requestUrl && !newTrack.requestUrl) {
        newTrack.requestUrl = requestUrl
      }
      this.tracks.addTrack(newTrack)

      // reverse lookup table related, might be rewritten if table structure is changed later
      if (Array.isArray(newTrack.getTableNames())) {
        newTrack.getTableNames().forEach(function (tableName) {
          this.reverseLookupTable[tableName] = newTrack
        }, this)
      } else {
        this.reverseLookupTable[newTrack.getTableNames()] = newTrack
      }
      // end reverse lookup related

      this.groups[groupID].addTrack(newTrack)
    }
    for (var groupID in groupInfo) {
      if (groupInfo.hasOwnProperty(groupID)) {
        this.groups[groupID] = new give.TrackGroup(groupID, groupInfo[groupID])
        groupInfo[groupID].tracks.forEach(loadTrackFromRemoteData.bind(this, groupID),
                          this)
      }
    }
    this._tracksInitialized = true
    this._tracksInitializing = false
    give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: this.getCleanID() + '-tracks-ready'})
  }

  give.RefObject.prototype.callOnTracksReady = function (callback) {
    // notice that callback needs to be a bound function if 'this' is important
    return this.initTracksFromServer(null, callback)
  }

  give.RefObject.prototype.getTracks = function (callback) {
    if (this._tracksInitialized) {
      return this.tracks
    } else {
      this.initTracksFromServer(null, callback)
      return null
    }
  }

  give.RefObject.prototype.getGroups = function (callback) {
    if (this._tracksInitialized) {
      return this.groups
    } else {
      this.initTracksFromServer(null, callback)
      return null
    }
  }

  give.RefObject.prototype.initTracksFromServer = function (target, callback) {
    // callback is the callback function taking no argument (already bound)
    if (!this._tracksInitialized) {
      if (callback) {
        give.mainTaskScheduler.addTask(new give.TaskEntry(callback,
          [this.getCleanID() + '-tracks-ready']))
      }
      if (!this._tracksInitializing) {
        give.postAjax(target || give.RefObject.initTrackTarget, {db: this.db}, function (data) {
          this.initTracks(data, false, give.TrackObject.fetchDataTarget)
        }, 'json', null, null, this)
        this._tracksInitializing = true
        give._verboseConsole('Tracks not initialized for ref ' +
          this.name + '.', give.VERBOSE_DEBUG)
      }
      return false
    } else {
      if (callback) {
        return callback()
      }
    }
  }

  give.RefObject.prototype.addCustomTrack = function (track, group, callback) {
    // if group ID is not specified, use "customTracks" as ID;
    // replace tracks with the same groupID and track.tableName
    group = group || {}
    var groupID = group.id || 'customTracks'
    if (!this.groups.hasOwnProperty(groupID)) {
      this.groups[groupID] = give.RefObject.createCustomGroup(group)
    }
    // remove existing track
    if (this.groups[groupID].hasTrack(track.tableName)) {
      this.groups[groupID].removeTrack(track.tableName)
      this.tracks.removeTrack(track.tableName)
    }
    var newTrack = new give.TrackObject(track.tableName, track, this)
    newTrack.groupID = groupID
    if (!newTrack.remoteUrl) {
      newTrack.remoteUrl = give.TrackObject.fetchCustomTarget
    }
    this.tracks.addTrack(newTrack)
    this.groups[groupID].addTrack(newTrack)
    if (callback) {
      callback(this)
    }
    give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: this.getCleanID() + '-custom-tracks-ready'})
  }

  give.RefObject.prototype.initializeMetaFilter = function (metaEntries) {
    // metaEntry as give.MetaDataEntries
    metaEntries = metaEntries || give.mainMetaDataEntries
    this.tracks.forEach(function (track) {
      var cellType = track.getSetting('cellType')
      var labName = track.getSetting('labName')
      var tissueType = metaEntries.findMeta(this.commonName, cellType, 'tissue')
      if (track.getCleanLowerTitle()) {
        if (!this.metaFilter.expMap.hasOwnProperty(track.getCleanLowerTitle())) {
          this.metaFilter.expMap[track.getCleanLowerTitle()] = []
          this.metaFilter.expMap[track.getCleanLowerTitle()].name = track.getTitle()
        }
        this.metaFilter.expMap[track.getCleanLowerTitle()].push(track.id)
      }
      if (cellType) {
        if (!this.metaFilter.cellLineMap.hasOwnProperty(cellType)) {
          this.metaFilter.cellLineMap[cellType] = []
        }
        this.metaFilter.cellLineMap[cellType].push(track.id)
      }
      if (labName) {
        if (!this.metaFilter.labMap[labName]) {
          this.metaFilter.labMap[labName] = []
        }
        this.metaFilter.labMap[labName].push(track.id)
      }
      if (tissueType) {
        if (!this.metaFilter.tissueMap[tissueType]) {
          this.metaFilter.tissueMap[tissueType] = []
        }
        this.metaFilter.tissueMap[tissueType].push(track.id)
      } else {
        give._verboseConsole(cellType + ' does not have a tissue type.',
          give.VERBOSE_DEBUG)
      }
    }, this)
    this.metaFilterInitialized = true
    give.fireSignal(give.TASKSCHEDULER_EVENT_NAME,
      {flag: this.getCleanID() + '-meta-filter-ready'})
  }

  give.RefObject.prototype.getFilteredTrackList = function (filter) {
    if (filter) {
      return this.getTracks().filter(filter, this)
    }
    return this.getTracks()
  }

  give.RefObject.prototype.setTrackSettings = function (prop, value, filter) {
    this.getFilteredTrackList(filter).forEach(function (track) {
      track.setSetting(prop, value)
    }, this)
  }

  give.RefObject.prototype.getTrackIDList = function (filter) {
    // return a list of all trackIDs that passes through the filter function
    return this.getFilteredTrackList(filter).map(function (track) {
      return track.id
    }, this)
  }

  give.RefObject.prototype.getTrackTableNameList = function (filter) {
    var result = []
    this.getFilteredTrackList(filter).forEach(function (track) {
      result = result.concat(track.getTableNames())
    }, this)
    return result
  }

  give.RefObject.initAllRef = function (target, refArray, filter, callback) {
    // initialize all ref from db
    // return an array of ref
    // callback is the callback function taking refArray as argument
    refArray = refArray || []
    refArray.splice(0, refArray.length)
    refArray.dbMap = {}
    refArray.ready = false
    refArray.currRef = refArray.currRef || function () {
      return this[this.selected] || this.dbMap[this.selected] || null
    }

    give.postAjax(target || give.RefObject.initAllTarget, {}, function (data) {
      for (var refDb in data) {
        if (data.hasOwnProperty(refDb) && (typeof filter !== 'function' || filter(data[refDb]))) {
          refArray.dbMap[refDb] = new give.RefObject(refDb, data[refDb].name,
                                   data[refDb].commonname,
                                   data[refDb].encode, data[refDb].dbname, data[refDb].chromInfo,
                                   data[refDb].settings)
          refArray.push(refArray.dbMap[refDb])
        }
      }
      refArray.ready = true
      refArray.selected = null
      if (callback) {
        callback(refArray)
      } else {
        give.fireSignal(give.TASKSCHEDULER_EVENT_NAME, {flag: 'ref-ready'})
      }
    }, 'json') // end ajax to initialize ref
    return refArray
  }

  give.RefObject.createCustomGroup = function (group) {
    group = group || {}
    var groupID = group.id || 'customTracks'
    group.label = group.label || 'Custom Tracks'
    group.priority = group.priority || give.TrackGroup.CUSTOM_GROUP_PRIORITY
    return new give.TrackGroup(groupID, group)
  }

  give.RefObject.findRefByDb = function (db) {
    if (typeof db === 'string' && !give.RefObject.refArray.ready) {
      // not ready yet, push to task scheduler
      throw (new Error('refArray is not initialized yet! ' +
        'Please use GIVe.RefObject.callOnRefReady() to wrap your function.'))
    } else {
      if (typeof db === 'string' &&
        give.RefObject.refArray.dbMap.hasOwnProperty(db)) {
        // look up reference in give.RefObject.refArray
        return give.RefObject.refArray.dbMap[db]
      } else if (db instanceof give.RefObject) {
        return db
      } else {
        throw (new Error('Invalid RefObject was given: ' + db))
      }
    }
  }

  give.RefObject.callOnRefReady = function (callback) {
    // callback is the callback function taking no argument (already bound)
    if (!give.RefObject.refArray || !give.RefObject.refArray.ready) {
      if (callback) {
        give.mainTaskScheduler.addTask(new give.TaskEntry(callback,
          ['ref-ready']))
      }
      return false
    } else {
      if (callback) {
        return callback()
      }
    }
  }

  give.RefObject.refFilter = give.Ref_RefFilter || function (ref) {
    return ref.settings['isGIVeEnabled']
  }

  give.RefObject.initAllTarget = give.host +
    (give.Ref_InitAllTarget || '/givdata/initRef.php')
  give.RefObject.initChromTarget = give.host +
    (give.Ref_InitChromTarget || '/givdata/initRef.php')
  give.RefObject.initTrackTarget = give.host +
    (give.Ref_InitTrackTarget || '/givdata/initTracks.php')

  give.RefObject.defaultViewWindows = give.Ref_DefaultViewWindows ||
    ['chr10:30000000-55000000', 'chr10:34900000-65000000']

  give.RefObject.refArray = give.RefObject.initAllRef()

  return give
})(GIVe || {})
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011  JTalks.org Team
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * This script provides interactive UI for contact management in user profile.
 */

/**
 * Application base path with trailing slash. Must be defined somewhere within the global scope.
 */
var baseUrl = $root;

/**
 * Namespace for this file.
 */
var AddContact = {};

/** Currently selected contact type */
AddContact.selectedContactType = null;

/** Aall contact types */
AddContact.contactTypes = null;

/** if entered contact is valid */
AddContact.isValueValid = true;

function deleteContactHandler() {
    var element = $(this).parent();
    var contactId = $(this).parent().find("#contactId:hidden").attr("value");
    var contactOwnerId = $(this).parent().find("#contactOwnerId:hidden").attr("value");

    var footerContent = ' \
            <button id="remove-contact-cancel" class="btn">' + $labelCancel + '</button> \
            <button id="remove-contact-ok" class="btn btn-primary">' + $labelOk + '</button>'

    var submitFunc = function (e) {
        e.preventDefault();
        $.ajax({
            url: baseUrl + '/contacts/remove/' + contactOwnerId + '/' + contactId,
            // this is the way Spring MVC represents HTTP DELETE for better browser compatibility
            type: "POST",
            data: {'_method': 'DELETE'},
            success: function () {
                element.fadeOut();
                jDialog.closeDialog();
            },
            error: function () {
                jDialog.createDialog({
                    type: jDialog.alertType,
                    bodyMessage: $labelDeleteContactFailture
                });
            }
        });
    };

    jDialog.createDialog({
        type: jDialog.confirmType,
        bodyMessage: $labelDeleteContactConfirmation,
        firstFocus: false,
        footerContent: footerContent,
        maxWidth: 300,
        tabNavigation: ['#remove-contact-ok', '#remove-contact-cancel'],
        handlers: {
            '#remove-contact-ok': {'click': submitFunc},
            '#remove-contact-cancel': {'static':'close'}
        }
    });

    $('#remove-contact-ok').focus();
}

/**
 * Binds click handler for "X" buttons (delete contact)
 */
function bindDeleteHandler() {
    $("#contacts").find(".contact").find("a.button").each(function () {
        this.onclick = deleteContactHandler;
    });
}

/**
 *  Returns HTML code for new contact populated with data
 * @param data user contact
 */
function getContactHtml(data) {
    //HTML template for single contact. Should be in sync with corresponding JSP.
    var template =
        '
'
            + '		<input type="hidden" value="${contactId}"/>'
            + '		'
            + '			'
            + '     '
            + '		'
            + '     	'
            + '         ${value}'
            + '     '
            + '
';

    var contactTypeInfo = AddContact.getContactType($('#contact_type').val(), AddContact.contactTypes);
    var actualValue = contactTypeInfo.displayPattern.replace(new RegExp('%s', 'gi'), $('#contact').val());

    var html = template;
    html = html.replace('${icon}', baseUrl + contactTypeInfo.icon);
    html = html.replace('${typeName}', contactTypeInfo.typeName);
    html = html.replace('${contactId}', data.id);
    html = html.replace('${buttonId}', data.id);
    html = html.replace('${value}', actualValue);

    return html;
}

/**
 * Find contact type with given id in given array and return it
 */
AddContact.getContactType = function (id, contactTypes) {
    var result = null;

    if (id !== undefined && contactTypes !== undefined) {
        $.each(contactTypes, function (i, obj) {
            if (obj.id == id) {
                result = obj;
                return;
            }
        });
    }

    return result;
}

/**
 * Reset all variables. Used when new popup is displayed
 */
AddContact.resetVariables = function () {
    AddContact.isValueValid = true;
    AddContact.contactTypes = null;
    AddContact.selectedContactType = null;
}

$(document).ready(function () {

    $('body').on('keyup', '#contact', function () {
        var value = $(this).val();
        if (value.length > 0 && !value.match(new RegExp(AddContact.selectedContactType.validationPattern))) {
            if (AddContact.isValueValid) {
                ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                AddContact.isValueValid = false;
            }
        } else {
            ErrorUtils.removeErrorMessage('#contact');
            AddContact.isValueValid = true;
        }
    });

    // when user selects other contact type
    $('body').on('change', '#contact_type', function () {
        var contactId = $(this).val();
        AddContact.selectedContactType = AddContact.getContactType(contactId, AddContact.contactTypes);
        $('#contact').attr('placeholder', AddContact.selectedContactType.mask);
        $('#contact').keyup();
    });

    //"Add contact" button handler
    $("#add_contact").click(function () {

        AddContact.resetVariables();

        $.getJSON(baseUrl + "/contacts/types", function (json) {

            AddContact.contactTypes = json;
            AddContact.selectedContactType = json[0];

            // select
            var bodyContent = '
'
                + '' + $labelContactType + ''
                + '
'
                +   '<select name="contact_type" id="contact_type" class="first dialog-input">';

            $.each(json, function (i, obj) {
                bodyContent += '<option value="' + obj.id + '">' + obj.typeName + '</option>';
            });
            bodyContent += '</select>

';

            // text input
            bodyContent += '
'
            bodyContent += '	' + $labelContactValue + '';
            bodyContent += '
';
            bodyContent += '		<input type="text" name="contact" id="contact" placeholder="'
                + AddContact.selectedContactType.mask + '" />';
            bodyContent += '
';
            bodyContent += '	' + $labelContactValueInfo + '';
            bodyContent += '
';

            var footerContent = ' \
            <button id="add-contact-cancel" class="btn">' + $labelCancel + '</button> \
            <button id="add-contact-ok" class="btn btn-primary">' + $labelOk + '</button>';

            var submitFunc = function (e) {
                e.preventDefault();
               if (AddContact.isValueValid && $('#contact').val() != '' && $('#contact').length > 0) {
                    var ownerId = $("#editedUserId").val();

                    var contact = {
                        ownerId: ownerId,
                        value: $('#contact').val(),
                        typeId: $('#contact_type').val()
                    };

                    $.ajax({
                        url: baseUrl + '/contacts/add',
                        type: "POST",
                        contentType: "application/json",
                        async: false,
                        data: JSON.stringify(contact),
                        success: function (data) {
                            if(data.status === 'SUCCESS'){
                                //populate contact template and append to page
                                $("#contacts").append(getContactHtml(data.result));
                                bindDeleteHandler();
                                jDialog.closeDialog();
                            }else{
                                ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                                AddContact.isValueValid = false;
                            }
                        },
                        error: function (data) {
                            ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                            AddContact.isValueValid = false;
                        }
                    });
                }else{
                   ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                   AddContact.isValueValid = false;
               }
            }

            jDialog.createDialog({
                dialogId: 'add-contact-dialog',
                title: $labelContactsAddDialog,
                bodyContent: bodyContent,
                footerContent: footerContent,
                maxWidth: 350,
                maxHeight: 350,
                tabNavigation: ['#contact_type', '#contact', '#add-contact-ok', '#add-contact-cancel'],
                handlers: {
                    '#add-contact-ok': {'click': submitFunc},
                    '#add-contact-cancel': {'static':'close'}
                }
            });
        });
    });

    bindDeleteHandler();
});
<commit_msg>JC-1538<commit_after>/*
 * Copyright (C) 2011  JTalks.org Team
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * This script provides interactive UI for contact management in user profile.
 */

/**
 * Application base path with trailing slash. Must be defined somewhere within the global scope.
 */
var baseUrl = $root;

/**
 * Namespace for this file.
 */
var AddContact = {};

/** Currently selected contact type */
AddContact.selectedContactType = null;

/** Aall contact types */
AddContact.contactTypes = null;

/** if entered contact is valid */
AddContact.isValueValid = true;

function deleteContactHandler() {
    var element = $(this).parent();
    var contactId = $(this).parent().find("#contactId:hidden").attr("value");
    var contactOwnerId = $(this).parent().find("#contactOwnerId:hidden").attr("value");

    var footerContent = ' \
            <button id="remove-contact-cancel" class="btn">' + $labelCancel + '</button> \
            <button id="remove-contact-ok" class="btn btn-primary">' + $labelOk + '</button>'

    var submitFunc = function (e) {
        e.preventDefault();
        $.ajax({
            url: baseUrl + '/contacts/remove/' + contactOwnerId + '/' + contactId,
            // this is the way Spring MVC represents HTTP DELETE for better browser compatibility
            type: "POST",
            data: {'_method': 'DELETE'},
            success: function () {
                element.fadeOut();
                jDialog.closeDialog();
            },
            error: function () {
                jDialog.createDialog({
                    type: jDialog.alertType,
                    bodyMessage: $labelDeleteContactFailture
                });
            }
        });
    };

    jDialog.createDialog({
        type: jDialog.confirmType,
        bodyMessage: $labelDeleteContactConfirmation,
        firstFocus: false,
        footerContent: footerContent,
        maxWidth: 300,
        tabNavigation: ['#remove-contact-ok', '#remove-contact-cancel'],
        handlers: {
            '#remove-contact-ok': {'click': submitFunc},
            '#remove-contact-cancel': {'static':'close'}
        }
    });

    $('#remove-contact-ok').focus();
}

/**
 * Binds click handler for "X" buttons (delete contact)
 */
function bindDeleteHandler() {
    $("#contacts").find(".contact").find("a.button").each(function () {
        this.onclick = deleteContactHandler;
    });
}

/**
 *  Returns HTML code for new contact populated with data
 * @param data user contact
 */
function getContactHtml(data) {
    //HTML template for single contact. Should be in sync with corresponding JSP.
    var template =
        '
'
            + '		<input type="hidden" value="${contactId}"/>'
            + '		'
            + '			'
            + '     '
            + '		'
            + '     	'
            + '         ${value}'
            + '     '
            + '
';

    var contactTypeInfo = AddContact.getContactType($('#contact_type').val(), AddContact.contactTypes);
    var actualValue = contactTypeInfo.displayPattern.replace(new RegExp('%s', 'gi'), $('#contact').val());

    var html = template;
    html = html.replace('${icon}', baseUrl + contactTypeInfo.icon);
    html = html.replace('${typeName}', contactTypeInfo.typeName);
    html = html.replace('${contactId}', data.id);
    html = html.replace('${buttonId}', data.id);
    html = html.replace('${value}', actualValue);

    return html;
}

/**
 * Find contact type with given id in given array and return it
 */
AddContact.getContactType = function (id, contactTypes) {
    var result = null;

    if (id !== undefined && contactTypes !== undefined) {
        $.each(contactTypes, function (i, obj) {
            if (obj.id == id) {
                result = obj;
                return;
            }
        });
    }

    return result;
}

/**
 * Reset all variables. Used when new popup is displayed
 */
AddContact.resetVariables = function () {
    AddContact.isValueValid = true;
    AddContact.contactTypes = null;
    AddContact.selectedContactType = null;
}

$(document).ready(function () {

    $('body').on('keyup', '#contact', function () {
        var value = $(this).val();
        if (value.length > 0 && !value.match(new RegExp(AddContact.selectedContactType.validationPattern))) {
            if (AddContact.isValueValid) {
                ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                AddContact.isValueValid = false;
            }
        } else {
            ErrorUtils.removeErrorMessage('#contact');
            AddContact.isValueValid = true;
        }
    });

    // when user selects other contact type
    $('body').on('change', '#contact_type', function () {
        var contactId = $(this).val();
        AddContact.selectedContactType = AddContact.getContactType(contactId, AddContact.contactTypes);
        $('#contact').attr('placeholder', AddContact.selectedContactType.mask);
        $('#contact').keyup();
    });

    //"Add contact" button handler
    $("#add_contact").on("click", function () {

        AddContact.resetVariables();

        $.getJSON(baseUrl + "/contacts/types", function (json) {

            AddContact.contactTypes = json;
            AddContact.selectedContactType = json[0];

            // select
            var bodyContent = '
'
                + '' + $labelContactType + ''
                + '
'
                +   '<select name="contact_type" id="contact_type" class="first dialog-input">';

            $.each(json, function (i, obj) {
                bodyContent += '<option value="' + obj.id + '">' + obj.typeName + '</option>';
            });
            bodyContent += '</select>

';

            // text input
            bodyContent += '
'
            bodyContent += '	' + $labelContactValue + '';
            bodyContent += '
';
            bodyContent += '		<input type="text" name="contact" id="contact" placeholder="'
                + AddContact.selectedContactType.mask + '" />';
            bodyContent += '
';
            bodyContent += '	' + $labelContactValueInfo + '';
            bodyContent += '
';

            var footerContent = ' \
            <button id="add-contact-cancel" class="btn">' + $labelCancel + '</button> \
            <button id="add-contact-ok" class="btn btn-primary">' + $labelOk + '</button>';

            var submitFunc = function (e) {
                e.preventDefault();
               if (AddContact.isValueValid && $('#contact').val() != '' && $('#contact').length > 0) {
                    var ownerId = $("#editedUserId").val();

                    var contact = {
                        ownerId: ownerId,
                        value: $('#contact').val(),
                        typeId: $('#contact_type').val()
                    };

                    $.ajax({
                        url: baseUrl + '/contacts/add',
                        type: "POST",
                        contentType: "application/json",
                        async: false,
                        data: JSON.stringify(contact),
                        success: function (data) {
                            if(data.status === 'SUCCESS'){
                                //populate contact template and append to page
                                $("#contacts").append(getContactHtml(data.result));
                                bindDeleteHandler();
                                jDialog.closeDialog();
                            }else{
                                ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                                AddContact.isValueValid = false;
                            }
                        },
                        error: function (data) {
                            ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                            AddContact.isValueValid = false;
                        }
                    });
                }else{
                   ErrorUtils.addErrorMessage('#contact', $labelValidationUsercontactNotMatch);
                   AddContact.isValueValid = false;
               }
            }

            jDialog.createDialog({
                dialogId: 'add-contact-dialog',
                title: $labelContactsAddDialog,
                bodyContent: bodyContent,
                footerContent: footerContent,
                maxWidth: 350,
                maxHeight: 350,
                tabNavigation: ['#contact_type', '#contact', '#add-contact-ok', '#add-contact-cancel'],
                handlers: {
                    '#add-contact-ok': {'click': submitFunc},
                    '#add-contact-cancel': {'static':'close'}
                }
            });
        });
    });

    bindDeleteHandler();
});
<|endoftext|>


<commit_before>/*
 * Backpack - Skyscanner's Design System
 *
 * Copyright 2018 Skyscanner Ltd
 *
 * 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.
 */

import React from 'react';
import BpkLink from 'bpk-component-link';
import BpkText from 'bpk-component-text';
import BpkBlockquote from 'bpk-component-blockquote';
import readme from 'react-native-bpk-component-touchable-overlay/readme.md';

import iosScreenshotDefault from 'react-native-bpk-component-touchable-overlay/screenshots/default.png';
import iosScreenshotTouchableHighlight from 'react-native-bpk-component-touchable-overlay/screenshots/touchable-highlight.png';

import Paragraph from './../../components/Paragraph';
import DocsPageBuilder from './../../components/DocsPageBuilder';

const touchableHighlightUrl =
  'https://facebook.github.io/react-native/docs/0.52/touchablehighlight.html';

const touchableNativeFeedbackUrl =
  'https://facebook.github.io/react-native/docs/0.52/touchablenativefeedback.html';

const components = [
  {
    id: 'touchableoverlay-vs-touchablehighlight',
    title: "Touchable Overlay vs React Native's Touchable Highlight",
    screenshots: [
      {
        title: 'Touchable Overlay',
        width: 750,
        height: 1334,
        src: `/${iosScreenshotDefault}`,
        altText: 'Backpack Touchable Overlay Component',
        subText: '(iPhone 8 Simulator)',
      },
      {
        title: "React Native's Touchable Highlight",
        width: 750,
        height: 1334,
        src: `/${iosScreenshotTouchableHighlight}`,
        altText: "React Native's Touchable Highlight Component",
        subText: '(iPhone 8 Simulator)',
      },
    ],
  },
];

const NativeTouchableOverlayPage = () => (
  <DocsPageBuilder
    title="Touchable Overlay"
    blurb={[
      <Paragraph>
        The Backpack Touchable Overlay component is to be used instead
        of the default{' '}
        <BpkLink href={touchableHighlightUrl} blank>
          React Native Touchable Highlight
        </BpkLink>{' '}
        component. The default Touchable Highlight component works by
        decreasing the opacity of the wrapped view to show an underlay colour.
        When views are nested within a Touchable Highlight wrapped
        view, their opacity is unchanged which produces an undesirable result.
        Have a look at the example below to see them both in action.
      </Paragraph>,
      <BpkBlockquote>
        <BpkText tag="span" bold>
          Note:
        </BpkText>{' '}
        This component is iOS only, for Android please stick to the default
        React Native{' '}
        <BpkLink href={touchableNativeFeedbackUrl} blank>
          Touchable Native Feedback
        </BpkLink>{' '}
        component.
      </BpkBlockquote>,
    ]}
    components={components}
    readme={readme}
    showMenu={false}
  />
);

export default NativeTouchableOverlayPage;
<commit_msg>[NOJIRA] Fix prop type warning<commit_after>/*
 * Backpack - Skyscanner's Design System
 *
 * Copyright 2018 Skyscanner Ltd
 *
 * 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.
 */

import React from 'react';
import BpkLink from 'bpk-component-link';
import BpkText from 'bpk-component-text';
import BpkBlockquote from 'bpk-component-blockquote';
import readme from 'react-native-bpk-component-touchable-overlay/readme.md';

import iosScreenshotDefault from 'react-native-bpk-component-touchable-overlay/screenshots/default.png';
import iosScreenshotTouchableHighlight from 'react-native-bpk-component-touchable-overlay/screenshots/touchable-highlight.png';

import Paragraph from './../../components/Paragraph';
import DocsPageBuilder from './../../components/DocsPageBuilder';

const touchableHighlightUrl =
  'https://facebook.github.io/react-native/docs/0.52/touchablehighlight.html';

const touchableNativeFeedbackUrl =
  'https://facebook.github.io/react-native/docs/0.52/touchablenativefeedback.html';

const components = [
  {
    id: 'touchableoverlay-vs-touchablehighlight',
    title: "Touchable Overlay vs React Native's Touchable Highlight",
    screenshots: [
      {
        title: 'Touchable Overlay',
        width: 750,
        height: 1334,
        src: `/${iosScreenshotDefault}`,
        altText: 'Backpack Touchable Overlay Component',
        subText: '(iPhone 8 Simulator)',
      },
      {
        title: "React Native's Touchable Highlight",
        width: 750,
        height: 1334,
        src: `/${iosScreenshotTouchableHighlight}`,
        altText: "React Native's Touchable Highlight Component",
        subText: '(iPhone 8 Simulator)',
      },
    ],
  },
];

const NativeTouchableOverlayPage = () => (
  <DocsPageBuilder
    title="Touchable Overlay"
    blurb={[
      <Paragraph>
        The Backpack Touchable Overlay component is to be used instead
        of the default{' '}
        <BpkLink href={touchableHighlightUrl} blank>
          React Native Touchable Highlight
        </BpkLink>{' '}
        component. The default Touchable Highlight component works by
        decreasing the opacity of the wrapped view to show an underlay colour.
        When views are nested within a Touchable Highlight wrapped
        view, their opacity is unchanged which produces an undesirable result.
        Have a look at the example below to see them both in action.
      </Paragraph>,
      <BpkBlockquote>
        <BpkText bold>Note:</BpkText> This component is iOS only, for Android
        please stick to the default React Native{' '}
        <BpkLink href={touchableNativeFeedbackUrl} blank>
          Touchable Native Feedback
        </BpkLink>{' '}
        component.
      </BpkBlockquote>,
    ]}
    components={components}
    readme={readme}
    showMenu={false}
  />
);

export default NativeTouchableOverlayPage;
<|endoftext|>