<commit_before>/*jslint
  indent: 4
*/

/*global
  $, google, mytrans, window, Cookies, Coordinates, get_cookie_string
*/

var Okapi = {};
Okapi.m_map = null;
Okapi.m_sites = null;
Okapi.m_ready = false;
Okapi.m_showCache = null;
Okapi.m_enabled = false;
Okapi.m_popup = null;
Okapi.m_marker = null;
Okapi.m_icons = null;
Okapi.m_timer = null;

Okapi.init = function (themap) {
    'use strict';

    this.m_map = themap;
    var self = this;

    google.maps.event.addListener(this.m_map, "center_changed", function () {
        self.scheduleLoad();
    });
    google.maps.event.addListener(this.m_map, "zoom_changed", function () {
        self.scheduleLoad();
    });
};

Okapi.parseLocation = function (s) {
    'use strict';

    var loc = s.split("|"),
        lat = parseFloat(loc[0]),
        lng = parseFloat(loc[1]);

    if (Coordinates.valid(lat, lng)) {
        return new google.maps.LatLng(lat, lng);
    }

    return null;
};

Okapi.setShowCache = function (code) {
    'use strict';

    this.m_showCache = code;
};

Okapi.setupSites = function () {
    'use strict';

    if (this.m_sites) {
        return;
    }

    var self = this,
        main_url = "http://www.opencaching.pl/okapi/services/apisrv/installations",
        keys = {
            "Opencaching.DE" : "YSqPufH82encfJ67ZxV2",
            "Opencaching.PL" : "jhRyc6rGmT6XEvxva29B",
            "Opencaching.NL" : "gcwaesuq3REu8RtCgLDj",
            "Opencaching.US" : "GvgyCMvwfH42GqJGL494",
            "Opencaching.ORG.UK" : "7t7VfpkCd4HuxPabfbHd",
            "Opencaching.RO" : "gqSWmVJhZGDwc4sRhyy7"
        },
        prefixes = {
            "Opencaching.DE" : "OC",
            "Opencaching.PL" : "OP",
            "Opencaching.NL" : "OB",
            "Opencaching.US" : "OU",
            "Opencaching.ORG.UK" : "OK",
            "Opencaching.RO" : "OR"
        };

    this.m_sites = [];

    $.ajax({
        url: main_url,
        dataType: 'json',
        success: function (response) {
            response.map(function (site) {
                if (keys[site.site_name] !== undefined) {
                    //console.log("adding OC site: " + site.site_name);
                    self.m_sites.push({
                        siteid: self.m_sites.length,
                        name: site.site_name,
                        site_url: site.site_url,
                        url: site.okapi_base_url,
                        prefix: prefixes[site.site_name],
                        key: keys[site.site_name],
                        ignore_user: null,
                        markers: {},
                        finished: true
                    });
                }
            });

            self.m_ready = true;
            if (self.m_enabled) {
                self.scheduleLoad(true);
            }
            if (self.m_showCache && self.m_showCache !== "") {
                self.centerMap(self.m_showCache);
                self.m_showCache = null;
            }
        }
    });
};

Okapi.setupIcons = function () {
    'use strict';

    if (this.m_icons) {
        return;
    }

    this.m_icons = {
        "Other": new google.maps.MarkerImage("img/cachetype-1.png"),
        "Traditional": new google.maps.MarkerImage("img/cachetype-2.png"),
        "Multi": new google.maps.MarkerImage("img/cachetype-3.png"),
        "Virtual": new google.maps.MarkerImage("img/cachetype-4.png"),
        "Webcam": new google.maps.MarkerImage("img/cachetype-5.png"),
        "Event": new google.maps.MarkerImage("img/cachetype-6.png"),
        "Quiz": new google.maps.MarkerImage("img/cachetype-7.png"),
        "Math/Physics": new google.maps.MarkerImage("img/cachetype-8.png"),
        "Moving": new google.maps.MarkerImage("img/cachetype-9.png"),
        "Drive-In": new google.maps.MarkerImage("img/cachetype-10.png")
    };
};

Okapi.icon = function (type) {
    'use strict';

    if (this.m_icons[type] !== undefined) {
        return this.m_icons[type];
    }

    return this.m_icons.Other;
};

Okapi.guessSiteId = function (code) {
    'use strict';

    code = code.toUpperCase();
    var siteid;
    for (siteid = 0; siteid < this.m_sites.length; siteid += 1) {
        if (code.startsWith(this.m_sites[siteid].prefix)) {
            return siteid;
        }
    }

    return -1;
};

Okapi.centerMap = function (code) {
    'use strict';

    if (!this.m_ready) {
        //console.log("okapi not ready");
        return;
    }

    var siteid = this.guessSiteId(code);
    if (siteid < 0) {
        //console.log("bad code. cannot determine okapi site");
        return;
    }

    this.showPopup(null, code.toUpperCase(), siteid);
};

Okapi.createPopupContent = function (code, response) {
    'use strict';

    var content =
        '' + code + ' ' + response.name + '
'
        + '
'
        + '
' + mytrans("geocache.owner") + '	' + '' + response.owner.username + '
'
        + '
' + mytrans("geocache.type") + '	' + response.type + '
'
        + '
' + mytrans("geocache.size") + '	' + response.size2 + '
'
        + '
' + mytrans("geocache.status") + '	' + response.status + '
'
        + '
' + mytrans("geocache.difficulty") + '	' + response.difficulty + '/5
'
        + '
' + mytrans("geocache.terrain") + '	' + response.terrain + '/5
'
        + '
' + mytrans("geocache.finds") + '	' + response.founds + '
'
        + '
';
    return content;
};

Okapi.showPopup = function (m, code, siteid) {
    'use strict';

    if (!this.m_popup) {
        this.m_popup = new google.maps.InfoWindow();
    }

    var self = this,
        site = this.m_sites[siteid];

    $.ajax({
        url: site.url + 'services/caches/geocache',
        dataType: 'json',
        data: {
            'consumer_key': site.key,
            'cache_code': code,
            'fields' : 'name|type|status|url|owner|founds|size2|difficulty|terrain|location'
        },
        success: function (response) {
            var coords = self.parseLocation(response.location);
            self.m_map.setCenter(coords);

            if (!m) {
                m = new google.maps.Marker({
                    position: coords,
                    map: self.m_map,
                    icon: self.icon(response.type)
                });
                if (self.m_maker) {
                    self.m_marker.setMap(null);
                }
                self.registerPopup(m, code, siteid);
                self.m_marker = m;
            }

            self.m_popup.setContent(self.createPopupContent(code, response));
            self.m_popup.open(self.m_map, m);
        }
    });
};

Okapi.registerPopup = function (m, code, siteid) {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;

    google.maps.event.addListener(m, 'click', function () {
        self.showPopup(m, code, siteid);
    });
};

Okapi.removeMarkersSite = function (markers) {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    if (markers) {
        markers.map(function (m) {
            m.setMap(null);
        });
    }
};

Okapi.removeMarkers = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;
    this.m_sites.map(function (site) {
        self.removeMarkersSite(site.markers);
        site.markers = {};
    });

    if (this.m_marker) {
        this.m_marker.setMap(null);
        delete this.m_marker;
        this.m_marker = null;
    }
};

Okapi.loadBboxSite = function (siteid) {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this,
        site = this.m_sites[siteid],
        b,
        bbox;

    if (!this.m_enabled) {
        site.finished = true;
        return;
    }

    if (!site.finished) {
        return;
    }

    site.finished = false;

    b = this.m_map.getBounds();
    bbox = b.getSouthWest().lat() + "|" + b.getSouthWest().lng() + "|" + b.getNorthEast().lat() + "|" + b.getNorthEast().lng();

    $.ajax({
        url: site.url + 'services/caches/shortcuts/search_and_retrieve',
        dataType: 'json',
        data: {
            'consumer_key': site.key,
            'search_method': 'services/caches/search/bbox',
            'search_params': '{"bbox" : "' + bbox + '", "limit" : "500"}',
            'retr_method': 'services/caches/geocaches',
            'retr_params': '{"fields": "code|name|location|type|status|url"}',
            'wrap': 'false'
        },
        success: function (response) {
            var addedCaches = {},
                cache,
                code;

            for (code in response) {
                if (!response.hasOwnProperty(code)) {
                    continue;
                }

                cache = response[code];
                if (cache.status !== "Available") {
                    continue;
                }

                addedCaches[cache.code] = true;
                if (site.markers[cache.code] !== undefined) {
                    continue;
                }

                site.markers[cache.code] = new google.maps.Marker({
                    position: self.parseLocation(cache.location),
                    map: self.m_map,
                    icon: self.icon(cache.type)
                });

                self.registerPopup(site.markers[cache.code], cache.code, siteid);
            }

            for (code in site.markers) {
                if (site.markers.hasOwnProperty(code) && addedCaches[code] === undefined) {
                    site.markers[code].setMap(null);
                    delete site.markers[code];
                }
            }
            site.finished = true;
        },
        error: function () {
            //console.log("okapi request failed: " + site.name);
            self.removeMarkersSite(site.markers);
            site.markers = {};
            site.finished = true;
        }
    });
};

Okapi.loadBbox = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;
    this.m_sites.map(function (site) {
        self.loadBboxSite(site.siteid);
    });
};

Okapi.unscheduleLoad = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    if (this.m_timer) {
        window.clearTimeout(this.m_timer);
        this.m_timer = null;
    }
};

Okapi.scheduleLoad = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;

    this.unscheduleLoad();
    this.m_timer = window.setTimeout(function () {
        self.loadBbox();
    }, 500);
};

Okapi.toggle = function (t) {
    'use strict';

    Cookies.set('load_caches', t ? "1" : "0", {expires: 30});
    if ($('#geocaches').is(':checked') !== t) {
        $('#geocaches').attr('checked', t);
    }

    if (this.m_enabled !== t) {
        this.m_enabled = t;
    }

    if (this.m_enabled) {
        this.setupIcons();
        this.setupSites();
        this.scheduleLoad();
    } else {
        this.unscheduleLoad();
        this.removeMarkers();
    }
};

Okapi.restore = function (defaultValue) {
    'use strict';

    var state = get_cookie_string("load_caches", "invalid");

    if (state === "0") {
        this.toggle(false);
    } else if (state === "1") {
        this.toggle(true);
    } else {
        this.toggle(defaultValue);
    }
};
<commit_msg>fixed Okapi.removeMarkers. fixes #64<commit_after>/*jslint
  indent: 4
*/

/*global
  $, google, mytrans, window, Cookies, Coordinates, get_cookie_string
*/

var Okapi = {};
Okapi.m_map = null;
Okapi.m_sites = null;
Okapi.m_ready = false;
Okapi.m_showCache = null;
Okapi.m_enabled = false;
Okapi.m_popup = null;
Okapi.m_marker = null;
Okapi.m_icons = null;
Okapi.m_timer = null;

