<commit_before>'use strict';

var path = require('path');

module.exports = function(html, attachments) {
  attachments.forEach(function(attachment) {
    attachment.applied = false;

    var regexps = [
      (attachment.fileName) ? new RegExp(']*cid:' + attachment.fileName.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&") + '[@"\'][^>]*>', 'ig') : undefined,
      (attachment.contentId) ? new RegExp(']*cid:' + attachment.contentId.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&") + '[@"\'][^>]*>', 'ig') : undefined,
    ];

    var content = Buffer.isBuffer(attachment.content) ? attachment.content.toString('base64') : attachment.content;

    var extension = path.extname(attachment.fileName).replace('.', '');
    if (extension === 'jpeg') {
      extension = 'jpg';
    }

    regexps.forEach(function(regexp) {
      if(regexp && regexp.test(html)) {
        attachment.applied = true;

        html = html.replace(regexp, '');
      }
    });
  });

  return html.replace(/]*cid:[^>]*>/ig, '');
};<commit_msg>Fix syntax<commit_after>'use strict';

var path = require('path');

module.exports = function(html, attachments) {
  attachments.forEach(function(attachment) {
    attachment.applied = false;

    var regexps = [
      (attachment.fileName) ? new RegExp(']*cid:' + attachment.fileName.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&") + '[@"\'][^>]*>', 'ig') : undefined,
      (attachment.contentId) ? new RegExp(']*cid:' + attachment.contentId.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&") + '[@"\'][^>]*>', 'ig') : undefined,
    ];

    var content = Buffer.isBuffer(attachment.content) ? attachment.content.toString('base64') : attachment.content;

    var extension = path.extname(attachment.fileName).replace('.', '');
    if(extension === 'jpeg') {
      extension = 'jpg';
    }

    regexps.forEach(function(regexp) {
      if(regexp && regexp.test(html)) {
        attachment.applied = true;

        html = html.replace(regexp, '');
      }
    });
  });

  return html.replace(/]*cid:[^>]*>/ig, '');
};<|endoftext|>


<commit_before>var dotVoteCardButtonCallback = function (t) {
    var currentMember = {};
    return t.member('all')
    .then(function(member) {
        currentMember = member;
        return t.get('card', 'shared', UMTrello.constants.data.votes, {});
    })
    .then(function(currentVotes) {
        if(!currentVotes.hasOwnProperty(currentMember.id)) {
            currentVotes[currentMember.id] = 0;
        }
        console.log("Old Value: " + currentVotes[currentMember.id]);
        currentVotes[currentMember.id]++;
        console.log("New Value: " + currentVotes[currentMember.id]);
        console.dir(currentVotes);
        return t.set('card', 'shared', UMTrello.constants.data.votes, currentVotes);
    })
    .catch(function(err) {
        console.log("Voting Error");
        console.dir(err);
    });
};

var sortCardsInListPopup = function (t) {
    return t.popup({
        title: 'Select List for Sorting',
        url: './sort-list.html',
        height: 200
    })
};

var clearListVotesPopup = function (t) {
    return t.popup({
        title: 'Select List to Clear Votes',
        url: './clear-list.html',
        height: 200
    })
};

var boardButtonCallback = function (t) {
    return t.popup({
        title: 'Dot Voting Actions',
        items: [
            {
                text: 'Clear Votes on a List',
                callback: clearListVotesPopup
            }
        ]
    });
};

var idsCallback = function (t) {
    return t.popup({
        title: 'IDS Discovery',
        url: './ids.html',
        height: 200
    })
};

var getCardBadges = function (t) {
    return t.get('card','shared', UMTrello.constants.data.votes, 0)
    .then(function(dotVotes) {
        var votes = 0;
        for(var key in dotVotes) {
            votes += dotVotes[key];
        }
        if(votes > 0) {
            return [{
                text: votes,
                icon: GREY_DOT_ICON
            }];
        }
        return [];
    })
    .catch(function(err) {
        console.log("Card Badge Error");
        console.dir(err);
    });
};

var getMemberFirstName = function(id, members) {
    var member = members.find(function(element) {
        return element.id === id;
    });
    if(member) {
        return UMTrello.getMembersFirstName(member);
    }
    console.log("Could not find member and/or name for member");
    return "";
};

var getCardDetailBadges = function(t, members) {
    return t.get('card', 'shared', UMTrello.constants.data.votes, {})
    .then(function(dotVotes) {
        var cards = [];
        for(var key in dotVotes) {
            if(dotVotes[key] > 0) {
                var description = dotVotes[key] + " votes";
                var memberName = getMemberFirstName(key, members);
                cards.push({
                    title: memberName,
                    text: description,
                    icon: GREY_DOT_ICON
                });
            }
        }
        return cards;
    })
    .catch(function(err) {
       console.log("Error When Creating Details Cards.");
       console.dir(err);
    });
};

var getIDSBadges = function(t, members) {
    return t.get('card', 'shared', UMTrello.constants.data.ids, {})
    .then(function(ids) {
        var cards = [];
        if(ids.reporter !== undefined && ids.reporter !== 0) {
            cards.push({
                title: 'IDS',
                text: 'Reporter: ' + UMTrello.getMembersNameFromID(members, ids.reporter),
                icon: null,
                callback: idsCallback
            });
        }
        if(ids.assignee !== undefined && ids.assignee !== 0) {
            cards.push({
                title: 'IDS',
                text: 'Reporter: ' + UMTrello.getMembersNameFromID(members, ids.assignee),
                icon: null,
                callback: idsCallback
            });
        }
        if(ids.what !== undefined && ids.what.trim() !== '') {
            cards.push({
                title: 'IDS',
                text: 'Issue: ' + ids.what,
                icon: null,
                callback: idsCallback
            });
        }
        console.log("IDS Cards");
        console.dir(cards);
        return cards;
    })
    .catch(function(err) {
        console.log("Error creating IDS cards");
        console.dir(err);
    })
};

var DOT_ICON = './images/dot.png';
var GREY_DOT_ICON = './images/grey-dot.png';

var _members;
var getMembers = function(t) {
    return new Promise(function(resolve, reject) {
        if(_members !== undefined) {
            resolve(_members);
        }
        return t.board('members')
        .then(function(board) {
            _members = board.members;
            resolve(_members);
        })
        .catch(function(err) {
            reject(err);
        });
    });

};

TrelloPowerUp.initialize({
    'board-buttons': function (t, options) {
        return [{
            icon: DOT_ICON,
            text: 'Dot Voting Actions',
            callback: boardButtonCallback
        }];
    },
    'card-buttons': function (t, options) {
        return [{
            icon: GREY_DOT_ICON,
            text: 'Dot Vote',
            callback: dotVoteCardButtonCallback
        }, {
            icon: GREY_DOT_ICON,
            text:  'IDS',
            callback: idsCallback
        }];
    },
    'card-badges': function (t, options) {
        return getMembers(t)
        .then(function(members) {
            return Promise.all([getCardBadges(t), getIDSBadges(t, members)])
            .spread(function(dotVotingBadges, idsBadges) {
                var output = idsBadges.concat(dotVotingBadges);
                console.log("Output");
                console.dir(output);
                return output;
            });
        })
        .catch(function(err) {
            console.log("Error on Card Badges");
            console.dir(err);
        });
    },
    'card-detail-badges': function (t, options) {
        return getMembers(t)
        .then(function(members) {
            return Promise.all([getCardDetailBadges(t, members), getIDSBadges(t, members)])
            .spread(function (dotVotingBadges, idsBadges) {
                var output = idsBadges.concat(dotVotingBadges);
                console.log("Output");
                console.dir(output);
                return output;
            });
        })
        .catch(function(err) {
            console.log("Error on Detail Card Badges");
            console.dir(err);
        });
    }
});

<commit_msg>Updating badge handling for IDS<commit_after>var dotVoteCardButtonCallback = function (t) {
    var currentMember = {};
    return t.member('all')
    .then(function(member) {
        currentMember = member;
        return t.get('card', 'shared', UMTrello.constants.data.votes, {});
    })
    .then(function(currentVotes) {
        if(!currentVotes.hasOwnProperty(currentMember.id)) {
            currentVotes[currentMember.id] = 0;
        }
        console.log("Old Value: " + currentVotes[currentMember.id]);
        currentVotes[currentMember.id]++;
        console.log("New Value: " + currentVotes[currentMember.id]);
        console.dir(currentVotes);
        return t.set('card', 'shared', UMTrello.constants.data.votes, currentVotes);
    })
    .catch(function(err) {
        console.log("Voting Error");
        console.dir(err);
    });
};

var sortCardsInListPopup = function (t) {
    return t.popup({
        title: 'Select List for Sorting',
        url: './sort-list.html',
        height: 200
    })
};

var clearListVotesPopup = function (t) {
    return t.popup({
        title: 'Select List to Clear Votes',
        url: './clear-list.html',
        height: 200
    })
};

var boardButtonCallback = function (t) {
    return t.popup({
        title: 'Dot Voting Actions',
        items: [
            {
                text: 'Clear Votes on a List',
                callback: clearListVotesPopup
            }
        ]
    });
};

var idsCallback = function (t) {
    return t.popup({
        title: 'IDS Discovery',
        url: './ids.html',
        height: 200
    })
};

var getCardBadges = function (t) {
    return t.get('card','shared', UMTrello.constants.data.votes, 0)
    .then(function(dotVotes) {
        var votes = 0;
        for(var key in dotVotes) {
            votes += dotVotes[key];
        }
        if(votes > 0) {
            return [{
                text: votes,
                icon: GREY_DOT_ICON
            }];
        }
        return [];
    })
    .catch(function(err) {
        console.log("Card Badge Error");
        console.dir(err);
    });
};

var getMemberFirstName = function(id, members) {
    var member = members.find(function(element) {
        return element.id === id;
    });
    if(member) {
        return UMTrello.getMembersFirstName(member);
    }
    console.log("Could not find member and/or name for member");
    return "";
};

var getCardDetailBadges = function(t, members) {
    return t.get('card', 'shared', UMTrello.constants.data.votes, {})
    .then(function(dotVotes) {
        var cards = [];
        for(var key in dotVotes) {
            if(dotVotes[key] > 0) {
                var description = dotVotes[key] + " votes";
                var memberName = getMemberFirstName(key, members);
                cards.push({
                    title: memberName,
                    text: description,
                    icon: GREY_DOT_ICON
                });
            }
        }
        return cards;
    })
    .catch(function(err) {
       console.log("Error When Creating Details Cards.");
       console.dir(err);
    });
};

