<commit_before>/**
 * @fileOverview options.js loads options from local storage to
 * initialize forms, and saves updates to the options.
 *
 * Available options include setting the some-trust whitelisted domains
 * and the server the user uploads their content to when generating new
 * injectable links.
 *
 * For more information about the whitelist, read:
 * https://github.com/privly/privly-organization/wiki/whitelist
 *
 * Local Storage Bindings Used:
 *
 * - user_whitelist_csv: This is the string of text the user gives the extension
 *   to specify which servers they trust to automatically inject into the host
 *   page. This string is presented to the user every time they visit options,
 *   but the string used by the content script is user_whitelist_regexp
 *
 * - user_whitelist_regexp: This string is formatted specifically so that
 *   privly.js can update its whitelist regexp.
 *
 * - posting_content_server_url: The content server the user will post to
 *   when generating new content.
 */

/**
 * Saves options to localStorage.
 */
function saveOptions() {

  var user_whitelist_input = document.getElementById("user_whitelist_csv");
  var invalid_chars = new RegExp("[^a-zA-Z0-9\-._]","g");
  var domains = user_whitelist_input.value.split(invalid_chars);
  var validateSubdomain = new RegExp("^(?!\-|_)[\\w\-](?!\-|_$){1,63}","g");
  //var validateDomain = new RegExp("^(?!\-)[a-zA-Z0-9\-](?!\-$){1,63}","g");
  var validateDomain = new RegExp("^(?!\-)[a-zA-Z0-9\-?]{1,63}$","g");
  var notEndInHyphen = new RegExp("[^\-]$","g"); //needed because javascript does not have look-behind
  var validateTLD = new RegExp("^[a-zA-Z]{2,9}$","g");
  var domain_regexp = "";  //stores regex to match validated domains
  var valid_domains = [];  //stores validated domains
  for (var i = 0; i < domains.length; i++){
    console.log(domains[i]);
    var parts = domains[i].split(".");
    var valid_parts_count = 0;
    for (var j = 0; j < parts.length; j++){
      switch (j){
        case parts.length-1: //TLD
          if (parts[j].match(validateTLD)){
            valid_parts_count++;
            console.log("\tTLD Matches " + parts[j] + ", " + parts[j].length);
          }
          break;
        case parts.length-2: // Domain
          if (parts[j].match(validateDomain) && parts[j].match(notEndInHyphen) ){
            valid_parts_count++;
            console.log("\tDomain Matches " + parts[j]);
          }
          break;
        default: //Subdomain(s)
          if (parts[j].match(validateSubdomain)){
            valid_parts_count++;
            console.log("\tSubdomain Matches " + parts[j]);
          }
      }
    }
    if (valid_parts_count === parts.length && parts.length > 1){
      domain_regexp += "|" + domains[i] + "\/";
      valid_domains.push(domains[i]+"\/");
      console.log("MATCHED " + domains[i]);
    }
  }

  domain_regexp = domain_regexp.replace(/^\|/, ""); //trim leading |
  //test newly created domain_regexp against list of valid domains
  for (var i = 0; i < valid_domains.length; i++){
    if (valid_domains[i].match(domain_regexp)){
      console.log(valid_domains[i] + " MATCHES");
    }
  }
  console.log(domain_regexp);
  var whitelist_csv = valid_domains.join(" , ");
  localStorage["user_whitelist_csv"] = whitelist_csv;
  localStorage["user_whitelist_regexp"] = domain_regexp;

  // Update status to let user know options were saved.
  var status = document.getElementById("status");
  status.innerHTML = "Options Saved.";
  setTimeout(function() {
    status.innerHTML = "";
    //document.location.reload()
  }, 750);
}

/**
 * Restores select box state to saved value from localStorage.
 */
function restoreOptions() {

  restore_server();

  var user_whitelist_csv = localStorage["user_whitelist_csv"];
  if (!user_whitelist_csv) {
    return;
  }
  var input = document.getElementById("user_whitelist_csv");
  input.value = user_whitelist_csv;
}

/**
 * Restores the current content server setting
 */
function restore_server(){

  var posting_content_server_url = localStorage["posting_content_server_url"];

  // check for local storage content
  if (!posting_content_server_url) {
    return;

  } else {

    // check conten type and restore
    switch(posting_content_server_url){

      //diplay the on menu
      case "https://privlyalpha.org":

        var alpha_input = document.getElementById("server_form");
        alpha_input.style.display = "block";
        var alpha = document.getElementById("alpha");
        alpha.checked = true;
        break;

      // display the on menu
      case "https://dev.privly.org":
        var dev_input = document.getElementById("server_form");
        dev_input.style.display = "block";
        var dev = document.getElementById("dev");
        dev.checked = true;
        break;

      // diplay the on menu
      case "http://localhost:3000":
        var local_input = document.getElementById("server_form");
        local_input.style.display = "block";
        var local = document.getElementById("local");
        local.checked = true;
        break;

      // user defined data
      default:

        // diplay the on menu
        var other_input = document.getElementById("server_form");
        other_input.style.display = "block";

        // diplay the other sub menu
        var user_input = document.getElementById("user");
        user_input.style.display = "block";
        var other = document.getElementById("other");
        other.checked = true;

        // populate the text box
        var other_content_server = document.getElementById("other_content_server");
        other_content_server.value = posting_content_server_url;

        var button = document.getElementById("save_server");
        button.style.display = "block";

    }
  }
}

/**
 * Save the current content server setting.
 *
 * @param {event} event the save button's click event.
 *
 */
function saveServer(event){

  // fired event object
  var target = event.target;

  // reset status
  var status = document.getElementById("server_status");
  status.innerHTML = "";

  // hide sub menu text box if not selected
  if(target.id != "save_server") {
    var other = document.getElementById("user");
    other.style.display = "none";
    var button = document.getElementById("save_server");
    button.style.display = "none";
  }

  // determine event
  switch(target.id) {

    // diplay the on menu
    case "on":
      var on_input = document.getElementById("server_form");
      on_input.style.display = "block";
      break;

    case "alpha":
      localStorage["posting_content_server_url"] = "https://privlyalpha.org";
      break;

    case "dev":
      localStorage["posting_content_server_url"] = "https://dev.privly.org";
      break;

    case "local":
      localStorage["posting_content_server_url"] = "http://localhost:3000";
      break;

    // open sub menu
    case "other":
      var button = document.getElementById("save_server");
      button.style.display = "block";
      var other = document.getElementById("user");
      other.style.display = "block";
      break;

    // save user entered content server
    case "save_server":
      var other_content_server = document.getElementById("other_content_server");
      var input = other_content_server.value;

      // validate user entered content server and
      if(validateContentServer(input)){
        localStorage["posting_content_server_url"] = input;

        // Update server status to let user know options were saved.
        status.innerHTML = "Content Server Saved.";
        setTimeout(function() {
          status.innerHTML = "";
        }, 750);

      } else {
        alert("Content Server not saved. please check input format.");
      }

      break;

    //default case is that the content server is set to the default position
    default:

      //hide menus
      var menu = document.getElementById("server_form");
      menu.style.display = "none";
      var sub_menu = document.getElementById("user");
      sub_menu.style.display = "none";
      var button = document.getElementById("save_server");
      button.style.display = "none";
      //remove the local storage
      localStorage.removeItem("posting_content_server_url");

  }
}

/**
 * Validates whether the URL is reachable with an HTTP request.
 *
 * @return {boolean} A boolean indicating whether the extension
 * successfully connected to the content server.
 *
 */
function validateContentServer(url) {

  //default http success value
  var request_success = 200;

  //update status of content server
  var status = document.getElementById("server_status");

  //check for internet connection
  var connection_check = navigator.onLine;
  if(connection_check){
    try{

      //create http object and request server
      var request = new XMLHttpRequest();
      request.open("GET", url, false);
      request.send(null);

      if(request.status === request_success){
        return true;
      }  else {
        status.innerHTML = "Verification Failed.";
        return false;
      }

    //catch http request exception 101 for network error
    } catch(e){
      status.innerHTML = "Verification Failed.";
      return false;
    }

  //if no connection is present then verification can not be made
  }else{
    alert("No Connection: Please connect to the internet if you want to"
            + "change your content server");
  }

}

/**
 * Sets the listeners on the UI elements of the page.
 */
function listeners(){

  // Options save button
  document.querySelector('#save').addEventListener('click', saveOptions);

  // content server listeners
  document.querySelector('#on').addEventListener('click', saveServer);
  document.querySelector('#off').addEventListener('click', saveServer);

  // content server sub menu listerners
  document.querySelector('#alpha').addEventListener('click', saveServer);
  document.querySelector('#dev').addEventListener('click', saveServer);
  document.querySelector('#local').addEventListener('click', saveServer);
  document.querySelector('#other').addEventListener('click', saveServer);
  document.querySelector('#save_server').addEventListener('click', saveServer);
}

// Save updates to the white list
document.addEventListener('DOMContentLoaded', restoreOptions);