Okapi.init = function (themap) {
    'use strict';

    this.m_map = themap;
    var self = this;

    google.maps.event.addListener(this.m_map, "center_changed", function () {
        self.scheduleLoad();
    });
    google.maps.event.addListener(this.m_map, "zoom_changed", function () {
        self.scheduleLoad();
    });
};

Okapi.parseLocation = function (s) {
    'use strict';

    var loc = s.split("|"),
        lat = parseFloat(loc[0]),
        lng = parseFloat(loc[1]);

    if (Coordinates.valid(lat, lng)) {
        return new google.maps.LatLng(lat, lng);
    }

    return null;
};

Okapi.setShowCache = function (code) {
    'use strict';

    this.m_showCache = code;
};

Okapi.setupSites = function () {
    'use strict';

    if (this.m_sites) {
        return;
    }

    var self = this,
        main_url = "http://www.opencaching.pl/okapi/services/apisrv/installations",
        keys = {
            "Opencaching.DE" : "YSqPufH82encfJ67ZxV2",
            "Opencaching.PL" : "jhRyc6rGmT6XEvxva29B",
            "Opencaching.NL" : "gcwaesuq3REu8RtCgLDj",
            "Opencaching.US" : "GvgyCMvwfH42GqJGL494",
            "Opencaching.ORG.UK" : "7t7VfpkCd4HuxPabfbHd",
            "Opencaching.RO" : "gqSWmVJhZGDwc4sRhyy7"
        },
        prefixes = {
            "Opencaching.DE" : "OC",
            "Opencaching.PL" : "OP",
            "Opencaching.NL" : "OB",
            "Opencaching.US" : "OU",
            "Opencaching.ORG.UK" : "OK",
            "Opencaching.RO" : "OR"
        };

    this.m_sites = [];

    $.ajax({
        url: main_url,
        dataType: 'json',
        success: function (response) {
            response.map(function (site) {
                if (keys[site.site_name] !== undefined) {
                    //console.log("adding OC site: " + site.site_name);
                    self.m_sites.push({
                        siteid: self.m_sites.length,
                        name: site.site_name,
                        site_url: site.site_url,
                        url: site.okapi_base_url,
                        prefix: prefixes[site.site_name],
                        key: keys[site.site_name],
                        ignore_user: null,
                        markers: {},
                        finished: true
                    });
                }
            });

            self.m_ready = true;
            if (self.m_enabled) {
                self.scheduleLoad(true);
            }
            if (self.m_showCache && self.m_showCache !== "") {
                self.centerMap(self.m_showCache);
                self.m_showCache = null;
            }
        }
    });
};

Okapi.setupIcons = function () {
    'use strict';

    if (this.m_icons) {
        return;
    }

    this.m_icons = {
        "Other": new google.maps.MarkerImage("img/cachetype-1.png"),
        "Traditional": new google.maps.MarkerImage("img/cachetype-2.png"),
        "Multi": new google.maps.MarkerImage("img/cachetype-3.png"),
        "Virtual": new google.maps.MarkerImage("img/cachetype-4.png"),
        "Webcam": new google.maps.MarkerImage("img/cachetype-5.png"),
        "Event": new google.maps.MarkerImage("img/cachetype-6.png"),
        "Quiz": new google.maps.MarkerImage("img/cachetype-7.png"),
        "Math/Physics": new google.maps.MarkerImage("img/cachetype-8.png"),
        "Moving": new google.maps.MarkerImage("img/cachetype-9.png"),
        "Drive-In": new google.maps.MarkerImage("img/cachetype-10.png")
    };
};

Okapi.icon = function (type) {
    'use strict';

    if (this.m_icons[type] !== undefined) {
        return this.m_icons[type];
    }

    return this.m_icons.Other;
};

Okapi.guessSiteId = function (code) {
    'use strict';

    code = code.toUpperCase();
    var siteid;
    for (siteid = 0; siteid < this.m_sites.length; siteid += 1) {
        if (code.startsWith(this.m_sites[siteid].prefix)) {
            return siteid;
        }
    }

    return -1;
};

Okapi.centerMap = function (code) {
    'use strict';

    if (!this.m_ready) {
        //console.log("okapi not ready");
        return;
    }

    var siteid = this.guessSiteId(code);
    if (siteid < 0) {
        //console.log("bad code. cannot determine okapi site");
        return;
    }

    this.showPopup(null, code.toUpperCase(), siteid);
};

Okapi.createPopupContent = function (code, response) {
    'use strict';

    var content =
        '' + code + ' ' + response.name + '
'
        + '
'
        + '
' + mytrans("geocache.owner") + '	' + '' + response.owner.username + '
'
        + '
' + mytrans("geocache.type") + '	' + response.type + '
'
        + '
' + mytrans("geocache.size") + '	' + response.size2 + '
'
        + '
' + mytrans("geocache.status") + '	' + response.status + '
'
        + '
' + mytrans("geocache.difficulty") + '	' + response.difficulty + '/5
'
        + '
' + mytrans("geocache.terrain") + '	' + response.terrain + '/5
'
        + '
' + mytrans("geocache.finds") + '	' + response.founds + '
'
        + '
';
    return content;
};

Okapi.showPopup = function (m, code, siteid) {
    'use strict';

    if (!this.m_popup) {
        this.m_popup = new google.maps.InfoWindow();
    }

    var self = this,
        site = this.m_sites[siteid];

    $.ajax({
        url: site.url + 'services/caches/geocache',
        dataType: 'json',
        data: {
            'consumer_key': site.key,
            'cache_code': code,
            'fields' : 'name|type|status|url|owner|founds|size2|difficulty|terrain|location'
        },
        success: function (response) {
            var coords = self.parseLocation(response.location);
            self.m_map.setCenter(coords);

            if (!m) {
                m = new google.maps.Marker({
                    position: coords,
                    map: self.m_map,
                    icon: self.icon(response.type)
                });
                if (self.m_maker) {
                    self.m_marker.setMap(null);
                }
                self.registerPopup(m, code, siteid);
                self.m_marker = m;
            }

            self.m_popup.setContent(self.createPopupContent(code, response));
            self.m_popup.open(self.m_map, m);
        }
    });
};

Okapi.registerPopup = function (m, code, siteid) {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;

    google.maps.event.addListener(m, 'click', function () {
        self.showPopup(m, code, siteid);
    });
};

Okapi.removeMarkers = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;
    this.m_sites.map(function (site) {
        var key;
        for (key in site.markers) {
            if (!site.markers.hasOwnProperty(key)) {
                continue;
            }
            site.markers[key].setMap(null);
        }
        site.markers = {};
    });

    if (this.m_marker) {
        this.m_marker.setMap(null);
        delete this.m_marker;
        this.m_marker = null;
    }
};

Okapi.loadBboxSite = function (siteid) {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this,
        site = this.m_sites[siteid],
        b,
        bbox;

    if (!this.m_enabled) {
        site.finished = true;
        return;
    }

    if (!site.finished) {
        return;
    }

    site.finished = false;

    b = this.m_map.getBounds();
    bbox = b.getSouthWest().lat() + "|" + b.getSouthWest().lng() + "|" + b.getNorthEast().lat() + "|" + b.getNorthEast().lng();

    $.ajax({
        url: site.url + 'services/caches/shortcuts/search_and_retrieve',
        dataType: 'json',
        data: {
            'consumer_key': site.key,
            'search_method': 'services/caches/search/bbox',
            'search_params': '{"bbox" : "' + bbox + '", "limit" : "500"}',
            'retr_method': 'services/caches/geocaches',
            'retr_params': '{"fields": "code|name|location|type|status|url"}',
            'wrap': 'false'
        },
        success: function (response) {
            var addedCaches = {},
                cache,
                code;

            for (code in response) {
                if (!response.hasOwnProperty(code)) {
                    continue;
                }

                cache = response[code];
                if (cache.status !== "Available") {
                    continue;
                }

                addedCaches[cache.code] = true;
                if (site.markers[cache.code] !== undefined) {
                    continue;
                }

                site.markers[cache.code] = new google.maps.Marker({
                    position: self.parseLocation(cache.location),
                    map: self.m_map,
                    icon: self.icon(cache.type)
                });

                self.registerPopup(site.markers[cache.code], cache.code, siteid);
            }

            for (code in site.markers) {
                if (site.markers.hasOwnProperty(code) && addedCaches[code] === undefined) {
                    site.markers[code].setMap(null);
                    delete site.markers[code];
                }
            }
            site.finished = true;
        },
        error: function () {
            //console.log("okapi request failed: " + site.name);
            self.removeMarkersSite(site.markers);
            site.markers = {};
            site.finished = true;
        }
    });
};

Okapi.loadBbox = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;
    this.m_sites.map(function (site) {
        self.loadBboxSite(site.siteid);
    });
};

Okapi.unscheduleLoad = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    if (this.m_timer) {
        window.clearTimeout(this.m_timer);
        this.m_timer = null;
    }
};

Okapi.scheduleLoad = function () {
    'use strict';

    if (!this.m_ready) {
        return;
    }

    var self = this;

    this.unscheduleLoad();
    this.m_timer = window.setTimeout(function () {
        self.loadBbox();
    }, 500);
};

Okapi.toggle = function (t) {
    'use strict';

    Cookies.set('load_caches', t ? "1" : "0", {expires: 30});
    if ($('#geocaches').is(':checked') !== t) {
        $('#geocaches').attr('checked', t);
    }

    if (this.m_enabled !== t) {
        this.m_enabled = t;
    }

    if (this.m_enabled) {
        this.setupIcons();
        this.setupSites();
        this.scheduleLoad();
    } else {
        this.unscheduleLoad();
        this.removeMarkers();
    }
};

Okapi.restore = function (defaultValue) {
    'use strict';

    var state = get_cookie_string("load_caches", "invalid");

    if (state === "0") {
        this.toggle(false);
    } else if (state === "1") {
        this.toggle(true);
    } else {
        this.toggle(defaultValue);
    }
};
<|endoftext|>


