<commit_before>// Gimme a Github object! Please.
function github() {
  return new Github({
    token: $.cookie('oauth-token'),
    username: $.cookie('username'),
    auth: "oauth"
  });
}

var currentRepo = {
  user: null,
  repo: null,
  instance: null
};

// Return a random string
// -------

function randomString() {
  var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
  var string_length = 8;
  var randomstring = '';
  for (var i=0; i<string_length; i++) {
    var rnum = Math.floor(Math.random() * chars.length);
    randomstring += chars.substring(rnum,rnum+1);
  }
  return randomstring;
}

// Smart caching (needed for managing subsequent updates)
// -------

function getRepo(user, repo) {
  if (currentRepo.user === user && currentRepo.repo === repo) {
    return currentRepo.instance; // Cached
  }

  currentRepo = {
    user: user,
    repo: repo,
    instance: github().getRepo(user, repo)
  };
  return currentRepo.instance;
}

// Authentication
// -------

function authenticate() {
  if ($.cookie("oauth-token")) return window.authenticated = true;
  var match = window.location.href.match(/\?code=([a-z0-9]*)/);

  // Handle Code
  if (match) {
    $.getJSON('{{site.gatekeeper_url}}/authenticate/'+match[1], function(data) {
      $.cookie('oauth-token', data.token);
      window.authenticated = true;
      // Adjust URL
      var regex = new RegExp("\\?code="+match[1]);
      window.location.href = window.location.href.replace(regex, '').replace('&state=', '');
    });
    return false;
  } else {
    return true;
  }
}

function logout() {
  window.authenticated = false;
  $.cookie("oauth-token", null);
}

// Load Application
// -------
//
// Load everything that's needed for the app + header

function loadApplication(cb) {

  if (window.authenticated) {
    $.ajax({
      type: "GET",
      url: 'https://api.github.com/user',
      dataType: 'json',
      contentType: 'application/x-www-form-urlencoded',
      headers : { Authorization : 'token ' + $.cookie('oauth-token') },
      success: function(res) {
        $.cookie("avatar", res.avatar_url);
        $.cookie("username", res.login);
        app.username = res.login;

        var user = github().getUser();
        var owners = {};

        user.repos(function(err, repos) {
          user.orgs(function(err, orgs) {
            _.each(repos, function(r) {
              owners[r.owner.login] = owners[r.owner.login] ? owners[r.owner.login].concat([r]) : [r];
            });

            cb(null, {
              "available_repos": repos,
              "organizations": orgs,
              "owners": owners
            });
          });
        });

      },
      error: function(err) {
        cb('error', { "available_repos": [], "owners": {} });
      }
    });

  } else {
    cb(null, { "available_repos": [], "owners": {} });
  }
}

// Load Repos
// -------
//
// List all available repositories for a certain user

function loadRepos(username, cb) {
  var user = github().getUser();

  user.show(username, function(err, u) {
    var owners = {};
    if (u.type.toLowerCase() === "user") {
      user.userRepos(username, function(err, repos) {
        cb(null, { "repos": repos, user: u });
      });
    } else {
      user.orgRepos(username, function(err, repos) {
        cb(null, { "repos": repos, user: u });
      });
    }
  });
}

// Load Branches
// -------
//
// List all available branches of a repository

function loadBranches(user, repo, cb) {
  var repo = getRepo(user, repo);

  repo.listBranches(function(err, branches) {
    cb(err, branches);
  });
}

// Get files from a tree based on a given path and searchstr
// -------

function getFiles(tree, path, searchstr) {
  var pathMatches = 0;
  function matchesPath(file) {
    if (file.path === path) return false; // skip current path
    var match = file.path.match(new RegExp("^"+path+"(.*)$"));
    if (match) {
      return !!searchstr || match[1].split('/').length <= (path ? 2 : 1);
    }
    return false;
  }

  function matchesSearch(file) {
    if (!searchstr) return true;
    // Insert crazy search pattern match algorithm
    return file.path.toLowerCase().search(searchstr.toLowerCase()) >= 0;
  }

  // Filter
  var files = _.filter(tree, function(file) {
    var matchSearch = new RegExp("("+searchstr+")", "i");

    // Depending on search use full path or filename
    file.name = searchstr ? file.path : _.extractFilename(file.path)[1];

    // Scope name to current path
    file.name = file.name.replace(new RegExp("^"+path+"/?"), "");

    // Mark match
    file.name = file.name.replace(matchSearch, "$1");

    if (!matchesPath(file)) return false;
    pathMatches += 1;
    return matchesSearch(file);
  });

  // Sort by name
  files = _.sortBy(files, function(entry){
    return (entry.type === "tree" ? "A" : "B") + entry.path;
  });

  return {
    tree: tree,
    files: files,
    total: pathMatches
  }
}

// Load Posts
// -------
//
// List all postings for a given repo+branch+path plus load _config.yml

function loadPosts(user, reponame, branch, path, cb) {
  var repo = getRepo(user, reponame);

  function loadConfig(cb) {
    repo.read(branch, "_config.yml", function(err, data) {
      if (err) return cb(err);
      cb(null, jsyaml.load(data));
    });
  }

  function load(repodata) {
    loadConfig(function(err, config) {
      app.state.jekyll = !err;
      app.state.config = config;

      var root = config && config.prose && config.prose.rooturl ? config.prose.rooturl : "";
      if (!path) path = root;

      repo.getTree(branch+"?recursive=true", function(err, tree) {
        if (err) return cb("Not found");
        loadBranches(user, reponame, function(err, branches) {
          if (err) return cb("Branches couldn't be fetched");
          app.state.path = path ? path : "";
          app.state.branches = _.filter(branches, function(b) { return b !== branch });
          cb(null, getFiles(tree, path, ""));
        });
      });
    });
  }

  repo.show(function(err, repodata) {
    if (!branch) app.state.branch = branch = repodata.master_branch;
    app.state.permissions = repodata.permissions;
    load();
  });
}

// Serialize
// -------

function serialize(content, metadata) {
  if (metadata) {
    return ["---", metadata, "---"].join('\n')+'\n\n'+content;
  } else {
    return content;
  }
}

// Save File
// -------
//
// Store a file to GitHub

function saveFile(user, repo, branch, path, content, message, cb) {
  var repo = getRepo(user, repo);
  repo.write(branch, path, content, message, cb);
}

// Fork repository
// -------
//
// Creates a fork for the current user

function forkRepo(user, reponame, branch, cb) {
  var repo = getRepo(user, reponame);
  var forkedRepo = getRepo(app.username, reponame);

  // Wait until contents are ready.

  function onceReady(cb) {
    _.delay(function() {
      forkedRepo.contents("", function(err, contents) {
        contents ? cb() : onceReady(cb);
      });
    }, 500);
  }

  repo.fork(function(err) {
    onceReady(function() {
      repo.getRef("heads/"+branch, function(err, commitSha) {
        // Create temp branch
        forkedRepo.listBranches( function( unused, branches ){
          //find the lowest patch number
          i=1; while ($.inArray('prose-patch-'+i, branches)!=-1){ i++ }
          var refSpec = { "ref": "refs/heads/prose-patch-"+i, "sha": commitSha };
          forkedRepo.createRef(refSpec, cb);
        });
      });
    });
  });
}

// New pull request
// -------
//
// Creates a new pull request

function createPullRequest(user, repo, pull, cb) {
  var repo = getRepo(user, repo);

  repo.createPullRequest(pull, function(err) {
    cb();
  });
}

// Patch File
// -------
//
// Send a pull request on GitHub

function patchFile(user, repo, branch, path, content, message, cb) {
  forkRepo(user, repo, branch, function(err, info) {
    branch = info.ref.substring( info.ref.lastIndexOf('/') + 1);
    saveFile(app.username, repo, branch, path, content, message, function(err) {
      if (err) return cb(err);
      var pull = {
        title: message,
        body: "This pull request has been automatically generated by Prose.io.",
        base: app.state.branch,
        head: app.username + ":" + branch,
      };
      createPullRequest(app.state.user, app.state.repo, pull, cb);
    });
  });
}

// Delete Post
// -------

function deletePost(user, repo, branch, path, file, cb) {
  var repo = getRepo(user, repo);
  repo.remove(branch, _.filepath(path, file), cb);
}

// Move Post
// -------

function movePost(user, repo, branch, path, newPath, cb) {
  var repo = getRepo(user, repo);
  repo.move(branch, path, newPath, cb);
}

// New Post
// -------
//
// Prepare new empty post

function emptyPost(user, repo, branch, path, cb) {
  var rawMetadata = "layout: default\npublished: false";
  var metadata = {
    "layout": "default",
    "published": false,
  };

  var cfg = app.state.config
  if (cfg && cfg.prose && cfg.prose.metadata) {
    if (cfg.prose.metadata[path]) {
      rawMetadata = cfg.prose.metadata[path];
      try {
        metadata = jsyaml.load(rawMetadata);
        if (metadata.date=="CURRENT_DATETIME") {
            var current = (new Date()).format('Y-m-d H:i');
            metadata.date = current;
            rawMetadata = rawMetadata.replace("CURRENT_DATETIME", current);
        }
      } catch(err) {
        console.log('ERROR encoding YAML');
        // No-op
      }
    }
  }

  cb(null, {
    "metadata": metadata,
    "raw_metadata": rawMetadata,
    "content": "# How does it work?\n\nEnter Text in Markdown format.",
    "repo": repo,
    "path": path,
    "published": false,
    "persisted": false,
    "writeable": true,
    "file": new Date().format("Y-m-d")+"-your-filename.md"
  });
}