// Listen for UI events
document.addEventListener('DOMContentLoaded', listeners);
<commit_msg>Regex improvement.<commit_after>/**
 * @fileOverview options.js loads options from local storage to
 * initialize forms, and saves updates to the options.
 *
 * Available options include setting the some-trust whitelisted domains
 * and the server the user uploads their content to when generating new
 * injectable links.
 *
 * For more information about the whitelist, read:
 * https://github.com/privly/privly-organization/wiki/whitelist
 *
 * Local Storage Bindings Used:
 *
 * - user_whitelist_csv: This is the string of text the user gives the extension
 *   to specify which servers they trust to automatically inject into the host
 *   page. This string is presented to the user every time they visit options,
 *   but the string used by the content script is user_whitelist_regexp
 *
 * - user_whitelist_regexp: This string is formatted specifically so that
 *   privly.js can update its whitelist regexp.
 *
 * - posting_content_server_url: The content server the user will post to
 *   when generating new content.
 */

/**
 * Saves options to localStorage.
 */
function saveOptions() {

  var user_whitelist_input = document.getElementById("user_whitelist_csv");
  var invalid_chars = new RegExp("[^a-zA-Z0-9\-._]","g");
  var domains = user_whitelist_input.value.split(invalid_chars);
  var validateSubdomain = new RegExp("^(?!\-|_)[\\w\-](?!\-|_$){1,63}","g");
  //var validateDomain = new RegExp("^(?!\-)[a-zA-Z0-9\-](?!\-$){1,63}","g");
  var validateDomain = new RegExp("^(?!\-)[a-zA-Z0-9\-?]{1,63}$","g");
  var notEndInHyphen = new RegExp("[^\-]$","g"); //needed because js regex does not have look-behind
  var validateTLD = new RegExp("^[a-zA-Z]{2,9}$","g");
  var domain_regexp = "";  //stores regex to match validated domains
  var valid_domains = [];  //stores validated domains
  for (var i = 0; i < domains.length; i++){
    console.log(domains[i]);
    var parts = domains[i].split(".");
    var valid_parts_count = 0;
    for (var j = 0; j < parts.length; j++){
      switch (j){
        case parts.length-1: //TLD
          if (parts[j].match(validateTLD)){
            valid_parts_count++;
            console.log("\tTLD Matches " + parts[j] + ", " + parts[j].length);
          }
          break;
        case parts.length-2: // Domain
          if (parts[j].match(validateDomain) && parts[j].match(notEndInHyphen) ){
            valid_parts_count++;
            console.log("\tDomain Matches " + parts[j]);
          }
          break;
        default: //Subdomain(s)
          if (parts[j].match(validateSubdomain)){
            valid_parts_count++;
            console.log("\tSubdomain Matches " + parts[j]);
          }
      }
    }
    if (valid_parts_count === parts.length && parts.length > 1){
      domain_regexp += "|" + domains[i] + "\/";
      valid_domains.push(domains[i]+"\/");
      console.log("MATCHED " + domains[i]);
    }
  }

  domain_regexp = domain_regexp.replace(/^\|/, ""); //trim leading |
  //test newly created domain_regexp against list of valid domains
  for (var i = 0; i < valid_domains.length; i++){
    if (valid_domains[i].match(domain_regexp)){
      console.log(valid_domains[i] + " MATCHES");
    }
  }
  console.log(domain_regexp);
  var whitelist_csv = valid_domains.join(" , ");
  localStorage["user_whitelist_csv"] = whitelist_csv;
  localStorage["user_whitelist_regexp"] = domain_regexp;

  // Update status to let user know options were saved.
  var status = document.getElementById("status");
  status.innerHTML = "Options Saved.";
  setTimeout(function() {
    status.innerHTML = "";
    document.location.reload()
  }, 750);
}

/**
 * Restores select box state to saved value from localStorage.
 */
function restoreOptions() {

  restore_server();

  var user_whitelist_csv = localStorage["user_whitelist_csv"];
  if (!user_whitelist_csv) {
    return;
  }
  var input = document.getElementById("user_whitelist_csv");
  input.value = user_whitelist_csv;
}

/**
 * Restores the current content server setting
 */
function restore_server(){

  var posting_content_server_url = localStorage["posting_content_server_url"];

  // check for local storage content
  if (!posting_content_server_url) {
    return;

  } else {

    // check conten type and restore
    switch(posting_content_server_url){

      //diplay the on menu
      case "https://privlyalpha.org":

        var alpha_input = document.getElementById("server_form");
        alpha_input.style.display = "block";
        var alpha = document.getElementById("alpha");
        alpha.checked = true;
        break;

      // display the on menu
      case "https://dev.privly.org":
        var dev_input = document.getElementById("server_form");
        dev_input.style.display = "block";
        var dev = document.getElementById("dev");
        dev.checked = true;
        break;

      // diplay the on menu
      case "http://localhost:3000":
        var local_input = document.getElementById("server_form");
        local_input.style.display = "block";
        var local = document.getElementById("local");
        local.checked = true;
        break;

      // user defined data
      default:

        // diplay the on menu
        var other_input = document.getElementById("server_form");
        other_input.style.display = "block";

        // diplay the other sub menu
        var user_input = document.getElementById("user");
        user_input.style.display = "block";
        var other = document.getElementById("other");
        other.checked = true;

        // populate the text box
        var other_content_server = document.getElementById("other_content_server");
        other_content_server.value = posting_content_server_url;

        var button = document.getElementById("save_server");
        button.style.display = "block";

    }
  }
}

/**
 * Save the current content server setting.
 *
 * @param {event} event the save button's click event.
 *
 */
function saveServer(event){

  // fired event object
  var target = event.target;

  // reset status
  var status = document.getElementById("server_status");
  status.innerHTML = "";

  // hide sub menu text box if not selected
  if(target.id != "save_server") {
    var other = document.getElementById("user");
    other.style.display = "none";
    var button = document.getElementById("save_server");
    button.style.display = "none";
  }

  // determine event
  switch(target.id) {

    // diplay the on menu
    case "on":
      var on_input = document.getElementById("server_form");
      on_input.style.display = "block";
      break;

    case "alpha":
      localStorage["posting_content_server_url"] = "https://privlyalpha.org";
      break;

    case "dev":
      localStorage["posting_content_server_url"] = "https://dev.privly.org";
      break;

    case "local":
      localStorage["posting_content_server_url"] = "http://localhost:3000";
      break;

    // open sub menu
    case "other":
      var button = document.getElementById("save_server");
      button.style.display = "block";
      var other = document.getElementById("user");
      other.style.display = "block";
      break;

    // save user entered content server
    case "save_server":
      var other_content_server = document.getElementById("other_content_server");
      var input = other_content_server.value;

      // validate user entered content server and
      if(validateContentServer(input)){
        localStorage["posting_content_server_url"] = input;

        // Update server status to let user know options were saved.
        status.innerHTML = "Content Server Saved.";
        setTimeout(function() {
          status.innerHTML = "";
        }, 750);

      } else {
        alert("Content Server not saved. please check input format.");
      }

      break;

    //default case is that the content server is set to the default position
    default:

      //hide menus
      var menu = document.getElementById("server_form");
      menu.style.display = "none";
      var sub_menu = document.getElementById("user");
      sub_menu.style.display = "none";
      var button = document.getElementById("save_server");
      button.style.display = "none";
      //remove the local storage
      localStorage.removeItem("posting_content_server_url");

  }
}

/**
 * Validates whether the URL is reachable with an HTTP request.
 *
 * @return {boolean} A boolean indicating whether the extension
 * successfully connected to the content server.
 *
 */
function validateContentServer(url) {

  //default http success value
  var request_success = 200;

  //update status of content server
  var status = document.getElementById("server_status");

  //check for internet connection
  var connection_check = navigator.onLine;
  if(connection_check){
    try{

      //create http object and request server
      var request = new XMLHttpRequest();
      request.open("GET", url, false);
      request.send(null);

      if(request.status === request_success){
        return true;
      }  else {
        status.innerHTML = "Verification Failed.";
        return false;
      }

    //catch http request exception 101 for network error
    } catch(e){
      status.innerHTML = "Verification Failed.";
      return false;
    }

  //if no connection is present then verification can not be made
  }else{
    alert("No Connection: Please connect to the internet if you want to"
            + "change your content server");
  }

}

/**
 * Sets the listeners on the UI elements of the page.
 */
function listeners(){

  // Options save button
  document.querySelector('#save').addEventListener('click', saveOptions);

  // content server listeners
  document.querySelector('#on').addEventListener('click', saveServer);
  document.querySelector('#off').addEventListener('click', saveServer);

  // content server sub menu listerners
  document.querySelector('#alpha').addEventListener('click', saveServer);
  document.querySelector('#dev').addEventListener('click', saveServer);
  document.querySelector('#local').addEventListener('click', saveServer);
  document.querySelector('#other').addEventListener('click', saveServer);
  document.querySelector('#save_server').addEventListener('click', saveServer);
}

// Save updates to the white list
document.addEventListener('DOMContentLoaded', restoreOptions);

// Listen for UI events
document.addEventListener('DOMContentLoaded', listeners);
<|endoftext|>


<commit_before>'use strict';

chrome.runtime.onInstalled.addListener(function (details) {
  console.log('previousVersion', details.previousVersion);
});

