<commit_before>const path = require('path')
const http = require('http')
const fs = require('fs')
const electron = require('electron')
//const autoUpdater = require('./auto-updater')
// const app = require('app');
const BrowserWindow = electron.BrowserWindow
const app = electron.app
const baseURL = "http://localhost:9527/"
const elasticlunr = require('./bower_components/elasticlunr/release/elasticlunr.min.js');
const electronLocalShortcut = require('electron-localshortcut');

// Playing around with some elastic search stuff in angular.
// For this app, the JSON docs to search will be packaged, so we can add them
// to the index once the app starts up and then use that index to search against
const index = elasticlunr(function() {
    this.addField('title');
    this.addField('body');
    this.addField('description');
    this.addField('url');
    this.setRef('id');
    this.documentStore = new elasticlunr.DocumentStore;
    this.saveDocument(true);
});

// Making this electron application a single instance app
// When another app starts up, whiel this is running, it will instead call this callback function
// and bring the other app to the foreground and hangle the commandline arguments passed to it
const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
  if(BrowserWindow) {
    var jsonPath = path.join(__dirname, "\\contents\\contents.json");

    fs.openSync(jsonPath, 'r+'); //throws error if file doesn't exist
    var data = fs.readFileSync(jsonPath); //file exists, get the contents
    var sections = JSON.parse(data);

    // Check for an argument
    cmdArg = checkForArg(commandLine);

    // and load the index.html of the app.
    // Launch the requested page or the index
    launchRequestedPage(cmdArg, sections);

    // If the help app is minimized, restore it
    if (mainWindow.isMinimized()) {
      mainWindow.restore();
    }

    mainWindow.focus();
  }
});

if (shouldQuit) {
  app.quit();
};

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {

    buildSearchIndex();

    var args = process.argv
    var jsonPath = path.join(__dirname, "\\contents\\contents.json");

    fs.openSync(jsonPath, 'r+'); //throws error if file doesn't exist
    var data = fs.readFileSync(jsonPath); //file exists, get the contents
    var sections = JSON.parse(data);

    // Create the browser window.
    mainWindow = new BrowserWindow({
        width: 1024,
        height: 768,
        toolbar: false,
        webPreferences: {
            nodeIntegration: false
        }
    });

    mainWindow.setMenu(null);

    mainWindow.maximize();

    var server = http.createServer(requestHandler).listen(9527);
    var cmdArg = "";

    // Check for an argument
    cmdArg = checkForArg(args);

    // and load the index.html of the app.
    // Launch the requested page or the index
    launchRequestedPage(cmdArg, sections);

    mainWindow.openDevTools();

    // Emitted when the window is closed.
    mainWindow.on('closed', function() {

        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null;
    });
});

// Launch the requested page or the index
function launchRequestedPage(cmdArg, sections) {
  if (cmdArg === "") {
      console.log("No Arguments to Launch")
      mainWindow.loadURL('http://localhost:9527/index.html');
  } else {
      for (i = 0; i < sections.length; i++) {
          if (sections[i].title === cmdArg) {
              mainWindow.loadURL(path.join(baseURL, sections[i].url));
              break;
          }
      }
  }
}

// Check for an argument
function checkForArg (args) {
  for (i = 0; i < args.length; i++) {
      console.log("Arg" + i + ": " + args[i]);
      if (args[i] === "-section") {
          console.log("Found section arg! == " + args[i + 1]);
          return args[i + 1];
      }
  }
  // No section for the argument found, launch the index by default
    return "";
}

function buildSearchIndex() {
  var jsonPath = "./app/search/search.json"
  fs.openSync(jsonPath, 'r+'); //throws error if file doesn't exist
  var data = fs.readFileSync(jsonPath);
  var documents = JSON.parse(data);

  documents.forEach(function(doc) {
    console.log(doc);
    index.addDoc(doc);
  });

    // var doc1 = {
    //     "id": 1,
    //     "title": "Oracle released its latest database Oracle 12g",
    //     "body": "Yestaday Oracle has released its new database Oracle 12g, this would make more money for this company and lead to a nice profit report of annual year.",
    //     "description": "Yestaday Oracle has released its new database Oracle 12g",
    //     "url": "/index.html"
    // }
    //
    // var doc2 = {
    //     "id": 2,
    //     "title": "Oracle released its profit report of 2015",
    //     "body": "As expected, Oracle released its profit report of 2015, during the good sales of database and hardware, Oracle's profit of 2015 reached 12.5 Billion.",
    //     "description": "As expected, Oracle released its profit report of 2015,",
    //     "url": "/index.html"
    // }
    //
    // index.addDoc(doc1);
    // index.addDoc(doc2);

}

/**
 * Let's try and explain some magic going on here.
 * So, we need to ignore requests to all "whitelisted" files on the server
 * This is basically all files that are not blacklisted or rewritePaths
 * The only rewrite at the moment is the /p/* path, we need to direct
 * the webclient to the actual location of the file, but not allow the
 * webclient to access the html pages contained directly. This is the
 * same for partials, except partials should never be delivered to the
 * client on their own and are instead used to inject into the DOM.
 **/