var getIDSBadges = function(t, members) {
    return t.get('card', 'shared', UMTrello.constants.data.ids, {})
    .then(function(ids) {
        var cards = [];
        if(ids.hasOwnProperty('reporter') && ids.reporter !== undefined && ids.reporter !== 0) {
            cards.push({
                title: 'IDS',
                text: 'Reporter: ' + UMTrello.getMembersNameFromID(members, ids.reporter),
                icon: null,
                callback: idsCallback
            });
        }
        if(ids.hasOwnProperty('assignee') && ids.assignee !== undefined && ids.assignee !== 0) {
            cards.push({
                title: 'IDS',
                text: 'Reporter: ' + UMTrello.getMembersNameFromID(members, ids.assignee),
                icon: null,
                callback: idsCallback
            });
        }
        if(ids.hasOwnProperty('what') && ids.what !== undefined && ids.what.trim() !== '') {
            cards.push({
                title: 'IDS',
                text: 'Issue: ' + ids.what,
                icon: null,
                callback: idsCallback
            });
        }
        console.log("IDS Cards");
        console.dir(cards);
        return cards;
    })
    .catch(function(err) {
        console.log("Error creating IDS cards");
        console.dir(err);
    })
};

var DOT_ICON = './images/dot.png';
var GREY_DOT_ICON = './images/grey-dot.png';

var _members;
var getMembers = function(t) {
    return new Promise(function(resolve, reject) {
        if(_members !== undefined) {
            resolve(_members);
        }
        return t.board('members')
        .then(function(board) {
            _members = board.members;
            resolve(_members);
        })
        .catch(function(err) {
            reject(err);
        });
    });

};

TrelloPowerUp.initialize({
    'board-buttons': function (t, options) {
        return [{
            icon: DOT_ICON,
            text: 'Dot Voting Actions',
            callback: boardButtonCallback
        }];
    },
    'card-buttons': function (t, options) {
        return [{
            icon: GREY_DOT_ICON,
            text: 'Dot Vote',
            callback: dotVoteCardButtonCallback
        }, {
            icon: GREY_DOT_ICON,
            text:  'IDS',
            callback: idsCallback
        }];
    },
    'card-badges': function (t, options) {
        return getMembers(t)
        .then(function(members) {
            return Promise.all([getCardBadges(t), getIDSBadges(t, members)])
            .spread(function(dotVotingBadges, idsBadges) {
                var output = idsBadges.concat(dotVotingBadges);
                console.log("Output");
                console.dir(output);
                return output;
            });
        })
        .catch(function(err) {
            console.log("Error on Card Badges");
            console.dir(err);
        });
    },
    'card-detail-badges': function (t, options) {
        return getMembers(t)
        .then(function(members) {
            return Promise.all([getCardDetailBadges(t, members), getIDSBadges(t, members)])
            .spread(function (dotVotingBadges, idsBadges) {
                var output = idsBadges.concat(dotVotingBadges);
                console.log("Output");
                console.dir(output);
                return output;
            });
        })
        .catch(function(err) {
            console.log("Error on Detail Card Badges");
            console.dir(err);
        });
    }
});

<|endoftext|>