chrome.browserAction.setBadgeText({text: '0'});

console.log('\'Allo \'Allo! Event Page for Browser Action');

/**
 * StopLeak namespace.
 * @namespace
 */
var stopleak = stopleak || {};

stopleak.blocks = {};

// Filter out request from the main frame (the
var requestFilter = {
  urls: ['<all_urls>'],
  types: ['sub_frame']
};

/**
 * Increments the number of block requests on tab tabId.
 * @param {number} tabId The id of the tab.
 */
function incBlockCount(tabId) {
  if(stopleak.blocks[tabId] === undefined) {
    stopleak.blocks[tabId] = 0;
  }
  stopleak.blocks[tabId] += 1;
}

/**
 * Modifies or blocks HTTP requests based on the request headers.
 * @param {!Object} details The HTTP request containing request headers.
 * @return {!Object} The BlockingResponse containing the modified request
 *    headers to send.
 */
function onBeforeSendHeaders(details) {
  if(details.tabId !== chrome.tabs.TAB_ID_NONE) {
    // Example code to delete User-Agent from request headers

    //for (var i = details.requestHeaders.length - 1; i >= 0; --i) {
    //   if (details.requestHeaders[i].name === 'User-Agent') {
    //     details.requestHeaders.splice(i, 1);
    //   }
    //}
    //console.log('Dropped User-Agent from tab ' + details.tabId);
  }
  return {requestHeaders: details.requestHeaders};
}

/**
 * Filters HTTP requests based on the requested url before TCP connection
 * is made.
 * @param {!Object} details The HTTP request before being sent.
 * @return {!Object} The BlockingResponse to allow or deny this request.
 */
function onBeforeRequest(details) {
  var cancel = {cancel: false};
  if(details.tabId !== chrome.tabs.TAB_ID_NONE) {
    console.log(details);
    var str = JSON.stringify(details);
    if(str.indexOf('shane') !== -1) {
      console.log('Blocking request to ' + details.url);
      incBlockCount(details.tabId);
      cancel.cancel = true;
    }
  }
  return cancel;
}

chrome.webRequest.onBeforeSendHeaders.addListener(
  onBeforeSendHeaders,
  requestFilter,
  ['blocking', 'requestHeaders']);

chrome.webRequest.onBeforeRequest.addListener(
  onBeforeRequest,
  requestFilter,
  ['blocking', 'requestBody']);
<commit_msg>Update badge text for each tab separately.<commit_after>'use strict';

chrome.runtime.onInstalled.addListener(function (details) {
  console.log('previousVersion', details.previousVersion);
});

chrome.browserAction.setBadgeText({text: '0'});

console.log('\'Allo \'Allo! Event Page for Browser Action');

/**
 * StopLeak namespace.
 * @namespace
 */
var stopleak = stopleak || {};

stopleak.blocks = {};

// Filter out request from the main frame (the
stopleak.requestFilter = {
  urls: ['<all_urls>'],
  // Everything but 'main_frame'
  types: ['sub_frame', 'stylesheet', 'script', 'image', 'object', 'xmlhttprequest', 'other']
};

/**
 * Increments the number of block requests on tab tabId.
 * @param {number} tabId The id of the tab.
 */
function incBlockCount(tabId) {
  if(stopleak.blocks[tabId] === undefined) {
    stopleak.blocks[tabId] = 0;
  }
  stopleak.blocks[tabId] += 1;
  chrome.browserAction.setBadgeText({text: '' + stopleak.blocks[tabId], tabId: tabId});
}

/**
 * Modifies or blocks HTTP requests based on the request headers.
 * @param {!Object} details The HTTP request containing request headers.
 * @return {!Object} The BlockingResponse containing the modified request
 *    headers to send.
 */
function onBeforeSendHeaders(details) {
  if(details.tabId !== chrome.tabs.TAB_ID_NONE) {
    // Example code to delete User-Agent from request headers

    //for (var i = details.requestHeaders.length - 1; i >= 0; --i) {
    //   if (details.requestHeaders[i].name === 'User-Agent') {
    //     details.requestHeaders.splice(i, 1);
    //   }
    //}
    //console.log('Dropped User-Agent from tab ' + details.tabId);
  }
  return {requestHeaders: details.requestHeaders};
}

/**
 * Filters HTTP requests based on the requested url before TCP connection
 * is made.
 * @param {!Object} details The HTTP request before being sent.
 * @return {!Object} The BlockingResponse to allow or deny this request.
 */
function onBeforeRequest(details) {
  var cancel = false;
  if(details.tabId !== chrome.tabs.TAB_ID_NONE) {
    console.debug(details);
    var str = JSON.stringify(details);
    if (str.indexOf('shane') !== -1) {
      console.debug('Blocking request to ' + details.url);
      incBlockCount(details.tabId);
      cancel = true;
    }
  }
  return {cancel: cancel};
}

chrome.webRequest.onBeforeSendHeaders.addListener(
  onBeforeSendHeaders,
  stopleak.requestFilter,
  ['blocking', 'requestHeaders']);

chrome.webRequest.onBeforeRequest.addListener(
  onBeforeRequest,
  stopleak.requestFilter,
  ['blocking', 'requestBody']);
<|endoftext|>


<commit_before>import Ember from 'ember';

function trackPage() {
  Ember.run.scheduleOnce('afterRender', () => {
    this.get('metrics').trackPage({
      page: this.get('url'),
      title: this.getWithDefault('currentRouteName', 'unknown')
    });
  });
}

export default Ember.Mixin.create({
  metrics: Ember.inject.service(),

  didTransition() {
    this._super(...arguments);

    trackPage.call(this);
  }
});
<commit_msg>I don't think currentRouteName will ever be undefined.<commit_after>import Ember from 'ember';

function trackPage() {
  Ember.run.scheduleOnce('afterRender', () => {
    this.get('metrics').trackPage({
      page: this.get('url'),
      title: this.get('currentRouteName')
    });
  });
}

export default Ember.Mixin.create({
  metrics: Ember.inject.service(),

  didTransition() {
    this._super(...arguments);

    trackPage.call(this);
  }
});
<|endoftext|>


<commit_before>var Promise = require('bluebird');
var blessed = require('blessed');
var _ = require('lazy.js');
var Point = require('text-buffer/lib/point');

var util = require('slap-util');
var baseWidgetOpts = require('./opts');

function BaseWidget (opts) {
  var self = this;

  if (!(self instanceof blessed.Node)) return new BaseWidget(opts);

  opts = _(baseWidgetOpts).merge(opts || {}).toObject();
  if (self instanceof BaseWidget) blessed.Box.call(self, opts); // this should not be called if an element inherits from built-in blessed classes
  self.focusable = opts.focusable;

  self.ready = Promise.delay(0)
    .then(function () { return self._initHandlers(); })
    .return(self);
}
BaseWidget.prototype.__proto__ = blessed.Box.prototype;

BaseWidget.prototype.walkDepthFirst = function (direction, after, fn) {
  if (arguments.length === 2) fn = after;
  var children = this.children.slice();
  if (direction === -1) children.reverse();
  if (after) children = children.slice(children.indexOf(after) + 1);
  return children.some(function (child) {
    return fn.apply(child, arguments) || BaseWidget.prototype.walkDepthFirst.call(child, direction, fn);
  });
};
BaseWidget.prototype.focusFirst = function (direction, after) {
  return this.walkDepthFirst(direction, after, function () {
    if (this.visible && this.focusable) {
      this.focus();
      return true;
    }
  });
};
BaseWidget.prototype._focusDirection = function (direction) {
  var self = this;
  var descendantParent;
  var descendant = self.screen.focused;
  while (descendant.hasAncestor(self)) {
    descendantParent = descendant.parent;
    if (BaseWidget.prototype.focusFirst.call(descendantParent, direction, descendant)) return self;
    descendant = descendantParent;
  }
  if (!self.focusFirst(direction)) throw new Error("no focusable descendant");
  return self;
};
BaseWidget.prototype.focusNext = function () {
  return this._focusDirection(1);
};
BaseWidget.prototype.focusPrev = function () {
  return this._focusDirection(-1);
};
BaseWidget.prototype.focus = function () {
  if (!this.hasFocus()) return blessed.Box.prototype.focus.apply(this, arguments);
  return this;
};
BaseWidget.prototype.isAttached = function () {
  return this.hasAncestor(this.screen);
};
BaseWidget.prototype.hasFocus = function (asChild) {
  var self = this;
  var focused = self.screen.focused;
  return focused.visible && (focused === self || focused.hasAncestor(self) || (asChild && self.hasAncestor(focused)));
};

BaseWidget.prototype.pos = function () {
  return new Point(this.atop + this.itop, this.aleft + this.ileft);
};
BaseWidget.prototype.size = function () {
  if (!this.isAttached()) return new Point(0, 0); // hack
  return new Point(this.height - this.iheight, this.width - this.iwidth);
};