// Load Post
// -------
//
// List all postings for a given repository
// Looks into _posts/blog

function loadPost(user, repo, branch, path, file, cb) {
  var repo = getRepo(user, repo);

  repo.read(branch, path ? path + "/" + file : file, function(err, data, commit) {
    if (err) return cb(err);

    // Given a YAML front matter, determines published or not
    function published(metadata) {
      return !!metadata.match(/published: true/);
    }

    // Extract YAML from a post, trims whitespace
    function parse(content) {
      var content = content.replace(/\r\n/g, "\n"); // normalize a little bit

      function writeable() {
        return !!(app.state.permissions && app.state.permissions.push);
      }

      if (!_.hasMetadata(content)) return {
        raw_metadata: "",
        content: content,
        published: false,
        writeable: writeable()
      };

      var res = { raw_metadata: "", published: false, writeable: writeable() };
      res.content = content.replace(/^(---\n)((.|\n)*?)\n---\n?/, function(match, dashes, frontmatter) {
        res.raw_metadata = frontmatter;
        res.published = published(frontmatter);
        return "";
      }).trim();
      return res;
    }

    var post = parse(data);
    cb(err, _.extend(post, {
      "sha": commit,
      "markdown": _.markdown(file),
      "jekyll": _.hasMetadata(data),
      "repo": repo,
      "path": path,
      "file": file,
      "persisted": true
    }));
  });
}
<commit_msg>fixes #254<commit_after>// Gimme a Github object! Please.
function github() {
  return new Github({
    token: $.cookie('oauth-token'),
    username: $.cookie('username'),
    auth: "oauth"
  });
}

var currentRepo = {
  user: null,
  repo: null,
  instance: null
};

// Return a random string
// -------

function randomString() {
  var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
  var string_length = 8;
  var randomstring = '';
  for (var i=0; i<string_length; i++) {
    var rnum = Math.floor(Math.random() * chars.length);
    randomstring += chars.substring(rnum,rnum+1);
  }
  return randomstring;
}

// Smart caching (needed for managing subsequent updates)
// -------

function getRepo(user, repo) {
  if (currentRepo.user === user && currentRepo.repo === repo) {
    return currentRepo.instance; // Cached
  }

  currentRepo = {
    user: user,
    repo: repo,
    instance: github().getRepo(user, repo)
  };
  return currentRepo.instance;
}

// Authentication
// -------

function authenticate() {
  if ($.cookie("oauth-token")) return window.authenticated = true;
  var match = window.location.href.match(/\?code=([a-z0-9]*)/);

  // Handle Code
  if (match) {
    $.getJSON('{{site.gatekeeper_url}}/authenticate/'+match[1], function(data) {
      $.cookie('oauth-token', data.token);
      window.authenticated = true;
      // Adjust URL
      var regex = new RegExp("\\?code="+match[1]);
      window.location.href = window.location.href.replace(regex, '').replace('&state=', '');
    });
    return false;
  } else {
    return true;
  }
}

function logout() {
  window.authenticated = false;
  $.cookie("oauth-token", null);
}

// Load Application
// -------
//
// Load everything that's needed for the app + header

function loadApplication(cb) {

  if (window.authenticated) {
    $.ajax({
      type: "GET",
      url: 'https://api.github.com/user',
      dataType: 'json',
      contentType: 'application/x-www-form-urlencoded',
      headers : { Authorization : 'token ' + $.cookie('oauth-token') },
      success: function(res) {
        $.cookie("avatar", res.avatar_url);
        $.cookie("username", res.login);
        app.username = res.login;

        var user = github().getUser();
        var owners = {};

        user.repos(function(err, repos) {
          user.orgs(function(err, orgs) {
            _.each(repos, function(r) {
              owners[r.owner.login] = owners[r.owner.login] ? owners[r.owner.login].concat([r]) : [r];
            });

            cb(null, {
              "available_repos": repos,
              "organizations": orgs,
              "owners": owners
            });
          });
        });

      },
      error: function(err) {
        cb('error', { "available_repos": [], "owners": {} });
      }
    });

  } else {
    cb(null, { "available_repos": [], "owners": {} });
  }
}

// Load Repos
// -------
//
// List all available repositories for a certain user

function loadRepos(username, cb) {
  var user = github().getUser();

  user.show(username, function(err, u) {
    var owners = {};
    if (u.type.toLowerCase() === "user") {
      user.userRepos(username, function(err, repos) {
        cb(null, { "repos": repos, user: u });
      });
    } else {
      user.orgRepos(username, function(err, repos) {
        cb(null, { "repos": repos, user: u });
      });
    }
  });
}

// Load Branches
// -------
//
// List all available branches of a repository

function loadBranches(user, repo, cb) {
  var repo = getRepo(user, repo);

  repo.listBranches(function(err, branches) {
    cb(err, branches);
  });
}

// Get files from a tree based on a given path and searchstr
// -------

function getFiles(tree, path, searchstr) {
  debugger;

  var pathMatches = 0;
  function matchesPath(file) {
    if (file.path === path) return false; // skip current path
    var match = file.path.match(new RegExp("^"+path+"/(.*)$"));
    if (match) {
      return !!searchstr || match[1].split('/').length <= (path ? 2 : 1);
    }
    return false;
  }

  function matchesSearch(file) {
    if (!searchstr) return true;
    // Insert crazy search pattern match algorithm
    return file.path.toLowerCase().search(searchstr.toLowerCase()) >= 0;
  }

  // Filter
  var files = _.filter(tree, function(file) {
    var matchSearch = new RegExp("("+searchstr+")", "i");

    // Depending on search use full path or filename
    file.name = searchstr ? file.path : _.extractFilename(file.path)[1];

    // Scope name to current path
    file.name = file.name.replace(new RegExp("^"+path+"/?"), "");

    // Mark match if searchstr not empty
    if (searchstr.length) {
      file.name = file.name.replace(matchSearch, "$1");
    }

    if (!matchesPath(file)) return false;
    pathMatches += 1;
    return matchesSearch(file);
  });

  // Sort by name
  files = _.sortBy(files, function(entry){
    return (entry.type === "tree" ? "A" : "B") + entry.path;
  });

  return {
    tree: tree,
    files: files,
    total: pathMatches
  }
}

// Load Posts
// -------
//
// List all postings for a given repo+branch+path plus load _config.yml

function loadPosts(user, reponame, branch, path, cb) {
  var repo = getRepo(user, reponame);

  function loadConfig(cb) {
    repo.read(branch, "_config.yml", function(err, data) {
      if (err) return cb(err);
      cb(null, jsyaml.load(data));
    });
  }

  function load(repodata) {
    loadConfig(function(err, config) {
      app.state.jekyll = !err;
      app.state.config = config;

      var root = config && config.prose && config.prose.rooturl ? config.prose.rooturl : "";
      if (!path) path = root;

      repo.getTree(branch+"?recursive=true", function(err, tree) {
        if (err) return cb("Not found");
        loadBranches(user, reponame, function(err, branches) {
          if (err) return cb("Branches couldn't be fetched");
          app.state.path = path ? path : "";
          app.state.branches = _.filter(branches, function(b) { return b !== branch });
          cb(null, getFiles(tree, path, ""));
        });
      });
    });
  }

  repo.show(function(err, repodata) {
    if (!branch) app.state.branch = branch = repodata.master_branch;
    app.state.permissions = repodata.permissions;
    load();
  });
}

// Serialize
// -------

function serialize(content, metadata) {
  if (metadata) {
    return ["---", metadata, "---"].join('\n')+'\n\n'+content;
  } else {
    return content;
  }
}

// Save File
// -------
//
// Store a file to GitHub

function saveFile(user, repo, branch, path, content, message, cb) {
  var repo = getRepo(user, repo);
  repo.write(branch, path, content, message, cb);
}

// Fork repository
// -------
//
// Creates a fork for the current user

function forkRepo(user, reponame, branch, cb) {
  var repo = getRepo(user, reponame);
  var forkedRepo = getRepo(app.username, reponame);

  // Wait until contents are ready.

  function onceReady(cb) {
    _.delay(function() {
      forkedRepo.contents("", function(err, contents) {
        contents ? cb() : onceReady(cb);
      });
    }, 500);
  }

  repo.fork(function(err) {
    onceReady(function() {
      repo.getRef("heads/"+branch, function(err, commitSha) {
        // Create temp branch
        forkedRepo.listBranches( function( unused, branches ){
          //find the lowest patch number
          i=1; while ($.inArray('prose-patch-'+i, branches)!=-1){ i++ }
          var refSpec = { "ref": "refs/heads/prose-patch-"+i, "sha": commitSha };
          forkedRepo.createRef(refSpec, cb);
        });
      });
    });
  });
}

// New pull request
// -------
//
// Creates a new pull request

function createPullRequest(user, repo, pull, cb) {
  var repo = getRepo(user, repo);

  repo.createPullRequest(pull, function(err) {
    cb();
  });
}

// Patch File
// -------
//
// Send a pull request on GitHub

function patchFile(user, repo, branch, path, content, message, cb) {
  forkRepo(user, repo, branch, function(err, info) {
    branch = info.ref.substring( info.ref.lastIndexOf('/') + 1);
    saveFile(app.username, repo, branch, path, content, message, function(err) {
      if (err) return cb(err);
      var pull = {
        title: message,
        body: "This pull request has been automatically generated by Prose.io.",
        base: app.state.branch,
        head: app.username + ":" + branch,
      };
      createPullRequest(app.state.user, app.state.repo, pull, cb);
    });
  });
}

