Html程序  |  1822行  |  44.1 KB

<!DOCTYPE HTML>
<html i18n-values="dir:textdirection;">
<head>
<meta charset="utf-8">
<title i18n-content="title"></title>
<link rel="icon" href="../../app/theme/downloads_favicon.png">
<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;
  box-sizing: border-box;
  background-image: -webkit-linear-gradient(#D0DAF8, #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;
}

*:-khtml-drag {
  background-color: rgba(238,238,238, 0.5);
}

*[draggable] {
  -khtml-user-drag: element;
  cursor: move;
}

.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-linear-gradient(#D0DAF8, #A6BAF7);
}
.deleteYesNoContainer {
  display: -webkit-box;
  -webkit-box-align: center;
  -webkit-box-pack: center;
}
.deleteYes {
  margin: 4px;
  text-decoration: underline;
  color: blue;
}

.deleteNo {
  margin: 4px;
  text-decoration: underline;
  color: blue;
}

.confirmdelete {
  text-align: center;
  border: 1px solid rgba(0, 0, 0, 0.25);
  border-radius: 2px;
  min-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-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;
}

.downloading {
  background: white;
}

.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('shared/images/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: 21px;
  height: 17px;
  background-repeat: no-repeat;
}

.rightarrow {
  opacity: 0.5;
  position: absolute;
  right: 22px;
  top: 8px;
}

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

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

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;
  font-size: .8em;
  position: relative;
  background: #fff;
}

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

.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-left: -22px;
  position: relative;
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  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 !important;
}

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: relative;
  z-index: 999;
  border: 1px solid #859EE8;
  cursor: pointer;
  padding: 4px;
  padding-bottom: 0;
  background: -webkit-linear-gradient(#F4F6FB, #CCD7F8);
}

div.controlbutton:hover {

  background: -webkit-linear-gradient(#FFF, #D9E0F6);
}

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

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

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

div.iconmedia {
  background: url('shared/images/icon_media.png');
}

div.iconfolder {
  background: url('shared/images/icon_folder.png');
}

div.iconfile {
  background: url('shared/images/icon_file.png');
}

div.iconphoto {
  background: url('shared/images/icon_photo.png');
}

div.iconmusic {
  background: url('shared/images/icon_media.png');
}

div.backbutton {
  border-radius: 4px;
  left: 0;
  top: 0;
}

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%;
}

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

.filename {
  left: 90px;
  top: 3px;
  border-radius: 4px;
  right: 10px;
  font-size: .8em;
  position: absolute;
}

div.buttonscontainer {
  display: -webkit-box;
  bottom: 0;
  right: 10px;
  position: absolute;
}

div.openbutton {
  min-width: 50px;
  margin: 3px;
}

div.cancelbutton {
  min-width: 50px;
  margin: 3px;
}

#newfolderbutton {
  bottom: 3px;
  left: 10px;
  position: absolute;
}

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

