<commit_before>var baseUrl = 'http://127.0.0.1:9000'; // enter IP

var explanationRequests = [], explanations = [], actions;

var dialog = document.createElement('dialog');

// START: document onReady
(function () {
  //insert dialog
  insertDialog();

  // get requests and annotations from the server and add them to the dom
  httpGet("/articles/single", {url: window.location.href}, function (article) {
    actions = article.links;
    show(article.requests, article.annotations);
  });
})();

function insertDialog() {

  dialog.innerHTML =
    '
Please explain this
' +
    '<button id="close">✖</button>' +
    '

' +
    '
' +
    '<textarea class="skiir-button-prefix" placeholder="Please explain the underlined text above"></textarea>' +
    '<button id="done" class="skiir-button">Done</button>' +
    '
' +
    '
Pick your sources:
' +
    '

' +
    '
Or vote for one of these explanations:
' +
    '

';
  dialog.id = "skiir-dialog";
  dialog.querySelector('#close').onclick = function (e) {
    dialog.close();
  };
  document.body.insertBefore(dialog, document.body.firstChild);
}

function show(requests, explanations) {
  // update de DOM met buttons en explanation components
  // TODO: Bug! only 1 request per paragraph!
  requests.forEach(function (exReq) {
    // search page for explanationRequest.text_surroundings

    exReq.paragraph = getParagraphOfText(exReq.text_surroundings, exReq.text);

    var exs = explanations.filter(function (i) {
      return exReq.id === i.request_id
    });

    if (exs.length) {
      // get the explanation with the most votes
      exReq.explanation = exs.reduce(function (prev, curr) {
        return curr.votes > prev.votes ? curr : prev;
      });
      addExplanation(exReq);
    }
    else {
      addExplanationRequest(exReq);
    }
  });
}

/**
 *
 *   <button>phrase
 *

 *     <button>improve
 *
explanation
 *     *references
 *
 * @param ex Explanation
 */
function addExplanation(ex) {

  var span = document.createElement('span');
  var button = document.createElement('button');
  button.textContent = ex.text;

  span.className = 'skiir-explanation';
  var links = '';
  if (ex.explanation.references) {
    links += '
';
    for (var key in ex.explanation.references) {
      links += '[' + key + ']';
    }
    links += '
';
  }

  var improveButton = document.createElement('button');
  improveButton.textContent = 'Improve';
  improveButton.className = 'skiir-button skiir-button-green improve';
  improveButton.onclick = function () {
    openDialog(ex);
  };
  var div = document.createElement('div');
  div.className = "skiir-explanation-box"
  div.innerHTML = '
' + ex.explanation.answer + '
' + links;
  div.insertBefore(improveButton, div.firstChild);
  span.appendChild(button);
  span.appendChild(div);
  button.onclick = function () {
    toggleShow(span);
  };

  try {

    var paragraph = ex.paragraph;
    var text = paragraph.innerHTML.split(ex.text);

    while (paragraph.firstChild) paragraph.removeChild(paragraph.firstChild);

    paragraph.appendChild(document.createTextNode(text[0]));
    paragraph.appendChild(span);
    paragraph.appendChild(document.createTextNode(text[1]));

  } catch (err) {
    console.error(err);
  }

  ex.span = span;
  explanations.push(ex);
}

function toggleShow(span) {
  if (span.classList.contains('show')) {
    span.classList.remove('show');
  } else {
    span.classList.add('show');
  }
}

/**
 * <button>phrase
 * @param exReq Explanation Request object
 */
function addExplanationRequest(exReq) {

  var button = document.createElement('button');
  button.className = 'skiir-help';
  button.textContent = exReq.text;
  button.onclick = function () {
    openDialog(exReq)
  };

  try {

    var paragraph = exReq.paragraph;
    var text = paragraph.innerHTML.split(exReq.text);

    while (paragraph.firstChild) paragraph.removeChild(paragraph.firstChild);

    paragraph.appendChild(document.createTextNode(text[0]));
    paragraph.appendChild(button);
    paragraph.appendChild(document.createTextNode(text[1]));

  }
  catch (err) {
    console.error(err);
  }
  exReq.button = button;
  explanationRequests.push(exReq);
}

function updateExplanationRequest(exReq) {
  console.log(exReq);

  var exs = explanations.filter(function (i) {
    return exReq.id === i.request_id
  });

  if (exs.length) {
    // get the explanation with the most votes
    exReq.explanation = exs.reduce(function (prev, curr) {
      return curr.votes > prev.votes ? curr : prev;
    });

    exReq.paragraph.innerHTML = exReq.paragraph.innerHTML.replace(exReq.button.outerHTML, exReq.text);

    delete exReq.button;

    addExplanation(exReq);
  }
}

function stringify(snip) {
  result = '';
  var bolds = snip.bolds[0];
  var start = snip.outer[0];
  var result = snip.snip;
  bolds.sort(function (a, b) {
    return b[1] - a[1]
  }).forEach(function (bold) {
    result = [result.slice(0, bold[1] - start), '', result.slice(bold[1] - start)].join('');
    result = [result.slice(0, bold[0] - start), '', result.slice(bold[0] - start)].join('');
    //console.log(result);
  });
  if (start != 0) result = "..." + result;
  result += '...';

  return result;
}

function openDialog(exReq) {

  var highlight = '' + exReq.text + '';
  dialog.showModal();
  dialog.querySelector('p#context').innerHTML = exReq.text_surroundings.replace(exReq.text, highlight);
  $("#exReqText").scrollView();

  // get related articles for snippets
  httpGet(exReq.actions.relatedArticles, null, function (data) {
    var snippetsHtml = '';
    data.forEach(function (s) {
      snippetsHtml +=
        '
' +
        '<input type="checkbox" value="' + s.reference + '">' +
        '
' +
        '' +
        '
' + s.title.toUpperCase() + '
' +
        s.snippets.map(stringify).reduce(function (a, b) {
          return a + b
        }, "") +
        '
' +
        '
';
    });

    dialog.querySelector('div#relatedArticles').innerHTML = snippetsHtml;

  });

  // get annotations for vote buttons
  httpGet(exReq.actions.annotations, null, function (data) {
    var snippetsHtml = '
';
    data.sort(function (a, b) {
      return b.votes - a.votes
    });
    data.forEach(function (s) {
      var vote_url = s.actions.vote;
      snippetsHtml +=
        '

' + s.votes + '
' +
        '<button class="skiir-button vote" data-url="' + vote_url + '">Vote</button>' +
        '' + s.answer + '
';
    });
    snippetsHtml += '
';
    dialog.querySelector('div#annotations').innerHTML = snippetsHtml;
  });

  // Vote button functionality
  $(dialog).off("click", "button.vote");
  $(dialog).on("click", "button.vote", function () {
    var b = $(this);
    $.post(baseUrl + b.attr('data-url'), null, function () {
      b.prev(".votes").text(1 + parseInt(b.prev(".votes").text()));
    });
  });

  // Submitting of Annotation:
  dialog.querySelector('#done').onclick = function (e) {
    var textarea = dialog.querySelector('textarea');

    // Can't submit empty annotation
    if (!textarea.value)
      return;

    var references = [].map.call( // return all values from checked checkboxes
      dialog.querySelectorAll('[type="checkbox"]:checked'), function (obj) {
        return obj.value;
      });

    var postData = {
      explanation: textarea.value,
      references: references
    };
    console.info("Sending annotation to server", textarea.value);

    textarea.value = "";

    httpPost(exReq.actions.annotate, postData, function (data) {
      console.log(data);

      $.getJSON(baseUrl + data.actions.annotation).done(function(data2) {
        // add the last (newest explanation to explanations
        console.log(data2);
        explanations.push(data2.slice(-1)[0]);
        updateExplanationRequest(exReq);
      });

      console.info('Posted annotation.')
    });

    dialog.close();
  };
}

function getParagraphOfText(surround, text) {
  var match = $("p:containsEscaped(" + escape(surround) + ") p:containsEscaped(" + escape(text) + ")");
  match = match.size() && match || $("p:containsEscaped(" + escape(text) + ")");
  return match.get(0);
}

function getSelectionParentElement() {
  var parentEl = null, sel;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      parentEl = sel.getRangeAt(0).commonAncestorContainer;
      if (parentEl.nodeType != 1) {
        parentEl = parentEl.parentNode;
      }
    }
  } else if ((sel = document.selection) && sel.type != "Control") {
    parentEl = sel.createRange().parentElement();
  }
  return parentEl;
}

// Adding a Request via right-clicking:
chrome.runtime.onMessage.addListener(function (req, sender, sendResponse) {
  if (req.details) {
    var exReq = req.details;
    console.debug("Send annotation request to server", exReq);

    var postbody = {
      "article_url": window.location.href,
      "article_title": document.title,
      "article_text": document.querySelector('.article-body').textContent,
      "request_text": exReq.text,
      "request_text_surroundings": getSelectionParentElement().textContent
    };
    var paragraph = getSelectionParentElement();

    $.ajax({
      url: baseUrl + "/requests",
      data: JSON.stringify(postbody),
      contentType: 'application/json',
      'type': 'POST'
    }).done(function (data) {
      // The request was saved, now display annotation request:
      $.getJSON(baseUrl + data.actions.self).done(function (exReq) {
        exReq.paragraph = paragraph;
        addExplanationRequest(exReq);
        //openDialog(exReq);
      });
    }).fail(function () {

    });
    sendResponse({farewell: "goodbye"});
  }
});

///////////////
// Utilities //
///////////////
function httpGet(url, params, callback) {

  function serialize(obj) {
    var str = [];
    for (var p in obj)
      if (obj.hasOwnProperty(p)) {
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
      }
    return str.join("&");
  }

  if (params) url += '?' + serialize(params);

  var httpRequest = new XMLHttpRequest();

  if (callback)
    httpRequest.onloadend = function () {
      callback(JSON.parse(httpRequest.responseText), httpRequest);
    };
  httpRequest.open('GET', baseUrl + url, true);
  httpRequest.send();

}

function httpPost(url, data, callback) {
  var httpRequest = new XMLHttpRequest();
  httpRequest.open("POST", baseUrl + url, true);
  httpRequest.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
  httpRequest.send(JSON.stringify(data));

  if (callback)
    httpRequest.onloadend = function () {
      var json = null;
      try {
        json = JSON.parse(httpRequest.responseText);
      } catch(e) {}
      callback(json, httpRequest);
    };
}

$.extend($.expr[':'], {
  containsEscaped: function (el, index, m) {
    var s = unescape(m[3]).replace(/[\s\n]+/g, " ").trim();
    return $(el).text().replace(/[\s\n]+/g, " ").indexOf(s) >= 0;
  }
});

// scrollParent is from Jquery-UI
$.fn.scrollParent = function (includeHidden) {
  var position = this.css("position"),
    excludeStaticParent = position === "absolute",
    overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
    scrollParent = this.parents().filter(function () {
      var parent = $(this);
      if (excludeStaticParent && parent.css("position") === "static") {
        return false;
      }
      return overflowRegex.test(parent.css("overflow") + parent.css("overflow-y") + parent.css("overflow-x"));
    }).eq(0);

  return position === "fixed" || !scrollParent.length ? $(this[0].ownerDocument || document) : scrollParent;
};
$.fn.scrollView = function (duration) {
  return this.each(function () {
    $($(this).scrollParent()).get(0).scrollTop = $(this).offset().top - $($(this).scrollParent()).offset().top;
  });
};
<commit_msg>fixed reference undefined link bug<commit_after>var baseUrl = 'http://127.0.0.1:9000'; // enter IP

var explanationRequests = [], explanations = [], actions;

var dialog = document.createElement('dialog');

// START: document onReady
(function () {
  //insert dialog
  insertDialog();

  // get requests and annotations from the server and add them to the dom
  httpGet("/articles/single", {url: window.location.href}, function (article) {
    actions = article.links;
    show(article.requests, article.annotations);
  });
})();

