<commit_before><!DOCTYPE HTML>
<html i18n-values="dir:textdirection;">
<head>
<meta charset="utf-8">
<title i18n-content="title"></title>
<style type="text/css">
div.header {
  border-bottom: 1px solid #7289E2;
  padding: 8px;
  margin: 0;
  width: 100%;
  left: 0;
  top: 0;
  height: 32px;
  position: absolute;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  background-image: -webkit-gradient(linear,
                                     left top,
                                     left bottom,
                                     from(#D0DAF8),
                                     to(#A6BAF7));
  border-bottom-color: #999;
  border-bottom-width: 1px;
  border-left-color: #999;
  border-left-width: 1px;
  border-right-color: #999;
  border-right-width: 1px;
  color: black;
}

.rowlink {
  height: 100%;
  width: 90%;
  cursor: pointer;
}

.status {
  position: absolute;
  display: none;
  bottom: 0;
  left: 0;
  right: 0;
  height: 24px;
  border-top-color: #999;
  border-top-width: 1px;
  padding-top: 6px;
  padding-left: 10px;
  background-image: -webkit-gradient(linear,
                                     left top,
                                     left bottom,
                                     from(#D0DAF8),
                                     to(#A6BAF7));
}
.deleteYes {
  width: 40px;
  height: 30px;
  float: left;
  text-decoration: underline;
  color: blue;
}

.deleteNo {
  width: 40px;
  height: 30px;
  float: left;
  text-decoration: underline;
  color: blue;
}

.confirmdelete {
  text-align: center;
  border: 1px solid rgba(0, 0, 0, 0.25);
  border-radius: 2px;
  height: 36px;
  padding: 4px;
}

.link {
  color: blue;
  text-decoration: underline;
  float: left;
  margin-left: 5px;
  margin-right: 5px;
}

.prompt {
  float: left;
  text-decoration: none;
  color: black;
  margin-left: 5px;
  margin-right: 5px;
  cursor: default;
}

a.iconlink {
  display: block;
/*  font-family: helvetica; */
  font-weight: bold;
  font-size: 11px;
  color: white;
  text-decoration: none;
}

a.iconlink img {
  margin-bottom: 5px;
}

ul.filebrowselist {
  list-style-type: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.playbackelement {
  width: 600px;
  height: 600px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 99999;
  background: black;
}

.fullscreenplayback {
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 99999;
  background: black;
}

.imagepreview {
  width: 600px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 99999;
  background: black;
}

.fullscreentoggle {
  top: 0;
  right: 0;
  width: 50px;
  height: 50px;
  z-index: 999999;
  cursor: pointer;
  background: url('../../app/theme/filebrowse_fullscreen.png');
  position: absolute;
  background-repeat: no-repeat;
}

li.filebrowserow div.icon {
  float: left;
  margin-left: -44px;
  margin-top: -3px;
  display: inline
  position: relative;
  width: 17px;
  height: 17px;
  background-repeat: no-repeat;
}

.rightarrow {
  opacity: 0.5;
}

.menuicon {
  background: url('../../app/theme/filebrowse_menu.png');
  position: absolute;
  right: 4px;
  top: 5px;
  height: 100%;
  width: 15px;
  margin-left: 0;
  margin-top: 5px;
  background-repeat: no-repeat;
  cursor: pointer;
  opacity: 0.3;
  -webkit-transition: opacity 0.2s ease-out ;
}

li.filebrowserow:hover .menuicon {
  opacity: 0.75;
  -webkit-transition: opacity 0.0s ease-out ;
}

li.filebrowserow:hover .menuicon:hover {
  opacity: 1.0;
  -webkit-transition: opacity 0.0s ease-out ;
}

.uploadcomplete {
  height: 100%;
  position: absolute;
  right: 0;
  top: 5px;
  height: 100%;
  width: 70px;
  margin-left: 5px;
  margin-top: 5px;
}

.uploadprogress {
  position: absolute;
  right: 0;
  top: 5px;
  height: 100%;
  width: 12px;
  margin-left: 5px;
  margin-top: 5px;
  background-repeat: no-repeat;
}

li.filebrowserow {
  border-bottom: 1px solid #f7f7f7;
  padding: 8px 5px 5px 54px;
/*  overflow: hidden; */
  font-size: .8em;
/*  font-family: helvetica; */
  position: relative;
  background: #fff;
}

.downloadstatus {
  width: 100%;
  font-size: .6em;
  height: 10px;
}

.downloadpause {
  right: 0;
  bottom: 0;
  height: 15px;
  cursor: pointer;
  color: blue;
  text-align: center;
  position: absolute;
}

li.filebrowserow:hover {
  background: #ebeff9;
  cursor: pointer;
}

li.filebrowserow span.name {
  margin-top: 10px;
  margin-left: -22px;
  position: relative;
}

li.filebrowserow input.name {
  margin-top: 0;
  margin-left: -22px;
  position: relative;
}

li.filebrowserow span.namelink {
  margin-top: 10px;
  margin-left: -22px;
  position: relative;
  color:#0D0052;
  -webkit-transition: color 1.0s ease-out ;
}

li.filebrowserow:hover span.namelink {
  text-decoration: underline;
  color: #20c;
  -webkit-transition: color 0.0s ease-out ;
}

li.selected {
  background-color: #b1c8f2;
}

div.title {
  text-align: right;
  position: relative;
  font-size: .8em;
  font-weight: bold;
  padding-top: 2px;
}

div.controlbutton {
  width: 16px;
  height: 15px;
  display: inline;
  position: absolute;
  z-index: 999;
  border: 1px solid #859EE8;
  cursor: pointer;
  padding: 4px;

  background: -webkit-gradient(linear,
                               left top,
                               left bottom,
                               from(#F4F6FB),
                               to(#CCD7F8));
}

div.controlbutton:hover {

  background: -webkit-gradient(linear,
                               left top,
                               left bottom,
                               from(#FFF),
                               to(#D9E0F6));
}

div.column {
  width: 250px;
  height: 100%;
  float: left;
  position: relative;
}

div.columnlist {
  width: 100%;
  bottom: 0;
  top: 32px;
  position: absolute;
  overflow-y: scroll;
  overflow-x: hidden;
}

div.iconmedia {
  background: url('../../app/theme/icon_media.png');
}

div.iconfolder {
  background: url('../../app/theme/icon_folder.png');
}

div.iconfile {
  background: url('../../app/theme/icon_file.png');
}

div.iconphoto {
  background: url('../../app/theme/icon_photo.png');
}

div.iconmusic {
  background: url('../../app/theme/icon_media.png');
}

div.backbutton {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
  left: 6px;
  top: 3px
}

div.fwdbutton {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
  left: 31px;
  top: 3px;
}

div.playbackcontainer {
  top: 0;
  left: 0;
  position: absolute;
  width: 100%;
  height: 100%;
  background: black;
}

div.scanningcontainer {
  top: 0;
  left: 0;
  position: absolute;
  width: 100%;
  height: 100%;
}

div.filebutton {
  width: 70px;
  height: 18px;
  cursor: pointer;
  padding-top: 2px;
  border: 1px solid #abb6ce;
  background-color: #f5f7fc;
  border-radius: 5px;
  text-align: center;
  font-size: .8em;
}

.filenameprompt {
  top: 10px;
  left: 13px;
  font-size: .8em;
  position: absolute;
}

.filename {
  left: 80px;
  top: 5px;
  right: 10px;
  font-size: .8em;
  position: absolute;
}

div.openbutton {
  bottom: 5px;
  left: 10px;
  position: absolute;
}

div.cancelbutton {
  bottom: 5px;
  left: 90px;
  position: absolute;
}

div.newfolderbutton {
  bottom: 5px;
  right: 10px;
  padding-left: 2px;
  padding-right: 2px;
  padding-top: 3px;
  position: absolute;
}

div.disabled {
  color: gray;
  cursor: default;
}

div.opencontainer {
  width: 100%;
  bottom: 0;
  left: 0;
  height: 30px;
  position: absolute;
  background-image: -webkit-gradient(linear,
                                     0% 0%,
                                     0% 90%,
                                     from(rgb(239, 242, 249)),
                                     to(rgba(201, 212, 245, 1)));
}

div.savecontainer {
  width: 100%;
  bottom: 0;
  left: 0;
  height: 60px;
  position: absolute;
  background-image: -webkit-gradient(linear,
                                     0% 0%,
                                     0% 90%,
                                     from(rgb(239, 242, 249)),
                                     to(rgba(201, 212, 245, 1)));
}

div.container {
  top: 0;
  position: absolute;
  width: 100%;
  left: 0;
  bottom: 0;
}

div.containerwithopenbuttons {
  top: 0;
  position: absolute;
  width: 100%;
  left: 0;
  bottom: 30px;
}

div.containerwithsavebuttons {
  top: 0;
  position: absolute;
  width: 100%;
  left: 0;
  bottom: 60px;
}

div.fullcontainer {
  top: 0px;
  position: absolute;
  left: 0;
  bottom: 0;
  right: 600px;
  overflow-y: hidden;
  overflow-x: scroll;
}

.popout {
  right: 10px;
  top: 10px;
  width: 15px;
  text-align: center;
  height: 10px;
  font-size: .4em;
  background: rgb(239, 242, 249);
  cursor: pointer;
  z-index: 99999;
  padding-top: 1px;
  border: 1px solid #999;
  position: absolute;
  border-radius: 5px;
}

.mediacontainer {
  top: 0;
  left: 0;
  position: absolute;
  width: 100%;
  height: 100%;
}

.menu {
  top: 14px;
  right: 2px;
  width: 100px;
  -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0px 3px 3px;
  border-bottom-left-radius: 4px 4px;
  border-bottom-right-radius: 4px 4px;
  border-top-left-radius: 4px 4px;
  border-top-right-radius: 0px 0px;
  position: absolute;
  display: none;
  z-index: 999;
  background: white;
  border-top-left-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.6);
  padding: 5px;
}

.menuitem {
  width: 100%;
  height: 20px;
  text-align: left;
  cursor: pointer;
  left: 0;
  color: #0D0052;
  -webkit-transition: color 1.0s ease-out ;
}

.menuitem:hover {
  text-decoration: underline;
  color: #20c;
  background: #ebeff9;
  -webkit-transition: color 0.0s ease-out ;
}

.menuitemdisabled {
  width: 100%;
  height: 20px;
  text-align: left;
  color: gray;
  left: 0;
}

</style>
<script src="shared/js/local_strings.js"></script>
<script>



function $(o) {
  return document.getElementById(o);
}

/**
 * Partial funciton application.
 *
 * Usage:
 * var g = partial(f, arg1, arg2);
 * g(arg3, arg4);
 *
 * @param {!Function} fn A function to partially apply.
 * @param {...*} var_args Additional arguments that are partially
 *     applied to fn.
 * @return {!Function} A partially-applied form of the function partial() was
 *     called with.
 */
function partial(fn, var_args) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function() {
    // Prepend the bound arguments to the current arguments.
    var newArgs = Array.prototype.slice.call(arguments);
    newArgs.unshift.apply(newArgs, args);
    return fn.apply(this, newArgs);
  };
}

var pathArray = [];
var currentNode = -1;
var menus = [];
var currentImageMenu = '';
var inFullMode = false;
var inSelectMode = false;
var videoPlaybackElement = null;
var photoPreviewElement = null;
var numColumns = 0;
var divArray = [];
var rootsDiv = null;
var currentlySelectedItems = [];
var currentlySelectedPaths = [];
var multiSelect = false;
var selectFolder = false;
var inSaveMode = false;
var currentMenu = null;
var mainColumn = null;
var localStrings;
var downloadList = [];

// strings
var kPauseDownload;
var kResumeDownload;

function goBackInList() {
  if (currentNode > 0) {
    currentNode--;
    getDataForPath(pathArray[currentNode]);
  }
}

function toggleFullscreen() {
  if (videoPlaybackElement != null) {
    if (videoPlaybackElement.className == 'fullscreenplayback') {
      videoPlaybackElement.className = 'playbackelement';
    } else {
      videoPlaybackElement.className = 'fullscreenplayback';
    }
  }
}

function goForwardInList() {
  if (currentNode < (pathArray.length - 1)) {
    currentNode++;
    getDataForPath(pathArray[currentNode]);
  }
}

var lastScrollLeft = 0;
function animateScrollRight() {

  var main = mainColumn;
  main.scrollLeft += 20;
  // since if its larger than a size, we know we reached the leftmost part when
  // it stops growing, so clear it out and no more timeouts.
  if (lastScrollLeft != main.scrollLeft) {
    lastScrollLeft = main.scrollLeft;
    setTimeout('animateScrollRight()', 15);
  } else {
    lastScrollLeft = 0;
  }

}

function getCurrentContainer() {
  if (inFullMode) {
    var newContainer = document.createElement('div');
    var main = $('inner');
    numColumns++;
    main.style.width = (numColumns * 250) + 'px';
    newContainer.className = 'column';
    main.appendChild(newContainer);
    animateScrollRight();
    return newContainer;
  } else {
    return mainColumn;
  }
}

function clearList(list) {
  if (list.hasChildNodes()) {
    while (list.childNodes.length >=1) {
      list.removeChild(list.firstChild);
    }
  }
}

function rootsChanged() {
  if (inFullMode) {
    chrome.send('getRoots', []);
  }
}

function browseFileResult(info, results) {
   var lastDirArray = info.path.split('/');
   var lastDir = lastDirArray[lastDirArray.length - 1];
   if (info.functionCall == 'getRoots') {
     if (rootsDiv) {
       clearList(rootsDiv);
       createNewList(lastDir, results, rootsDiv, info.path);
     } else {
       var main = getCurrentContainer();
       rootsDiv = main;
       divArray.push(main);
       createNewList(lastDir, results, main, info.path);
     }
   } else if (info.functionCall == 'getChildren') {
     var main = getCurrentContainer();
     main.id = 'dir/' + info.path;
     divArray.push(main);
     document.location.hash = info.path;
     createNewList(lastDir, results, main, info.path);
   } else if (info.functionCall == 'refresh') {
     var main = $('dir/' + info.path);
     if (main) {
       clearList(main);
       createNewList(lastDir, results, main, info.path);
     } else {
       // not currently displayed, so just return.
       return;
     }
   }
  chrome.send("getDownloads", []);
}

function pathIsVideoFile(path) {
  return /\.(mp4|ogg|mpg|avi)$/i.test(path);
}

function pathIsAudioFile(path) {
  return /\.(mp3|m4a)$/i.test(path);
}

function pathIsImageFile(path) {
  return /\.(jpg|png|gif)$/i.test(path);
}

function pathIsHtmlFile(path) {
  return /\.(htm|html)$/i.test(path);
}

function moveScrollLeft() {
  var main = mainColumn;
  main.scrollLeft += 10;
}

function setUpForPlayback(path) {
   var mediapath = 'file://' + path;
   var header = $('header');
   document.body.removeChild(header);
   var main = mainColumn;
   main.className = 'playbackcontainer';
   var elementType;
   if (pathIsVideoFile(path)) {
     elementType = 'video';
   } else if (pathIsAudioFile(path)) {
     elementType = 'audio';
   } else {
     // close because we can't deal with this.
     return;
   }
   var element = document.createElement(elementType);
   element.className = 'mediacontainer';
   element.autoplay = true;
   element.controls = true;
   element.src = mediapath;
   main.appendChild(element);
}

function getClassForPath(path, isDirectory) {
  if (isDirectory) {
    return 'icon iconfolder';
  } else if (pathIsImageFile(path)) {
    return 'icon iconphoto';
  } else if (pathIsVideoFile(path)) {
    return 'icon iconmedia';
  } else if (pathIsAudioFile(path)) {
    return 'icon iconmusic';
  }
  return 'icon iconfile';
}

function getDataForPath(path) {
  if (path == 'roots' ) {
    if (inSaveMode) {
      var newfolderbutton = $('newfolderbutton');
      newfolderbutton.className = 'filebutton newfolderbutton disabled';
      var savebutton = $('savebutton');
      savebutton.className = 'filebutton openbutton disabled';
    } else if (inSelectMode) {
      var openbutton = $('openbutton');
      openbutton.className = 'filebutton openbutton disabled';
    }
    chrome.send('getRoots', []);
  } else {
    if (inSaveMode) {
      var newfolderbutton = $('newfolderbutton');
      newfolderbutton.className = 'filebutton newfolderbutton';
      var savebutton = $('savebutton');
      savebutton.className = 'filebutton openbutton';
    } else if (inSelectMode) {
      var openbutton = $('openbutton');
      openbutton.className = 'filebutton openbutton';
    }
    chrome.send('getChildren', [path]);
  }
};

function setUpForScanning() {
  var header = $('header');
  document.body.removeChild(header);
  var main = mainColumn;
  main.className = 'scanningcontainer';
  main.textContent = localStrings.getString('scanning');
};

function dialogOkClick() {
   if (currentlySelectedPaths.length == 0) {
     return;
   }
   if (!multiSelect) {
     chrome.send('DialogClose', [JSON.stringify({'path' : currentlySelectedPaths[0]})]);
   } else {
     chrome.send('DialogClose', [JSON.stringify({'path' : currentlySelectedPaths})]);
   }
};

function dialogCancelClick() {
   chrome.send('DialogClose', ['']);
};

function dialogSaveClick() {
  var filenameInput = $('filename');
  var filename = filenameInput.value;
  var currentPath = pathArray[pathArray.length - 1];
  if (currentPath == 'roots') {
    return;
  }
  currentPath += '/';
  currentPath += filename;
  chrome.send('DialogClose', [JSON.stringify({'path' : currentPath})]);
};


function createNewFormItem(initialName, isDirectory, id, blurcallback, keypresscallback) {
  var element = document.createElement('li');
  element.className = 'filebrowserow';
  element.id = 'listItem' + elementIdCounter;
  elementIdCounter++;

  var link;
  link = document.createElement('div');
  link.className = 'rowlink';

  var icon = document.createElement('div');
  icon.className = getClassForPath('', isDirectory);
  link.appendChild(icon);
  var input = document.createElement('input');
  input.className = 'name';
  input.id = 'newfoldername';
  input.onblur = blurcallback;
  input.onkeypress = keypresscallback;

  input.value = initialName;
  link.appendChild(input);

  element.appendChild(link);

  return element;
};

function createFolder(elementId) {
  var currentPath = pathArray[pathArray.length - 1];
  var element = $('newfoldername');
  if (element) {
    element.id = '';
    var filename = element.value;
    currentPath += '/';
    currentPath += filename;
    var existingfolder = $(currentPath);
    var counter = 1;
    while (existingfolder) {
      var testfilepath = currentPath;
      testfilepath = testfilepath + counter;
      existingfolder = $(testfilepath);
      if (!existingfolder) {
        currentPath = testfilepath;
        filename = filename + counter;
        break;
      }
      counter++;
    }
    if (filename == '') {
      return false;
    }
    var parent = element.parentNode;
    parent.removeChild(element);
    listitem = parent.parentNode;

    parent.onclick = getFunctionForItem(currentPath, listitem.id, true);

    var span = document.createElement('span');
    if (inSelectMode) {
      span.className = 'name';
    } else {
      span.className = 'namelink';
    }
    span.textContent = filename;
    parent.appendChild(span);

    var rightArrow = document.createElement('span');
    rightArrow.textContent = '»';
    rightArrow.className = 'rightarrow';
    parent.appendChild(rightArrow);

    chrome.send('createNewFolder', [currentPath]);
  }
  return false;
}

function deleteFile(path) {
  chrome.send('deleteFile', [path]);
}

function removeDeleteConfirm(path) {
  var element = menus[path];
  element.firstChild.removeChild(element.firstChild.lastChild);
}

function deleteFileConfirm(path) {
  var askingDiv = document.createElement('div');
  askingDiv.className = 'confirmdelete';
  askingDiv.textContent = localStrings.getString('confirmdelete');
  var yes = document.createElement('div');
  yes.className = 'deleteYes';
  yes.textContent = localStrings.getString('confirmyes');
  yes.onclick = partial(deleteFile, path);
  var no = document.createElement('div');
  no.onclick = partial(removeDeleteConfirm, path);
  no.textContent = localStrings.getString('confirmcancel');
  no.className = 'deleteNo';
  askingDiv.appendChild(yes);
  askingDiv.appendChild(no);
  var element = menus[path];
  if (element) {
    element.firstChild.appendChild(askingDiv);
  }
  window.event.stopPropagation();
}

function createFolderTyping(elementId) {
   if (window.event.keyCode == 13) {
     createFolder(elementId);
   }
}

function getDirectoryForPath(path) {
  var index = path.lastIndexOf('/');
  if (index == -1) {
    return path;
  }
  return path.substr(path, index);
}

function pauseToggleDownload(id) {
  var element = $('downloaditem' + id);
  if (element.textContent == kPauseDownload) {
    element.textContent = kResumeDownload;
  } else {
    element.textContent = kPauseDownload;
  }
  // Have to convert to a string, the system wasn't accepting ints
  chrome.send('pauseToggleDownload', ['' + id]);
}

function downloadsList(results) {
  downloadUpdated(results);
}

function allowDownload(id) {
  chrome.send('allowDownload', ['' + id]);
}

function cancelDownload(id) {
  chrome.send('cancelDownload', ['' + id]);
}

function getPathAndFilenameForPath(path) {
  return path.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/);
}

function downloadUpdated(results) {
  for (var x = 0; x < results.length; x++) {
    var element = $(results[x].file_path);
    if (!element && results[x].state != 'CANCELLED') {
      extracted = getPathAndFilenameForPath(results[x].file_path);
      var dirId = $('list/dir/' + extracted[1]);
      if (dirId) {
        element = createNewItem(extracted[2], results[x].file_path, false);
        dirId.appendChild(element);
        element.scrollIntoView();
      }
    }
    if (element) {
      if (results[x].state == 'CANCELLED') {
         element.parentNode.removeChild(element);
         continue;
      }
      if (results[x].percent < 100 || results[x].state == 'DANGEROUS') {
        var progressDiv = null;
        for (var y = 0; y < element.children.length; y++) {
           if (element.children[y].className == 'downloadstatus') {
             progressDiv = element.children[y];
             break;
           }
        }
        if (progressDiv == null) {
          element.className = 'filebrowserow downloading';
          var progressDiv = document.createElement('div');
          progressDiv.className = 'downloadstatus';
          element.appendChild(progressDiv);
          var pauseDiv = document.createElement('div');
          pauseDiv.onclick = partial(pauseToggleDownload, results[x].id);
          pauseDiv.className = 'downloadpause';
          if (results[x].state == "DANGEROUS") {
            pauseDiv.onClick = undefined;
            var prompt = document.createElement('div');
            prompt.textContent = localStrings.getString('allowdownload');
            prompt.className = 'prompt';
            pauseDiv.appendChild(prompt);
            var yes = document.createElement('div');
            yes.className = 'link';
            yes.textContent = localStrings.getString('confirmyes');
            yes.onclick = partial(allowDownload, results[x].id);
            var no = document.createElement('div');
            no.onclick = partial(cancelDownload, results[x].id);
            no.textContent = localStrings.getString('confirmcancel');
            no.className = 'link';
            pauseDiv.appendChild(yes);
            pauseDiv.appendChild(no);
          } else if (results[x].state == "PAUSED") {
            pauseDiv.textContent = kResumeDownload;
          } else if (results[x].state == "IN_PROGRESS") {
            pauseDiv.textContent = kPauseDownload;
          }
          pauseDiv.id = 'downloaditem' + results[x].id;
          element.appendChild(pauseDiv);
        }
        if (results[x].state != "DANGEROUS" ||
            results[x].percent < 100) {
          progressDiv.textContent = results[x].progress_status_text;
        }<commit_msg>Chaning filebrowse so when the user downloads a dangerous URL, it doesn't show the updates about the download until the user presses allow. (much like the standard UI)<commit_after><!DOCTYPE HTML>
<html i18n-values="dir:textdirection;">
<head>
<meta charset="utf-8">
<title i18n-content="title"></title>
<style type="text/css">
div.header {
  border-bottom: 1px solid #7289E2;
  padding: 8px;
  margin: 0;
  width: 100%;
  left: 0;
  top: 0;
  height: 32px;
  position: absolute;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  background-image: -webkit-gradient(linear,
                                     left top,
                                     left bottom,
                                     from(#D0DAF8),
                                     to(#A6BAF7));
  border-bottom-color: #999;
  border-bottom-width: 1px;
  border-left-color: #999;
  border-left-width: 1px;
  border-right-color: #999;
  border-right-width: 1px;
  color: black;
}

.rowlink {
  height: 100%;
  width: 90%;
  cursor: pointer;
}

.status {
  position: absolute;
  display: none;
  bottom: 0;
  left: 0;
  right: 0;
  height: 24px;
  border-top-color: #999;
  border-top-width: 1px;
  padding-top: 6px;
  padding-left: 10px;
  background-image: -webkit-gradient(linear,
                                     left top,
                                     left bottom,
                                     from(#D0DAF8),
                                     to(#A6BAF7));
}
.deleteYes {
  width: 40px;
  height: 30px;
  float: left;
  text-decoration: underline;
  color: blue;
}

.deleteNo {
  width: 40px;
  height: 30px;
  float: left;
  text-decoration: underline;
  color: blue;
}

.confirmdelete {
  text-align: center;
  border: 1px solid rgba(0, 0, 0, 0.25);
  border-radius: 2px;
  height: 36px;
  padding: 4px;
}

.link {
  color: blue;
  text-decoration: underline;
  float: left;
  margin-left: 5px;
  margin-right: 5px;
}

.prompt {
  float: left;
  text-decoration: none;
  color: black;
  margin-left: 5px;
  margin-right: 5px;
  cursor: default;
}

a.iconlink {
  display: block;
/*  font-family: helvetica; */
  font-weight: bold;
  font-size: 11px;
  color: white;
  text-decoration: none;
}

a.iconlink img {
  margin-bottom: 5px;
}

ul.filebrowselist {
  list-style-type: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.playbackelement {
  width: 600px;
  height: 600px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 99999;
  background: black;
}

.fullscreenplayback {
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 99999;
  background: black;
}

.imagepreview {
  width: 600px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 99999;
  background: black;
}

.fullscreentoggle {
  top: 0;
  right: 0;
  width: 50px;
  height: 50px;
  z-index: 999999;
  cursor: pointer;
  background: url('../../app/theme/filebrowse_fullscreen.png');
  position: absolute;
  background-repeat: no-repeat;
}

li.filebrowserow div.icon {
  float: left;
  margin-left: -44px;
  margin-top: -3px;
  display: inline
  position: relative;
  width: 17px;
  height: 17px;
  background-repeat: no-repeat;
}

.rightarrow {
  opacity: 0.5;
}

.menuicon {
  background: url('../../app/theme/filebrowse_menu.png');
  position: absolute;
  right: 4px;
  top: 5px;
  height: 100%;
  width: 15px;
  margin-left: 0;
  margin-top: 5px;
  background-repeat: no-repeat;
  cursor: pointer;
  opacity: 0.3;
  -webkit-transition: opacity 0.2s ease-out ;
}

li.filebrowserow:hover .menuicon {
  opacity: 0.75;
  -webkit-transition: opacity 0.0s ease-out ;
}

li.filebrowserow:hover .menuicon:hover {
  opacity: 1.0;
  -webkit-transition: opacity 0.0s ease-out ;
}

.uploadcomplete {
  height: 100%;
  position: absolute;
  right: 0;
  top: 5px;
  height: 100%;
  width: 70px;
  margin-left: 5px;
  margin-top: 5px;
}

.uploadprogress {
  position: absolute;
  right: 0;
  top: 5px;
  height: 100%;
  width: 12px;
  margin-left: 5px;
  margin-top: 5px;
  background-repeat: no-repeat;
}

li.filebrowserow {
  border-bottom: 1px solid #f7f7f7;
  padding: 8px 5px 5px 54px;
/*  overflow: hidden; */
  font-size: .8em;
/*  font-family: helvetica; */
  position: relative;
  background: #fff;
}

.downloadstatus {
  width: 100%;
  font-size: .6em;
  height: 10px;
}

.downloadpause {
  right: 0;
  bottom: 0;
  height: 15px;
  cursor: pointer;
  color: blue;
  text-align: center;
  position: absolute;
}

li.filebrowserow:hover {
  background: #ebeff9;
  cursor: pointer;
}

li.filebrowserow span.name {
  margin-top: 10px;
  margin-left: -22px;
  position: relative;
}

li.filebrowserow input.name {
  margin-top: 0;
  margin-left: -22px;
  position: relative;
}

li.filebrowserow span.namelink {
  margin-top: 10px;
  margin-left: -22px;
  position: relative;
  color:#0D0052;
  -webkit-transition: color 1.0s ease-out ;
}

li.filebrowserow:hover span.namelink {
  text-decoration: underline;
  color: #20c;
  -webkit-transition: color 0.0s ease-out ;
}

li.selected {
  background-color: #b1c8f2;
}

div.title {
  text-align: right;
  position: relative;
  font-size: .8em;
  font-weight: bold;
  padding-top: 2px;
}

div.controlbutton {
  width: 16px;
  height: 15px;
  display: inline;
  position: absolute;
  z-index: 999;
  border: 1px solid #859EE8;
  cursor: pointer;
  padding: 4px;

  background: -webkit-gradient(linear,
                               left top,
                               left bottom,
                               from(#F4F6FB),
                               to(#CCD7F8));
}

div.controlbutton:hover {

  background: -webkit-gradient(linear,
                               left top,
                               left bottom,
                               from(#FFF),
                               to(#D9E0F6));
}

div.column {
  width: 250px;
  height: 100%;
  float: left;
  position: relative;
}

div.columnlist {
  width: 100%;
  bottom: 0;
  top: 32px;
  position: absolute;
  overflow-y: scroll;
  overflow-x: hidden;
}

div.iconmedia {
  background: url('../../app/theme/icon_media.png');
}

div.iconfolder {
  background: url('../../app/theme/icon_folder.png');
}

div.iconfile {
  background: url('../../app/theme/icon_file.png');
}

div.iconphoto {
  background: url('../../app/theme/icon_photo.png');
}

div.iconmusic {
  background: url('../../app/theme/icon_media.png');
}

div.backbutton {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
  left: 6px;
  top: 3px
}

div.fwdbutton {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
  left: 31px;
  top: 3px;
}

div.playbackcontainer {
  top: 0;
  left: 0;
  position: absolute;
  width: 100%;
  height: 100%;
  background: black;
}

div.scanningcontainer {
  top: 0;
  left: 0;
  position: absolute;
  width: 100%;
  height: 100%;
}

div.filebutton {
  width: 70px;
  height: 18px;
  cursor: pointer;
  padding-top: 2px;
  border: 1px solid #abb6ce;
  background-color: #f5f7fc;
  border-radius: 5px;
  text-align: center;
  font-size: .8em;
}

.filenameprompt {
  top: 10px;
  left: 13px;
  font-size: .8em;
  position: absolute;
}

.filename {
  left: 80px;
  top: 5px;
  right: 10px;
  font-size: .8em;
  position: absolute;
}

div.openbutton {
  bottom: 5px;
  left: 10px;
  position: absolute;
}

div.cancelbutton {
  bottom: 5px;
  left: 90px;
  position: absolute;
}

div.newfolderbutton {
  bottom: 5px;
  right: 10px;
  padding-left: 2px;
  padding-right: 2px;
  padding-top: 3px;
  position: absolute;
}

div.disabled {
  color: gray;
  cursor: default;
}

div.opencontainer {
  width: 100%;
  bottom: 0;
  left: 0;
  height: 30px;
  position: absolute;
  background-image: -webkit-gradient(linear,
                                     0% 0%,
                                     0% 90%,
                                     from(rgb(239, 242, 249)),
                                     to(rgba(201, 212, 245, 1)));
}

div.savecontainer {
  width: 100%;
  bottom: 0;
  left: 0;
  height: 60px;
  position: absolute;
  background-image: -webkit-gradient(linear,
                                     0% 0%,
                                     0% 90%,
                                     from(rgb(239, 242, 249)),
                                     to(rgba(201, 212, 245, 1)));
}

div.container {
  top: 0;
  position: absolute;
  width: 100%;
  left: 0;
  bottom: 0;
}

div.containerwithopenbuttons {
  top: 0;
  position: absolute;
  width: 100%;
  left: 0;
  bottom: 30px;
}

div.containerwithsavebuttons {
  top: 0;
  position: absolute;
  width: 100%;
  left: 0;
  bottom: 60px;
}

div.fullcontainer {
  top: 0px;
  position: absolute;
  left: 0;
  bottom: 0;
  right: 600px;
  overflow-y: hidden;
  overflow-x: scroll;
}

.popout {
  right: 10px;
  top: 10px;
  width: 15px;
  text-align: center;
  height: 10px;
  font-size: .4em;
  background: rgb(239, 242, 249);
  cursor: pointer;
  z-index: 99999;
  padding-top: 1px;
  border: 1px solid #999;
  position: absolute;
  border-radius: 5px;
}

.mediacontainer {
  top: 0;
  left: 0;
  position: absolute;
  width: 100%;
  height: 100%;
}

.menu {
  top: 14px;
  right: 2px;
  width: 100px;
  -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0px 3px 3px;
  border-bottom-left-radius: 4px 4px;
  border-bottom-right-radius: 4px 4px;
  border-top-left-radius: 4px 4px;
  border-top-right-radius: 0px 0px;
  position: absolute;
  display: none;
  z-index: 999;
  background: white;
  border-top-left-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.6);
  padding: 5px;
}

.menuitem {
  width: 100%;
  height: 20px;
  text-align: left;
  cursor: pointer;
  left: 0;
  color: #0D0052;
  -webkit-transition: color 1.0s ease-out ;
}

.menuitem:hover {
  text-decoration: underline;
  color: #20c;
  background: #ebeff9;
  -webkit-transition: color 0.0s ease-out ;
}

.menuitemdisabled {
  width: 100%;
  height: 20px;
  text-align: left;
  color: gray;
  left: 0;
}

</style>
<script src="shared/js/local_strings.js"></script>
<script>



function $(o) {
  return document.getElementById(o);
}

/**
 * Partial funciton application.
 *
 * Usage:
 * var g = partial(f, arg1, arg2);
 * g(arg3, arg4);
 *
 * @param {!Function} fn A function to partially apply.
 * @param {...*} var_args Additional arguments that are partially
 *     applied to fn.
 * @return {!Function} A partially-applied form of the function partial() was
 *     called with.
 */
function partial(fn, var_args) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function() {
    // Prepend the bound arguments to the current arguments.
    var newArgs = Array.prototype.slice.call(arguments);
    newArgs.unshift.apply(newArgs, args);
    return fn.apply(this, newArgs);
  };
}

var pathArray = [];
var currentNode = -1;
var menus = [];
var currentImageMenu = '';
var inFullMode = false;
var inSelectMode = false;
var videoPlaybackElement = null;
var photoPreviewElement = null;
var numColumns = 0;
var divArray = [];
var rootsDiv = null;
var currentlySelectedItems = [];
var currentlySelectedPaths = [];
var multiSelect = false;
var selectFolder = false;
var inSaveMode = false;
var currentMenu = null;
var mainColumn = null;
var localStrings;
var downloadList = [];

// strings
var kPauseDownload;
var kResumeDownload;

function goBackInList() {
  if (currentNode > 0) {
    currentNode--;
    getDataForPath(pathArray[currentNode]);
  }
}

function toggleFullscreen() {
  if (videoPlaybackElement != null) {
    if (videoPlaybackElement.className == 'fullscreenplayback') {
      videoPlaybackElement.className = 'playbackelement';
    } else {
      videoPlaybackElement.className = 'fullscreenplayback';
    }
  }
}

function goForwardInList() {
  if (currentNode < (pathArray.length - 1)) {
    currentNode++;
    getDataForPath(pathArray[currentNode]);
  }
}

var lastScrollLeft = 0;
function animateScrollRight() {

  var main = mainColumn;
  main.scrollLeft += 20;
  // since if its larger than a size, we know we reached the leftmost part when
  // it stops growing, so clear it out and no more timeouts.
  if (lastScrollLeft != main.scrollLeft) {
    lastScrollLeft = main.scrollLeft;
    setTimeout('animateScrollRight()', 15);
  } else {
    lastScrollLeft = 0;
  }

}

function getCurrentContainer() {
  if (inFullMode) {
    var newContainer = document.createElement('div');
    var main = $('inner');
    numColumns++;
    main.style.width = (numColumns * 250) + 'px';
    newContainer.className = 'column';
    main.appendChild(newContainer);
    animateScrollRight();
    return newContainer;
  } else {
    return mainColumn;
  }
}

function clearList(list) {
  if (list.hasChildNodes()) {
    while (list.childNodes.length >=1) {
      list.removeChild(list.firstChild);
    }
  }
}

function rootsChanged() {
  if (inFullMode) {
    chrome.send('getRoots', []);
  }
}

function browseFileResult(info, results) {
   var lastDirArray = info.path.split('/');
   var lastDir = lastDirArray[lastDirArray.length - 1];
   if (info.functionCall == 'getRoots') {
     if (rootsDiv) {
       clearList(rootsDiv);
       createNewList(lastDir, results, rootsDiv, info.path);
     } else {
       var main = getCurrentContainer();
       rootsDiv = main;
       divArray.push(main);
       createNewList(lastDir, results, main, info.path);
     }
   } else if (info.functionCall == 'getChildren') {
     var main = getCurrentContainer();
     main.id = 'dir/' + info.path;
     divArray.push(main);
     document.location.hash = info.path;
     createNewList(lastDir, results, main, info.path);
   } else if (info.functionCall == 'refresh') {
     var main = $('dir/' + info.path);
     if (main) {
       clearList(main);
       createNewList(lastDir, results, main, info.path);
     } else {
       // not currently displayed, so just return.
       return;
     }
   }
  chrome.send("getDownloads", []);
}

function pathIsVideoFile(path) {
  return /\.(mp4|ogg|mpg|avi)$/i.test(path);
}

function pathIsAudioFile(path) {
  return /\.(mp3|m4a)$/i.test(path);
}

function pathIsImageFile(path) {
  return /\.(jpg|png|gif)$/i.test(path);
}

function pathIsHtmlFile(path) {
  return /\.(htm|html)$/i.test(path);
}

function moveScrollLeft() {
  var main = mainColumn;
  main.scrollLeft += 10;
}

function setUpForPlayback(path) {
   var mediapath = 'file://' + path;
   var header = $('header');
   document.body.removeChild(header);
   var main = mainColumn;
   main.className = 'playbackcontainer';
   var elementType;
   if (pathIsVideoFile(path)) {
     elementType = 'video';
   } else if (pathIsAudioFile(path)) {
     elementType = 'audio';
   } else {
     // close because we can't deal with this.
     return;
   }
   var element = document.createElement(elementType);
   element.className = 'mediacontainer';
   element.autoplay = true;
   element.controls = true;
   element.src = mediapath;
   main.appendChild(element);
}

function getClassForPath(path, isDirectory) {
  if (isDirectory) {
    return 'icon iconfolder';
  } else if (pathIsImageFile(path)) {
    return 'icon iconphoto';
  } else if (pathIsVideoFile(path)) {
    return 'icon iconmedia';
  } else if (pathIsAudioFile(path)) {
    return 'icon iconmusic';
  }
  return 'icon iconfile';
}

function getDataForPath(path) {
  if (path == 'roots' ) {
    if (inSaveMode) {
      var newfolderbutton = $('newfolderbutton');
      newfolderbutton.className = 'filebutton newfolderbutton disabled';
      var savebutton = $('savebutton');
      savebutton.className = 'filebutton openbutton disabled';
    } else if (inSelectMode) {
      var openbutton = $('openbutton');
      openbutton.className = 'filebutton openbutton disabled';
    }
    chrome.send('getRoots', []);
  } else {
    if (inSaveMode) {
      var newfolderbutton = $('newfolderbutton');
      newfolderbutton.className = 'filebutton newfolderbutton';
      var savebutton = $('savebutton');
      savebutton.className = 'filebutton openbutton';
    } else if (inSelectMode) {
      var openbutton = $('openbutton');
      openbutton.className = 'filebutton openbutton';
    }
    chrome.send('getChildren', [path]);
  }
};

function setUpForScanning() {
  var header = $('header');
  document.body.removeChild(header);
  var main = mainColumn;
  main.className = 'scanningcontainer';
  main.textContent = localStrings.getString('scanning');
};

function dialogOkClick() {
   if (currentlySelectedPaths.length == 0) {
     return;
   }
   if (!multiSelect) {
     chrome.send('DialogClose', [JSON.stringify({'path' : currentlySelectedPaths[0]})]);
   } else {
     chrome.send('DialogClose', [JSON.stringify({'path' : currentlySelectedPaths})]);
   }
};

function dialogCancelClick() {
   chrome.send('DialogClose', ['']);
};

function dialogSaveClick() {
  var filenameInput = $('filename');
  var filename = filenameInput.value;
  var currentPath = pathArray[pathArray.length - 1];
  if (currentPath == 'roots') {
    return;
  }
  currentPath += '/';
  currentPath += filename;
  chrome.send('DialogClose', [JSON.stringify({'path' : currentPath})]);
};


function createNewFormItem(initialName, isDirectory, id, blurcallback, keypresscallback) {
  var element = document.createElement('li');
  element.className = 'filebrowserow';
  element.id = 'listItem' + elementIdCounter;
  elementIdCounter++;

  var link;
  link = document.createElement('div');
  link.className = 'rowlink';

  var icon = document.createElement('div');
  icon.className = getClassForPath('', isDirectory);
  link.appendChild(icon);
  var input = document.createElement('input');
  input.className = 'name';
  input.id = 'newfoldername';
  input.onblur = blurcallback;
  input.onkeypress = keypresscallback;

  input.value = initialName;
  link.appendChild(input);

  element.appendChild(link);

  return element;
};

function createFolder(elementId) {
  var currentPath = pathArray[pathArray.length - 1];
  var element = $('newfoldername');
  if (element) {
    element.id = '';
    var filename = element.value;
    currentPath += '/';
    currentPath += filename;
    var existingfolder = $(currentPath);
    var counter = 1;
    while (existingfolder) {
      var testfilepath = currentPath;
      testfilepath = testfilepath + counter;
      existingfolder = $(testfilepath);
      if (!existingfolder) {
        currentPath = testfilepath;
        filename = filename + counter;
        break;
      }
      counter++;
    }
    if (filename == '') {
      return false;
    }
    var parent = element.parentNode;
    parent.removeChild(element);
    listitem = parent.parentNode;

    parent.onclick = getFunctionForItem(currentPath, listitem.id, true);

    var span = document.createElement('span');
    if (inSelectMode) {
      span.className = 'name';
    } else {
      span.className = 'namelink';
    }
    span.textContent = filename;
    parent.appendChild(span);

    var rightArrow = document.createElement('span');
    rightArrow.textContent = '»';
    rightArrow.className = 'rightarrow';
    parent.appendChild(rightArrow);

    chrome.send('createNewFolder', [currentPath]);
  }
  return false;
}

function deleteFile(path) {
  chrome.send('deleteFile', [path]);
}

function removeDeleteConfirm(path) {
  var element = menus[path];
  element.firstChild.removeChild(element.firstChild.lastChild);
}

function deleteFileConfirm(path) {
  var askingDiv = document.createElement('div');
  askingDiv.className = 'confirmdelete';
  askingDiv.textContent = localStrings.getString('confirmdelete');
  var yes = document.createElement('div');
  yes.className = 'deleteYes';
  yes.textContent = localStrings.getString('confirmyes');
  yes.onclick = partial(deleteFile, path);
  var no = document.createElement('div');
  no.onclick = partial(removeDeleteConfirm, path);
  no.textContent = localStrings.getString('confirmcancel');
  no.className = 'deleteNo';
  askingDiv.appendChild(yes);
  askingDiv.appendChild(no);
  var element = menus[path];
  if (element) {
    element.firstChild.appendChild(askingDiv);
  }
  window.event.stopPropagation();
}

function createFolderTyping(elementId) {
   if (window.event.keyCode == 13) {
     createFolder(elementId);
   }
}

function getDirectoryForPath(path) {
  var index = path.lastIndexOf('/');
  if (index == -1) {
    return path;
  }
  return path.substr(path, index);
}

function pauseToggleDownload(id) {
  var element = $('downloaditem' + id);
  if (element.textContent == kPauseDownload) {
    element.textContent = kResumeDownload;
  } else {
    element.textContent = kPauseDownload;
  }
  // Have to convert to a string, the system wasn't accepting ints
  chrome.send('pauseToggleDownload', ['' + id]);
}

function downloadsList(results) {
  downloadUpdated(results);
}

function allowDownload(id) {
  chrome.send('allowDownload', ['' + id]);
}

function cancelDownload(id) {
  chrome.send('cancelDownload', ['' + id]);
}

function getPathAndFilenameForPath(path) {
  return path.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/);
}

function downloadUpdated(results) {
  for (var x = 0; x < results.length; x++) {
    var element = $(results[x].file_path);
    if (!element && results[x].state != 'CANCELLED') {
      extracted = getPathAndFilenameForPath(results[x].file_path);
      var dirId = $('list/dir/' + extracted[1]);
      if (dirId) {
        element = createNewItem(extracted[2], results[x].file_path, false);
        dirId.appendChild(element);
        element.scrollIntoView();
      }
    }
    if (element) {
      if (results[x].state == 'CANCELLED') {
         element.parentNode.removeChild(element);
         continue;
      }
      if (results[x].percent < 100 || results[x].state == 'DANGEROUS') {
        var progressDiv = null;
        for (var y = 0; y < element.children.length; y++) {
           if (element.children[y].className == 'downloadstatus') {
             progressDiv = element.children[y];
             break;
           }
        }
        if (progressDiv == null) {
          element.className = 'filebrowserow downloading';
          var progressDiv = document.createElement('div');
          progressDiv.className = 'downloadstatus';
          element.appendChild(progressDiv);
          var pauseDiv = document.createElement('div');
          pauseDiv.onclick = partial(pauseToggleDownload, results[x].id);
          pauseDiv.className = 'downloadpause';
          if (results[x].state == "DANGEROUS") {
            pauseDiv.onClick = undefined;
            var prompt = document.createElement('div');
            prompt.textContent = localStrings.getString('allowdownload');
            prompt.className = 'prompt';
            pauseDiv.appendChild(prompt);
            var yes = document.createElement('div');
            yes.className = 'link';
            yes.textContent = localStrings.getString('confirmyes');
            yes.onclick = partial(allowDownload, results[x].id);
            var no = document.createElement('div');
            no.onclick = partial(cancelDownload, results[x].id);
            no.textContent = localStrings.getString('confirmcancel');
            no.className = 'link';
            pauseDiv.appendChild(yes);
            pauseDiv.appendChild(no);
            progressDiv.textContent = '';
          } else if (results[x].state == "PAUSED") {
            pauseDiv.textContent = kResumeDownload;
          } else if (results[x].state == "IN_PROGRESS") {
            pauseDiv.textContent = kPauseDownload;
          }
          pauseDiv.id = 'downloaditem' + results[x].id;
          element.appendChild(pauseDiv);
        }
        if (results[x].percent < 100) {
          progressDiv.textContent = results[x].progress_status_text;
        }
{'fraction_non_alphanumeric': 0.13945036026270485, 'fraction_numerical': 0.023337371676337437, 'mean_word_length': 2.8546616418155004, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 104, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4215606', 'n_tokens_mistral': 16676, 'n_tokens_neox': 15519, 'n_words': 3520}