div.opencontainer {
  width: 100%;
  bottom: 0;
  left: 0;
  height: 30px;
  position: absolute;
  background-image: -webkit-linear-gradient(#fcfcfc, #eff1f2 90%);
}

div.savecontainer {
  width: 100%;
  bottom: 0;
  left: 0;
  height: 60px;
  position: absolute;
  background-image: -webkit-linear-gradient(#fcfcfc, #eff1f2 90%);
}

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

div.containerwithopenbuttons {
  top: 0;
  position: absolute;
  right: 0;
  border: 1px solid #C2C2C2;
  margin: 4px;
  left: 0;
  bottom: 30px;
}

div.containerwithsavebuttons {
  top: 0;
  position: absolute;
  right: 0;
  margin: 4px;
  border: 1px solid #C2C2C2;
  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: 180px;
  -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;
}

.downloading[dangerous] > * > .icon {
  background: url('../../app/theme/alert_small.png');
}

input.error {
  background-color: #ff6666;
}

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

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

/**
 * Partial function 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(e) {
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    // 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);
  };
}

function supportsPdf() {
  return 'application/pdf' in navigator.mimeTypes;
}

var currentSavedPath = '';
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 = [];
var advancedEnabled = false;
var mediaPlayerEnabled = false;
// strings
var kPauseDownload;
var kResumeDownload;

function enabledResult(info) {
  advancedEnabled = info.enabled;
  mediaPlayerEnabled = info.mpEnabled;
  mainColumn = $('main');
  if (!advancedEnabled) {
    $('header').style.display = 'none';
  }
  if (document.documentElement.clientWidth <= 600) {
    inFullMode = false;
    if (chrome.dialogArguments) {
      var args = JSON.parse(chrome.dialogArguments);
      if (args.type == 'open') {
        multiSelect = false;
        selectFolder = false;
      } else if (args.type == 'save') {
        inSaveMode = true;
        selectFolder = false;
      } else if (args.type == 'open_multiple') {
        multiSelect = true;
        selectFolder = false;
      } else if (args.type == 'folder') {
        multiSelect = false;
        selectFolder = true;
      } else {
        alert('got unknown type' + args.type);
      }
      inSelectMode = true;
      if (inSaveMode) {
        var main = mainColumn;
        main.className = 'containerwithsavebuttons';
        var savemenu = document.createElement('div');
        savemenu.className = 'savecontainer';

        // The container is used for placing buttons horizontally.
        var buttonsContainer = document.createElement('div');
        buttonsContainer.className = 'buttonscontainer';
        savemenu.appendChild(buttonsContainer);

        var savebutton = document.createElement('button');
        savebutton.id = 'savebutton';
        savebutton.className = 'openbutton disabled';
        savebutton.onclick = dialogSaveClick;
        savebutton.textContent = localStrings.getString('save');
        buttonsContainer.appendChild(savebutton);

        var cancelbutton = document.createElement('button');
        cancelbutton.className = 'cancelbutton';
        cancelbutton.textContent = localStrings.getString('confirmcancel');
        cancelbutton.onclick = dialogCancelClick;
        buttonsContainer.appendChild(cancelbutton);

        var filenameprompt = document.createElement('div');
        filenameprompt.className = 'filenameprompt';
        filenameprompt.textContent = localStrings.getString('filenameprompt');
        savemenu.appendChild(filenameprompt);

        var backbutton = $('back');
        if (backbutton) {
          backbutton.style.top = '5px';
        }

        var filename = document.createElement('input');
        filename.className = 'filename';
        filename.id = 'filename';
        filename.value = args.current_file;
        savemenu.appendChild(filename);

        if (advancedEnabled) {
          var newfolderbutton = document.createElement('button');
          newfolderbutton.id = 'newfolderbutton';
          newfolderbutton.className = 'newfolderbutton disabled';
          newfolderbutton.textContent = localStrings.getString('newfolder');
          newfolderbutton.onclick = dialogNewFolderClick;
          savemenu.appendChild(newfolderbutton);
        }
        
        document.body.appendChild(savemenu);
        // Give focus to the save button. This has to be done after the
        // parent node is added to document.body.
        savebutton.focus();

      } else {
        var main = mainColumn;
        main.className = 'containerwithopenbuttons';
        var openmenu = document.createElement('div');
        openmenu.className = 'opencontainer';
        var openbutton = document.createElement('button');
        openbutton.id = 'openbutton';
        openbutton.className = 'openbutton disabled';
        var cancelbutton = document.createElement('button');
        cancelbutton.className = 'cancelbutton';
        openmenu.appendChild(openbutton);
        openbutton.onclick = dialogOkClick;
        openmenu.appendChild(cancelbutton);
        cancelbutton.onclick = dialogCancelClick;
        openbutton.textContent = localStrings.getString('open');
        cancelbutton.textContent = localStrings.getString('confirmcancel');
        document.body.appendChild(openmenu);
        var backbutton = $('back');
        if (backbutton) {
          backbutton.style.top = '5px';
        }
      }
    }
  } else {
    var main = mainColumn;
    main.className = 'fullcontainer';
    var innerContainer = document.createElement('div');
    innerContainer.className = 'container';
    innerContainer.id = 'inner';
    main.appendChild(innerContainer);
    inFullMode = true;
    $('back').style.display = 'none';
  }

  if (document.location.href.indexOf('#') != -1) {
    var currentpathArray = document.location.href.split('#');
    var path = currentpathArray[1];
    if (path == 'scanningdevice') {
      setUpForScanning();
    } else {
      currentNode++;
      currentSavedPath = path;
      getDataForPath(path);
    }
  } else {
    currentNode++;
    if (advancedEnabled) {
      currentSavedPath = 'roots';
      getDataForPath('roots');
    } else {
      currentSavedPath = localStrings.getString('downloadpath');
      getDataForPath(currentSavedPath);
    }
  }
  chrome.send('getDownloads', []);
}

function isPathUnderRoot(path, includeRoot) {
  var downloadpath = localStrings.getString('downloadpath');
  return (!includeRoot || path !== downloadpath) 
    && path.search(downloadpath) === 0;
}

function goBackInList() {
  currentNode--;
  if (isPathUnderRoot(currentSavedPath, true)) {
    var c = currentSavedPath.split('/');
    c.pop();
    currentSavedPath = c.join('/');
  } else {
    currentSavedPath = 'roots';
  }
  getDataForPath(currentSavedPath);
}

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

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.addEventListener('dragover', function(e) {
      if (e.preventDefault) e.preventDefault();
      e.dataTransfer.dropEffect = 'copy';
      return false;
    }, false);
    main.addEventListener('drop', function(e) {
      if (e.stopPropagation) e.stopPropagation();
      var src = e.dataTransfer.getData('Text');
      var path = getPathAndFilenameForPath(src);
      var dest = currentSavedPath + '/' + path[2];
      var dirId = $('list/dir/' + currentSavedPath);
      if (dirId) {
        var element = $(dest);
        if (!element) {
          // TODO(dhg): We probably should do some checking for
          // existance.
          element = createNewFakeItem(path[2], dest, false, true);
        }
        dirId.appendChild(element);
        element.scrollIntoView();
      }
      chrome.send('copyFile', [src, dest]);
      return false;
    }, false);
    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 moveScrollLeft() {
  var main = mainColumn;
  main.scrollLeft += 10;
}

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) {
  var newfolderbutton = $('newfolderbutton');
  if (newfolderbutton && advancedEnabled) {
    // Enable newfolder button for paths under downloadpath
    if (inSaveMode && isPathUnderRoot(path, false)) {
      newfolderbutton.className = 'newfolderbutton';
    } else {
      newfolderbutton.className = 'newfolderbutton disabled';
    }
  }
  
  if (path == 'roots') {
    if (inSaveMode) {
      var savebutton = $('savebutton');
      savebutton.className = 'openbutton disabled';
    } else if (inSelectMode) {
      var openbutton = $('openbutton');
      openbutton.className = 'openbutton disabled';
    }
    chrome.send('getRoots', []);
  } else {
    if (inSaveMode) {
      var savebutton = $('savebutton');
      savebutton.className = 'openbutton';
    } else if (inSelectMode) {
      var openbutton = $('openbutton');
      openbutton.className = '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 = currentSavedPath;
  if (currentPath == 'roots') {
    return;
  }
  currentPath += '/';
  currentPath += filename;
  chrome.send('validateSavePath', [currentPath]);

  filenameInput.disabled = true;
  $('savebutton').disabled = true;
}

function onValidatedSavePath(valid, savePath) {
  var filenameInput = $('filename');

  filenameInput.disabled = false;
  $('savebutton').disabled = false;

  if (valid) {
    filenameInput.classList.remove('error');
    chrome.send('DialogClose', [JSON.stringify({'path' : savePath})]);
  } else {
    filenameInput.classList.add('error');
  }
}

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 = currentSavedPath;
  var element = $('newfoldername');
  if (!element) {
    return false;
  }
  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++;
  }
  
  // Disallow / in folder name.
  if (filename.match(/^[^\/]+$/) === null) {
    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]);
}

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

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

function deleteFileConfirm(path) {
  var element = menus[path];
  if (!element || element.querySelector('.confirmdelete')) {
    return;
  }
  var askingDiv = document.createElement('div');
  askingDiv.className = 'confirmdelete';
  askingDiv.textContent = localStrings.getString('confirmdelete');
  yesNoDiv = document.createElement('div');
  yesNoDiv.className = 'deleteYesNoContainer';
  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';
  yesNoDiv.appendChild(yes);
  yesNoDiv.appendChild(no);
  askingDiv.appendChild(yesNoDiv);
  element.firstChild.appendChild(askingDiv);
  askingDiv.scrollIntoView();
  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 allowDownload(id, path) {
  var element = $(path);
  element.removeAttribute('dangerous');
  var pauseDiv = $('downloaditem' + id);
  if (pauseDiv) {
    if (pauseDiv.firstChild) {
      pauseDiv.removeChild(pauseDiv.firstChild);
    }
    pauseDiv.onclick = partial(pauseToggleDownload, id);
    pauseDiv.textContent = kPauseDownload;
  }
  chrome.send('allowDownload', ['' + id]);
}

function cancelDownload(id, path) {
  var element = $(path);
  element.removeAttribute('dangerous');
  chrome.send('cancelDownload', ['' + id]);
}

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

function newDownload(results) {
  var x;
  for (x = 0; x < results.length; x++) {
    var element = $(results[x].file_path);
    if (!element &&
        results[x].state != 'CANCELLED' &&
        results[x].state != 'INTERRUPTED') {
      var extracted = getPathAndFilenameForPath(results[x].file_path);
      var dirId = $('list/dir/' + extracted[1]);
      if (dirId) {
        element =
            createNewItem(results[x].file_name, results[x].file_path, false);
        downloadList.push(element);
        if (dirId.firstChild) {
          dirId.insertBefore(element, dirId.firstChild);
        } else {
          dirId.appendChild(element);
        }
        element.scrollIntoView();
      }
    }
  }
}

function removeDownload(element, dirId) {
  var status = undefined;
  var pause = undefined;
  for (var x = 0; x < element.children.length; x++) {
    if (element.children[x].className == 'downloadstatus') {
      var child = element.children[x];
      status = child;
    } else if (element.children[x].className == 'downloadpause') {
      var child = element.children[x];
      pause = child;
    }
  }
  if (status) {
    element.removeChild(status);
  }
  if (pause) {
    element.removeChild(pause);
  }
  element.className = 'filebrowserow';
  var elementList = [];
  for (var x = 0; x < downloadList.length; x++) {
    if (element != downloadList[x]) {
      elementList.push(downloadList[x]);
    }
  }
  downloadList = elementList;
  if (dirId) {
    dirId.removeChild(element);
  }
}

function downloadsList(results) {
  var removeDownloads = [];
  removeDownloads.pushUnique = function(element) {
  if (this.indexOf(element) === -1) {
      this.push(element);
    }
  };
  for (var y = 0; y < downloadList.length; y++) {
    var found = false;
    for (var x = 0; x < results.length; x++) {
      var element = $(results[x].file_path);
      if (downloadList[y] == element) {
        found = true;
        break;
      }
    }
    if (!found) {
      removeDownloads.pushUnique(downloadList[y]);
    }
  }

  for (var i = 0; i < results.length; ++i) {
    downloadUpdated(results[i]);
  }

  for (var x = 0; x < removeDownloads.length; x++) {
    var element = removeDownloads[x];
    var extracted = getPathAndFilenameForPath(element.id);
    var dirId = $('list/dir/' + extracted[1]);
    removeDownload(element, dirId);
  }
}

function downloadUpdated(result) {
  var element = $(result.file_path);
  var extracted = getPathAndFilenameForPath(result.file_path);
  var dirId = $('list/dir/' + extracted[1]);
  if (!element &&
      result.state != 'CANCELLED' &&
      result.state != 'INTERRUPTED') {
    if (dirId) {
      element = createNewItem(result.file_name, result.file_path, false);
      if (dirId.firstChild) {
        dirId.insertBefore(element, dirId.firstChild);
      } else {
        dirId.appendChild(element);
      }
      element.scrollIntoView();
    }
  }
  if (element) {
    if (result.state == 'CANCELLED' ||
        result.state == 'INTERRUPTED') {
      element.parentNode.removeChild(element);
      return;
    }
    if (result.percent < 100 || result.state == 'DANGEROUS') {
      var progressDiv = null;
      for (var y = 0; y < element.children.length; y++) {
        if (element.children[y].className == 'downloadstatus') {
          progressDiv = element.children[y];
        }
      }
      if (progressDiv == null) {
        downloadList.push(element);
        element.className = 'filebrowserow downloading';
        fixTitleForItem(element, result);
        var progressDiv = document.createElement('div');
        progressDiv.className = 'downloadstatus';
        element.appendChild(progressDiv);
        var pauseDiv = document.createElement('div');
        pauseDiv.onclick = partial(pauseToggleDownload, result.id);
        pauseDiv.className = 'downloadpause';
        if (result.state == 'DANGEROUS') {
          element.setAttribute('dangerous', 'true');
          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,
                                result.id,
                                result.file_path);
          var no = document.createElement('div');
          no.onclick = partial(cancelDownload,
                               result.id,
                               result.file_path);
          no.textContent = localStrings.getString('confirmcancel');
          no.className = 'link';
          pauseDiv.onclick = undefined;
          pauseDiv.appendChild(yes);
          pauseDiv.appendChild(no);
          progressDiv.textContent = '';
        }
        pauseDiv.id = 'downloaditem' + result.id;
        element.appendChild(pauseDiv);
      }
      var pauseDiv = $('downloaditem' + result.id);
      if (pauseDiv &&
          result.state == 'PAUSED' &&
          pauseDiv.textContent != kResumeDownload) {
        pauseDiv.textContent = kResumeDownload;
      } else if (pauseDiv &&
                 result.state == 'IN_PROGRESS' &&
                 pauseDiv.textContent != kPauseDownload) {
        pauseDiv.textContent = kPauseDownload;
      }
      if (result.percent < 100 &&
          result.state != 'DANGEROUS') {
        progressDiv.textContent = result.progress_status_text;
      }

    } else {
      removeDownloadIfDone(element, dirId);
    }
  }
}

function removeDownloadIfDone(element, dirId) {
  var len = downloadList.length;
  while (len--) {
    if (element.title === downloadList[len].title) {
      if (element.id !== downloadList[len].id) {
        // Dangerous download.
        removeDownload(downloadList[len], dirId);
      } else {
        removeDownload(downloadList[len]);
      }
      break;
    }
  }
}

function dialogNewFolderClick() {
  var newfolderbutton = $('newfolderbutton');
  if (newfolderbutton.className.indexOf('disabled') != -1) {
    return;
  }

  var main = divArray[divArray.length - 1];
  var list;
  for (var x = 0; x < main.childNodes.length; x++) {
    if (main.childNodes[x].className == 'columnlist' ||
        main.childNodes[x].className == 'columnlistadv') {
      list = main.childNodes[x].firstChild;
      break;
    }
  }
  var id = 'listItem' + elementIdCounter;
  elementIdCounter++;
  var element = createNewFormItem('',
                                  true,
                                  id,
                                  partial(createFolder, id),
                                  partial(createFolderTyping, id));
  list.appendChild(element);
  element.scrollIntoView();
  var inputelement = $('newfoldername');
  inputelement.focus();
}

///////////////////////////////////////////////////////////////////////////////
// Document Functions:
/**
 * Window onload handler, sets up the page.
 */
function load() {
  localStrings = new LocalStrings();
  kPauseDownload = localStrings.getString('pause');
  kResumeDownload = localStrings.getString('resume');
  chrome.send('isAdvancedEnabled', ['']);
}

function jumpToNode(nodeNumber) {
  if (currentNode == nodeNumber) {
    return;
  }
  if (inFullMode) {
    var main = $('inner');
    for (var x = (nodeNumber + 1); x < divArray.length; x++) {
      main.removeChild(divArray[x]);
      numColumns--;
    }
    divArray = divArray.slice(0, nodeNumber + 1);
  }
  currentNode = nodeNumber;
}

function descend(path, nodeNumber) {
  jumpToNode(nodeNumber);
  currentNode++;
  if (selectFolder) {
    currentlySelectedPaths = [];
    currentlySelectedPaths.push(path);
  }
  currentSavedPath = path;
  getDataForPath(path);
}

function clearPreviewPane() {
  if (videoPlaybackElement != null) {
    document.body.removeChild($('fullscreentoggle'));
    document.body.removeChild(videoPlaybackElement);
    videoPlaybackElement = null;
  }
  if (photoPreviewElement != null) {
    document.body.removeChild(photoPreviewElement);
    photoPreviewElement = null;
  }
}

function playMediaFile(path) {
  var newPath = 'file://' + path;
  chrome.send('playMediaFile', [newPath]);
}

function enqueueMediaFile(path) {
  var newPath = 'file://' + path;
  chrome.send('enqueueMediaFile', [newPath]);
}

function showImage(path) {
  if (inFullMode) {
    if (photoPreviewElement == null) {
      photoPreviewElement = document.createElement('img');
      photoPreviewElement.className = 'imagepreview';
      photoPreviewElement.src = 'file://' + path;
      document.body.appendChild(photoPreviewElement);
    } else {
      photoPreviewElement.src = 'file://' + path;
    }
  } else {
    chrome.send('openNewFullWindow', ['chrome://slideshow#' + path]);
  }
}

function showPath(path) {
  chrome.send('openNewFullWindow', ['file://' + path]);
}

function clearMenus() {
  if (currentMenu) {
    currentMenu.firstChild.style.display = 'none';
    currentMenu.style.opacity = '';
    currentMenu = null;
  }
}

function uploadImage(path) {
  var status = $('status');
  status.style.display = 'block';
  var extracted = getPathAndFilenameForPath(path);
  var main = $('dir/' + extracted[1]);
  main.style.bottom = '30px';
  status.textContent = 'Uploading';
  chrome.send('uploadToPicasaweb', [path]);
}

function showMenu(path) {
  var element = menus[path];
  if (element.firstChild.style.display == 'block') {
    // Second click should clear the menu.
    clearMenus();
  } else {
    clearMenus();
    element.firstChild.style.display = 'block';
    element.style.opacity = '1';
    currentMenu = element;
    currentMenu.scrollIntoView();
  }
  window.event.stopPropagation();
}

function uploadComplete(result) {
  var element = $('status');
  if (result.status_code == 201) {
    element.textContent = '';
    var a = document.createElement('a');
    a.href = result.url;
    a.target = '_blank';
    //TODO(altimofeev): Should really be localStrings.getString(...)
    a.textContent = 'Uploaded';
    element.appendChild(a);
  } else {
    element.textContent = 'Error';
  }
}

function findInArray(arr, element) {
  for (var x = 0; x < arr.length; x++) {
    if (arr[x] == element) {
      return x;
    }
  }
  return -1;
}

function selectItem(elementid, path) {
  var element = $(elementid);
  if (element.className == 'filebrowserow downloading') {
    return;
  }
  var index;
  if ((index = findInArray(currentlySelectedItems, element)) != -1) {
    // the user must want to toggle
    currentlySelectedItems.splice(index, 1);
    element.classname = 'filebrowserow';
    index = findInArray(currentlySelectedPaths, path);
    currentlySelectedPaths.splice(index, 1);
  } else {
    if (!multiSelect) {
      // clear out previous selected elements
      for (var x = 0; x < currentlySelectedItems.length; x++) {
        currentlySelectedItems[x].className = 'filebrowserow';
      }
      currentlySelectedItems = [];
      currentlySelectedPaths = [];
    }
    element.className = 'selected filebrowserow';
    currentlySelectedItems.push(element);
    currentlySelectedPaths.push(path);
    if (inSaveMode) {
      var extracted = getPathAndFilenameForPath(path);
      var file = $('filename');
      file.value = extracted[2];
    }
  }
}

function setItemInfoText(element, text) {
  var span;
  if (element.childNodes.length == 2) {
    span = document.createElement('span');
    span.className = 'name';
    span.textContent = text;
    element.appendChild(span);
    element.childNodes.item(1).style.display = 'none';
  } else {
    span = element.childNodes.item(2);
    span.textContent = text;
  }
}

function getUnknownFileTypeHandler() {
  return function() {
    var element = event.currentTarget;
    setItemInfoText(element,
                    localStrings.getStringF('error_unknown_file_type',
                    element.childNodes.item(1).textContent));
  };
}

function getFunctionForItem(path, id, isDirectory) {
  if (isDirectory) {
    return function() {
      selectItem(id, path);
      descend(path, currentNode);
    };
  }
  if (inSelectMode) {
    return function() {
      selectItem(id, path);
    };
  }
  if (pathIsAudioFile(path)) {
    return function() {
      playMediaFile(path);
    };
  }
  if (pathIsVideoFile(path)) {
    return function() {
      playMediaFile(path);
    };
  }
  if (pathIsImageFile(path)) {
    return function() {
      showImage(path);
    }
  }
  if (pathIsHtmlFile(path)) {
    return function() {
      showPath(path);
    }
  }
  if (pathIsPdfFile(path) && supportsPdf()) {
    return function() {
      showPath(path);
    }
  }

  return getUnknownFileTypeHandler();
}

/**
 * Double click handler for items.
 *
 * @param {string} path The file path of the item.
 * @param {string} id The id for this item.
 * @param {boolean} isDirectory Whether this item is a directory.
 * @return {Function} The function to handle the double click.
 */
function getDoubleClickForItem(path, id, isDirectory) {
  if (isDirectory) {
    return function() {};
  }
  if (inSelectMode) {
    return function() {
      selectItem(id, path);
      dialogOkClick();
    };
  }
  return function() {};
}

var elementIdCounter = 0;

function createNewFakeItem(title, path, isDirectory, hasspinner) {
  var element = document.createElement('li');

  element.className = 'filebrowserow';
  element.id = path;
  elementIdCounter++;
  var link;
  link = document.createElement('div');
  link.className = 'rowlink';

  var icon = document.createElement('div');
  icon.className = getClassForPath(path, isDirectory);
  link.appendChild(icon);

  var span = document.createElement('span');
  span.className = 'name';
  span.textContent = title;
  link.appendChild(span);

  element.appendChild(link);

  // Setup Menu
  var currentPath = currentSavedPath;
  if (hasspinner) {
    var spinicon = document.createElement('div');
    spinicon.align = 'right';
    spinicon.className = 'spinicon';
    element.appendChild(spinicon);
  }
  return element;
}

function createNewItem(title, path, isDirectory) {
  var element = document.createElement('li');
  element.setAttribute('draggable', 'true');

  element.addEventListener('dragstart', function(e) {
    e.dataTransfer.effectAllowed = 'copy';
    e.dataTransfer.setData('Text', this.id);
  }, false);

  element.className = 'filebrowserow';
  element.title = title;
  /*element.id = 'listItem' + elementIdCounter;*/
  element.id = path;
  elementIdCounter++;
  var link;
  link = document.createElement('div');
  link.onclick = getFunctionForItem(path, element.id, isDirectory);
  link.ondblclick = getDoubleClickForItem(path, element.id, isDirectory);
  link.className = 'rowlink';

  var icon = document.createElement('div');
  icon.className = getClassForPath(path, isDirectory);
  link.appendChild(icon);

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

  element.appendChild(link);

  // Setup Menu
  var currentPath = currentSavedPath;
  if (currentPath != 'roots') {
    var menuicon = document.createElement('div');
    var menu = document.createElement('div');
    menu.className = 'menu';
    if ((pathIsVideoFile(path) || pathIsAudioFile(path)) &&
        mediaPlayerEnabled) {
      var enqueueitem = document.createElement('div');
      enqueueitem.textContent = localStrings.getString('enqueue');
      enqueueitem.className = 'menuitem';
      enqueueitem.onclick = partial(enqueueMediaFile, path);
      menu.appendChild(enqueueitem);
    }
    var deleteitem = document.createElement('div');
    deleteitem.textContent = localStrings.getString('delete');
    deleteitem.className = 'menuitem';
    deleteitem.onclick = partial(deleteFileConfirm, path);
    menu.appendChild(deleteitem);
    menuicon.align = 'right';
    menuicon.className = 'menuicon';
    menuicon.onclick = partial(showMenu, path);
    menuicon.appendChild(menu);
    element.appendChild(menuicon);
    menus[path] = menuicon;
  }
  if (isDirectory) {
    var rightarrow = document.createElement('span');
    rightarrow.innerHTML = '&nbsp;&raquo;';
    rightarrow.className = 'rightarrow';
    link.appendChild(rightarrow);
  }
  return element;
}

function fixTitleForItem(element, result) {
  element.title = result.file_name;
  // This is a bit fragile.
  element.getElementsByTagName('span')[0].textContent = result.file_name;
}

function clearChildren(element) {
  element.innerHTML = '';
}

function popout(path) {
  var newPath = 'chrome://filebrowse#' + path;
  chrome.send('openNewPopupWindow', [newPath]);
}

function createNewList(title, results, main, path) {
  downloadList = [];
  clearChildren(main);

  var mainList = document.createElement('div');
  if (advancedEnabled) {
    mainList.className = 'columnlistadv';
  } else {
    mainList.className = 'columnlist';
  }

  var list = document.createElement('ul');
  list.className = 'filebrowselist';
  list.id = 'list/dir/' + path;
  // Use the translated title for the Downloads directory.
  if (path == localStrings.getString('downloadpath')) {
    document.title = (localStrings.getString('downloadtitle') || title);
  } else {
    document.title = title;
  }
  if (advancedEnabled) {
    var header = document.createElement('div');
    header.className = 'header';
    var divTitle = document.createElement('div');
    divTitle.className = 'title';
    if (inFullMode) {
      divTitle.style['text-align'] = 'center';
    }
    divTitle.innerText = title;
    if (inFullMode && (path.length != 0)) {
      var popOutButton = document.createElement('div');
      popOutButton.innerHTML = '&prod;';
      popOutButton.className = 'popout';
      popOutButton.onclick = partial(popout, path);
      header.appendChild(popOutButton);
    }
    header.appendChild(divTitle);
    main.appendChild(header);
  }
  main.appendChild(mainList);
  for (var x = 0; x < results.length; x++) {
    var element = createNewItem(results[x].title,
                                results[x].path,
                                results[x].isDirectory);
    list.appendChild(element);
  }
  mainList.appendChild(list);
}

</script>
<body onload='load();' onclick='clearMenus()' onselectstart='return false'
  i18n-values=".style.fontFamily:fontfamily">
<div id='header' class=''>
  <div id='back' class='backbutton controlbutton' onclick='goBackInList();return false;'>
    <img src="shared/images/filebrowse_back.png">
  </div>
  <div id='currenttitle' class=''></div>
</div><br>
<div id='main' class='container'></div>
<div id='status' class='status'></div>
</body>
</html>