function insertDialog() {

  dialog.innerHTML =
    '
Please explain this
' +
    '<button id="close">✖</button>' +
    '

' +
    '
' +
    '<textarea class="skiir-button-prefix" placeholder="Please explain the underlined text above"></textarea>' +
    '<button id="done" class="skiir-button">Done</button>' +
    '
' +
    '
Pick your sources:
' +
    '

' +
    '
Or vote for one of these explanations:
' +
    '

';
  dialog.id = "skiir-dialog";
  dialog.querySelector('#close').onclick = function (e) {
    dialog.close();
  };
  document.body.insertBefore(dialog, document.body.firstChild);
}

function show(requests, explanations) {
  // update de DOM met buttons en explanation components
  // TODO: Bug! only 1 request per paragraph!
  requests.forEach(function (exReq) {
    // search page for explanationRequest.text_surroundings

    exReq.paragraph = getParagraphOfText(exReq.text_surroundings, exReq.text);

    var exs = explanations.filter(function (i) {
      return exReq.id === i.request_id
    });

    if (exs.length) {
      // get the explanation with the most votes
      exReq.explanation = exs.reduce(function (prev, curr) {
        return curr.votes > prev.votes ? curr : prev;
      });
      addExplanation(exReq);
    }
    else {
      addExplanationRequest(exReq);
    }
  });
}

/**
 *
 *   <button>phrase
 *

 *     <button>improve
 *
explanation
 *     *references
 *
 * @param ex Explanation
 */
function addExplanation(ex) {

  var span = document.createElement('span');
  var button = document.createElement('button');
  button.textContent = ex.text;

  span.className = 'skiir-explanation';
  var links = '';
  if (ex.explanation.references) {
    links += '
';
    for (var key in ex.explanation.references) {
      links += '[' + key + ']';
    }
    links += '
';
  }

  var improveButton = document.createElement('button');
  improveButton.textContent = 'Improve';
  improveButton.className = 'skiir-button skiir-button-green improve';
  improveButton.onclick = function () {
    openDialog(ex);
  };
  var div = document.createElement('div');
  div.className = "skiir-explanation-box"
  div.innerHTML = '
' + ex.explanation.answer + '
' + links;
  div.insertBefore(improveButton, div.firstChild);
  span.appendChild(button);
  span.appendChild(div);
  button.onclick = function () {
    toggleShow(span);
  };

  try {

    var paragraph = ex.paragraph;
    var text = paragraph.innerHTML.split(ex.text);

    while (paragraph.firstChild) paragraph.removeChild(paragraph.firstChild);

    paragraph.appendChild(document.createTextNode(text[0]));
    paragraph.appendChild(span);
    paragraph.appendChild(document.createTextNode(text[1]));

  } catch (err) {
    console.error(err);
  }

  ex.span = span;
  explanations.push(ex);
}

function toggleShow(span) {
  if (span.classList.contains('show')) {
    span.classList.remove('show');
  } else {
    span.classList.add('show');
  }
}

/**
 * <button>phrase
 * @param exReq Explanation Request object
 */
function addExplanationRequest(exReq) {

  var button = document.createElement('button');
  button.className = 'skiir-help';
  button.textContent = exReq.text;
  button.onclick = function () {
    openDialog(exReq)
  };

  try {

    var paragraph = exReq.paragraph;
    var text = paragraph.innerHTML.split(exReq.text);

    while (paragraph.firstChild) paragraph.removeChild(paragraph.firstChild);

    paragraph.appendChild(document.createTextNode(text[0]));
    paragraph.appendChild(button);
    paragraph.appendChild(document.createTextNode(text[1]));

  }
  catch (err) {
    console.error(err);
  }
  exReq.button = button;
  explanationRequests.push(exReq);
}

function updateExplanationRequest(exReq) {

  var exs = explanations.filter(function (i) {
    return exReq.id === i.request_id
  });

  if (exs.length) {
    // get the explanation with the most votes
    exReq.explanation = exs.reduce(function (prev, curr) {
      return curr.votes > prev.votes ? curr : prev;
    });

    exReq.paragraph.innerHTML = exReq.paragraph.innerHTML.replace(exReq.button.outerHTML, exReq.text);

    delete exReq.button;

    addExplanation(exReq);
  }
}

function stringify(snip) {
  result = '';
  var bolds = snip.bolds[0];
  var start = snip.outer[0];
  var result = snip.snip;
  bolds.sort(function (a, b) {
    return b[1] - a[1]
  }).forEach(function (bold) {
    result = [result.slice(0, bold[1] - start), '', result.slice(bold[1] - start)].join('');
    result = [result.slice(0, bold[0] - start), '', result.slice(bold[0] - start)].join('');
  });
  if (start != 0) result = "..." + result;
  result += '...';

  return result;
}

function openDialog(exReq) {

  var highlight = '' + exReq.text + '';
  dialog.showModal();
  dialog.querySelector('p#context').innerHTML = exReq.text_surroundings.replace(exReq.text, highlight);
  $("#exReqText").scrollView();

  // get related articles for snippets
  httpGet(exReq.actions.relatedArticles, null, function (data) {
    var snippetsHtml = '';
    data.forEach(function (s) {
      snippetsHtml +=
        '
' +
        '<input type="checkbox" value="' + s.url + '">' +
        '
' +
        '' +
        '
' + s.title.toUpperCase() + '
' +
        s.snippets.map(stringify).reduce(function (a, b) {
          return a + b
        }, "") +
        '
' +
        '
';
    });

    dialog.querySelector('div#relatedArticles').innerHTML = snippetsHtml;

  });

  // get annotations for vote buttons
  httpGet(exReq.actions.annotations, null, function (data) {
    var snippetsHtml = '
';
    data.sort(function (a, b) {
      return b.votes - a.votes
    });
    data.forEach(function (s) {
      var vote_url = s.actions.vote;
      snippetsHtml +=
        '

' + s.votes + '
' +
        '<button class="skiir-button vote" data-url="' + vote_url + '">Vote</button>' +
        '' + s.answer + '
';
    });
    snippetsHtml += '
';
    dialog.querySelector('div#annotations').innerHTML = snippetsHtml;
  });

  // Vote button functionality
  $(dialog).off("click", "button.vote");
  $(dialog).on("click", "button.vote", function () {
    var b = $(this);
    $.post(baseUrl + b.attr('data-url'), null, function () {
      b.prev(".votes").text(1 + parseInt(b.prev(".votes").text()));
    });
  });

  // Submitting of Annotation:
  dialog.querySelector('#done').onclick = function (e) {
    var textarea = dialog.querySelector('textarea');

    // Can't submit empty annotation
    if (!textarea.value)
      return;

    var references = [].map.call( // return all values from checked checkboxes
      dialog.querySelectorAll('[type="checkbox"]:checked'), function (obj) {
        return obj.value;
      });

    var postData = {
      explanation: textarea.value,
      references: references
    };
    console.info("Sending annotation to server", textarea.value);

    textarea.value = "";

    httpPost(exReq.actions.annotate, postData, function (data) {

      $.getJSON(baseUrl + data.actions.annotation).done(function(data2) {
        // add the last (newest explanation to explanations
        explanations.push(data2.slice(-1)[0]);
        updateExplanationRequest(exReq);
      });

      console.info('Posted annotation.')
    });

    dialog.close();
  };
}

function getParagraphOfText(surround, text) {
  var match = $("p:containsEscaped(" + escape(surround) + ") p:containsEscaped(" + escape(text) + ")");
  match = match.size() && match || $("p:containsEscaped(" + escape(text) + ")");
  return match.get(0);
}

function getSelectionParentElement() {
  var parentEl = null, sel;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      parentEl = sel.getRangeAt(0).commonAncestorContainer;
      if (parentEl.nodeType != 1) {
        parentEl = parentEl.parentNode;
      }
    }
  } else if ((sel = document.selection) && sel.type != "Control") {
    parentEl = sel.createRange().parentElement();
  }
  return parentEl;
}

// Adding a Request via right-clicking:
chrome.runtime.onMessage.addListener(function (req, sender, sendResponse) {
  if (req.details) {
    var exReq = req.details;
    console.debug("Send annotation request to server", exReq);

    var postbody = {
      "article_url": window.location.href,
      "article_title": document.title,
      "article_text": document.querySelector('.article-body').textContent,
      "request_text": exReq.text,
      "request_text_surroundings": getSelectionParentElement().textContent
    };
    var paragraph = getSelectionParentElement();

    $.ajax({
      url: baseUrl + "/requests",
      data: JSON.stringify(postbody),
      contentType: 'application/json',
      'type': 'POST'
    }).done(function (data) {
      // The request was saved, now display annotation request:
      $.getJSON(baseUrl + data.actions.self).done(function (exReq) {
        exReq.paragraph = paragraph;
        addExplanationRequest(exReq);
        //openDialog(exReq);
      });
    }).fail(function () {

    });
    sendResponse({farewell: "goodbye"});
  }
});

///////////////
// Utilities //
///////////////
function httpGet(url, params, callback) {

  function serialize(obj) {
    var str = [];
    for (var p in obj)
      if (obj.hasOwnProperty(p)) {
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
      }
    return str.join("&");
  }

  if (params) url += '?' + serialize(params);

  var httpRequest = new XMLHttpRequest();

  if (callback)
    httpRequest.onloadend = function () {
      callback(JSON.parse(httpRequest.responseText), httpRequest);
    };
  httpRequest.open('GET', baseUrl + url, true);
  httpRequest.send();

}

function httpPost(url, data, callback) {
  var httpRequest = new XMLHttpRequest();
  httpRequest.open("POST", baseUrl + url, true);
  httpRequest.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
  httpRequest.send(JSON.stringify(data));

  if (callback)
    httpRequest.onloadend = function () {
      var json = null;
      try {
        json = JSON.parse(httpRequest.responseText);
      } catch(e) {}
      callback(json, httpRequest);
    };
}

$.extend($.expr[':'], {
  containsEscaped: function (el, index, m) {
    var s = unescape(m[3]).replace(/[\s\n]+/g, " ").trim();
    return $(el).text().replace(/[\s\n]+/g, " ").indexOf(s) >= 0;
  }
});

// scrollParent is from Jquery-UI
$.fn.scrollParent = function (includeHidden) {
  var position = this.css("position"),
    excludeStaticParent = position === "absolute",
    overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
    scrollParent = this.parents().filter(function () {
      var parent = $(this);
      if (excludeStaticParent && parent.css("position") === "static") {
        return false;
      }
      return overflowRegex.test(parent.css("overflow") + parent.css("overflow-y") + parent.css("overflow-x"));
    }).eq(0);

  return position === "fixed" || !scrollParent.length ? $(this[0].ownerDocument || document) : scrollParent;
};
$.fn.scrollView = function (duration) {
  return this.each(function () {
    $($(this).scrollParent()).get(0).scrollTop = $(this).offset().top - $($(this).scrollParent()).offset().top;
  });
};
<|endoftext|>


<commit_before>/*
#
# img2musicXML.js - v0.1-Alpha
# Apache v2 License
#
*/

// Create img2musicXML (abbreviated as i2mx) namespace
var i2mx = i2mx || { };

// Create JsCheckup class (@TODO: Move to inside namespace)
var JsCheckup = function() {
	this.divClassName = "i2mx-checkup";

	this.activate = function() {
		var divList = document.getElementsByClassName(this.divClassName);

		// @TODO: Implement multiple divs support
		divList[0].innerHTML = "No checlist for now, but img2musicXML loaded successfully!"; // @TODO: Multi-line
	}

}

var jsCheckup = new JsCheckup();