function requestHandler(req, res) {
    console.log("Entered requestHandler...");
    var
        file = req.url == '/' ? '/index.html' : req.url,
        root = __dirname,
        page404 = root + '/404.html',
        fullPath = "",
        ignoredPaths = ['/bower_components/'],
        rewritePaths = ['/p/'],
        REWRITTING = false;

    if (result = startsWith(req.url, ignoredPaths).found) {
        console.log("!!ALERT!! Requested URL is Blacklisted!");
        fullPath = path.join(root, file).replace(/\//g, "/");
    } else if (result = startsWith(req.url, rewritePaths).found) {
        REWRITTING = true;
        console.log("!!ALERT!! Requested URL is Rewriteable! " + req.url);
        if (rewritePaths[result.index] == '/p/') {
            console.log("Rewrite path = " + file);
            fullPath = path.join(root, file).replace(/\//g, "/");
        }
        else {
            console.log("Got a strange result from Request Handler: " + result.index);
            file = page404;
            fullPath = path.join(root, file).replace(/\//g, "/");
        }
    } else if (result = startsWith(req.url, ['/search/results.html']).found) {
        console.log("This is a results request, handle me.");
        file = '/search/results.html';
        fullPath = path.join(root, file).replace(/\//g, "/");
    } else if (result = startsWith(req.url, ['/find/']).found) {
        console.log("This is a search request, handle me.");
        console.log("Request Type:" + req.method);

        if (req.method === 'POST') {
            console.log("We got a POST!");
            var searchTerm = getParameterByName("v", req.url);
            console.log("Search Term: " + searchTerm);
            var result = index.search(searchTerm);
            console.log("Search Result:" + JSON.stringify(result));
            var docs = retreiveResultDocs(result);
            res.end(JSON.stringify(docs));
        } else if (req.method === 'GET') {
            console.log("We got a GET! Since this is a find, it should have been a POST, who screwed up?");
        }
    } else {
        fullPath = path.join(root, file).replace(/\//g, "/");
    }

    console.log("root = " + root);
    console.log("file = " + file);

    // Make full path to file and replace / with \
    // fullPath = path.join(root, file).replace(/\//g, "/");
    console.log("fullPath = " + fullPath);

    if (!REWRITTING) {
        getFile(fullPath, res, page404);
    } else {
        fs.readFile(path.join(__dirname, "index.html"), function(err, contents) {
            if (!err) {
                res.end(contents);
            } else {
                console.dir(err);
            }
        });
    }

};

function retreiveResultDocs(results) {
  // TODO: For each result in results, retreive JSON DOC object and prepare to return
  // to the client.

  var docs = [];
  for (var i = 0; i < results.length; i++) {
    var cRef = parseInt(results[i].ref);
    docs.push(index.documentStore.getDoc(cRef));
  }

  return docs;
};

// Checks to see if the URL passed starts with any of the items in provided array
function startsWith(string, array) {
    console.log("Starts with entered... " + string);
    for (i = 0; i < array.length; i++)
        if (string.startsWith(array[i]))
            return {
                found: true,
                index: i
            }
    return {
        found: false,
        index: i
    }
};

function getFile(filePath, res, page404) {

    console.log("Get File Path === " + filePath);

    var file = decodeURI(filePath);

    fs.exists(file, function(exists) {
        if (exists) {
            fs.readFile(file, function(err, contents) {
                if (!err) {
                    res.end(contents);
                } else {
                    console.dir(err);
                }
            });
        } else {
            fs.readFile(page404, function(err, contents) {
                if (!err) {
                    res.writeHead(404, {
                        'Content-Type': 'text/html'
                    });
                    res.end(contents);
                } else {
                    console.dir(err);
                }
            });
        }
    });
};

// Decodes a URL and retrieves the specified parameter value.
function getParameterByName(name, url) {
    if (!url) {
      console.log("No URL specified in getParameterByName().")
    }
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}
<commit_msg>Removed electron local shortcut<commit_after>const path = require('path')
const http = require('http')
const fs = require('fs')
const electron = require('electron')
//const autoUpdater = require('./auto-updater')
// const app = require('app');
const BrowserWindow = electron.BrowserWindow
const app = electron.app
const baseURL = "http://localhost:9527/"
const elasticlunr = require('./bower_components/elasticlunr/release/elasticlunr.min.js');

// Playing around with some elastic search stuff in angular.
// For this app, the JSON docs to search will be packaged, so we can add them
// to the index once the app starts up and then use that index to search against
const index = elasticlunr(function() {
    this.addField('title');
    this.addField('body');
    this.addField('description');
    this.addField('url');
    this.setRef('id');
    this.documentStore = new elasticlunr.DocumentStore;
    this.saveDocument(true);
});

// Making this electron application a single instance app
// When another app starts up, whiel this is running, it will instead call this callback function
// and bring the other app to the foreground and hangle the commandline arguments passed to it
const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
  if(BrowserWindow) {
    var jsonPath = path.join(__dirname, "\\contents\\contents.json");

    fs.openSync(jsonPath, 'r+'); //throws error if file doesn't exist
    var data = fs.readFileSync(jsonPath); //file exists, get the contents
    var sections = JSON.parse(data);

    // Check for an argument
    cmdArg = checkForArg(commandLine);

    // and load the index.html of the app.
    // Launch the requested page or the index
    launchRequestedPage(cmdArg, sections);

    // If the help app is minimized, restore it
    if (mainWindow.isMinimized()) {
      mainWindow.restore();
    }

    mainWindow.focus();
  }
});

if (shouldQuit) {
  app.quit();
};

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {

    buildSearchIndex();

    var args = process.argv
    var jsonPath = path.join(__dirname, "\\contents\\contents.json");

    fs.openSync(jsonPath, 'r+'); //throws error if file doesn't exist
    var data = fs.readFileSync(jsonPath); //file exists, get the contents
    var sections = JSON.parse(data);

    // Create the browser window.
    mainWindow = new BrowserWindow({
        width: 1024,
        height: 768,
        toolbar: false,
        webPreferences: {
            nodeIntegration: false
        }
    });

    mainWindow.setMenu(null);

    mainWindow.maximize();

    var server = http.createServer(requestHandler).listen(9527);
    var cmdArg = "";

    // Check for an argument
    cmdArg = checkForArg(args);

    // and load the index.html of the app.
    // Launch the requested page or the index
    launchRequestedPage(cmdArg, sections);

    mainWindow.openDevTools();

    // Emitted when the window is closed.
    mainWindow.on('closed', function() {

        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null;
    });
});

// Launch the requested page or the index
function launchRequestedPage(cmdArg, sections) {
  if (cmdArg === "") {
      console.log("No Arguments to Launch")
      mainWindow.loadURL('http://localhost:9527/index.html');
  } else {
      for (i = 0; i < sections.length; i++) {
          if (sections[i].title === cmdArg) {
              mainWindow.loadURL(path.join(baseURL, sections[i].url));
              break;
          }
      }
  }
}

// Check for an argument
function checkForArg (args) {
  for (i = 0; i < args.length; i++) {
      console.log("Arg" + i + ": " + args[i]);
      if (args[i] === "-section") {
          console.log("Found section arg! == " + args[i + 1]);
          return args[i + 1];
      }
  }
  // No section for the argument found, launch the index by default
    return "";
}

function buildSearchIndex() {
  var jsonPath = "./app/search/search.json"
  fs.openSync(jsonPath, 'r+'); //throws error if file doesn't exist
  var data = fs.readFileSync(jsonPath);
  var documents = JSON.parse(data);

  documents.forEach(function(doc) {
    console.log(doc);
    index.addDoc(doc);
  });

    // var doc1 = {
    //     "id": 1,
    //     "title": "Oracle released its latest database Oracle 12g",
    //     "body": "Yestaday Oracle has released its new database Oracle 12g, this would make more money for this company and lead to a nice profit report of annual year.",
    //     "description": "Yestaday Oracle has released its new database Oracle 12g",
    //     "url": "/index.html"
    // }
    //
    // var doc2 = {
    //     "id": 2,
    //     "title": "Oracle released its profit report of 2015",
    //     "body": "As expected, Oracle released its profit report of 2015, during the good sales of database and hardware, Oracle's profit of 2015 reached 12.5 Billion.",
    //     "description": "As expected, Oracle released its profit report of 2015,",
    //     "url": "/index.html"
    // }
    //
    // index.addDoc(doc1);
    // index.addDoc(doc2);

}

/**
 * Let's try and explain some magic going on here.
 * So, we need to ignore requests to all "whitelisted" files on the server
 * This is basically all files that are not blacklisted or rewritePaths
 * The only rewrite at the moment is the /p/* path, we need to direct
 * the webclient to the actual location of the file, but not allow the
 * webclient to access the html pages contained directly. This is the
 * same for partials, except partials should never be delivered to the
 * client on their own and are instead used to inject into the DOM.
 **/
function requestHandler(req, res) {
    console.log("Entered requestHandler...");
    var
        file = req.url == '/' ? '/index.html' : req.url,
        root = __dirname,
        page404 = root + '/404.html',
        fullPath = "",
        ignoredPaths = ['/bower_components/'],
        rewritePaths = ['/p/'],
        REWRITTING = false;

    if (result = startsWith(req.url, ignoredPaths).found) {
        console.log("!!ALERT!! Requested URL is Blacklisted!");
        fullPath = path.join(root, file).replace(/\//g, "/");
    } else if (result = startsWith(req.url, rewritePaths).found) {
        REWRITTING = true;
        console.log("!!ALERT!! Requested URL is Rewriteable! " + req.url);
        if (rewritePaths[result.index] == '/p/') {
            console.log("Rewrite path = " + file);
            fullPath = path.join(root, file).replace(/\//g, "/");
        }
        else {
            console.log("Got a strange result from Request Handler: " + result.index);
            file = page404;
            fullPath = path.join(root, file).replace(/\//g, "/");
        }
    } else if (result = startsWith(req.url, ['/search/results.html']).found) {
        console.log("This is a results request, handle me.");
        file = '/search/results.html';
        fullPath = path.join(root, file).replace(/\//g, "/");
    } else if (result = startsWith(req.url, ['/find/']).found) {
        console.log("This is a search request, handle me.");
        console.log("Request Type:" + req.method);

        if (req.method === 'POST') {
            console.log("We got a POST!");
            var searchTerm = getParameterByName("v", req.url);
            console.log("Search Term: " + searchTerm);
            var result = index.search(searchTerm);
            console.log("Search Result:" + JSON.stringify(result));
            var docs = retreiveResultDocs(result);
            res.end(JSON.stringify(docs));
        } else if (req.method === 'GET') {
            console.log("We got a GET! Since this is a find, it should have been a POST, who screwed up?");
        }
    } else {
        fullPath = path.join(root, file).replace(/\//g, "/");
    }

    console.log("root = " + root);
    console.log("file = " + file);

    // Make full path to file and replace / with \
    // fullPath = path.join(root, file).replace(/\//g, "/");
    console.log("fullPath = " + fullPath);

    if (!REWRITTING) {
        getFile(fullPath, res, page404);
    } else {
        fs.readFile(path.join(__dirname, "index.html"), function(err, contents) {
            if (!err) {
                res.end(contents);
            } else {
                console.dir(err);
            }
        });
    }

};

function retreiveResultDocs(results) {
  // TODO: For each result in results, retreive JSON DOC object and prepare to return
  // to the client.

  var docs = [];
  for (var i = 0; i < results.length; i++) {
    var cRef = parseInt(results[i].ref);
    docs.push(index.documentStore.getDoc(cRef));
  }

  return docs;
};

// Checks to see if the URL passed starts with any of the items in provided array
function startsWith(string, array) {
    console.log("Starts with entered... " + string);
    for (i = 0; i < array.length; i++)
        if (string.startsWith(array[i]))
            return {
                found: true,
                index: i
            }
    return {
        found: false,
        index: i
    }
};

function getFile(filePath, res, page404) {

    console.log("Get File Path === " + filePath);

    var file = decodeURI(filePath);

    fs.exists(file, function(exists) {
        if (exists) {
            fs.readFile(file, function(err, contents) {
                if (!err) {
                    res.end(contents);
                } else {
                    console.dir(err);
                }
            });
        } else {
            fs.readFile(page404, function(err, contents) {
                if (!err) {
                    res.writeHead(404, {
                        'Content-Type': 'text/html'
                    });
                    res.end(contents);
                } else {
                    console.dir(err);
                }
            });
        }
    });
};

// Decodes a URL and retrieves the specified parameter value.
function getParameterByName(name, url) {
    if (!url) {
      console.log("No URL specified in getParameterByName().")
    }
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}
<|endoftext|>


<commit_before>/* document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names,
     class names and ids and can be nested. For example:

       elements = document.getElementsBySelect('div#main p a.external')

     Will return an array of all 'a' elements with 'external' in their
     class attribute that are contained inside 'p' elements that are
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            try {
                elements = currentContext[h].getElementsByTagName(tagName);
            }
            catch(e) {
                elements = [];
            }
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute
   Tag
*/
<commit_msg>Fixed #10783 -- Fixed Javascript error when adding a new object in admin.<commit_after>/* document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names,
     class names and ids and can be nested. For example:

       elements = document.getElementsBySelect('div#main p a.external')

     Will return an array of all 'a' elements with 'external' in their
     class attribute that are contained inside 'p' elements that are
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (!element || (tagName && element.nodeName.toLowerCase() != tagName)) {
        // ID not found or tag with that ID not found, return false.
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            try {
                elements = currentContext[h].getElementsByTagName(tagName);
            }
            catch(e) {
                elements = [];
            }
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute
   Tag
*/
<|endoftext|>


<commit_before>/*
   Copyright 2017 kanreisa

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
"use strict";

const electron = require("electron");
const app = electron.app;
const settings = require("electron-settings");
const { autoUpdater } = require("electron-updater");
const isDev = require('electron-is-dev');
const Mirakurun = require("mirakurun").default;
const regexp = require("./regexp");
const pkg = require("../package.json");

const mirakurun = global.mirakurun = new Mirakurun();
mirakurun.userAgent = `${pkg.name}/${app.getVersion()}`;

const icon = {
    normal: electron.nativeImage.createFromPath(`${__dirname}/images/icon.png`),
    normal30: electron.nativeImage.createFromPath(`${__dirname}/images/icon30.png`),
    offline: electron.nativeImage.createFromPath(`${__dirname}/images/icon-gray.png`),
    active: electron.nativeImage.createFromPath(`${__dirname}/images/icon-active.png`)
};

autoUpdater.on("update-downloaded", () => {
    // Wait 5 seconds, then quit and install
    // In your application, you don't need to wait 5 seconds.
    // You could call autoUpdater.quitAndInstall(); immediately
    setTimeout(() => autoUpdater.quitAndInstall(), 5000);
});

app.on("ready", init);

const TrayMenuItems = [
    {
        label: "Status",
        click: showStatus
    },
    {
        label: "Preferences",
        click: showPref
    },
    {
        type: "separator"
    },
    {
        label: "Open Homepage",
        click: openHomepage
    },
    {
        label: "Report Bugs",
        click: openFeedback
    },
    {
        type: "separator"
    },
    {
        label: `About ${ app.getName() }`,
        icon: icon.normal,
        click: about
    },
    {
        type: "separator"
    },
    {
        label: "Quit",
        accelerator: "CmdOrCtrl+Q",
        click: quit
    }
];

let statusWindow,
    prefWindow,
    tray,
    menu,
    eventsStream,
    checkRetryTimer;

function init() {

    menu = electron.Menu.buildFromTemplate(TrayMenuItems);

    tray = new electron.Tray(icon.offline);
    tray.setToolTip(`${app.getName()} - N/A`);
    tray.setContextMenu(menu);

    tray.on("click", () => {
        if (mirakurun.host) {
            showStatus();
        } else {
            showPref();
        }
    });

    prefWindow = new electron.BrowserWindow({
        icon: icon.normal,
        width: 400,
        height: 200,
        minWidth: 400,
        minHeight: 200,
        frame: false,
        closable: false,
        alwaysOnTop: true,
        transparent: true,
        show: false
    });

    prefWindow.loadURL(`file://${ __dirname }/ui/pref.html`);

    setTimeout(checker, 1000);
    settings.watch("host", () => checkRetryTimer = setTimeout(checker, 1500));
    settings.watch("port", () => checkRetryTimer = setTimeout(checker, 1500));

    if (!isDev) {
        autoUpdater.allowPrerelease = true;// TODO
        setInterval(() => autoUpdater.checkForUpdates(), 1000 * 60 * 60 * 6);
        setTimeout(() => autoUpdater.checkForUpdates(), 5000);
    }
}

async function checker() {

    clearTimeout(checkRetryTimer);

    tray.setImage(icon.offline);

    if (eventsStream) {
        if (eventsStream.socket.destroyed === false) {
            eventsStream.destroy();
        }

        eventsStream.removeAllListeners();
    }

    const host = settings.get("host");
    const port = settings.get("port");
    console.log("host:", host);
    console.log("port:", port);

    if (!host || !port) {
        return;
    }
    if (regexp.privateIPv4Address.test(host) === false || regexp.integer.test(port) === false) {
        return;
    }

    mirakurun.host = host;
    mirakurun.port = parseInt(port, 10);

    try {
        global.tuners = await mirakurun.getTuners();
        console.log("tuners:", global.tuners.length);
    } catch (e) {
        console.warn("tuners:", "error");
        tray.setToolTip(`${app.getName()} - Disconnected`);

        checkRetryTimer = setTimeout(checker, 5000);
        return;
    }

    try {
        eventsStream = await mirakurun.getEventsStream({
            resource: "tuner",
            type: "update"
        });
        eventsStream.setEncoding("utf8");
        console.warn("events:", eventsStream.statusCode);
    } catch (e) {
        console.warn("events:", "error");
        tray.setToolTip(`${app.getName()} - Disconnected`);

        checkRetryTimer = setTimeout(checker, 5000);
        return;
    }

    if (eventsStream.statusCode !== 200) {
        eventsStream = undefined;
        tray.setToolTip(`${app.getName()} - Error: ${eventsStream.statusCode}`);

        checkRetryTimer = setTimeout(checker, 5000);
        return;
    }

    const updateTray = () => {
        const isActive = global.tuners.some(tuner => tuner.isUsing === true && tuner.users.some(user => user.priority !== -1));
        if (isActive) {
            tray.setToolTip(`${app.getName()} - Active`);
            tray.setImage(icon.active);
        } else {
            tray.setToolTip(`${app.getName()} - Standby`);
            tray.setImage(icon.normal);
        }
    };
    updateTray();

    eventsStream.on("data", data => {
        data = data.match(/(\{.+\})\n,/m);
        if (!data) {
            return;
        }
        // console.log(data[1]);
        try {
            const tuner = JSON.parse(data[1]).data;
            global.tuners[tuner.index] = tuner;
            updateTray();
        } catch (e) { }
    });

    eventsStream.on("end", () => {
        console.log("ENDED!!! will retry");
        checkRetryTimer = setTimeout(checker, 3000);
    });

    clearTimeout(checkRetryTimer);
}

function showStatus() {

    if (statusWindow) {
        statusWindow.show();
        statusWindow.focus();
        return;
    }

    statusWindow = new electron.BrowserWindow({
        icon: icon.normal,
        width: 600,
        height: 350,
        minWidth: 600,
        minHeight: 300,
        frame: false,
        closable: true,
        alwaysOnTop: true,
        transparent: true
    });

    statusWindow.loadURL(`file://${ __dirname }/ui/status.html`);

    statusWindow.once("closed", () => {
        statusWindow = null;
    });
}

function showPref() {

    prefWindow.show();
    prefWindow.focus();
}

function openHomepage() {
    electron.shell.openExternal(pkg.homepage);
}

function openFeedback() {
    electron.shell.openExternal(pkg.bugs.url);
}

function about() {

    electron.dialog.showMessageBox({
        type: "info",
        icon: icon.normal30,
        title: app.getName(),
        message: app.getName(),
        detail: `Version ${app.getVersion()}\nNode ${process.version}`,
        buttons: [
            "Close"
        ]
    });
}

function quit() {

    if (statusWindow) {
        statusWindow.destroy();
    }
    if (prefWindow) {
        prefWindow.destroy();
    }

    app.quit();
}
<commit_msg>fix code style<commit_after>/*
   Copyright 2017 kanreisa

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
"use strict";

const electron = require("electron");
const app = electron.app;
const settings = require("electron-settings");
const { autoUpdater } = require("electron-updater");
const isDev = require("electron-is-dev");
const Mirakurun = require("mirakurun").default;
const regexp = require("./regexp");
const pkg = require("../package.json");

const mirakurun = global.mirakurun = new Mirakurun();
mirakurun.userAgent = `${pkg.name}/${app.getVersion()}`;

const icon = {
    normal: electron.nativeImage.createFromPath(`${__dirname}/images/icon.png`),
    normal30: electron.nativeImage.createFromPath(`${__dirname}/images/icon30.png`),
    offline: electron.nativeImage.createFromPath(`${__dirname}/images/icon-gray.png`),
    active: electron.nativeImage.createFromPath(`${__dirname}/images/icon-active.png`)
};

autoUpdater.on("update-downloaded", () => {
    // Wait 5 seconds, then quit and install
    // In your application, you don't need to wait 5 seconds.
    // You could call autoUpdater.quitAndInstall(); immediately
    setTimeout(() => autoUpdater.quitAndInstall(), 5000);
});

app.on("ready", init);

const TrayMenuItems = [
    {
        label: "Status",
        click: showStatus
    },
    {
        label: "Preferences",
        click: showPref
    },
    {
        type: "separator"
    },
    {
        label: "Open Homepage",
        click: openHomepage
    },
    {
        label: "Report Bugs",
        click: openFeedback
    },
    {
        type: "separator"
    },
    {
        label: `About ${ app.getName() }`,
        icon: icon.normal,
        click: about
    },
    {
        type: "separator"
    },
    {
        label: "Quit",
        accelerator: "CmdOrCtrl+Q",
        click: quit
    }
];

let statusWindow,
    prefWindow,
    tray,
    menu,
    eventsStream,
    checkRetryTimer;

function init() {

    menu = electron.Menu.buildFromTemplate(TrayMenuItems);

    tray = new electron.Tray(icon.offline);
    tray.setToolTip(`${app.getName()} - N/A`);
    tray.setContextMenu(menu);

    tray.on("click", () => {
        if (mirakurun.host) {
            showStatus();
        } else {
            showPref();
        }
    });

    prefWindow = new electron.BrowserWindow({
        icon: icon.normal,
        width: 400,
        height: 200,
        minWidth: 400,
        minHeight: 200,
        frame: false,
        closable: false,
        alwaysOnTop: true,
        transparent: true,
        show: false
    });

    prefWindow.loadURL(`file://${ __dirname }/ui/pref.html`);

    setTimeout(checker, 1000);
    settings.watch("host", () => checkRetryTimer = setTimeout(checker, 1500));
    settings.watch("port", () => checkRetryTimer = setTimeout(checker, 1500));

    if (!isDev) {
        autoUpdater.allowPrerelease = true;// TODO
        setInterval(() => autoUpdater.checkForUpdates(), 1000 * 60 * 60 * 6);
        setTimeout(() => autoUpdater.checkForUpdates(), 5000);
    }
}

async function checker() {

    clearTimeout(checkRetryTimer);

    tray.setImage(icon.offline);

    if (eventsStream) {
        if (eventsStream.socket.destroyed === false) {
            eventsStream.destroy();
        }

        eventsStream.removeAllListeners();
    }

    const host = settings.get("host");
    const port = settings.get("port");
    console.log("host:", host);
    console.log("port:", port);

    if (!host || !port) {
        return;
    }
    if (regexp.privateIPv4Address.test(host) === false || regexp.integer.test(port) === false) {
        return;
    }

    mirakurun.host = host;
    mirakurun.port = parseInt(port, 10);

    try {
        global.tuners = await mirakurun.getTuners();
        console.log("tuners:", global.tuners.length);
    } catch (e) {
        console.warn("tuners:", "error");
        tray.setToolTip(`${app.getName()} - Disconnected`);

        checkRetryTimer = setTimeout(checker, 5000);
        return;
    }

    try {
        eventsStream = await mirakurun.getEventsStream({
            resource: "tuner",
            type: "update"
        });
        eventsStream.setEncoding("utf8");
        console.warn("events:", eventsStream.statusCode);
    } catch (e) {
        console.warn("events:", "error");
        tray.setToolTip(`${app.getName()} - Disconnected`);

        checkRetryTimer = setTimeout(checker, 5000);
        return;
    }

    if (eventsStream.statusCode !== 200) {
        eventsStream = undefined;
        tray.setToolTip(`${app.getName()} - Error: ${eventsStream.statusCode}`);

        checkRetryTimer = setTimeout(checker, 5000);
        return;
    }

    const updateTray = () => {
        const isActive = global.tuners.some(tuner => tuner.isUsing === true && tuner.users.some(user => user.priority !== -1));
        if (isActive) {
            tray.setToolTip(`${app.getName()} - Active`);
            tray.setImage(icon.active);
        } else {
            tray.setToolTip(`${app.getName()} - Standby`);
            tray.setImage(icon.normal);
        }
    };
    updateTray();

    eventsStream.on("data", data => {
        data = data.match(/(\{.+\})\n,/m);
        if (!data) {
            return;
        }
        // console.log(data[1]);
        try {
            const tuner = JSON.parse(data[1]).data;
            global.tuners[tuner.index] = tuner;
            updateTray();
        } catch (e) { }
    });

    eventsStream.on("end", () => {
        console.log("ENDED!!! will retry");
        checkRetryTimer = setTimeout(checker, 3000);
    });

    clearTimeout(checkRetryTimer);
}

function showStatus() {

    if (statusWindow) {
        statusWindow.show();
        statusWindow.focus();
        return;
    }

    statusWindow = new electron.BrowserWindow({
        icon: icon.normal,
        width: 600,
        height: 350,
        minWidth: 600,
        minHeight: 300,
        frame: false,
        closable: true,
        alwaysOnTop: true,
        transparent: true
    });

    statusWindow.loadURL(`file://${ __dirname }/ui/status.html`);

    statusWindow.once("closed", () => {
        statusWindow = null;
    });
}

function showPref() {

    prefWindow.show();
    prefWindow.focus();
}

function openHomepage() {
    electron.shell.openExternal(pkg.homepage);
}

function openFeedback() {
    electron.shell.openExternal(pkg.bugs.url);
}

function about() {

    electron.dialog.showMessageBox({
        type: "info",
        icon: icon.normal30,
        title: app.getName(),
        message: app.getName(),
        detail: `Version ${app.getVersion()}\nNode ${process.version}`,
        buttons: [
            "Close"
        ]
    });
}

function quit() {

    if (statusWindow) {
        statusWindow.destroy();
    }
    if (prefWindow) {
        prefWindow.destroy();
    }

    app.quit();
}
<|endoftext|>


<commit_before>/*global define:true requirejs:true*/
/* jshint strict: false */
requirejs.config({
    paths: {
        'jquery': '../jquery/jquery',
        'gioc': '../gioc'
    }
});

define(['gioc', 'jquery'], function (Gioc, $) {
    console.log('Loading');

    var Ajax = function(){};

    var Sync = function(){};
    Sync.prototype.pull = function(){
    	console.log('Sync: ', this.url);
    	return this;
    };

    var User = function(){};
    User.prototype.fullName = function(){
    	return this.first + ' ' + this.last;
    };

	var gioc = new Gioc();
	gioc.map('User', User,{});

	/*
	 * Try to add a dependency solver based on requirejs
	 * We might have to keep track of dependencies, and only
	 * execute next solver if the previous one failed, so we
	 * might want to modify the array as we go, to remove the
	 * key from the next loop.
	 */
	gioc.addSolver('deps', function(key, target, deps){
		console.log('========>> ', target)
		try{
			deps.map(function(dep){
				console.log(dep)
				if(! dep in target){
					console.log('try to solve')
					var lib = require(dep);
					if(lib) target[dep] = lib;
				}
			}, this);

		}catch(e){}
	});

	gioc.map('ajax', function(){return new Ajax;},{
		// deps:['user']
	});
	gioc.map('sync', function(options){
		return new Sync;
	},{deps:['ajax']});

	gioc.map('userid', 123456789, {
		modifier:function(id){
			console.log('modifier ', id);
			return Math.round(id / 100000);
		}
	});

	gioc.map('user', function(options){
		console.log('user factory: ', this, options);
		return new User();
	}, {
		factoryOptions:true,
		deps:['userid',
			  'jquery',
			  {id:'sync',
				options:{
			  	props:{url:'localhost'},
				post:function(){
					console.log('************ hello sync ', this, arguments);
				}
			}
		}]
	});

	console.log('Beans ', gioc.beans);

	var userid = gioc.solve('userid');
	console.log('userid ', userid);

	var pepe = gioc.solve('user', {props:{first:'pepe', last:'rone'}});
	console.log('User pepe ', pepe);

	window.pepe = pepe;
	window.gioc = gioc;
});<commit_msg>App: Update after example.<commit_after>/*global define:true requirejs:true*/
/* jshint strict: false */
requirejs.config({
    paths: {
        'jquery': '../jquery/jquery',
        'gioc': '../gioc'
    }
});

define(['gioc', 'jquery'], function (Gioc, $) {
    console.log('Loading');

    var Ajax = function(){};

    var Sync = function(){};
    Sync.prototype.pull = function(){
    	console.log('Sync: ', this.url);
    	return this;
    };

    var User = function(){};
    User.prototype.fullName = function(){
    	return this.first + ' ' + this.last;
    };

	var gioc = new Gioc();
	gioc.map('User', User,{});

	/*
	 * Try to add a dependency solver based on requirejs
	 * We might have to keep track of dependencies, and only
	 * execute next solver if the previous one failed, so we
	 * might want to modify the array as we go, to remove the
	 * key from the next loop.
	 */
	gioc.addSolver('deps', function(key, target, deps){
		console.log('========>> ', target)
		try{
			deps.map(function(dep){
				console.log(dep)
				if(! dep in target){
					console.log('try to solve')
					var lib = require(dep);
					if(lib) target[dep] = lib;
				}
			}, this);

		}catch(e){}
	});

	gioc.map('ajax', function(){return new Ajax;},{
		// deps:['user']
	});
	gioc.map('sync', function(options){
		return new Sync;
	},{deps:['ajax']});

	gioc.map('userid', 123456789, {
		modifier:function(id){
			console.log('modifier ', id);
			return Math.round(id / 100000);
		}
	});

	gioc.map('user', function(options){
		console.log('user factory: ', this, options);
		return new User();
	}, {
		factoryOptions:true,
		deps:['userid',
			  'jquery',
			  {id:'sync',
				options:{
			  	props:{url:'localhost'},
				after:function(){
					console.log('************ POST: hello sync ', this, arguments);
				}
			}
		}]
	});

	console.log('Beans ', gioc.beans);

	var userid = gioc.solve('userid');
	console.log('userid ', userid);

	var pepe = gioc.solve('user', {props:{first:'pepe', last:'rone'}});
	console.log('User pepe ', pepe);

	window.pepe = pepe;
	window.gioc = gioc;
});<|endoftext|>


<commit_before>import ReactDOM from 'react-dom'
import React from 'react'

// const Break = React.createClass({
//   render: function() {
//     return (
//

//         *
//         Break
//         5:00
//         Break
//
//

//     )
//   }
// })

const TasksList = React.createClass({
  render: function() {
    const createItem = function(item) {
      return (

          {item.id}
          {item.task}
          1:00
          Pomodoro

      )
    }
    return (

              #
              Task
              Duration
              Type

            {this.props.tasksList.map(createItem)}

    )
  },
})

const Timer = React.createClass({
  getInitialState: function() {
    return {
      timeRemaining: {
        mins: 25,
        secs: '00',
      },
      tasksList: [],
      task: '',
    }
  },
  onChange: function(e) {
    this.setState({task: e.target.value})
  },
  handleSubmit: function(e) {
    e.preventDefault()
    if (this.state.task === '') {
      return
    }
    if (this.state.tasksList[0]) {
      this.state.tasksList[0].current = false
    }
    const newItemArray = [{
      id: this.state.tasksList.length + 1,
      task: this.state.task,
      current: true,
      createdOn: Date.now(),
    }]
    const nextItems = newItemArray.concat(this.state.tasksList)
    const nextText = ''
    this.setState({
      tasksList: nextItems,
      task: nextText,
    })
    if (this.state.tasksList.length === 0) {
      this.start()
    }
  },
  tick: function() {
    const newTimeRemaining = {}
    if (this.state.timeRemaining.secs > 0) {
      newTimeRemaining.mins = this.state.timeRemaining.mins
      newTimeRemaining.secs = this.state.timeRemaining.secs -  1
      if (newTimeRemaining.secs < 10) {
        newTimeRemaining.secs = '0' + newTimeRemaining.secs
      }
    } else {
      newTimeRemaining.mins = this.state.timeRemaining.mins - 1
      if (this.state.timeRemaining.secs === 0 || this.state.timeRemaining.secs === '00') {
        newTimeRemaining.secs = 59
      } else {
        newTimeRemaining.secs = this.state.timeRemaining.secs -  1
      }
    }
    this.setState({timeRemaining: newTimeRemaining})
  },
  start: function() {
    this.interval = setInterval(this.tick, 1000)
  },
  pause: function() {
    clearInterval(this.interval)
  },
  next: function() {
    clearInterval(this.interval)
    this.setState({timeRemaining: 1500})
  },
  componentWillUnmount: function() {
    clearInterval(this.interval)
  },
  render: function() {
    return (

{this.state.timeRemaining.mins}:{this.state.timeRemaining.secs}

            <button type="button" className="btn btn-default btn-lg" onClick={this.start}>Start</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.pause}>Pause</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.next}>Next</button>

Pomodoros

                  2

Work time

                  50:00

Break time

                  10:00

Breaks

                  1

        <form onSubmit={this.handleSubmit}>

            <input type="text" className="form-control" placeholder="Add new task" onChange={this.onChange} value={this.state.task} />

              <button className="btn btn-default" type="submit">{'Add #' + (this.state.tasksList.length + 1)}</button>

        </form>
        <TasksList tasksList={this.state.tasksList} />

    )
  },
})

ReactDOM.render(<Timer />, document.getElementById('app'))
<commit_msg>remove break class<commit_after>import ReactDOM from 'react-dom'
import React from 'react'

const TasksList = React.createClass({
  render: function() {
    const createItem = function(item) {
      return (

          {item.id}
          {item.task}
          1:00
          Pomodoro

      )
    }
    return (

              #
              Task
              Duration
              Type

            {this.props.tasksList.map(createItem)}

    )
  },
})

const Timer = React.createClass({
  getInitialState: function() {
    return {
      timeRemaining: {
        mins: 25,
        secs: '00',
      },
      tasksList: [],
      task: '',
    }
  },
  onChange: function(e) {
    this.setState({task: e.target.value})
  },
  handleSubmit: function(e) {
    e.preventDefault()
    if (this.state.task === '') {
      return
    }
    if (this.state.tasksList[0]) {
      this.state.tasksList[0].current = false
    }
    const newItemArray = [{
      id: this.state.tasksList.length + 1,
      task: this.state.task,
      current: true,
      createdOn: Date.now(),
    }]
    const nextItems = newItemArray.concat(this.state.tasksList)
    const nextText = ''
    this.setState({
      tasksList: nextItems,
      task: nextText,
    })
    if (this.state.tasksList.length === 0) {
      this.start()
    }
  },
  tick: function() {
    const newTimeRemaining = {}
    if (this.state.timeRemaining.secs > 0) {
      newTimeRemaining.mins = this.state.timeRemaining.mins
      newTimeRemaining.secs = this.state.timeRemaining.secs -  1
      if (newTimeRemaining.secs < 10) {
        newTimeRemaining.secs = '0' + newTimeRemaining.secs
      }
    } else {
      newTimeRemaining.mins = this.state.timeRemaining.mins - 1
      if (this.state.timeRemaining.secs === 0 || this.state.timeRemaining.secs === '00') {
        newTimeRemaining.secs = 59
      } else {
        newTimeRemaining.secs = this.state.timeRemaining.secs -  1
      }
    }
    this.setState({timeRemaining: newTimeRemaining})
  },
  start: function() {
    this.interval = setInterval(this.tick, 1000)
  },
  pause: function() {
    clearInterval(this.interval)
  },
  next: function() {
    clearInterval(this.interval)
    this.setState({timeRemaining: 1500})
  },
  componentWillUnmount: function() {
    clearInterval(this.interval)
  },
  render: function() {
    return (

{this.state.timeRemaining.mins}:{this.state.timeRemaining.secs}

            <button type="button" className="btn btn-default btn-lg" onClick={this.start}>Start</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.pause}>Pause</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.next}>Next</button>

Pomodoros

                  2

Work time

                  50:00

Break time

                  10:00

Breaks

                  1

        <form onSubmit={this.handleSubmit}>

            <input type="text" className="form-control" placeholder="Add new task" onChange={this.onChange} value={this.state.task} />

              <button className="btn btn-default" type="submit">{'Add #' + (this.state.tasksList.length + 1)}</button>

        </form>
        <TasksList tasksList={this.state.tasksList} />

    )
  },
})

ReactDOM.render(<Timer />, document.getElementById('app'))
<|endoftext|>


<commit_before>var counter;

function setup() {
    var canvas = createCanvas(400, 400);
    canvas.parent('play');
    counter = new Counter();
    counter.new();
}

function draw() {
    background(233, 0, 0);
    counter.draw();
}

function keyTyped() {
    if (key === ' ') {
        counter.new();
    }
}

function Counter () {
    this.objects = [];
    this.number = 0;

    this.new = function () {
        this.objects = [];
        this.number = random(1, 10);
        for(var i = 1; i < this.number; i++) {
            this.objects.push(createVector(random(40,360), random(40,360)));
        }
    }

    this.draw = function() {
        for(var i = 0; i < this.objects.length; i++) {
            var object = this.objects[i];
            ellipse(object.x, object.y, 80);
        }
    }
}<commit_msg>Circles should not overlap with each other<commit_after>var counter;

function setup() {
    var canvas = createCanvas(400, 400);
    canvas.parent('play');
    counter = new Counter();
    counter.new();
}

function draw() {
    background(233, 0, 0);
    counter.draw();
}

function keyTyped() {
    if (key === ' ') {
        counter.new();
    }
}

function Counter () {
    this.objects = [];
    this.number = 0;

    this.new = function () {
        this.objects = [];
        this.number = random(1, 10);
        while(this.objects.length < this.number - 1) {
            var newObject = createVector(random(45,355), random(45,355));

            if (this.objects.every(function(item){
                return p5.Vector.sub(item, newObject).mag() > 85;
            }))
            {
                this.objects.push(newObject);
            }
        }
    }

    this.draw = function() {
        for(var i = 0; i < this.objects.length; i++) {
            var object = this.objects[i];
            ellipse(object.x, object.y, 80);
        }
    }
}<|endoftext|>


<commit_before>dojo.provide("dijit.form._FormWidget");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated],
{
	/*
	Summary:
		_FormWidget's correspond to native HTML elements such as <checkbox> or <button>.
		Each _FormWidget represents a single HTML element.

		All these widgets should have these attributes just like native HTML input elements.
		You can set them during widget construction.

		They also share some common methods.
	*/

	// baseClass: String
	//		Root CSS class of the widget (ex: dijitTextBox), used to add CSS classes of widget
	//		(ex: "dijitTextBox dijitTextBoxInvalid dijitTextBoxFocused dijitTextBoxInvalidFocused")
	//		See _setStateClass().
	baseClass: "",

	// name: String
	//		Name used when submitting form; same as "name" attribute or plain HTML elements
	name: "",

	// alt: String
	//		Corresponds to the native HTML <input> element's attribute.
	alt: "",

	// value: String
	//		Corresponds to the native HTML <input> element's attribute.
	value: "",

	// type: String
	//		Corresponds to the native HTML <input> element's attribute.
	type: "text",

	// tabIndex: Integer
	//		Order fields are traversed when user hits the tab key
	tabIndex: "0",

	// disabled: Boolean
	//		Should this widget respond to user input?
	//		In markup, this is specified as "disabled='disabled'", or just "disabled".
	disabled: false,

	// readOnly: Boolean
	//		Should this widget respond to user input?
	//		In markup, this is specified as "readOnly".
	//		Similar to disabled except readOnly form values are submitted
	readOnly: false,

	// intermediateChanges: Boolean
	//		Fires onChange for each value change or only on demand
	intermediateChanges: false,

	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
	// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
	// directly in the template as read by the parser in order to function. IE is known to specifically
	// require the 'name' attribute at element creation time.
	attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap),
		{value:"focusNode", disabled:"focusNode", readOnly:"focusNode", id:"focusNode", tabIndex:"focusNode", alt:"focusNode"}),

	setAttribute: function(/*String*/ attr, /*anything*/ value){
		this.inherited(arguments);
		switch(attr){
			case "disabled":
				var tabIndexNode = this[this.attributeMap['tabIndex']||'domNode'];
				if(value){
					//reset those, because after the domNode is disabled, we can no longer receive
					//mouse related events, see #4200
					this._hovering = false;
					this._active = false;
					// remove the tabIndex, especially for FF
					tabIndexNode.removeAttribute('tabIndex');
				}else{
					tabIndexNode.setAttribute('tabIndex', this.tabIndex);
				}
				dijit.setWaiState(this[this.attributeMap['disabled']||'domNode'], "disabled", value);
				this._setStateClass();
		}
	},

	setDisabled: function(/*Boolean*/ disabled){
		// summary:
		//		Set disabled state of widget (Deprecated).
		dojo.deprecated("setDisabled("+disabled+") is deprecated. Use attr('disabled',"+disabled+") instead.", "", "2.0");
		this.setAttribute('disabled', disabled);
	},

	_onFocus: function(e){
		dijit.scrollIntoView(this.domNode);
		this.inherited(arguments);
	},

	_onMouse : function(/*Event*/ event){
		// summary:
		//	Sets _hovering, _active, and stateModifier properties depending on mouse state,
		//	then calls setStateClass() to set appropriate CSS classes for this.domNode.
		//
		//	To get a different CSS class for hover, send onmouseover and onmouseout events to this method.
		//	To get a different CSS class while mouse button is depressed, send onmousedown to this method.

		var mouseNode = event.currentTarget;
		if(mouseNode && mouseNode.getAttribute){
			this.stateModifier = mouseNode.getAttribute("stateModifier") || "";
		}

		if(!this.disabled){
			switch(event.type){
				case "mouseenter":
				case "mouseover":
					this._hovering = true;
					this._active = this._mouseDown;
					break;

				case "mouseout":
				case "mouseleave":
					this._hovering = false;
					this._active = false;
					break;

				case "mousedown" :
					this._active = true;
					this._mouseDown = true;
					// set a global event to handle mouseup, so it fires properly
					//	even if the cursor leaves the button
					var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
						//if user clicks on the button, even if the mouse is released outside of it,
						//this button should get focus (which mimics native browser buttons)
						if(this._mouseDown && this.isFocusable()){
							this.focus();
						}
						this._active = false;
						this._mouseDown = false;
						this._setStateClass();
						this.disconnect(mouseUpConnector);
					});
					break;
			}
			this._setStateClass();
		}
	},

	isFocusable: function(){
		return !this.disabled && !this.readOnly && this.focusNode && (dojo.style(this.domNode, "display") != "none");
	},

	focus: function(){
		dijit.focus(this.focusNode);
	},

	_setStateClass: function(){
		// summary
		//	Update the visual state of the widget by setting the css classes on this.domNode
		//  (or this.stateNode if defined) by combining this.baseClass with
		//	various suffixes that represent the current widget state(s).
		//
		//	In the case where a widget has multiple
		//	states, it sets the class based on all possible
		//  combinations.  For example, an invalid form widget that is being hovered
		//	will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
		//
		//	For complex widgets with multiple regions, there can be various hover/active states,
		//	such as "Hover" or "CloseButtonHover" (for tab buttons).
		//	This is controlled by a stateModifier="CloseButton" attribute on the close button node.
		//
		//	The widget may have one or more of the following states, determined
		//	by this.state, this.checked, this.valid, and this.selected:
		//		Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
		//		Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
		//		Selected - ex: currently selected tab will have this.selected==true
		//
		//	In addition, it may have one or more of the following states,
		//	based on this.disabled and flags set in _onMouse (this._active, this._hovering, this._focused):
		//		Disabled	- if the widget is disabled
		//		Active		- if the mouse (or space/enter key?) is being pressed down
		//		Focused		- if the widget has focus
		//		Hover		- if the mouse is over the widget

		// Get original (non state related, non baseClass related) class specified in template
		if(!("staticClass" in this)){
			this.staticClass = (this.stateNode||this.domNode).className;
		}

		// Compute new set of classes
		var classes = this.baseClass.split(" ");

		function multiply(modifier){
			classes=classes.concat(dojo.map(classes, function(c){ return c+modifier; }), "dijit"+modifier);
		}

		if(this.checked){
			multiply("Checked");
		}
		if(this.state){
			multiply(this.state);
		}
		if(this.selected){
			multiply("Selected");
		}

		if(this.disabled){
			multiply("Disabled");
		}else if(this.readOnly){
			multiply("ReadOnly");
		}else if(this._active){
			multiply(this.stateModifier+"Active");
		}else{
			if(this._focused){
				multiply("Focused");
			}
			if(this._hovering){
				multiply(this.stateModifier+"Hover");
			}
		}

		(this.stateNode || this.domNode).className = this.staticClass + " " + classes.join(" ");
	},

	compare: function(/*anything*/val1, /*anything*/val2){
		// summary: compare 2 values
		if((typeof val1 == "number") && (typeof val2 == "number")){
			return (isNaN(val1) && isNaN(val2))? 0 : (val1-val2);
		}else if(val1 > val2){ return 1; }
		else if(val1 < val2){ return -1; }
		else { return 0; }
	},

	onChange: function(newValue){
		// summary: callback when value is changed
	},

	_onChangeActive: false,

	_handleOnChange: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
		// summary: set the value of the widget.
		this._lastValue = newValue;
		if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
			// this block executes not for a change, but during initialization,
			// and is used to store away the original value (or for ToggleButton, the original checked state)
			this._resetValue = this._lastValueReported = newValue;
		}
		if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&
			((typeof newValue != typeof this._lastValueReported) ||
				this.compare(newValue, this._lastValueReported) != 0)){
			this._lastValueReported = newValue;
			if(this._onChangeActive){ this.onChange(newValue); }
		}
	},

	create: function(){
		this.inherited(arguments);
		this._onChangeActive = true;
		this._setStateClass();
	},

	destroy: function(){
		if(this._layoutHackHandle){
			clearTimeout(this._layoutHackHandle);
		}
		this.inherited(arguments);
	},

	setValue: function(/*String*/ value){
		dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use attr('value',"+value+") instead.", "", "2.0");
		this.setAttribute('value', value);
	},

	_getValueDeprecated: true, // Form uses this, remove when getValue is removed
	getValue: function(){
		dojo.deprecated("dijit.form._FormWidget:getValue() is deprecated.  Use widget.value instead.", "", "2.0");
		return this.value;
	},

	_layoutHack: function(){
		// summary: work around table sizing bugs on FF2 by forcing redraw
		if(dojo.isFF == 2){
			var node=this.domNode;
			var old = node.style.opacity;
			node.style.opacity = "0.999";
			this._layoutHackHandle = setTimeout(dojo.hitch(this, function(){
				this._layoutHackHandle = null;
				node.style.opacity = old;
			}), 0);
		}
	}
});

dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
{
	/*
	Summary:
		_FormValueWidget's correspond to native HTML elements such as <input> or <select> that have user changeable values.
		Each _ValueWidget represents a single input value, and has a (possibly hidden) <input> element,
		to which it serializes its input value, so that form submission (either normal submission or via FormBind?)
		works as expected.
	*/

	// TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,
	// so maybe {value: ""} is so the value *doesn't* get copied to focusNode?
	// Seems like we really want value removed from attributeMap altogether
	// (although there's no easy way to do that now)
	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap),
		{value:""}),

	postCreate: function(){
		if(dojo.isIE || dojo.isSafari){ // IE won't stop the event with keypress and Safari won't send an ESCAPE to keypress at all
			this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
		}
		this.setValue(this.value, null);
	},

	setValue: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
		// summary: set the value of the widget.
		this.value = newValue;
		this._handleOnChange(newValue, priorityChange);
	},

	_getValueDeprecated: false, // remove when _FormWidget:getValue is removed
	getValue: function(){
		// summary: get the value of the widget.
		return this._lastValue;
	},

	undo: function(){
		// summary: restore the value to the last value passed to onChange
		this.setValue(this._lastValueReported, false);
	},

	reset: function(){
		this._hasBeenBlurred = false;
		this.setValue(this._resetValue, true);
	},

	_valueChanged: function(){
		var v = this.getValue();
		var lv = this._lastValueReported;
		// Equality comparison of objects such as dates are done by reference so
		// two distinct objects are != even if they have the same data. So use
		// toStrings in case the values are objects.
		return ((v !== null && (v !== undefined) && v.toString)?v.toString():'') !== ((lv !== null && (lv !== undefined) && lv.toString)?lv.toString():'');
	},

	_onKeyDown: function(e){
		if(e.keyCode == dojo.keys.ESCAPE && !e.ctrlKey && !e.altKey){
			var te;
			if(dojo.isIE){
				e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
				te = document.createEventObject();
				te.keyCode = dojo.keys.ESCAPE;
				te.shiftKey = e.shiftKey;
				e.srcElement.fireEvent('onkeypress', te);
			}else if(dojo.isSafari){ // ESCAPE needs help making it into keypress
				te = document.createEvent('Events');
				te.initEvent('keypress', true, true);
				te.keyCode = dojo.keys.ESCAPE;
				te.shiftKey = e.shiftKey;
				e.target.dispatchEvent(te);
			}
		}
	},

	_onKeyPress: function(e){
		if(e.charOrCode == dojo.keys.ESCAPE && !e.ctrlKey && !e.altKey && this._valueChanged()){
			this.undo();
			dojo.stopEvent(e);
			return false;
		}else if(this.intermediateChanges){
			var _this = this;
			// the setTimeout allows the key to post to the widget input box
			setTimeout(function(){ _this._handleOnChange(_this.getValue(), false); }, 0);
		}
		return true;
	}
});
<commit_msg>Support attr('value') and deprecate myWidget.getValue()/myWidget.value for form widgets. Refs #7244 !strict<commit_after>dojo.provide("dijit.form._FormWidget");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated],
{
	/*
	Summary:
		_FormWidget's correspond to native HTML elements such as <checkbox> or <button>.
		Each _FormWidget represents a single HTML element.

		All these widgets should have these attributes just like native HTML input elements.
		You can set them during widget construction.

		They also share some common methods.
	*/

	// baseClass: String
	//		Root CSS class of the widget (ex: dijitTextBox), used to add CSS classes of widget
	//		(ex: "dijitTextBox dijitTextBoxInvalid dijitTextBoxFocused dijitTextBoxInvalidFocused")
	//		See _setStateClass().
	baseClass: "",

	// name: String
	//		Name used when submitting form; same as "name" attribute or plain HTML elements
	name: "",

	// alt: String
	//		Corresponds to the native HTML <input> element's attribute.
	alt: "",

	// value: String
	//		Corresponds to the native HTML <input> element's attribute.
	value: "",

	// type: String
	//		Corresponds to the native HTML <input> element's attribute.
	type: "text",

	// tabIndex: Integer
	//		Order fields are traversed when user hits the tab key
	tabIndex: "0",

	// disabled: Boolean
	//		Should this widget respond to user input?
	//		In markup, this is specified as "disabled='disabled'", or just "disabled".
	disabled: false,

	// readOnly: Boolean
	//		Should this widget respond to user input?
	//		In markup, this is specified as "readOnly".
	//		Similar to disabled except readOnly form values are submitted
	readOnly: false,

	// intermediateChanges: Boolean
	//		Fires onChange for each value change or only on demand
	intermediateChanges: false,

	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
	// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
	// directly in the template as read by the parser in order to function. IE is known to specifically
	// require the 'name' attribute at element creation time.
	attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap),
		{value:"focusNode", disabled:"focusNode", readOnly:"focusNode", id:"focusNode", tabIndex:"focusNode", alt:"focusNode"}),

	setAttribute: function(/*String*/ attr, /*anything*/ value){
		this.inherited(arguments);
		switch(attr){
			case "disabled":
				var tabIndexNode = this[this.attributeMap['tabIndex']||'domNode'];
				if(value){
					//reset those, because after the domNode is disabled, we can no longer receive
					//mouse related events, see #4200
					this._hovering = false;
					this._active = false;
					// remove the tabIndex, especially for FF
					tabIndexNode.removeAttribute('tabIndex');
				}else{
					tabIndexNode.setAttribute('tabIndex', this.tabIndex);
				}
				dijit.setWaiState(this[this.attributeMap['disabled']||'domNode'], "disabled", value);
				this._setStateClass();
		}
	},

	setDisabled: function(/*Boolean*/ disabled){
		// summary:
		//		Set disabled state of widget (Deprecated).
		dojo.deprecated("setDisabled("+disabled+") is deprecated. Use attr('disabled',"+disabled+") instead.", "", "2.0");
		this.setAttribute('disabled', disabled);
	},

	_onFocus: function(e){
		dijit.scrollIntoView(this.domNode);
		this.inherited(arguments);
	},

	_onMouse : function(/*Event*/ event){
		// summary:
		//	Sets _hovering, _active, and stateModifier properties depending on mouse state,
		//	then calls setStateClass() to set appropriate CSS classes for this.domNode.
		//
		//	To get a different CSS class for hover, send onmouseover and onmouseout events to this method.
		//	To get a different CSS class while mouse button is depressed, send onmousedown to this method.

		var mouseNode = event.currentTarget;
		if(mouseNode && mouseNode.getAttribute){
			this.stateModifier = mouseNode.getAttribute("stateModifier") || "";
		}

		if(!this.disabled){
			switch(event.type){
				case "mouseenter":
				case "mouseover":
					this._hovering = true;
					this._active = this._mouseDown;
					break;

				case "mouseout":
				case "mouseleave":
					this._hovering = false;
					this._active = false;
					break;

				case "mousedown" :
					this._active = true;
					this._mouseDown = true;
					// set a global event to handle mouseup, so it fires properly
					//	even if the cursor leaves the button
					var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
						//if user clicks on the button, even if the mouse is released outside of it,
						//this button should get focus (which mimics native browser buttons)
						if(this._mouseDown && this.isFocusable()){
							this.focus();
						}
						this._active = false;
						this._mouseDown = false;
						this._setStateClass();
						this.disconnect(mouseUpConnector);
					});
					break;
			}
			this._setStateClass();
		}
	},

	isFocusable: function(){
		return !this.disabled && !this.readOnly && this.focusNode && (dojo.style(this.domNode, "display") != "none");
	},

	focus: function(){
		dijit.focus(this.focusNode);
	},

	_setStateClass: function(){
		// summary
		//	Update the visual state of the widget by setting the css classes on this.domNode
		//  (or this.stateNode if defined) by combining this.baseClass with
		//	various suffixes that represent the current widget state(s).
		//
		//	In the case where a widget has multiple
		//	states, it sets the class based on all possible
		//  combinations.  For example, an invalid form widget that is being hovered
		//	will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
		//
		//	For complex widgets with multiple regions, there can be various hover/active states,
		//	such as "Hover" or "CloseButtonHover" (for tab buttons).
		//	This is controlled by a stateModifier="CloseButton" attribute on the close button node.
		//
		//	The widget may have one or more of the following states, determined
		//	by this.state, this.checked, this.valid, and this.selected:
		//		Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
		//		Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
		//		Selected - ex: currently selected tab will have this.selected==true
		//
		//	In addition, it may have one or more of the following states,
		//	based on this.disabled and flags set in _onMouse (this._active, this._hovering, this._focused):
		//		Disabled	- if the widget is disabled
		//		Active		- if the mouse (or space/enter key?) is being pressed down
		//		Focused		- if the widget has focus
		//		Hover		- if the mouse is over the widget

		// Get original (non state related, non baseClass related) class specified in template
		if(!("staticClass" in this)){
			this.staticClass = (this.stateNode||this.domNode).className;
		}

		// Compute new set of classes
		var classes = this.baseClass.split(" ");

		function multiply(modifier){
			classes=classes.concat(dojo.map(classes, function(c){ return c+modifier; }), "dijit"+modifier);
		}

		if(this.checked){
			multiply("Checked");
		}
		if(this.state){
			multiply(this.state);
		}
		if(this.selected){
			multiply("Selected");
		}

		if(this.disabled){
			multiply("Disabled");
		}else if(this.readOnly){
			multiply("ReadOnly");
		}else if(this._active){
			multiply(this.stateModifier+"Active");
		}else{
			if(this._focused){
				multiply("Focused");
			}
			if(this._hovering){
				multiply(this.stateModifier+"Hover");
			}
		}

		(this.stateNode || this.domNode).className = this.staticClass + " " + classes.join(" ");
	},

	compare: function(/*anything*/val1, /*anything*/val2){
		// summary: compare 2 values
		if((typeof val1 == "number") && (typeof val2 == "number")){
			return (isNaN(val1) && isNaN(val2))? 0 : (val1-val2);
		}else if(val1 > val2){ return 1; }
		else if(val1 < val2){ return -1; }
		else { return 0; }
	},

	onChange: function(newValue){
		// summary: callback when value is changed
	},

	_onChangeActive: false,

	_handleOnChange: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
		// summary: set the value of the widget.
		this._lastValue = newValue;
		if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
			// this block executes not for a change, but during initialization,
			// and is used to store away the original value (or for ToggleButton, the original checked state)
			this._resetValue = this._lastValueReported = newValue;
		}
		if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&
			((typeof newValue != typeof this._lastValueReported) ||
				this.compare(newValue, this._lastValueReported) != 0)){
			this._lastValueReported = newValue;
			if(this._onChangeActive){ this.onChange(newValue); }
		}
	},

	create: function(){
		this.inherited(arguments);
		this._onChangeActive = true;
		this._setStateClass();
	},

	destroy: function(){
		if(this._layoutHackHandle){
			clearTimeout(this._layoutHackHandle);
		}
		this.inherited(arguments);
	},

	setValue: function(/*String*/ value){
		dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use attr('value',"+value+") instead.", "", "2.0");
		this.setAttribute('value', value);
	},

	getValue: function(){
		dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use attr('value') instead.", "", "2.0");
		return this.attr('value');
	},

	_layoutHack: function(){
		// summary: work around table sizing bugs on FF2 by forcing redraw
		if(dojo.isFF == 2){
			var node=this.domNode;
			var old = node.style.opacity;
			node.style.opacity = "0.999";
			this._layoutHackHandle = setTimeout(dojo.hitch(this, function(){
				this._layoutHackHandle = null;
				node.style.opacity = old;
			}), 0);
		}
	}
});

dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
{
	/*
	Summary:
		_FormValueWidget's correspond to native HTML elements such as <input> or <select> that have user changeable values.
		Each _ValueWidget represents a single input value, and has a (possibly hidden) <input> element,
		to which it serializes its input value, so that form submission (either normal submission or via FormBind?)
		works as expected.
	*/

	// TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,
	// so maybe {value: ""} is so the value *doesn't* get copied to focusNode?
	// Seems like we really want value removed from attributeMap altogether
	// (although there's no easy way to do that now)
	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap),
		{value:""}),

	postCreate: function(){
		if(dojo.isIE || dojo.isSafari){ // IE won't stop the event with keypress and Safari won't send an ESCAPE to keypress at all
			this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
		}
		this.setValue(this.value, null);
	},

	setValue: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
		// summary: set the value of the widget.
		this.value = newValue;
		this._handleOnChange(newValue, priorityChange);
	},

	_attrGetValue: function(/*String*/ value){
		// summary:
		//		Hook so attr('value') works.
		return this._lastValue;
	},

	undo: function(){
		// summary: restore the value to the last value passed to onChange
		this.setValue(this._lastValueReported, false);
	},

	reset: function(){
		this._hasBeenBlurred = false;
		this.setValue(this._resetValue, true);
	},

	_valueChanged: function(){
		var v = this.attr('value');
		var lv = this._lastValueReported;
		// Equality comparison of objects such as dates are done by reference so
		// two distinct objects are != even if they have the same data. So use
		// toStrings in case the values are objects.
		return ((v !== null && (v !== undefined) && v.toString)?v.toString():'') !== ((lv !== null && (lv !== undefined) && lv.toString)?lv.toString():'');
	},

	_onKeyDown: function(e){
		if(e.keyCode == dojo.keys.ESCAPE && !e.ctrlKey && !e.altKey){
			var te;
			if(dojo.isIE){
				e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
				te = document.createEventObject();
				te.keyCode = dojo.keys.ESCAPE;
				te.shiftKey = e.shiftKey;
				e.srcElement.fireEvent('onkeypress', te);
			}else if(dojo.isSafari){ // ESCAPE needs help making it into keypress
				te = document.createEvent('Events');
				te.initEvent('keypress', true, true);
				te.keyCode = dojo.keys.ESCAPE;
				te.shiftKey = e.shiftKey;
				e.target.dispatchEvent(te);
			}
		}
	},

	_onKeyPress: function(e){
		if(e.charOrCode == dojo.keys.ESCAPE && !e.ctrlKey && !e.altKey && this._valueChanged()){
			this.undo();
			dojo.stopEvent(e);
			return false;
		}else if(this.intermediateChanges){
			var _this = this;
			// the setTimeout allows the key to post to the widget input box
			setTimeout(function(){ _this._handleOnChange(_this.attr('value'), false); }, 0);
		}
		return true;
	}
});
<|endoftext|>


