<commit_before>'use strict';

var d3 = require('d3');
var topojson = require('topojson');

function locatorMap(){
  var height = 300,
  width = 300,
  map,
  locations,
  locatorProjection = d3.geo.albers() //standard UK
    .center([-2.5, 55.4])
    .rotate([0, 0])
    .parallels([50, 60])
    .scale(1500)
    .translate([width / 2, height / 2]),
  path = d3.geo.path().projection(locatorProjection);

  function locator(g){
    var svg = g.append('div').attr('class','locator-container')
      .append('svg')
      .attr({
        viewBox:'0 0 ' + width + ' ' + height + '',
        width:height,
        height:width
      });

    if(map){
      svg.selectAll(".subunit")
        .data(topojson.feature(map, map.objects.subunits).features)
        .enter()
        .append("path")
        .attr("class", function(d) { return "subunit region-" + d.id.toLowerCase(); })
        .attr("d", path);

      svg.append("path")
        .datum(topojson.mesh(map, map.objects.subunits, function(a, b) { return a !== b && a.id !== "IRL"; }))
        .attr("d", path)
        .attr("class", "subunit-boundary");

      svg.append("path")
        .datum(topojson.mesh(map, map.objects.subunits, function(a, b) { return a === b && a.id === "IRL"; }))
        .attr("d", path)
        .attr("class", "subunit-boundary IRL");
    }

    if(locations){
      svg.selectAll('circle')
        .data(locations)
        .enter()
        .append('circle')
        .attr({
          'class':function(d){
            return 'constituency-point ' + (d.holderpredicted);
          },
          'r':2,
          'transform':function(d){
            return 'translate(' + locatorProjection(d.coords) + ')';}
        });
    }
  }

  locator.locations = function(a){
    locations = a;
    return locator;
  };

  locator.map = function(m){
    map = m;
    return locator;
  };

  return locator;
}

module.exports = locatorMap;
<commit_msg>fixed switched height, width<commit_after>'use strict';

var d3 = require('d3');
var topojson = require('topojson');

function locatorMap(){
  var height = 300,
  width = 200,
  map,
  locations,
  locatorProjection = d3.geo.albers() //standard UK
    .center([-2.5, 55.4])
    .rotate([0, 0])
    .parallels([50, 60])
    .scale(1500)
    .translate([width / 2, height / 2]),
  path = d3.geo.path().projection(locatorProjection);

  function locator(g){
    var svg = g.append('div').attr('class','locator-container')
      .append('svg')
      .attr({
        viewBox:'0 0 ' + width + ' ' + height + '',
        width:width,
        height:height
      });

    if(map){
      svg.selectAll(".subunit")
        .data(topojson.feature(map, map.objects.subunits).features)
        .enter()
        .append("path")
        .attr("class", function(d) { return "subunit region-" + d.id.toLowerCase(); })
        .attr("d", path);

      svg.append("path")
        .datum(topojson.mesh(map, map.objects.subunits, function(a, b) { return a !== b && a.id !== "IRL"; }))
        .attr("d", path)
        .attr("class", "subunit-boundary");

      svg.append("path")
        .datum(topojson.mesh(map, map.objects.subunits, function(a, b) { return a === b && a.id === "IRL"; }))
        .attr("d", path)
        .attr("class", "subunit-boundary IRL");
    }

    if(locations){
      svg.selectAll('circle')
        .data(locations)
        .enter()
        .append('circle')
        .attr({
          'class':function(d){
            return 'constituency-point ' + (d.holderpredicted);
          },
          'r':2,
          'transform':function(d){
            return 'translate(' + locatorProjection(d.coords) + ')';}
        });
    }
  }

  locator.locations = function(a){
    locations = a;
    return locator;
  };

  locator.width = function(x){
    width = x;
    return locator;
  };

  locator.height = function(x){
    width = x;
    return locator;
  };

  locator.map = function(m){
    map = m;
    return locator;
  };

  return locator;
}

module.exports = locatorMap;
<|endoftext|>


<commit_before>/**
 * Created by J on 10/7/2014.
 */

'use strict';
var fs = require('fs');
var Classes = require('./classes');

function generateResults (requirementsObject, numberResults) {
    var flatRequirementsMap = {},
    requirements = new Classes.TopLevelRequirementsGroup(requirementsObject, flatRequirementsMap);
    return generateTestBenchManifests(flatRequirementsMap, "MyDesign", numberResults);
}

function generateTestBenchManifests (requirementsMap, seedDesignName, numberResults) {
    var testbenchManifestGrid = {};
    var metricMap = {};
    var name;
    var numResults = numberResults || 1;

    for (name in requirementsMap) {
        var requirement = requirementsMap[name];
        var metricName = requirement.metricName;
        var metric;

        if (metricMap.hasOwnProperty(metricName)) {
            metric = metricMap[metricName];
        } else {
            metric = new Classes.Metric(requirement)
            metricMap[metricName] = metric;
        }

        for (var i=0;i<numResults;i++) {
            var tbName = requirement.testBench;
            var dName = seedDesignName + "_" + (i + 1).toString();
            var uniqueName = tbName + '_' + dName;
            var tb;

            giveMetricValues(metric, requirement, resultsShouldPass);

            if (testbenchManifestGrid.hasOwnProperty(dName)) {
                if (testbenchManifestGrid[dName].hasOwnProperty(tbName)) {
                    tb = testbenchManifestGrid[dName][tbName];
                } else {
                    tb = new Classes.TestBenchManifest(tbName, dName);
                    testbenchManifestGrid[dName][tbName] = tb;
                }
            } else {
                tb = new Classes.TestBenchManifest(tbName, dName);
                testbenchManifestGrid[dName] = {};
                testbenchManifestGrid[dName][tbName] = tb;
            }

            // These two lines are to remove the reference to the "Metric" object.
            var metricString =JSON.stringify(metric, null, 4);
            var metricJson = JSON.parse(metricString);

            tb.Metrics.push(metricJson);
        }
    }

    var results = [];

    for (dName in testbenchManifestGrid) {
        var singleResult = [];
        for (tbName in testbenchManifestGrid[dName]) {
            singleResult.push(testbenchManifestGrid[dName][tbName]);
        }

        results.push(singleResult);
    }

    return results;
}

function giveMetricValues (metricInstance, requirementInstance) {
    var difference = Math.abs(requirementInstance.objective - requirementInstance.threshold),
        average = (requirementInstance.objective + requirementInstance.threshold)/ 2,
        randomNumber = Math.random(),
        unitScale = (randomNumber - 0.5);

    metricInstance.Value = average + difference*unitScale;
}

var main = function () {

    var args = process.argv.slice(2),
        requirementsFilePath,
        numberResultsToGenerate;

    if (args[0]) {
        requirementsFilePath = args[0];
    }
    if (args[1]) {
        numberResultsToGenerate = args[1];
    }

    fs.readFile(requirementsFilePath, 'utf8', function(err, data) {
        if (err) {
            console.log("Could not read json file " + filePath);
        }

        var requirementsObject = JSON.parse(data);
            //splitPath = requirementsFilePath.split('/'),
            //title = splitPath[splitPath.length - 1].split('.')[0],

        var result = generateResults(requirementsObject, numberResultsToGenerate);
        JSON.stringify(result, null, 4);
    });
};

if (require.main === module) {
    main();
}

module.exports.generateResults = generateResults;<commit_msg>remove obsolete argument<commit_after>/**
 * Created by J on 10/7/2014.
 */

'use strict';
var fs = require('fs');
var Classes = require('./classes');

function generateResults (requirementsObject, numberResults) {
    var flatRequirementsMap = {},
    requirements = new Classes.TopLevelRequirementsGroup(requirementsObject, flatRequirementsMap);
    return generateTestBenchManifests(flatRequirementsMap, "MyDesign", numberResults);
}

function generateTestBenchManifests (requirementsMap, seedDesignName, numberResults) {
    var testbenchManifestGrid = {};
    var metricMap = {};
    var name;
    var numResults = numberResults || 1;

    for (name in requirementsMap) {
        var requirement = requirementsMap[name];
        var metricName = requirement.metricName;
        var metric;

        if (metricMap.hasOwnProperty(metricName)) {
            metric = metricMap[metricName];
        } else {
            metric = new Classes.Metric(requirement)
            metricMap[metricName] = metric;
        }

        for (var i=0;i<numResults;i++) {
            var tbName = requirement.testBench;
            var dName = seedDesignName + "_" + (i + 1).toString();
            var uniqueName = tbName + '_' + dName;
            var tb;

            giveMetricValues(metric, requirement);

            if (testbenchManifestGrid.hasOwnProperty(dName)) {
                if (testbenchManifestGrid[dName].hasOwnProperty(tbName)) {
                    tb = testbenchManifestGrid[dName][tbName];
                } else {
                    tb = new Classes.TestBenchManifest(tbName, dName);
                    testbenchManifestGrid[dName][tbName] = tb;
                }
            } else {
                tb = new Classes.TestBenchManifest(tbName, dName);
                testbenchManifestGrid[dName] = {};
                testbenchManifestGrid[dName][tbName] = tb;
            }

            // These two lines are to remove the reference to the "Metric" object.
            var metricString =JSON.stringify(metric, null, 4);
            var metricJson = JSON.parse(metricString);

            tb.Metrics.push(metricJson);
        }
    }

    var results = [];

    for (dName in testbenchManifestGrid) {
        var singleResult = [];
        for (tbName in testbenchManifestGrid[dName]) {
            singleResult.push(testbenchManifestGrid[dName][tbName]);
        }

        results.push(singleResult);
    }

    return results;
}

function giveMetricValues (metricInstance, requirementInstance) {
    var difference = Math.abs(requirementInstance.objective - requirementInstance.threshold),
        average = (requirementInstance.objective + requirementInstance.threshold)/ 2,
        randomNumber = Math.random(),
        unitScale = (randomNumber - 0.5);

    metricInstance.Value = average + difference*unitScale;
}