// Delete Post
// -------

function deletePost(user, repo, branch, path, file, cb) {
  var repo = getRepo(user, repo);
  repo.remove(branch, _.filepath(path, file), cb);
}

// Move Post
// -------

function movePost(user, repo, branch, path, newPath, cb) {
  var repo = getRepo(user, repo);
  repo.move(branch, path, newPath, cb);
}

// New Post
// -------
//
// Prepare new empty post

function emptyPost(user, repo, branch, path, cb) {
  var rawMetadata = "layout: default\npublished: false";
  var metadata = {
    "layout": "default",
    "published": false,
  };

  var cfg = app.state.config
  if (cfg && cfg.prose && cfg.prose.metadata) {
    if (cfg.prose.metadata[path]) {
      rawMetadata = cfg.prose.metadata[path];
      try {
        metadata = jsyaml.load(rawMetadata);
        if (metadata.date=="CURRENT_DATETIME") {
            var current = (new Date()).format('Y-m-d H:i');
            metadata.date = current;
            rawMetadata = rawMetadata.replace("CURRENT_DATETIME", current);
        }
      } catch(err) {
        console.log('ERROR encoding YAML');
        // No-op
      }
    }
  }

  cb(null, {
    "metadata": metadata,
    "raw_metadata": rawMetadata,
    "content": "# How does it work?\n\nEnter Text in Markdown format.",
    "repo": repo,
    "path": path,
    "published": false,
    "persisted": false,
    "writeable": true,
    "file": new Date().format("Y-m-d")+"-your-filename.md"
  });
}

// Load Post
// -------
//
// List all postings for a given repository
// Looks into _posts/blog

function loadPost(user, repo, branch, path, file, cb) {
  var repo = getRepo(user, repo);

  repo.read(branch, path ? path + "/" + file : file, function(err, data, commit) {
    if (err) return cb(err);

    // Given a YAML front matter, determines published or not
    function published(metadata) {
      return !!metadata.match(/published: true/);
    }

    // Extract YAML from a post, trims whitespace
    function parse(content) {
      var content = content.replace(/\r\n/g, "\n"); // normalize a little bit

      function writeable() {
        return !!(app.state.permissions && app.state.permissions.push);
      }

      if (!_.hasMetadata(content)) return {
        raw_metadata: "",
        content: content,
        published: false,
        writeable: writeable()
      };

      var res = { raw_metadata: "", published: false, writeable: writeable() };
      res.content = content.replace(/^(---\n)((.|\n)*?)\n---\n?/, function(match, dashes, frontmatter) {
        res.raw_metadata = frontmatter;
        res.published = published(frontmatter);
        return "";
      }).trim();
      return res;
    }

    var post = parse(data);
    cb(err, _.extend(post, {
      "sha": commit,
      "markdown": _.markdown(file),
      "jekyll": _.hasMetadata(data),
      "repo": repo,
      "path": path,
      "file": file,
      "persisted": true
    }));
  });
}
<|endoftext|>


<commit_before>import 'air-datepicker'
import moment from 'moment'

export { DateEditor }

/* TODO: avoid duplication */
$.fn.datepicker.language['en'] = {
  days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
  daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
  daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
  months: ['January','February','March','April','May','June', 'July','August','September','October','November','December'],
  monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
  today: 'Today',
  clear: 'Clear',
  dateFormat: 'yyyy-mm-dd',
  timeFormat: 'hh:ii aa',
  firstDay: 0
};