<commit_before>(function () {
  'use strict';

  var React = require('react');
  var Licon = require('../../../../src/js/index.js');

  var SingleIcon = React.createClass({
    incrementIndex: function () {
      this.setState({
        iconIndex: (this.state.iconIndex += 1) % this.props.icons.length
      });
    },

    selectRandom: function () {
      var randomIconIndex = Math.floor((Math.random() * this.props.icons.length));

      while(this.props.icons.length > 1 && randomIconIndex === this.state.iconIndex) {
        randomIconIndex = Math.floor((Math.random() * this.props.icons.length));
      }

      this.setState({
        iconIndex: randomIconIndex
      });
    },

    componentDidMount: function () {
      setInterval(this.selectRandom, 2000);
    },

    setBorder: function (value) {
      this.setState({
        border: value
      });
    },

    setShape: function (value) {
      this.setState({
        shape: value
      });
    },

    setSize: function (value) {
      this.setState({
        size: value
      });
    },

    getInitialState: function () {
      return {
        iconIndex: 0,
        border: false,
        shape: null,
        size: null
      };
    },

    render: function () {
      return (

            <Licon icon={this.props.icons[this.state.iconIndex]}
              border={this.state.border}
              round={this.state.shape === 'round'}
              rounded={this.state.shape === 'rounded'}
              small={this.state.size === 'small'}
              large={this.state.size === 'large'} />

              {this.props.icons[this.state.iconIndex]}

                Border:

                  On
                  <input type='radio'
                    checked={this.state.border}
                    onChange={this.setBorder.bind(this, true)} />

                  Off
                  <input type='radio'
                    checked={!this.state.border}
                    onChange={this.setBorder.bind(this, false)} />

                Shape:

                  Default
                  <input type='radio'
                    checked={!this.state.shape}
                    onChange={this.setShape.bind(this, null)} />

                  Round
                  <input type='radio'
                    checked={this.state.shape === 'round'}
                    onChange={this.setShape.bind(this, 'round')} />

                  Rounded
                  <input type='radio'
                    checked={this.state.shape === 'rounded'}
                    onChange={this.setShape.bind(this, 'rounded')} />

                Size:

                  Default
                  <input type='radio'
                    checked={!this.state.size}
                    onChange={this.setSize.bind(this, null)} />

                  Small
                  <input type='radio'
                    checked={this.state.size === 'small'}
                    onChange={this.setSize.bind(this, 'small')} />

                  Large
                  <input type='radio'
                    checked={this.state.size === 'large'}
                    onChange={this.setSize.bind(this, 'large')} />

      );
    }
  });

  module.exports = SingleIcon;
})();
<commit_msg>Reorder border settings<commit_after>(function () {
  'use strict';

  var React = require('react');
  var Licon = require('../../../../src/js/index.js');

  var SingleIcon = React.createClass({
    incrementIndex: function () {
      this.setState({
        iconIndex: (this.state.iconIndex += 1) % this.props.icons.length
      });
    },

    selectRandom: function () {
      var randomIconIndex = Math.floor((Math.random() * this.props.icons.length));

      while(this.props.icons.length > 1 && randomIconIndex === this.state.iconIndex) {
        randomIconIndex = Math.floor((Math.random() * this.props.icons.length));
      }

      this.setState({
        iconIndex: randomIconIndex
      });
    },

    componentDidMount: function () {
      setInterval(this.selectRandom, 2000);
    },

    setBorder: function (value) {
      this.setState({
        border: value
      });
    },

    setShape: function (value) {
      this.setState({
        shape: value
      });
    },

    setSize: function (value) {
      this.setState({
        size: value
      });
    },

    getInitialState: function () {
      return {
        iconIndex: 0,
        border: false,
        shape: null,
        size: null
      };
    },

    render: function () {
      return (

            <Licon icon={this.props.icons[this.state.iconIndex]}
              border={this.state.border}
              round={this.state.shape === 'round'}
              rounded={this.state.shape === 'rounded'}
              small={this.state.size === 'small'}
              large={this.state.size === 'large'} />

              {this.props.icons[this.state.iconIndex]}

                Border:

                  Off
                  <input type='radio'
                    checked={!this.state.border}
                    onChange={this.setBorder.bind(this, false)} />

                  On
                  <input type='radio'
                    checked={this.state.border}
                    onChange={this.setBorder.bind(this, true)} />

                Shape:

                  Default
                  <input type='radio'
                    checked={!this.state.shape}
                    onChange={this.setShape.bind(this, null)} />

                  Round
                  <input type='radio'
                    checked={this.state.shape === 'round'}
                    onChange={this.setShape.bind(this, 'round')} />

                  Rounded
                  <input type='radio'
                    checked={this.state.shape === 'rounded'}
                    onChange={this.setShape.bind(this, 'rounded')} />

                Size:

                  Default
                  <input type='radio'
                    checked={!this.state.size}
                    onChange={this.setSize.bind(this, null)} />

                  Small
                  <input type='radio'
                    checked={this.state.size === 'small'}
                    onChange={this.setSize.bind(this, 'small')} />

                  Large
                  <input type='radio'
                    checked={this.state.size === 'large'}
                    onChange={this.setSize.bind(this, 'large')} />

      );
    }
  });

  module.exports = SingleIcon;
})();
<|endoftext|>


<commit_before>var nodeList = document.getElementsByClassName('draggable');

for(var i=0;i<nodeList.length;i++) {
    var obj = nodeList[i];
    obj.addEventListener('touchmove', function(event) {

      var touch = event.targetTouches[0];
      var izq = document.getElementById('mano_izq');
      var ancho = obj.offsetWidth;
      var alto = obj.offsetHeight;
      event.target.style.left = touch.pageX-(ancho/2) + 'px';
      event.target.style.top = touch.pageY-(alto/2) + 'px';
      var posicion = Math.floor(touch.pageX-(ancho*1.5));
      var muestra = document.getElementById('muestra');
      muestra.innerHTML = ''+posicion+'
'+izq.offsetLeft+'';
      if ((posicion >= (izq.offsetLeft-10)) && (posicion <= (izq.offsetLeft+10))) {
        this.style.boxShadow = '-9px 9px 5px 0px rgba(0,0,0,0.75)';
        this.style.zIndex = '5';
      }
      else {
        this.style.boxShadow = '';
        this.style.zIndex = '';
      }
      event.preventDefault();
  }, false);
};

/*
var obj = document.getElementById('d1');
obj.addEventListener('touchmove', function(event) {
  // If there's exactly one finger inside this element
  if (event.targetTouches.length == 1) {
    var touch = event.targetTouches[0];
    // Place element where the finger is
    obj.style.left = touch.pageX-40 + 'px';
    obj.style.top = touch.pageY-40 + 'px';
  }
  event.preventDefault();
}, false);
*/
<commit_msg>Update app.js<commit_after>var nodeList = document.getElementsByClassName('draggable');

for(var i=0;i<nodeList.length;i++) {
    var obj = nodeList[i];
    obj.addEventListener('touchmove', function(event) {

      var touch = event.targetTouches[0];
      var izq = document.getElementById('mano_izq');
      var ancho = this.offsetWidth;
      var alto = this.offsetHeight;
      event.target.style.left = touch.pageX-(ancho/2) + 'px';
      event.target.style.top = touch.pageY-(alto/2) + 'px';
      var posicion = Math.floor(touch.pageX-(ancho*1.5));
      var muestra = document.getElementById('muestra');
      muestra.innerHTML = ''+posicion+'
'+izq.offsetLeft+'';
      if ((posicion >= (izq.offsetLeft-10)) && (posicion <= (izq.offsetLeft+10))) {
        this.style.boxShadow = '-9px 9px 5px 0px rgba(0,0,0,0.75)';
        this.style.zIndex = '5';
      }
      else {
        this.style.boxShadow = '';
        this.style.zIndex = '';
      }
      event.preventDefault();
  }, false);
};

/*
var obj = document.getElementById('d1');
obj.addEventListener('touchmove', function(event) {
  // If there's exactly one finger inside this element
  if (event.targetTouches.length == 1) {
    var touch = event.targetTouches[0];
    // Place element where the finger is
    obj.style.left = touch.pageX-40 + 'px';
    obj.style.top = touch.pageY-40 + 'px';
  }
  event.preventDefault();
}, false);
*/
<|endoftext|>


<commit_before>var storage = (function () {
    return {
        /**
        Saves the key, value pair to localStorage.
        key: The name of the value to be saved.
        value: The value to be saved.
        */
        saveOnce: function saveOnce(key, value) {
            if (angular.isObject(value)) {
                localStorage.setItem(key, JSON.stringify(value));
            } else {
                localStorage.setItem(key, value);
            }
        },

        /**
        Saves the key, value pair to localStorage and chrome.storage.
        key: The name of the value to be saved.
        value: The value to be saved.
        */
        saveTwice: function saveTwice(key, value) {
            if (chrome.storage) {
                var obj = {};
                obj[key] = value;
                chrome.storage.sync.set(obj);
            }
            this.saveOnce(key, value);
        },

        /**
        Saves the key, value pair to angularjs scope, localStorage and chrome.storage.
        key: The name of the value to be saved.
        value: The value to be saved.
        scope: The angularjs scope of the current app.
        */
        saveThrice: function saveThrice(key, value, scope) {
            scope[key] = value;
            this.saveTwice(key, value);
        },

        /**
        Gets the value from localStorage, syncs chrome.storage and saves it to angularjs scope.
        Does not return the value beacuse it might need to make an async call.
        key: The key to be retrieved.
        defaultValue: The value to initialize all storages if the key does not exist.
        scope: The angularjs scope where the value will be saved.
        jsonify: A flag to identify whether the returned value should be parsed as JSON. Only applicable to localStorage.
        callback: A callback function to run when value has been retrieved.
    */
        get: function (key, defaultValue, scope, jsonify, callback) {
            callback = util.maybe(callback);
            // If the value is in localStorage, retieve from there.
            var foundInLocalStorage = false;
            if (localStorage.getItem(key)) {
                if (jsonify) {
                    scope[key] = JSON.parse(localStorage.getItem(key));
                } else {
                    scope[key] = localStorage.getItem(key);
                }
                foundInLocalStorage = true;
                // If we found it, still make the async call for synced data to update the storages.
            } else {
                scope[key] = defaultValue;
            }
            callback();
            chrome.storage.sync.get(key, function(container) {
                if (container[key]) {
//                    if(!foundInLocalStorage) {
                        scope.$apply(function () {
                            // Save retrieved data to localStorage and scope.
                            storage.saveThrice(key, container[key], scope);
                            callback();
                        });
//                    }
                }
            });
        }
    };
})();
<commit_msg>Simplify storage.js. Remove unnecessary code in get function.<commit_after>var storage = (function () {
    return {
        /**
        Saves the key, value pair to localStorage.
        key: The name of the value to be saved.
        value: The value to be saved.
        */
        saveOnce: function saveOnce(key, value) {
            if (angular.isObject(value)) {
                localStorage.setItem(key, JSON.stringify(value));
            } else {
                localStorage.setItem(key, value);
            }
        },

        /**
        Saves the key, value pair to localStorage and chrome.storage.
        key: The name of the value to be saved.
        value: The value to be saved.
        */
        saveTwice: function saveTwice(key, value) {
            if (chrome.storage) {
                var obj = {};
                obj[key] = value;
                chrome.storage.sync.set(obj);
            }
            this.saveOnce(key, value);
        },

        /**
        Saves the key, value pair to angularjs scope, localStorage and chrome.storage.
        key: The name of the value to be saved.
        value: The value to be saved.
        scope: The angularjs scope of the current app.
        */
        saveThrice: function saveThrice(key, value, scope) {
            scope[key] = value;
            this.saveTwice(key, value);
        },

        saveLocal: function saveLocal(key, value) {
            if (angular.isObject(value)) {
                localStorage.setItem(key, JSON.stringify(value));
            } else {
                localStorage.setItem(key, value);
            }
        },

        saveRemote: function saveRemote(key, value) {
            if (chrome.storage) {
                var obj = {};
                obj[key] = value;
                chrome.storage.sync.set(obj);
            }
        },

        saveModel: function saveModel(key, value) {
            saveLocal(key, value);
            saveRemote(key, value);
        },

        saveAll: function saveAll(key, value, scope) {
            saveModel(key, value);
            scope[key] = value;
        },

        getJSON: function getJSON(str) {
            var res = {};
            try {
                res = JSON.parse(str);
            } catch(e) {
                res = str;
            }
            return res;
        },

        /**
        Gets the value from localStorage, syncs chrome.storage and saves it to angularjs scope.
        Does not return the value beacuse it might need to make an async call.
        chrome.storage.sync always wins.
        key: The key to be retrieved.
        defaultValue: The value to initialize all storages if the key does not exist.
        scope: The angularjs scope where the value will be saved.
        jsonify: A flag to identify whether the returned value should be parsed as JSON. Only applicable to localStorage.
        callback: A callback function to run when value has been retrieved.
    */
        get: function (key, defaultValue, scope, jsonify, callback) {
            var that = this;
            callback = util.maybe(callback);

            var value = this.getJSON(localStorage.getItem(key));
            scope[key] = value ? value : defaultValue;
            callback();
            chrome.storage.sync.get(key, function(container) {
                if (container[key]) {
                    that.saveLocal(key, container[key]);
                    scope.$apply(function () {
                        scope[key] = container[key];
                        callback();
                    });
                }
            });
        }
    };
})();
<|endoftext|>