<commit_before>/* LANGUAGE
================================================== */typeof VMM!="undefined"&&(VMM.Language={lang:"pl",api:{wikipedia:"pl"},date:{month:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],month_abbr:["Sty.","Lut.","Mar.","Kwi.","Maj.","Cze.","Lip.","Sie.","Wrz.","Paź.","Lis.","Gru."],day:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],day_abbr:["Nie.","Pon.","Wto.","Śro.","Czw.","Pią.","Sob."]},dateformats:{year:"yyyy",month_short:"mmm",month:"mmmm yyyy",full_short:"d mmm",full:"d mmmm yyyy",time_no_seconds_short:"HH:MM",time_no_seconds_small_date:"HH:MM'
'd mmmm yyyy''",full_long:"dddd',' d mmm yyyy 'um' HH:MM",full_long_small_date:"HH:MM'
'dddd',' d mmm yyyy''"},messages:{loading_timeline:"Ładowanie Timeline... ",return_to_title:"Wróć do tutułu",expand_timeline:"Rozszerz Timeline",contract_timeline:"Umowa Timeline",wikipedia:"Z Wikipedii, wolnej encyklopedii",loading_content:"Ładowanie zawartości",loading:"Ładowanie"}});<commit_msg>Fixed polish translations<commit_after>/* LANGUAGE
================================================== */typeof VMM!="undefined"&&(VMM.Language={lang:"pl",api:{wikipedia:"pl"},date:{month:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],month_abbr:["Sty.","Lut.","Mar.","Kwi.","Maj.","Cze.","Lip.","Sie.","Wrz.","Paź.","Lis.","Gru."],day:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],day_abbr:["Nie.","Pon.","Wto.","Śro.","Czw.","Pią.","Sob."]},dateformats:{year:"yyyy",month_short:"mmm",month:"mmmm yyyy",full_short:"d mmm",full:"d mmmm yyyy",time_no_seconds_short:"HH:MM",time_no_seconds_small_date:"HH:MM'
'd mmmm yyyy''",full_long:"dddd',' d mmm yyyy 'um' HH:MM",full_long_small_date:"HH:MM'
'dddd',' d mmm yyyy''"},messages:{loading_timeline:"Ładowanie Timeline... ",return_to_title:"Wróć do tytułu",expand_timeline:"Powiększ Timeline",contract_timeline:"Zmniejsz Timeline",wikipedia:"Z Wikipedii, wolnej encyklopedii",loading_content:"Ładowanie zawartości",loading:"Ładowanie"}});
<|endoftext|>


<commit_before>(function() { // just for scoping

// readFile fnuction from logan
// http://www.gozer.org/mozilla/userChrome.js/scripts/userScripts.uc.js
// |file| must be an nsIFile.
// Returns the contents of the file as a string.
function readFile(file)
{
  var content = '';

  var stream = Components.classes['@mozilla.org/network/file-input-stream;1']
                    .createInstance(Components.interfaces.nsIFileInputStream);
  stream.init(file, 0x01, 0, 0);

  var script = Components.classes['@mozilla.org/scriptableinputstream;1']
              .createInstance(Components.interfaces.nsIScriptableInputStream);
  script.init(stream);

  if (stream.available()) {
    var data = script.read(4096);

    while (data.length > 0) {
      content += data;
      data = script.read(4096);
    }
  }

  stream.close();
  script.close();

  return content;
}

// http://developer.mozilla.org/en/docs/Code_snippets:On_page_load
// https://bugzilla.mozilla.org/show_bug.cgi?id=329514

window.addEventListener("load", domFuzzInit, false);

function domFuzzInit(event)
{
  window.removeEventListener("load", domFuzzInit, false);

  var appcontent = document.getElementById("appcontent");
  appcontent.addEventListener("load", onPageLoad, true);

  // http://developer.mozilla.org/en/docs/Code_snippets:Interaction_between_privileged_and_non-privileged_pages
  // Setting the last argument to |true| means we're allowing untrusted events to trigger this chrome event handler.
  window.addEventListener("please-quit", pleaseQuitCalled, true, true);
  window.addEventListener("please-gc", pleaseGCCalled, true, true);

}

function onPageLoad(event)
{
  var doc = event.originalTarget;
  if (doc.nodeName != "#document")
    return;

  var hash = doc.location.hash;

  var r = hash.split("!");

  if (r[0] != "#squarefree-af")
    return;
  if (!(/^[a-zA-Z0-9\-.]*$/.test(r[1]))) {
    dump("Sketchy fuzzer filename!\n");
    return;
  }

  // I hope having this event listener doesn't have side effects!
  doc.addEventListener("pagehide", quitPageHide, false);

  var d = Components.classes["@mozilla.org/file/directory_service;1"]
                    .getService(Components.interfaces.nsIProperties)
                    .get("ProfD", Components.interfaces.nsIFile);

  d.append("extensions");
  d.append("domfuzz@squarefree.com");

  var extensionLocation = readFile(d).replace(/\s*$/, "");

  var f = Components.classes["@mozilla.org/file/local;1"]
                    .createInstance(Components.interfaces.nsILocalFile);
  f.initWithPath(extensionLocation);

  dir = f.parent;
  dir.append("fuzzers");
  // dir now points to the directory containing fuzzer-combined.js, etc.

  var scriptToInject =
    readFile(indir(dir, "fuzz.js")) + "\n"
  + readFile(indir(dir, r[1])) + "\n"
  + readFile(indir(dir, "fuzz-finish-auto.js")) + "\n"
  + "document.getElementById('fuzz1').parentNode.removeChild(document.getElementById('fuzz1'));\n"
  + "fuzzSettings = [" + r[2] + "];\n"
  + "setTimeout(fuzzOnload, 400);\n";

  insertionPoint = doc.getElementsByTagName("head")[0] || doc.documentElement;

  if (!insertionPoint)
    return;

  var script = doc.createElementNS("http://www.w3.org/1999/xhtml", "script");
  script.setAttribute("id", "fuzz1");
  script.setAttribute("type", "text/javascript");
  script.textContent = scriptToInject;
  insertionPoint.appendChild(script);
}

function indir(dir, filename)
{
  var d = dir.clone();
  d.append(filename);
  return d;
}

/*
function quitTimeout()
{
  dump("Quitting due to timeout.\n");
  goQuitApplication();
}
*/

function quitPageHide()
{
  dumpln("Quitting due to pagehide.\n");
  goQuitApplication();
}

function pleaseQuitCalled()
{
  dump("Quitting because I got a please-quit event from the web page.\n");
  goQuitApplication();
}

function pleaseGCCalled()
{
  dump("GC!\n");
  Components.utils.forceGC();

        window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
              .getInterface(Components.interfaces.nsIDOMWindowUtils)
              .garbageCollect();
        window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
              .getInterface(Components.interfaces.nsIDOMWindowUtils)
              .garbageCollect();
        window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
              .getInterface(Components.interfaces.nsIDOMWindowUtils)
              .garbageCollect();
}

// From quit.js, which Bob Clary extracted from mozilla/toolkit/content

function canQuitApplication()
{
  var os = Components.classes["@mozilla.org/observer-service;1"]
    .getService(Components.interfaces.nsIObserverService);
  if (!os)
  {
    return true;
  }

  try
 {
    var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
      .createInstance(Components.interfaces.nsISupportsPRBool);
    os.notifyObservers(cancelQuit, "quit-application-requested", null);

    // Something aborted the quit process.
    if (cancelQuit.data)
    {
      return false;
    }
  }
  catch (ex)
  {
  }
  os.notifyObservers(null, "quit-application-granted", null);
  return true;
}

function goQuitApplication()
{
  var privs = 'UniversalPreferencesRead UniversalPreferencesWrite ' +
    'UniversalXPConnect';

  try
  {
    netscape.security.PrivilegeManager.enablePrivilege(privs);
  }
  catch(ex)
  {
    throw('goQuitApplication: privilege failure ' + ex);
  }

  if (!canQuitApplication())
  {
    return false;
  }

  var kAppStartup = '@mozilla.org/toolkit/app-startup;1';
  var kAppShell   = '@mozilla.org/appshell/appShellService;1';
  var   appService;
  var   forceQuit;

  if (kAppStartup in Components.classes)
  {
    appService = Components.classes[kAppStartup].
      getService(Components.interfaces.nsIAppStartup);
    forceQuit  = Components.interfaces.nsIAppStartup.eForceQuit;

  }
  else if (kAppShell in Components.classes)
  {
    appService = Components.classes[kAppShell].
      getService(Components.interfaces.nsIAppShellService);
    forceQuit = Components.interfaces.nsIAppShellService.eForceQuit;
  }
  else
  {
    throw 'goQuitApplication: no AppStartup/appShell';
  }

  var windowManager = Components.
    classes['@mozilla.org/appshell/window-mediator;1'].getService();

  var windowManagerInterface = windowManager.
    QueryInterface(Components.interfaces.nsIWindowMediator);

  var enumerator = windowManagerInterface.getEnumerator(null);

  while (enumerator.hasMoreElements())
  {
    var domWindow = enumerator.getNext();
    if (("tryToClose" in domWindow) && !domWindow.tryToClose())
    {
      return false;
    }
    domWindow.close();
  }

  try
  {
    appService.quit(forceQuit);
  }
  catch(ex)
  {
    throw('goQuitApplication: ' + ex);
  }

  return true;
}

})();

<commit_msg>Add please-run-soon thing to domfuzz.js (faster than setTimeout, supposed to have guaranteed-stable interleaving with interruptible reflow)<commit_after>(function() { // just for scoping

function dumpln(s) { dump(s + "\n"); }

// readFile fnuction from logan
// http://www.gozer.org/mozilla/userChrome.js/scripts/userScripts.uc.js
// |file| must be an nsIFile.
// Returns the contents of the file as a string.
function readFile(file)
{
  var content = '';

  var stream = Components.classes['@mozilla.org/network/file-input-stream;1']
                    .createInstance(Components.interfaces.nsIFileInputStream);
  stream.init(file, 0x01, 0, 0);

  var script = Components.classes['@mozilla.org/scriptableinputstream;1']
              .createInstance(Components.interfaces.nsIScriptableInputStream);
  script.init(stream);

  if (stream.available()) {
    var data = script.read(4096);

    while (data.length > 0) {
      content += data;
      data = script.read(4096);
    }
  }

  stream.close();
  script.close();

  return content;
}

// http://developer.mozilla.org/en/docs/Code_snippets:On_page_load
// https://bugzilla.mozilla.org/show_bug.cgi?id=329514

window.addEventListener("load", domFuzzInit, false);

function domFuzzInit(event)
{
  window.removeEventListener("load", domFuzzInit, false);

  var appcontent = document.getElementById("appcontent");
  appcontent.addEventListener("load", onPageLoad, true);

  // http://developer.mozilla.org/en/docs/Code_snippets:Interaction_between_privileged_and_non-privileged_pages
  // Setting the last argument to |true| means we're allowing untrusted events to trigger this chrome event handler.
  window.addEventListener("please-quit", pleaseQuitCalled, true, true);
  window.addEventListener("please-gc", pleaseGCCalled, true, true);
  window.addEventListener("please-run-soon", pleaseRunSoonCalled, true, true);

}

function onPageLoad(event)
{
  var doc = event.originalTarget;
  if (doc.nodeName != "#document")
    return;

  var hash = doc.location.hash;

  var r = hash.split("!");

  if (r[0] != "#squarefree-af")
    return;
  if (!(/^[a-zA-Z0-9\-.]*$/.test(r[1]))) {
    dump("Sketchy fuzzer filename!\n");
    return;
  }

  // I hope having this event listener doesn't have side effects!
  doc.addEventListener("pagehide", quitPageHide, false);

  var d = Components.classes["@mozilla.org/file/directory_service;1"]
                    .getService(Components.interfaces.nsIProperties)
                    .get("ProfD", Components.interfaces.nsIFile);

  d.append("extensions");
  d.append("domfuzz@squarefree.com");

  var extensionLocation = readFile(d).replace(/\s*$/, "");

  var f = Components.classes["@mozilla.org/file/local;1"]
                    .createInstance(Components.interfaces.nsILocalFile);
  f.initWithPath(extensionLocation);

  dir = f.parent;
  dir.append("fuzzers");
  // dir now points to the directory containing fuzzer-combined.js, etc.

  var scriptToInject =
    readFile(indir(dir, "fuzz.js")) + "\n"
  + readFile(indir(dir, r[1])) + "\n"
  + readFile(indir(dir, "fuzz-finish-auto.js")) + "\n"
  + "document.getElementById('fuzz1').parentNode.removeChild(document.getElementById('fuzz1'));\n"
  + "fuzzSettings = [" + r[2] + "];\n"
  + "setTimeout(fuzzOnload, 400);\n";

  insertionPoint = doc.getElementsByTagName("head")[0] || doc.documentElement;

  if (!insertionPoint)
    return;

  var script = doc.createElementNS("http://www.w3.org/1999/xhtml", "script");
  script.setAttribute("id", "fuzz1");
  script.setAttribute("type", "text/javascript");
  script.textContent = scriptToInject;
  insertionPoint.appendChild(script);
}

function indir(dir, filename)
{
  var d = dir.clone();
  d.append(filename);
  return d;
}

/*
function quitTimeout()
{
  dump("Quitting due to timeout.\n");
  goQuitApplication();
}
*/

function quitPageHide()
{
  dumpln("Quitting due to pagehide.\n");
  goQuitApplication();
}

function pleaseQuitCalled()
{
  dump("Quitting because I got a please-quit event from the web page.\n");
  goQuitApplication();
}

function pleaseGCCalled()
{
  dump("GC!\n");
  Components.utils.forceGC();

  window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
        .getInterface(Components.interfaces.nsIDOMWindowUtils)
        .garbageCollect();
  window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
        .getInterface(Components.interfaces.nsIDOMWindowUtils)
        .garbageCollect();
  window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
        .getInterface(Components.interfaces.nsIDOMWindowUtils)
        .garbageCollect();
}

// Stick an event on the thread's queue.
// Useful for precise interactions with interruptible reflow (much more precise than setTimeout);
// also potentially faster than setTimeout (which always takes at least 10ms).
// Based on "executeSoon" in
// http://mxr.mozilla.org/mozilla-central/source/testing/mochitest/tests/SimpleTest/SimpleTest.js
function pleaseRunSoonCalled(event)
{
  var target = event.originalTarget;
  var detail = event.detail; // an opaque string that is returned to the page
  var tm = Components.classes["@mozilla.org/thread-manager;1"]
             .getService(Components.interfaces.nsIThreadManager);

  tm.mainThread.dispatch({
    run: function() {
      dispatchBackToPage(target, detail);
    }
  }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
}

function dispatchBackToPage(target, detail)
{
  //dumpln("Dispatching back to page: " + target + " " + detail);
  var evt = document.createEvent("Events");
  evt.detail = detail;
  evt.initEvent("run-now", true, false);
  target.dispatchEvent(evt);
}

// From quit.js, which Bob Clary extracted from mozilla/toolkit/content

function canQuitApplication()
{
  var os = Components.classes["@mozilla.org/observer-service;1"]
    .getService(Components.interfaces.nsIObserverService);
  if (!os)
  {
    return true;
  }

  try
 {
    var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
      .createInstance(Components.interfaces.nsISupportsPRBool);
    os.notifyObservers(cancelQuit, "quit-application-requested", null);

    // Something aborted the quit process.
    if (cancelQuit.data)
    {
      return false;
    }
  }
  catch (ex)
  {
  }
  os.notifyObservers(null, "quit-application-granted", null);
  return true;
}

function goQuitApplication()
{
  var privs = 'UniversalPreferencesRead UniversalPreferencesWrite ' +
    'UniversalXPConnect';

  try
  {
    netscape.security.PrivilegeManager.enablePrivilege(privs);
  }
  catch(ex)
  {
    throw('goQuitApplication: privilege failure ' + ex);
  }

  if (!canQuitApplication())
  {
    return false;
  }

  var kAppStartup = '@mozilla.org/toolkit/app-startup;1';
  var kAppShell   = '@mozilla.org/appshell/appShellService;1';
  var   appService;
  var   forceQuit;

  if (kAppStartup in Components.classes)
  {
    appService = Components.classes[kAppStartup].
      getService(Components.interfaces.nsIAppStartup);
    forceQuit  = Components.interfaces.nsIAppStartup.eForceQuit;

  }
  else if (kAppShell in Components.classes)
  {
    appService = Components.classes[kAppShell].
      getService(Components.interfaces.nsIAppShellService);
    forceQuit = Components.interfaces.nsIAppShellService.eForceQuit;
  }
  else
  {
    throw 'goQuitApplication: no AppStartup/appShell';
  }

  var windowManager = Components.
    classes['@mozilla.org/appshell/window-mediator;1'].getService();

  var windowManagerInterface = windowManager.
    QueryInterface(Components.interfaces.nsIWindowMediator);

  var enumerator = windowManagerInterface.getEnumerator(null);

  while (enumerator.hasMoreElements())
  {
    var domWindow = enumerator.getNext();
    if (("tryToClose" in domWindow) && !domWindow.tryToClose())
    {
      return false;
    }
    domWindow.close();
  }

  try
  {
    appService.quit(forceQuit);
  }
  catch(ex)
  {
    throw('goQuitApplication: ' + ex);
  }

  return true;
}

})();

<|endoftext|>


<commit_before>"use strict";

var Path = require('path');

var expect = require("expect.js");
var fs = require("fs-promise");
//var semver = require('semver');
var BasicInterfaces = require("..");
var assert = require('self-explain').assert;
var differences = assert.allDifferences;
var assertCatch = require('self-explain').assertCatch;

function leva(x){
    // esta función debe desaparecer y las ocurrencias de EVAL reemplazarse por eval
    // cuando esté cerrado: https://github.com/codenautas/self-explain/issues/11
    return x;
}

describe("basic-interfaces", function(){
    var basicInterfaces = new BasicInterfaces();
    describe('typed', function(){
        it("accepts boolean values", function(){
            eval(assert(!differences(basicInterfaces.boolean.discrepances(true),null)));
            eval(assert(!differences(basicInterfaces.boolean.discrepances(false),null)));
            eval(assert(!differences(basicInterfaces.boolean.nullable.discrepances(null),null)));
        });
        it("detect non boolean",function(){
            eval(assert(!differences(basicInterfaces.boolean.discrepances("ufs"), 'string value in boolean')));
        })
        it("detect non nullable",function(){
            eval(assert(!differences(basicInterfaces.boolean.discrepances(null),'null value detected in boolean')));
        })
    });
    describe('plain', function(){
        it("accept ok", function(){
            leva(assert(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob', age:42}) === null
            ));
        });
        it("detect bad attr type", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob', age:'42', isChief:false}),
                {age:"string value in number"}
            )));
        });
        it("detect lack mandatory attr type", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob'}),
                {age:'lack mandatory property'}
            )));
        });
        it("detect extra attr", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob', age:42, ischief:true}),
                {ischief:'unexpected property'}
            )));
        });
        it("various detects", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({names:'Tom & Bob', age:'42'}),
                {
                    names:'unexpected property',
                    age:"string value in number",
                    name:'lack mandatory property'
                }
            )));
        });
    });
});