$.fn.datepicker.language['ca'] = {
  days: ['Diumenge', 'Dilluns', 'Dimarts', 'Dimecres', 'Dijous', 'Divendres', 'Dissabte'],
  daysShort: ['Diu', 'Dill', 'Dima', 'Dime', 'Dij', 'Div', 'Dis'],
  daysMin: ['Dg', 'Dl', 'Dm', 'Dc', 'Dj', 'Dv', 'Ds'],
  months: ['Gener','Febrer','Març','Abril','Maig','Juny', 'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'],
  monthsShort: ['Gen', 'Feb', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Oct', 'Nov', 'Des'],
  today: 'Avui',
  clear: 'Netejar',
  dateFormat: 'yyyy-mm-dd',
  timeFormat: 'hh:ii aa',
  firstDay: 1
};

$.fn.datepicker.language['es'] = {
  days: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
  daysShort: ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'],
  daysMin: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
  months: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
  monthsShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
  today: 'Hoy',
  clear: 'Limpiar',
  dateFormat: 'yyyy-mm-dd',
  timeFormat: 'hh:ii aa',
  firstDay: 1
};
/* ./ TODO: avoid duplication */

function DateEditor(args) {
  let $input,
    datepickerInstance,
    defaultDate,
    options = args.column.options && args.column.options.date ? args.column.options.date : {};

  this.init = function(){
    defaultDate = options.defaultDate = args.item[args.column.field];

    $input = $('<input type="text" class="editor-text" autocomplete="off" />');
    $input.appendTo(args.container);
    $input.focus().val(defaultDate).select();

    datepickerInstance = $input.datepicker({
      autoClose: true,
      language: I18n.locale
    }).data('datepicker');
  };

  this.destroy = function() {
    datepickerInstance.destroy();
    $input.remove();
  };

  this.show = function() {
    datepickerInstance.show();
  };

  this.hide = function() {
    datepickerInstance.hide();
  };

  this.position = function(_position) {};

  this.focus = function(){
    $input.focus();
  };

  this.loadValue = function(item) {
    var currentDateString = item[args.column.field];

    if (currentDateString) {
      var date = moment(currentDateString, "YYYY-MM-DD").toDate();
    } else {
      var date = moment().toDate();
    }

    $input.val(currentDateString);
    $input.select();
    datepickerInstance.selectDate(date);
  };

  this.serializeValue = function(){
    return $input.val();
  };

  this.applyValue = function(item, state){
    item[args.column.field] = state;
  };

  this.isValueChanged = function(){
    return (!($input.val() == '' && defaultDate == null)) && ($input.val() != defaultDate);
  };

  this.validate = function(){
    if (args.column.validator){
      let validationResults = args.column.validator($input.val(), args);
      if (!validationResults.valid){
        return validationResults;
      }
    }

    return {
      valid: true,
      msg: null
    };
  };

  this.init();
}
<commit_msg>Disable manual edition of slickgrid datepicker fields<commit_after>import 'air-datepicker'
import moment from 'moment'

export { DateEditor }

/* TODO: avoid duplication */
$.fn.datepicker.language['en'] = {
  days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
  daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
  daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
  months: ['January','February','March','April','May','June', 'July','August','September','October','November','December'],
  monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
  today: 'Today',
  clear: 'Clear',
  dateFormat: 'yyyy-mm-dd',
  timeFormat: 'hh:ii aa',
  firstDay: 0
};

$.fn.datepicker.language['ca'] = {
  days: ['Diumenge', 'Dilluns', 'Dimarts', 'Dimecres', 'Dijous', 'Divendres', 'Dissabte'],
  daysShort: ['Diu', 'Dill', 'Dima', 'Dime', 'Dij', 'Div', 'Dis'],
  daysMin: ['Dg', 'Dl', 'Dm', 'Dc', 'Dj', 'Dv', 'Ds'],
  months: ['Gener','Febrer','Març','Abril','Maig','Juny', 'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'],
  monthsShort: ['Gen', 'Feb', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Oct', 'Nov', 'Des'],
  today: 'Avui',
  clear: 'Netejar',
  dateFormat: 'yyyy-mm-dd',
  timeFormat: 'hh:ii aa',
  firstDay: 1
};

$.fn.datepicker.language['es'] = {
  days: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
  daysShort: ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'],
  daysMin: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
  months: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
  monthsShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
  today: 'Hoy',
  clear: 'Limpiar',
  dateFormat: 'yyyy-mm-dd',
  timeFormat: 'hh:ii aa',
  firstDay: 1
};
/* ./ TODO: avoid duplication */

function DateEditor(args) {
  let $input,
    datepickerInstance,
    defaultDate,
    options = args.column.options && args.column.options.date ? args.column.options.date : {};

  this.init = function(){
    defaultDate = options.defaultDate = args.item[args.column.field];

    $input = $('<input type="text" class="editor-text" autocomplete="off" disabled />');
    $input.appendTo(args.container);
    $input.focus().val(defaultDate).select();

    datepickerInstance = $input.datepicker({
      autoClose: true,
      language: I18n.locale
    }).data('datepicker');
  };

  this.destroy = function() {
    datepickerInstance.destroy();
    $input.remove();
  };

  this.show = function() {
    datepickerInstance.show();
  };

  this.hide = function() {
    datepickerInstance.hide();
  };

  this.position = function(_position) {};

  this.focus = function(){
    $input.focus();
  };

  this.loadValue = function(item) {
    var currentDateString = item[args.column.field];

    if (currentDateString) {
      var date = moment(currentDateString, "YYYY-MM-DD").toDate();
    } else {
      var date = moment().toDate();
    }

    $input.val(currentDateString);
    $input.select();
    datepickerInstance.selectDate(date);
  };

  this.serializeValue = function(){
    return $input.val();
  };

  this.applyValue = function(item, state){
    item[args.column.field] = state;
  };

  this.isValueChanged = function(){
    return (!($input.val() == '' && defaultDate == null)) && ($input.val() != defaultDate);
  };

  this.validate = function(){
    if (args.column.validator){
      let validationResults = args.column.validator($input.val(), args);
      if (!validationResults.valid){
        return validationResults;
      }
    }

    return {
      valid: true,
      msg: null
    };
  };

  this.init();
}
<|endoftext|>


<commit_before>String.strReplaceNthSub = function(needle, replacement, occurrence){
  var arr = this.split(needle);
  if(occurrence < arr.length){
    arr[occurrence - 1] += replacement + arr[occurrence];
    arr[occurrence].unset();
    this = arr.join();
  }
  return this;
}

String.subStringCount = function(subString,step){
  if(step==null||step==undefined||step==0){
    step=subString.length;
  }
  if(subString.length<=0){
    return 0;
  }
  var pos = 0;
  var count = 0;
  while(true){
    pos = String.indexOf(subString,pos);
    if(pos>=0){
      count++;
      pos+=step;
    }else break;
  }
  return count;
}
<commit_msg>Update string.o.js<commit_after>String.strReplaceNthSub = function(needle, replacement, occurrence){
  var arr = this.split(needle);
  if(occurrence < arr.length){
    arr[occurrence - 1] += replacement + arr[occurrence];
    delete arr[occurrence];
    this = arr.join();
  }
  return this;
}

String.subStringCount = function(subString,step){
  if(step==null||step==undefined||step==0){
    step=subString.length;
  }
  if(subString.length<=0){
    return 0;
  }
  var pos = 0;
  var count = 0;
  while(true){
    pos = String.indexOf(subString,pos);
    if(pos>=0){
      count++;
      pos+=step;
    }else break;
  }
  return count;
}
<|endoftext|>


<commit_before>const express = require('express'),
    util = require('../api_util'),
    router = express.Router(),
    models = require('../../../db/model/models'),
    userAPI = models.userAPI,
    cache = require('../../../cache');

router.get('/:userId', function (req, res, next) {
    let userId = req.params.userId;
    util.queryResponse(res, userAPI.findUserById(userId).then(util.formatUserResponse));
});

router.put('/:userId', function (req, res, next) {
    let receivedUser = req.body,
        userId = req.params.userId;
    util.removeInternalUserAttributes(receivedUser);
    util.queryResponse(res, userAPI.updateUser(userId, receivedUser).then(util.formatUserResponse));
});

router.get('/get/:key', function (req, res, next) {
    let key = req.params.key;
    cache.get(key)
        .then(function (val) {
            res.send(String(val));
        })
        .catch(function (err) {
            res.send(err);
        });
});

router.get('/set/:key/:val', function (req, res, next) {
    let key = req.params.key,
        val = req.params.val;
    cache.set(key, val);
    res.send('Set');
});
module.exports = router;
<commit_msg>redis works<commit_after>const express = require('express'),
    util = require('../api_util'),
    router = express.Router(),
    models = require('../../../db/model/models'),
    userAPI = models.userAPI;

router.get('/:userId', function (req, res, next) {
    let userId = req.params.userId;
    util.queryResponse(res, userAPI.findUserById(userId).then(util.formatUserResponse));
});

router.put('/:userId', function (req, res, next) {
    let receivedUser = req.body,
        userId = req.params.userId;
    util.removeInternalUserAttributes(receivedUser);
    util.queryResponse(res, userAPI.updateUser(userId, receivedUser).then(util.formatUserResponse));
});

module.exports = router;
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var _ = require('@sailshq/lodash');

/**
 * 200 (OK) Response
 *
 * Usage:
 * return res.ok();
 * return res.ok(data);
 * return res.ok(data, 'auth/login');
 *
 * @param  {Object} data
 * @param  {String|Object} options
 *          - pass string to render specified view
 */

module.exports = function sendOK (data) {

  // Get access to `req` and `res`
  var req = this.req;
  var res = this.res;

  // Get access to `sails`
  var sails = req._sails;

  // Set status code
  res.status(200);

  // If the data is an error instance and it doesn't have a custom .toJSON(),
  // use its stack instead (otherwise res.json() will turn it into an empty dictionary).
  if (_.isError(data)) {
    if (!_.isFunction(data.toJSON)) {
      data = data.stack;
    }
  }

  return res.json(data);

};
<commit_msg>Log a deprecation message if > 1 args are sent to res.ok()<commit_after>/**
 * Module dependencies
 */

var _ = require('@sailshq/lodash');

/**
 * 200 (OK) Response
 *
 * Usage:
 * return res.ok();
 * return res.ok(data);
 * return res.ok(data, 'auth/login');
 *
 * @param  {Object} data
 * @param  {String|Object} options
 *          - pass string to render specified view
 */

module.exports = function sendOK (data) {

  // Get access to `req` and `res`
  var req = this.req;
  var res = this.res;

  // Get access to `sails`
  var sails = req._sails;

  // If a second argument was given, log a message.
  if (arguments[1]) {
    sails.log.debug('The second argument to `res.ok()` is deprecated.');
    sails.log.debug('To serve a view via `res.ok()`, override the response');
    sails.log.debug('in \'api/responses/ok.js\'.\n');
  }

  // Set status code
  res.status(200);

  // If the data is an error instance and it doesn't have a custom .toJSON(),
  // use its stack instead (otherwise res.json() will turn it into an empty dictionary).
  if (_.isError(data)) {
    if (!_.isFunction(data.toJSON)) {
      data = data.stack;
    }
  }

  return res.json(data);

};
<|endoftext|>


<commit_before>/**
 * grunt/pipeline.js
 *
 * The order in which your css, javascript, and template files should be
 * compiled and linked from your views and static HTML files.
 *
 * (Note that you can take advantage of Grunt-style wildcard/glob/splat expressions
 * for matching multiple files.)
 */

// CSS files to inject in order
//
// (if you're using LESS with the built-in default config, you'll want
//  to change `assets/styles/importer.less` instead.)
var cssFilesToInject = [
  'styles/**/*.css'
];

// Client-side javascript files to inject in order
// (uses Grunt-style wildcard/glob/splat expressions)
var jsFilesToInject = [

  // Load sails.io before everything else
  'js/dependencies/sails.io.js',

  // Dependencies like jQuery, or Angular are brought in here
  'js/dependencies/**/*.js',

  // All of the rest of your client-side js files
  // will be injected here in no particular order.
  'js/**/*.js'
];

// Client-side HTML templates are injected using the sources below
// The ordering of these templates shouldn't matter.
// (uses Grunt-style wildcard/glob/splat expressions)
//
// By default, Sails uses JST templates and precompiles them into
// functions for you.  If you want to use jade, handlebars, dust, etc.,
// with the linker, no problem-- you'll just want to make sure the precompiled
// templates get spit out to the same file.  Be sure and check out `tasks/README.md`
// for information on customizing and installing new tasks.
var templateFilesToInject = [
  'templates/**/*.html'
];

// Prefix relative paths to source files so they point to the proper locations
// (i.e. where the other Grunt tasks spit them out, or in some cases, where
// they reside in the first place)
module.exports.cssFilesToInject = cssFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.jsFilesToInject = jsFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.templateFilesToInject = templateFilesToInject.map(function(path) {
  return 'assets/' + path;
});
<commit_msg>load bootstrap and angular first<commit_after>/**
 * grunt/pipeline.js
 *
 * The order in which your css, javascript, and template files should be
 * compiled and linked from your views and static HTML files.
 *
 * (Note that you can take advantage of Grunt-style wildcard/glob/splat expressions
 * for matching multiple files.)
 */

// CSS files to inject in order
//
// (if you're using LESS with the built-in default config, you'll want
//  to change `assets/styles/importer.less` instead.)
var cssFilesToInject = [
  'styles/bootstrap.css',
  'styles/**/*.css'
];

// Client-side javascript files to inject in order
// (uses Grunt-style wildcard/glob/splat expressions)
var jsFilesToInject = [

  // Load sails.io before everything else
  'js/dependencies/sails.io.js',

  // Dependencies like jQuery, or Angular are brought in here
  'js/dependencies/angular.js',
  'js/dependencies/**/*.js',

  // All of the rest of your client-side js files
  // will be injected here in no particular order.
  'js/**/*.js'
];

// Client-side HTML templates are injected using the sources below
// The ordering of these templates shouldn't matter.
// (uses Grunt-style wildcard/glob/splat expressions)
//
// By default, Sails uses JST templates and precompiles them into
// functions for you.  If you want to use jade, handlebars, dust, etc.,
// with the linker, no problem-- you'll just want to make sure the precompiled
// templates get spit out to the same file.  Be sure and check out `tasks/README.md`
// for information on customizing and installing new tasks.
var templateFilesToInject = [
  'templates/**/*.html'
];

// Prefix relative paths to source files so they point to the proper locations
// (i.e. where the other Grunt tasks spit them out, or in some cases, where
// they reside in the first place)
module.exports.cssFilesToInject = cssFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.jsFilesToInject = jsFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.templateFilesToInject = templateFilesToInject.map(function(path) {
  return 'assets/' + path;
});
<|endoftext|>


<commit_before>define(function (require) {

  return {
    create: require('./project/create').create
  };

});
<commit_msg>added destroy to ProjectModals.js<commit_after>define(function (require) {

  return {
    create: require('./project/create').create,
    destroy: require('./project/destroy').destroy
  };

});
<|endoftext|>


<commit_before>/*
 * cmdrjs
 * Version 1.0.1-alpha
 * Copyright 2014 Shaftware.
 * All Rights Reserved.
 * Use, reproduction, distribution, and modification of this code is subject to the terms and
 * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
 *
 * Project: https://github.com/shaftware/cmdrjs
 */

; (function (define) {
    define(['jquery'], function ($) {

        var version = '1.0.1-alpha',
            commands = {},
            activated = false,
            template = '

<textarea class="prompt" spellcheck="false" row="1" />

',
            container,
            input,
            prefix,
            prompt,
            output,
            outputLine,
            current,
            queue = [],
            history = [],
            historyIndex = -1,
            config = {
                autoOpen: false,
                openKey: 96,
                closeKey: 27,
                echo: true,
                promptPrefix: '> '
            };

        var cmdr = {
            activate: activate,
            deactivate: deactivate,
            reactivate: reactivate,
            open: open,
            close: close,
            read: read,
            readLine: readLine,
            write: write,
            writeLine: writeLine,
            clear: clear,
            execute: execute,
            setup: setup,
            commands: commands,
            config: config,
            version: version
        };

        cmdr.setup('VER', function () {
            cmdr.writeLine('cmdrjs (version ' + cmdr.version + ')');
        }, {
            description: 'Displays the cmdrjs version'
        });

        cmdr.setup('HELP', function () {
            cmdr.writeLine('The following commands are available:');
            cmdr.writeLine();
            for (var name in commands) {
                var command = commands[name];
                cmdr.write(pad(name, ' ', 10));
                cmdr.writeLine(command.description);
            }
            cmdr.writeLine();
        }, {
            description: 'Lists the available commands'
        });

        cmdr.setup('ECHO', function (arg) {
            var toggle = arg.toUpperCase();
            if (toggle === 'ON') {
                cmdr.config.echo = true;
            } else if (toggle === 'OFF') {
                cmdr.config.echo = false;
            } else {
                cmdr.writeLine(arg);
            }
        }, {
            parse: false,
            description: 'Displays provided text or toggles command echoing'
        });

        cmdr.setup('CLS', function () {
            cmdr.clear();
        }, {
            description: 'Clears the command prompt'
        });

        cmdr.setup('EXIT', function () {
            cmdr.close();
        }, {
            description: 'Closes the command prompt'
        });

        return cmdr;

        function activate() {
            if (activated) return;

            container = $(template).appendTo('body');
            input = $('.input', container);
            prefix = $('.prefix', container);
            prompt = $('.prompt', container);
            output = $('.output', container);

            $(document).on('keypress.cmdr', function (event) {
                if (!isOpen() && !$(event.target).is('input, textarea, select') && checkKey(event, config.openKey)) {
                    event.preventDefault();
                    open();
                } else if (isOpen() && checkKey(event, config.closeKey)) {
                    close();
                }
            });

            prompt.on('keydown', function (event) {
                if (!current) {
                    switch (event.keyCode) {
                        case 13:
                            var value = prompt.val();
                            if (value) {
                                execute(value);
                            }
                            return false;
                        case 38:
                            historyBack();
                            return false;
                        case 40:
                            historyForward();
                            return false;
                        case 9:
                            return false;
                    }
                } else if (current.readLine && event.keyCode === 13) {
                    current.readLine.resolve(prompt.val());
                    return false;
                }
                return true;
            });

            prompt.on('keypress', function(event) {
                if (current && current.read) {
                    if (event.charCode !== 0) {
                        current.read.char = String.fromCharCode(event.charCode);
                        if (current.read.capture) {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                return true;
            });

            prompt.on('keyup', function () {
                if (current && current.read && current.read.char) {
                    current.read.resolve(current.read.char);
                }
            });

            prompt.on('paste', function () {
                setTimeout(function () {
                    var value = prompt.val();
                    var lines = value.split(/\r\n|\r|\n/g);
                    var length = lines.length;
                    if (length > 1) {
                        for (var i = 1; i < length; i++) {
                            if (lines[i].length > 0) {
                                queue.push(lines[i]);
                            }
                        }
                        if (current && current.readLine) {
                            current.readLine.resolve(lines[0]);
                        } else if (current && current.read) {
                            current.read.resolve(lines[0][0]);
                        } else {
                            execute(lines[0]);
                        }
                    }
                }, 0);
            });

            prompt.on('change cut paste drop keydown', function () {
                setTimeout(function () {
                    prompt.height('auto').height(prompt[0].scrollHeight);
                }, 0);
            });

            var resizeThrottle;
            $(window).on('resize.cmdr', function () {
                clearTimeout(resizeThrottle);
                resizeThrottle = setTimeout(function () {
                    prompt.height('auto').height(prompt[0].scrollHeight);
                }, 100);
            });

            container.on('click', function (event) {
                if (!$(event.target).is('.input *, .output *')) {
                    prompt.focus();
                }
            });

            activateInput();

            activated = true;

            if (config.autoOpen) {
                open();
            }
        }

        function deactivate() {
            if (!activated) return;

            container.remove();
            container = null;
            input = null;
            prefix = null;
            prompt = null;
            output = null;

            $(document).off('keypress.cmdr');
            $(window).off('resize.cmdr');

            activated = false;
        }

        function reactivate() {
            if (activated) {
                deactivate();
            }
            activate();
        }

        function isOpen() {
            return container.is(':visible');
        }

        function open() {
            if (!activated) return;

            container.show();

            setTimeout(function () {
                prompt.css('text-indent', getPrefixWidth() + 'px').focus();
            }, 0);
        }

        function close() {
            if (!activated) return;

            container.hide();
            prompt.blur();
        }

        function read(callback, capture) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.read = $.Deferred().always(function (value) {
                current.read = null;
                if (!capture) {
                    prompt.val(value);
                }
                deactivateInput();
                if (callback.call(current, value) === true) {
                    read(callback, capture);
                } else {
                    flushInput();
                }
            });
            current.read.capture = capture;

            if (queue.length > 0) {
                current.read.resolve(queue.shift()[0]);
            }
        }

        function readLine(callback) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.readLine = $.Deferred().always(function (value) {
                current.readLine = null;
                prompt.val(value);
                deactivateInput();
                flushInput();
                if (callback.call(current, value) === true) {
                    readLine(callback);
                }
            });

            if (queue.length > 0) {
                current.readLine.resolve(queue.shift());
            }
        }

        function write(value, cssClass) {
            if (!activated) return;

            value = value || '';

            var outputValue = $('').addClass(cssClass).text(value);
            if (!outputLine) {
                outputLine = $('
').appendTo(output);
            }
            outputLine.append(outputValue);
        }

        function writeLine(value, cssClass) {
            if (!activated) return;

            value = (value || '') + '\n';

            write(value, cssClass);
            outputLine = null;
        }

        function clear() {
            if (!activated) return;

            output.html('');
        }

        function execute(command) {
            if (!activated) return;
            if (current) {
                queue.push(command);
                return;
            };

            if (typeof command !== 'string' || command.length === 0) {
                throw 'Invalid command';
            }

            prompt.val(command);
            flushInput(!config.echo);
            historyAdd(command);
            deactivateInput();

            command = command.trim();

            var parsed = parseCommand(command);
            var definition = commands[parsed.name.toUpperCase()];
            if (!definition) {
                writeLine('Invalid command', 'error');
                activateInput();
                return;
            }

            current = {
                command: command,
                definition: definition
            };

            var args = parsed.args;
            if (!definition.parse) {
                args = [parsed.arg];
            }

            var result = definition.callback.apply(current, args);

            $.when(result).always(function () {
                setTimeout(function () {
                    current = null;
                    activateInput();
                    if (queue.length > 0) {
                        execute(queue.shift());
                    }
                }, 0);
            });
        }

        function setup(name, callback, settings) {
            var definition = resolveDefinition(name, callback, settings);
            commands[definition.name] = definition;
        }

        function activateInput(inline) {
            if (inline) {
                if (outputLine) {
                    prefix.text(outputLine.text());
                    outputLine.remove();
                    outputLine = null;
                }
            } else {
                prefix.text(config.promptPrefix);
            }
            input.show();
            setTimeout(function () {
                prompt.prop('disabled', false).css('text-indent', getPrefixWidth() + 'px').focus();
            }, 0);
        }

        function deactivateInput() {
            prompt.prop('disabled', true);
            input.hide();
        }

        function flushInput(preventWrite) {
            if (!preventWrite) {
                write(prefix.text());
                writeLine(prompt.val());
            }
            prefix.text('');
            prompt.val('');
        }

        function historyAdd(command) {
            history.unshift(command);
            historyIndex = -1;
        }

        function historyBack() {
            if (history.length > historyIndex + 1) {
                historyIndex++;
                prompt.val(history[historyIndex]).change();
            }
        }

        function historyForward() {
            if (historyIndex > 0) {
                historyIndex--;
                prompt.val(history[historyIndex]).change();
            }
        }

        function parseCommand(command) {
            var exp = /[^\s"]+|"([^"]*)"/gi,
                name = null,
                arg = null,
                args = [];

            do {
                var match = exp.exec(command);
                if (match != null) {
                    var value = match[1] ? match[1] : match[0];
                    if (match.index === 0) {
                        name = value;
                        arg = command.substr(value.length + (match[1] ? 3 : 1));
                    } else {
                        args.push(value);
                    }
                }
            } while (match != null);

            return {
                name: name,
                arg: arg,
                args: args
            };
        }

        function resolveDefinition(name, callback, settings) {
            if (typeof name !== 'string') {
                settings = callback;
                callback = name;
                name = null;
            }
            if (typeof callback !== 'function') {
                settings = callback;
                callback = null;
            }

            var definition = {
                name: name,
                callback: callback,
                parse: true
            };

            $.extend(definition, settings);

            if (typeof definition.name !== 'string' ||
                typeof definition.callback !== 'function') {
                throw 'Invalid command definition';
            }

            definition.name = definition.name.toUpperCase();

            return definition;
        }

        function checkKey(event, key) {
            return (event.which || event.keyCode) === key;
        }

        function getPrefixWidth() {
            var width = prefix.width();
            var text = prefix.text();
            var spacePadding = text.length - text.trim().length;
            width += spacePadding * getPrefixSpaceWidth();
            return width;
        }

        function getPrefixSpaceWidth() {
            if (!prefix._spaceWidth) {
                var elem1 = $('| |').appendTo(prefix);
                var elem2 = $('||').appendTo(prefix);
                prefix._spaceWidth = elem1.innerWidth() - elem2.innerWidth();
                elem1.remove();
                elem2.remove();
            }
            return prefix._spaceWidth;
        }

        function pad(value, padding, length) {
            var right = length >= 0;
            length = Math.abs(length);
            while (value.length < length) {
                value = right ? value + padding : padding + value;
            }
            return value;
        }

    });
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(require('jquery'));
    } else {
        window['cmdr'] = factory(window['jQuery']);
    }
}));
<commit_msg>replacing text area with contenteditable div<commit_after>/*
 * cmdrjs
 * Version 1.0.2-alpha
 * Copyright 2014 Shaftware.
 * All Rights Reserved.
 * Use, reproduction, distribution, and modification of this code is subject to the terms and
 * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
 *
 * Project: https://github.com/shaftware/cmdrjs
 */

; (function (define) {
    define(['jquery'], function ($) {

        var version = '1.0.1-alpha',
            commands = {},
            activated = false,
            template = '

',
            container,
            input,
            prefix,
            prompt,
            output,
            outputLine,
            current,
            queue = [],
            history = [],
            historyIndex = -1,
            config = {
                autoOpen: false,
                openKey: 96,
                closeKey: 27,
                echo: true,
                promptPrefix: '> '
            };

        var cmdr = {
            activate: activate,
            deactivate: deactivate,
            reactivate: reactivate,
            open: open,
            close: close,
            read: read,
            readLine: readLine,
            write: write,
            writeLine: writeLine,
            clear: clear,
            execute: execute,
            setup: setup,
            commands: commands,
            config: config,
            version: version
        };

        cmdr.setup('VER', function () {
            cmdr.writeLine('cmdrjs (version ' + cmdr.version + ')');
        }, {
            description: 'Displays the cmdrjs version'
        });

        cmdr.setup('HELP', function () {
            cmdr.writeLine('The following commands are available:');
            cmdr.writeLine();
            for (var name in commands) {
                var command = commands[name];
                if (!!unwrap(command.available)) {
                    cmdr.write(pad(name, ' ', 10));
                    cmdr.writeLine(command.description);
                }
            }
            cmdr.writeLine();
        }, {
            description: 'Lists the available commands'
        });

        cmdr.setup('ECHO', function (arg) {
            var toggle = arg.toUpperCase();
            if (toggle === 'ON') {
                cmdr.config.echo = true;
            } else if (toggle === 'OFF') {
                cmdr.config.echo = false;
            } else {
                cmdr.writeLine(arg);
            }
        }, {
            parse: false,
            description: 'Displays provided text or toggles command echoing'
        });

        cmdr.setup('CLS', function () {
            cmdr.clear();
        }, {
            description: 'Clears the command prompt'
        });

        cmdr.setup('EXIT', function () {
            cmdr.close();
        }, {
            description: 'Closes the command prompt'
        });

        return cmdr;

        function activate() {
            if (activated) return;

            container = $(template).appendTo('body');
            input = $('.input', container);
            prefix = $('.prefix', container);
            prompt = $('.prompt', container);
            output = $('.output', container);

            $(document).on('keypress.cmdr', function (event) {
                if (!isOpen() && !$(event.target).is('input, textarea, select, [contenteditable]') && checkKey(event, config.openKey)) {
                    event.preventDefault();
                    open();
                } else if (isOpen() && checkKey(event, config.closeKey)) {
                    close();
                }
            });

            prompt.on('keydown', function (event) {
                if (!current) {
                    switch (event.keyCode) {
                        case 13:
                            var value = promptVal();
                            if (value) {
                                execute(value);
                            }
                            event.preventDefault();
                            return false;
                        case 38:
                            historyBack();
                            event.preventDefault();
                            return false;
                        case 40:
                            historyForward();
                            event.preventDefault();
                            return false;
                        case 9:
                            event.preventDefault();
                            return false;
                    }
                } else if (current.readLine && event.keyCode === 13) {
                    current.readLine.resolve(promptVal());
                    return false;
                }
                return true;
            });

            prompt.on('keypress', function(event) {
                if (current && current.read) {
                    if (event.charCode !== 0) {
                        current.read.char = String.fromCharCode(event.charCode);
                        if (current.read.capture) {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                return true;
            });

            prompt.on('keyup', function () {
                if (current && current.read && current.read.char) {
                    current.read.resolve(current.read.char);
                }
            });

            prompt.on('paste', function () {
                setTimeout(function () {
                    var value = promptVal()
                    var lines = value.split(/\r\n|\r|\n/g);
                    var length = lines.length;
                    if (length > 1) {
                        for (var i = 1; i < length; i++) {
                            if (lines[i].length > 0) {
                                queue.push(lines[i]);
                            }
                        }
                        if (current && current.readLine) {
                            current.readLine.resolve(lines[0]);
                        } else if (current && current.read) {
                            current.read.resolve(lines[0][0]);
                        } else {
                            execute(lines[0]);
                        }
                    }
                }, 0);
            });

            prompt.on('change cut paste drop keydown', function () {
                setTimeout(function () {
                    prompt.height('auto').height(prompt[0].scrollHeight);
                }, 0);
            });

            var resizeThrottle;
            $(window).on('resize.cmdr', function () {
                clearTimeout(resizeThrottle);
                resizeThrottle = setTimeout(function () {
                    prompt.height('auto').height(prompt[0].scrollHeight);
                }, 100);
            });

            container.on('click', function (event) {
                if (!$(event.target).is('.input *, .output *')) {
                    prompt.focus();
                }
            });

            activateInput();

            activated = true;

            if (config.autoOpen) {
                open();
            }
        }

        function deactivate() {
            if (!activated) return;

            container.remove();
            container = null;
            input = null;
            prefix = null;
            prompt = null;
            output = null;

            $(document).off('keypress.cmdr');
            $(window).off('resize.cmdr');

            activated = false;
        }

        function reactivate() {
            if (activated) {
                deactivate();
            }
            activate();
        }

        function isOpen() {
            return container.is(':visible');
        }

        function open() {
            if (!activated) return;

            container.show();

            setTimeout(function () {
                prompt.css('text-indent', getPrefixWidth() + 'px').focus();
            }, 0);
        }

        function close() {
            if (!activated) return;

            container.hide();
            prompt.blur();
        }

        function read(callback, capture) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.read = $.Deferred().always(function (value) {
                current.read = null;
                if (!capture) {
                    promptVal(value);
                }
                deactivateInput();
                if (callback.call(current, value) === true) {
                    read(callback, capture);
                } else {
                    flushInput();
                }
            });
            current.read.capture = capture;

            if (queue.length > 0) {
                current.read.resolve(queue.shift()[0]);
            }
        }

        function readLine(callback) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.readLine = $.Deferred().always(function (value) {
                current.readLine = null;
                promptVal(value);
                deactivateInput();
                flushInput();
                if (callback.call(current, value) === true) {
                    readLine(callback);
                }
            });

            if (queue.length > 0) {
                current.readLine.resolve(queue.shift());
            }
        }

        function write(value, cssClass) {
            if (!activated) return;

            value = value || '';

            var outputValue = $('').addClass(cssClass).text(value);
            if (!outputLine) {
                outputLine = $('
').appendTo(output);
            }
            outputLine.append(outputValue);
        }

        function writeLine(value, cssClass) {
            if (!activated) return;

            value = (value || '') + '\n';

            write(value, cssClass);
            outputLine = null;
        }

        function clear() {
            if (!activated) return;

            output.html('');
        }

        function execute(command) {
            if (!activated) return;
            if (current) {
                queue.push(command);
                return;
            };

            if (typeof command !== 'string' || command.length === 0) {
                throw 'Invalid command';
            }

            promptVal(command);
            flushInput(!config.echo);
            historyAdd(command);
            deactivateInput();

            command = command.trim();

            var parsed = parseCommand(command);
            var definition = commands[parsed.name.toUpperCase()];
            if (!definition || !unwrap(definition.available)) {
                writeLine('Invalid command', 'error');
                activateInput();
                return;
            }

            current = {
                command: command,
                definition: definition
            };

            var args = parsed.args;
            if (!definition.parse) {
                args = [parsed.arg];
            }

            var result = definition.callback.apply(current, args);

            $.when(result).always(function () {
                setTimeout(function () {
                    current = null;
                    activateInput();
                    if (queue.length > 0) {
                        execute(queue.shift());
                    }
                }, 0);
            });
        }

        function setup(name, callback, settings) {
            var definition = resolveDefinition(name, callback, settings);
            commands[definition.name] = definition;
        }

        function activateInput(inline) {
            if (inline) {
                if (outputLine) {
                    prefix.text(outputLine.text());
                    outputLine.remove();
                    outputLine = null;
                }
            } else {
                prefix.text(config.promptPrefix);
            }
            input.show();
            setTimeout(function () {
                prompt.prop('disabled', false).css('text-indent', getPrefixWidth() + 'px').focus();
            }, 0);
        }

        function deactivateInput() {
            prompt.prop('disabled', true);
            input.hide();
        }

        function flushInput(preventWrite) {
            if (!preventWrite) {
                write(prefix.text());
                writeLine(promptVal());
            }
            prefix.text('');
            promptVal('');
        }

        function historyAdd(command) {
            history.unshift(command);
            historyIndex = -1;
        }

        function historyBack() {
            if (history.length > historyIndex + 1) {
                historyIndex++;
                promptVal(history[historyIndex]).change();
            }
        }

        function historyForward() {
            if (historyIndex > 0) {
                historyIndex--;
                promptVal(history[historyIndex]).change();
            }
        }

        function parseCommand(command) {
            var exp = /[^\s"]+|"([^"]*)"/gi,
                name = null,
                arg = null,
                args = [];

            do {
                var match = exp.exec(command);
                if (match != null) {
                    var value = match[1] ? match[1] : match[0];
                    if (match.index === 0) {
                        name = value;
                        arg = command.substr(value.length + (match[1] ? 3 : 1));
                    } else {
                        args.push(value);
                    }
                }
            } while (match != null);

            return {
                name: name,
                arg: arg,
                args: args
            };
        }

        function resolveDefinition(name, callback, settings) {
            if (typeof name !== 'string') {
                settings = callback;
                callback = name;
                name = null;
            }
            if (typeof callback !== 'function') {
                settings = callback;
                callback = null;
            }

            var definition = {
                name: name,
                callback: callback,
                parse: true,
                available: true
            };

            $.extend(definition, settings);

            if (typeof definition.name !== 'string' ||
                typeof definition.callback !== 'function') {
                throw 'Invalid command definition';
            }

            definition.name = definition.name.toUpperCase();

            return definition;
        }

        function checkKey(event, key) {
            return (event.which || event.keyCode) === key;
        }

        function getPrefixWidth() {
            var width = prefix.width();
            var text = prefix.text();
            var spacePadding = text.length - text.trim().length;
            width += spacePadding * getPrefixSpaceWidth();
            return width;
        }

        function getPrefixSpaceWidth() {
            if (!prefix._spaceWidth) {
                var elem1 = $('| |').appendTo(prefix);
                var elem2 = $('||').appendTo(prefix);
                prefix._spaceWidth = elem1.innerWidth() - elem2.innerWidth();
                elem1.remove();
                elem2.remove();
            }
            return prefix._spaceWidth;
        }

        function pad(value, padding, length) {
            var right = length >= 0;
            length = Math.abs(length);
            while (value.length < length) {
                value = right ? value + padding : padding + value;
            }
            return value;
        }

        function unwrap(value) {
            return typeof value === 'function' ? value() : value;
        }

        function promptVal(value) {
            if (typeof value === 'undefined') {
                return prompt.html().replace(/[<]br[^>]*[>]/gi, '');
            } else {
                prompt.html(value);
            }
        }

    });
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(require('jquery'));
    } else {
        window['cmdr'] = factory(window['jQuery']);
    }
}));
<|endoftext|>


<commit_before>/**
 * @author Chia-Yuan Hsiung
 */
Ti.include('database.js');

var win = Titanium.UI.currentWindow;

//the data storage empty array
var data = [];
//define search bar which will attach to  table view
var searchBar = Titanium.UI.createSearchBar({
	showCancel:true,
	height :43,
	top:0
});

//print out the searchbar value whenever it changes
searchBar.addEventListener('change' , function(e){

	Ti.API.info('user searching for: ' + e.value);
});
//when the return key is hit, make searchBar get blur
searchBar.addEventListener('return' , function(e){
	searchBar.blur();
});

//when the cancel but ton is tapped,make searchBar get blur too
searchBar.addEventListener('cancel', function(e){
	searchBar.blur();
});
//end of search bar
//create a table view
var favoritesTable = Titanium.UI.createTableView({
	height: 366,
	width: 	320,
	top: 	0,
	left: 	0,
	search: searchBar,
	filterAttribute:'filter'
});
//tablerow selected function: create new window
favoritesTable.addEventListener('click', function(e){

	//get the selected row index
	var selectedRow = e.rowData;
	Ti.API.info(">>>>>>>>>>>>selectedRow.title "+selectedRow.title);
	Ti.API.info(">>>>>>>>>>>>selectedRow.description "+selectedRow.description);

	// create detail window
	var detailWindow = Titanium.UI.createWindow({
		_title:selectedRow.title,
		_description:selectedRow.description,
		_link:selectedRow.link,
		backgroundColor:'#fff',
		url: 'detail.js',
		id:0
	});

	Titanium.UI.currentTab.open(detailWindow);
});

function loadFavorites(){
	data = getFavorites();
	if(data.length>0){
		for(var i = 0; i<data.length; i++){
			var sqlReaultSet = data[i];
			Ti.API.warn(">>>>>>>>>>>>>>>>>>>>>>>>>>>> "+sqlReaultSet.id+":"+sqlReaultSet.title+", "
		+sqlReaultSet.description+","+sqlReaultSet.link);

		}
		favoritesTable.data = data;
		win.add(favoritesTable);

	}else{
		var label2 = Titanium.UI.createLabel({
			color:'#999',
			text:'No Favorites yet.',
			font:{fontSize:20,fontFamily:'Helvetica Neue'},
			textAlign:'center',
			width:'auto',
			top: 100
		});

		win.add(label2);
	}

}
//the focus event l istener wi l l ensure that the l ist / / is refreshed whenever the tab is changed
win.addEventListener('focus', loadFavorites);
<commit_msg>Showing Detail from favorites is ok for both iOS and Android<commit_after>/**
 * @author Chia-Yuan Hsiung
 */
Ti.include('database.js');

var win = Titanium.UI.currentWindow;

//the data storage empty array
var data = [];
//define search bar which will attach to  table view
var searchBar = Titanium.UI.createSearchBar({
	showCancel:true,
	height :43,
	top:0
});

//print out the searchbar value whenever it changes
searchBar.addEventListener('change' , function(e){

	Ti.API.info('user searching for: ' + e.value);
});
//when the return key is hit, make searchBar get blur
searchBar.addEventListener('return' , function(e){
	searchBar.blur();
});

//when the cancel but ton is tapped,make searchBar get blur too
searchBar.addEventListener('cancel', function(e){
	searchBar.blur();
});
//end of search bar
//create a table view
var favoritesTable = Titanium.UI.createTableView({
	height: 366,
	width: 	320,
	top: 	0,
	left: 	0,
	search: searchBar,
	filterAttribute:'filter'
});
//tablerow selected function: create new window
favoritesTable.addEventListener('click', function(e){

	//get the selected row index
	var theFavorite = data[e.index];

	// create detail window
	var detailWindow = Titanium.UI.createWindow({
		_title:theFavorite.title,
		_description:theFavorite.description,
		_link:theFavorite.link,
		backgroundColor:'#fff',
		title:theFavorite.title,
		url: 'detail.js',
		id:0
	});

	Titanium.UI.currentTab.open(detailWindow);
});

function loadFavorites(){
	data = getFavorites();
	if(data.length>0){
		favoritesTable.data = data;
		win.add(favoritesTable);

	}else{
		var label2 = Titanium.UI.createLabel({
			color:'#999',
			text:'No Favorites yet.',
			font:{fontSize:20,fontFamily:'Helvetica Neue'},
			textAlign:'center',
			width:'auto',
			top: 100
		});

		win.add(label2);
	}

}
//the focus event l istener wi l l ensure that the l ist / / is refreshed whenever the tab is changed
win.addEventListener('focus', loadFavorites);
<|endoftext|>


<commit_before>var davReadMethods = {
  'GET': true,
  'HEAD': true,
  'OPTIONS': true,
  'PROPFIND': true,
  'REPORT': true
};

var webReadMethods = {
  'GET': true,
  'HEAD': true,
  'OPTIONS': true
}

var validate = {
  edit: function validateEdit(req) {
    return true;
  },

  view: function validateView(req) {
    return webReadMethods[req.method];
  },

  sync: function validateSync(req) {
    return davReadMethods[req.method];
  }
};

module.exports = function(req, res, next) {
  var permissions = req.headers['x-sandstorm-permissions'];

  if(permissions) {
    permissions = permissions.split(',');

    if(req.url === '/api/permissions') {
      res.writeHead(200, {'Content-Type': 'application/json'});
      res.end(JSON.stringify({permissions: permissions}));
      return;
    }

    for(var i = 0; i < permissions.length; i++) {
      var permission = permissions[i];

      if(validate[permission] && validate[permission](req)) {
        return next();
      }
    }
    res.writeHead(403, {});
    res.end("Access denied.");
  } else {
    if(req.url === '/api/permissions') {
      res.writeHead(404, {});
      res.end();
    } else {
      next();
    }
  }
};
<commit_msg>ensure web UI works with read-only permissions<commit_after>var readMethods = {
  'GET': true,
  'HEAD': true,
  'OPTIONS': true,
  'PROPFIND': true,
  'REPORT': true
};

var validate = {
  edit: function validateEdit(req) {
    return true;
  },

  view: function validateView(req) {
    return readMethods[req.method];
  },

  sync: function validateSync(req) {
    return readMethods[req.method];
  }
};

module.exports = function(req, res, next) {
  var permissions = req.headers['x-sandstorm-permissions'];

  if(permissions) {
    permissions = permissions.split(',');

    if(req.url === '/api/permissions') {
      res.writeHead(200, {'Content-Type': 'application/json'});
      res.end(JSON.stringify({permissions: permissions}));
      return;
    }

    for(var i = 0; i < permissions.length; i++) {
      var permission = permissions[i];

      if(validate[permission] && validate[permission](req)) {
        return next();
      }
    }
    res.writeHead(403, {});
    res.end("Access denied.");
  } else {
    if(req.url === '/api/permissions') {
      res.writeHead(404, {});
      res.end();
    } else {
      next();
    }
  }
};
<|endoftext|>


<commit_before>/* Copyright 2012 Mozilla Foundation
 *
 * 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.
 */

import { RenderingCancelledException } from "pdfjs-lib";

const CLEANUP_TIMEOUT = 30000;

const RenderingStates = {
  INITIAL: 0,
  RUNNING: 1,
  PAUSED: 2,
  FINISHED: 3,
};

/**
 * Controls rendering of the views for pages and thumbnails.
 */
class PDFRenderingQueue {
  constructor() {
    this.pdfViewer = null;
    this.pdfThumbnailViewer = null;
    this.onIdle = null;
    this.highestPriorityPage = null;
    /** @type {number} */
    this.idleTimeout = null;
    this.printing = false;
    this.isThumbnailViewEnabled = false;
  }

  /**
   * @param {PDFViewer} pdfViewer
   */
  setViewer(pdfViewer) {
    this.pdfViewer = pdfViewer;
  }

  /**
   * @param {PDFThumbnailViewer} pdfThumbnailViewer
   */
  setThumbnailViewer(pdfThumbnailViewer) {
    this.pdfThumbnailViewer = pdfThumbnailViewer;
  }

  /**
   * @param {IRenderableView} view
   * @returns {boolean}
   */
  isHighestPriority(view) {
    return this.highestPriorityPage === view.renderingId;
  }

  /**
   * @returns {boolean}
   */
  hasViewer() {
    return !!this.pdfViewer;
  }

  /**
   * @param {Object} currentlyVisiblePages
   */
  renderHighestPriority(currentlyVisiblePages) {
    if (this.idleTimeout) {
      clearTimeout(this.idleTimeout);
      this.idleTimeout = null;
    }

    // Pages have a higher priority than thumbnails, so check them first.
    if (this.pdfViewer.forceRendering(currentlyVisiblePages)) {
      return;
    }
    // No pages needed rendering, so check thumbnails.
    if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled) {
      if (this.pdfThumbnailViewer.forceRendering()) {
        return;
      }
    }

    if (this.printing) {
      // If printing is currently ongoing do not reschedule cleanup.
      return;
    }

    if (this.onIdle) {
      this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT);
    }
  }

  /**
   * @param {Object} visible
   * @param {Array} views
   * @param {boolean} scrolledDown
   */
  getHighestPriority(visible, views, scrolledDown) {
    /**
     * The state has changed. Figure out which page has the highest priority to
     * render next (if any).
     *
     * Priority:
     * 1. visible pages
     * 2. if last scrolled down, the page after the visible pages, or
     *    if last scrolled up, the page before the visible pages
     */
    const visibleViews = visible.views;

    const numVisible = visibleViews.length;
    if (numVisible === 0) {
      return null;
    }
    for (let i = 0; i < numVisible; ++i) {
      const view = visibleViews[i].view;
      if (!this.isViewFinished(view)) {
        return view;
      }
    }

    // All the visible views have rendered; try to render next/previous pages.
    if (scrolledDown) {
      const nextPageIndex = visible.last.id;
      // IDs start at 1, so no need to add 1.
      if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) {
        return views[nextPageIndex];
      }
    } else {
      const previousPageIndex = visible.first.id - 2;
      if (
        views[previousPageIndex] &&
        !this.isViewFinished(views[previousPageIndex])
      ) {
        return views[previousPageIndex];
      }
    }
    // Everything that needs to be rendered has been.
    return null;
  }

  /**
   * @param {IRenderableView} view
   * @returns {boolean}
   */
  isViewFinished(view) {
    return view.renderingState === RenderingStates.FINISHED;
  }

  /**
   * Render a page or thumbnail view. This calls the appropriate function
   * based on the views state. If the view is already rendered it will return
   * `false`.
   *
   * @param {IRenderableView} view
   */
  renderView(view) {
    switch (view.renderingState) {
      case RenderingStates.FINISHED:
        return false;
      case RenderingStates.PAUSED:
        this.highestPriorityPage = view.renderingId;
        view.resume();
        break;
      case RenderingStates.RUNNING:
        this.highestPriorityPage = view.renderingId;
        break;
      case RenderingStates.INITIAL:
        this.highestPriorityPage = view.renderingId;
        view
          .draw()
          .finally(() => {
            this.renderHighestPriority();
          })
          .catch(reason => {
            if (reason instanceof RenderingCancelledException) {
              return;
            }
            console.error(`renderView: "${reason}"`);
          });
        break;
    }
    return true;
  }
}

export { PDFRenderingQueue, RenderingStates };
<commit_msg>Reduce unnecessary duplication in `PDFRenderingQueue.getHighestPriority`<commit_after>/* Copyright 2012 Mozilla Foundation
 *
 * 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.
 */

import { RenderingCancelledException } from "pdfjs-lib";

const CLEANUP_TIMEOUT = 30000;

const RenderingStates = {
  INITIAL: 0,
  RUNNING: 1,
  PAUSED: 2,
  FINISHED: 3,
};

/**
 * Controls rendering of the views for pages and thumbnails.
 */
class PDFRenderingQueue {
  constructor() {
    this.pdfViewer = null;
    this.pdfThumbnailViewer = null;
    this.onIdle = null;
    this.highestPriorityPage = null;
    /** @type {number} */
    this.idleTimeout = null;
    this.printing = false;
    this.isThumbnailViewEnabled = false;
  }

  /**
   * @param {PDFViewer} pdfViewer
   */
  setViewer(pdfViewer) {
    this.pdfViewer = pdfViewer;
  }

  /**
   * @param {PDFThumbnailViewer} pdfThumbnailViewer
   */
  setThumbnailViewer(pdfThumbnailViewer) {
    this.pdfThumbnailViewer = pdfThumbnailViewer;
  }

  /**
   * @param {IRenderableView} view
   * @returns {boolean}
   */
  isHighestPriority(view) {
    return this.highestPriorityPage === view.renderingId;
  }

  /**
   * @returns {boolean}
   */
  hasViewer() {
    return !!this.pdfViewer;
  }

  /**
   * @param {Object} currentlyVisiblePages
   */
  renderHighestPriority(currentlyVisiblePages) {
    if (this.idleTimeout) {
      clearTimeout(this.idleTimeout);
      this.idleTimeout = null;
    }

    // Pages have a higher priority than thumbnails, so check them first.
    if (this.pdfViewer.forceRendering(currentlyVisiblePages)) {
      return;
    }
    // No pages needed rendering, so check thumbnails.
    if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled) {
      if (this.pdfThumbnailViewer.forceRendering()) {
        return;
      }
    }

    if (this.printing) {
      // If printing is currently ongoing do not reschedule cleanup.
      return;
    }

    if (this.onIdle) {
      this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT);
    }
  }

  /**
   * @param {Object} visible
   * @param {Array} views
   * @param {boolean} scrolledDown
   */
  getHighestPriority(visible, views, scrolledDown) {
    /**
     * The state has changed. Figure out which page has the highest priority to
     * render next (if any).
     *
     * Priority:
     * 1. visible pages
     * 2. if last scrolled down, the page after the visible pages, or
     *    if last scrolled up, the page before the visible pages
     */
    const visibleViews = visible.views;

    const numVisible = visibleViews.length;
    if (numVisible === 0) {
      return null;
    }
    for (let i = 0; i < numVisible; ++i) {
      const view = visibleViews[i].view;
      if (!this.isViewFinished(view)) {
        return view;
      }
    }

    // All the visible views have rendered; try to render next/previous page.
    // (IDs start at 1, so no need to add 1 when `scrolledDown === true`.)
    const preRenderIndex = scrolledDown
      ? visible.last.id
      : visible.first.id - 2;
    const preRenderView = views[preRenderIndex];

    if (preRenderView && !this.isViewFinished(preRenderView)) {
      return preRenderView;
    }
    // Everything that needs to be rendered has been.
    return null;
  }

  /**
   * @param {IRenderableView} view
   * @returns {boolean}
   */
  isViewFinished(view) {
    return view.renderingState === RenderingStates.FINISHED;
  }

  /**
   * Render a page or thumbnail view. This calls the appropriate function
   * based on the views state. If the view is already rendered it will return
   * `false`.
   *
   * @param {IRenderableView} view
   */
  renderView(view) {
    switch (view.renderingState) {
      case RenderingStates.FINISHED:
        return false;
      case RenderingStates.PAUSED:
        this.highestPriorityPage = view.renderingId;
        view.resume();
        break;
      case RenderingStates.RUNNING:
        this.highestPriorityPage = view.renderingId;
        break;
      case RenderingStates.INITIAL:
        this.highestPriorityPage = view.renderingId;
        view
          .draw()
          .finally(() => {
            this.renderHighestPriority();
          })
          .catch(reason => {
            if (reason instanceof RenderingCancelledException) {
              return;
            }
            console.error(`renderView: "${reason}"`);
          });
        break;
    }
    return true;
  }
}

export { PDFRenderingQueue, RenderingStates };
<|endoftext|>