// @TODO: Check window.onload vs document.onload
// @TODO: Use event listener instead of onload
document.onload = function() {
	jsCheckup.activate();
}
<commit_msg>Replace document.onload to window.onload<commit_after>/*
#
# img2musicXML.js - v0.1-Alpha
# Apache v2 License
#
*/

// Create img2musicXML (abbreviated as i2mx) namespace
var i2mx = i2mx || { };

// Create JsCheckup class (@TODO: Move to inside namespace)
var JsCheckup = function() {
	this.divClassName = "i2mx-checkup";

	this.activate = function() {
		var divList = document.getElementsByClassName(this.divClassName);

		// @TODO: Implement multiple divs support
		divList[0].innerHTML = "No checlist for now, but img2musicXML loaded successfully!"; // @TODO: Multi-line
	}

}

var jsCheckup = new JsCheckup();

// @TODO: Use event listener instead of onload
window.onload = function() {
	jsCheckup.activate();
}
<|endoftext|>


<commit_before>////////////////////
// Tickets getter //
////////////////////

'use strict';

module.exports = function (db) {
    return function (req, res) {
        res.json({
            'foo': 'bar'
        });
    };
};
<commit_msg>Such useless file<commit_after><|endoftext|>


<commit_before>import { ATTR_KEY } from '../constants';
import { isString, isFunction } from '../util';
import { isSameNodeType, isNamedNode } from './index';
import { isFunctionalComponent, buildFunctionalComponent } from './functional-component';
import { buildComponentFromVNode } from './component';
import { setAccessor } from '../dom/index';
import { createNode, collectNode } from '../dom/recycler';
import { unmountComponent } from './component';
import options from '../options';

/** Diff recursion count, used to track the end of the diff cycle. */
export const mounts = [];

/** Diff recursion count, used to track the end of the diff cycle. */
export let diffLevel = 0;

let isSvgMode = false;

let hydrating = false;

export function flushMounts() {
	let c;
	while ((c=mounts.pop())) {
		if (options.afterMount) options.afterMount(c);
		if (c.componentDidMount) c.componentDidMount();
	}
}

/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
 *	@param {Element} [dom=null]		A DOM node to mutate into the shape of the `vnode`
 *	@param {VNode} vnode			A VNode (with descendants forming a tree) representing the desired DOM structure
 *	@returns {Element} dom			The created/mutated element
 *	@private
 */
export function diff(dom, vnode, context, mountAll, parent, componentRoot) {
	if (!diffLevel++) {
		isSvgMode = parent instanceof SVGElement;
		hydrating = dom && !(ATTR_KEY in dom);
	}
	let ret = idiff(dom, vnode, context, mountAll);
	if (parent && ret.parentNode!==parent) parent.appendChild(ret);
	if (!--diffLevel) {
		hydrating = false;
		if (!componentRoot) flushMounts();
	}
	return ret;
}

function idiff(dom, vnode, context, mountAll) {
	let originalAttributes = vnode && vnode.attributes;

	while (isFunctionalComponent(vnode)) {
		vnode = buildFunctionalComponent(vnode, context);
	}

	if (vnode==null) vnode = '';

	if (isString(vnode)) {
		if (dom && dom instanceof Text) {
			if (dom.nodeValue!=vnode) {
				dom.nodeValue = vnode;
			}
		}
		else {
			if (dom) recollectNodeTree(dom);
			dom = document.createTextNode(vnode);
		}
		dom[ATTR_KEY] = true;
		return dom;

	}

	if (isFunction(vnode.nodeName)) {
		return buildComponentFromVNode(dom, vnode, context, mountAll);
	}

	let out = dom,
		nodeName = String(vnode.nodeName),
		prevSvgMode = isSvgMode,
		vchildren = vnode.children;

	isSvgMode = nodeName==='svg' ? true : nodeName==='foreignObject' ? false : isSvgMode;

	if (!dom) {
		out = createNode(nodeName, isSvgMode);
	}
	else if (!isNamedNode(dom, nodeName)) {
		out = createNode(nodeName, isSvgMode);
		// move children into the replacement node
		while (dom.firstChild) out.appendChild(dom.firstChild);
		// reclaim element nodes
		if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
		recollectNodeTree(dom);
	}

	let fc = out.firstChild,
		props = out[ATTR_KEY];
	if (!props) {
		out[ATTR_KEY] = props = {};
		for (let a=out.attributes, i=a.length; i--; ) props[a[i].name] = a[i].value;
	}

	diffAttributes(out, vnode.attributes, props);

	// fast-path for elements containing a single TextNode:
	if (!hydrating && vchildren && vchildren.length===1 && typeof vchildren[0]==='string' && fc instanceof Text && !fc.nextSibling) {
		if (fc.nodeValue!=vchildren[0]) {
			fc.nodeValue = vchildren[0];
		}
	}
	else if (vchildren && vchildren.length || fc) {
		innerDiffNode(out, vchildren, context, mountAll);
	}

	if (originalAttributes && typeof originalAttributes.ref==='function') {
		(props.ref = originalAttributes.ref)(out);
	}

	isSvgMode = prevSvgMode;

	return out;
}

/** Apply child and attribute changes between a VNode and a DOM Node to the DOM. */
function innerDiffNode(dom, vchildren, context, mountAll) {
	let originalChildren = dom.childNodes,
		children = [],
		keyed = {},
		keyedLen = 0,
		min = 0,
		len = originalChildren.length,
		childrenLen = 0,
		vlen = vchildren && vchildren.length,
		j, c, vchild, child;

	if (len) {
		for (let i=0; i<len; i++) {
			let child = originalChildren[i],
				props = child[ATTR_KEY],
				key = vlen ? ((c = child._component) ? c.__key : props ? props.key : null) : null;
			if (key!=null) {
				keyedLen++;
				keyed[key] = child;
			}
			else if (hydrating || props) {
				children[childrenLen++] = child;
			}
		}
	}

	if (vlen) {
		for (let i=0; i<vlen; i++) {
			vchild = vchildren[i];
			child = null;

			// if (isFunctionalComponent(vchild)) {
			// 	vchild = buildFunctionalComponent(vchild);
			// }

			// attempt to find a node based on key matching
			let key = vchild.key;
			if (key!=null) {
				if (keyedLen && key in keyed) {
					child = keyed[key];
					keyed[key] = undefined;
					keyedLen--;
				}
			}
			// attempt to pluck a node of the same type from the existing children
			else if (!child && min<childrenLen) {
				for (j=min; j<childrenLen; j++) {
					c = children[j];
					if (c && isSameNodeType(c, vchild)) {
						child = c;
						children[j] = undefined;
						if (j===childrenLen-1) childrenLen--;
						if (j===min) min++;
						break;
					}
				}
				if (!child && min<childrenLen && isFunction(vchild.nodeName) && mountAll) {
					child = children[min];
					children[min++] = undefined;
				}
			}

			// morph the matched/found/created DOM child to match vchild (deep)
			child = idiff(child, vchild, context, mountAll);

			if (child && child!==dom) {
				if (i>=len) {
					dom.appendChild(child);
				}
				else if (child!==originalChildren[i]) {
					dom.insertBefore(child, originalChildren[i] || null);
				}
			}
		}
	}

	if (keyedLen) {
		for (let i in keyed) if (keyed[i]) recollectNodeTree(keyed[i]);
	}

	// remove orphaned children
	if (min<childrenLen) {
		removeOrphanedChildren(children);
	}
}

/** Reclaim children that were unreferenced in the desired VTree */
export function removeOrphanedChildren(children, unmountOnly) {
	for (let i=children.length; i--; ) {
		if (children[i]) {
			recollectNodeTree(children[i], unmountOnly);
		}
	}
}

/** Reclaim an entire tree of nodes, starting at the root. */
export function recollectNodeTree(node, unmountOnly) {
	// @TODO: Need to make a call on whether Preact should remove nodes not created by itself.
	// Currently it *does* remove them. Discussion: https://github.com/developit/preact/issues/39
	//if (!node[ATTR_KEY]) return;

	let component = node._component;
	if (component) {
		unmountComponent(component, !unmountOnly);
	}
	else {
		if (node[ATTR_KEY] && node[ATTR_KEY].ref) node[ATTR_KEY].ref(null);

		if (!unmountOnly) {
			collectNode(node);
		}

		if (node.childNodes && node.childNodes.length) {
			removeOrphanedChildren(node.childNodes, unmountOnly);
		}
	}
}

/** Apply differences in attributes from a VNode to the given DOM Node. */
function diffAttributes(dom, attrs, old) {
	for (let name in old) {
		if (!(attrs && name in attrs) && old[name]!=null) {
			setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode);
		}
	}

	// new & updated
	if (attrs) {
		for (let name in attrs) {
			if (name!=='children' && name!=='innerHTML' && (!(name in old) || attrs[name]!==(name==='value' || name==='checked' ? dom[name] : old[name]))) {
				setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
			}
		}
	}
}
<commit_msg>Fix diff reflow when removing leading element. Fixes #394<commit_after>import { ATTR_KEY } from '../constants';
import { isString, isFunction } from '../util';
import { isSameNodeType, isNamedNode } from './index';
import { isFunctionalComponent, buildFunctionalComponent } from './functional-component';
import { buildComponentFromVNode } from './component';
import { setAccessor, removeNode } from '../dom/index';
import { createNode, collectNode } from '../dom/recycler';
import { unmountComponent } from './component';
import options from '../options';

/** Diff recursion count, used to track the end of the diff cycle. */
export const mounts = [];

/** Diff recursion count, used to track the end of the diff cycle. */
export let diffLevel = 0;

let isSvgMode = false;

let hydrating = false;

export function flushMounts() {
	let c;
	while ((c=mounts.pop())) {
		if (options.afterMount) options.afterMount(c);
		if (c.componentDidMount) c.componentDidMount();
	}
}

/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
 *	@param {Element} [dom=null]		A DOM node to mutate into the shape of the `vnode`
 *	@param {VNode} vnode			A VNode (with descendants forming a tree) representing the desired DOM structure
 *	@returns {Element} dom			The created/mutated element
 *	@private
 */
export function diff(dom, vnode, context, mountAll, parent, componentRoot) {
	if (!diffLevel++) {
		isSvgMode = parent instanceof SVGElement;
		hydrating = dom && !(ATTR_KEY in dom);
	}
	let ret = idiff(dom, vnode, context, mountAll);
	if (parent && ret.parentNode!==parent) parent.appendChild(ret);
	if (!--diffLevel) {
		hydrating = false;
		if (!componentRoot) flushMounts();
	}
	return ret;
}

function idiff(dom, vnode, context, mountAll) {
	let originalAttributes = vnode && vnode.attributes;

	while (isFunctionalComponent(vnode)) {
		vnode = buildFunctionalComponent(vnode, context);
	}

	if (vnode==null) vnode = '';

	if (isString(vnode)) {
		if (dom && dom instanceof Text) {
			if (dom.nodeValue!=vnode) {
				dom.nodeValue = vnode;
			}
		}
		else {
			if (dom) recollectNodeTree(dom);
			dom = document.createTextNode(vnode);
		}
		dom[ATTR_KEY] = true;
		return dom;

	}

	if (isFunction(vnode.nodeName)) {
		return buildComponentFromVNode(dom, vnode, context, mountAll);
	}

	let out = dom,
		nodeName = String(vnode.nodeName),
		prevSvgMode = isSvgMode,
		vchildren = vnode.children;

	isSvgMode = nodeName==='svg' ? true : nodeName==='foreignObject' ? false : isSvgMode;

	if (!dom) {
		out = createNode(nodeName, isSvgMode);
	}
	else if (!isNamedNode(dom, nodeName)) {
		out = createNode(nodeName, isSvgMode);
		// move children into the replacement node
		while (dom.firstChild) out.appendChild(dom.firstChild);
		// reclaim element nodes
		if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
		recollectNodeTree(dom);
	}

	let fc = out.firstChild,
		props = out[ATTR_KEY];
	if (!props) {
		out[ATTR_KEY] = props = {};
		for (let a=out.attributes, i=a.length; i--; ) props[a[i].name] = a[i].value;
	}

	diffAttributes(out, vnode.attributes, props);

	// fast-path for elements containing a single TextNode:
	if (!hydrating && vchildren && vchildren.length===1 && typeof vchildren[0]==='string' && fc instanceof Text && !fc.nextSibling) {
		if (fc.nodeValue!=vchildren[0]) {
			fc.nodeValue = vchildren[0];
		}
	}
	else if (vchildren && vchildren.length || fc) {
		innerDiffNode(out, vchildren, context, mountAll);
	}

	if (originalAttributes && typeof originalAttributes.ref==='function') {
		(props.ref = originalAttributes.ref)(out);
	}

	isSvgMode = prevSvgMode;

	return out;
}