<commit_msg>Elimino ref a expect.js para que corra<commit_after>"use strict";

var Path = require('path');

var fs = require("fs-promise");
//var semver = require('semver');
var BasicInterfaces = require("..");
var assert = require('self-explain').assert;
var differences = assert.allDifferences;
var assertCatch = require('self-explain').assertCatch;

function leva(x){
    // esta función debe desaparecer y las ocurrencias de EVAL reemplazarse por eval
    // cuando esté cerrado: https://github.com/codenautas/self-explain/issues/11
    return x;
}

describe("basic-interfaces", function(){
    var basicInterfaces = new BasicInterfaces();
    describe('typed', function(){
        it("accepts boolean values", function(){
            eval(assert(!differences(basicInterfaces.boolean.discrepances(true),null)));
            eval(assert(!differences(basicInterfaces.boolean.discrepances(false),null)));
            eval(assert(!differences(basicInterfaces.boolean.nullable.discrepances(null),null)));
        });
        it("detect non boolean",function(){
            eval(assert(!differences(basicInterfaces.boolean.discrepances("ufs"), 'string value in boolean')));
        })
        it("detect non nullable",function(){
            eval(assert(!differences(basicInterfaces.boolean.discrepances(null),'null value detected in boolean')));
        })
    });
    describe('plain', function(){
        it("accept ok", function(){
            leva(assert(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob', age:42}) === null
            ));
        });
        it("detect bad attr type", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob', age:'42', isChief:false}),
                {age:"string value in number"}
            )));
        });
        it("detect lack mandatory attr type", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob'}),
                {age:'lack mandatory property'}
            )));
        });
        it("detect extra attr", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({name:'Bob', age:42, ischief:true}),
                {ischief:'unexpected property'}
            )));
        });
        it("various detects", function(){
            leva(assert(!differences(
                basicInterfaces.plain({
                    name:basicInterfaces.string,
                    age:basicInterfaces.number,
                    isChief:basicInterfaces.boolean.nullable,
                }).discrepances({names:'Tom & Bob', age:'42'}),
                {
                    names:'unexpected property',
                    age:"string value in number",
                    name:'lack mandatory property'
                }
            )));
        });
    });
});

<|endoftext|>


<commit_before>Skip to content
 This repository
Explore
Gist
Blog
Help
@wcastand wcastand

 Unwatch 1
  Star 0
  Fork 0
wcastand/Zik3D
 branch: master  Zik3D/js/app.js
@wcastandwcastand 7 minutes ago Changes to be committed:
1 contributor
RawBlameHistory     125 lines (111 sloc)  3.839 kb
var player;
var shape;
var setup;
var stats;
var gui;
var playButton;

window.requestAnimationFrame = (function(){
  return window.requestAnimationFrame  ||
  window.webkitRequestAnimationFrame ||
  window.mozRequestAnimationFrame    ||
  window.oRequestAnimationFrame      ||
  window.msRequestAnimationFrame     ||
  function(callback){
    window.setTimeout(callback, 1000 / 60);
  };
})();

document.addEventListener('DOMContentLoaded', function(){
  stats = new Stats();
  shape = new threejs();
  player = new Audio();
  gui = new dat.GUI();
  setup = false;

  shape.init();

  initGUI();
  initStats();
  initDropZone();
  initControls();
});

function initControls(){
  playButton = document.querySelector('#play');
  playButton.style.visibility = "hidden";
  playButton.addEventListener('click', function(){
    if(setup){
      if(this.classList.contains('icon-play')){
        player.play();
        this.classList.remove('icon-play')
        this.classList.add('icon-stop');
      }
      else{
        player.stop();
        this.classList.remove('icon-stop')
        this.classList.add('icon-play');
      }
    }
  })
}

function initDropZone(){
  var dropZone = document.querySelector('.dropzone');
  dropZone.addEventListener('dragover', handleDragOver, false);
  dropZone.addEventListener('drop', handleFileSelect, false);
}

function initStats(){
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.right = '0px';
  stats.domElement.style.bottom = '0px';
  document.body.appendChild( stats.domElement );
}

function initGUI(){
  gui.addColor(shape, 'firstColor');
  gui.addColor(shape, 'secondColor');
  gui.add(shape, 'typeTransform', { Scale: 0, Position: 1 });
  var controllerSpaceX = gui.add(shape, 'spaceX');
  var controllerSpaceY = gui.add(shape, 'spaceY');
  var controllerSize   = gui.add(shape, 'size');
  var controllerNbX    = gui.add(shape, 'nbX');
  var controllerNbY    = gui.add(shape, 'nbY');
  var controllerScaleMin  = gui.add(shape, 'scaleMin');
  var controllerScaleMax  = gui.add(shape, 'scaleMax');
  var controllerPosition  = gui.add(shape, 'position');

  controllerSize.onFinishChange(function(value) {shape.size = value; shape.initShape();});
  controllerNbX.onFinishChange(function(value) {shape.nbX = value; shape.initShape();});
  controllerNbY.onFinishChange(function(value) {shape.nbY = value; shape.initShape();});
  controllerSpaceX.onFinishChange(function(value) {shape.spaceX = value; shape.initShape();});
  controllerSpaceY.onFinishChange(function(value) {shape.spaceY = value; shape.initShape();});
  controllerScaleMin.onFinishChange(function(value) {shape.scaleMin = value; shape.initShape();});
  controllerScaleMax.onFinishChange(function(value) {shape.scaleMax = value; shape.initShape();});
  controllerPosition.onFinishChange(function(value) {shape.position = value; shape.initShape();});
}

function handleFileSelect(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  document.querySelector('.container').style.visibility = "visible";

  var files = evt.dataTransfer.files;
  var output = [];
  var f = files[0];
  if(f.type.indexOf("audio") != -1){
    setup = false;
    var reader = new FileReader();
    reader.onload = (function(f) {
      return function(e) {
        player.decodeData(e.target.result, function(){
          setup = true;
          document.querySelector('.container').style.visibility = "hidden";
          playButton.style.visibility = "visible";
          playButton.classList.remove('icon-play')
          playButton.classList.add('icon-stop');
        });
      };
    })(f);
    reader.readAsArrayBuffer(f);
  }
}

function handleDragOver(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  evt.dataTransfer.dropEffect = 'copy';
}

window.onresize = function(evt){
  shape = new threejs();
  shape.init();
}
Status API Training Shop Blog About
© 2015 GitHub, Inc. Terms Privacy Security Contact
<commit_msg> Changes to be committed: 	modified:   js/app.js<commit_after>var player;
var shape;
var setup;
var stats;
var gui;
var playButton;

window.requestAnimationFrame = (function(){
  return window.requestAnimationFrame  ||
  window.webkitRequestAnimationFrame ||
  window.mozRequestAnimationFrame    ||
  window.oRequestAnimationFrame      ||
  window.msRequestAnimationFrame     ||
  function(callback){
    window.setTimeout(callback, 1000 / 60);
  };
})();

document.addEventListener('DOMContentLoaded', function(){
  stats = new Stats();
  shape = new threejs();
  player = new Audio();
  gui = new dat.GUI();
  setup = false;

  shape.init();

  initGUI();
  initStats();
  initDropZone();
  initControls();
});

function initControls(){
  playButton = document.querySelector('#play');
  playButton.style.visibility = "hidden";
  playButton.addEventListener('click', function(){
    if(setup){
      if(this.classList.contains('icon-play')){
        player.play();
        this.classList.remove('icon-play')
        this.classList.add('icon-stop');
      }
      else{
        player.stop();
        this.classList.remove('icon-stop')
        this.classList.add('icon-play');
      }
    }
  })
}

function initDropZone(){
  var dropZone = document.querySelector('.dropzone');
  dropZone.addEventListener('dragover', handleDragOver, false);
  dropZone.addEventListener('drop', handleFileSelect, false);
}

function initStats(){
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.right = '0px';
  stats.domElement.style.bottom = '0px';
  document.body.appendChild( stats.domElement );
}

function initGUI(){
  gui.addColor(shape, 'firstColor');
  gui.addColor(shape, 'secondColor');
  gui.add(shape, 'typeTransform', { Scale: 0, Position: 1 });
  var controllerSpaceX = gui.add(shape, 'spaceX');
  var controllerSpaceY = gui.add(shape, 'spaceY');
  var controllerSize   = gui.add(shape, 'size');
  var controllerNbX    = gui.add(shape, 'nbX');
  var controllerNbY    = gui.add(shape, 'nbY');
  var controllerScaleMin  = gui.add(shape, 'scaleMin');
  var controllerScaleMax  = gui.add(shape, 'scaleMax');
  var controllerPosition  = gui.add(shape, 'position');

  controllerSize.onFinishChange(function(value) {shape.size = value; shape.initShape();});
  controllerNbX.onFinishChange(function(value) {shape.nbX = value; shape.initShape();});
  controllerNbY.onFinishChange(function(value) {shape.nbY = value; shape.initShape();});
  controllerSpaceX.onFinishChange(function(value) {shape.spaceX = value; shape.initShape();});
  controllerSpaceY.onFinishChange(function(value) {shape.spaceY = value; shape.initShape();});
  controllerScaleMin.onFinishChange(function(value) {shape.scaleMin = value; shape.initShape();});
  controllerScaleMax.onFinishChange(function(value) {shape.scaleMax = value; shape.initShape();});
  controllerPosition.onFinishChange(function(value) {shape.position = value; shape.initShape();});
}