BaseWidget.prototype.shrinkWidth = function () { return this.content.length + this.iwidth; };
BaseWidget.prototype.getBindings = function () {
  return this.options.bindings;
};
BaseWidget.prototype.resolveBinding = function (key, source1, source2, etc) {
  return BaseWidget.resolveBinding.apply(null,
    [key, BaseWidget.prototype.getBindings.call(this)].concat([].slice.call(arguments, 1))
  );
};
BaseWidget.resolveBinding = function (key, source1, source2, etc) {
  var bindings = [].slice.call(arguments, 1).reduce(function (bindings, sourceBindings) {
    return bindings.merge(sourceBindings);
  }, _()).toObject();
  for (var name in bindings) {
    if (bindings.hasOwnProperty(name)) {
      var keyBindings = bindings[name];
      if (!keyBindings) continue;
      if (typeof keyBindings === 'string') keyBindings = [keyBindings];
      if (keyBindings.some(function (binding) { return binding === key.full || binding === key.sequence; }))
        return name;
    }
  }
};

BaseWidget.prototype._initHandlers = function () {
  var self = this;
  self.on('focus', function () {
    logger.debug('focus', util.typeOf(self));
    if (!self.focusable) self.focusNext();
  });
  self.on('blur', function () { logger.debug('blur', util.typeOf(self)); });
  self.on('show', function () { self.setFront(); });
  self.on('element keypress', function (el, ch, key) {
    switch (BaseWidget.prototype.resolveBinding.call(self, key)) {
      case 'hide': self.hide(); return false;
      case 'focusNext': self.focusNext(); return false;
      case 'focusPrev': self.focusPrev(); return false;
    }
  });
};

module.exports = BaseWidget;
<commit_msg>refactor(logger): remove references to global logger<commit_after>var Promise = require('bluebird');
var blessed = require('blessed');
var _ = require('lazy.js');
var Point = require('text-buffer/lib/point');

var util = require('slap-util');
var baseWidgetOpts = require('./opts');

function BaseWidget (opts) {
  var self = this;

  if (!(self instanceof blessed.Node)) return new BaseWidget(opts);

  opts = _(baseWidgetOpts).merge(opts || {}).toObject();
  if (self instanceof BaseWidget) blessed.Box.call(self, opts); // this should not be called if an element inherits from built-in blessed classes
  self.focusable = opts.focusable;

  self.ready = Promise.delay(0)
    .then(function () { return self._initHandlers(); })
    .return(self);
}
BaseWidget.prototype.__proto__ = blessed.Box.prototype;

BaseWidget.prototype.walkDepthFirst = function (direction, after, fn) {
  if (arguments.length === 2) fn = after;
  var children = this.children.slice();
  if (direction === -1) children.reverse();
  if (after) children = children.slice(children.indexOf(after) + 1);
  return children.some(function (child) {
    return fn.apply(child, arguments) || BaseWidget.prototype.walkDepthFirst.call(child, direction, fn);
  });
};
BaseWidget.prototype.focusFirst = function (direction, after) {
  return this.walkDepthFirst(direction, after, function () {
    if (this.visible && this.focusable) {
      this.focus();
      return true;
    }
  });
};
BaseWidget.prototype._focusDirection = function (direction) {
  var self = this;
  var descendantParent;
  var descendant = self.screen.focused;
  while (descendant.hasAncestor(self)) {
    descendantParent = descendant.parent;
    if (BaseWidget.prototype.focusFirst.call(descendantParent, direction, descendant)) return self;
    descendant = descendantParent;
  }
  if (!self.focusFirst(direction)) throw new Error("no focusable descendant");
  return self;
};
BaseWidget.prototype.focusNext = function () {
  return this._focusDirection(1);
};
BaseWidget.prototype.focusPrev = function () {
  return this._focusDirection(-1);
};
BaseWidget.prototype.focus = function () {
  if (!this.hasFocus()) return blessed.Box.prototype.focus.apply(this, arguments);
  return this;
};
BaseWidget.prototype.isAttached = function () {
  return this.hasAncestor(this.screen);
};
BaseWidget.prototype.hasFocus = function (asChild) {
  var self = this;
  var focused = self.screen.focused;
  return focused.visible && (focused === self || focused.hasAncestor(self) || (asChild && self.hasAncestor(focused)));
};

BaseWidget.prototype.pos = function () {
  return new Point(this.atop + this.itop, this.aleft + this.ileft);
};
BaseWidget.prototype.size = function () {
  if (!this.isAttached()) return new Point(0, 0); // hack
  return new Point(this.height - this.iheight, this.width - this.iwidth);
};

BaseWidget.prototype.shrinkWidth = function () { return this.content.length + this.iwidth; };
BaseWidget.prototype.getBindings = function () {
  return this.options.bindings;
};
BaseWidget.prototype.resolveBinding = function (key, source1, source2, etc) {
  return BaseWidget.resolveBinding.apply(null,
    [key, BaseWidget.prototype.getBindings.call(this)].concat([].slice.call(arguments, 1))
  );
};
BaseWidget.resolveBinding = function (key, source1, source2, etc) {
  var bindings = [].slice.call(arguments, 1).reduce(function (bindings, sourceBindings) {
    return bindings.merge(sourceBindings);
  }, _()).toObject();
  for (var name in bindings) {
    if (bindings.hasOwnProperty(name)) {
      var keyBindings = bindings[name];
      if (!keyBindings) continue;
      if (typeof keyBindings === 'string') keyBindings = [keyBindings];
      if (keyBindings.some(function (binding) { return binding === key.full || binding === key.sequence; }))
        return name;
    }
  }
};

BaseWidget.prototype._initHandlers = function () {
  var self = this;
  self.on('focus', function () {
    util.logger.debug('focus', util.typeOf(self));
    if (!self.focusable) self.focusNext();
  });
  self.on('blur', function () { util.logger.debug('blur', util.typeOf(self)); });
  self.on('show', function () { self.setFront(); });
  self.on('element keypress', function (el, ch, key) {
    switch (BaseWidget.prototype.resolveBinding.call(self, key)) {
      case 'hide': self.hide(); return false;
      case 'focusNext': self.focusNext(); return false;
      case 'focusPrev': self.focusPrev(); return false;
    }
  });
};

module.exports = BaseWidget;
<|endoftext|>


<commit_before>// Page Object
module.exports = {

  get: function() {
    return browser.get('#/');
  },

  pageName: element(by.binding('pageName'))

};
<commit_msg>src/app/home e2e test's code style update #32<commit_after>// Page Object
module.exports = {

  get: function() {
    return browser.get('#/');
  },

  pageName: element(by.binding('vm.pageName'))

};
<|endoftext|>


<commit_before>// Helper for changing tabs
var changeTabs = function (event) {
    event.stopPropagation(); event.preventDefault();

    var parent = document.querySelector('section.mainSection.work'),
        active = parent.querySelectorAll('.active'),
        article, i = 0, j = active.length;

    // Remove active class from all elements under parent
    for (; i < j; ++i)
        active[i].classList.remove('active');

    // Make article with same ID as tab active
    article = parent.querySelector('article[data-id="' +
        event.currentTarget.dataset.id + '"]');
    if (!article) return; // don't do anything if there's no article
    article.classList.add('active');

    // Make tab active, too
    event.currentTarget.classList.add('active');

    // Is this is a submenu item?
    parent = event.currentTarget.parentElement.parentElement;
    if ( parent.nodeName.toLowerCase() === 'li' ) {
        // Make active
        parent.classList.add('active');
    }
};

// Tabs
Template.workNav.helpers({
    name: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['name']);
        if (result)
            return result.name;
    },
    icon: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['icon']);
        if (result)
            return result.icon;
    },
    hasChildren: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result && result.tabs && result.tabs.length)
            return true;

        return false;
    },
    tabs: function (id) {
        var result;
        id = id || this._id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    }
});

// Navigation
Template.workListItem.helpers({
    icon: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['icon']);
        if (result)
            return result.icon;
    },
    name: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['name']);
        if (result)
            return result.name;
    },
    tabs: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    },
    tabName: function (id) {
        var result;
        id = id || this;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.name;
    }
});

// Content Container
Template.workContentContainer.helpers({
    tabs: function (id) {
        var result;
        id = id || this._id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    },
    template: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['template']);

        if (result)
            return result.template;
    },
    subtabs: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    }
});
// Content
Template.workContent.helpers({
    content: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['content']);
        if (result)
            return result.content; return '';
    },
    icon: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['icon']);
        if (result)
            return result.icon;
    },
    name: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['name']);
        if (result)
            return result.name;
    }
});

// Set the first tab as active
/*Template.tab.onRendered(function () {
    var parent;

    try {
        // TODO:  How robust is this?!
        parent = this.firstNode.parentElement.parentElement.parentElement;

        // Set the very first result as active.  Should be the first in the DOM.
        parent.querySelector('main > article').classList.add('active');
        parent.querySelector('menu li').classList.add('active');
    } catch (error) { }
});*/

// Helper for changing tabs
Template.workNav.events({
    'click li': changeTabs,
});

Template.workContent.events({
    'click footer.truncate button': function (event) {
        event.preventDefault;
        $("body").addClass("workReadingAnimate").delay(2000).queue(function(){
            $("body").removeClass("workReadingAnimate").dequeue();
            $("body").addClass("workReading").dequeue();
        });
    },
    'click button.backToTopWork': function (event) {
        offset = $('[id="what-we-do"]').offset().top + 228;
        $('body').animate({ scrollTop: offset }, 750);
    },
    'click .workTertiary > ul > li > a': function (event) {
        event.stopPropagation(); event.preventDefault();
        alert('This will scroll down to the appropriate subsection content.')
    }
});