/** Apply child and attribute changes between a VNode and a DOM Node to the DOM. */
function innerDiffNode(dom, vchildren, context, mountAll) {
	let originalChildren = dom.childNodes,
		children = [],
		keyed = {},
		keyedLen = 0,
		min = 0,
		len = originalChildren.length,
		childrenLen = 0,
		vlen = vchildren && vchildren.length,
		j, c, vchild, child;

	if (len) {
		for (let i=0; i<len; i++) {
			let child = originalChildren[i],
				props = child[ATTR_KEY],
				key = vlen ? ((c = child._component) ? c.__key : props ? props.key : null) : null;
			if (key!=null) {
				keyedLen++;
				keyed[key] = child;
			}
			else if (hydrating || props) {
				children[childrenLen++] = child;
			}
		}
	}

	if (vlen) {
		for (let i=0; i<vlen; i++) {
			vchild = vchildren[i];
			child = null;

			// if (isFunctionalComponent(vchild)) {
			// 	vchild = buildFunctionalComponent(vchild);
			// }

			// attempt to find a node based on key matching
			let key = vchild.key;
			if (key!=null) {
				if (keyedLen && key in keyed) {
					child = keyed[key];
					keyed[key] = undefined;
					keyedLen--;
				}
			}
			// attempt to pluck a node of the same type from the existing children
			else if (!child && min<childrenLen) {
				for (j=min; j<childrenLen; j++) {
					c = children[j];
					if (c && isSameNodeType(c, vchild)) {
						child = c;
						children[j] = undefined;
						if (j===childrenLen-1) childrenLen--;
						if (j===min) min++;
						break;
					}
				}
				if (!child && min<childrenLen && isFunction(vchild.nodeName) && mountAll) {
					child = children[min];
					children[min++] = undefined;
				}
			}

			// morph the matched/found/created DOM child to match vchild (deep)
			child = idiff(child, vchild, context, mountAll);

			if (child && child!==dom) {
				if (i>=len) {
					dom.appendChild(child);
				}
				else if (child!==originalChildren[i]) {
					if (child===originalChildren[i+1]) {
						removeNode(originalChildren[i]);
					}
					dom.insertBefore(child, originalChildren[i] || null);
				}
			}
		}
	}

	if (keyedLen) {
		for (let i in keyed) if (keyed[i]) recollectNodeTree(keyed[i]);
	}

	// remove orphaned children
	if (min<childrenLen) {
		removeOrphanedChildren(children);
	}
}

/** Reclaim children that were unreferenced in the desired VTree */
export function removeOrphanedChildren(children, unmountOnly) {
	for (let i=children.length; i--; ) {
		if (children[i]) {
			recollectNodeTree(children[i], unmountOnly);
		}
	}
}

/** Reclaim an entire tree of nodes, starting at the root. */
export function recollectNodeTree(node, unmountOnly) {
	// @TODO: Need to make a call on whether Preact should remove nodes not created by itself.
	// Currently it *does* remove them. Discussion: https://github.com/developit/preact/issues/39
	//if (!node[ATTR_KEY]) return;

	let component = node._component;
	if (component) {
		unmountComponent(component, !unmountOnly);
	}
	else {
		if (node[ATTR_KEY] && node[ATTR_KEY].ref) node[ATTR_KEY].ref(null);

		if (!unmountOnly) {
			collectNode(node);
		}

		if (node.childNodes && node.childNodes.length) {
			removeOrphanedChildren(node.childNodes, unmountOnly);
		}
	}
}

/** Apply differences in attributes from a VNode to the given DOM Node. */
function diffAttributes(dom, attrs, old) {
	for (let name in old) {
		if (!(attrs && name in attrs) && old[name]!=null) {
			setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode);
		}
	}

	// new & updated
	if (attrs) {
		for (let name in attrs) {
			if (name!=='children' && name!=='innerHTML' && (!(name in old) || attrs[name]!==(name==='value' || name==='checked' ? dom[name] : old[name]))) {
				setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
			}
		}
	}
}
<|endoftext|>


<commit_before>/* A screen to view and edit transect details */

// Get transectID from calling window
var args = arguments[0];
var transectID = args.transectID;

// Create stake orientation labels (Fixes Issue #13)
var stakeBarLabels = [
	{title:"Top Left / Bottom Right", enabled:false},
	{title:"Top Right / Bottom Left", enabled:false}
];
$.stakeBar.labels = stakeBarLabels;

// Query the database and store values associated with a transectID
try {
	var db = Ti.Database.open('ltemaDB');

	resultRow = db.execute(	'SELECT transect_id, transect_name, surveyor, plot_distance, stake_orientation, comments \
							FROM transect t \
							WHERE transect_id = ?', transectID);

	var transectName = resultRow.fieldByName('transect_name');
	var surveyor = resultRow.fieldByName('surveyor');
	var plotDistance = resultRow.fieldByName('plot_distance');
	var stakeOrientation = resultRow.fieldByName('stake_orientation');
	var comments = resultRow.fieldByName('comments');

	//Assign editable TextField values
	$.transectName.value = transectName;
	$.surveyor.value = surveyor;
	$.plotDistance.value = plotDistance;
	$.comments.value = comments;

	//TODO: perhaps an ENUM or CONSTANT would be useful here
	if (stakeOrientation === "Top Left / Bottom Right") {
		$.stakeBar.index = 0;
	} else if (stakeOrientation === "Top Right / Bottom Left") {
		$.stakeBar.index = 1;
	} else {
		alert('invalid stakeOrientation value');
	}
} catch (e) {
	alert ('DEV ALERT - transectsModal try/catch failed');
} finally {
	resultRow.close();
	db.close();
}

// Initially disable input fields
$.transectName.editable = false;
$.surveyor.editable = false;
$.plotDistance.editable = false;
$.comments.editable = false;

/* Listeners */

//TODO: Confirm all conditions with project specs, project sponsor
// When an input field loses focus check for errors
$.transectName.addEventListener('blur', function(e) {
	if ($.transectName.value.length < 2) {
		$.transectError.visible = true;
		$.transectError.text = "Transect name should be at least 2 characters";
	} else {
		$.transectError.visible = false;
	}
});
$.surveyor.addEventListener('blur', function(e) {
	if ($.surveyor.value.length < 2) {
		$.surveyorError.visible = true;
		$.surveyorError.text = "Surveyor should have at least 2 characters";
	} else {
		$.surveyorError.visible = false;
	}
});
$.plotDistance.addEventListener('blur', function(e) {
	if ($.plotDistance.value < 1) {
		$.plotDistanceError.visible = true;
		$.plotDistanceError.text = "Plot distance should be at least 1 meter";
	} else if ($.plotDistance.value > 50) {
		$.plotDistanceError.visible = true;
		$.plotDistanceError.text = "Plot distance should be at most 50 meters";
	} else {
		$.plotDistanceError.visible = false;
	}
});

$.stakeBar.addEventListener('blur', function(e) {
	//TODO
});

$.comments.addEventListener('blur', function(e) {
	//TODO
});

// Replace bad input (non-numbers) on plotDistance TextField
$.plotDistance.addEventListener('change', function(e) {
	e.source.value = e.source.value.replace(/[^0-9]+/,"");
});

// TESTING - an example of restricting the keyboard input
//Listen and replace bad input on transectName
//$.transectName.addEventListener('change', function (e) {
//	e.source.value = e.source.value.replace(/[^0-9a-zA-Z ()_,.-]/,"");
//});

/* Functions */

//swaps editable property of fields
function editBtnClick(e){
	//enable or disable edit mode
    if (e.source.title == "Edit") {
    	$.modalWin.editing = true;
        e.source.title = "Done";

        //Enable editing
        $.transectName.editable = true;
		$.surveyor.editable = true;
		$.plotDistance.editable = true;
		stakeBarLabels[0].enabled = true;
		stakeBarLabels[1].enabled = true;
		$.stakeBar.labels = stakeBarLabels;
		$.comments.editable = true;

        //disable the button button during edit mode
        $.backBtn.enabled = false;

    } else { //title is "Done"
    	//fire error-checking listeners
    	$.transectName.blur();
    	$.surveyor.blur();
    	$.plotDistance.blur();
   		if (($.transectError.visible == true)||($.surveyorError.visible == true)||($.plotDistanceError.visible == true)) {
   			return;
   		}

        $.modalWin.editing = false;
        e.source.title = "Edit";
        //enable the back button
        $.backBtn.enabled = true;

        //disable editing
        $.transectName.editable = false;
		$.surveyor.editable = false;
		$.plotDistance.editable = false;
		stakeBarLabels[0].enabled = false;
		stakeBarLabels[1].enabled = false;
		$.stakeBar.labels = stakeBarLabels;
		$.comments.editable = false;

		saveEdit();
    }
}

//Save changes to transect
function saveEdit(){
	try {
		var db = Ti.Database.open('ltemaDB');
		db.execute( 'UPDATE OR FAIL transect SET transect_name= ?, surveyor= ?, plot_distance= ?, comments= ? WHERE transect_id= ?',
					$.transectName.value, $.surveyor.value, $.plotDistance.value, $.comments.value, transectID);
	} catch (e){
		alert ('DEV ALERT: transectsModal saveEdit() catch');
	} finally {
		db.close();
	}

}

//Navigate back
function backBtnClick(){
	Ti.App.fireEvent("app:refreshTransects");
	$.modalNav.close();
}<commit_msg>saves updated stake orientation<commit_after>/* A screen to view and edit transect details */

// Get transectID from calling window
var args = arguments[0];
var transectID = args.transectID;

// Create stake orientation labels (Fixes Issue #13)
var stakeBarLabels = [
	{title:"Top Left / Bottom Right", enabled:false},
	{title:"Top Right / Bottom Left", enabled:false}
];
$.stakeBar.labels = stakeBarLabels;

// Query the database and store values associated with a transectID
try {
	var db = Ti.Database.open('ltemaDB');

	resultRow = db.execute(	'SELECT transect_id, transect_name, surveyor, plot_distance, stake_orientation, comments \
							FROM transect t \
							WHERE transect_id = ?', transectID);

	var transectName = resultRow.fieldByName('transect_name');
	var surveyor = resultRow.fieldByName('surveyor');
	var plotDistance = resultRow.fieldByName('plot_distance');
	var stakeOrientation = resultRow.fieldByName('stake_orientation');
	var comments = resultRow.fieldByName('comments');

	//Assign editable TextField values
	$.transectName.value = transectName;
	$.surveyor.value = surveyor;
	$.plotDistance.value = plotDistance;
	$.comments.value = comments;

	//TODO: perhaps an ENUM or CONSTANT would be useful here
	if (stakeOrientation === "Top Left / Bottom Right") {
		$.stakeBar.index = 0;
	} else if (stakeOrientation === "Top Right / Bottom Left") {
		$.stakeBar.index = 1;
	} else {
		alert('invalid stakeOrientation value');
	}
} catch (e) {
	alert ('DEV ALERT - transectsModal try/catch failed');
} finally {
	resultRow.close();
	db.close();
}