function handleFileSelect(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  document.querySelector('.container').style.visibility = "visible";

  var files = evt.dataTransfer.files;
  var output = [];
  var f = files[0];
  if(f.type.indexOf("audio") != -1){
    setup = false;
    var reader = new FileReader();
    reader.onload = (function(f) {
      return function(e) {
        player.decodeData(e.target.result, function(){
          setup = true;
          document.querySelector('.container').style.visibility = "hidden";
          playButton.style.visibility = "visible";
          playButton.classList.remove('icon-play')
          playButton.classList.add('icon-stop');
        });
      };
    })(f);
    reader.readAsArrayBuffer(f);
  }
}

function handleDragOver(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  evt.dataTransfer.dropEffect = 'copy';
}

window.onresize = function(evt){
  shape = new threejs();
  shape.init();
}
<|endoftext|>


<commit_before>var SteamCommunity = require('steamcommunity');

module.exports = TradeOfferManager;

TradeOfferManager.SteamID = require('steamid');
TradeOfferManager.ETradeOfferState = require('../resources/ETradeOfferState.js');
TradeOfferManager.EOfferFilter = require('../resources/EOfferFilter.js');

TradeOfferManager.getStateName = function(state) {
	for(var i in TradeOfferManager.ETradeOfferState) {
		if(TradeOfferManager.ETradeOfferState[i] == state) {
			return i;
		}
	}

	return state;
};

require('util').inherits(TradeOfferManager, require('events').EventEmitter);

function TradeOfferManager(steam, domain, language, pollInterval) {
	this._steam = steam;
	this._community = new SteamCommunity();
	this._domain = domain || 'localhost';
	this._language = language;
	this._languageName = null;
	this._pollInterval = pollInterval || 30000;
	this._pollTimer = null;
	this._lastPoll = 0;
	this.pollData = {};

	if(language) {
		var lang = require('languages').getLanguageInfo(language);
		if(!lang.name) {
			this._language = null;
		} else {
			this._languageName = lang.name.toLowerCase();
		}
	}

	if(this._steam) {
		this._steam.on('tradeOffers', function(count) {
			this.doPoll();
		}.bind(this));

		// We don't have access to the Steam namespace, so we'll need to use a hardcoded value instead of the enum
		// UPDATE THIS if node-steam ever handles the ClientItemAnnouncements msg
		this._steam._handlers[5576] = function(data) {
			this.doPoll();
		}.bind(this);
	}

	this._request = this._community._request; // I probably shouldn't be doing this...

	this._assetCache = {};

	this.apiKey = null;
}

TradeOfferManager.prototype.setCookies = function(cookies, callback) {
	if(this._languageName) {
		cookies = cookies.concat(['Steam_Language=' + this._languageName]);
	}

	this._community.setCookies(cookies);
	this._checkApiKey(function(err) {
		if(!err) {
			if(!this._pollTimer && this._pollInterval >= 1000) {
				this.doPoll();
			}
		}

		callback(err);
	}.bind(this));
};

TradeOfferManager.prototype.parentalUnlock = function(pin, callback) {
	this._community.parentalUnlock(pin, function(err) {
		if(err && callback) {
			callback(new Error(err));
		}
	});
};

TradeOfferManager.prototype._checkApiKey = function(callback) {
	if(this.apiKey) {
		if(callback) {
			callback();
		}

		return;
	}

	this._community.getWebApiKey(this._domain, function(err, key) {
		if(err) {
			return makeAnError(new Error(err), callback);
		}

		this.apiKey = key;
		callback();
	}.bind(this));
};

TradeOfferManager.prototype.loadInventory = function(appid, contextid, tradableOnly, callback, data, start) {
	this._request('https://steamcommunity.com/my/inventory/json/' + appid + '/' + contextid + '/', {
		"qs": {
			"start": start,
			"l": this._languageName,
			"trading": tradableOnly ? 1 : undefined
		},
		"json": true
	}, function(err, response, body) {
		if(err || response.statusCode != 200) {
			return callback(err || new Error("HTTP error " + response.statusCode));
		}

		if(!body || !body.success || !body.rgInventory || !body.rgDescriptions || !body.rgCurrency) {
			return callback(new Error("Malformed response"));
		}

		this._digestDescriptions(body.rgDescriptions);

		data = (data || []).concat(this._mapItemsToDescriptions(appid, contextid, body.rgInventory)).concat(this._mapItemsToDescriptions(appid, contextid, body.rgCurrency));
		if(body.more) {
			this.loadInventory(appid, contextid, tradableOnly, callback, data, body.more_start);
		} else {
			callback(null, data);
		}
	}.bind(this));
};

TradeOfferManager.prototype.getOfferToken = function(callback) {
	this._request("https://steamcommunity.com/my/tradeoffers/privacy", function(err, response, body) {
		if(err || response.statusCode != 200) {
			return callback(err || new Error("HTTP error " + response.statusCode));
		}

		var match = body.match(/https?:\/\/(www.)?steamcommunity.com\/tradeoffer\/new\/?\?partner=\d+(&|&)token=([a-zA-Z0-9]+)/);
		if(match) {
			callback(null, match[3]);
		} else {
			callback(new Error("Malformed response"));
		}
	});
};

function makeAnError(error, callback) {
	if(callback) {
		callback(error);
	}
}

require('./webapi.js');
require('./assets.js');
require('./polling.js');
require('./classes/TradeOffer.js');
<commit_msg>Use an options object for constructor, added cancelTime option<commit_after>var SteamCommunity = require('steamcommunity');

module.exports = TradeOfferManager;

TradeOfferManager.SteamID = require('steamid');
TradeOfferManager.ETradeOfferState = require('../resources/ETradeOfferState.js');
TradeOfferManager.EOfferFilter = require('../resources/EOfferFilter.js');

TradeOfferManager.getStateName = function(state) {
	for(var i in TradeOfferManager.ETradeOfferState) {
		if(TradeOfferManager.ETradeOfferState[i] == state) {
			return i;
		}
	}

	return state;
};

require('util').inherits(TradeOfferManager, require('events').EventEmitter);

function TradeOfferManager(options) {
	options = options || {};

	this._steam = options.steam;
	this._domain = options.domain || 'localhost';
	this._language = options.language;
	this._pollInterval = options.pollInterval || 30000;
	this._cancelTime = options.cancelTime;

	if(this._language) {
		var lang = require('languages').getLanguageInfo(this._language);
		if(!lang.name) {
			this._language = null;
			this._languageName = null;
		} else {
			this._languageName = lang.name.toLowerCase();
		}
	}

	if(this._steam) {
		this._steam.on('tradeOffers', function(count) {
			this.doPoll();
		}.bind(this));

		// We don't have access to the Steam namespace, so we'll need to use a hardcoded value instead of the enum
		// UPDATE THIS if node-steam ever handles the ClientItemAnnouncements msg
		this._steam._handlers[5576] = function(data) {
			this.doPoll();
		}.bind(this);
	}

	this._community = new SteamCommunity();
	this._request = this._community.request;
	this._assetCache = {};
	this._pollTimer = null;
	this._lastPoll = 0;

	this.pollData = {};
	this.apiKey = null;
}

TradeOfferManager.prototype.setCookies = function(cookies, callback) {
	if(this._languageName) {
		cookies = cookies.concat(['Steam_Language=' + this._languageName]);
	}

	this._community.setCookies(cookies);
	this._checkApiKey(function(err) {
		if(!err) {
			if(!this._pollTimer && this._pollInterval >= 1000) {
				this.doPoll();
			}
		}

		callback(err);
	}.bind(this));
};

TradeOfferManager.prototype.parentalUnlock = function(pin, callback) {
	this._community.parentalUnlock(pin, function(err) {
		if(err && callback) {
			callback(new Error(err));
		}
	});
};

TradeOfferManager.prototype._checkApiKey = function(callback) {
	if(this.apiKey) {
		if(callback) {
			callback();
		}

		return;
	}

	this._community.getWebApiKey(this._domain, function(err, key) {
		if(err) {
			return makeAnError(new Error(err), callback);
		}

		this.apiKey = key;
		callback();
	}.bind(this));
};

TradeOfferManager.prototype.loadInventory = function(appid, contextid, tradableOnly, callback, data, start) {
	this._request('https://steamcommunity.com/my/inventory/json/' + appid + '/' + contextid + '/', {
		"qs": {
			"start": start,
			"l": this._languageName,
			"trading": tradableOnly ? 1 : undefined
		},
		"json": true
	}, function(err, response, body) {
		if(err || response.statusCode != 200) {
			return callback(err || new Error("HTTP error " + response.statusCode));
		}

		if(!body || !body.success || !body.rgInventory || !body.rgDescriptions || !body.rgCurrency) {
			return callback(new Error("Malformed response"));
		}

		this._digestDescriptions(body.rgDescriptions);

		data = (data || []).concat(this._mapItemsToDescriptions(appid, contextid, body.rgInventory)).concat(this._mapItemsToDescriptions(appid, contextid, body.rgCurrency));
		if(body.more) {
			this.loadInventory(appid, contextid, tradableOnly, callback, data, body.more_start);
		} else {
			callback(null, data);
		}
	}.bind(this));
};

TradeOfferManager.prototype.getOfferToken = function(callback) {
	this._request("https://steamcommunity.com/my/tradeoffers/privacy", function(err, response, body) {
		if(err || response.statusCode != 200) {
			return callback(err || new Error("HTTP error " + response.statusCode));
		}

		var match = body.match(/https?:\/\/(www.)?steamcommunity.com\/tradeoffer\/new\/?\?partner=\d+(&|&)token=([a-zA-Z0-9]+)/);
		if(match) {
			callback(null, match[3]);
		} else {
			callback(new Error("Malformed response"));
		}
	});
};

function makeAnError(error, callback) {
	if(callback) {
		callback(error);
	}
}

require('./webapi.js');
require('./assets.js');
require('./polling.js');
require('./classes/TradeOffer.js');
<|endoftext|>