// From jQuery Providers file
// TODO: rewrite this
/*Template.work.onRendered(function () {
    //Opening The workDetails pane
    $('.workGrid > ul > li > a, .backToIndex a').click(function(){
        if($('body').hasClass('workDetails')){
            event.preventDefault();
            $('body').removeClass('workDetails');
        } else{
            event.preventDefault();
            $('body').addClass('workDetails');
        }
    });

});*/

// Eoghan's stuff
Template.work.onRendered(function () {
    // Handle adding and removing the Body 'workActive' class
    $('.workNav > ul > li > h2 > a:not(.backToIndexWorkA), .workNav ul > li > ul > li > a').click(function () {
        event.preventDefault();
        if($("body").hasClass('openNavItem')){
            $("body").removeClass('openNavItem');
        }
        if(!$("body").hasClass('workActive')){
            $("body").removeClass("workBack");
            $("body").addClass('openNavItem');
            $("body").addClass("workFadeIn").delay(250).queue(function(){
                $(this).removeClass("workFadeIn").dequeue();
                $(this).addClass("workActive").dequeue();
            });
            //$('body').addClass('workFadeOut');
        }
    });

    $('.workNav li.backToIndexWork').click(function(){
        event.preventDefault();
        $("body").addClass("workFadeOut").delay(175).queue(function(){
        $('body').removeClass('workActive');
        $('body').removeClass('workReading');
        $(this).removeClass("workFadeOut").dequeue();
        });
        //offset = $('[id="what-we-do"]').offset().top - 125;
        //$('body').animate({ scrollTop: offset }, 350);
    });
});<commit_msg>Fixed a bug with the tabName helper that caused work section nav items to lose their names.<commit_after>// Helper for changing tabs
var changeTabs = function (event) {
    event.stopPropagation(); event.preventDefault();

    var parent = document.querySelector('section.mainSection.work'),
        active = parent.querySelectorAll('.active'),
        article, i = 0, j = active.length;

    // Remove active class from all elements under parent
    for (; i < j; ++i)
        active[i].classList.remove('active');

    // Make article with same ID as tab active
    article = parent.querySelector('article[data-id="' +
        event.currentTarget.dataset.id + '"]');
    if (!article) return; // don't do anything if there's no article
    article.classList.add('active');

    // Make tab active, too
    event.currentTarget.classList.add('active');

    // Is this is a submenu item?
    parent = event.currentTarget.parentElement.parentElement;
    if ( parent.nodeName.toLowerCase() === 'li' ) {
        // Make active
        parent.classList.add('active');
    }
};

// Tabs
Template.workNav.helpers({
    name: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['name']);
        if (result)
            return result.name;
    },
    icon: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['icon']);
        if (result)
            return result.icon;
    },
    hasChildren: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result && result.tabs && result.tabs.length)
            return true;

        return false;
    },
    tabs: function (id) {
        var result;
        id = id || this._id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    }
});

// Navigation
Template.workListItem.helpers({
    icon: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['icon']);
        if (result)
            return result.icon;
    },
    name: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['name']);
        if (result)
            return result.name;
    },
    tabs: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    },
    tabName: function (id) {
        var result;
        id = id || this;

        result = Thriver.sections.get(id, ['name']);

        if (result)
            return result.name;
    }
});

// Content Container
Template.workContentContainer.helpers({
    tabs: function (id) {
        var result;
        id = id || this._id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    },
    template: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['template']);

        if (result)
            return result.template;
    },
    subtabs: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['tabs']);

        if (result)
            return result.tabs;
    }
});
// Content
Template.workContent.helpers({
    content: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['content']);
        if (result)
            return result.content; return '';
    },
    icon: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['icon']);
        if (result)
            return result.icon;
    },
    name: function (id) {
        var result;
        id = id || this.id;

        result = Thriver.sections.get(id, ['name']);
        if (result)
            return result.name;
    }
});

// Set the first tab as active
/*Template.tab.onRendered(function () {
    var parent;

    try {
        // TODO:  How robust is this?!
        parent = this.firstNode.parentElement.parentElement.parentElement;

        // Set the very first result as active.  Should be the first in the DOM.
        parent.querySelector('main > article').classList.add('active');
        parent.querySelector('menu li').classList.add('active');
    } catch (error) { }
});*/

// Helper for changing tabs
Template.workNav.events({
    'click li': changeTabs,
});

Template.workContent.events({
    'click footer.truncate button': function (event) {
        event.preventDefault;
        $("body").addClass("workReadingAnimate").delay(2000).queue(function(){
            $("body").removeClass("workReadingAnimate").dequeue();
            $("body").addClass("workReading").dequeue();
        });
    },
    'click button.backToTopWork': function (event) {
        offset = $('[id="what-we-do"]').offset().top + 228;
        $('body').animate({ scrollTop: offset }, 750);
    },
    'click .workTertiary > ul > li > a': function (event) {
        event.stopPropagation(); event.preventDefault();
        alert('This will scroll down to the appropriate subsection content.')
    }
});

// From jQuery Providers file
// TODO: rewrite this
/*Template.work.onRendered(function () {
    //Opening The workDetails pane
    $('.workGrid > ul > li > a, .backToIndex a').click(function(){
        if($('body').hasClass('workDetails')){
            event.preventDefault();
            $('body').removeClass('workDetails');
        } else{
            event.preventDefault();
            $('body').addClass('workDetails');
        }
    });

});*/

// Eoghan's stuff
Template.work.onRendered(function () {
    // Handle adding and removing the Body 'workActive' class
    $('.workNav > ul > li > h2 > a:not(.backToIndexWorkA), .workNav ul > li > ul > li > a').click(function () {
        event.preventDefault();
        if($("body").hasClass('openNavItem')){
            $("body").removeClass('openNavItem');
        }
        if(!$("body").hasClass('workActive')){
            $("body").removeClass("workBack");
            $("body").addClass('openNavItem');
            $("body").addClass("workFadeIn").delay(250).queue(function(){
                $(this).removeClass("workFadeIn").dequeue();
                $(this).addClass("workActive").dequeue();
            });
            //$('body').addClass('workFadeOut');
        }
    });

    $('.workNav li.backToIndexWork').click(function(){
        event.preventDefault();
        $("body").addClass("workFadeOut").delay(175).queue(function(){
        $('body').removeClass('workActive');
        $('body').removeClass('workReading');
        $(this).removeClass("workFadeOut").dequeue();
        });
        //offset = $('[id="what-we-do"]').offset().top - 125;
        //$('body').animate({ scrollTop: offset }, 350);
    });
});<|endoftext|>


<commit_before>// Copyright (c) 2016 Kari Karvonen, OH1KK

var ant_switch_ext_name = 'ant_switch';		// NB: must match ant_switch.c:ant_switch_ext.name
var ant_switch_first_time = true;
var ant_switch_poll_interval;
var ant_switch_exantenna=0; // to avoid console.log spam on timerupdates

function ant_switch_main()
{
	ext_switch_to_client(ant_switch_ext_name, ant_switch_first_time, ant_switch_recv);		// tell server to use us (again)
	if (!ant_switch_first_time)
		ant_switch_controls_setup();
	ant_switch_first_time = false;
}

var ant_switch_cmd_e = { CMD1:0 };

function ant_switch_recv(data)
{
	var firstChars = getFirstChars(data, 3);

	// process data sent from server/C by ext_send_data_msg()
	if (firstChars == "DAT") {
		var ba = new Uint8Array(data, 4);
		var cmd = ba[0];

		if (cmd == ant_switch_cmd_e.CMD1) {
			// do something ...
		} else {
			console.log('ant_switch_recv: DATA UNKNOWN cmd='+ cmd +' len='+ (ba.length-1));
		}
		return;
	}

	// process command sent from server/C by ext_send_msg() or ext_send_encoded_msg()
	var stringData = arrayBufferToString(data);
	var params = stringData.substring(4).split(" ");

	for (var i=0; i < params.length; i++) {
		var param = params[i].split("=");

		switch (param[0]) {

			case "ready":
				ant_switch_controls_setup();
				break;

			case "Antenna":
				var arg = String.fromCharCode(param[1]).charAt(0);
                                ant_switch_process_reply(arg);
				break;

			default:
				console.log('ant_switch_recv: UNKNOWN CMD '+ param[0]);
				break;
		}
	}
}