<commit_before>{
    'use strict';

    const electron = require('electron');
    const app = electron.app;
    const BrowserWindow = electron.BrowserWindow;

    // simple parameters initialization
    let electronConfig = {
        "URL_LAUNCHER_TOUCH": (process.env.URL_LAUNCHER_TOUCH == null) ? 0 : parseInt(process.env.URL_LAUNCHER_TOUCH),
        "URL_LAUNCHER_TOUCH_SIMULATE": (process.env.URL_LAUNCHER_TOUCH_SIMULATE == null) ? 0 : parseInt(process.env.URL_LAUNCHER_TOUCH_SIMULATE),
        "URL_LAUNCHER_FRAME": (process.env.URL_LAUNCHER_FRAME == null) ? 0 : parseInt(process.env.URL_LAUNCHER_FRAME),
        "URL_LAUNCHER_KIOSK": (process.env.URL_LAUNCHER_KIOSK == null) ? 1 : parseInt(process.env.URL_LAUNCHER_KIOSK),
        "URL_LAUNCHER_NODE": (process.env.URL_LAUNCHER_NODE == null) ? 0 : parseInt(process.env.URL_LAUNCHER_NODE),
        "URL_LAUNCHER_WIDTH": (process.env.URL_LAUNCHER_WIDTH == null) ? 1920 : parseInt(process.env.URL_LAUNCHER_WIDTH),
        "URL_LAUNCHER_HEIGHT": (process.env.URL_LAUNCHER_HEIGHT == null) ? 1080 : parseInt(process.env.URL_LAUNCHER_HEIGHT),
        "URL_LAUNCHER_TITLE": (process.env.URL_LAUNCHER_TITLE == null) ? "RESIN.IO" : process.env.URL_LAUNCHER_TITLE,
        "URL_LAUNCHER_CONSOLE": (process.env.URL_LAUNCHER_CONSOLE == null) ? 0 : parseInt(process.env.URL_LAUNCHER_CONSOLE),
        "URL_LAUNCHER_URL": (process.env.URL_LAUNCHER_URL == null) ? "file:////usr/src/app/data/index.html" : process.env.URL_LAUNCHER_URL,
        "URL_LAUNCHER_ZOOM": (process.env.URL_LAUNCHER_ZOOM == null) ? 1.0 : parseFloat(process.env.URL_LAUNCHER_ZOOM),
        "URL_LAUNCHER_OVERLAY_SCROLLBARS": (process.env.URL_LAUNCHER_OVERLAY_SCROLLBARS == null) ? 0 : parseInt(process.env.URL_LAUNCHER_OVERLAY_SCROLLBARS)
    };

    let window = null;

    // enable touch events if your device supports them
    if (electronConfig.URL_LAUNCHER_TOUCH) {
        app.commandLine.appendSwitch("--touch-devices");
    }
    // simulate touch events - might be useful for touchscreen with partial driver support
    if (electronConfig.URL_LAUNCHER_TOUCH_SIMULATE) {
        app.commandLine.appendSwitch("--simulate-touch-screen-with-mouse");
    }

    /*
      we initialize our application display as a callback of the electronJS "ready" event
    */
    app.on('ready', () => {

        // here we actually configure the behavour of electronJS
        window = new BrowserWindow({
            width: parseInt(electronConfig.URL_LAUNCHER_WIDTH),
            height: parseInt(electronConfig.URL_LAUNCHER_HEIGHT),
            frame: (electronConfig.URL_LAUNCHER_FRAME) ? true : false,
            title: electronConfig.URL_LAUNCHER_TITLE,
            kiosk: (electronConfig.URL_LAUNCHER_KIOSK) ? true : false,
            webPreferences: {
                nodeIntegration: (electronConfig.URL_LAUNCHER_NODE) ? true : false,
                zoomFactor: electronConfig.URL_LAUNCHER_ZOOM,
                overlayScrollbars: (electronConfig.URL_LAUNCHER_OVERLAY_SCROLLBARS) ? true : false
            }
        });

        window.webContents.on('did-finish-load', () => {
            setTimeout(() => {
                window.show();
            }, 300);

        });

        // if the env-var is set to true, a portion of the screen will be dedicated to the chrome-dev-tools
        if (electronConfig.URL_LAUNCHER_CONSOLE) {
            window.openDevTools();
        }

        // the big red button, here we go
        window.loadURL(electronConfig.URL_LAUNCHER_URL);
    });
}
<commit_msg>deal only with legal calues<commit_after>{
    'use strict';

    const electron = require('electron');
    const app = electron.app;
    const BrowserWindow = electron.BrowserWindow;

    // simple parameters initialization
    let electronConfig = {
        "URL_LAUNCHER_TOUCH": (process.env.URL_LAUNCHER_TOUCH == null || process.env.URL_LAUNCHER_TOUCH != '0' || process.env.URL_LAUNCHER_TOUCH != '1') ? 0 : parseInt(process.env.URL_LAUNCHER_TOUCH),
        "URL_LAUNCHER_TOUCH_SIMULATE": (process.env.URL_LAUNCHER_TOUCH_SIMULATE == null || process.env.URL_LAUNCHER_TOUCH_SIMULATE != '0' || process.env.URL_LAUNCHER_TOUCH_SIMULATE != '1') ? 0 : parseInt(process.env.URL_LAUNCHER_TOUCH_SIMULATE),
        "URL_LAUNCHER_FRAME": (process.env.URL_LAUNCHER_FRAME == null || process.env.URL_LAUNCHER_FRAME != '0' || process.env.URL_LAUNCHER_FRAME != '1') ? 0 : parseInt(process.env.URL_LAUNCHER_FRAME),
        "URL_LAUNCHER_KIOSK": (process.env.URL_LAUNCHER_KIOSK == null || process.env.URL_LAUNCHER_KIOSK != '0' || process.env.URL_LAUNCHER_KIOSK != '1') ? 1 : parseInt(process.env.URL_LAUNCHER_KIOSK),
        "URL_LAUNCHER_NODE": (process.env.URL_LAUNCHER_NODE == null || process.env.URL_LAUNCHER_NODE != '0' || process.env.URL_LAUNCHER_NODE != '1') ? 0 : parseInt(process.env.URL_LAUNCHER_NODE),
        "URL_LAUNCHER_WIDTH": (process.env.URL_LAUNCHER_WIDTH == null) ? 1920 : parseInt(process.env.URL_LAUNCHER_WIDTH),
        "URL_LAUNCHER_HEIGHT": (process.env.URL_LAUNCHER_HEIGHT == null) ? 1080 : parseInt(process.env.URL_LAUNCHER_HEIGHT),
        "URL_LAUNCHER_TITLE": (process.env.URL_LAUNCHER_TITLE == null) ? "RESIN.IO" : process.env.URL_LAUNCHER_TITLE,
        "URL_LAUNCHER_CONSOLE": (process.env.URL_LAUNCHER_CONSOLE == null || process.env.URL_LAUNCHER_CONSOLE != '0' || process.env.URL_LAUNCHER_CONSOLE != '1') ? 0 : parseInt(process.env.URL_LAUNCHER_CONSOLE),
        "URL_LAUNCHER_URL": (process.env.URL_LAUNCHER_URL == null) ? "file:////usr/src/app/data/index.html" : process.env.URL_LAUNCHER_URL,
        "URL_LAUNCHER_ZOOM": (process.env.URL_LAUNCHER_ZOOM == null) ? 1.0 : parseFloat(process.env.URL_LAUNCHER_ZOOM),
        "URL_LAUNCHER_OVERLAY_SCROLLBARS": (process.env.URL_LAUNCHER_OVERLAY_SCROLLBARS == null || process.env.URL_LAUNCHER_OVERLAY_SCROLLBARS != '0' || process.env.URL_LAUNCHER_OVERLAY_SCROLLBARS != '1') ? 0 : parseInt(process.env.URL_LAUNCHER_OVERLAY_SCROLLBARS)
    };

    let window = null;

    // enable touch events if your device supports them
    if (electronConfig.URL_LAUNCHER_TOUCH) {
        app.commandLine.appendSwitch("--touch-devices");
    }
    // simulate touch events - might be useful for touchscreen with partial driver support
    if (electronConfig.URL_LAUNCHER_TOUCH_SIMULATE) {
        app.commandLine.appendSwitch("--simulate-touch-screen-with-mouse");
    }

    /*
      we initialize our application display as a callback of the electronJS "ready" event
    */
    app.on('ready', () => {

        // here we actually configure the behavour of electronJS
        window = new BrowserWindow({
            width: parseInt(electronConfig.URL_LAUNCHER_WIDTH),
            height: parseInt(electronConfig.URL_LAUNCHER_HEIGHT),
            frame: (electronConfig.URL_LAUNCHER_FRAME) ? true : false,
            title: electronConfig.URL_LAUNCHER_TITLE,
            kiosk: (electronConfig.URL_LAUNCHER_KIOSK) ? true : false,
            webPreferences: {
                nodeIntegration: (electronConfig.URL_LAUNCHER_NODE) ? true : false,
                zoomFactor: electronConfig.URL_LAUNCHER_ZOOM,
                overlayScrollbars: (electronConfig.URL_LAUNCHER_OVERLAY_SCROLLBARS) ? true : false
            }
        });

        window.webContents.on('did-finish-load', () => {
            setTimeout(() => {
                window.show();
            }, 300);

        });

        // if the env-var is set to true, a portion of the screen will be dedicated to the chrome-dev-tools
        if (electronConfig.URL_LAUNCHER_CONSOLE) {
            window.openDevTools();
        }

        // the big red button, here we go
        window.loadURL(electronConfig.URL_LAUNCHER_URL);
    });
}
<|endoftext|>