<commit_before>'use strict';

var path = require('path'),
    util = require('util'),
    debug = require('debug'),
    _ = require('lodash'),
    q = require('q'),
    chalk = require('chalk'),
    polyfillService = require('polyfill-service'),
    browserify = require('browserify'),

    Browser = require('./browser'),
    ClientBridge = require('./client-bridge'),

    GeminiError = require('../errors/gemini-error'),
    WdErrors = require('../constants/wd-errors'),

    OPERA_NOT_SUPPORTED = 'Not supported in OperaDriver yet';

module.exports = class NewBrowser extends Browser {
    constructor(config) {
        super(config);

        this.log = debug('gemini:browser:' + this.id);

        var wdLog = debug('gemini:webdriver:' + this.id);

        this._wd.on('connection', function(code, message, error) {
            wdLog('Error: code %d, %s', code, message);
        });

        this._wd.on('status', function(info) {
            wdLog(info);
        });
        this._wd.on('command', function(eventType, command, response) {
            if (eventType === 'RESPONSE' && command === 'takeScreenshot()') {
                response = '<binary-data>';
            }
            if (typeof response !== 'string') {
                response = JSON.stringify(response);
            }
            wdLog(chalk.cyan(eventType), command, chalk.grey(response || ''));
        });

        this._exposeWdApi([
            'sleep',
            'waitForElementByCssSelector',
            'waitFor',
            'moveTo',
            'click',
            'doubleClick',
            'buttonDown',
            'buttonUp',
            'keys',
            'type',
            'tapElement',
            'flick',
            'execute',
            'setWindowSize',
            'getWindowSize',
            'getOrientation',
            'setOrientation'
        ]);
    }

    _exposeWdApi(methods) {
        var _this = this;
        methods.forEach(function(method) {
            _this[method] = function() {
                return _this._wd[method].apply(_this._wd, arguments);
            };
        });
    }

    launch(calibrator) {
        return this.initSession()
            .then(() => this._setDefaultSize())
            .then(() => {
                // maximize is required, because default
                // windows size in phantomjs can prevent
                // some shadows from fitting in
                if (this._shouldMaximize()) {
                    return this._maximize();
                }
            })
            .then(() => {
                if (!this.config.calibrate || this._calibration) {
                    return;
                }

                return calibrator.calibrate(this)
                    .then((calibration) => this._setCalibration(calibration));
            })
            .then(() => this._buildPolyfills())
            .then(() => this.buildScripts())
            .then(() => this.chooseLocator())
            .catch((e) => {
                if (e.code === 'ECONNREFUSED') {
                    return q.reject(new GeminiError(
                        `Unable to connect to ${this.config.gridUrl}.`,
                        'Make sure that URL in config file is correct and selenium\nserver is running.'
                    ));
                }

                const error = new GeminiError(`Cannot launch browser ${this.id}:\n${e.message}.`);

                error.browserId = this.id;
                error.sessionId = this.sessionId;

                // selenium does not provide a way to distinguish different reasons of failure
                return q.reject(error);
            });
    }

    initSession() {
        return this._setSessionRequestTimeout()
            .then(() => this._wd.init(this.capabilities))
            .spread((sessionId) => {
                this.sessionId = sessionId;
                this.log('launched session %o', this);
            })
            .then(() => this._setHttpTimeout());
    }

    _setDefaultSize() {
        var size = this.config.windowSize;
        if (!size) {
            return;
        }
        return this._wd.setWindowSize(size.width, size.height)
            .fail(function(e) {
                // Its the only reliable way to detect not supported operation
                // in legacy operadriver.
                var message = e.cause && e.cause.value && e.cause.value.message;
                if (message === OPERA_NOT_SUPPORTED) {
                    console.warn(chalk.yellow('WARNING!'));
                    console.warn('Legacy Opera Driver does not support window resizing');
                    console.warn('windowSize setting will be ignored.');
                    return;
                }
                return q.reject(e);
            });
    }

    _buildPolyfills() {
        /*jshint evil:true*/
        //polyfills are needed for older browsers, namely, IE8

        var _this = this;
        return _this._wd.eval('navigator.userAgent')
            .then(function(ua) {
                return polyfillService.getPolyfillString({
                    uaString: ua,
                    minify: true,
                    features: {
                        'getComputedStyle': {flags: ['gated']},
                        'matchMedia': {flags: ['gated']},
                        'document.querySelector': {flags: ['gated']},
                        'String.prototype.trim': {flags: ['gated']}
                    }
                });
            })
            .then(function(polyfill) {
                _this._polyfill = polyfill;
            });
    }

    openRelative(relativeURL) {
        return this.open(this.config.getAbsoluteUrl(relativeURL));
    }

    // Zoom reset should be skipped before calibration cause we're unable to build client scripts before
    // calibration done. Reset will be executed as 1 of calibration steps.
    open(url, params) {
        params = _.defaults(params || {}, {
            resetZoom: true
        });

        var _this = this;
        return this._wd.get(url)
            .then(function(result) {
                return params.resetZoom
                    ? _this._clientBridge.call('resetZoom').thenResolve(result)
                    : result;
            });
    }

    injectScript(script) {
        return this._wd.execute(script);
    }

    evalScript(script) {
        /*jshint evil:true*/
        return this._wd.eval(script);
    }

    buildScripts() {
        var script = browserify({
                entries: './gemini',
                basedir: path.join(__dirname, 'client-scripts')
            });

        if (!this.config.system.coverage.enabled) {
            script.exclude('./gemini.coverage');
        }

        script.transform({sourcemap: false, global: true}, 'uglifyify');
        var queryLib = this._needsSizzle? './query.sizzle.js' : './query.native.js';
        script.transform({
            aliases: {
                './query': {relative: queryLib}
            },
            verbose: false
        }, 'aliasify');

        var _this = this;

        return q.nfcall(script.bundle.bind(script))
            .then(function(buf) {
                var scripts = _this._polyfill + '\n' + buf.toString();
                _this._clientBridge = new ClientBridge(_this, scripts);
                return scripts;
            });
    }

    get _needsSizzle() {
        return this._calibration && !this._calibration.hasCSS3Selectors;
    }

    chooseLocator() {
        this.findElement = this._needsSizzle? this._findElementScript : this._findElementWd;
    }

    reset() {
        var _this = this;
        // We can't use findElement here because it requires page with body tag
        return this.evalScript('document.body')
            .then(function(body) {
                // Selenium IEDriver doesn't move cursor to (0, 0) first time
                // https://github.com/SeleniumHQ/selenium/issues/672
                // So we do it in two steps: -> (1, 1) -> (0, 0)
                return _this._wd.moveTo(body, 1, 1)
                    .then(_this._wd.moveTo.bind(_this._wd, body, 0, 0));
            })
            .fail(function(e) {
                return q.reject(_.extend(e || {}, {
                    browserId: _this.id,
                    sessionId: _this.sessionId
                }));
            });
    }

    get browserName() {
        return this.capabilities.browserName;
    }

    get version() {
        return this.capabilities.version;
    }

    get capabilities() {
        return this.config.desiredCapabilities;
    }

    _shouldMaximize() {
        if (this.config.windowSize) {
            return false;
        }

        return this.browserName === 'phantomjs';
    }

    _maximize() {
        var _this = this;
        return _this._wd.windowHandle()
            .then(function(handle) {
                return _this._wd.maximize(handle);
            });
    }

    findElement(selector) {
        throw new Error('findElement is called before appropriate locator is chosen');
    }

    _findElementWd(selector) {
        return this._wd.elementByCssSelector(selector)
            .fail(function(error) {
                if (error.status === WdErrors.ELEMENT_NOT_FOUND) {
                    error.selector = selector;
                }
                return q.reject(error);
            });
    }

    _findElementScript(selector) {
        return this._clientBridge.call('query.first', [selector])
            .then(function(element) {
                if (element) {
                    return element;
                }

                var error = new Error('Unable to find element');
                error.status = WdErrors.ELEMENT_NOT_FOUND;
                error.selector = selector;
                return q.reject(error);
            });
    }

    prepareScreenshot(selectors, opts) {
        opts = _.extend(opts, {
            usePixelRatio: this._calibration? this._calibration.usePixelRatio : true
        });
        return this._clientBridge.call('prepareScreenshot', [selectors, opts || {}]);
    }

    quit() {
        if (!this.sessionId) {
            return q();
        }

        return this._wd.quit()
            .then(() => this.log('kill browser %o', this))
            .catch((err) => console.warn(err));
    }

    inspect() {
        return util.format('[%s (%s)]', this.id, this.sessionId);
    }
};
<commit_msg>Remove two-fase movement to 0,0 on browser reset<commit_after>'use strict';

var path = require('path'),
    util = require('util'),
    debug = require('debug'),
    _ = require('lodash'),
    q = require('q'),
    chalk = require('chalk'),
    polyfillService = require('polyfill-service'),
    browserify = require('browserify'),

    Browser = require('./browser'),
    ClientBridge = require('./client-bridge'),

    GeminiError = require('../errors/gemini-error'),
    WdErrors = require('../constants/wd-errors'),

    OPERA_NOT_SUPPORTED = 'Not supported in OperaDriver yet';