function ant_switch_controls_setup()
{

   var buttons_html = '';
   var antdesc = [ ];
   var tmp;
   for (tmp=1; tmp<8; tmp++) antdesc[tmp] = ext_get_cfg_param_string('ant_switch.ant'+tmp+'desc', '', EXT_NO_SAVE);
   console.log('ant_switch: Antenna configuration');
   for (tmp = 1; tmp<8; tmp++) {
           if (antdesc[tmp] == undefined || antdesc[tmp] == null || antdesc[tmp] == '') {
                antdesc[tmp] = '';
           }  else {
                buttons_html+=w3_divs('','', w3_inline('', '', w3_btn('Antenna '+tmp, 'ant_switch_select_'+tmp),antdesc[tmp]));
           }
           console.log('ant_switch: Antenna '+ tmp +': '+ antdesc[tmp]);
   }

   buttons_html+=w3_inline('', '', w3_btn('Ground all', 'ant_switch_select_groundall'), 'Ground all antennas');
   console.log('ant_switch: Antenna g: Ground all antennas');
   var data_html =
      '

';
	var controls_html =
		w3_divs('id-ant_display-controls w3-text-white', '',
			data_html,
        		w3_divs('w3-container', 'w3-tspace-8',
			        w3_divs('', 'w3-medium w3-text-aqua', 'MS-S7-WEB Antenna switch'),
                                w3_divs('id-ant-display-selected', '','Selected antenna: unknown'),
                                w3_divs('', '',buttons_html),
                                w3_divs('', '','')
                        )
		);

	ext_panel_show(controls_html, null, null);
	ant_switch_visible(1);
        ant_switch_poll();
}

function ant_switch_blur()
{
        kiwi_clearInterval(ant_switch_poll_interval);
	console.log('### ant_switch_blur');
	ant_switch_visible(0);		// hook to be called when controls panel is closed
}

// called to display HTML for configuration parameters in admin interface
function ant_switch_config_html()
{
	ext_admin_config(ant_switch_ext_name, 'Antenna switch',
		w3_divs('id-ant_switch w3-text-teal w3-hide', '',
			'MS-S7-WEB Antenna switch configuration' +
			'
Leave Antenna description field empty if you want to disable antenna' +
			'
' +
			w3_third('', 'w3-container',
				w3_divs('', 'w3-margin-bottom',
					w3_input_get_param('Antenna 1 description', 'ant_switch.ant1desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 2 description', 'ant_switch.ant2desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 3 description', 'ant_switch.ant3desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 4 description', 'ant_switch.ant4desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 5 description', 'ant_switch.ant5desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 6 description', 'ant_switch.ant6desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 7 description', 'ant_switch.ant7desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna switch failure or unknown status decription', 'ant_switch.ant0desc', 'w3_string_set_cfg_cb')
				), '', ''
			)
		)
	);
}

function ant_switch_visible(v)
{
	visible_block('id-ant_switch-data', v);
}

function ant_switch_select_1(path,val) {
        ant_switch_select_antenna('1');
}
function ant_switch_select_2(path,val) {
        ant_switch_select_antenna('2');
}
function ant_switch_select_3(path,val) {
        ant_switch_select_antenna('3');
}
function ant_switch_select_4(path,val) {
        ant_switch_select_antenna('4');
}
function ant_switch_select_5(path,val) {
        ant_switch_select_antenna('5');
}
function ant_switch_select_6(path,val) {
        ant_switch_select_antenna('6');
}
function ant_switch_select_7(path,val) {
        ant_switch_select_antenna('7');
}

function ant_switch_select_groundall(path,val) {
        setTimeout('w3_radio_unhighlight('+ q(path) +')', w3_highlight_time);
        ant_switch_select_antenna('g');
}

function ant_switch_select_antenna(ant) {
        console.log('ant_switch: switching to antenna '+ant);
	ext_send('SET Antenna='+ant);
        ext_send('GET Antenna');
}

function ant_switch_poll() {
        kiwi_clearInterval(ant_switch_poll_interval);
        ant_switch_poll_interval = setInterval(ant_switch_poll, 10000);
        ext_send('GET Antenna');
}

function ant_switch_process_reply(ant) {
        ant_selected_antenna = ant;

        var need_to_inform = false;
        if (ant_switch_exantenna != ant) {
                // antenna changed.
                need_to_inform = true;
                ant_switch_exantenna = ant;
        }

        if (ant == 'g') {
                if (need_to_inform) console.log('ant_switch: all antennas grouded');
                ant_display_update('Thunderstorm mode. All antennas are grounded.');
        } else {
                if (need_to_inform) console.log('ant_switch: antenna '+ ant_selected_antenna +' in use');
                ant_display_update('Antenna '+ant_selected_antenna + ": "+ext_get_cfg_param_string('ant_switch.ant'+ant_selected_antenna+'desc', '', EXT_NO_SAVE));
        }

        // update highlights
        var inputs = document.getElementsByTagName("button");
        for (var i = 0; i < inputs.length; i++) {
                if (inputs[i].textContent == 'Antenna '+ant) {
                        // highlight
                        w3_highlight(inputs[i]);
                } else {
                        // unhighlight
                        var re=/^Antenna ([1-7])/i;
                        if (inputs[i].textContent.match(re)) w3_unhighlight(inputs[i]);
                }
        }

}

function ant_display_update(ant) {
        html('id-ant-display-selected').innerHTML = ant;
        var el = html('rx-antenna');
        if (el != undefined && ant) {
                el.innerHTML = ant;
        }
}
<commit_msg>Allow admin to lock antenna switching<commit_after>// Copyright (c) 2016 Kari Karvonen, OH1KK

var ant_switch_ext_name = 'ant_switch';		// NB: must match ant_switch.c:ant_switch_ext.name
var ant_switch_first_time = true;
var ant_switch_poll_interval;
var ant_switch_exantenna=0; // to avoid console.log spam on timerupdates

function ant_switch_main()
{
	ext_switch_to_client(ant_switch_ext_name, ant_switch_first_time, ant_switch_recv);		// tell server to use us (again)
	if (!ant_switch_first_time)
		ant_switch_controls_setup();
	ant_switch_first_time = false;
}

var ant_switch_cmd_e = { CMD1:0 };

function ant_switch_recv(data)
{
	var firstChars = getFirstChars(data, 3);

	// process data sent from server/C by ext_send_data_msg()
	if (firstChars == "DAT") {
		var ba = new Uint8Array(data, 4);
		var cmd = ba[0];

		if (cmd == ant_switch_cmd_e.CMD1) {
			// do something ...
		} else {
			console.log('ant_switch_recv: DATA UNKNOWN cmd='+ cmd +' len='+ (ba.length-1));
		}
		return;
	}

	// process command sent from server/C by ext_send_msg() or ext_send_encoded_msg()
	var stringData = arrayBufferToString(data);
	var params = stringData.substring(4).split(" ");

	for (var i=0; i < params.length; i++) {
		var param = params[i].split("=");

		switch (param[0]) {

			case "ready":
				ant_switch_controls_setup();
				break;

			case "Antenna":
				var arg = String.fromCharCode(param[1]).charAt(0);
                                ant_switch_process_reply(arg);
				break;
                        case "DenySwitching":
                                var arg = String.fromCharCode(param[1]).charAt(0);
                                ant_switch_denyswitching(arg);
			default:
				console.log('ant_switch_recv: UNKNOWN CMD '+ param[0]);
				break;
		}
	}
}

function ant_switch_controls_setup()
{

   var buttons_html = '';
   var antdesc = [ ];
   var tmp;
   for (tmp=1; tmp<8; tmp++) antdesc[tmp] = ext_get_cfg_param_string('ant_switch.ant'+tmp+'desc', '', EXT_NO_SAVE);
   console.log('ant_switch: Antenna configuration');
   for (tmp = 1; tmp<8; tmp++) {
           if (antdesc[tmp] == undefined || antdesc[tmp] == null || antdesc[tmp] == '') {
                antdesc[tmp] = '';
           }  else {
                buttons_html+=w3_divs('','', w3_inline('', '', w3_btn('Antenna '+tmp, 'ant_switch_select_'+tmp),antdesc[tmp]));
           }
           console.log('ant_switch: Antenna '+ tmp +': '+ antdesc[tmp]);
   }

   buttons_html+=w3_inline('', '', w3_btn('Ground all', 'ant_switch_select_groundall'), 'Ground all antennas');
   console.log('ant_switch: Antenna g: Ground all antennas');
   var data_html =
      '

';
	var controls_html =
		w3_divs('id-ant_display-controls w3-text-white', '',
			data_html,
        		w3_divs('w3-container', 'w3-tspace-8',
			        w3_divs('', 'w3-medium w3-text-aqua', 'Antenna switch'),
                                w3_divs('id-ant-display-selected', '','Selected antenna: unknown'),
                                w3_divs('id-ant-display-denyswitching', '',''),
                                w3_divs('', '',buttons_html),
                                w3_divs('', '','')
                        )
		);

	ext_panel_show(controls_html, null, null);
	ant_switch_visible(1);
        ant_switch_poll();
}

function ant_switch_blur()
{
        kiwi_clearInterval(ant_switch_poll_interval);
	console.log('### ant_switch_blur');
	ant_switch_visible(0);		// hook to be called when controls panel is closed
}