<commit_before>/*global describe, it, expect, example, before, after, beforeEach, afterEach, mocha, sinon*/
'use strict';
var assert = require('chai').assert;
var Raven = require('raven-js');
var $ = require('jquery');
var m = require('mithril');
var AddProject = require('js/addProjectPlugin');

//console.log(AddProject);
describe('AddProjectPlugin', () => {
    it('should validate if new project name is not empty', () => {
        var project = new AddProject.controller();
        project.newProjectName('Hello');
        project.checkValid();
        assert.ok(project.isValid(), true);
        project.newProjectName('');
        project.checkValid();
        assert.notOk(project.isValid(), false);
    });
    it('should load project categories from api server', () => {
        var project = new AddProject.controller();
        var promise = project.loadCategories();
        promise.then(function(){
            assert.ok(project.categoryList.length > 0);
            console.log(project.categoryList);
        });
    });
});<commit_msg>Add reset testing to addProjectPlugin<commit_after>/*global describe, it, expect, example, before, after, beforeEach, afterEach, mocha, sinon*/
'use strict';
var assert = require('chai').assert;
var Raven = require('raven-js');
var $ = require('jquery');
var m = require('mithril');
var AddProject = require('js/addProjectPlugin');

//console.log(AddProject);
describe('AddProjectPlugin', () => {
    it('should validate if new project name is not empty', () => {
        var project = new AddProject.controller();
        project.newProjectName('Hello');
        project.checkValid();
        assert.ok(project.isValid(), true);
        project.newProjectName('');
        project.checkValid();
        assert.notOk(project.isValid(), false);
    });
    it('should load project categories from api server', () => {
        var project = new AddProject.controller();
        var promise = project.loadCategories();
        promise.then(function(){
            assert.ok(project.categoryList.length > 0);
            console.log(project.categoryList);
        });
    });
    it('should reset states and defaults when reset function runs', () => {
        var project = new AddProject.controller();
        // Change values
        project.newProjectName('Hello there');
        project.viewState('error');
        project.newProjectDesc('Description');
        project.newProjectCategory('thesis');
        // Reset
        project.reset();
        // Assert the return to defaults;
        assert.equal(project.newProjectName(), '');
        assert.equal(project.viewState(), 'form');
        assert.equal(project.newProjectDesc(), '');
        assert.equal(project.newProjectCategory(), 'project');
    });
});<|endoftext|>


