/* <copyright> This file contains proprietary software owned by Motorola Mobility, Inc.<br/> No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. </copyright> */ var Montage = require("montage/core/core").Montage, Component = require("montage/ui/component").Component, iconsListModule = require("js/components/ui/icon-list-basic/iconsList.reel"), treeModule = require("js/components/ui/tree-basic/tree.reel"); var PickerNavigator = exports.PickerNavigator = Montage.create(Component, { popup:{ enumerable: false, writable: true, value: null }, mainContentData:{ enumerable:false, writable:true, value:null }, _firstTime: { enumerable: false, value: true }, firstTime:{ get: function(){}, set: function(){} }, pickerCallback:{ enumerable:false, writable:true, value:null }, selectedItems:{//passed to pickerCallback on click of OK enumerable:false, writable:true, value:[] }, /** * store a reference to the currently selected node... for single selection */ currentSelectedNode:{ enumerable:false, writable:true, value:null }, currentURI:{ enumerable:false, writable:true, value:null }, iconsViewDrawnOnce:{ enumerable:false, writable:true, value:false }, /** * for tree view only * will store folder uri vs tree instance map */ treeRefHash:{ enumerable:false, writable:true, value:{ } }, selectedPickerView:{ enumerable:false, writable:true, value:null }, /** * Contains the different Views and their update handlers */ pickerViews:{ enumerable:false, writable:true, value: function(){ var that = this; return { "iconView":that.updateIconView, "treeView":that.updateTreeView } } }, pickerModel:{ enumerable:false, writable:true, value:null }, willDraw: { enumerable: false, value: function() { } }, draw: { enumerable: false, value: function() { this.filterVal.innerHTML = this.pickerModel.currentFilter; if(this.pickerModel.fatalError !== null){ this.error.innerHTML = this.pickerModel.fatalError; } } }, didDraw: { enumerable: false, value: function() { var that = this; this.iconList = null; this.newContent = null; this.spanEl = null; this.addIdentifiers(); var topLevelDirs = this.pickerModel.topLevelDirectories; var leftNav = this.leftNav; //draw left nav if(!!topLevelDirs && (typeof topLevelDirs === "object") && ('splice' in topLevelDirs) && ('join' in topLevelDirs) &&(topLevelDirs.length > 0)){ topLevelDirs.forEach(function(dirObj){ var newDiv = document.createElement("div"); newDiv.className = "driversList"; newDiv.innerHTML = dirObj.name; leftNav.appendChild(newDiv); if(dirObj.uri === this.pickerModel.currentRoot){ newDiv.classList.add("highlighted"); //enable ok for logical drive selections, when in directory selection mode if(this.pickerModel.inFileMode === false){ this.okButton.removeAttribute("disabled"); //put into selectedItems..currently single selection is supported this.selectedItems = [dirObj.uri]; } } newDiv.addEventListener("click", function(evt){that.handleTopLevelDirectoryClicks(evt, dirObj);}, false); }, that); }else{ console.error("need at least 1 valid top level directory"); } //Draw icon view list //TODO: check the default view and draw the appropriate view if(this.mainContentData !== null){ this.currentURI = this.pickerModel.currentRoot; //draw the IconsList if icons view container is on if(this.iconViewContainer.style.display === "block"){ this.iconList = iconsListModule.IconsList.create(); //console.log(this.mainContentData); this.iconList.iconsViewDataObject = this.mainContentData; this.iconList.element = this.iconViewContainer; this.iconList.needsDraw = true; this.iconsViewDrawnOnce = true; this.selectedPickerView = "iconView"; if(!this.iconView.classList.contains("viewSelected")){ this.iconView.classList.add("viewSelected") } if(this.treeView.classList.contains("viewSelected")){ this.treeView.classList.remove("viewSelected"); } }else if(this.treeViewContainer.style.display === "block"){ //else draw the Tree if tree view container is on this.renderTree(this.treeViewContainer, this.currentURI); this.selectedPickerView = "treeView"; if(!this.treeView.classList.contains("viewSelected")){ this.treeView.classList.add("viewSelected") } if(this.iconView.classList.contains("viewSelected")){ this.iconView.classList.remove("viewSelected"); } } this.updateAddressBar(this.pickerModel.currentRoot); this.pickerModel.storeHistory(this.pickerModel.currentRoot);//populate history this.updateMetadata(this.currentURI); //for directory selection, selected url is the folder entered if(!this.pickerModel.inFileMode ){ this.okButton.removeAttribute("disabled"); //put into selectedItems..currently single selection is supported this.selectedItems = [this.pickerModel.currentRoot]; } } this.element.addEventListener("openFolder", function(evt){that.handlePickerNavOpenFolder(evt);}, false);//add icon double click event listener to reload iconList with new set of data this.element.addEventListener("selectedItem", function(evt){that.handlePickerNavSelectedItem(evt);}, false);//for single selection only this.element.addEventListener("showMetadata", function(evt){that.handlePickerNavShowMetadata(evt);}, false);//show metadata on hover of icon this.element.addEventListener("updateMetadata", function(evt){that.handlePickerNavUpdateMetadata(evt);}, false);//show metadata on click of icon //this.addressGo.addEventListener("click", this, false); this.addressBarUri.addEventListener("keydown", this, false); this.addressBarUri.addEventListener("keyup", this, false); this.refreshButton.addEventListener("click", this, false);//refresh - gets from file system directly this.backArrow.addEventListener("click", this, false); this.forwardArrow.addEventListener("click", this, false); //populate filters if in file selection mode if(this.pickerModel.inFileMode === true){ var filtersDD = this.element.querySelector(".filters .dropdown"); if(!!this.pickerModel.fileFilters && (typeof this.pickerModel.fileFilters === "object") && ('splice' in this.pickerModel.fileFilters) && ('join' in this.pickerModel.fileFilters)){ this.pickerModel.fileFilters.forEach(function(aFilter){ var newDiv = document.createElement("div"); newDiv.innerHTML = aFilter; filtersDD.appendChild(newDiv); newDiv.addEventListener("click", function(evt){that.handleFilterClick(evt, aFilter, filtersDD)}, false); }, this); } var renderedWidth = this.getComputedWidth(filtersDD); this.filters.style.width = "" + (parseInt((renderedWidth.substring(0, (renderedWidth.length - 2)))) + 20) + "px"; }else{ this.filters.style.display = "none"; } /** * attach click event listeners to the addressbar dropdown arrows */ var dropDownArrows = this.element.getElementsByClassName("dropdownArrow"); for(var x=0; x<dropDownArrows.length;x++){ dropDownArrows[x].addEventListener("click", function(evt){that.handleAddressDropdownArrowClick(evt);}, false); } this.iconView.addEventListener("click", this, false); this.treeView.addEventListener("click", this, false); this.element.addEventListener("drawTree", function(evt){that.handlePickerNavDrawTree(evt);}, false); this.element.addEventListener("refreshTreeSegment", function(evt){that.handlePickerNavRefreshTreeSegment(evt);}, false); this.resultsArea.addEventListener("click", function(evt){that.handleResultsAreaClick(evt);}, false); this.element.addEventListener("click", function(evt){that.handlePickerNavClick(evt);}, false); this.okButton.addEventListener("click", function(evt){that.handleOkButtonAction(evt);}, false); this.cancelButton.addEventListener("click", function(evt){that.handleCancelButtonAction(evt);}, false); //ready to show picker now this.element.style.visibility = "visible"; } }, updateAddressBar:{ writable: false, enumerable:true, value: function(folderUri){ var addressBarEl = this.addressBarUri; if(addressBarEl){ addressBarEl.value = folderUri; //update left drive selection } } }, cleanupUri:{ writable: false, enumerable:true, value: function(folderUri){ folderUri = folderUri.replace(/^\s+|\s+$/g,""); // strip any leading or trailing spaces //remove unnecessary / from end - for Win and Mac .... don't trim for the root if(((folderUri.charAt(folderUri.length - 1) === "/") || (folderUri.charAt(folderUri.length - 1) === "\\")) && (folderUri !== "/")){ folderUri = folderUri.substring(0, (folderUri.length - 1)); //console.log("*** new uri = "+ folderUri); } return folderUri; } }, clearSelection:{ writable: false, enumerable:true, value: function(folderUri){ if((this.currentSelectedNode !== null) && (this.currentSelectedNode.classList.contains("selected"))){ this.currentSelectedNode.classList.remove("selected"); } this.currentSelectedNode = null; //disable OK if(!this.okButton.hasAttribute("disabled")){ this.okButton.setAttribute("disabled", "true"); } } }, toggleDropdown:{ writable: false, enumerable:true, value: function(dropdownArrowEl){ var dropdownDiv = dropdownArrowEl.parentNode.getElementsByClassName("dropdown")[0]; dropdownDiv.classList.toggle("hide"); } }, closeDropdowns:{ writable:false, enumerable:true, value:function(clickedTarget){ if(!clickedTarget.classList.contains("dropdownArrow")){//if not clicked on the drop down arrow itself var dropDowns = this.element.getElementsByClassName("dropdown"); for(var x=0; x<dropDowns.length;x++){ if(!dropDowns[x].classList.contains("hide")){//if dropdown open if(this.isOutside(dropDowns[x], clickedTarget)){ dropDowns[x].classList.add("hide"); //console.log("!!! closed DD: "+dropDowns[x].classList.toString()); } } } } } }, prepareAddressDropdownData:{ writable:false, enumerable:true, value:function(uri){ uri = this.cleanupUri(uri); var arr = []; var temp = new String(uri); while(temp.indexOf("/") != -1){ temp = temp.substring(0, temp.lastIndexOf("/")); //populate dropdown irrespective of validity // if(!!this.application.ninja.filePickerController._directoryContentCache[temp]){//check if it is a valid location // arr.push(temp); // }else{ // break; // } if(temp.length >0){ arr.push(temp); }else{//for unix root / arr.push("/"); } } //console.log(arr); return arr; } }, renderTree:{ writable:false, enumerable:true, value:function(element, uri){ if(!!element){ var tree = treeModule.Tree.create(); tree.treeViewDataObject = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel); //console.log("renderTree() for "+ uri); //console.log(tree.treeViewDataObject); tree.element = element; tree.needsDraw = true; } } }, updateIconView:{ writable:false, enumerable:true, value:function(uri, fromCache){ var status = true; var iconViewContainer = this.element.querySelector(".iconViewContainer"); if((typeof fromCache === 'undefined') || (fromCache === true)){ this.newContent = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel); } else{ this.newContent = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel, false); } if(!!this.newContent && this.newContent.length > 0){ //clear selection this.clearSelection(); this.spanEl = iconViewContainer.querySelector(".noResults"); if(!!this.spanEl){ this.spanEl.style.display = "none"; } this.iconList.iconsViewDataObject = this.newContent; }else{ this.iconList.iconsViewDataObject = []; this.spanEl = iconViewContainer.querySelector(".noResults"); if(!!this.spanEl){ this.spanEl.style.display = "block"; }else{ this.spanEl = document.createElement("span"); this.spanEl.className = "noResults"; this.spanEl.innerHTML = "no results"; this.spanEl.style.display = "block"; iconViewContainer.appendChild(this.spanEl); } status = false; //for no match } this.updateMetadata(uri); return status; } }, updateTreeView:{ writable:false, enumerable:true, value:function(uri, fromCache){ var status = true; //need to draw every time since an expanded tree won't update with just bound data update var treeViewContainer = this.element.querySelector(".treeViewContainer"); //first clean up treeViewContainer while(treeViewContainer.hasChilden){ treeViewContainer.removeChild(treeViewContainer.lastChild); } //now draw the unexpanded tree with the current uri data if(!!treeViewContainer){ var data = []; if((typeof fromCache === 'undefined') || (fromCache === true)){ data = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel); } else{ data = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel, false); } if(data.length > 0){ //clear selection this.clearSelection(); this.spanEl = this.element.querySelector(".treeViewContainer").querySelector(".noResults"); if(!!this.spanEl){ this.spanEl.style.display = "none"; } var tree = treeModule.Tree.create(); tree.treeViewDataObject = data; tree.element = treeViewContainer; tree.needsDraw = true; }else{ var treeUl = treeViewContainer.getElementsByTagName("ul")[0]; if(!!treeUl){ treeUl.style.display = "none"; } this.spanEl = this.element.querySelector(".treeViewContainer").querySelector(".noResults"); if(!!this.spanEl){ this.spanEl.style.display = "block"; }else{ this.spanEl = document.createElement("span"); this.spanEl.className = "noResults"; this.spanEl.innerHTML = "no results"; this.spanEl.style.display = "block"; this.element.querySelector(".treeViewContainer").appendChild(this.spanEl); } status = false; //for no match } this.updateMetadata(uri); return status; } } }, updateMetadata:{ enumerable: false, writable:false, value:function(currentUri){ var data = this.application.ninja.filePickerController._directoryContentCache[currentUri]; var metadata = ""; if(!!data){ if(data.name !== ""){ metadata = "Name: "+data.name; } metadata = metadata + "<br />" + "Type: "+data.type; if(data.size){metadata = metadata + "<br />" + "Size: "+data.size;} if(data.creationDate){metadata = metadata + "<br />" + "Creation date: "+ this.formatTimestamp(data.creationDate);} if(data.modifiedDate){metadata = metadata + "<br />" + "Modified date: "+ this.formatTimestamp(data.modifiedDate);} } this.element.getElementsByClassName("right-bottom")[0].innerHTML = metadata; } }, isOutside:{ enumerable:true, value:function(el, targetEl){ var isOutside = true; if(el){ var childElements = el.getElementsByTagName("*");//get a flat NodeList of all the child elements if(childElements != null){ for(var i=0; i< childElements.length; i++){ if(childElements[i] === targetEl){//targetEl matches with an element inside the menu isOutside = false; break; } } } } return isOutside; } }, /** * convert timestamp to human readable form * * @param: timestamp - UTC milliseconds */ formatTimestamp:{ writable:false, enumerable: false, value: function(timestamp) { var aDate = new Date(); timestamp = timestamp - (aDate.getTimezoneOffset()*60*1000);//convert from GMT to local timestamp aDate = new Date(timestamp); return aDate.toLocaleString(); } }, /** * Event Listners */ addIdentifiers:{ value: function(){ this.element.identifier = "pickerNav"; //this.addressGo.identifier = "addressGo"; this.addressBarUri.identifier = "addressBarUri"; this.refreshButton.identifier = "refreshButton"; this.backArrow.identifier = "backArrow"; this.forwardArrow.identifier = "forwardArrow"; this.iconView.identifier = "iconView"; this.treeView.identifier = "treeView"; this.resultsArea.identifier = "resultsArea"; } }, handleTopLevelDirectoryClicks : { enumerable: true, writable: false, value : function(evt, dirObj){ this.currentURI = dirObj.uri; var status = this.pickerViews()[this.selectedPickerView].call(this, dirObj.uri);//dynamically calls the update function of the current picker view this.updateAddressBar(dirObj.uri); this.pickerModel.currentRoot = dirObj.uri; //populate history this.pickerModel.storeHistory(dirObj.uri); //disable forward button for explicit new urls if(!this.forwardArrow.classList.contains("disable")){ this.forwardArrow.classList.add("disable"); } //enable back button if required if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){ this.backArrow.classList.remove("disable"); } //dehighlight current selection and highlight new selection var currentHighlighted = evt.target.parentNode.querySelector(".highlighted"); if(!!currentHighlighted){ currentHighlighted.classList.remove("highlighted"); } if(!evt.target.classList.contains("highlighted")){ evt.target.classList.add("highlighted"); } //enable ok for logical drive selections, when in directory selection mode if(this.pickerModel.inFileMode === false){ this.okButton.removeAttribute("disabled"); //put into selectedItems..currently single selection is supported this.selectedItems = [dirObj.uri]; } } }, handlePickerNavOpenFolder: { value: function(evt){ this.currentURI = evt.folderUri; var status = this.pickerViews()[this.selectedPickerView].call(this, evt.folderUri);//dynamically calls the update function of the current picker view //update address-bar this.updateAddressBar(evt.folderUri); //populate history this.pickerModel.storeHistory(evt.folderUri); //disable forward button for explicit new urls if(!this.forwardArrow.classList.contains("disable")){ this.forwardArrow.classList.add("disable"); } //enable back button if required if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){ this.backArrow.classList.remove("disable"); } //for directory selection, selected url is the folder entered if(!this.pickerModel.inFileMode ){ this.okButton.removeAttribute("disabled"); //put into selectedItems..currently single selection is supported this.selectedItems = [evt.folderUri]; } } }, handlePickerNavSelectedItem: { value:function(evt){ var uri = evt.uri; //handle deselection of other icons for single selection if((this.currentSelectedNode !== null) && (this.currentSelectedNode !== evt.target) && (this.currentSelectedNode.classList.contains("selected"))){ this.currentSelectedNode.classList.remove("selected"); this.currentSelectedNode = null; } //enable OK button if the selection is valid as per the picker mode if((this.pickerModel.inFileMode && (this.application.ninja.filePickerController._directoryContentCache[uri].type === "file")) || (!this.pickerModel.inFileMode && (this.application.ninja.filePickerController._directoryContentCache[uri].type === "directory"))){ this.okButton.removeAttribute("disabled"); //put into selectedItems..currently single selection is supported this.selectedItems = [uri]; if(!evt.target.classList.contains("selected")){ evt.target.classList.add("selected"); } this.currentSelectedNode = evt.target; }else{ //test: highlight non-selectable icons too if(!evt.target.classList.contains("selected")){ evt.target.classList.add("selected"); } this.currentSelectedNode = evt.target; //end- test //disable OK if(!this.okButton.hasAttribute("disabled")){ this.okButton.setAttribute("disabled", "true"); } } } }, handlePickerNavShowMetadata: { value: function(evt){ //update matadata only if nothing is already selected if(this.currentSelectedNode == null){ //console.log("handle showmetadata - true"); this.metadataSection.innerHTML = evt.metadata; } } }, handlePickerNavUpdateMetadata:{ value: function(evt){ this.metadataSection.innerHTML = evt.metadata; } }, handleAddressGoClick :{ value: function(evt){ if(this.addressBarUri.value !== ""){ var uri = this.addressBarUri.value; uri = this.cleanupUri(uri); this.currentURI = uri; var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view //populate history this.pickerModel.storeHistory(uri); //disable forward button for explicit new urls if(!this.forwardArrow.classList.contains("disable")){ this.forwardArrow.classList.add("disable"); } //enable back button if required if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){ this.backArrow.classList.remove("disable"); } } } }, handleAddressBarUriKeydown:{ value: function(evt){ if(evt.keyCode === 13 ){ var uri = this.addressBarUri.value; uri = this.cleanupUri(uri); this.currentURI = uri; var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view //populate history this.pickerModel.storeHistory(uri); //disable forward button for explicit new urls if(!this.forwardArrow.classList.contains("disable")){ this.forwardArrow.classList.add("disable"); } //enable back button if required if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){ this.backArrow.classList.remove("disable"); } } } }, handleAddressBarUriKeyup:{ value: function(evt){ //disable ok if user enters an invalid uri if(!this.application.ninja.coreIoApi.isValidUri(this.addressBarUri.value)){ //disable OK if(!this.okButton.hasAttribute("disabled")){ this.okButton.setAttribute("disabled", "true"); } }else{ this.okButton.removeAttribute("disabled"); this.selectedItems = [this.addressBarUri.value]; } } }, handleRefreshButtonClick:{ value:function(evt){ var uri = this.addressBarUri.value; uri = this.cleanupUri(uri); var status = this.pickerViews()[this.selectedPickerView].call(this, uri, false);//dynamically calls the update function of the current picker view } }, handleBackArrowClick :{ value:function(evt){ var uri = ""; //console.log("*** backArrow: pointer ="+this.pickerModel.currentHistoryPointer); if(this.pickerModel.currentHistoryPointer >0){ uri = this.pickerModel._history[this.pickerModel.currentHistoryPointer -1]; //console.log("*** back uri= "+ uri); //console.log(this.pickerModel._history); this.currentURI = uri; var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view //update address-bar this.updateAddressBar(uri); this.pickerModel.currentHistoryPointer -= 1; //disable back button if it is at the beginning if((this.pickerModel.currentHistoryPointer === 0) && (!evt.target.classList.contains("disable"))){ evt.target.classList.add("disable"); } //enable forward button if required if((this.pickerModel.currentHistoryPointer < (this.pickerModel._history.length -1) && (this.forwardArrow.classList.contains("disable")))){ this.forwardArrow.classList.remove("disable"); } } //console.log("***new backArrow: pointer ="+this.pickerModel.currentHistoryPointer); } }, handleForwardArrowClick: { value:function(evt){ var uri = ""; //console.log("*** forwardArrow: pointer ="+this.pickerModel.currentHistoryPointer); if(this.pickerModel.currentHistoryPointer < (this.pickerModel._history.length -1)){ uri = this.pickerModel._history[this.pickerModel.currentHistoryPointer + 1]; //console.log("*** forward uri= "+ uri); //console.log(this.pickerModel._history); this.currentURI = uri; var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view //update address-bar this.updateAddressBar(uri); this.pickerModel.currentHistoryPointer += 1; //disable forward button if pointer is at the end if((this.pickerModel.currentHistoryPointer === (this.pickerModel._history.length -1)) && (!evt.target.classList.contains("disable"))){ evt.target.classList.add("disable"); } //enable back button if required if((this.pickerModel.currentHistoryPointer > 0) && (this.backArrow.classList.contains("disable"))){ this.backArrow.classList.remove("disable"); } } //console.log("***new forwardArrow: pointer ="+this.pickerModel.currentHistoryPointer); } }, handleOkButtonAction : { value: function(evt){ //console.log("$$$ File Picker : selected "+ this.selectedItems.toString()); var success = true; if(!!this.pickerModel.callback && (this.selectedItems.length > 0)){//call the callback if it is available try{ this.pickerModel.callback({"uri":this.selectedItems}); }catch(e){ success = false; console.log("[Error] Failed to open "+ this.selectedItems.toString()); console.log(e.stack); } }else{//else send an event with the selected files var pickerSelectionEvent = document.createEvent("Events"); pickerSelectionEvent.initEvent("pickerSelectionsDone", false, false); pickerSelectionEvent.selectedItems = this.selectedItems; this.eventManager.dispatchEvent(pickerSelectionEvent); } //store last opened/saved folder, and view after IO is successful var dataStore = window.sessionStorage; try { if(this.pickerModel.pickerMode === "write"){ dataStore.setItem('lastSavedFolderURI',escape(""+this.currentURI)); } else if(this.pickerModel.inFileMode === true){ dataStore.setItem('lastOpenedFolderURI_fileSelection',escape(""+this.currentURI)); }else if(this.pickerModel.inFileMode === false){ dataStore.setItem('lastOpenedFolderURI_folderSelection',escape(""+this.currentURI)); } } catch(e){ if(e.code == 22){ dataStore.clear(); } } this.cleanup();//clear up any unnecessary memory if(this.popup){ this.popup.hide(); } //end - close dialog } }, handleCancelButtonAction :{ value:function(evt){ //clean up memory this.cleanup(); if(this.popup){ this.popup.hide(); } } }, handleFilterClick:{ value: function(evt, aFilter, filtersDD){ this.pickerModel.currentFilter = aFilter; this.pickerViews()[this.selectedPickerView].call(this, this.currentURI);//dynamically calls the update function of the current picker view this.element.querySelector(".filters .filterVal").innerHTML = evt.target.innerHTML; filtersDD.classList.toggle("hide"); } }, handleAddressDropdownArrowClick:{ value: function(evt){ var that = this; //populate dropdown dynamically for addressbar var addressbarDD = this.element.querySelector(".addressbar .dropdown"); if((evt.target === this.element.querySelector(".addressbar .dropdownArrow")) && (addressbarDD.classList.contains("hide"))){//dropdown is closed //clear old dropdown contents while(addressbarDD.hasChildNodes()){ addressbarDD.removeChild(addressbarDD.lastChild); } var uriTrail = this.prepareAddressDropdownData(this.addressBarUri.value); if(uriTrail.length >0){ uriTrail.forEach(function(aUri){ var newDiv = document.createElement("div"); newDiv.innerHTML = aUri; addressbarDD.appendChild(newDiv); newDiv.addEventListener("click", function(evt){that.handleAddressTrailClick(evt, aUri, addressbarDD);}, false); }, this); } } //open close dropdown this.toggleDropdown(evt.target); } }, handleAddressTrailClick: { value: function(evt, aUri, addressbarDD){ this.currentURI = aUri; var status = this.pickerViews()[this.selectedPickerView].call(this, aUri);//dynamically calls the update function of the current picker view //populate history this.pickerModel.storeHistory(aUri); //disable forward button for explicit new urls if(!this.forwardArrow.classList.contains("disable")){ this.forwardArrow.classList.add("disable"); } //enable back button if required if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){ this.backArrow.classList.remove("disable"); } this.addressBarUri.value = evt.target.innerHTML; addressbarDD.classList.toggle("hide"); } }, handleIconViewClick :{ value:function(evt){ this.selectedPickerView = "iconView"; if(this.element.querySelector(".iconViewContainer").style.display === "none"){ //draw if icons list is not already drawn if(this.iconsViewDrawnOnce === false){ this.iconList = iconsListModule.IconsList.create(); this.iconList.iconsViewDataObject = that.mainContentData; this.iconList.element = that.iconViewContainer; this.iconList.needsDraw = true; this.iconsViewDrawnOnce = true; }else{ this.pickerViews()[this.selectedPickerView].call(this, this.currentURI); } this.element.querySelector(".iconViewContainer").style.display = "block"; } this.element.querySelector(".treeViewContainer").style.display = "none"; //enable selection if(!evt.target.classList.contains("viewSelected")){ evt.target.classList.add("viewSelected") } if(this.treeView.classList.contains("viewSelected")){ this.treeView.classList.remove("viewSelected"); } } }, handleTreeViewClick : { value:function(evt){ this.selectedPickerView = "treeView"; if(this.element.querySelector(".treeViewContainer").style.display === "none"){ this.pickerViews()[this.selectedPickerView].call(this, this.currentURI); this.element.querySelector(".treeViewContainer").style.display = "block"; } this.element.querySelector(".iconViewContainer").style.display = "none"; //enable selection if(!evt.target.classList.contains("viewSelected")){ evt.target.classList.add("viewSelected") } if(this.iconView.classList.contains("viewSelected")){ this.iconView.classList.remove("viewSelected"); } } }, handlePickerNavDrawTree:{ value: function(evt){ //toggle open or close for directory if(evt.uriType === "directory"){ this.renderTree(evt.subTreeContainer, evt.uri); } } }, handlePickerNavRefreshTreeSegment:{ value: function(evt){ // if(this.application.ninja.filePickerController.checkIfStale(evt.uri)){ // //update tree segment if was stale // evt.treeSegment.treeViewDataObject = this.application.ninja.filePickerController.prepareContentList(evt.uri, this.pickerModel, true, false); // } } }, handleResultsAreaClick: { value:function(evt){ //console.log("### clicked right-top"); if((evt.target.querySelectorAll(".icon").length > 1) || (evt.target.querySelectorAll(".atreeItem").length > 1)){//not clicked on an icon //console.log("@@ clicked in empty area"); this.clearSelection(); } } }, handlePickerNavClick:{ value: function(evt){ //console.log("### clicked picker"); this.closeDropdowns(evt.target); } }, getComputedWidth:{ value: function(element){ var calculatedWidth = "0px"; var orginalDisplay = element.style.display; var originalVisibility = element.style.visibility; element.style.display = "block"; element.style.visibility = "hidden"; calculatedWidth = window.getComputedStyle(element, null).getPropertyValue("width"); element.style.display = orginalDisplay; element.style.visibility = originalVisibility; return calculatedWidth; } }, cleanup:{ writable:false, enumerable:true, value:function(){ //clear memory - TODO:check for more memory leaks this.pickerModel = null; this.application.ninja.filePickerController._directoryContentCache = {}; //remove listeners this.element.removeEventListener("openFolder", this, false);//add icon double click event listener to reload iconList with new set of data this.element.removeEventListener("selectedItem", this, false);//for single selection only this.element.removeEventListener("showMetadata", this, false);//show metadata on hover of icon this.element.removeEventListener("updateMetadata", this, false);//show metadata on click of icon //this.addressGo.removeEventListener("click", this, false); this.addressBarUri.removeEventListener("keydown", this, false); this.refreshButton.removeEventListener("click", this, false);//refresh - gets from file system directly this.backArrow.removeEventListener("click", this, false); this.forwardArrow.removeEventListener("click", this, false); this.iconView.removeEventListener("click", this, false); this.treeView.removeEventListener("click", this, false); this.element.removeEventListener("drawTree", this, false); this.resultsArea.removeEventListener("click", this, false); this.element.removeEventListener("click", this, false); } } });