// Initially disable input fields
$.transectName.editable = false;
$.surveyor.editable = false;
$.plotDistance.editable = false;
$.comments.editable = false;

/* Listeners */

//TODO: Confirm all conditions with project specs, project sponsor
// When an input field loses focus check for errors
$.transectName.addEventListener('blur', function(e) {
	if ($.transectName.value.length < 2) {
		$.transectError.visible = true;
		$.transectError.text = "Transect name should be at least 2 characters";
	} else {
		$.transectError.visible = false;
	}
});
$.surveyor.addEventListener('blur', function(e) {
	if ($.surveyor.value.length < 2) {
		$.surveyorError.visible = true;
		$.surveyorError.text = "Surveyor should have at least 2 characters";
	} else {
		$.surveyorError.visible = false;
	}
});
$.plotDistance.addEventListener('blur', function(e) {
	if ($.plotDistance.value < 1) {
		$.plotDistanceError.visible = true;
		$.plotDistanceError.text = "Plot distance should be at least 1 meter";
	} else if ($.plotDistance.value > 50) {
		$.plotDistanceError.visible = true;
		$.plotDistanceError.text = "Plot distance should be at most 50 meters";
	} else {
		$.plotDistanceError.visible = false;
	}
});

$.stakeBar.addEventListener('blur', function(e) {
	//TODO
});

$.comments.addEventListener('blur', function(e) {
	//TODO
});

// Replace bad input (non-numbers) on plotDistance TextField
$.plotDistance.addEventListener('change', function(e) {
	e.source.value = e.source.value.replace(/[^0-9]+/,"");
});

// TESTING - an example of restricting the keyboard input
//Listen and replace bad input on transectName
//$.transectName.addEventListener('change', function (e) {
//	e.source.value = e.source.value.replace(/[^0-9a-zA-Z ()_,.-]/,"");
//});

/* Functions */

//swaps editable property of fields
function editBtnClick(e){
	//enable or disable edit mode
    if (e.source.title == "Edit") {
    	$.modalWin.editing = true;
        e.source.title = "Done";

        //Enable editing
        $.transectName.editable = true;
		$.surveyor.editable = true;
		$.plotDistance.editable = true;
		stakeBarLabels[0].enabled = true;
		stakeBarLabels[1].enabled = true;
		$.stakeBar.labels = stakeBarLabels;
		$.comments.editable = true;

        //disable the button button during edit mode
        $.backBtn.enabled = false;

    } else { //title is "Done"
    	//fire error-checking listeners
    	$.transectName.blur();
    	$.surveyor.blur();
    	$.plotDistance.blur();
   		if (($.transectError.visible == true)||($.surveyorError.visible == true)||($.plotDistanceError.visible == true)) {
   			return;
   		}

        $.modalWin.editing = false;
        e.source.title = "Edit";
        //enable the back button
        $.backBtn.enabled = true;

        //disable editing
        $.transectName.editable = false;
		$.surveyor.editable = false;
		$.plotDistance.editable = false;
		stakeBarLabels[0].enabled = false;
		stakeBarLabels[1].enabled = false;
		$.stakeBar.labels = stakeBarLabels;
		$.comments.editable = false;

		saveEdit();
    }
}

//Save changes to transect
function saveEdit(){
	try {
		var db = Ti.Database.open('ltemaDB');
		db.execute( 'UPDATE OR FAIL transect SET transect_name= ?, surveyor= ?, plot_distance= ?, stake_orientation= ?, comments= ? WHERE transect_id= ?',
					$.transectName.value, $.surveyor.value, $.plotDistance.value, stakeBarLabels[$.stakeBar.index].title, $.comments.value, transectID);
	} catch (e){
		alert ('DEV ALERT: transectsModal saveEdit() catch');
	} finally {
		db.close();
	}

}

//Navigate back
function backBtnClick(){
	Ti.App.fireEvent("app:refreshTransects");
	$.modalNav.close();
}<|endoftext|>


<commit_before>var baseKarma = require('./base-karma')

module.exports = function(config) {

  var baseConfig = baseKarma(config);

  config.set(Object.assign(baseConfig, {
    browsers: [
      'bs_firefox_android',
      'bs_chrome_mac',
    ],
    reporters: [
      'mocha', 'BrowserStack',
    ],
    client: {
      mocha: {
        reporter: 'html',
      }
    },
    browserStack: {
      startTunnel: true
    },
    customLaunchers: {
      bs_firefox_android: {
        base: 'BrowserStack',
        browser: 'Android Browser',
        real_mobile: true,
        device: 'Samsung Galaxy S8',
        os: 'android',
        os_version: '7.0',
      },
      bs_chrome_mac: {
        base: 'BrowserStack',
        browser: 'Chrome',
        browser_version: '66',
        os: 'OS X',
        os_version: 'High Sierra',
      },
    },
  }));

};
<commit_msg>Configure BrowserStack testing on IE 11 and Edge<commit_after>var baseKarma = require('./base-karma')

module.exports = function(config) {

  var baseConfig = baseKarma(config);

  config.set(Object.assign(baseConfig, {
    browsers: [
      'bs_firefox_android',
      'bs_chrome_mac',
      'bs_ie_11',
      'bs_edge',
    ],
    reporters: [
      'mocha', 'BrowserStack',
    ],
    client: {
      mocha: {
        reporter: 'html',
      }
    },
    browserStack: {
      startTunnel: true
    },
    customLaunchers: {
      bs_firefox_android: {
        base: 'BrowserStack',
        browser: 'Android Browser',
        real_mobile: true,
        device: 'Samsung Galaxy S8',
        os: 'android',
        os_version: '7.0',
      },
      bs_chrome_mac: {
        base: 'BrowserStack',
        browser: 'Chrome',
        browser_version: '66',
        os: 'OS X',
        os_version: 'High Sierra',
      },
      bs_ie_11: {
        base: 'BrowserStack',
        browser: 'IE',
        browser_version: '11',
        os: 'Windows',
        os_version: '7',
      },
      bs_edge: {
        base: 'BrowserStack',
        browser: 'Edge',
        browser_version: '16',
        os: 'Windows',
        os_version: '10',
      },
    },
  }));

};
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var redis = require('redis');

/**
 * Setting up redis clients.
 */

var songsclient = redis.createClient(
  process.env.SONGS_DB_PORT || 6379,
  process.env.SONGS_DB_HOST || '127.0.0.1'
);
var usersclient = redis.createClient(
  process.env.USERS_DB_PORT || 6379,
  process.env.USERS_DB_HOST || '127.0.0.1'
);

if (process.env.NODE_ENV === 'production') {
  songsclient.auth(process.env.SONGS_DB_AUTH);
  usersclient.auth(process.env.USERS_DB_AUTH);
}

songsclient.on('error', function(err) {
  console.error(err.message);
});

usersclient.on('error', function(err) {
  console.error(err.message);
});

/**
 * Expose the clients
 */

exports.songs = songsclient;
exports.users = usersclient;
<commit_msg>changed the configuration of the redis clients<commit_after>/**
 * Module dependencies.
 */

var redis = require('redis');

/**
 * Setting up redis clients.
 */

var songsclient = redis.createClient({ auth_pass: process.env.DB_AUTH })
  , usersclient = redis.createClient({ auth_pass: process.env.DB_AUTH });

songsclient.on('error', function(err) {
  console.error(err.message);
});

usersclient.on('error', function(err) {
  console.error(err.message);
});

usersclient.select(1);

/**
 * Expose the clients
 */

exports.songs = songsclient;
exports.users = usersclient;
<|endoftext|>


<commit_before>import { ATTR_KEY } from '../constants';
import { isString, isFunction } from '../util';
import { isSameNodeType, isNamedNode } from './index';
import { isFunctionalComponent, buildFunctionalComponent } from './functional-component';
import { buildComponentFromVNode } from './component';
import { setAccessor, removeNode } from '../dom/index';
import { createNode, collectNode } from '../dom/recycler';
import { unmountComponent } from './component';
import options from '../options';

/** Queue of components that have been mounted and are awaiting componentDidMount */
export const mounts = [];

/** Diff recursion count, used to track the end of the diff cycle. */
export let diffLevel = 0;

/** Global flag indicating if the diff is currently within an SVG */
let isSvgMode = false;

/** Global flag indicating if the diff is performing hydration */
let hydrating = false;

/** Invoke queued componentDidMount lifecycle methods */
export function flushMounts() {
	let c;
	while ((c=mounts.pop())) {
		if (options.afterMount) options.afterMount(c);
		if (c.componentDidMount) c.componentDidMount();
	}
}

/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
 *	@param {Element} [dom=null]		A DOM node to mutate into the shape of the `vnode`
 *	@param {VNode} vnode			A VNode (with descendants forming a tree) representing the desired DOM structure
 *	@returns {Element} dom			The created/mutated element
 *	@private
 */
export function diff(dom, vnode, context, mountAll, parent, componentRoot) {
	// diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
	if (!diffLevel++) {
		// when first starting the diff, check if we're diffing an SVG or within an SVG
		isSvgMode = parent instanceof SVGElement;

		// hydration is inidicated by the existing element to be diffed not having a prop cache
		hydrating = dom && !(ATTR_KEY in dom);
	}

	let ret = idiff(dom, vnode, context, mountAll);

	// append the element if its a new parent
	if (parent && ret.parentNode!==parent) parent.appendChild(ret);

	// diffLevel being reduced to 0 means we're exiting the diff
	if (!--diffLevel) {
		hydrating = false;
		// invoke queued componentDidMount lifecycle methods
		if (!componentRoot) flushMounts();
	}

	return ret;
}

function idiff(dom, vnode, context, mountAll) {
	let originalAttributes = vnode && vnode.attributes;

	// Resolve ephemeral Pure Functional Components
	while (isFunctionalComponent(vnode)) {
		vnode = buildFunctionalComponent(vnode, context);
	}

	// empty values (null & undefined) render as empty Text nodes
	if (vnode==null) vnode = '';

	// Fast case: Strings create/update Text nodes.
	if (isString(vnode)) {
		// update if it's already a Text node
		if (dom && dom instanceof Text) {
			if (dom.nodeValue!=vnode) {
				dom.nodeValue = vnode;
			}
		}
		else {
			// it wasn't a Text node: replace it with one and recycle the old Element
			if (dom) recollectNodeTree(dom);
			dom = document.createTextNode(vnode);
		}

		// Mark for non-hydration updates
		dom[ATTR_KEY] = true;
		return dom;
	}

	// If the VNode represents a Component, perform a component diff.
	if (isFunction(vnode.nodeName)) {
		return buildComponentFromVNode(dom, vnode, context, mountAll);
	}

	let out = dom,
		nodeName = String(vnode.nodeName),	// @TODO this masks undefined component errors as `<undefined>`
		prevSvgMode = isSvgMode,
		vchildren = vnode.children;

	// SVGs have special namespace stuff.
	// This tracks entering and exiting that namespace when descending through the tree.
	isSvgMode = nodeName==='svg' ? true : nodeName==='foreignObject' ? false : isSvgMode;

	if (!dom) {
		// case: we had no element to begin with
		// - create an element with the nodeName from VNode
		out = createNode(nodeName, isSvgMode);
	}
	else if (!isNamedNode(dom, nodeName)) {
		// case: Element and VNode had different nodeNames
		// - need to create the correct Element to match VNode
		// - then migrate children from old to new

		out = createNode(nodeName, isSvgMode);

		// move children into the replacement node
		while (dom.firstChild) out.appendChild(dom.firstChild);

		// if the previous Element was mounted into the DOM, replace it inline
		if (dom.parentNode) dom.parentNode.replaceChild(out, dom);

		// recycle the old element (skips non-Element node types)
		recollectNodeTree(dom);
	}

	let fc = out.firstChild,
		props = out[ATTR_KEY];

	// Attribute Hydration: if there is no prop cache on the element,
	// ...create it and populate it with the element's attributes.
	if (!props) {
		out[ATTR_KEY] = props = {};
		for (let a=out.attributes, i=a.length; i--; ) props[a[i].name] = a[i].value;
	}

	// Apply attributes/props from VNode to the DOM Element:
	diffAttributes(out, vnode.attributes, props);

	// Optimization: fast-path for elements containing a single TextNode:
	if (!hydrating && vchildren && vchildren.length===1 && typeof vchildren[0]==='string' && fc && fc instanceof Text && !fc.nextSibling) {
		if (fc.nodeValue!=vchildren[0]) {
			fc.nodeValue = vchildren[0];
		}
	}
	// otherwise, if there are existing or new children, diff them:
	else if (vchildren && vchildren.length || fc) {
		innerDiffNode(out, vchildren, context, mountAll);
	}

	// invoke original ref (from before resolving Pure Functional Components):
	if (originalAttributes && typeof originalAttributes.ref==='function') {
		(props.ref = originalAttributes.ref)(out);
	}

	isSvgMode = prevSvgMode;

	return out;
}