<commit_before>define(['xaml!js/svg/SvgDescriptor', "js/svg/SvgElement", 'js/core/Base'], function (SvgDescriptor, SvgElement, Base) {

    var Svg = SvgDescriptor.inherit("js.svg.Svg", {

        defaults: {
            tagName: "svg",
            viewBox: "0 0 100 100",

            hidden: null
        },

        $classAttributes: ["defs", "hidden"],

        ctor: function() {
            this.callBase();
            this.fontManager = new Svg.FontManager(this);
            this.$svgRoot = this;

            this.setViewBox.apply(this,this.$.viewBox.split(" "));
        },

        setViewBox: function (x, y, width, height) {

            this.$viewBoxX = x;
            this.$viewBoxY = y;
            this.$viewBoxWidth = width;
            this.$viewBoxHeight = height;

            this.set("viewBox", [x, y, width, height].join(" "));
        },

        localToGlobalFactor: function() {
            return {
                x: this.$.width / this.$viewBoxWidth,
                y: this.$.height / this.$viewBoxHeight
            };
        },

        globalToLocalFactor: function () {
            return {
                x: this.$viewBoxWidth / this.$.width,
                y: this.$viewBoxHeight / this.$.height
            };
        },

        save: function() {

            var window = this.$stage.$window;

            // dirty hack to get dom as string
            var div = this.$stage.$document.createElement("div");
            div.appendChild(this.$el.cloneNode(true));
            // dirty hack2
            var svgContent = div.innerHTML.replace(/^\<svg/, "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' ");
            svgContent = svgContent.replace(/(href=['"])\/{2}/g, "$1http://");

            var svg = new Blob([svgContent], {
                type: "image/svg+xml;charset=utf-8"
            });

            var domUrl = window.URL || window.webkitURL || window;
            return domUrl.createObjectURL(svg);

        }

    });

    Svg.FontManager = Base.inherit("js.svg.Svg.FontManager", {

        ctor: function(svg) {
            this.$svg = svg;
            this.$fontCache = {};

            this.callBase();
        },

        loadExternalFont: function (fontFamily, src, callback) {
            var svg = this.$svg;

            var cache = this.$fontCache[fontFamily];

            if (!cache) {
                var font = svg.$templates["external-font"].createInstance({
                    $fontFamily: fontFamily,
                    $src: src
                });

                cache = this.$fontCache[fontFamily] = {
                    font: font,
                    loaded: false,
                    callbacks: [callback]
                };

                var text = svg.$stage.$document.createElementNS(SvgElement.SVG_NAMESPACE, "text");
                text.textContent = "SvgFontMeasurer";

                var hidden = svg.$.hidden.$el;
                hidden.appendChild(text);

                var originalBox = text.getBBox();
                svg.$.defs.addChild(font);
                text.setAttribute("font-family", fontFamily);

                setTimeout(checkFontLoaded, 0);

                function checkFontLoaded() {
                    var current = text.getBBox();

                    if (current.x === originalBox.x && current.y === originalBox.y &&
                        current.width === originalBox.width && current.height === originalBox.height) {

                        // same check later
                        setTimeout(checkFontLoaded, 100);
                    } else {
                        cache.loaded = true;
                        hidden.removeChild(text);

                        for (var i = 0; i < cache.callbacks.length; i++) {
                            try {
                                cache.callbacks[i] && cache.callbacks[i]();
                            } catch (e) {
                                // invoke callbacks
                            }
                        }
                    }
                }

            } else {

                if (cache.loaded) {
                    callback && callback();
                } else {
                    cache.callbacks.push(callback);
                }

            }

        }
    });

    return Svg;
});<commit_msg>fixed fontLoading<commit_after>define(['xaml!js/svg/SvgDescriptor', "js/svg/SvgElement", 'js/core/Base'], function (SvgDescriptor, SvgElement, Base) {

    var Svg = SvgDescriptor.inherit("js.svg.Svg", {

        defaults: {
            tagName: "svg",
            viewBox: "0 0 100 100",

            hidden: null
        },

        $classAttributes: ["defs", "hidden"],

        ctor: function() {
            this.callBase();
            this.fontManager = new Svg.FontManager(this);
            this.$svgRoot = this;

            this.setViewBox.apply(this,this.$.viewBox.split(" "));
        },

        setViewBox: function (x, y, width, height) {

            this.$viewBoxX = x;
            this.$viewBoxY = y;
            this.$viewBoxWidth = width;
            this.$viewBoxHeight = height;

            this.set("viewBox", [x, y, width, height].join(" "));
        },

        localToGlobalFactor: function() {
            return {
                x: this.$.width / this.$viewBoxWidth,
                y: this.$.height / this.$viewBoxHeight
            };
        },

        globalToLocalFactor: function () {
            return {
                x: this.$viewBoxWidth / this.$.width,
                y: this.$viewBoxHeight / this.$.height
            };
        },

        save: function() {

            var window = this.$stage.$window;

            // dirty hack to get dom as string
            var div = this.$stage.$document.createElement("div");
            div.appendChild(this.$el.cloneNode(true));
            // dirty hack2
            var svgContent = div.innerHTML.replace(/^\<svg/, "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' ");
            svgContent = svgContent.replace(/(href=['"])\/{2}/g, "$1http://");

            var svg = new Blob([svgContent], {
                type: "image/svg+xml;charset=utf-8"
            });

            var domUrl = window.URL || window.webkitURL || window;
            return domUrl.createObjectURL(svg);

        }

    });

    Svg.FontManager = Base.inherit("js.svg.Svg.FontManager", {

        ctor: function(svg) {
            this.$svg = svg;
            this.$fontCache = {};

            this.callBase();
        },

        loadExternalFont: function (fontFamily, src, callback) {
            var svg = this.$svg;

            var cache = this.$fontCache[fontFamily];

            if (!cache) {
                var font = svg.$templates["external-font"].createInstance({
                    $fontFamily: fontFamily,
                    $src: src
                });

                cache = this.$fontCache[fontFamily] = {
                    font: font,
                    loaded: false,
                    callbacks: [callback]
                };

                var text = svg.$stage.$document.createElementNS(SvgElement.SVG_NAMESPACE, "text");
                text.textContent = "SvgFontMeasurer";
                var hidden = svg.$.hidden.$el;

                hidden.appendChild(text);
                svg.$.defs.addChild(font);

                setTimeout(function(){
                    text.setAttribute("font-family", "__ABCDE__");  // set to undefined font and measure

                    var originalBox = text.getBBox();

                    text.setAttribute("font-family", fontFamily); // set to loading font / first undefined

                    setTimeout(checkFontLoaded, 0);

                    function checkFontLoaded() {
                        var current = text.getBBox();

                        // compare bounding boxes of two
                        if (current.x === originalBox.x && current.y === originalBox.y &&
                            current.width === originalBox.width && current.height === originalBox.height) {

                            // same check later
                            setTimeout(checkFontLoaded, 100);
                        } else {
                            cache.loaded = true;
                            hidden.removeChild(text);

                            for (var i = 0; i < cache.callbacks.length; i++) {
                                try {
                                    cache.callbacks[i] && cache.callbacks[i]();
                                } catch(e) {
                                    // invoke callbacks
                                }
                            }
                        }
                    }
                },100);

            } else {

                if (cache.loaded) {
                    callback && callback();
                } else {
                    cache.callbacks.push(callback);
                }

            }

        }
    });

    return Svg;
});<|endoftext|>


<commit_before>describe('HotPath', function () {
  'use strict';

  var assume = require('assume')
    , HotPath = require('../hotpath');

  it('is exposed as function', function () {
    assume(HotPath).to.be.a('function');
  });

  describe('#set', function () {
    it('only stores data if we do not blow out of memory', function () {
      var hp = new HotPath({ available: 100 });

      assume(hp.set('foo', new Buffer(40))).to.equal(false);
      assume(hp.set('foo', new Buffer(2))).to.equal(true);

      hp.destroy();
    });

    it('transforms everything in buffers');
    it('increments the allocated size');
    it('returns true when stored');
  });

  describe('#get', function () {
    it('returns the stored buffer');
  });

  describe('#remove', function () {
    it('returns false when not stored');
  });

  describe('#ram', function () {
    it('normalizes the ram to a maximum');
    it('it allows more memory when we have more RAM available');
  });
});
<commit_msg>[test] Add more specific store checks<commit_after>describe('HotPath', function () {
  'use strict';

  var assume = require('assume')
    , HotPath = require('../hotpath');

  it('is exposed as function', function () {
    assume(HotPath).to.be.a('function');
  });

  describe('#set', function () {
    it('only stores data if we do not blow out of memory', function () {
      var hp = new HotPath({ available: 100 });

      assume(hp.set('foo', new Buffer(40))).to.equal(false);
      assume(hp.get('foo')).to.equal(undefined);

      assume(hp.set('foo', new Buffer(2))).to.equal(true);
      assume(hp.get('foo')).to.be.a('buffer');

      hp.destroy();
    });

    it('transforms everything in buffers');
    it('increments the allocated size');
    it('returns true when stored');
  });

  describe('#get', function () {
    it('returns the stored buffer');
  });

  describe('#remove', function () {
    it('returns false when not stored');
  });

  describe('#ram', function () {
    it('normalizes the ram to a maximum');
    it('it allows more memory when we have more RAM available');
  });
});
<|endoftext|>


<commit_before>// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Document Type Mapping', {
	local_doctype: function(frm) {
		if (frm.doc.local_doctype) {
			frappe.model.clear_table(frm.doc, 'field_mapping');
			let fields = frm.events.get_fields(frm);
			$.each(fields, function(i, data) {
				let row = frappe.model.add_child(frm.doc, 'Document Type Mapping', 'field_mapping');
				row.local_fieldname = data;
			});
			refresh_field('field_mapping');
		}
	},

	get_fields: function(frm) {
		let filtered_fields = [];
		frappe.model.with_doctype(frm.doc.local_doctype, ()=> {
			frappe.get_meta(frm.doc.local_doctype).fields.map( field => {
				if (field.fieldname !== 'remote_docname' && field.fieldname !== 'remote_site_name' && frappe.model.is_value_type(field) && !field.hidden) {
					filtered_fields.push(field.fieldname);
				}
			});
		});
		return filtered_fields;
	}
});
<commit_msg>fix: use the correct dt name while populating data in mapping table<commit_after>// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Document Type Mapping', {
	local_doctype: function(frm) {
		if (frm.doc.local_doctype) {
			frappe.model.clear_table(frm.doc, 'field_mapping');
			let fields = frm.events.get_fields(frm);
			$.each(fields, function(i, data) {
				let row = frappe.model.add_child(frm.doc, 'Document Type Field Mapping', 'field_mapping');
				row.local_fieldname = data;
			});
			refresh_field('field_mapping');
		}
	},

	get_fields: function(frm) {
		let filtered_fields = [];
		frappe.model.with_doctype(frm.doc.local_doctype, ()=> {
			frappe.get_meta(frm.doc.local_doctype).fields.map( field => {
				if (field.fieldname !== 'remote_docname' && field.fieldname !== 'remote_site_name' && frappe.model.is_value_type(field) && !field.hidden) {
					filtered_fields.push(field.fieldname);
				}
			});
		});
		return filtered_fields;
	}
});
<|endoftext|>


<commit_before>$(document).ready(function(){
    // the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
    $('.modal').modal();
  });

function MenuItem(id,longName,price){
    this.id = id;
    this.longName = longName;
    this.price = price;
  }

var basket=[];
var ul = document.getElementById("basketItems");
var li = document.createElement("li");

var ribs = new MenuItem("ribs", "Spare Ribs in Barbecue Sauce", 4.60);
var ccm = new MenuItem("ccm", "Chicken Chow Mein", 4.20);
var cfr = new MenuItem("cfr", "Chicken Fried Rice", 4.20);
var cc = new MenuItem("cc", "Curry Chicken", 4.70);
var ssc = new MenuItem("ssc", "Sweet and Sour Chicken Crispy Balls", 4.00);

var basketTotal =document.getElementById("basketTotal");
var ribbutton=document.getElementById("ribs");
var ccmbutton=document.getElementById("ccm");
var cfrbutton=document.getElementById("cfr");
var ccbutton=document.getElementById("cc");
var sscbutton=document.getElementById("ssc");

ribbutton.onclick = function(){addToBasket(ribs)}
ccmbutton.onclick = function(){addToBasket(ccm)}
cfrbutton.onclick = function(){addToBasket(cfr)}
ccbutton.onclick = function(){addToBasket(cc)}
sscbutton.onclick = function(){addToBasket(ssc)}

function addToBasket(item){
    basket.push(item);
    Materialize.toast(item.longName + " added to basket", 4000);
    basketTotal.innerHTML=("("+basket.length+")")
    li.appendChild(document.createTextNode(item.longName + "£" + item.price+"0"));
    ul.appendChild(li);
}

<commit_msg>basket<commit_after>$(document).ready(function(){
    // the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
    $('.modal').modal();
  });

function MenuItem(id,longName,price){
    this.id = id;
    this.longName = longName;
    this.price = price;
  }

var basket=[];
var ul = document.getElementById("basketItems");
var li = document.createElement("li");

var ribs = new MenuItem("ribs", "Spare Ribs in Barbecue Sauce", 4.60);
var ccm = new MenuItem("ccm", "Chicken Chow Mein", 4.20);
var cfr = new MenuItem("cfr", "Chicken Fried Rice", 4.20);
var cc = new MenuItem("cc", "Curry Chicken", 4.70);
var ssc = new MenuItem("ssc", "Sweet and Sour Chicken Crispy Balls", 4.00);

var basketTotal =document.getElementById("basketTotal");
var ribbutton=document.getElementById("ribs");
var ccmbutton=document.getElementById("ccm");
var cfrbutton=document.getElementById("cfr");
var ccbutton=document.getElementById("cc");
var sscbutton=document.getElementById("ssc");

ribbutton.onclick = function(){addToBasket(ribs)}
ccmbutton.onclick = function(){addToBasket(ccm)}
cfrbutton.onclick = function(){addToBasket(cfr)}
ccbutton.onclick = function(){addToBasket(cc)}
sscbutton.onclick = function(){addToBasket(ssc)}

function addToBasket(item){
    basket.push(item);
    Materialize.toast(item.longName + " added to basket", 4000);
    basketTotal.innerHTML=("("+basket.length+")")
    li.appendChild(document.createTextNode(item.longName + ":\t" + "£" + item.price+"0"));
    ul.appendChild(li);
}

<|endoftext|>


<commit_before>'use strict';

var plotlist = document.getElementById('plot-list');
var anchor = document.getElementById('embedded-graph');
var image = document.getElementById('embedded-image');

var gd = null;

anchor.style.position = 'relative';
anchor.style.top = '80px';
anchor.style.height = '600px';
anchor.style.width = '1000px';

function plotButtons(plots) {

    Object.keys(plots).forEach( function (plotname) {

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

        button.style.cssFloat = 'left';
        button.style.width = '100px';
        button.style.height = '40px';

        button.innerHTML = plotname;

        plotlist.appendChild(button);

        button.addEventListener('click', function () {

            var myImage = new Image();
            myImage.src = './testplots/'+ plotname + '.png';

            image.innerHTML = '';
            image.appendChild(myImage);

            anchor.innerHTML = '';

            gd = document.createElement('div');
            anchor.appendChild(gd);

            var plot = plots[plotname];
            Plotly.plot(gd, plot.data, plot.layout);

        });
    });

    var snapshot = document.createElement('button');

    snapshot.style.cssFloat = 'left';
    snapshot.style.width = '100px';
    snapshot.style.height = '40px';
    snapshot.style.marginLeft = '25px';
    snapshot.innerHTML = 'snapshot';
    snapshot.style.background = 'blue';

    plotlist.appendChild(snapshot);

    snapshot.addEventListener('click', function () {

        /*
         * Grab the currently loaded plot and make an image - replacing the plot.
         */
        if (!gd) return;

        var layout = gd.layout;
        var data = gd.data;

        if (!layout || !data) return;

        Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach( function (key) {
            var scene = gd._fullLayout[key]._scene;
            scene.destroy();
        });

        // create a fresh gd
        anchor.innerHTML = '';
        gd = document.createElement('div');
        anchor.appendChild(gd);

        /*
         * Replot with staticPlot
         */
        Plotly.plot(gd, data, layout, {staticPlot: true, plot3dPixelRatio: 2}).then( function () {
            Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach( function (key) {
                  var scene = gd._fullLayout[key]._scene;
                  var dataURL = scene.toImage();

                  var myImage = new Image();
                  myImage.src = dataURL;

                  myImage.onload = function () {
                      myImage.height = scene.container.clientHeight;
                      myImage.width = scene.container.clientWidth;
                  };

                  image.innerHTML = '';
                  image.appendChild(myImage);
              });
        })
    });

    var loseContextButton = document.createElement('button');
    loseContextButton.style.cssFloat = 'left';
    loseContextButton.style.width = '100px';
    loseContextButton.style.height = '40px';
    loseContextButton.style.marginLeft = '25px';
    loseContextButton.innerHTML = 'lose context';
    loseContextButton.style.background = 'blue';
    plotlist.appendChild(loseContextButton);

    loseContextButton.addEventListener('click', function() {
      if(!gd) {
        return;
      }
      Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach( function (key) {
          var scene = gd._fullLayout[key]._scene;
          var gl = scene.glplot.gl;
          var ext = gl.getExtension('WEBGL_lose_context');
          ext.loseContext();
      });
    });

        var pummelButton = document.createElement('button');
        pummelButton.style.cssFloat = 'left';
        pummelButton.style.width = '100px';
        pummelButton.style.height = '40px';
        pummelButton.style.marginLeft = '25px';
        pummelButton.innerHTML = 'pummel3d';
        pummelButton.style.background = 'blue';
        plotlist.appendChild(pummelButton);

        var i = 0;
        var mock = require('./testplots/marker-color.json');
        var statusDiv = document.getElementById('status-info');

        pummelButton.addEventListener('click', function () {
            setInterval(function () {
                var plotDiv = document.createElement('div');
                window.plotDiv = plotDiv;

                plotDiv.id = 'div' + i;
                document.body.appendChild(plotDiv);

                Plotly.plot(plotDiv, mock.data, mock.layout, {staticPlot: true}).then(function () {

                    Plotly.Plots.getSubplotIds(plotDiv._fullLayout, 'gl3d').forEach( function (key) {
                        var scene = plotDiv._fullLayout[key]._scene;
                        scene.destroy();
                        i ++;
                        statusDiv.innerHTML = 'Created ' + i + ' webgl contexts.';
                    });

                    document.body.removeChild(plotDiv);
                });

            }, 500);
        });

}

var plots = {};

plots['marker-color'] = require('./testplots/marker-color.json');
plots['log-axis-big'] = require('./testplots/log-axis-big.json');
plots['delaunay'] = require('./testplots/delaunay.json');
plots['log-axis'] = require('./testplots/log-axis.json');
plots['multi-scene'] = require('./testplots/multi-scene.json');
plots['surface-lighting'] = require('./testplots/surface-lighting.json');
plots['z-range'] = require('./testplots/z-range.json');
plots['mirror-ticks'] = require('./testplots/mirror-ticks.json');
plots['autorange-zero'] = require('./testplots/autorange-zero.json');
plots['contour-lines'] = require('./testplots/contour-lines.json');
plots['xy-defined-ticks'] = require('./testplots/xy-defined-ticks.json');
plots['opacity-surface'] = require('./testplots/opacity-surface.json');
plots['projection-traces'] = require('./testplots/projection-traces.json');
plots['opacity-scaling-spikes'] = require('./testplots/opacity-scaling-spikes.json');
plots['text-weirdness'] = require('./testplots/text-weirdness.json');
plots['wire-surface'] = require('./testplots/wire-surface.json');
plots['triangle-mesh3d'] = require('./testplots/triangle.json');
plots['snowden'] = require('./testplots/snowden.json');
plots['bunny'] = require('./testplots/bunny.json');
plots['ribbons'] = require('./testplots/ribbons.json');
plots['date-time'] = require('./testplots/scatter-date.json');
plots['cufflinks'] = require('./testplots/cufflinks.json');
plots['chrisp-nan-1'] = require('./testplots/chrisp-nan-1.json');

plotButtons(plots);
<commit_msg>toggle restore context as well<commit_after>'use strict';

var plotlist = document.getElementById('plot-list');
var anchor = document.getElementById('embedded-graph');
var image = document.getElementById('embedded-image');

var gd = null;

anchor.style.position = 'relative';
anchor.style.top = '80px';
anchor.style.height = '600px';
anchor.style.width = '1000px';

function plotButtons(plots) {

    Object.keys(plots).forEach( function (plotname) {

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

        button.style.cssFloat = 'left';
        button.style.width = '100px';
        button.style.height = '40px';

        button.innerHTML = plotname;

        plotlist.appendChild(button);

        button.addEventListener('click', function () {

            var myImage = new Image();
            myImage.src = './testplots/'+ plotname + '.png';

            image.innerHTML = '';
            image.appendChild(myImage);

            anchor.innerHTML = '';

            gd = document.createElement('div');
            anchor.appendChild(gd);

            var plot = plots[plotname];
            Plotly.plot(gd, plot.data, plot.layout);

        });
    });

    var snapshot = document.createElement('button');

    snapshot.style.cssFloat = 'left';
    snapshot.style.width = '100px';
    snapshot.style.height = '40px';
    snapshot.style.marginLeft = '25px';
    snapshot.innerHTML = 'snapshot';
    snapshot.style.background = 'blue';

    plotlist.appendChild(snapshot);

    snapshot.addEventListener('click', function () {

        /*
         * Grab the currently loaded plot and make an image - replacing the plot.
         */
        if (!gd) return;

        var layout = gd.layout;
        var data = gd.data;

        if (!layout || !data) return;

        Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach( function (key) {
            var scene = gd._fullLayout[key]._scene;
            scene.destroy();
        });

        // create a fresh gd
        anchor.innerHTML = '';
        gd = document.createElement('div');
        anchor.appendChild(gd);

        /*
         * Replot with staticPlot
         */
        Plotly.plot(gd, data, layout, {staticPlot: true, plot3dPixelRatio: 2}).then( function () {
            Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach( function (key) {
                  var scene = gd._fullLayout[key]._scene;
                  var dataURL = scene.toImage();

                  var myImage = new Image();
                  myImage.src = dataURL;

                  myImage.onload = function () {
                      myImage.height = scene.container.clientHeight;
                      myImage.width = scene.container.clientWidth;
                  };

                  image.innerHTML = '';
                  image.appendChild(myImage);
              });
        })
    });

    var loseContextButton = document.createElement('button');
    loseContextButton.style.cssFloat = 'left';
    loseContextButton.style.width = '100px';
    loseContextButton.style.height = '40px';
    loseContextButton.style.marginLeft = '25px';
    loseContextButton.innerHTML = 'lose/restore context';
    loseContextButton.style.background = 'blue';
    plotlist.appendChild(loseContextButton);

    var ext = null;
    loseContextButton.addEventListener('click', function() {
      if(!gd) {
        return;
      }
      Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach( function (key) {
          var scene = gd._fullLayout[key]._scene;
          var gl = scene.glplot.gl;
          if(gl.isContextLost()) {
            ext.restoreContext();
          } else {
            ext = gl.getExtension('WEBGL_lose_context');
            ext.loseContext();
          }
      });
    });

        var pummelButton = document.createElement('button');
        pummelButton.style.cssFloat = 'left';
        pummelButton.style.width = '100px';
        pummelButton.style.height = '40px';
        pummelButton.style.marginLeft = '25px';
        pummelButton.innerHTML = 'pummel3d';
        pummelButton.style.background = 'blue';
        plotlist.appendChild(pummelButton);

        var i = 0;
        var mock = require('./testplots/marker-color.json');
        var statusDiv = document.getElementById('status-info');

        pummelButton.addEventListener('click', function () {
            setInterval(function () {
                var plotDiv = document.createElement('div');
                window.plotDiv = plotDiv;

                plotDiv.id = 'div' + i;
                document.body.appendChild(plotDiv);

                Plotly.plot(plotDiv, mock.data, mock.layout, {staticPlot: true}).then(function () {

                    Plotly.Plots.getSubplotIds(plotDiv._fullLayout, 'gl3d').forEach( function (key) {
                        var scene = plotDiv._fullLayout[key]._scene;
                        scene.destroy();
                        i ++;
                        statusDiv.innerHTML = 'Created ' + i + ' webgl contexts.';
                    });

                    document.body.removeChild(plotDiv);
                });

            }, 500);
        });

}

var plots = {};

plots['marker-color'] = require('./testplots/marker-color.json');
plots['log-axis-big'] = require('./testplots/log-axis-big.json');
plots['delaunay'] = require('./testplots/delaunay.json');
plots['log-axis'] = require('./testplots/log-axis.json');
plots['multi-scene'] = require('./testplots/multi-scene.json');
plots['surface-lighting'] = require('./testplots/surface-lighting.json');
plots['z-range'] = require('./testplots/z-range.json');
plots['mirror-ticks'] = require('./testplots/mirror-ticks.json');
plots['autorange-zero'] = require('./testplots/autorange-zero.json');
plots['contour-lines'] = require('./testplots/contour-lines.json');
plots['xy-defined-ticks'] = require('./testplots/xy-defined-ticks.json');
plots['opacity-surface'] = require('./testplots/opacity-surface.json');
plots['projection-traces'] = require('./testplots/projection-traces.json');
plots['opacity-scaling-spikes'] = require('./testplots/opacity-scaling-spikes.json');
plots['text-weirdness'] = require('./testplots/text-weirdness.json');
plots['wire-surface'] = require('./testplots/wire-surface.json');
plots['triangle-mesh3d'] = require('./testplots/triangle.json');
plots['snowden'] = require('./testplots/snowden.json');
plots['bunny'] = require('./testplots/bunny.json');
plots['ribbons'] = require('./testplots/ribbons.json');
plots['date-time'] = require('./testplots/scatter-date.json');
plots['cufflinks'] = require('./testplots/cufflinks.json');
plots['chrisp-nan-1'] = require('./testplots/chrisp-nan-1.json');

plotButtons(plots);
<|endoftext|>


<commit_before>/**
 * DEVELOPED BY
 * GIL LOPES BUENO
 * gilbueno.mail@gmail.com
 *
 * WORKS WITH:
 * IE 9+, FF 4+, SF 5+, WebKit, CH 7+, OP 12+, BESEN, Rhino 1.7+
 *
 * FORK:
 * https://github.com/melanke/Watch.JS
 */

"use strict";
(function (factory) {
    if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else {
        // Browser globals
        window.WatchJS = factory();
        window.watch = window.WatchJS.watch;
        window.unwatch = window.WatchJS.unwatch;
        window.callWatchers = window.WatchJS.callWatchers;
    }
}(function () {

    var WatchJS = {
        noMore: false
    },
    lengthsubjects = [];

    var isFunction = function (functionToCheck) {
            var getType = {};
            return functionToCheck && getType.toString.call(functionToCheck) == '[object Function]';
    };

    var isInt = function (x) {
        return x % 1 === 0;
    };

    var isArray = function(obj) {
        return Object.prototype.toString.call(obj) === '[object Array]';
    };

    var getObjDiff = function(a, b){
        var aplus = [],
        bplus = [];

        if(!(typeof a == "string") && !(typeof b == "string")){

            if (isArray(a)) {
                for (var i=0; i<a.length; i++) {
                    if (b[i] === undefined) aplus.push(i);
                }
            } else {
                for(var i in a){
                    if (a.hasOwnProperty(i)) {
                        if(b[i] === undefined) {
                            aplus.push(i);
                        }
                    }
                }
            }

            if (isArray(b)) {
                for (var j=0; j<b.length; j++) {
                    if (a[j] === undefined) bplus.push(j);
                }
            } else {
                for(var j in b){
                    if (b.hasOwnProperty(j)) {
                        if(a[j] === undefined) {
                            bplus.push(j);
                        }
                    }
                }
            }
        }

        return {
            added: aplus,
            removed: bplus
        }
    };

    var clone = function(obj){

        if (null == obj || "object" != typeof obj) {
            return obj;
        }

        var copy = obj.constructor();

        for (var attr in obj) {
            copy[attr] = obj[attr];
        }

        return copy;

    }

    var defineGetAndSet = function (obj, propName, getter, setter) {
        try {

            Object.observe(obj, function(changes) {
                changes.forEach(function(change) {
                    if (change.name === propName) {
                        setter(change.object[change.name]);
                    }
                });
            });

        } catch(e) {

            try {
                    Object.defineProperty(obj, propName, {
                            get: getter,
                            set: setter,
                            enumerable: true,
                            configurable: true
                    });
            } catch(e2) {
                try{
                    Object.prototype.__defineGetter__.call(obj, propName, getter);
                    Object.prototype.__defineSetter__.call(obj, propName, setter);
                } catch(e3) {
                    throw new Error("watchJS error: browser not supported :/")
                }
            }

        }
    };

    var defineProp = function (obj, propName, value) {
        try {
            Object.defineProperty(obj, propName, {
                enumerable: false,
                configurable: true,
                writable: false,
                value: value
            });
        } catch(error) {
            obj[propName] = value;
        }
    };

    var watch = function () {

        if (isFunction(arguments[1])) {
            watchAll.apply(this, arguments);
        } else if (isArray(arguments[1])) {
            watchMany.apply(this, arguments);
        } else {
            watchOne.apply(this, arguments);
        }

    };

    var watchAll = function (obj, watcher, level, addNRemove) {

        if ((typeof obj == "string") || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        var props = [];

        if(isArray(obj)) {
            for (var prop = 0; prop < obj.length; prop++) { //for each item if obj is an array
                props.push(prop); //put in the props
            }
        } else {
            for (var prop2 in obj) { //for each attribute if obj is an object
				if (prop2 == "$val") {
					continue;
				}

                if (Object.prototype.hasOwnProperty.call(obj, prop2)) {
                    props.push(prop2); //put in the props
                }
            }
        }

        watchMany(obj, props, watcher, level, addNRemove); //watch all items of the props

        if (addNRemove) {
            pushToLengthSubjects(obj, "$$watchlengthsubjectroot", watcher, level);
        }
    };

    var watchMany = function (obj, props, watcher, level, addNRemove) {

        if ((typeof obj == "string") || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        for (var i=0; i<props.length; i++) { //watch each property
            var prop = props[i];
            watchOne(obj, prop, watcher, level, addNRemove);
        }

    };

    var watchOne = function (obj, prop, watcher, level, addNRemove) {
        if ((typeof obj == "string") || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        if(isFunction(obj[prop])) { //dont watch if it is a function
            return;
        }
        if(obj[prop] != null && (level === undefined || level > 0)){
            watchAll(obj[prop], watcher, level!==undefined? level-1 : level); //recursively watch all attributes of this
        }

        defineWatcher(obj, prop, watcher, level);

        if(addNRemove && (level === undefined || level > 0)){
            pushToLengthSubjects(obj, prop, watcher, level);
        }

    };

    var unwatch = function () {

        if (isFunction(arguments[1])) {
            unwatchAll.apply(this, arguments);
        } else if (isArray(arguments[1])) {
            unwatchMany.apply(this, arguments);
        } else {
            unwatchOne.apply(this, arguments);
        }

    };

    var unwatchAll = function (obj, watcher) {

        if (obj instanceof String || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        if (isArray(obj)) {
            var props = [];
            for (var prop = 0; prop < obj.length; prop++) { //for each item if obj is an array
                props.push(prop); //put in the props
            }
            unwatchMany(obj, props, watcher); //watch all itens of the props
        } else {
            var unwatchPropsInObject = function (obj2) {
                var props = [];
                for (var prop2 in obj2) { //for each attribute if obj is an object
                    if (obj2.hasOwnProperty(prop2)) {
                        if (obj2[prop2] instanceof Object) {
                            unwatchPropsInObject(obj2[prop2]); //recurs into object props
                        } else {
                            props.push(prop2); //put in the props
                        }
                    }
                }
                unwatchMany(obj2, props, watcher); //unwatch all of the props
            };
            unwatchPropsInObject(obj);
        }
    };

    var unwatchMany = function (obj, props, watcher) {

        for (var prop2 in props) { //watch each attribute of "props" if is an object
            if (props.hasOwnProperty(prop2)) {
                unwatchOne(obj, props[prop2], watcher);
            }
        }
    };

    var defineWatcher = function (obj, prop, watcher, level) {

        var val = obj[prop];

        watchFunctions(obj, prop);

        if (!obj.watchers) {
            defineProp(obj, "watchers", {});
        }

        if (!obj.watchers[prop]) {
            obj.watchers[prop] = [];
        }

        for (var i=0; i<obj.watchers[prop].length; i++) {
            if(obj.watchers[prop][i] === watcher){
                return;
            }
        }

        obj.watchers[prop].push(watcher); //add the new watcher in the watchers array

        var getter = function () {
            return val;
        };

        var setter = function (newval) {
            var oldval = val;
            val = newval;

            if (level !== 0 && obj[prop]){
                // watch sub properties
                watchAll(obj[prop], watcher, (level===undefined)?level:level-1);
            }

            watchFunctions(obj, prop);

            if (!WatchJS.noMore){
                //if (JSON.stringify(oldval) !== JSON.stringify(newval)) {
                if (oldval !== newval) {
                    callWatchers(obj, prop, "set", newval, oldval);
                    WatchJS.noMore = false;
                }
            }
        };

        defineGetAndSet(obj, prop, getter, setter);

    };

    var callWatchers = function (obj, prop, action, newval, oldval) {
        if (prop !== undefined) {
            for (var wr=0; wr<obj.watchers[prop].length; wr++) {
                obj.watchers[prop][wr].call(obj, prop, action, newval, oldval);
            }
        } else {
            for (var prop in obj) {//call all
                if (obj.hasOwnProperty(prop)) {
                    callWatchers(obj, prop, action, newval, oldval);
                }
            }
        }
    };

    // @todo code related to "watchFunctions" is certainly buggy
    var methodNames = ['pop', 'push', 'reverse', 'shift', 'sort', 'slice', 'unshift', 'splice'];
    var defineArrayMethodWatcher = function (obj, prop, original, methodName) {
        defineProp(obj[prop], methodName, function () {
            var response = original.apply(obj[prop], arguments);
            watchOne(obj, obj[prop]);
            if (methodName !== 'slice') {
                callWatchers(obj, prop, methodName,arguments);
            }
            return response;
        });
    };

    var watchFunctions = function(obj, prop) {

        if ((!obj[prop]) || (obj[prop] instanceof String) || (!isArray(obj[prop]))) {
            return;
        }

        for (var i = methodNames.length, methodName; i--;) {
            methodName = methodNames[i];
            defineArrayMethodWatcher(obj, prop, obj[prop][methodName], methodName);
        }

    };

    var unwatchOne = function (obj, prop, watcher) {
        if (obj.watchers[prop] !== undefined) {
            for (var i=0; i<obj.watchers[prop].length; i++) {
                var w = obj.watchers[prop][i];

                if(w == watcher) {
                    obj.watchers[prop].splice(i, 1);
                }
            }
        }

        removeFromLengthSubjects(obj, prop, watcher);
    };

    var loop = function(start, stop){

        // var t0 = performance.now();

        for(var i=start; i<stop; i++) {

            var subj = lengthsubjects[i];
            if (subj) {
                if (subj.prop === "$$watchlengthsubjectroot") {

                    var difference = getObjDiff(subj.obj, subj.actual);

                    if(difference.added.length || difference.removed.length){
                        if(difference.added.length){
                            watchMany(subj.obj, difference.added, subj.watcher, subj.level - 1, true);
                        }

                        subj.watcher.call(subj.obj, "root", "differentattr", difference, subj.actual);
                    }
                    subj.actual = clone(subj.obj);

                } else {

                    var difference = getObjDiff(subj.obj[subj.prop], subj.actual);

                    if(difference.added.length || difference.removed.length){
                        if(difference.added.length){
                            for (var j=0; j<subj.obj.watchers[subj.prop].length; j++) {
                                watchMany(subj.obj[subj.prop], difference.added, subj.obj.watchers[subj.prop][j], subj.level - 1, true);
                            }
                        }

                        callWatchers(subj.obj, subj.prop, "differentattr", difference, subj.actual);
                    }

                    subj.actual = clone(subj.obj[subj.prop]);

                }
            }
        }

        // var t1 = performance.now();
        // console.log("loop (" + start + ", " + stop + ") " + lengthsubjects.length + " ws: " +  (t1 - t0) + " milliseconds.");

    };

    var pushToLengthSubjects = function(obj, prop, watcher, level){

        var actual;

        if (prop === "$$watchlengthsubjectroot") {
            actual =  clone(obj);
        } else {
            actual = clone(obj[prop]);
        }

        lengthsubjects.push({
            obj: obj,
            prop: prop,
            actual: actual,
            watcher: watcher,
            level: level
        });
    };

    var removeFromLengthSubjects = function(obj, prop, watcher){

        for (var i=0; i<lengthsubjects.length; i++) {
            var subj = lengthsubjects[i];

            if (subj.obj == obj && subj.prop == prop && subj.watcher == watcher) {
                lengthsubjects.splice(i, 1);
            }
        }

    };

    WatchJS.watch = watch;
    WatchJS.unwatch = unwatch;
    WatchJS.callWatchers = callWatchers;
    WatchJS.loop = loop;
    WatchJS.lengthsubjects = lengthsubjects;

    return WatchJS;

}));
<commit_msg>Remove Object.observe code and checks for defineProperty support<commit_after>/**
 * DEVELOPED BY
 * GIL LOPES BUENO
 * gilbueno.mail@gmail.com
 *
 * WORKS WITH:
 * IE 9+, FF 4+, SF 5+, WebKit, CH 7+, OP 12+, BESEN, Rhino 1.7+
 *
 * FORK:
 * https://github.com/melanke/Watch.JS
 */

"use strict";
(function (factory) {
    if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else {
        // Browser globals
        window.WatchJS = factory();
        window.watch = window.WatchJS.watch;
        window.unwatch = window.WatchJS.unwatch;
        window.callWatchers = window.WatchJS.callWatchers;
    }
}(function () {

    var WatchJS = {
        noMore: false
    },
    lengthsubjects = [];

    var isFunction = function (functionToCheck) {
            var getType = {};
            return functionToCheck && getType.toString.call(functionToCheck) == '[object Function]';
    };

    var isInt = function (x) {
        return x % 1 === 0;
    };

    var isArray = function(obj) {
        return Object.prototype.toString.call(obj) === '[object Array]';
    };

    var getObjDiff = function(a, b){
        var aplus = [],
        bplus = [];

        if(!(typeof a == "string") && !(typeof b == "string")){

            if (isArray(a)) {
                for (var i=0; i<a.length; i++) {
                    if (b[i] === undefined) aplus.push(i);
                }
            } else {
                for(var i in a){
                    if (a.hasOwnProperty(i)) {
                        if(b[i] === undefined) {
                            aplus.push(i);
                        }
                    }
                }
            }

            if (isArray(b)) {
                for (var j=0; j<b.length; j++) {
                    if (a[j] === undefined) bplus.push(j);
                }
            } else {
                for(var j in b){
                    if (b.hasOwnProperty(j)) {
                        if(a[j] === undefined) {
                            bplus.push(j);
                        }
                    }
                }
            }
        }

        return {
            added: aplus,
            removed: bplus
        }
    };

    var clone = function(obj){

        if (null == obj || "object" != typeof obj) {
            return obj;
        }

        var copy = obj.constructor();

        for (var attr in obj) {
            copy[attr] = obj[attr];
        }

        return copy;

    }

    var defineGetAndSet = function (obj, propName, getter, setter) {
        Object.defineProperty(obj, propName, {
            get: getter,
            set: setter,
            enumerable: true,
            configurable: true
        });
    };

    var defineProp = function (obj, propName, value) {
        Object.defineProperty(obj, propName, {
            enumerable: false,
            configurable: true,
            writable: false,
            value: value
        });
    };

    var watch = function () {

        if (isFunction(arguments[1])) {
            watchAll.apply(this, arguments);
        } else if (isArray(arguments[1])) {
            watchMany.apply(this, arguments);
        } else {
            watchOne.apply(this, arguments);
        }

    };

    var watchAll = function (obj, watcher, level, addNRemove) {

        if ((typeof obj == "string") || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        var props = [];

        if(isArray(obj)) {
            for (var prop = 0; prop < obj.length; prop++) { //for each item if obj is an array
                props.push(prop); //put in the props
            }
        } else {
            for (var prop2 in obj) { //for each attribute if obj is an object
				if (prop2 == "$val") {
					continue;
				}

                if (Object.prototype.hasOwnProperty.call(obj, prop2)) {
                    props.push(prop2); //put in the props
                }
            }
        }

        watchMany(obj, props, watcher, level, addNRemove); //watch all items of the props

        if (addNRemove) {
            pushToLengthSubjects(obj, "$$watchlengthsubjectroot", watcher, level);
        }
    };

    var watchMany = function (obj, props, watcher, level, addNRemove) {

        if ((typeof obj == "string") || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        for (var i=0; i<props.length; i++) { //watch each property
            var prop = props[i];
            watchOne(obj, prop, watcher, level, addNRemove);
        }

    };

    var watchOne = function (obj, prop, watcher, level, addNRemove) {
        if ((typeof obj == "string") || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        if(isFunction(obj[prop])) { //dont watch if it is a function
            return;
        }
        if(obj[prop] != null && (level === undefined || level > 0)){
            watchAll(obj[prop], watcher, level!==undefined? level-1 : level); //recursively watch all attributes of this
        }

        defineWatcher(obj, prop, watcher, level);

        if(addNRemove && (level === undefined || level > 0)){
            pushToLengthSubjects(obj, prop, watcher, level);
        }

    };

    var unwatch = function () {

        if (isFunction(arguments[1])) {
            unwatchAll.apply(this, arguments);
        } else if (isArray(arguments[1])) {
            unwatchMany.apply(this, arguments);
        } else {
            unwatchOne.apply(this, arguments);
        }

    };

    var unwatchAll = function (obj, watcher) {

        if (obj instanceof String || (!(obj instanceof Object) && !isArray(obj))) { //accepts only objects and array (not string)
            return;
        }

        if (isArray(obj)) {
            var props = [];
            for (var prop = 0; prop < obj.length; prop++) { //for each item if obj is an array
                props.push(prop); //put in the props
            }
            unwatchMany(obj, props, watcher); //watch all itens of the props
        } else {
            var unwatchPropsInObject = function (obj2) {
                var props = [];
                for (var prop2 in obj2) { //for each attribute if obj is an object
                    if (obj2.hasOwnProperty(prop2)) {
                        if (obj2[prop2] instanceof Object) {
                            unwatchPropsInObject(obj2[prop2]); //recurs into object props
                        } else {
                            props.push(prop2); //put in the props
                        }
                    }
                }
                unwatchMany(obj2, props, watcher); //unwatch all of the props
            };
            unwatchPropsInObject(obj);
        }
    };

    var unwatchMany = function (obj, props, watcher) {

        for (var prop2 in props) { //watch each attribute of "props" if is an object
            if (props.hasOwnProperty(prop2)) {
                unwatchOne(obj, props[prop2], watcher);
            }
        }
    };

    var defineWatcher = function (obj, prop, watcher, level) {

        var val = obj[prop];

        watchFunctions(obj, prop);

        if (!obj.watchers) {
            defineProp(obj, "watchers", {});
        }

        if (!obj.watchers[prop]) {
            obj.watchers[prop] = [];
        }

        for (var i=0; i<obj.watchers[prop].length; i++) {
            if(obj.watchers[prop][i] === watcher){
                return;
            }
        }

        obj.watchers[prop].push(watcher); //add the new watcher in the watchers array

        var getter = function () {
            return val;
        };

        var setter = function (newval) {
            var oldval = val;
            val = newval;

            if (level !== 0 && obj[prop]){
                // watch sub properties
                watchAll(obj[prop], watcher, (level===undefined)?level:level-1);
            }

            watchFunctions(obj, prop);

            if (!WatchJS.noMore){
                //if (JSON.stringify(oldval) !== JSON.stringify(newval)) {
                if (oldval !== newval) {
                    callWatchers(obj, prop, "set", newval, oldval);
                    WatchJS.noMore = false;
                }
            }
        };

        defineGetAndSet(obj, prop, getter, setter);

    };

    var callWatchers = function (obj, prop, action, newval, oldval) {
        if (prop !== undefined) {
            for (var wr=0; wr<obj.watchers[prop].length; wr++) {
                obj.watchers[prop][wr].call(obj, prop, action, newval, oldval);
            }
        } else {
            for (var prop in obj) {//call all
                if (obj.hasOwnProperty(prop)) {
                    callWatchers(obj, prop, action, newval, oldval);
                }
            }
        }
    };

    // @todo code related to "watchFunctions" is certainly buggy
    var methodNames = ['pop', 'push', 'reverse', 'shift', 'sort', 'slice', 'unshift', 'splice'];
    var defineArrayMethodWatcher = function (obj, prop, original, methodName) {
        defineProp(obj[prop], methodName, function () {
            var response = original.apply(obj[prop], arguments);
            watchOne(obj, obj[prop]);
            if (methodName !== 'slice') {
                callWatchers(obj, prop, methodName,arguments);
            }
            return response;
        });
    };

    var watchFunctions = function(obj, prop) {

        if ((!obj[prop]) || (obj[prop] instanceof String) || (!isArray(obj[prop]))) {
            return;
        }

        for (var i = methodNames.length, methodName; i--;) {
            methodName = methodNames[i];
            defineArrayMethodWatcher(obj, prop, obj[prop][methodName], methodName);
        }

    };

    var unwatchOne = function (obj, prop, watcher) {
        if (obj.watchers[prop] !== undefined) {
            for (var i=0; i<obj.watchers[prop].length; i++) {
                var w = obj.watchers[prop][i];

                if(w == watcher) {
                    obj.watchers[prop].splice(i, 1);
                }
            }
        }

        removeFromLengthSubjects(obj, prop, watcher);
    };

    var loop = function(start, stop){

        // var t0 = performance.now();

        for(var i=start; i<stop; i++) {

            var subj = lengthsubjects[i];
            if (subj) {
                if (subj.prop === "$$watchlengthsubjectroot") {

                    var difference = getObjDiff(subj.obj, subj.actual);

                    if(difference.added.length || difference.removed.length){
                        if(difference.added.length){
                            watchMany(subj.obj, difference.added, subj.watcher, subj.level - 1, true);
                        }

                        subj.watcher.call(subj.obj, "root", "differentattr", difference, subj.actual);
                    }
                    subj.actual = clone(subj.obj);

                } else {

                    var difference = getObjDiff(subj.obj[subj.prop], subj.actual);

                    if(difference.added.length || difference.removed.length){
                        if(difference.added.length){
                            for (var j=0; j<subj.obj.watchers[subj.prop].length; j++) {
                                watchMany(subj.obj[subj.prop], difference.added, subj.obj.watchers[subj.prop][j], subj.level - 1, true);
                            }
                        }

                        callWatchers(subj.obj, subj.prop, "differentattr", difference, subj.actual);
                    }

                    subj.actual = clone(subj.obj[subj.prop]);

                }
            }
        }

        // var t1 = performance.now();
        // console.log("loop (" + start + ", " + stop + ") " + lengthsubjects.length + " ws: " +  (t1 - t0) + " milliseconds.");

    };

    var pushToLengthSubjects = function(obj, prop, watcher, level){

        var actual;

        if (prop === "$$watchlengthsubjectroot") {
            actual =  clone(obj);
        } else {
            actual = clone(obj[prop]);
        }

        lengthsubjects.push({
            obj: obj,
            prop: prop,
            actual: actual,
            watcher: watcher,
            level: level
        });
    };

    var removeFromLengthSubjects = function(obj, prop, watcher){

        for (var i=0; i<lengthsubjects.length; i++) {
            var subj = lengthsubjects[i];

            if (subj.obj == obj && subj.prop == prop && subj.watcher == watcher) {
                lengthsubjects.splice(i, 1);
            }
        }

    };

    WatchJS.watch = watch;
    WatchJS.unwatch = unwatch;
    WatchJS.callWatchers = callWatchers;
    WatchJS.loop = loop;
    WatchJS.lengthsubjects = lengthsubjects;

    return WatchJS;

}));
<|endoftext|>