var main = function () {

    var args = process.argv.slice(2),
        requirementsFilePath,
        numberResultsToGenerate;

    if (args[0]) {
        requirementsFilePath = args[0];
    }
    if (args[1]) {
        numberResultsToGenerate = args[1];
    }

    fs.readFile(requirementsFilePath, 'utf8', function(err, data) {
        if (err) {
            console.log("Could not read json file " + filePath);
        }

        var requirementsObject = JSON.parse(data);
            //splitPath = requirementsFilePath.split('/'),
            //title = splitPath[splitPath.length - 1].split('.')[0],

        var result = generateResults(requirementsObject, numberResultsToGenerate);
        JSON.stringify(result, null, 4);
    });
};

if (require.main === module) {
    main();
}

module.exports.generateResults = generateResults;<|endoftext|>


<commit_before>/**
 * nanoAudioPlayer plugin for jQuery
 * by Lasse Nielsen
 * @version 0.1
 * 03.02.2013
 * http://github.com/nano-entertainment/NanoAudioPlayer
 */
(function($){
  $.fn.nanoAudioPlayer = function( options ){
    var defaults = {
      autoplay: false,
      loop: false,
      element: new Audio()
    };

    var opts = $.extend(defaults, options);

    // EventListener

    // autoplay
    opts.element.bind('canplay', function() {
      if( opts.autoplay ) opts.element.play();
    });

    //loop
    if( typeof opts.element.loop == 'boolean') {
      opts.element.loop = opts.loop;
    } else {
      opts.element.bind('ended', function() {
        if( opts.loop ) {
          opts.element.duration = opts.element.startTime;
          opts.element.play();
        }
      })
    }
    opts.element.bind('ended', function() {
      if( opts.loop ) {
        opts.element.duration = 0;
        opts.element.play();
      }
    })

    // Html-Event Listener

    //play
    $(this).find('.play').bind('click', function() {
      opts.audioElement.play();
    });

    //pause
    $(this).find('.pause').bind('click', function() {
      opts.audioElement.pause();
    });

    // playToggle
    $(this).find('.play-toggle').bind('click', function() {
      if(opts.audioElement.paused) {
    	opts.audioElement.play();
      } else {
        opts.audioElement.pause();
      }

    });

  }
})(jQuery);<commit_msg>add suffix detection<commit_after>/**
 * nanoAudioPlayer plugin for jQuery
 * by Lasse Nielsen
 * @version 0.1
 * 03.02.2013
 * http://github.com/nano-entertainment/NanoAudioPlayer
 */