/** Apply child and attribute changes between a VNode and a DOM Node to the DOM.
 *	@param {Element} dom		Element whose children should be compared & mutated
 *	@param {Array} vchildren	Array of VNodes to compare to `dom.childNodes`
 *	@param {Object} context		Implicitly descendant context object (from most recent `getChildContext()`)
 *	@param {Boolean} mountAll
 */
function innerDiffNode(dom, vchildren, context, mountAll) {
	let originalChildren = dom.childNodes,
		children = [],
		keyed = {},
		keyedLen = 0,
		min = 0,
		len = originalChildren.length,
		childrenLen = 0,
		vlen = vchildren && vchildren.length,
		j, c, vchild, child;

	if (len) {
		for (let i=0; i<len; i++) {
			let child = originalChildren[i],
				props = child[ATTR_KEY],
				key = vlen ? ((c = child._component) ? c.__key : props ? props.key : null) : null;
			if (key!=null) {
				keyedLen++;
				keyed[key] = child;
			}
			else if (hydrating || props) {
				children[childrenLen++] = child;
			}
		}
	}

	if (vlen) {
		for (let i=0; i<vlen; i++) {
			vchild = vchildren[i];
			child = null;

			// if (isFunctionalComponent(vchild)) {
			// 	vchild = buildFunctionalComponent(vchild);
			// }

			// attempt to find a node based on key matching
			let key = vchild.key;
			if (key!=null) {
				if (keyedLen && key in keyed) {
					child = keyed[key];
					keyed[key] = undefined;
					keyedLen--;
				}
			}
			// attempt to pluck a node of the same type from the existing children
			else if (!child && min<childrenLen) {
				for (j=min; j<childrenLen; j++) {
					c = children[j];
					if (c && isSameNodeType(c, vchild)) {
						child = c;
						children[j] = undefined;
						if (j===childrenLen-1) childrenLen--;
						if (j===min) min++;
						break;
					}
				}
			}

			// morph the matched/found/created DOM child to match vchild (deep)
			child = idiff(child, vchild, context, mountAll);

			if (child && child!==dom) {
				if (i>=len) {
					dom.appendChild(child);
				}
				else if (child!==originalChildren[i]) {
					if (child===originalChildren[i+1]) {
						removeNode(originalChildren[i]);
					}
					dom.insertBefore(child, originalChildren[i] || null);
				}
			}
		}
	}

	if (keyedLen) {
		for (let i in keyed) if (keyed[i]) recollectNodeTree(keyed[i]);
	}

	// remove orphaned children
	while (min<=childrenLen) {
		child = children[childrenLen--];
		if (child) recollectNodeTree(child);
	}
}

/** Recursively recycle (or just unmount) a node an its descendants.
 *	@param {Node} node						DOM node to start unmount/removal from
 *	@param {Boolean} [unmountOnly=false]	If `true`, only triggers unmount lifecycle, skips removal
 */
export function recollectNodeTree(node, unmountOnly) {
	let component = node._component;
	if (component) {
		// if node is owned by a Component, unmount that component (ends up recursing back here)
		unmountComponent(component, !unmountOnly);
	}
	else {
		// If the node's VNode had a ref function, invoke it with null here.
		// (this is part of the React spec, and smart for unsetting references)
		if (node[ATTR_KEY] && node[ATTR_KEY].ref) node[ATTR_KEY].ref(null);

		if (!unmountOnly) {
			collectNode(node);
		}

		// Recollect/unmount all children.
		// - we use .lastChild here because it causes less reflow than .firstChild
		// - it's also cheaper than accessing the .childNodes Live NodeList
		let c;
		while ((c=node.lastChild)) recollectNodeTree(c, unmountOnly);
	}
}

/** Apply differences in attributes from a VNode to the given DOM Element.
 *	@param {Element} dom		Element with attributes to diff `attrs` against
 *	@param {Object} attrs		The desired end-state key-value attribute pairs
 *	@param {Object} old			Current/previous attributes (from previous VNode or element's prop cache)
 */
function diffAttributes(dom, attrs, old) {
	// remove attributes no longer present on the vnode by setting them to undefined
	for (let name in old) {
		if (!(attrs && name in attrs) && old[name]!=null) {
			setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode);
		}
	}

	// add new & update changed attributes
	if (attrs) {
		for (let name in attrs) {
			if (name!=='children' && name!=='innerHTML' && (!(name in old) || attrs[name]!==(name==='value' || name==='checked' ? dom[name] : old[name]))) {
				setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
			}
		}
	}
}
<commit_msg>Only save ref from original attributes.<commit_after>import { ATTR_KEY } from '../constants';
import { isString, isFunction } from '../util';
import { isSameNodeType, isNamedNode } from './index';
import { isFunctionalComponent, buildFunctionalComponent } from './functional-component';
import { buildComponentFromVNode } from './component';
import { setAccessor, removeNode } from '../dom/index';
import { createNode, collectNode } from '../dom/recycler';
import { unmountComponent } from './component';
import options from '../options';

/** Queue of components that have been mounted and are awaiting componentDidMount */
export const mounts = [];

/** Diff recursion count, used to track the end of the diff cycle. */
export let diffLevel = 0;

/** Global flag indicating if the diff is currently within an SVG */
let isSvgMode = false;

/** Global flag indicating if the diff is performing hydration */
let hydrating = false;

/** Invoke queued componentDidMount lifecycle methods */
export function flushMounts() {
	let c;
	while ((c=mounts.pop())) {
		if (options.afterMount) options.afterMount(c);
		if (c.componentDidMount) c.componentDidMount();
	}
}

/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
 *	@param {Element} [dom=null]		A DOM node to mutate into the shape of the `vnode`
 *	@param {VNode} vnode			A VNode (with descendants forming a tree) representing the desired DOM structure
 *	@returns {Element} dom			The created/mutated element
 *	@private
 */
export function diff(dom, vnode, context, mountAll, parent, componentRoot) {
	// diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
	if (!diffLevel++) {
		// when first starting the diff, check if we're diffing an SVG or within an SVG
		isSvgMode = parent instanceof SVGElement;

		// hydration is inidicated by the existing element to be diffed not having a prop cache
		hydrating = dom && !(ATTR_KEY in dom);
	}

	let ret = idiff(dom, vnode, context, mountAll);

	// append the element if its a new parent
	if (parent && ret.parentNode!==parent) parent.appendChild(ret);

	// diffLevel being reduced to 0 means we're exiting the diff
	if (!--diffLevel) {
		hydrating = false;
		// invoke queued componentDidMount lifecycle methods
		if (!componentRoot) flushMounts();
	}

	return ret;
}

function idiff(dom, vnode, context, mountAll) {
	let ref = vnode && vnode.attributes && vnode.attributes.ref;

	// Resolve ephemeral Pure Functional Components
	while (isFunctionalComponent(vnode)) {
		vnode = buildFunctionalComponent(vnode, context);
	}

	// empty values (null & undefined) render as empty Text nodes
	if (vnode==null) vnode = '';

	// Fast case: Strings create/update Text nodes.
	if (isString(vnode)) {
		// update if it's already a Text node
		if (dom && dom instanceof Text) {
			if (dom.nodeValue!=vnode) {
				dom.nodeValue = vnode;
			}
		}
		else {
			// it wasn't a Text node: replace it with one and recycle the old Element
			if (dom) recollectNodeTree(dom);
			dom = document.createTextNode(vnode);
		}

		// Mark for non-hydration updates
		dom[ATTR_KEY] = true;
		return dom;
	}

	// If the VNode represents a Component, perform a component diff.
	if (isFunction(vnode.nodeName)) {
		return buildComponentFromVNode(dom, vnode, context, mountAll);
	}

	let out = dom,
		nodeName = String(vnode.nodeName),	// @TODO this masks undefined component errors as `<undefined>`
		prevSvgMode = isSvgMode,
		vchildren = vnode.children;

	// SVGs have special namespace stuff.
	// This tracks entering and exiting that namespace when descending through the tree.
	isSvgMode = nodeName==='svg' ? true : nodeName==='foreignObject' ? false : isSvgMode;

	if (!dom) {
		// case: we had no element to begin with
		// - create an element with the nodeName from VNode
		out = createNode(nodeName, isSvgMode);
	}
	else if (!isNamedNode(dom, nodeName)) {
		// case: Element and VNode had different nodeNames
		// - need to create the correct Element to match VNode
		// - then migrate children from old to new

		out = createNode(nodeName, isSvgMode);

		// move children into the replacement node
		while (dom.firstChild) out.appendChild(dom.firstChild);

		// if the previous Element was mounted into the DOM, replace it inline
		if (dom.parentNode) dom.parentNode.replaceChild(out, dom);

		// recycle the old element (skips non-Element node types)
		recollectNodeTree(dom);
	}

	let fc = out.firstChild,
		props = out[ATTR_KEY];

	// Attribute Hydration: if there is no prop cache on the element,
	// ...create it and populate it with the element's attributes.
	if (!props) {
		out[ATTR_KEY] = props = {};
		for (let a=out.attributes, i=a.length; i--; ) props[a[i].name] = a[i].value;
	}

	// Apply attributes/props from VNode to the DOM Element:
	diffAttributes(out, vnode.attributes, props);

	// Optimization: fast-path for elements containing a single TextNode:
	if (!hydrating && vchildren && vchildren.length===1 && typeof vchildren[0]==='string' && fc && fc instanceof Text && !fc.nextSibling) {
		if (fc.nodeValue!=vchildren[0]) {
			fc.nodeValue = vchildren[0];
		}
	}
	// otherwise, if there are existing or new children, diff them:
	else if (vchildren && vchildren.length || fc) {
		innerDiffNode(out, vchildren, context, mountAll);
	}

	// invoke original ref (from before resolving Pure Functional Components):
	if (typeof ref==='function') {
		(props.ref = ref)(out);
	}

	isSvgMode = prevSvgMode;

	return out;
}

/** Apply child and attribute changes between a VNode and a DOM Node to the DOM.
 *	@param {Element} dom		Element whose children should be compared & mutated
 *	@param {Array} vchildren	Array of VNodes to compare to `dom.childNodes`
 *	@param {Object} context		Implicitly descendant context object (from most recent `getChildContext()`)
 *	@param {Boolean} mountAll
 */