module.exports = class NewBrowser extends Browser {
    constructor(config) {
        super(config);

        this.log = debug('gemini:browser:' + this.id);

        var wdLog = debug('gemini:webdriver:' + this.id);

        this._wd.on('connection', function(code, message, error) {
            wdLog('Error: code %d, %s', code, message);
        });

        this._wd.on('status', function(info) {
            wdLog(info);
        });
        this._wd.on('command', function(eventType, command, response) {
            if (eventType === 'RESPONSE' && command === 'takeScreenshot()') {
                response = '<binary-data>';
            }
            if (typeof response !== 'string') {
                response = JSON.stringify(response);
            }
            wdLog(chalk.cyan(eventType), command, chalk.grey(response || ''));
        });

        this._exposeWdApi([
            'sleep',
            'waitForElementByCssSelector',
            'waitFor',
            'moveTo',
            'click',
            'doubleClick',
            'buttonDown',
            'buttonUp',
            'keys',
            'type',
            'tapElement',
            'flick',
            'execute',
            'setWindowSize',
            'getWindowSize',
            'getOrientation',
            'setOrientation'
        ]);
    }

    _exposeWdApi(methods) {
        var _this = this;
        methods.forEach(function(method) {
            _this[method] = function() {
                return _this._wd[method].apply(_this._wd, arguments);
            };
        });
    }

    launch(calibrator) {
        return this.initSession()
            .then(() => this._setDefaultSize())
            .then(() => {
                // maximize is required, because default
                // windows size in phantomjs can prevent
                // some shadows from fitting in
                if (this._shouldMaximize()) {
                    return this._maximize();
                }
            })
            .then(() => {
                if (!this.config.calibrate || this._calibration) {
                    return;
                }

                return calibrator.calibrate(this)
                    .then((calibration) => this._setCalibration(calibration));
            })
            .then(() => this._buildPolyfills())
            .then(() => this.buildScripts())
            .then(() => this.chooseLocator())
            .catch((e) => {
                if (e.code === 'ECONNREFUSED') {
                    return q.reject(new GeminiError(
                        `Unable to connect to ${this.config.gridUrl}.`,
                        'Make sure that URL in config file is correct and selenium\nserver is running.'
                    ));
                }

                const error = new GeminiError(`Cannot launch browser ${this.id}:\n${e.message}.`);

                error.browserId = this.id;
                error.sessionId = this.sessionId;

                // selenium does not provide a way to distinguish different reasons of failure
                return q.reject(error);
            });
    }

    initSession() {
        return this._setSessionRequestTimeout()
            .then(() => this._wd.init(this.capabilities))
            .spread((sessionId) => {
                this.sessionId = sessionId;
                this.log('launched session %o', this);
            })
            .then(() => this._setHttpTimeout());
    }

    _setDefaultSize() {
        var size = this.config.windowSize;
        if (!size) {
            return;
        }
        return this._wd.setWindowSize(size.width, size.height)
            .fail(function(e) {
                // Its the only reliable way to detect not supported operation
                // in legacy operadriver.
                var message = e.cause && e.cause.value && e.cause.value.message;
                if (message === OPERA_NOT_SUPPORTED) {
                    console.warn(chalk.yellow('WARNING!'));
                    console.warn('Legacy Opera Driver does not support window resizing');
                    console.warn('windowSize setting will be ignored.');
                    return;
                }
                return q.reject(e);
            });
    }

    _buildPolyfills() {
        /*jshint evil:true*/
        //polyfills are needed for older browsers, namely, IE8

        var _this = this;
        return _this._wd.eval('navigator.userAgent')
            .then(function(ua) {
                return polyfillService.getPolyfillString({
                    uaString: ua,
                    minify: true,
                    features: {
                        'getComputedStyle': {flags: ['gated']},
                        'matchMedia': {flags: ['gated']},
                        'document.querySelector': {flags: ['gated']},
                        'String.prototype.trim': {flags: ['gated']}
                    }
                });
            })
            .then(function(polyfill) {
                _this._polyfill = polyfill;
            });
    }

    openRelative(relativeURL) {
        return this.open(this.config.getAbsoluteUrl(relativeURL));
    }

    // Zoom reset should be skipped before calibration cause we're unable to build client scripts before
    // calibration done. Reset will be executed as 1 of calibration steps.
    open(url, params) {
        params = _.defaults(params || {}, {
            resetZoom: true
        });

        var _this = this;
        return this._wd.get(url)
            .then(function(result) {
                return params.resetZoom
                    ? _this._clientBridge.call('resetZoom').thenResolve(result)
                    : result;
            });
    }

    injectScript(script) {
        return this._wd.execute(script);
    }

    evalScript(script) {
        /*jshint evil:true*/
        return this._wd.eval(script);
    }

    buildScripts() {
        var script = browserify({
                entries: './gemini',
                basedir: path.join(__dirname, 'client-scripts')
            });

        if (!this.config.system.coverage.enabled) {
            script.exclude('./gemini.coverage');
        }

        script.transform({sourcemap: false, global: true}, 'uglifyify');
        var queryLib = this._needsSizzle? './query.sizzle.js' : './query.native.js';
        script.transform({
            aliases: {
                './query': {relative: queryLib}
            },
            verbose: false
        }, 'aliasify');

        var _this = this;

        return q.nfcall(script.bundle.bind(script))
            .then(function(buf) {
                var scripts = _this._polyfill + '\n' + buf.toString();
                _this._clientBridge = new ClientBridge(_this, scripts);
                return scripts;
            });
    }

    get _needsSizzle() {
        return this._calibration && !this._calibration.hasCSS3Selectors;
    }

    chooseLocator() {
        this.findElement = this._needsSizzle? this._findElementScript : this._findElementWd;
    }

    reset() {
        // We can't use findElement here because it requires page with body tag
        return this.evalScript('document.body')
            .then(body => this._wd.moveTo(body, 0, 0))
            .catch(e => {
                return q.reject(_.extend(e || {}, {
                    browserId: this.id,
                    sessionId: this.sessionId
                }));
            });
    }

    get browserName() {
        return this.capabilities.browserName;
    }

    get version() {
        return this.capabilities.version;
    }

    get capabilities() {
        return this.config.desiredCapabilities;
    }

    _shouldMaximize() {
        if (this.config.windowSize) {
            return false;
        }

        return this.browserName === 'phantomjs';
    }

    _maximize() {
        var _this = this;
        return _this._wd.windowHandle()
            .then(function(handle) {
                return _this._wd.maximize(handle);
            });
    }

    findElement(selector) {
        throw new Error('findElement is called before appropriate locator is chosen');
    }

    _findElementWd(selector) {
        return this._wd.elementByCssSelector(selector)
            .fail(function(error) {
                if (error.status === WdErrors.ELEMENT_NOT_FOUND) {
                    error.selector = selector;
                }
                return q.reject(error);
            });
    }

    _findElementScript(selector) {
        return this._clientBridge.call('query.first', [selector])
            .then(function(element) {
                if (element) {
                    return element;
                }

                var error = new Error('Unable to find element');
                error.status = WdErrors.ELEMENT_NOT_FOUND;
                error.selector = selector;
                return q.reject(error);
            });
    }

    prepareScreenshot(selectors, opts) {
        opts = _.extend(opts, {
            usePixelRatio: this._calibration? this._calibration.usePixelRatio : true
        });
        return this._clientBridge.call('prepareScreenshot', [selectors, opts || {}]);
    }

    quit() {
        if (!this.sessionId) {
            return q();
        }

        return this._wd.quit()
            .then(() => this.log('kill browser %o', this))
            .catch((err) => console.warn(err));
    }

    inspect() {
        return util.format('[%s (%s)]', this.id, this.sessionId);
    }
};
<|endoftext|>


<commit_before>/**
 * @copyright Copyright © 2016 Medalia, Inc. All rights reserved.
 * @license Licensed under the MIT License (MIT).
 */

'use strict';

const UrlProvider = require('../lib/UrlProvider');
const assert = require('chai').assert;
const querystring = require('querystring');

describe('UrlProvider test suite', () => {
    const room = 'My awesome room?';
    const apiToken = '123///45!!';

    it('urlObject test', () => {
        var actual = UrlProvider.urlObject(room, apiToken);
        var expected = {
            protocol: 'https:',
            host: 'api.hipchat.com',
            pathname: '/v2/room/' + querystring.escape(room) + '/notification',
            query: {auth_token: apiToken}
        };
        assert.deepEqual(actual, expected);
    });

    it('format test', () => {
        var url = UrlProvider.formatUrl(room, apiToken);
        assert.equal(querystring.unescape(url), 'https://api.hipchat.com/v2/room/' + room + '/notification?auth_token=' + apiToken);
    });

});<commit_msg>new test<commit_after>/**
 * @copyright Copyright © 2016 Medalia, Inc. All rights reserved.
 * @license Licensed under the MIT License (MIT).
 */

'use strict';

const UrlProvider = require('../lib/UrlProvider');
const assert = require('chai').assert;
const querystring = require('querystring');

describe('UrlProvider test suite', () => {
    const room = 'My awesome room?';
    const apiToken = '123   ///    45!!';

    it('urlObject test', () => {
        var actual = UrlProvider.urlObject(room, apiToken);
        var expected = {
            protocol: 'https:',
            host: 'api.hipchat.com',
            pathname: '/v2/room/' + querystring.escape(room) + '/notification',
            query: {auth_token: apiToken}
        };
        assert.deepEqual(actual, expected);
    });

    it('format test', () => {
        var url = UrlProvider.formatUrl(room, apiToken);
        assert.equal(querystring.unescape(url), 'https://api.hipchat.com/v2/room/' + room + '/notification?auth_token=' + apiToken);
    });

    it('format test, unescape', () => {
        var url = UrlProvider.formatUrl(room, apiToken);
        assert.notEqual(url, 'https://api.hipchat.com/v2/room/' + room + '/notification?auth_token=' + apiToken);
    });

});<|endoftext|>


<commit_before>/* @flow weak */

/**
 * OfflineMobile Android
 * Sustainable Solutions (NZ) Ltd. 2016
 */

import React from 'react';
import {
  Image,
  View,
} from 'react-native';

import globalStyles, { BACKGROUND_COLOR } from './globalStyles';

import { Navigator } from './navigation';

import { PAGES } from './pages';

import {
  FinaliseButton,
  FinaliseModal,
  LoginModal,
  SyncState,
} from './widgets';

import { Synchronizer } from './sync';
import { SyncAuthenticator, UserAuthenticator } from './authentication';
import { Database, schema } from './database';
import { Scheduler } from './Scheduler';
import { Settings } from './settings';

const SYNC_INTERVAL = 10 * 60 * 1000; // 10 minutes in milliseconds
const AUTHENTICATION_INTERVAL = 10 * 60 * 1000; // 10 minutes in milliseconds

export default class OfflineMobileApp extends React.Component {

  constructor() {
    super();
    this.database = new Database(schema);
    this.settings = new Settings(this.database);
    this.userAuthenticator = new UserAuthenticator(this.database, this.settings);
    const syncAuthenticator = new SyncAuthenticator(this.database, this.settings);
    this.synchronizer = new Synchronizer(this.database, syncAuthenticator, this.settings);
    this.scheduler = new Scheduler();
    const initialised = this.synchronizer.isInitialised();
    this.state = {
      initialised: initialised,
      currentUser: null,
      isSyncing: false,
      syncError: '',
      lastSync: null, // Date of the last successful sync
      confirmFinalise: false,
      recordToFinalise: null,
      recordTypeToFinalise: null,
    };
  }