(function($){
  $.fn.nanoAudioPlayer = function( options ){
    var defaults = {
      autoplay: false,
      loop: false,
      element: new Audio()
    };

    var opts = $.extend(defaults, options);

    // EventListener

    // autoplay
    opts.element.addEventListener('canplay', function() {
      if( opts.autoplay ) opts.element.play();
    }, false);

    var suffix;

    if(opts.element.canPlayType("audio/ogg"))
      {
        suffix = "ogg";
      } else {
        suffix = "mp3";
      }
    opts.element.src = opts.file + "." + suffix;

    //loop
    if( typeof opts.element.loop == 'boolean') {
      opts.element.loop = opts.loop;
    } else {
      opts.element.addEventListener('ended', function() {
        if( opts.loop ) {
          opts.element.duration = opts.element.startTime;
          opts.element.play();
        }
      }, false)
    }

    // Html-Event Listener

    //play
    $(this).find('.play').bind('click', function() {
      opts.audioElement.play();
    });

    //pause
    $(this).find('.pause').bind('click', function() {
      opts.audioElement.pause();
    });

    // playToggle
    $(this).find('.play-toggle').bind('click', function() {
      if(opts.audioElement.paused) {
    	opts.audioElement.play();
      } else {
        opts.audioElement.pause();
      }

    });

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


<commit_before>import { createStore, applyMiddleware } from 'redux'
import _ from 'lodash'

// See
// https://github.com/gaearon/redux-thunk and http://redux.js.org/docs/advanced/AsyncActions.html
import thunkMiddleware from 'redux-thunk'

import reducers from '../reducers'
import { initialStates } from '../reducers'

export default function configureStore(props) {

    // This is how we get initial props from Symfony into redux.
    const { recipes, recipe, baseUrl, location } = props
    const { recipesState } = initialStates

    // Redux expects to initialize the store using an Object
    const initialState = {
        recipesState: _.extend(recipesState, {
            recipe: recipe,
            recipes: recipes,
            baseUrl: baseUrl,
            location: location,
        }),
    }

    const store = createStore(
        reducers,
        initialState,
        applyMiddleware(thunkMiddleware),
    )
    return store
}
<commit_msg>Add dev tools<commit_after>import { createStore, applyMiddleware, compose } from 'redux'
import _ from 'lodash'

// See
// https://github.com/gaearon/redux-thunk and http://redux.js.org/docs/advanced/AsyncActions.html
import thunkMiddleware from 'redux-thunk'

import reducers from '../reducers'
import { initialStates } from '../reducers'

export default function configureStore(props) {

    // This is how we get initial props from Symfony into redux.
    const { recipes, recipe, baseUrl, location } = props
    const { recipesState } = initialStates

    // Redux expects to initialize the store using an Object
    const initialState = {
        recipesState: _.extend(recipesState, {
            recipe: recipe,
            recipes: recipes,
            baseUrl: baseUrl,
            location: location,
        }),
    }

    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

    const store = createStore(
        reducers,
        initialState,
        composeEnhancers(applyMiddleware(thunkMiddleware))
    )
    return store
}
<|endoftext|>


<commit_before>/*jslint node: true, browser: true, devel:true, white: false*/
/*global Event, define, $*/
define(["history", "view", "markdown"], function (History, View, Markdown) {
    View = new View();
    Markdown = new Markdown();
    function TM(val) {
        if (val === undefined) {
            val = "";
        }

        this.doc = document.createElement("pre");
        this.doc.id = "TM";
        this.doc.className += "tm-w-default";
        try {
            this.doc.contentEditable = "plaintext-only";
        } catch (e) {
            this.doc.contentEditable = true;
        }
        document.getElementById("TMHolder").appendChild(this.doc);
        this.value = val;
        this.store = val;
        this.selectionStart = 0;
        this.selectionEnd = 0;
        this.searchPos = 0;
        this.storedScrollTop = 0;
        this.lastInput = null;
        this.lastCursor = {selectionStart: 0, selectionEnd: 0};
        this.history = new History();
        this.hasSaved = false;
        this.checkpoint = null;
    }
    TM.prototype = {
        get value() {
            this._value = this.doc.textContent;
            return this._value;
        },
        set value(value) {
            this.doc.textContent = value;
            var html = Markdown.toEditorHTML(value);
            var sel = this.getSelection();
            this.doc.innerHTML = html;
            this.selectionEnd = sel.selectionEnd;
            this.selectionStart = sel.selectionStart;
            this._value = value;
        },
        get text() {
            // this.text and this.value are now essentially
            // the same thing since we've switched from <div> to <pre>.
            return this.doc.textContent;
        },
        set text(value) {
            this.value = value;
        },
        get textContent() {
            return this.value;
        },
        set textContent(value) {
            this.value = value;
        },
        get selectionStart() {
            this._selection();
            return this._selectionStart;
        },
        set selectionStart(value) {
            this._selectionStart = value;
            this._updateSelection();
        },
        get selectionEnd() {
            this._selection();
            return this._selectionEnd;
        },
        set selectionEnd(value) {
            this._selectionEnd = value;
            this._updateSelection();
        }
    };
    TM.prototype.insertText = function (text, andSelectIt) {
        var val = this.value,
            start = this.selectionStart,
            end = this.selectionEnd;
        this.value = [val.slice(0, start), text, val.slice(end)].join("");
        this.selectionEnd = start + text.length;
        if (andSelectIt) {
            // We want to select the inserted text after it's been added.
            this.selectionStart = start;
        } else {
            this.selectionStart = start + text.length;
        }
        // Dispatch input event to update history.
        var e = new Event("input");
        this.doc.dispatchEvent(e);
    };
    TM.prototype.clone = function () {
        var ntm = this.init(this.value);
        var sel = this.getSelection();
        ntm.selectionEnd = sel.selectionEnd;
        ntm.selectionStart = sel.selectionStart;
        ntm.history = this.history;
        ntm.checkpoint = this.checkpoint;
        ntm.hasSaved = this.hasSaved;
        ntm.lastInput = this.lastInput;
        ntm.lastCursor = this.lastCursor;
        this.blur();
        ntm.storedScrollTop = this.storedScrollTop;
        return ntm;
    };
    TM.prototype.update = function () {
        window.tm = this;
    };
    TM.prototype.upgrade = function (tm) {
        var tmholder = document.getElementById("TMHolder");
        while (tmholder.lastChild) {
            tmholder.removeChild(tmholder.lastChild);
        }
        tmholder.appendChild(tm.doc);
    };
    TM.prototype.blur = function () {
        this.handleBlur();
        this.doc.blur();
    };
    TM.prototype.handleBlur = function () {
        this.storedScrollTop = this.doc.scrollTop;
    };
    TM.prototype.focus = function () {
        this.doc.focus();
        this.handleFocus();
    };
    TM.prototype.handleFocus = function () {
        this.doc.scrollTop = this.storedScrollTop;
        this.restoreSelection();
    };
    TM.prototype.isFocused = function () {
        return document.activeElement === this.doc;
    };
    TM.prototype.getSelection = function () {
        var selStart = this.selectionStart,
            selEnd = this.selectionEnd;
        return {selectionStart: selStart, selectionEnd: selEnd};
    };
    TM.prototype.restoreSelection = function () {
        this.selectionEnd = this.lastCursor.selectionEnd;
        this.selectionStart = this.lastCursor.selectionStart;
    };
    TM.prototype._selection = function () {
        var range;
        try {
            // This sometimes doesn't work in desktop app.
            range = window.getSelection().getRangeAt(0);
        } catch (e) {
            // Fix range by creating one.
            window.getSelection().addRange(document.createRange());
            range = window.getSelection().getRangeAt(0);
        }
        var rangeClone = range.cloneRange();
        rangeClone.selectNodeContents(this.doc);
        rangeClone.setEnd(range.startContainer, range.startOffset);
        this._selectionStart = rangeClone.toString().length;
        rangeClone.setEnd(range.endContainer, range.endOffset);
        this._selectionEnd = rangeClone.toString().length;
    };
    TM.prototype._updateSelection = function () {
        // TODO: Rewrite this.
        var range = document.createRange(),
            winselection = window.getSelection(),
            charIndex = 0,
            nodeStack = [this.doc],
            node,
            foundStart = false,
            start = this._selectionStart,
            end = this._selectionEnd,
            stop = false;
        range.setStart(this.doc, 0);
        range.collapse(true);
        while (!stop && (nodeStack.length > 0)) {
            node = nodeStack.pop();
            if (node.nodeType === 3) {
                var nextCharIndex = charIndex + node.length;
                if (!foundStart && start >= charIndex && start <= nextCharIndex) {
                    range.setStart(node, start - charIndex);
                    foundStart = true;
                }
                if (foundStart && end >= charIndex && end <= nextCharIndex) {
                    range.setEnd(node, end - charIndex);
                    stop = true;
                }
                charIndex = nextCharIndex;
            } else {
                var i = node.childNodes.length;
                while (i--) {
                    nodeStack.push(node.childNodes[i]);
                }
            }
        }
        winselection.removeAllRanges();
        winselection.addRange(range);
    };
    TM.prototype.select = function () {
        // selects whole document (textarea default functionality).
        this.selectionStart = 0;
        this.selectionEnd = this.text.length;
    };
    TM.prototype.find = function (value, backward, looping) {
        var pos;
        if (backward) { // findPrev
            var cal;
            if (this.searchPos === 0 || this.searchPos === value.length) {
                // at top, search from bottom
                cal = this.text.length;
            } else { // search above position.
                cal = this.searchPos - (value.length + 1);
            }
            pos =  this.text.lastIndexOf(value, cal);
        } else { // findNext
            pos = this.text.indexOf(value, this.searchPos);
            if (backward === undefined) {
                backward = false;
            }
        }

        if (pos !== -1) {
            this.selectionStart = pos;
            this.selectionEnd = pos + value.length;
            this.searchPos = pos + value.length;
            this.scrollToSelection();
            return true;
        }

        // Query not anywhere found after current position. Loop back to start
        // once.
        this.searchPos = 0;
        if (looping === undefined) {
            // loop once to go back to start of document if at bottom.
            return this.find(value, backward, true);
        }

        // Looped and still nothing found.
        alert("'" + value + "' not found");
        return false;
    };
    TM.prototype.findAll = function (value) {
        return this.text.split(value).length - 1;
    };
    TM.prototype.replace = function (value, replacement, backward) {
        if (value !== "") {
            var found = this.find(value, backward); // find and select thing
            if (found) {
                // replace selected text through insertText
                this.lastInput = null; // set lastInput to null so it forces an undo.
                this.insertText(replacement, true);
                return true;
            }
        }

        return false;
    };
    TM.prototype.replaceAll = function (value, replacement) {
        if (value !== "") {
            var oldContent = this.value;
            this.value = oldContent.split(value).join(replacement);
            this.history.change(
                this,
                {from: oldContent, to: this.value},
                this.getSelection()
            );
            // Dispatch input event to update history.
            var e = new Event("input");
            this.doc.dispatchEvent(e);
        }
    };
    TM.prototype.scrollToSelection = function () {
        var range = window.getSelection().getRangeAt(0),
            t = range.getBoundingClientRect().top;
        this.doc.scrollTop += t - window.innerHeight / 2;
        this.storedScrollTop = this.doc.scrollTop;
    };
    TM.prototype.getWordCount = function () {
        var doc = this.value.match(/\S+/g),
            subdoc = this.value.substring(this.selectionStart, this.selectionEnd),
            selection = subdoc.match(/\S+/g),
            docCount,
            selectCount;
        if (selection) {
            selectCount = selection.length;
        } else {
            selectCount = 0;
        }

        if (doc) {
            docCount = doc.length;
        } else {
            docCount = 0;
        }

        return {doc: docCount, selection: selectCount};
    };
    TM.prototype.init = function (val) {
        var tm = new TM(val);
        tm.doc.addEventListener("input", function () {
            var store = window.tm.store,
                value = window.tm.value;
            window.tm.history.change(
                window.tm,
                {from: store, to: value},
                window.tm.getSelection()
            );
            View.setFileDirty(true);
            View.displayWordCount();
            window.tm.store = window.tm.value;
            var html = Markdown.toEditorHTML(value);
            var sel = window.tm.getSelection();
            window.tm.doc.innerHTML = html;
            window.tm.selectionEnd = sel.selectionEnd;
            window.tm.selectionStart = sel.selectionStart;
        });
        tm.doc.addEventListener("keydown", function (e) {
            View.toggleSuperfluous(true);

            if (!e.metaKey && !e.altKey && e.keyIdentifier !== "Shift") {
                window.tm.lastInput = e.which;
            }

            // Insert tab.
            if (window.tm.isFocused() && e.which === 9) {
                window.tm.insertText("\t");
                e.preventDefault();
            }

            // store the cursor position/selection.
            window.tm.lastCursor = window.tm.getSelection();
        });
        tm.doc.addEventListener("keypress", function () {
            View.playClicks();
        });
        tm.doc.addEventListener("mouseup", function (e) {
            View.displayWordCount();

            // store the cursor position/selection.
            window.tm.lastCursor = window.tm.getSelection();

            // For shift-clicking on links so that they open.
            if (e.shiftKey && e.target.localName === "a") {
                if (!window.Wrong.gui) {
                    // Not using native app.
                    window.location = e.target.href;
                } else {
                    // If using Desktop app, open in browser.
                    window.Wrong.gui.Shell.openExternal(e.target.href);
                }
            }
        });
        tm.doc.addEventListener("dragenter", function (e) {
            View.toggleSuperfluous(false);
        });
        tm.doc.addEventListener("drop", function (e) {
            var data = e.dataTransfer.getData("text");
            if (data.length > 0) {
                e.stopPropagation();
                tm.insertText(data, true);
            }
        });
        tm.doc.onpaste = function (e) {
            e.preventDefault();
            var content;
            if (e.clipboardData) {
                // cmd-paste
                content = e.clipboardData.getData("text/plain");
            } else {
                // Right-click > paste
                content = window.Wrong.clip.get();
            }
            var oldContent = window.tm.value;
            window.tm.insertText(content);
        };
        tm.doc.addEventListener("contextmenu", function (e) {
            // Insert editmenu on right-click.
            if (window.Wrong.editmenu) {
                window.Wrong.editmenu.popup(e.x, e.y);
            }
        });
        return tm;
    };
    return TM;
});
<commit_msg>Open non-js links in new tab<commit_after>/*jslint node: true, browser: true, devel:true, white: false*/
/*global Event, define, $*/
define(["history", "view", "markdown"], function (History, View, Markdown) {
    View = new View();
    Markdown = new Markdown();
    function TM(val) {
        if (val === undefined) {
            val = "";
        }

        this.doc = document.createElement("pre");
        this.doc.id = "TM";
        this.doc.className += "tm-w-default";
        try {
            this.doc.contentEditable = "plaintext-only";
        } catch (e) {
            this.doc.contentEditable = true;
        }
        document.getElementById("TMHolder").appendChild(this.doc);
        this.value = val;
        this.store = val;
        this.selectionStart = 0;
        this.selectionEnd = 0;
        this.searchPos = 0;
        this.storedScrollTop = 0;
        this.lastInput = null;
        this.lastCursor = {selectionStart: 0, selectionEnd: 0};
        this.history = new History();
        this.hasSaved = false;
        this.checkpoint = null;
    }
    TM.prototype = {
        get value() {
            this._value = this.doc.textContent;
            return this._value;
        },
        set value(value) {
            this.doc.textContent = value;
            var html = Markdown.toEditorHTML(value);
            var sel = this.getSelection();
            this.doc.innerHTML = html;
            this.selectionEnd = sel.selectionEnd;
            this.selectionStart = sel.selectionStart;
            this._value = value;
        },
        get text() {
            // this.text and this.value are now essentially
            // the same thing since we've switched from <div> to <pre>.
            return this.doc.textContent;
        },
        set text(value) {
            this.value = value;
        },
        get textContent() {
            return this.value;
        },
        set textContent(value) {
            this.value = value;
        },
        get selectionStart() {
            this._selection();
            return this._selectionStart;
        },
        set selectionStart(value) {
            this._selectionStart = value;
            this._updateSelection();
        },
        get selectionEnd() {
            this._selection();
            return this._selectionEnd;
        },
        set selectionEnd(value) {
            this._selectionEnd = value;
            this._updateSelection();
        }
    };
    TM.prototype.insertText = function (text, andSelectIt) {
        var val = this.value,
            start = this.selectionStart,
            end = this.selectionEnd;
        this.value = [val.slice(0, start), text, val.slice(end)].join("");
        this.selectionEnd = start + text.length;
        if (andSelectIt) {
            // We want to select the inserted text after it's been added.
            this.selectionStart = start;
        } else {
            this.selectionStart = start + text.length;
        }
        // Dispatch input event to update history.
        var e = new Event("input");
        this.doc.dispatchEvent(e);
    };
    TM.prototype.clone = function () {
        var ntm = this.init(this.value);
        var sel = this.getSelection();
        ntm.selectionEnd = sel.selectionEnd;
        ntm.selectionStart = sel.selectionStart;
        ntm.history = this.history;
        ntm.checkpoint = this.checkpoint;
        ntm.hasSaved = this.hasSaved;
        ntm.lastInput = this.lastInput;
        ntm.lastCursor = this.lastCursor;
        this.blur();
        ntm.storedScrollTop = this.storedScrollTop;
        return ntm;
    };
    TM.prototype.update = function () {
        window.tm = this;
    };
    TM.prototype.upgrade = function (tm) {
        var tmholder = document.getElementById("TMHolder");
        while (tmholder.lastChild) {
            tmholder.removeChild(tmholder.lastChild);
        }
        tmholder.appendChild(tm.doc);
    };
    TM.prototype.blur = function () {
        this.handleBlur();
        this.doc.blur();
    };
    TM.prototype.handleBlur = function () {
        this.storedScrollTop = this.doc.scrollTop;
    };
    TM.prototype.focus = function () {
        this.doc.focus();
        this.handleFocus();
    };
    TM.prototype.handleFocus = function () {
        this.doc.scrollTop = this.storedScrollTop;
        this.restoreSelection();
    };
    TM.prototype.isFocused = function () {
        return document.activeElement === this.doc;
    };
    TM.prototype.getSelection = function () {
        var selStart = this.selectionStart,
            selEnd = this.selectionEnd;
        return {selectionStart: selStart, selectionEnd: selEnd};
    };
    TM.prototype.restoreSelection = function () {
        this.selectionEnd = this.lastCursor.selectionEnd;
        this.selectionStart = this.lastCursor.selectionStart;
    };
    TM.prototype._selection = function () {
        var range;
        try {
            // This sometimes doesn't work in desktop app.
            range = window.getSelection().getRangeAt(0);
        } catch (e) {
            // Fix range by creating one.
            window.getSelection().addRange(document.createRange());
            range = window.getSelection().getRangeAt(0);
        }
        var rangeClone = range.cloneRange();
        rangeClone.selectNodeContents(this.doc);
        rangeClone.setEnd(range.startContainer, range.startOffset);
        this._selectionStart = rangeClone.toString().length;
        rangeClone.setEnd(range.endContainer, range.endOffset);
        this._selectionEnd = rangeClone.toString().length;
    };
    TM.prototype._updateSelection = function () {
        // TODO: Rewrite this.
        var range = document.createRange(),
            winselection = window.getSelection(),
            charIndex = 0,
            nodeStack = [this.doc],
            node,
            foundStart = false,
            start = this._selectionStart,
            end = this._selectionEnd,
            stop = false;
        range.setStart(this.doc, 0);
        range.collapse(true);
        while (!stop && (nodeStack.length > 0)) {
            node = nodeStack.pop();
            if (node.nodeType === 3) {
                var nextCharIndex = charIndex + node.length;
                if (!foundStart && start >= charIndex && start <= nextCharIndex) {
                    range.setStart(node, start - charIndex);
                    foundStart = true;
                }
                if (foundStart && end >= charIndex && end <= nextCharIndex) {
                    range.setEnd(node, end - charIndex);
                    stop = true;
                }
                charIndex = nextCharIndex;
            } else {
                var i = node.childNodes.length;
                while (i--) {
                    nodeStack.push(node.childNodes[i]);
                }
            }
        }
        winselection.removeAllRanges();
        winselection.addRange(range);
    };
    TM.prototype.select = function () {
        // selects whole document (textarea default functionality).
        this.selectionStart = 0;
        this.selectionEnd = this.text.length;
    };
    TM.prototype.find = function (value, backward, looping) {
        var pos;
        if (backward) { // findPrev
            var cal;
            if (this.searchPos === 0 || this.searchPos === value.length) {
                // at top, search from bottom
                cal = this.text.length;
            } else { // search above position.
                cal = this.searchPos - (value.length + 1);
            }
            pos =  this.text.lastIndexOf(value, cal);
        } else { // findNext
            pos = this.text.indexOf(value, this.searchPos);
            if (backward === undefined) {
                backward = false;
            }
        }

        if (pos !== -1) {
            this.selectionStart = pos;
            this.selectionEnd = pos + value.length;
            this.searchPos = pos + value.length;
            this.scrollToSelection();
            return true;
        }

        // Query not anywhere found after current position. Loop back to start
        // once.
        this.searchPos = 0;
        if (looping === undefined) {
            // loop once to go back to start of document if at bottom.
            return this.find(value, backward, true);
        }

        // Looped and still nothing found.
        alert("'" + value + "' not found");
        return false;
    };
    TM.prototype.findAll = function (value) {
        return this.text.split(value).length - 1;
    };
    TM.prototype.replace = function (value, replacement, backward) {
        if (value !== "") {
            var found = this.find(value, backward); // find and select thing
            if (found) {
                // replace selected text through insertText
                this.lastInput = null; // set lastInput to null so it forces an undo.
                this.insertText(replacement, true);
                return true;
            }
        }

        return false;
    };
    TM.prototype.replaceAll = function (value, replacement) {
        if (value !== "") {
            var oldContent = this.value;
            this.value = oldContent.split(value).join(replacement);
            this.history.change(
                this,
                {from: oldContent, to: this.value},
                this.getSelection()
            );
            // Dispatch input event to update history.
            var e = new Event("input");
            this.doc.dispatchEvent(e);
        }
    };
    TM.prototype.scrollToSelection = function () {
        var range = window.getSelection().getRangeAt(0),
            t = range.getBoundingClientRect().top;
        this.doc.scrollTop += t - window.innerHeight / 2;
        this.storedScrollTop = this.doc.scrollTop;
    };
    TM.prototype.getWordCount = function () {
        var doc = this.value.match(/\S+/g),
            subdoc = this.value.substring(this.selectionStart, this.selectionEnd),
            selection = subdoc.match(/\S+/g),
            docCount,
            selectCount;
        if (selection) {
            selectCount = selection.length;
        } else {
            selectCount = 0;
        }

        if (doc) {
            docCount = doc.length;
        } else {
            docCount = 0;
        }

        return {doc: docCount, selection: selectCount};
    };
    TM.prototype.init = function (val) {
        var tm = new TM(val);
        tm.doc.addEventListener("input", function () {
            var store = window.tm.store,
                value = window.tm.value;
            window.tm.history.change(
                window.tm,
                {from: store, to: value},
                window.tm.getSelection()
            );
            View.setFileDirty(true);
            View.displayWordCount();
            window.tm.store = window.tm.value;
            var html = Markdown.toEditorHTML(value);
            var sel = window.tm.getSelection();
            window.tm.doc.innerHTML = html;
            window.tm.selectionEnd = sel.selectionEnd;
            window.tm.selectionStart = sel.selectionStart;
        });
        tm.doc.addEventListener("keydown", function (e) {
            View.toggleSuperfluous(true);

            if (!e.metaKey && !e.altKey && e.keyIdentifier !== "Shift") {
                window.tm.lastInput = e.which;
            }

            // Insert tab.
            if (window.tm.isFocused() && e.which === 9) {
                window.tm.insertText("\t");
                e.preventDefault();
            }

            // store the cursor position/selection.
            window.tm.lastCursor = window.tm.getSelection();
        });
        tm.doc.addEventListener("keypress", function () {
            View.playClicks();
        });
        tm.doc.addEventListener("mouseup", function (e) {
            View.displayWordCount();

            // store the cursor position/selection.
            window.tm.lastCursor = window.tm.getSelection();

            // For shift-clicking on links so that they open.
            if (e.shiftKey && e.target.localName === "a") {
                if (!window.Wrong.gui) {
                    // Not using native app.
                    if (e.target.href.indexOf("javascript:") !== 0) {
                        window.top.open(e.target.href, "_blank");
                    } else {
                        window.location = e.target.href;
                    }
                } else {
                    // If using Desktop app, open in browser.
                    window.Wrong.gui.Shell.openExternal(e.target.href);
                }
            }
        });
        tm.doc.addEventListener("dragenter", function (e) {
            View.toggleSuperfluous(false);
        });
        tm.doc.addEventListener("drop", function (e) {
            var data = e.dataTransfer.getData("text");
            if (data.length > 0) {
                e.stopPropagation();
                tm.insertText(data, true);
            }
        });
        tm.doc.onpaste = function (e) {
            e.preventDefault();
            var content;
            if (e.clipboardData) {
                // cmd-paste
                content = e.clipboardData.getData("text/plain");
            } else {
                // Right-click > paste
                content = window.Wrong.clip.get();
            }
            var oldContent = window.tm.value;
            window.tm.insertText(content);
        };
        tm.doc.addEventListener("contextmenu", function (e) {
            // Insert editmenu on right-click.
            if (window.Wrong.editmenu) {
                window.Wrong.editmenu.popup(e.x, e.y);
            }
        });
        return tm;
    };
    return TM;
});
<|endoftext|>


<commit_before>(function($) {
    jQuery.fn.extend({
        html5_qrcode: function(qrcodeSuccess, qrcodeError, videoError) {
            return this.each(function() {
                var currentElem = $(this);

                var height = currentElem.height();
                var width = currentElem.width();

                if (height == null) {
                    height = 250;
                }

                if (width == null) {
                    width = 300;
                }

                var vidElem = $('<video width="' + width + 'px" height="' + height + 'px"></video>').appendTo(currentElem);
                var canvasElem = $('<canvas id="qr-canvas" width="' + (width - 2) + 'px" height="' + (height - 2) + 'px" style="display:none;"></canvas>').appendTo(currentElem);

                var video = vidElem[0];
                var canvas = canvasElem[0];
                var context = canvas.getContext('2d');
                var localMediaStream;
                video.setAttribute('autoplay','');

                var scan = function() {
                    if (localMediaStream) {
                        context.drawImage(video, 0, 0, 307, 250);

                        try {
                            qrcode.decode();
                        } catch (e) {
                            qrcodeError(e, localMediaStream);
                        }

                        $.data(currentElem[0], "timeout", setTimeout(scan, 500));

                    } else {
                        $.data(currentElem[0], "timeout", setTimeout(scan, 500));
                    }
                };//end snapshot function

                window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
                navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

                var successCallback = function(stream) {
                    video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
                    localMediaStream = stream;
                    $.data(currentElem[0], "stream", stream);

                    video.play();
                    $.data(currentElem[0], "timeout", setTimeout(scan, 1000));
                };

                // Call the getUserMedia method with our callback functions
                if (navigator.getUserMedia) {
                    navigator.getUserMedia({video: {facingMode:"environment"}}, successCallback, function(error) {
                        videoError(error, localMediaStream);
                    });
                } else {
                    console.log('Native web camera streaming (getUserMedia) not supported in this browser.');
                    // Display a friendly "sorry" message to the user
                }

                qrcode.callback = function (result) {
                    qrcodeSuccess(result, localMediaStream);
                };
            }); // end of html5_qrcode
        },
        html5_qrcode_stop: function() {
            return this.each(function() {
                //stop the stream and cancel timeouts
                $(this).data('stream').getVideoTracks().forEach(function(videoTrack) {
                    videoTrack.stop();
                });

                clearTimeout($(this).data('timeout'));
            });
        }
    });
})(jQuery);<commit_msg>try making the qr reader a bit faster<commit_after>(function($) {
    jQuery.fn.extend({
        html5_qrcode: function(qrcodeSuccess, qrcodeError, videoError) {
            return this.each(function() {
                var currentElem = $(this);

                var height = currentElem.height();
                var width = currentElem.width();

                if (height == null) {
                    height = 250;
                }

                if (width == null) {
                    width = 300;
                }

                var vidElem = $('<video width="' + width + 'px" height="' + height + 'px"></video>').appendTo(currentElem);
                var canvasElem = $('<canvas id="qr-canvas" width="' + (width - 2) + 'px" height="' + (height - 2) + 'px" style="display:none;"></canvas>').appendTo(currentElem);

                var video = vidElem[0];
                var canvas = canvasElem[0];
                var context = canvas.getContext('2d');
                var localMediaStream;
                video.setAttribute('autoplay','');

                var scan = function() {
                    if (localMediaStream) {
                        context.drawImage(video, 0, 0, 307, 250);

                        try {
                            qrcode.decode();
                        } catch (e) {
                            qrcodeError(e, localMediaStream);
                        }

                        $.data(currentElem[0], "timeout", setTimeout(scan, 250));

                    } else {
                        $.data(currentElem[0], "timeout", setTimeout(scan, 500));
                    }
                };//end snapshot function

                window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
                navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

                var successCallback = function(stream) {
                    video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
                    localMediaStream = stream;
                    $.data(currentElem[0], "stream", stream);

                    video.play();
                    $.data(currentElem[0], "timeout", setTimeout(scan, 500));
                };

                // Call the getUserMedia method with our callback functions
                if (navigator.getUserMedia) {
                    navigator.getUserMedia({video: {facingMode:"environment"}}, successCallback, function(error) {
                        videoError(error, localMediaStream);
                    });
                } else {
                    console.log('Native web camera streaming (getUserMedia) not supported in this browser.');
                    // Display a friendly "sorry" message to the user
                }

                qrcode.callback = function (result) {
                    qrcodeSuccess(result, localMediaStream);
                };
            }); // end of html5_qrcode
        },
        html5_qrcode_stop: function() {
            return this.each(function() {
                //stop the stream and cancel timeouts
                $(this).data('stream').getVideoTracks().forEach(function(videoTrack) {
                    videoTrack.stop();
                });

                clearTimeout($(this).data('timeout'));
            });
        }
    });
})(jQuery);<|endoftext|>


<commit_before>import {Store} from 'flummox';
import _m from 'mori';

class TeamStore extends Store {
    constructor(flux) {
        super();

        const teamActions = flux.getActions('team');

        this._empty();

        this.registerAsync(
            teamActions.fetchAccounts,
            null,
            this.receiveAccounts,
            null);
    }

    receiveAccounts(accounts) {
        this.setState({
            accounts: _m.toClj(accounts)
        });
    }

    getAccounts() {
        return _m
                .toJs(this.state.accounts)
                .sort((a, b) => {
                    let aName = a.name.toLowerCase(),
                        bName = b.name.toLowerCase();
                    return aName < bName ?
                            -1 :
                            bName < aName ?
                                1 : 0;
                });
    }

    _empty() {
        this.setState({
            accounts: _m.vector()
        });
    }
}

export default TeamStore;
<commit_msg>#260 immutable team<commit_after>import {Store} from 'flummox';
import Immutable from 'immutable';

class TeamStore extends Store {
    constructor(flux) {
        super();

        const teamActions = flux.getActions('team');

        this._empty();

        this.registerAsync(
            teamActions.fetchAccounts,
            null,
            this.receiveAccounts,
            null);
    }

    receiveAccounts(accounts) {
        this.setState({
            accounts: Immutable.fromJS(accounts)
        });
    }

    getAccounts() {
        return this.state.accounts
                .sortBy(a => a.get('name').toLowerCase())
                .toJS();
    }

    _empty() {
        this.setState({
            accounts: Immutable.List()
        });
    }
}

export default TeamStore;
<|endoftext|>


<commit_before>/*
 * This file is part of Invenio.
 * Copyright (C) 2013, 2014 CERN.
 *
 * Invenio is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * Invenio is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Invenio; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

/* A file contatining fuctions treating the search field. */
/**
 * @requires jQuery-caret: https://github.com/acdvorak/jquery.caret
 * @requires search_parser.js: invenio/modules/search
 *
 *
 * CONFIGURATION

  Example:

  searchField.searchTypeahead({
    value_hints_url: '/list/%TYPE?q=%QUERY',
    options_sets: {
      invenio: invenio_parser_options,
      spires: spires_parser_options
    },
    default_set: 'invenio'
  }

  searchField - jQuery selector
  value_hints_url - url for getting remote queries - other than keywords
    e.g. authors
  options_sets - syntax schema, there can be many of them switched with custom keywords
  default_set - default options set, used when the typeahead field is empty

  Below an example of one of the options set

  var invenio_parser_options = {
      keywords: {
        SEARCH: {
          SPIRES_SWITCH: {
            min_length: 1,
            keyword_function: setSpireSyntax,
            detection_condition: isFirstWord,
            values: ['find'],
            autocomplete_suffix: ' '
          },
          LOGICAL_EXP: {
            min_length: 1,
            values: ['AND', 'OR', 'AND NOT'],
            autocomplete_suffix: ' '
          }
        },
        ORDER: {
          QUERY_TYPE: {
            min_length: 1,
            finish_condition: endsWithColon,
            values: area_keywords,
            autocomplete_suffix: ':'
          },
          QUERY_VALUE: {
            min_length: 3,
            finish_condition: notEndsWithColon
          }
        }
      },
      get_next_word_type: get_next_word_type,
      value_type_interpretation: {
        author: 'exactauthor'
      },
      separators: [' ', '(', ')', ':']
    };

    separators - all keywords separators
    value_type_interpretation - keys are QUERY_TYPE values,
     whereas values are the corresponding strings used
     for substitution of '%TYPE' string in value_hints_url
     in the main configuration options.

    get_next_word_type(previous_word_type, word_types) -
      function used by ORDER method to get the next word type
      can return array of keywords names, but there cannot be
      two of them from ORDER method
        word_types - all the keywords names

    keywords - a dictionary with all the words types interpreted
      by the parser.

      First key is the method used for parsing.

      There are two methods:
        SEARCH - searches for the keyword in a parsed string and
          marks it corespondingly,
        ORDER - detects the kind of typeahead basing the decision
          on the order of words using get_next_word_type function

      Method SEARCH has priority over method ORDER. It may be used
      to find keywords containing separators as well as special
      functional keywords which are used to change option set
      (key options_sets in configuration).

    Parsing algorithm:
      1. do SEARCH method - look for keywords
      2. find separators which are not marked as words
        with SEARCH method
      3. do ORDER method - get type of every not marked
        keyword basing on the get_next_word_type function

    Inside methods configuration there are keywords defined.

    KEYWORDS_GROUP_NAME: {
      min_length: 1,
      keyword_function: function(search_typeahead),
      detection_condition: function(str, char_roles, start_idx),
      finish_condition: function(str, char_roles, end_idx)
      values: [],
      autocomplete_suffix: ' '
    }

    KEYWORDS_GROUP_NAME - just identifier of the group
    min_length - minimal length to show the hints
    keyword_function - function run on keyword detection
      search_typeahead - typeahead object
    detection_condition - addtional detection condition boolean function
      tested for SEARCH method keywords (optional)
      when false the string part will not be marked as the
      keyword despite such a string was found
    finish_condition - addtional word finish condition boolean
      function tested for ORDER method keywords
      when false the keyword will be marked continually despde
      a following separator (optional)
    values - possible values of a keyword - required for all
      keywords beside QUERY_VALUE which values are get remotely
    autocomplete_suffix - string added after the autocompleted
      value, may be a default separator
 *
 */

define([
  'jquery',
  'js/search/search_parser',
  'typeahead', // $.fn.typeahead()
], function($, SearchParser) {
  "use strict";

  function SearchTypeahead(element, options) {

    this.$element = $(element);
    this.options = $.extend({}, $.fn.searchTypeahead.defaults,
      options);

    this.dontBracket = false;
    this.value_types = this.options.value_types;
    var that = this;

    for (var i in this.options.options_sets) {
      this.options.options_sets[i] =
        this.initializeOptionsSet(this.options.options_sets[i]);
    }

    this.parser = new SearchParser(this.options.options_sets, this.options.default_set);

    this.initTypeahead();

    this.ttTypeahead = this.$element.data("ttTypeahead");

    // saves overwritten functions
    this.orgTypeahead = {
      setInputValue: this.ttTypeahead.input.setInputValue,
      setHintValue: this.ttTypeahead.input.setHintValue,
    };

    this.ttTypeahead.input.setInputValue = function(value, silent) {
      return that.setInputFieldValue.apply(that, [value, silent]);
    };

    // update parser state on input event
    this.$element.on('input', function(event) {
      var input_field_value = $(this).val();
      that.parser.updateSource(input_field_value, $(this).caret());
    });

    // disable grey hint in input field background - not compatible yet
    // with this kind of typeahead
    this.ttTypeahead.input.setHintValue = function(value) {};

    // sets initial query_range
    this.parser.reparseSource(this.$element.val());
    this.query_range = this.parser.getQueryRangeIdx(this.$element.val().length);
  }

  var PluginClass = SearchTypeahead;
  var dataLabel = 'search_typeahead';

  SearchTypeahead.prototype = {

    /**
     * Setups the typeahead element
     */
    initTypeahead: function() {

      var that = this;

      var engine = new Bloodhound({
        remote: {
          url: this.options.value_hints_url,
          replace: function(url, query) {
            return that.getUrl.call(that, url, query);
          },
          filter: this.processResponse
        },
        datumTokenizer: function(d) {
          return Bloodhound.tokenizers.whitespace(d.value);
        },
        // not used after the modifications but required by bloodhound
        queryTokenizer: Bloodhound.tokenizers.whitespace
      });

      for (var set_name in this.options.options_sets) {
        var options = this.options.options_sets[set_name];
        options.indices = this.createIndices(engine, options.keywords);
      }

      engine.get = function(field_value, cb) {
        return that.getHints(field_value, cb, this);
      };

      engine.initialize();

      this.$element.typeahead({
        // min length is controlled in getHints function
        // this setting is to pass everything
        minLength: 1
      },
      {
        source: engine.ttAdapter(),
        displayKey: 'value'
      });
    },

    /**
     * Initialize an option set
     *
     * @param options option set
     * @returns initialized set
     */
    initializeOptionsSet: function(options) {
      options.word_types = {};
      options.keywords_flat = {};
      for (var method_key in options.keywords) {
        var method = options.keywords[method_key];
        for (var word_type in method) {
          var conf = method[word_type];
          options.keywords_flat[word_type] = conf;
        }
      }

      return options;
    },

    /**
     * Creates search indices for typeahead engine
     *
     * @param engine empty engine should be passed here
     * @param keywords keywords configuration -
     *  the part passed in to the class constructor at key
     *  keywords
     * @returns {Array} Array of search indices
     */
    createIndices: function(engine, keywords) {
      var search_indices = [];

      for (var method_key in keywords) {
        var method = keywords[method_key];
        for (var word_type in method) {
          var conf = method[word_type];
          if (conf.values === undefined)
            continue;

          var index = deepCopy(engine.index);
          index.add(convertToTypeaheadDict(conf));
          search_indices[word_type] = index;
        }
      }

      return search_indices;

      function deepCopy(obj) {
        /// clones an object
        return jQuery.extend(true, {}, obj);
      }

      function convertToTypeaheadDict(conf) {
        var suffix = '';
        if (conf.autocomplete_suffix)
          suffix += conf.autocomplete_suffix;
        return $.map(conf.values,
          function(val, i) {
            var result = {
              value: val + suffix,
              raw_value: val,
              suffix: suffix
            };
            return result;
          }
        );
      }
    },

    /**
     * Updates the template url with a query
     *
     * @param url template url containing '%TYPE' in
     *  the place of query type and '%QUERY' in the place
     *  of query value
     * @param query {Object} an object with properties:
     *  remote: the string to be put instead of %TYPE
     *  value: the string to be put instead of %QUERY
     * @returns {String} the result url
     */
    getUrl: function(url, query) {

      url = url.replace('%TYPE', query.remote);
      url = url.replace('%QUERY', query.value);

      return url;
    },

    /**
     * Processes the coming response to get the one in the format
     * expected by typeahead - an Array of dictionaries
     *
     * @param response
     * @returns {*}
     */
    processResponse: function(response) {
      return response.results;
    },

    /**
     * Fetches hints for typeahead
     *
     * @param field_value the new value of the input field
     * @param cb typeahead callback
     * @param bloodhound bloodhound engine
     */
    getHints: function(field_value, cb, bloodhound) {
      var matches = [];

      var caretIdx = this.$element.caret();

      this.parser.updateSource(field_value, caretIdx);
      this.query_range = this.parser.getQueryRangeIdx(caretIdx);
      var query = this.parser.getAutocompleteQuery(
        this.query_range.start, caretIdx);

      // saves the current query inside typeahead to prevent improper text
      // merging on blur
      this.ttTypeahead.input.setQuery(query.value);

      var options_set = this.options.options_sets[
        this.parser.getOptionsSetName()
      ];

      if (!query.type) {
        cb && cb([]);
        return;
      }

      if (query.type == options_set.word_types.QUERY_VALUE && query.remote) {
        if (query.value.length < getMinLength(query.type)) {
          cb && cb([]);
          return;
        }
        // later used in setInputValue cannot be passed in another way
        this.dontBracket = false;
        bloodhound._getFromRemote(query, returnRemoteMatches);
        return;
      } else {

        // assure it's an array
        query.type = [].concat(query.type);
        var search_indices = options_set.indices;

        for (var i in query.type) {
          var type_name = query.type[i];
          if (query.value.length < getMinLength(type_name))
            continue;
          if (!search_indices[type_name])
            continue;
          matches = matches.concat(search_indices[type_name].get(query.value));
        }
        if (matches.length > 0) {
          matches = bloodhound.sorter(matches).slice(0, bloodhound.limit);
        }
        this.dontBracket = true;
        cb && cb(matches);
      }

      function returnRemoteMatches(remoteMatches) {
          cb && cb(bloodhound.sorter(remoteMatches));
      }

      function getMinLength(type) {
        return options_set.keywords_flat[type].min_length;
      }
    },

    /**
     * Merges the current input field value with a hint
     * from typeahead
     *
     * @param {String} to_merge the value to be merged
     * @param {*} query_range
     * @returns {string} merged string
     */
    mergeWithCurrentInputFieldValue: function(to_merge, query_range) {
      var input_field_value = this.$element.val();

      var precedingStr = input_field_value.slice(
        0, query_range.start);
      var followingStr = input_field_value.slice(
        query_range.end, input_field_value.length);

      if (precedingStr[precedingStr.length - 1] == '"' &&
          to_merge[0] == '"') {
        precedingStr = precedingStr.slice(0, precedingStr.length - 1);
      }

      return precedingStr + to_merge + followingStr;
    },

    /**
     * Does all the tricks which need to be done at setting
     * value of the input field.
     *
     * @param {String} value typeahead suggestion
     * @param silent corresponding twitter's typeahead parameter - see
     *   twitter typeahead documentation
     * @returns {*}
     */
    setInputFieldValue: function(value, silent) {

      var bracketedValue = value;
      if (value.indexOf(' ') > -1 && !this.dontBracket) {
        bracketedValue = bracketStr(value);
      }

      var merged = this.mergeWithCurrentInputFieldValue(
        bracketedValue, this.query_range);

      // run original setInputValue with merged value
      var result = this.orgTypeahead.setInputValue.call(
        this.ttTypeahead.input, merged, silent);

      // update query range
      this.query_range.end =
        this.query_range.start + bracketedValue.length;

      // set caret position
      var new_caret_pos = this.query_range.end;
      this.$element.caret(new_caret_pos);

      // update parser
      this.parser.updateSource(merged, new_caret_pos);
      return result;

      function bracketStr(str) {
        if (str[0] == '\"')
          return str + '"';
        return '"' + str + '"';
      }
    },

    /**
     * The function should be used to set field value of
     * typeahead-enabled input field using javascript.
     * It updates internal query value of typeahead.js
     * to which the field is reseted on blur event.
     *
     * @method setFieldValue
     * @param {String} new_value new value to set
     */
    setFieldValue: function(new_value) {
      this.$element.val(new_value);
      this.ttTypeahead.input.setQuery(new_value);
    }
  };

  $.fn.searchTypeahead = function (option) {

    var $elements = this;

    return $elements.map(function (idx, element) {
      var $element = $(element);
      var object = $element.data(dataLabel)
      var options = typeof option == 'object' && option;
      // attach jQuery plugin
      if (!object) {
        object = new PluginClass($element, options)
        $element.data(dataLabel, object)
      }
      return object;
    });
  };

  $.fn.searchTypeahead.defaults = {};

});
<commit_msg>search: fix for stucked focus on the search field<commit_after>/*
 * This file is part of Invenio.
 * Copyright (C) 2013, 2014 CERN.
 *
 * Invenio is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * Invenio is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Invenio; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

/* A file contatining fuctions treating the search field. */
/**
 * @requires jQuery-caret: https://github.com/acdvorak/jquery.caret
 * @requires search_parser.js: invenio/modules/search
 *
 *
 * CONFIGURATION

  Example:

  searchField.searchTypeahead({
    value_hints_url: '/list/%TYPE?q=%QUERY',
    options_sets: {
      invenio: invenio_parser_options,
      spires: spires_parser_options
    },
    default_set: 'invenio'
  }

  searchField - jQuery selector
  value_hints_url - url for getting remote queries - other than keywords
    e.g. authors
  options_sets - syntax schema, there can be many of them switched with custom keywords
  default_set - default options set, used when the typeahead field is empty

  Below an example of one of the options set

  var invenio_parser_options = {
      keywords: {
        SEARCH: {
          SPIRES_SWITCH: {
            min_length: 1,
            keyword_function: setSpireSyntax,
            detection_condition: isFirstWord,
            values: ['find'],
            autocomplete_suffix: ' '
          },
          LOGICAL_EXP: {
            min_length: 1,
            values: ['AND', 'OR', 'AND NOT'],
            autocomplete_suffix: ' '
          }
        },
        ORDER: {
          QUERY_TYPE: {
            min_length: 1,
            finish_condition: endsWithColon,
            values: area_keywords,
            autocomplete_suffix: ':'
          },
          QUERY_VALUE: {
            min_length: 3,
            finish_condition: notEndsWithColon
          }
        }
      },
      get_next_word_type: get_next_word_type,
      value_type_interpretation: {
        author: 'exactauthor'
      },
      separators: [' ', '(', ')', ':']
    };

    separators - all keywords separators
    value_type_interpretation - keys are QUERY_TYPE values,
     whereas values are the corresponding strings used
     for substitution of '%TYPE' string in value_hints_url
     in the main configuration options.

    get_next_word_type(previous_word_type, word_types) -
      function used by ORDER method to get the next word type
      can return array of keywords names, but there cannot be
      two of them from ORDER method
        word_types - all the keywords names

    keywords - a dictionary with all the words types interpreted
      by the parser.

      First key is the method used for parsing.

      There are two methods:
        SEARCH - searches for the keyword in a parsed string and
          marks it corespondingly,
        ORDER - detects the kind of typeahead basing the decision
          on the order of words using get_next_word_type function

      Method SEARCH has priority over method ORDER. It may be used
      to find keywords containing separators as well as special
      functional keywords which are used to change option set
      (key options_sets in configuration).

    Parsing algorithm:
      1. do SEARCH method - look for keywords
      2. find separators which are not marked as words
        with SEARCH method
      3. do ORDER method - get type of every not marked
        keyword basing on the get_next_word_type function

    Inside methods configuration there are keywords defined.

    KEYWORDS_GROUP_NAME: {
      min_length: 1,
      keyword_function: function(search_typeahead),
      detection_condition: function(str, char_roles, start_idx),
      finish_condition: function(str, char_roles, end_idx)
      values: [],
      autocomplete_suffix: ' '
    }

    KEYWORDS_GROUP_NAME - just identifier of the group
    min_length - minimal length to show the hints
    keyword_function - function run on keyword detection
      search_typeahead - typeahead object
    detection_condition - addtional detection condition boolean function
      tested for SEARCH method keywords (optional)
      when false the string part will not be marked as the
      keyword despite such a string was found
    finish_condition - addtional word finish condition boolean
      function tested for ORDER method keywords
      when false the keyword will be marked continually despde
      a following separator (optional)
    values - possible values of a keyword - required for all
      keywords beside QUERY_VALUE which values are get remotely
    autocomplete_suffix - string added after the autocompleted
      value, may be a default separator
 *
 */

define([
  'jquery',
  'js/search/search_parser',
  'typeahead', // $.fn.typeahead()
], function($, SearchParser) {
  "use strict";

  function SearchTypeahead(element, options) {

    this.$element = $(element);
    this.options = $.extend({}, $.fn.searchTypeahead.defaults,
      options);

    this.dontBracket = false;
    this.value_types = this.options.value_types;
    var that = this;

    for (var i in this.options.options_sets) {
      this.options.options_sets[i] =
        this.initializeOptionsSet(this.options.options_sets[i]);
    }

    this.parser = new SearchParser(this.options.options_sets, this.options.default_set);

    this.initTypeahead();

    this.ttTypeahead = this.$element.data("ttTypeahead");

    // saves overwritten functions
    this.orgTypeahead = {
      setInputValue: this.ttTypeahead.input.setInputValue,
      setHintValue: this.ttTypeahead.input.setHintValue,
    };

    this.ttTypeahead.input.setInputValue = function(value, silent) {
      return that.setInputFieldValue.apply(that, [value, silent]);
    };

    // update parser state on input event
    this.$element.on('input', function(event) {
      var input_field_value = $(this).val();
      that.parser.updateSource(input_field_value, $(this).caret());
    });

    // disable grey hint in input field background - not compatible yet
    // with this kind of typeahead
    this.ttTypeahead.input.setHintValue = function(value) {};

    // sets initial query_range
    this.parser.reparseSource(this.$element.val());
    this.query_range = this.parser.getQueryRangeIdx(this.$element.val().length);
  }

  var PluginClass = SearchTypeahead;
  var dataLabel = 'search_typeahead';

  SearchTypeahead.prototype = {

    /**
     * Setups the typeahead element
     */
    initTypeahead: function() {

      var that = this;

      var engine = new Bloodhound({
        remote: {
          url: this.options.value_hints_url,
          replace: function(url, query) {
            return that.getUrl.call(that, url, query);
          },
          filter: this.processResponse
        },
        datumTokenizer: function(d) {
          return Bloodhound.tokenizers.whitespace(d.value);
        },
        // not used after the modifications but required by bloodhound
        queryTokenizer: Bloodhound.tokenizers.whitespace
      });

      for (var set_name in this.options.options_sets) {
        var options = this.options.options_sets[set_name];
        options.indices = this.createIndices(engine, options.keywords);
      }

      engine.get = function(field_value, cb) {
        return that.getHints(field_value, cb, this);
      };

      engine.initialize();

      this.$element.typeahead({
        // min length is controlled in getHints function
        // this setting is to pass everything
        minLength: 1
      },
      {
        source: engine.ttAdapter(),
        displayKey: 'value'
      });
    },

    /**
     * Initialize an option set
     *
     * @param options option set
     * @returns initialized set
     */
    initializeOptionsSet: function(options) {
      options.word_types = {};
      options.keywords_flat = {};
      for (var method_key in options.keywords) {
        var method = options.keywords[method_key];
        for (var word_type in method) {
          var conf = method[word_type];
          options.keywords_flat[word_type] = conf;
        }
      }

      return options;
    },

    /**
     * Creates search indices for typeahead engine
     *
     * @param engine empty engine should be passed here
     * @param keywords keywords configuration -
     *  the part passed in to the class constructor at key
     *  keywords
     * @returns {Array} Array of search indices
     */
    createIndices: function(engine, keywords) {
      var search_indices = [];

      for (var method_key in keywords) {
        var method = keywords[method_key];
        for (var word_type in method) {
          var conf = method[word_type];
          if (conf.values === undefined)
            continue;

          var index = deepCopy(engine.index);
          index.add(convertToTypeaheadDict(conf));
          search_indices[word_type] = index;
        }
      }

      return search_indices;

      function deepCopy(obj) {
        /// clones an object
        return jQuery.extend(true, {}, obj);
      }

      function convertToTypeaheadDict(conf) {
        var suffix = '';
        if (conf.autocomplete_suffix)
          suffix += conf.autocomplete_suffix;
        return $.map(conf.values,
          function(val, i) {
            var result = {
              value: val + suffix,
              raw_value: val,
              suffix: suffix
            };
            return result;
          }
        );
      }
    },

    /**
     * Updates the template url with a query
     *
     * @param url template url containing '%TYPE' in
     *  the place of query type and '%QUERY' in the place
     *  of query value
     * @param query {Object} an object with properties:
     *  remote: the string to be put instead of %TYPE
     *  value: the string to be put instead of %QUERY
     * @returns {String} the result url
     */
    getUrl: function(url, query) {

      url = url.replace('%TYPE', query.remote);
      url = url.replace('%QUERY', query.value);

      return url;
    },

    /**
     * Processes the coming response to get the one in the format
     * expected by typeahead - an Array of dictionaries
     *
     * @param response
     * @returns {*}
     */
    processResponse: function(response) {
      return response.results;
    },

    /**
     * Fetches hints for typeahead
     *
     * @param field_value the new value of the input field
     * @param cb typeahead callback
     * @param bloodhound bloodhound engine
     */
    getHints: function(field_value, cb, bloodhound) {
      var matches = [];

      var caretIdx = this.$element.caret();

      this.parser.updateSource(field_value, caretIdx);
      this.query_range = this.parser.getQueryRangeIdx(caretIdx);
      var query = this.parser.getAutocompleteQuery(
        this.query_range.start, caretIdx);

      // saves the current query inside typeahead to prevent improper text
      // merging on blur
      this.ttTypeahead.input.setQuery(query.value);

      var options_set = this.options.options_sets[
        this.parser.getOptionsSetName()
      ];

      if (!query.type) {
        cb && cb([]);
        return;
      }

      if (query.type == options_set.word_types.QUERY_VALUE && query.remote) {
        if (query.value.length < getMinLength(query.type)) {
          cb && cb([]);
          return;
        }
        // later used in setInputValue cannot be passed in another way
        this.dontBracket = false;
        bloodhound._getFromRemote(query, returnRemoteMatches);
        return;
      } else {

        // assure it's an array
        query.type = [].concat(query.type);
        var search_indices = options_set.indices;

        for (var i in query.type) {
          var type_name = query.type[i];
          if (query.value.length < getMinLength(type_name))
            continue;
          if (!search_indices[type_name])
            continue;
          matches = matches.concat(search_indices[type_name].get(query.value));
        }
        if (matches.length > 0) {
          matches = bloodhound.sorter(matches).slice(0, bloodhound.limit);
        }
        this.dontBracket = true;
        cb && cb(matches);
      }

      function returnRemoteMatches(remoteMatches) {
          cb && cb(bloodhound.sorter(remoteMatches));
      }

      function getMinLength(type) {
        return options_set.keywords_flat[type].min_length;
      }
    },

    /**
     * Merges the current input field value with a hint
     * from typeahead
     *
     * @param {String} to_merge the value to be merged
     * @param {*} query_range
     * @returns {string} merged string
     */
    mergeWithCurrentInputFieldValue: function(to_merge, query_range) {
      var input_field_value = this.$element.val();

      var precedingStr = input_field_value.slice(
        0, query_range.start);
      var followingStr = input_field_value.slice(
        query_range.end, input_field_value.length);

      if (precedingStr[precedingStr.length - 1] == '"' &&
          to_merge[0] == '"') {
        precedingStr = precedingStr.slice(0, precedingStr.length - 1);
      }

      return precedingStr + to_merge + followingStr;
    },

    /**
     * Checks if the input field is focused.
     *
     * @returns {boolean}
     * @private
     */
    _isFocused: function() {
      return !!this.$element.filter($(document.activeElement)).length;
    },

    /**
     * Does all the tricks which need to be done at setting
     * a value of the input field.
     *
     * It is run also by resetInputValue from twitter's typeahead.js on blur
     * event.
     *
     * @param {String} value typeahead suggestion
     * @param silent corresponding twitter's typeahead parameter - see
     *   twitter typeahead documentation
     * @returns {*}
     */
    setInputFieldValue: function(value, silent) {

      var bracketedValue = value;
      if (value.indexOf(' ') > -1 && !this.dontBracket) {
        bracketedValue = bracketStr(value);
      }

      var merged = this.mergeWithCurrentInputFieldValue(
        bracketedValue, this.query_range);

      // run original setInputValue with merged value
      // must be run before setting the caret position as the caret position
      // should be updated after updating the value of the input field
      var result = this.orgTypeahead.setInputValue.call(
        this.ttTypeahead.input, merged, silent);

      // update query range
      this.query_range.end =
        this.query_range.start + bracketedValue.length;

      // update the parser until the end of the typed and autocompleted part of
      // the query
      this.parser.updateSource(merged, this.query_range.end);

      // To set the caret position the element must be focused, otherwise
      // $.fn.caret focuses it which is not the desired result on blur event.
      // When the element is not focused we don't care about the caret position
      // update. In this situation a focus event by pressing Tab button selects
      // the whole text, whereas focus by clicking moves the caret to the click
      // position, so the caret position is not stored anyway.
      if (this._isFocused())
        // if a user types and just autocompleted, move the caret to the end of
        // the autocompleted part
        this.$element.caret(this.query_range.end);

      return result;

      function bracketStr(str) {
        if (str[0] == '\"')
          return str + '"';
        return '"' + str + '"';
      }
    },

    /**
     * The function should be used to set field value of
     * typeahead-enabled input field using javascript.
     * It updates internal query value of typeahead.js
     * to which the field is reseted on blur event.
     *
     * @method setFieldValue
     * @param {String} new_value new value to set
     */
    setFieldValue: function(new_value) {
      this.$element.val(new_value);
      this.ttTypeahead.input.setQuery(new_value);
    }
  };

  $.fn.searchTypeahead = function (option) {

    var $elements = this;

    return $elements.map(function (idx, element) {
      var $element = $(element);
      var object = $element.data(dataLabel)
      var options = typeof option == 'object' && option;
      // attach jQuery plugin
      if (!object) {
        object = new PluginClass($element, options)
        $element.data(dataLabel, object)
      }
      return object;
    });
  };

  $.fn.searchTypeahead.defaults = {};

});
<|endoftext|>


<commit_before>// http://developer.appcelerator.com/question/124014/saving-xml-file-offline-for-read-later
function getData(url, f, win){

if(Ti.Platform.name === 'iPhone OS') {
    var activityStyle = Ti.UI.iPhone.ActivityIndicatorStyle.DARK;
} else {
    var activityStyle = Ti.UI.ActivityIndicatorStyle.DARK;
}

//innitialise the array
var data = [];
//if internet connection is on - continue
if(Titanium.Network.online) {
    //Show the activity indicator
var activityIndicator = Ti.UI.createActivityIndicator({
    height: '100%',
    width: '100%',
    color: '#404347',
    backgroundColor: '#d8d8d8',
    font: {
        fontFamily: 'Helvetica Neue',
        fontSize: 14,
        fontWeight: 'normal'
    },
    message: 'Loading...',
    style: activityStyle,
});
win.add(activityIndicator);
activityIndicator.show();

    //open network connection
    var xhr = Ti.Network.createHTTPClient({
        cache: Ti.App.Properties.getBool('cache', true),
        timeout:5000,
    });
    xhr.open('GET', url);
    xhr.onload = function () {
        //Writing data to a file
        f.write(this.responseData);
        getXMLdata(f);
        showTable(win);
    };

    xhr.onerror = function() {
        Ti.API.info('XHR Error: ' + xhr.status + ' - ' + xhr.statusText);
     //check response status and act aaccordingly.
     if(xhr.status != 200) {
        if(f.exists()) {
        getXMLdata(f);
        showTable(win);
        alert('Offline Mode');
       }
        else if(!f.exists()) {
        activityIndicator.hide();
        alert('The service is currently unavailable. Please Try Again Later.');
        }
    }};
    try {
        xhr.send();
    } catch(e) {
        Ti.API.info('error with xhr.send(): '+e);
        xhr.abort();
        activityIndicator.hide();
    }
}
else if(f.exists()) {
        getXMLdata(f);
        showTable(win);
    }
else if(!f.exists()) {
        activityIndicator.hide();
        alert('Your device is not connected to the internet.');
}

function showTable(win) {
    var searchBar = Titanium.UI.createSearchBar({
    barColor:'#bbb',
    tintColor :'#980012',
    height:43,
    top:0,
    });
    // create table
    var tableView = Ti.UI.createTableView({
        data: data,
        search:searchBar,
        filterAttribute:'filter',
        searchHidden:true,
        hideSearchOnSelection: true,
    });
    win.add(tableView);
    // add event handeler
    tableView.addEventListener('click', function (e) {
        /*
        var detailWin = Ti.UI.createWindow({
            //title of the label that the user selected
            title: e.row.children[0].text,
            barColor: '#650000',
            url: 'tableDetail.js',
       });
       */
           //alternative method:
           // var Window = require('windowClass');
        var detailWin = new Window (e.row.children[0].text, 'tableDetail.js');
        detailWin.desc = e.row.desc;
        tabGroup.activeTab.open(detailWin, {
            animation: true
        });
        //Hide the activity indicator when the funtion has completed
        activityIndicator.hide();
    });
    searchBar.addEventListener('change', function (e) {
        Ti.App.Properties.setString('search', searchBar.value);
    });
    win.addEventListener('focus', function(e) {
        if(searchBar.value){
        searchBar.value=Ti.App.Properties.getString('search','');
        tableView.searchHidden=false;
        }
    });
};

function getXMLdata(file) {
    if(file.exists()) {
        //read file
        var contents = f.read().text;
// Ti.API.info('contents = ' + contents);
        var doc = Ti.XML.parseString(contents);
        //var doc = this.responseXML.documentElement;
        var items = doc.getElementsByTagName('item');
        var x = 0;
        for(var i = 0; i < items.length; i++) {
            var item = items.item(i);
            var title = item.getElementsByTagName('title').item(0).text;
            var description = item.getElementsByTagName('description').item(0).text;
            var pubDate = item.getElementsByTagName('pubDate').item(0).text;
            var link = item.getElementsByTagName('link').item(0).text;
            //display content and create objects
            var row = Ti.UI.createTableViewRow({
                height: 80,
                layout: 'vertical',
                selectedBackgroundColor: '#650000',
            });
            row.filter = title; //data for search
            var labelText = title;
            var label = Ti.UI.createLabel({
                text: labelText,
                highlightedColor: '#fff',
                left: 5,
                top: 5,
                bottom: 5,
                right: 5,
            });
            //add objects
            row.add(label);
            row.desc = description;
            data[x++] = row;
        }
    }
}}
<commit_msg>removed unessesary passed var's<commit_after>// http://developer.appcelerator.com/question/124014/saving-xml-file-offline-for-read-later
function getData(url, f, win){

if(Ti.Platform.name === 'iPhone OS') {
    var activityStyle = Ti.UI.iPhone.ActivityIndicatorStyle.DARK;
} else {
    var activityStyle = Ti.UI.ActivityIndicatorStyle.DARK;
}

//innitialise the array
var data = [];
//if internet connection is on - continue
if(Titanium.Network.online) {
    //Show the activity indicator
var activityIndicator = Ti.UI.createActivityIndicator({
    height: '100%',
    width: '100%',
    color: '#404347',
    backgroundColor: '#d8d8d8',
    font: {
        fontFamily: 'Helvetica Neue',
        fontSize: 14,
        fontWeight: 'normal'
    },
    message: 'Loading...',
    style: activityStyle,
});
win.add(activityIndicator);
activityIndicator.show();

    //open network connection
    var xhr = Ti.Network.createHTTPClient({
        cache: Ti.App.Properties.getBool('cache', true),
        timeout:5000,
    });
    xhr.open('GET', url);
    xhr.onload = function () {
        //Writing data to a file
        f.write(this.responseData);
        getXMLdata(f);
        showTable();
    };

    xhr.onerror = function() {
        Ti.API.info('XHR Error: ' + xhr.status + ' - ' + xhr.statusText);
     //check response status and act aaccordingly.
     if(xhr.status != 200) {
        if(f.exists()) {
        getXMLdata(f);
        showTable();
        alert('Offline Mode');
       }
        else if(!f.exists()) {
        activityIndicator.hide();
        alert('The service is currently unavailable. Please Try Again Later.');
        }
    }};
    try {
        xhr.send();
    } catch(e) {
        Ti.API.info('error with xhr.send(): '+e);
        xhr.abort();
        activityIndicator.hide();
    }
}
else if(f.exists()) {
        getXMLdata(f);
        showTable();
    }
else if(!f.exists()) {
        activityIndicator.hide();
        alert('Your device is not connected to the internet.');
}

function showTable() {
    var searchBar = Titanium.UI.createSearchBar({
    barColor:'#bbb',
    tintColor :'#980012',
    height:43,
    top:0,
    });
    // create table
    var tableView = Ti.UI.createTableView({
        data: data,
        search:searchBar,
        filterAttribute:'filter',
        searchHidden:true,
        hideSearchOnSelection: true,
    });
    win.add(tableView);
    // add event handeler
    tableView.addEventListener('click', function (e) {
        /*
        var detailWin = Ti.UI.createWindow({
            //title of the label that the user selected
            title: e.row.children[0].text,
            barColor: '#650000',
            url: 'tableDetail.js',
       });
       */
           //alternative method:
           // var Window = require('windowClass');
        var detailWin = new Window (e.row.children[0].text, 'tableDetail.js');
        detailWin.desc = e.row.desc;
        tabGroup.activeTab.open(detailWin, {
            animation: true
        });
        //Hide the activity indicator when the funtion has completed
        activityIndicator.hide();
    });
    searchBar.addEventListener('change', function (e) {
        Ti.App.Properties.setString('search', searchBar.value);
    });
    win.addEventListener('focus', function(e) {
        if(searchBar.value){
        searchBar.value=Ti.App.Properties.getString('search','');
        tableView.searchHidden=false;
        }
    });
};

function getXMLdata(file) {
    if(file.exists()) {
        //read file
        var contents = f.read().text;
// Ti.API.info('contents = ' + contents);
        var doc = Ti.XML.parseString(contents);
        //var doc = this.responseXML.documentElement;
        var items = doc.getElementsByTagName('item');
        var x = 0;
        for(var i = 0; i < items.length; i++) {
            var item = items.item(i);
            var title = item.getElementsByTagName('title').item(0).text;
            var description = item.getElementsByTagName('description').item(0).text;
            var pubDate = item.getElementsByTagName('pubDate').item(0).text;
            var link = item.getElementsByTagName('link').item(0).text;
            //display content and create objects
            var row = Ti.UI.createTableViewRow({
                height: 80,
                layout: 'vertical',
                selectedBackgroundColor: '#650000',
            });
            row.filter = title; //data for search
            var labelText = title;
            var label = Ti.UI.createLabel({
                text: labelText,
                highlightedColor: '#fff',
                left: 5,
                top: 5,
                bottom: 5,
                right: 5,
            });
            //add objects
            row.add(label);
            row.desc = description;
            data[x++] = row;
        }
    }
}}
<|endoftext|>