function innerDiffNode(dom, vchildren, context, mountAll) {
	let originalChildren = dom.childNodes,
		children = [],
		keyed = {},
		keyedLen = 0,
		min = 0,
		len = originalChildren.length,
		childrenLen = 0,
		vlen = vchildren && vchildren.length,
		j, c, vchild, child;

	if (len) {
		for (let i=0; i<len; i++) {
			let child = originalChildren[i],
				props = child[ATTR_KEY],
				key = vlen ? ((c = child._component) ? c.__key : props ? props.key : null) : null;
			if (key!=null) {
				keyedLen++;
				keyed[key] = child;
			}
			else if (hydrating || props) {
				children[childrenLen++] = child;
			}
		}
	}

	if (vlen) {
		for (let i=0; i<vlen; i++) {
			vchild = vchildren[i];
			child = null;

			// if (isFunctionalComponent(vchild)) {
			// 	vchild = buildFunctionalComponent(vchild);
			// }

			// attempt to find a node based on key matching
			let key = vchild.key;
			if (key!=null) {
				if (keyedLen && key in keyed) {
					child = keyed[key];
					keyed[key] = undefined;
					keyedLen--;
				}
			}
			// attempt to pluck a node of the same type from the existing children
			else if (!child && min<childrenLen) {
				for (j=min; j<childrenLen; j++) {
					c = children[j];
					if (c && isSameNodeType(c, vchild)) {
						child = c;
						children[j] = undefined;
						if (j===childrenLen-1) childrenLen--;
						if (j===min) min++;
						break;
					}
				}
			}

			// morph the matched/found/created DOM child to match vchild (deep)
			child = idiff(child, vchild, context, mountAll);

			if (child && child!==dom) {
				if (i>=len) {
					dom.appendChild(child);
				}
				else if (child!==originalChildren[i]) {
					if (child===originalChildren[i+1]) {
						removeNode(originalChildren[i]);
					}
					dom.insertBefore(child, originalChildren[i] || null);
				}
			}
		}
	}

	if (keyedLen) {
		for (let i in keyed) if (keyed[i]) recollectNodeTree(keyed[i]);
	}

	// remove orphaned children
	while (min<=childrenLen) {
		child = children[childrenLen--];
		if (child) recollectNodeTree(child);
	}
}

/** Recursively recycle (or just unmount) a node an its descendants.
 *	@param {Node} node						DOM node to start unmount/removal from
 *	@param {Boolean} [unmountOnly=false]	If `true`, only triggers unmount lifecycle, skips removal
 */
export function recollectNodeTree(node, unmountOnly) {
	let component = node._component;
	if (component) {
		// if node is owned by a Component, unmount that component (ends up recursing back here)
		unmountComponent(component, !unmountOnly);
	}
	else {
		// If the node's VNode had a ref function, invoke it with null here.
		// (this is part of the React spec, and smart for unsetting references)
		if (node[ATTR_KEY] && node[ATTR_KEY].ref) node[ATTR_KEY].ref(null);

		if (!unmountOnly) {
			collectNode(node);
		}

		// Recollect/unmount all children.
		// - we use .lastChild here because it causes less reflow than .firstChild
		// - it's also cheaper than accessing the .childNodes Live NodeList
		let c;
		while ((c=node.lastChild)) recollectNodeTree(c, unmountOnly);
	}
}

/** Apply differences in attributes from a VNode to the given DOM Element.
 *	@param {Element} dom		Element with attributes to diff `attrs` against
 *	@param {Object} attrs		The desired end-state key-value attribute pairs
 *	@param {Object} old			Current/previous attributes (from previous VNode or element's prop cache)
 */
function diffAttributes(dom, attrs, old) {
	// remove attributes no longer present on the vnode by setting them to undefined
	for (let name in old) {
		if (!(attrs && name in attrs) && old[name]!=null) {
			setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode);
		}
	}

	// add new & update changed attributes
	if (attrs) {
		for (let name in attrs) {
			if (name!=='children' && name!=='innerHTML' && (!(name in old) || attrs[name]!==(name==='value' || name==='checked' ? dom[name] : old[name]))) {
				setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
			}
		}
	}
}
<|endoftext|>


<commit_before>define(['text!./activities-list.html', 'app','moment' ], function(template, app,moment) {
    'use strict';

    app.directive('activitiesList', ['$http','$location',  function($http,$location) {
        return {
            restrict: 'E',
            template: template,
            replace: false,
            scope: {
                country: '=?country',
                year: '=?year',
                month: '=?month',
                search: '=?search',
                count: '=?count',
            },

            link: function($scope, $element, $attr) {
                  $scope.currentPage =0;
                  if(!$attr.hidePagenation)
                      $scope.hidePagenation=false;
                  else
                      $scope.hidePagenation=$attr.hidePagenation;

                  if(!$attr.itemsPerPage)
                    $scope.itemsPerPage =5;
                  else
                    $scope.itemsPerPage =$attr.itemsPerPage;

                    if(!$attr.hideCountryReference)
                      $scope.hideCountryReference =false;
                    else
                      $scope.hideCountryReference =true;

                  $scope.prevDate = false;
            }, //link

            controller: ['$scope','$timeout', function($scope,$timeout) {
              search();
              $timeout(function(){
                $scope.$watch('year', function(newValue, oldValue) {
                  if(newValue!==oldValue)
                    search();
                });
                $scope.$watch('month', function(newValue, oldValue) {
                  if(newValue!==oldValue)
                    search();
                });
                $scope.$watch('country', function(newValue, oldValue) {
                  if(newValue!==oldValue || (newValue && newValue.length === 2))
                    search();
                });
                $scope.$watch('search', function(newValue, oldValue) {
                  if(newValue!==oldValue)
                    search();
                });
                $scope.$watch('currentPage', function(newValue, oldValue) {
                    if(newValue!==oldValue)
                      search();
                });
              },1000);

              $scope.getNumberPages = function() {
                  if($scope.count && $scope.itemsPerPage && ($scope.count > $scope.itemsPerPage))
                    return new Array(Math.floor($scope.count/$scope.itemsPerPage)+1);
                  else
                      return new Array(1);

              };

              $scope.changePage = function(index) {
                  $scope.prevDate=false;
                  $scope.currentPage=index;

              };
              $scope.isActive = function(index) {
                  return ($scope.currentPage===(index));

              };

              $scope.getCountryFlag = function(code) {
                  return 'https://www.cbd.int/images/flags/48/flag-'+code+'-48.png';

              };

              //=======================================================================
          		//
          		//=======================================================================
          		$scope.goTo= function (url,code){
                if(code)
          			   $location.url(url+code);
                else
                  $location.url(url);
          		};

              $scope.sectionTitle = function(date) {

                  return moment(date,moment.ISO_8601).format('MMMM YYYY');
              };
              $scope.showSection = function(date,index) {
                if(index===0)$scope.prevDate=false;

                  if(!$scope.prevDate || !(moment($scope.prevDate).isSame(date,'year') && moment($scope.prevDate).isSame(date,'month'))){
                    $scope.prevDate=date;
                    return true;
                  }else {
                    $scope.prevDate=date;
                    return false;
                  }

              };
              //=======================================================================
              //
              //=======================================================================
              function generateDateQuery() {
                var q,startD,endD,totalDaysInMonth = '';
                  $scope.prevDate=false;

                if(!$scope.year && $scope.month){
                  var year=2009;
                  q=' AND (';
                  for(var i=1; i<=12 ; i++){
                    year=year+1;
                    totalDaysInMonth= moment(year+'-'+$scope.month, "YYYY-MM").daysInMonth();
                    startD = moment('01-'+$scope.month+'-'+year,"DD-MM-YYYY").toISOString();
                    endD = moment(totalDaysInMonth+'-'+$scope.month+'-'+year, "DD-MM-YYYY").toISOString();
                    q+= ' startDate_dt:['+startD+' TO '+endD+']';
                    if(i!=12) q+=' OR';
                  }
                  q=q+')';
                } else

                if($scope.year && !$scope.month){
                  startD = moment('01-01-'+$scope.year,"DD-MM-YYYY").toISOString();
                  endD = moment('31-12-'+$scope.year, "DD-MM-YYYY").toISOString();
                   q= ' AND startDate_dt:['+startD+' TO '+endD+']';
                } else

                if($scope.year && $scope.month){
                  totalDaysInMonth= moment($scope.year+'-'+$scope.month, "YYYY-MM").daysInMonth();
                  startD = moment('01-'+$scope.month+'-'+$scope.year,"DD-MM-YYYY").toISOString();
                  endD = moment(totalDaysInMonth+'-'+$scope.month+'-'+$scope.year, "DD-MM-YYYY").toISOString();
                   q= ' AND startDate_dt:['+startD+' TO '+endD+']';
                }

                return q;
              }
              $scope.generateDateQuery = generateDateQuery;

              //=======================================================================
              //
              //=======================================================================
              function search() {
                var q = 'schema_s:undbAction';
                $scope.loading=true;
                if($scope.search)
                    q= q+' AND (title_t:"' + $scope.search + '*" OR description_t:"' + $scope.search + '*")';
                if($scope.country)
                  q= q+' AND country_s:'+$scope.country;

                if($scope.year || $scope.month){
                  q = q+generateDateQuery();
                }

                var queryParameters = {
                  'q': q,
                  'wt': 'json',
                  'sort': 'startDate_dt desc, title_t asc',
                  'start': $scope.currentPage * $scope.itemsPerPage,
  								'rows': $scope.itemsPerPage,
                };
                  $http.get('/api/v2013/index', {
                    params: queryParameters,
                    cache: true
                  }).success(function(data) {
                    $scope.count = data.response.numFound;
                    $scope.actions = data.response.docs;
                    $scope.loading = false;
                  });
              }
              $scope.trustSrc = search;

              $scope.extractId = function(id){
                  return parseInt(id.replace('52000000cbd08', ''), 16);
              };

            }],
        }; // return
    }]); //app.directive('searchFilterCountries

}); // define
<commit_msg>kill error call to index, does initial search after executing link and $attrs loaded<commit_after>define(['text!./activities-list.html', 'app','moment' ], function(template, app,moment) {
    'use strict';

    app.directive('activitiesList', ['$http','$location',  function($http,$location) {
        return {
            restrict: 'E',
            template: template,
            replace: false,
            require:'activitiesList',
            scope: {
                country: '=?country',
                year: '=?year',
                month: '=?month',
                search: '=?search',
                count: '=?count',
            },

            link: function($scope, $element, $attr,ctrl) {
                  $scope.currentPage =0;
                  if(!$attr.hidePagenation)
                      $scope.hidePagenation=false;
                  else
                      $scope.hidePagenation=$attr.hidePagenation;

                  if(!$attr.itemsPerPage)
                    $scope.itemsPerPage =5;
                  else
                    $scope.itemsPerPage =$attr.itemsPerPage;

                    if(!$attr.hideCountryReference)
                      $scope.hideCountryReference =false;
                    else
                      $scope.hideCountryReference =true;
                  ctrl.search();
                  $scope.prevDate = false;
            }, //link

            controller: ['$scope','$timeout', function($scope,$timeout) {

              $timeout(function(){
                $scope.$watch('year', function(newValue, oldValue) {
                  if(newValue!==oldValue)
                    search();
                });
                $scope.$watch('month', function(newValue, oldValue) {
                  if(newValue!==oldValue)
                    search();
                });
                $scope.$watch('country', function(newValue, oldValue) {
                  if(newValue!==oldValue || (newValue && newValue.length === 2))
                    search();
                });
                $scope.$watch('search', function(newValue, oldValue) {
                  if(newValue!==oldValue)
                    search();
                });
                $scope.$watch('currentPage', function(newValue, oldValue) {
                    if(newValue!==oldValue)
                      search();
                });
              },1000);

              $scope.getNumberPages = function() {
                  if($scope.count && $scope.itemsPerPage && ($scope.count > $scope.itemsPerPage))
                    return new Array(Math.floor($scope.count/$scope.itemsPerPage)+1);
                  else
                      return new Array(1);

              };

              $scope.changePage = function(index) {
                  $scope.prevDate=false;
                  $scope.currentPage=index;

              };
              $scope.isActive = function(index) {
                  return ($scope.currentPage===(index));

              };

              $scope.getCountryFlag = function(code) {
                  return 'https://www.cbd.int/images/flags/48/flag-'+code+'-48.png';

              };

              //=======================================================================
          		//
          		//=======================================================================
          		$scope.goTo= function (url,code){
                if(code)
          			   $location.url(url+code);
                else
                  $location.url(url);
          		};

              $scope.sectionTitle = function(date) {

                  return moment(date,moment.ISO_8601).format('MMMM YYYY');
              };
              $scope.showSection = function(date,index) {
                if(index===0)$scope.prevDate=false;

                  if(!$scope.prevDate || !(moment($scope.prevDate).isSame(date,'year') && moment($scope.prevDate).isSame(date,'month'))){
                    $scope.prevDate=date;
                    return true;
                  }else {
                    $scope.prevDate=date;
                    return false;
                  }

              };
              //=======================================================================
              //
              //=======================================================================
              function generateDateQuery() {
                var q,startD,endD,totalDaysInMonth = '';
                  $scope.prevDate=false;

                if(!$scope.year && $scope.month){
                  var year=2009;
                  q=' AND (';
                  for(var i=1; i<=12 ; i++){
                    year=year+1;
                    totalDaysInMonth= moment(year+'-'+$scope.month, "YYYY-MM").daysInMonth();
                    startD = moment('01-'+$scope.month+'-'+year,"DD-MM-YYYY").toISOString();
                    endD = moment(totalDaysInMonth+'-'+$scope.month+'-'+year, "DD-MM-YYYY").toISOString();
                    q+= ' startDate_dt:['+startD+' TO '+endD+']';
                    if(i!=12) q+=' OR';
                  }
                  q=q+')';
                } else

                if($scope.year && !$scope.month){
                  startD = moment('01-01-'+$scope.year,"DD-MM-YYYY").toISOString();
                  endD = moment('31-12-'+$scope.year, "DD-MM-YYYY").toISOString();
                   q= ' AND startDate_dt:['+startD+' TO '+endD+']';
                } else

                if($scope.year && $scope.month){
                  totalDaysInMonth= moment($scope.year+'-'+$scope.month, "YYYY-MM").daysInMonth();
                  startD = moment('01-'+$scope.month+'-'+$scope.year,"DD-MM-YYYY").toISOString();
                  endD = moment(totalDaysInMonth+'-'+$scope.month+'-'+$scope.year, "DD-MM-YYYY").toISOString();
                   q= ' AND startDate_dt:['+startD+' TO '+endD+']';
                }

                return q;
              }
              $scope.generateDateQuery = generateDateQuery;

              //=======================================================================
              //
              //=======================================================================
              function search() {
                var q = 'schema_s:undbAction';
                $scope.loading=true;
                if($scope.search)
                    q= q+' AND (title_t:"' + $scope.search + '*" OR description_t:"' + $scope.search + '*")';
                if($scope.country)
                  q= q+' AND country_s:'+$scope.country;

                if($scope.year || $scope.month){
                  q = q+generateDateQuery();
                }

                var queryParameters = {
                  'q': q,
                  'wt': 'json',
                  'sort': 'startDate_dt desc, title_t asc',
                  'start': $scope.currentPage * $scope.itemsPerPage,
  								'rows': $scope.itemsPerPage,
                };
                  $http.get('/api/v2013/index/select', {
                    params: queryParameters,
                    cache: true
                  }).success(function(data) {
                    $scope.count = data.response.numFound;
                    $scope.actions = data.response.docs;
                    $scope.loading = false;
                  });
              }
              this.search = search;

              $scope.extractId = function(id){
                  return parseInt(id.replace('52000000cbd08', ''), 16);
              };

            }],
        }; // return
    }]); //app.directive('searchFilterCountries

}); // define
<|endoftext|>