// called to display HTML for configuration parameters in admin interface
function ant_switch_config_html()
{
        var denyswitching = ext_get_cfg_param('ant_switch.denyswitching', '', EXT_NO_SAVE);
	ext_admin_config(ant_switch_ext_name, 'Antenna switch',
		w3_divs('id-ant_switch w3-text-teal w3-hide', '',
			'Antenna switch configuration' +
			'
' +
			w3_third('', 'w3-container',
				w3_divs('', 'w3-margin-bottom',
                                        w3_divs('', '', 'Deny antenna switching? ' +
                                                w3_radio_btn('No', 'ant_switch.denyswitching', denyswitching? 0:1, 'ant_denyswitching') +
                                                w3_radio_btn('Yes', 'ant_switch.denyswitching', denyswitching? 1:0, 'ant_denyswitching')
                                        ),
                                        w3_divs('', '','
If antenna switching is denied then users cannot switch antennas. Admin can always switch antennas from KiwiSDR ssh root console using /usr/local/bin/ms-s7-web script.'),
                                        w3_divs('', '','
Antenna buttons configuration
'),
                                        w3_divs('', '','Leave Antenna description field empty if you want to hide antenna button from users
'),
					w3_input_get_param('Antenna 1 description', 'ant_switch.ant1desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 2 description', 'ant_switch.ant2desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 3 description', 'ant_switch.ant3desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 4 description', 'ant_switch.ant4desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 5 description', 'ant_switch.ant5desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 6 description', 'ant_switch.ant6desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna 7 description', 'ant_switch.ant7desc', 'w3_string_set_cfg_cb'),
					w3_input_get_param('Antenna switch failure or unknown status decription', 'ant_switch.ant0desc', 'w3_string_set_cfg_cb')
				), '', ''
			)
		)
	);
}

function ant_switch_visible(v)
{
	visible_block('id-ant_switch-data', v);
}

function ant_switch_select_1(path,val) {
        ant_switch_select_antenna('1');
}
function ant_switch_select_2(path,val) {
        ant_switch_select_antenna('2');
}
function ant_switch_select_3(path,val) {
        ant_switch_select_antenna('3');
}
function ant_switch_select_4(path,val) {
        ant_switch_select_antenna('4');
}
function ant_switch_select_5(path,val) {
        ant_switch_select_antenna('5');
}
function ant_switch_select_6(path,val) {
        ant_switch_select_antenna('6');
}
function ant_switch_select_7(path,val) {
        ant_switch_select_antenna('7');
}

function ant_switch_select_groundall(path,val) {
        setTimeout('w3_radio_unhighlight('+ q(path) +')', w3_highlight_time);
        ant_switch_select_antenna('g');
}

function ant_switch_select_antenna(ant) {
        console.log('ant_switch: switching to antenna '+ant);
	ext_send('SET Antenna='+ant);
        ext_send('GET Antenna');
}

function ant_switch_poll() {
        kiwi_clearInterval(ant_switch_poll_interval);
        ant_switch_poll_interval = setInterval(ant_switch_poll, 10000);
        ext_send('GET Antenna');
}

function ant_switch_process_reply(ant) {
        ant_selected_antenna = ant;
        var need_to_inform = false;

        if (ant_switch_exantenna != ant) {
                // antenna changed.
                need_to_inform = true;
                ant_switch_exantenna = ant;
        }

        if (ant == 'g') {
                if (need_to_inform) console.log('ant_switch: all antennas grouded');
                ant_display_update('Thunderstorm mode. All antennas are grounded.');
        } else {
                if (need_to_inform) console.log('ant_switch: antenna '+ ant_selected_antenna +' in use');
                ant_display_update('Antenna '+ant_selected_antenna + ": "+ext_get_cfg_param_string('ant_switch.ant'+ant_selected_antenna+'desc', '', EXT_NO_SAVE));
        }

        // update highlights
        var inputs = document.getElementsByTagName("button");
        for (var i = 0; i < inputs.length; i++) {
                if (inputs[i].textContent == 'Antenna '+ant) {
                        // highlight
                        w3_highlight(inputs[i]);
                } else {
                        // unhighlight
                        var re=/^Antenna ([1-7])/i;
                        if (inputs[i].textContent.match(re)) w3_unhighlight(inputs[i]);
                }
        }
        var status_denyswitching = ext_get_cfg_param('ant_switch.denyswitching', '');
        if (status_denyswitching == 1) {
                // lock buttons
                html('id-ant-display-denyswitching').innerHTML = 'Antenna switching disallowed by admin';
        } else {
                // unlock buttons
                html('id-ant-display-denyswitching').innerHTML = 'Antenna switching normal operation';
        }

}

function ant_display_update(ant) {
        // FIXME: How to notify other users about antenna changes?
        html('id-ant-display-selected').innerHTML = ant;
        /*
        var el = html('rx-antenna');
        if (el != undefined && ant) {
                el.innerHTML = ant;
        }
        */
}

function ant_denyswitching(id, idx) {
        var tmp = ext_set_cfg_param(id, idx, EXT_SAVE);
}
<|endoftext|>


<commit_before>// ajaxcom.js
// https://github.com/advertize/AjaxCom
(function($) {
    "use strict";

    $.event.props.push('state');
    $(window).on('popstate.ajaxcom', function(event) {
        if (typeof event.state === 'object' && event.state !== null) {
            window.location.reload();
        }
    });
    window.history.replaceState({}, null);

    // Intercept click and submit events and perform an ajax request then
    // handle instructions returned
    //
    // Exported as $.fn.ajaxcom
    //
    // Returns the jQuery object
    function fnAjaxcom(selector, options) {
        if (!selector) {
            selector = 'a, form';
        }
        this.on('click', selector, function(event) {
            var opts = $.extend({}, options);
            handleClick(event, opts);
        });
        this.on('submit', selector, function(event) {
            var opts = $.extend({}, options);
            handleSubmit(event, opts);
        });
        return this;
    }

    // Does the ajax request
    //
    // Exported as $.ajaxcom
    //
    // Returns the same as $.ajax
    function ajaxcom(options) {
        var defaults = {
            dataType: 'json'
        };
        options = $.extend(true, {}, $.ajaxSettings, defaults, options);

        options.beforeSend = function(xhr, settings) {
            xhr.setRequestHeader('X-AjaxCom', 'true');
        }

        options.success = function(data, status, xhr) {
            if (data.ajaxcom) {
                $.each(data.ajaxcom, function(index, operation) {
                    handleOperation(operation);
                });
            }
        }

        return $.ajax(options);
    }

    // Handle click events
    //
    // Exported as $.ajaxcom.click
    function handleClick(event, options)
    {
        // Middle, cmd, ctrl, shift, alt clicks should open in a new tab as normal
        if (event.which>1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
            return;
        }

        var link = event.currentTarget;

        // Ignore non anchor elements
        if (link.tagName.toUpperCase()!=='A') {
            return;
        }

        // Ignore external links
        if (location.protocol!==link.protocol || location.host!==link.host) {
            return;
        }

        // Ignore anchors on the same page
        if (link.hash && link.href.replace(link.hash, '')===location.href.replace(location.hash, '')) {
            return;
        }

        // Ignore empty anchors
        if (link.href===location.href + '#') {
            return;
        }

        var defaults = {
            url: link.href
        };

        ajaxcom($.extend({}, defaults, options));

        event.preventDefault();
    }

    // Handle submit events
    //
    // Exported as $.ajaxcom.submit
    function handleSubmit(event, options)
    {
        var form = event.currentTarget;

        // Ignore nonform elements
        if (form.tagName.toUpperCase()!=='FORM') {
            return;
        }

        var defaults = {
            type: form.method,
            url: form.action,
            data: $(form).serializeArray()
        }

        ajaxcom($.extend({}, defaults, options));

        event.preventDefault();
    }

    // Delegates operations to their handler
    function handleOperation(operation) {
        switch (operation.operation) {
            case 'container':
                handleContainer(operation.options)
                break;
            case 'modal':
                handleModal(operation.options);
                break;
            case 'changeurl':
                handleChangeUrl(operation.options);
                break;
            case 'callback':
                handleCallback(operation.options);
                break;
            default:
                throw "Operation " + operation.operation + " is not supported";
                break;
        }
    }

    // Handle modals
    function handleModal(options) {
        switch (options.type) {
            case 'twitterbootstrap':
                twitterbootstrap();
                break;
            default:
                throw "Modal type " + options.type + " is not supported";
                break;
        }

        function twitterbootstrap() {
            if (options.close === true) {
                $(options.html).modal('hide');
            } else {
                var $html = $(options.html);
                $html.modal();
                if (options.autoremove) {
                    $html.on('hidden', function(event) {
                        $(this).remove();
                    });
                }
            }
        }
    }

    // Handle change urls
    function handleChangeUrl(options) {
        console.warn('handleChangeUrl is not yet fully implement');
        switch (options.method) {
            case 'push':
                setTimeout(function() {
                    window.history.pushState({}, null, options.url);
                }, options.wait);
                break;
            case 'replace':
                setTimeout(function() {
                    window.history.replaceState({}, null, options.url);
                }, options.wait);
                break;
            case 'redirect':
                setTimeout(function() {
                    window.location.href = options.url;
                }, options.wait);
                break;
            default:
                throw "ChangeUrl method " + options.method + " is not supported";
                break;
        }
    }

    // Handle callbacks
    function handleCallback(options) {
        if ($.isFunction(window[options.callFunction])) {
            window[options.callFunction]();
        } else {
            console.warn('Callback ' + options.callFunction + ' is not a function');
        }
    }

    // Handle containers
    function handleContainer(options) {
        switch (options.method) {
            case 'replaceWith':
                replaceWith();
                break;
            case 'append':
                append();
                break;
            case 'prepend':
                prepend();
                break;
            case 'html':
                html();
                break;
            case 'val':
                val();
                break;
            case 'remove':
                remove();
                break;
            default:
                throw "Container method " + options.method + " is not supported";
                break;
        }

        function removeClass() {
            if (options.removeClass) {
                $(options.target).removeClass(options.removeClass);
            }
        }

        function addClass() {
            if (options.addClass) {
                $(options.target).addClass(options.addClass);
            }
        }

        function replaceWith() {
            var $element = $(options.value);
            $element.hide();
            if (options.animate===true) {
                $(options.target).fadeOut(600, function() {
                    $(options.target).replaceWith($element);
                    $element.fadeIn(600);
                });
            } else {
                $(options.target).replaceWith($element.show());
            }
        }
        function append() {

            if (options.animate===true) {
                var $element = $(options.value);
                $element.hide();
                $(options.target).append($element);
                $element.fadeIn(600);
            } else {
                $(options.target).append(options.value);
            }
        }
        function prepend() {

            if (options.animate===true) {
                var $element = $(options.value);
                $element.hide();
                $(options.target).prepend($element);
                $element.fadeIn(600);
            } else {
                $(options.target).prepend(options.value);
            }
        }
        function html() {
            if (options.animate===true) {
                $(options.target).fadeOut(600, function() {
                    $(options.target).html(options.value);
                    removeClass();
                    addClass();
                    $(options.target).fadeIn(600);
                });
            } else {
                $(options.target).html(options.value);
                removeClass();
                addClass();
            }
        }
        function val() {
            $(options.target).val(options.value);
            removeClass();
            addClass();
        }
        function remove() {
            if (options.animate===true) {
                $(options.target).fadeOut(600, function() {
                    $(options.target).remove();
                });
            } else {
                $(options.target).remove();
            }
        }
    }

    $.fn.ajaxcom = fnAjaxcom;
    $.ajaxcom = ajaxcom;
    $.ajaxcom.click = handleClick;
    $.ajaxcom.submit = handleSubmit;
})(jQuery);
<commit_msg>Check whether history is defined before using it<commit_after>// ajaxcom.js
// https://github.com/advertize/AjaxCom
(function($) {
    "use strict";

    $.event.props.push('state');
    $(window).on('popstate.ajaxcom', function(event) {
        if (typeof event.state === 'object' && event.state !== null) {
            window.location.reload();
        }
    });
    history && history.replaceState && history.replaceState({}, null);

    // Intercept click and submit events and perform an ajax request then
    // handle instructions returned
    //
    // Exported as $.fn.ajaxcom
    //
    // Returns the jQuery object
    function fnAjaxcom(selector, options) {
        if (!selector) {
            selector = 'a, form';
        }
        this.on('click', selector, function(event) {
            var opts = $.extend({}, options);
            handleClick(event, opts);
        });
        this.on('submit', selector, function(event) {
            var opts = $.extend({}, options);
            handleSubmit(event, opts);
        });
        return this;
    }

    // Does the ajax request
    //
    // Exported as $.ajaxcom
    //
    // Returns the same as $.ajax
    function ajaxcom(options) {
        var defaults = {
            dataType: 'json'
        };
        options = $.extend(true, {}, $.ajaxSettings, defaults, options);

        options.beforeSend = function(xhr, settings) {
            xhr.setRequestHeader('X-AjaxCom', 'true');
        }

        options.success = function(data, status, xhr) {
            if (data.ajaxcom) {
                $.each(data.ajaxcom, function(index, operation) {
                    handleOperation(operation);
                });
            }
        }

        return $.ajax(options);
    }

    // Handle click events
    //
    // Exported as $.ajaxcom.click
    function handleClick(event, options)
    {
        // Middle, cmd, ctrl, shift, alt clicks should open in a new tab as normal
        if (event.which>1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
            return;
        }

        var link = event.currentTarget;

        // Ignore non anchor elements
        if (link.tagName.toUpperCase()!=='A') {
            return;
        }

        // Ignore external links
        if (location.protocol!==link.protocol || location.host!==link.host) {
            return;
        }

        // Ignore anchors on the same page
        if (link.hash && link.href.replace(link.hash, '')===location.href.replace(location.hash, '')) {
            return;
        }

        // Ignore empty anchors
        if (link.href===location.href + '#') {
            return;
        }

        var defaults = {
            url: link.href
        };

        ajaxcom($.extend({}, defaults, options));

        event.preventDefault();
    }

    // Handle submit events
    //
    // Exported as $.ajaxcom.submit
    function handleSubmit(event, options)
    {
        var form = event.currentTarget;

        // Ignore nonform elements
        if (form.tagName.toUpperCase()!=='FORM') {
            return;
        }

        var defaults = {
            type: form.method,
            url: form.action,
            data: $(form).serializeArray()
        }

        ajaxcom($.extend({}, defaults, options));

        event.preventDefault();
    }

    // Delegates operations to their handler
    function handleOperation(operation) {
        switch (operation.operation) {
            case 'container':
                handleContainer(operation.options)
                break;
            case 'modal':
                handleModal(operation.options);
                break;
            case 'changeurl':
                handleChangeUrl(operation.options);
                break;
            case 'callback':
                handleCallback(operation.options);
                break;
            default:
                throw "Operation " + operation.operation + " is not supported";
                break;
        }
    }

    // Handle modals
    function handleModal(options) {
        switch (options.type) {
            case 'twitterbootstrap':
                twitterbootstrap();
                break;
            default:
                throw "Modal type " + options.type + " is not supported";
                break;
        }

        function twitterbootstrap() {
            if (options.close === true) {
                $(options.html).modal('hide');
            } else {
                var $html = $(options.html);
                $html.modal();
                if (options.autoremove) {
                    $html.on('hidden', function(event) {
                        $(this).remove();
                    });
                }
            }
        }
    }

    // Handle change urls
    function handleChangeUrl(options) {
        console.warn('handleChangeUrl is not yet fully implement');
        switch (options.method) {
            case 'push':
                setTimeout(function() {
                    history && history.pushState && history.pushState({}, null, options.url);
                }, options.wait);
                break;
            case 'replace':
                setTimeout(function() {
                    history && history.replaceState && history.replaceState({}, null, options.url);
                }, options.wait);
                break;
            case 'redirect':
                setTimeout(function() {
                    window.location.href = options.url;
                }, options.wait);
                break;
            default:
                throw "ChangeUrl method " + options.method + " is not supported";
                break;
        }
    }

    // Handle callbacks
    function handleCallback(options) {
        if ($.isFunction(window[options.callFunction])) {
            window[options.callFunction]();
        } else {
            console.warn('Callback ' + options.callFunction + ' is not a function');
        }
    }

    // Handle containers
    function handleContainer(options) {
        switch (options.method) {
            case 'replaceWith':
                replaceWith();
                break;
            case 'append':
                append();
                break;
            case 'prepend':
                prepend();
                break;
            case 'html':
                html();
                break;
            case 'val':
                val();
                break;
            case 'remove':
                remove();
                break;
            default:
                throw "Container method " + options.method + " is not supported";
                break;
        }

        function removeClass() {
            if (options.removeClass) {
                $(options.target).removeClass(options.removeClass);
            }
        }

        function addClass() {
            if (options.addClass) {
                $(options.target).addClass(options.addClass);
            }
        }

        function replaceWith() {
            var $element = $(options.value);
            $element.hide();
            if (options.animate===true) {
                $(options.target).fadeOut(600, function() {
                    $(options.target).replaceWith($element);
                    $element.fadeIn(600);
                });
            } else {
                $(options.target).replaceWith($element.show());
            }
        }
        function append() {

            if (options.animate===true) {
                var $element = $(options.value);
                $element.hide();
                $(options.target).append($element);
                $element.fadeIn(600);
            } else {
                $(options.target).append(options.value);
            }
        }
        function prepend() {

            if (options.animate===true) {
                var $element = $(options.value);
                $element.hide();
                $(options.target).prepend($element);
                $element.fadeIn(600);
            } else {
                $(options.target).prepend(options.value);
            }
        }
        function html() {
            if (options.animate===true) {
                $(options.target).fadeOut(600, function() {
                    $(options.target).html(options.value);
                    removeClass();
                    addClass();
                    $(options.target).fadeIn(600);
                });
            } else {
                $(options.target).html(options.value);
                removeClass();
                addClass();
            }
        }
        function val() {
            $(options.target).val(options.value);
            removeClass();
            addClass();
        }
        function remove() {
            if (options.animate===true) {
                $(options.target).fadeOut(600, function() {
                    $(options.target).remove();
                });
            } else {
                $(options.target).remove();
            }
        }
    }

    $.fn.ajaxcom = fnAjaxcom;
    $.ajaxcom = ajaxcom;
    $.ajaxcom.click = handleClick;
    $.ajaxcom.submit = handleSubmit;
})(jQuery);
<|endoftext|>