  componentWillMount() {
    this.logOut = this.logOut.bind(this);
    this.onAuthentication = this.onAuthentication.bind(this);
    this.onInitialised = this.onInitialised.bind(this);
    this.renderFinaliseButton = this.renderFinaliseButton.bind(this);
    this.renderScene = this.renderScene.bind(this);
    this.renderSyncState = this.renderSyncState.bind(this);
    this.synchronize = this.synchronize.bind(this);
    this.scheduler.schedule(this.synchronize,
                            SYNC_INTERVAL);
    this.scheduler.schedule(() => {
      if (this.state.currentUser !== null) { // Only reauthenticate if currently logged in
        this.userAuthenticator.reauthenticate(this.onAuthentication);
      }}, AUTHENTICATION_INTERVAL);
  }

  componentWillUnmount() {
    this.scheduler.clearAll();
  }

  onAuthentication(user) {
    this.setState({ currentUser: user });
  }

  onInitialised() {
    this.setState({ initialised: true });
  }

  async synchronize() {
    if (!this.state.initialised || this.state.isSyncing) return; // If already syncing, skip
    try {
      this.setState({ isSyncing: true });
      await this.synchronizer.synchronize();
      this.setState({ isSyncing: false });
    } catch (error) {
      this.setState({
        isSyncing: false,
        syncError: error.message,
      });
    }
  }

  logOut() {
    this.setState({ currentUser: null });
  }

  renderFinaliseButton() {
    return (
      <FinaliseButton
        isFinalised={this.state.recordToFinalise.status === 'finalised'}
        onPress={() => this.setState({ confirmFinalise: true })}
      />);
  }

  renderLogo() {
    return (
      <Image
        resizeMode="contain"
        source={require('./images/logo.png')}
      />
    );
  }

  renderScene(props) {
    const navigateTo = (key, title, extraProps) => {
      // If the page we're going to takes in a record that can be finalised, retain it in state
      let recordToFinalise = null;
      let recordType = null;
      if (extraProps && 'invoice' in extraProps) {
        recordToFinalise = extraProps.invoice;
        recordType = 'Transaction';
      } else if (extraProps && 'requisition' in extraProps) {
        recordToFinalise = extraProps.requisition;
        recordType = 'Requisition';
      } else if (extraProps && 'stocktake' in extraProps) {
        recordToFinalise = extraProps.stocktake;
        recordType = 'Stocktake';
      } else if (extraProps && 'transaction' in extraProps) {
        recordToFinalise = extraProps.transaction;
        recordType = 'Transaction';
      }
      this.setState({ recordToFinalise: recordToFinalise, recordTypeToFinalise: recordType });

      // Now navigate to the page, passing on any extra props and the finalise button if required
      const navigationProps = { key, title, ...extraProps };
      if (recordToFinalise) navigationProps.renderRightComponent = this.renderFinaliseButton;
      props.onNavigate({ type: 'push', ...navigationProps });
    };
    const { key, ...extraProps } = props.scene.navigationState;
    const Page = PAGES[key]; // Get the page the navigation key relates to
    // Return the requested page with any extra props passed to navigateTo in pageProps
    return (
      <Page
        navigateTo={navigateTo}
        database={this.database}
        logOut={this.logOut}
        currentUser={this.state.currentUser}
        {...extraProps}
      />);
  }

  renderSyncState() {
    return (
      <SyncState
        isSyncing={this.state.isSyncing}
        syncError={this.state.syncError}
        settings={this.settings}
      />
    );
  }

  render() {
    if (!this.state.initialised) {
      const FirstUsePage = PAGES.firstUse;
      return (
        <FirstUsePage
          synchronizer={this.synchronizer}
          onInitialised={this.onInitialised}
        />
      );
    }
    return (
      <View style={globalStyles.appBackground}>
        <Navigator
          renderScene={this.renderScene}
          renderCentreComponent={this.renderLogo}
          renderRightComponent={this.renderSyncState}
          navBarStyle={globalStyles.navBarStyle}
          backgroundColor={BACKGROUND_COLOR}
        />
        <FinaliseModal
          database={this.database}
          isOpen={this.state.confirmFinalise}
          onClose={() => this.setState({ confirmFinalise: false })}
          record={this.state.recordToFinalise}
          recordType={this.state.recordTypeToFinalise}
          user={this.state.currentUser}
        />
        <LoginModal
          authenticator={this.userAuthenticator}
          isAuthenticated={this.state.currentUser !== null}
          onAuthentication={this.onAuthentication}
        />
      </View>
    );
  }
}
<commit_msg>Reset sync error state after good sync<commit_after>/* @flow weak */

/**
 * OfflineMobile Android
 * Sustainable Solutions (NZ) Ltd. 2016
 */

import React from 'react';
import {
  Image,
  View,
} from 'react-native';

import globalStyles, { BACKGROUND_COLOR } from './globalStyles';

import { Navigator } from './navigation';

import { PAGES } from './pages';

import {
  FinaliseButton,
  FinaliseModal,
  LoginModal,
  SyncState,
} from './widgets';

import { Synchronizer } from './sync';
import { SyncAuthenticator, UserAuthenticator } from './authentication';
import { Database, schema } from './database';
import { Scheduler } from './Scheduler';
import { Settings } from './settings';

const SYNC_INTERVAL = 10 * 60 * 1000; // 10 minutes in milliseconds
const AUTHENTICATION_INTERVAL = 10 * 60 * 1000; // 10 minutes in milliseconds

export default class OfflineMobileApp extends React.Component {

  constructor() {
    super();
    this.database = new Database(schema);
    this.settings = new Settings(this.database);
    this.userAuthenticator = new UserAuthenticator(this.database, this.settings);
    const syncAuthenticator = new SyncAuthenticator(this.database, this.settings);
    this.synchronizer = new Synchronizer(this.database, syncAuthenticator, this.settings);
    this.scheduler = new Scheduler();
    const initialised = this.synchronizer.isInitialised();
    this.state = {
      initialised: initialised,
      currentUser: null,
      isSyncing: false,
      syncError: '',
      lastSync: null, // Date of the last successful sync
      confirmFinalise: false,
      recordToFinalise: null,
      recordTypeToFinalise: null,
    };
  }

  componentWillMount() {
    this.logOut = this.logOut.bind(this);
    this.onAuthentication = this.onAuthentication.bind(this);
    this.onInitialised = this.onInitialised.bind(this);
    this.renderFinaliseButton = this.renderFinaliseButton.bind(this);
    this.renderScene = this.renderScene.bind(this);
    this.renderSyncState = this.renderSyncState.bind(this);
    this.synchronize = this.synchronize.bind(this);
    this.scheduler.schedule(this.synchronize,
                            SYNC_INTERVAL);
    this.scheduler.schedule(() => {
      if (this.state.currentUser !== null) { // Only reauthenticate if currently logged in
        this.userAuthenticator.reauthenticate(this.onAuthentication);
      }}, AUTHENTICATION_INTERVAL);
  }

  componentWillUnmount() {
    this.scheduler.clearAll();
  }

  onAuthentication(user) {
    this.setState({ currentUser: user });
  }

  onInitialised() {
    this.setState({ initialised: true });
  }

  async synchronize() {
    if (!this.state.initialised || this.state.isSyncing) return; // If already syncing, skip
    try {
      this.setState({ isSyncing: true });
      await this.synchronizer.synchronize();
      this.setState({
        isSyncing: false,
        syncError: null,
      });
    } catch (error) {
      this.setState({
        isSyncing: false,
        syncError: error.message,
      });
    }
  }

  logOut() {
    this.setState({ currentUser: null });
  }

  renderFinaliseButton() {
    return (
      <FinaliseButton
        isFinalised={this.state.recordToFinalise.status === 'finalised'}
        onPress={() => this.setState({ confirmFinalise: true })}
      />);
  }

  renderLogo() {
    return (
      <Image
        resizeMode="contain"
        source={require('./images/logo.png')}
      />
    );
  }

  renderScene(props) {
    const navigateTo = (key, title, extraProps) => {
      // If the page we're going to takes in a record that can be finalised, retain it in state
      let recordToFinalise = null;
      let recordType = null;
      if (extraProps && 'invoice' in extraProps) {
        recordToFinalise = extraProps.invoice;
        recordType = 'Transaction';
      } else if (extraProps && 'requisition' in extraProps) {
        recordToFinalise = extraProps.requisition;
        recordType = 'Requisition';
      } else if (extraProps && 'stocktake' in extraProps) {
        recordToFinalise = extraProps.stocktake;
        recordType = 'Stocktake';
      } else if (extraProps && 'transaction' in extraProps) {
        recordToFinalise = extraProps.transaction;
        recordType = 'Transaction';
      }
      this.setState({ recordToFinalise: recordToFinalise, recordTypeToFinalise: recordType });

      // Now navigate to the page, passing on any extra props and the finalise button if required
      const navigationProps = { key, title, ...extraProps };
      if (recordToFinalise) navigationProps.renderRightComponent = this.renderFinaliseButton;
      props.onNavigate({ type: 'push', ...navigationProps });
    };
    const { key, ...extraProps } = props.scene.navigationState;
    const Page = PAGES[key]; // Get the page the navigation key relates to
    // Return the requested page with any extra props passed to navigateTo in pageProps
    return (
      <Page
        navigateTo={navigateTo}
        database={this.database}
        logOut={this.logOut}
        currentUser={this.state.currentUser}
        {...extraProps}
      />);
  }

  renderSyncState() {
    return (
      <SyncState
        isSyncing={this.state.isSyncing}
        syncError={this.state.syncError}
        settings={this.settings}
      />
    );
  }

  render() {
    if (!this.state.initialised) {
      const FirstUsePage = PAGES.firstUse;
      return (
        <FirstUsePage
          synchronizer={this.synchronizer}
          onInitialised={this.onInitialised}
        />
      );
    }
    return (
      <View style={globalStyles.appBackground}>
        <Navigator
          renderScene={this.renderScene}
          renderCentreComponent={this.renderLogo}
          renderRightComponent={this.renderSyncState}
          navBarStyle={globalStyles.navBarStyle}
          backgroundColor={BACKGROUND_COLOR}
        />
        <FinaliseModal
          database={this.database}
          isOpen={this.state.confirmFinalise}
          onClose={() => this.setState({ confirmFinalise: false })}
          record={this.state.recordToFinalise}
          recordType={this.state.recordTypeToFinalise}
          user={this.state.currentUser}
        />
        <LoginModal
          authenticator={this.userAuthenticator}
          isAuthenticated={this.state.currentUser !== null}
          onAuthentication={this.onAuthentication}
        />
      </View>
    );
  }
}
<|endoftext|>