<commit_before>/** @babel */

import {CompositeDisposable} from 'atom'

import React from 'react'
import ReactDom from 'react-dom'

import EtchWrapper from '../views/etch-wrapper'
import StatusBar from '../views/status-bar'
import Panel from '../views/panel'
import PaneItem from '../views/pane-item'
import FilePatchController from './file-patch-controller'
import GitPanelController from './git-panel-controller'
import StatusBarTileController from './status-bar-tile-controller'

const nullFilePatchState = {
  filePath: null,
  filePatch: null,
  stagingStatus: null,
  amending: null,
}

export default class GithubPackageController extends React.Component {
  static propTypes = {
    workspace: React.PropTypes.object.isRequired,
    commandRegistry: React.PropTypes.object.isRequired,
    notificationManager: React.PropTypes.object.isRequired,
    repository: React.PropTypes.object,
    statusBar: React.PropTypes.object,
    legacyStatusBar: React.PropTypes.bool,
  }

  static defaultProps = {
    legacyStatusBar: false,
  }

  constructor (props, context) {
    super(props, context)
    this.state = {
      ...nullFilePatchState
    }

    this.showFilePatchForPath = this.showFilePatchForPath.bind(this)
    this.showMergeConflictFileForPath = this.showMergeConflictFileForPath.bind(this)
    this.onRepoRefresh = this.onRepoRefresh.bind(this)
    this.subscriptions = new CompositeDisposable()
  }

  render () {
    return (

        <StatusBar statusBar={this.props.statusBar} legacy={this.props.legacyStatusBar}>
          <EtchWrapper type="span">
            <StatusBarTileController
              workspace={this.props.workspace}
              repository={this.props.repository}
              toggleGitPanel={this.toggleGitPanel}
            />
          </EtchWrapper>
        </StatusBar>
        {this.props.gitPanelActive ? this.renderGitPanel() : null}
        {(this.state.filePath && this.state.filePatch) ? this.renderFilePatchController() : null}

    )
  }

  renderGitPanel () {
    return (
      <Panel workspace={this.props.workspace} location="right">
        <EtchWrapper ref={c => this.gitPanelController = c}>
          <GitPanelController
            workspace={this.props.workspace}
            commandRegistry={this.props.commandRegistry}
            notificationManager={this.props.notificationManager}
            repository={this.props.repository}
            didSelectFilePath={this.showFilePatchForPath}
            didSelectMergeConflictFile={this.showMergeConflictFileForPath}
            didChangeAmending={this.didChangeAmending}
            focusFilePatchView={this.focusFilePatchView}
          />
        </EtchWrapper>
      </Panel>
    )
  }

  renderFilePatchController () {
    return (
      <PaneItem
        workspace={this.props.workspace}
        getItem={container => container.getWrappedComponent()}
        ref={c => this.filePatchControllerPane = c}
        onDidCloseItem={() => this.setState({...nullFilePatchState})}
      >
        <EtchWrapper ref={c => this.filePatchController = c} reattachDomNode={false}>
          <FilePatchController
            repository={this.props.repository}
            filePatch={this.state.filePatch}
            stagingStatus={this.state.stagingStatus}
            onRepoRefresh={this.onRepoRefresh}
          />
        </EtchWrapper>
      </PaneItem>
    )
  }

  async showFilePatchForPath (filePath, stagingStatus, {activate, amending} = {}) {
    const repository = this.props.repository
    if (!repository) return

    const filePatch = await repository.getFilePatchForPath(filePath, {staged: stagingStatus === 'staged', amending})
    if (filePatch) {
      this.setState({
        filePath: filePath,
        filePatch: filePatch,
        stagingStatus: stagingStatus,
        amending: amending,
      }, () => {
        // TODO: can be better done w/ a prop?
        if (activate) {
          this.filePatchControllerPane.activate()
        }
      })
    } else {
      this.setState({...nullFilePatchState})
    }
  }

  onRepoRefresh () {
    this.showFilePatchForPath(this.state.filePath, this.state.stagingStatus, {amending: this.state.amending})
  }

  showMergeConflictFileForPath() {}
  didChangeAmending() {}
  focusFilePatchView() {}
}
<commit_msg>:art:<commit_after>/** @babel */

import {CompositeDisposable} from 'atom'

import React from 'react'
import ReactDom from 'react-dom'

import EtchWrapper from '../views/etch-wrapper'
import StatusBar from '../views/status-bar'
import Panel from '../views/panel'
import PaneItem from '../views/pane-item'
import FilePatchController from './file-patch-controller'
import GitPanelController from './git-panel-controller'
import StatusBarTileController from './status-bar-tile-controller'

const nullFilePatchState = {
  filePath: null,
  filePatch: null,
  stagingStatus: null,
  amending: null,
}

export default class GithubPackageController extends React.Component {
  static propTypes = {
    workspace: React.PropTypes.object.isRequired,
    commandRegistry: React.PropTypes.object.isRequired,
    notificationManager: React.PropTypes.object.isRequired,
    repository: React.PropTypes.object,
    statusBar: React.PropTypes.object,
    legacyStatusBar: React.PropTypes.bool,
  }

  static defaultProps = {
    legacyStatusBar: false,
  }

  constructor (props, context) {
    super(props, context)
    this.state = {
      ...nullFilePatchState
    }

    this.showFilePatchForPath = this.showFilePatchForPath.bind(this)
    this.showMergeConflictFileForPath = this.showMergeConflictFileForPath.bind(this)
    this.onRepoRefresh = this.onRepoRefresh.bind(this)
    this.subscriptions = new CompositeDisposable()
  }

  render () {
    return (

        <StatusBar statusBar={this.props.statusBar} legacy={this.props.legacyStatusBar}>
          <EtchWrapper type="span">
            <StatusBarTileController
              workspace={this.props.workspace}
              repository={this.props.repository}
              toggleGitPanel={this.toggleGitPanel}
            />
          </EtchWrapper>
        </StatusBar>
        {this.props.gitPanelActive ? this.renderGitPanel() : null}
        {(this.state.filePath && this.state.filePatch) ? this.renderFilePatchController() : null}

    )
  }

  renderGitPanel () {
    return (
      <Panel workspace={this.props.workspace} location="right">
        <EtchWrapper ref={c => this.gitPanelController = c}>
          <GitPanelController
            workspace={this.props.workspace}
            commandRegistry={this.props.commandRegistry}
            notificationManager={this.props.notificationManager}
            repository={this.props.repository}
            didSelectFilePath={this.showFilePatchForPath}
            didSelectMergeConflictFile={this.showMergeConflictFileForPath}
            didChangeAmending={this.didChangeAmending}
            focusFilePatchView={this.focusFilePatchView}
          />
        </EtchWrapper>
      </Panel>
    )
  }

  renderFilePatchController () {
    return (
      <PaneItem
        workspace={this.props.workspace}
        getItem={container => container.getWrappedComponent()}
        ref={c => this.filePatchControllerPane = c}
        onDidCloseItem={() => this.setState({...nullFilePatchState})}
      >
        <EtchWrapper ref={c => this.filePatchController = c} reattachDomNode={false}>
          <FilePatchController
            repository={this.props.repository}
            filePatch={this.state.filePatch}
            stagingStatus={this.state.stagingStatus}
            onRepoRefresh={this.onRepoRefresh}
          />
        </EtchWrapper>
      </PaneItem>
    )
  }

  async showFilePatchForPath (filePath, stagingStatus, {activate, amending} = {}) {
    const repository = this.props.repository
    if (!repository) return

    const filePatch = await repository.getFilePatchForPath(filePath, {staged: stagingStatus === 'staged', amending})
    if (filePatch) {
      this.setState({ filePath, filePatch, stagingStatus, amending }, () => {
        // TODO: can be better done w/ a prop?
        if (activate) {
          this.filePatchControllerPane.activate()
        }
      })
    } else {
      this.setState({...nullFilePatchState})
    }
  }

  onRepoRefresh () {
    this.showFilePatchForPath(this.state.filePath, this.state.stagingStatus, {amending: this.state.amending})
  }

  showMergeConflictFileForPath() {}

  didChangeAmending() {}

  focusFilePatchView() {}
}
<|endoftext|>