/* <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 TreeControl = require("js/components/tree.reel").Tree, ResizerControl = require("js/panels/Resizer").Resizer, nj = require("js/lib/NJUtils").NJUtils; exports.ProjectPanelBase = (require("montage/core/core").Montage).create(require("montage/ui/component").Component, { hasTemplate: { value: true }, _hasFocus: { numerable: false, value: false }, /* The current project that we have in memory */ _activeProject: { value: false }, activeProject: { get: function() { return this._activeProject; }, set: function(objNewProject) { this._activeProject = objNewProject; } }, /* Is the panel initialized? Helps keep us from re-initializing things when a project switches */ _isPanelInitialized: { value: false }, isPanelInitialized: { get: function() { return this._isPanelInitialized; }, set: function(boolValue) { this._isPanelInitialized = boolValue; } }, /* Project models: is there an active project, did the user just swap the project, etc. */ _swapProject: { value: false }, swapProject: { get: function() { return this._swapProject; }, set: function(boolValue) { this._swapProject = boolValue; } }, _updateTree: { value: false }, updateTree: { get: function() { return this._updateTree; }, set: function(boolValue) { this._updateTree = boolValue; } }, _updateAssets: { value: false }, _updateAssets : { get: function() { return this._updateAssets; }, set: function(boolValue) { this._updateAssets = boolValue; } }, _hasActiveProject: { value: false }, hasActiveProject: { get: function() { return this._hasActiveProject; }, set: function(boolValue) { if (this.hasActiveProject !== boolValue) { this._hasActiveProject = boolValue; this.needsDraw = true; this.swapProject = true; this.loadPanelState(); } } }, setActiveProject: { value: function(myVal) { this.hasActiveProject = myVal; } }, /* Focus monitor: needed to modify keyboard navigation through panels. */ _hasFocus: { value: false }, hasFocus: { get: function() { return this._hasFocus; }, set: function(newVal) { if (this._hasFocus !== newVal) { this._hasFocus = newVal; } } }, /* Active column models: Used to store the state of the columns as a resize is happening */ _activeColumn: { enumerable: false, value: false }, activeColumn: { get: function() { return this._activeColumn; }, set: function(intActiveColumn) { this._activeColumn = intActiveColumn; } }, _activeColumnWidths: { enumerable: false, value: [0,0,0] }, activeColumnWidths: { get: function() { return this._activeColumnWidths; }, set: function(activeColumnWidths) { for (var i = 0; i < activeColumnWidths.length; i++) { if (this._activeColumnWidths[i] !== activeColumnWidths[i]) { this._activeColumnWidths[i] = activeColumnWidths[i]; this.activeColumn = i; this.needsDraw = true; } } } }, /* resizeColumn: Method to resize a column */ resizeColumn: { value: function(strSelectorBase) { // Resize column with index this.activeColumn in view specified by strSelectorBase. var intAdjust = 0, intTotalWidth = 0, arrToChange = [], arrToChangeLength = 0, arrHeaders = document.querySelectorAll(strSelectorBase + " .pp-header"); arrHeadersLength = arrHeaders.length; containerList = document.querySelectorAll(strSelectorBase + " .pp-scroll-linked"); containerListLength = containerList.length, intNewWidth = 0, strNewWidth = "", boolProjectView = true, arrStoredWidths = this.panelState.projectColumnWidths; if (strSelectorBase.indexOf("assets") > -1) { boolProjectView = false; arrStoredWidths = this.panelState.assetColumnWidths; } if (this.activeColumn === 0) { strSelector = strSelectorBase + " .pp-col-files"; intAdjust = 17; } else if (this.activeColumn === 1) { strSelector = strSelectorBase + " .pp-col-date"; intAdjust = 6; } else if (this.activeColumn === 2) { strSelector = strSelectorBase + " .pp-col-size"; intAdjust = 6; } else if (this.activeColumn === 3) { strSelector = strSelectorBase + " .pp-col-type"; intAdjust = 10; } else { return; } if ((this.activeColumn === 3) && boolProjectView) { return; } // Adjust intAdjust: for the asset view it needs to be 0. if (strSelectorBase.indexOf("assets") >0) { intAdjust = 0; } // Get the total width of the headers and set the container to that width. for (i = 0; i < arrHeadersLength; i++) { intTotalWidth = intTotalWidth + parseInt(arrHeaders[i].offsetWidth); } if (intTotalWidth === 0) { for (i = 0; i < arrStoredWidths.length; i++) { intTotalWidth = intTotalWidth + arrStoredWidths[i]; } } for (i = 0; i < containerListLength; i++) { containerList[i].style.minWidth = (intTotalWidth+12) + "px"; } intNewWidth = arrHeaders[this.activeColumn].offsetWidth; if (intNewWidth === 0) { intNewWidth = arrStoredWidths[this.activeColumn]; } strNewWidth = (intNewWidth - intAdjust) + "px"; // Get the array of column elements to change, and change them arrToChange = document.querySelectorAll(strSelector); arrToChangeLength = arrToChange.length; for (i = 0; i < arrToChangeLength; i++) { arrToChange[i].style.width = strNewWidth; } // Once resize has been completed, we need to update the panelState object: if (!boolProjectView) { this.panelState.assetColumnWidths[this.activeColumn] = intNewWidth; } else { this.panelState.projectColumnWidths[this.activeColumn] = intNewWidth; } } }, /* checkForResize: Check if the columns in the active view are being resized */ checkForResize: { value: function() { var arrHeaders = document.querySelectorAll("#pp-view-" + this.panelState.activeView + " .pp-header"), arrHeadersLength = arrHeaders.length, i=0, colWidth = 0, arrCols = this.panelState.projectColumnWidths; if (this.panelState.activeView === "assets") { arrCols = this.panelState.assetColumnWidths; } for (i = 0; i < arrHeadersLength; i++) { colWidth = parseInt(arrHeaders[i].offsetWidth); if (colWidth !== arrCols[i]) { this.activeColumn = i; i = arrHeadersLength; this.needsDraw = true; } } } }, /* Shift key status: is the shift key pressed (used for keyboard navigation and multiselect) */ _isShiftKeyDown: { value: false }, isShiftKeyDown: { get: function() { return this._isShiftKeyDown; }, set: function(boolValue) { this._isShiftKeyDown = boolValue; } }, /* Inline editor models: is the inline editor active, and a pointer to the current one */ _activeInlineEditor: { value: false }, activeInlineEditor: { get: function() { return this._activeInlineEditor; }, set: function(myVal) { this._activeInlineEditor = myVal; } }, _isInlineEditorActive: { value: false }, isInlineEditorActive: { get: function() { return this._isInlineEditorActive; }, set: function(newVal) { this._isInlineEditorActive = newVal; } }, /* Active sort: If the user is actively sorting the columns in the asset view */ _isSortActive: { value: false }, isSortActive: { get: function() { return this._isSortActive; }, set: function(boolValue) { this._isSortActive = boolValue; if (boolValue) { this.needsDraw = true; } } }, /* Active filter: If the user is actively filtering the asset view */ _isFilterActive: { value: false }, isFilterActive: { get: function() { return this._isFilterActive; }, set: function(boolValue) { this._isFilterActive = boolValue; } }, /* filteredAssets: where the filtered assets live */ _filteredAssets: { value: [] }, filteredAssets: { get: function() { return this._filteredAssets; }, set: function(arrValues) { this._filteredAssets = arrValues; } }, /* filterAssets: Method for filtering the assets */ filterAssets: { value: function(strFilter) { var arrItems = document.querySelectorAll("#pp-container-assets .pp-col-files div"), arrItemsLength = arrItems.length, i = 0, arrFilteredAssets = []; for (i = 0; i < arrItemsLength; i++) { var currText = arrItems[i].querySelector(".inline-editable").firstChild.nodeValue; if (currText.indexOf(strFilter) > -1) { arrFilteredAssets.push(i); } } return arrFilteredAssets; } }, /* Asset Controllers: get first/last/previous/next visible asset, highlighting a row, and clearing a highlight */ getFirstVisibleAsset: { value: function() { var arrAssets = document.querySelectorAll("#pp-container-assets .pp-col-files div"), arrAssetsLength = arrAssets.length, i =0, cssProp = ""; for (i = 0; i < arrAssetsLength; i++) { cssProp = window.getComputedStyle(arrAssets[i],null).getPropertyValue("display"); if (cssProp == "block") { return arrAssets[i]; } } } }, getLastVisibleAsset: { value: function() { var arrAssets = document.querySelectorAll("#pp-container-assets .pp-col-files div"), arrAssetsLength = arrAssets.length, i = 0, cssProp = ""; for (i = arrAssetsLength; i >0; i--) { if (arrAssets[i] != null) { cssProp = window.getComputedStyle(arrAssets[i],null).getPropertyValue("display"); } if (cssProp == "block") { return arrAssets[i]; } } } }, getNextVisibleAsset: { value: function(currAsset) { var arrAssets = document.querySelectorAll("#pp-container-assets .pp-col-files div"), arrAssetsLength = arrAssets.length, i =0, cssProp = "", boolContinue = false; for (i = 0; i < arrAssetsLength; i++) { if (!boolContinue) { if (arrAssets[i].isSameNode(currAsset)) { boolContinue = true; } } else { cssProp = window.getComputedStyle(arrAssets[i],null).getPropertyValue("display"); if (cssProp == "block") { return arrAssets[i]; } } } // If we've got this far, there isn't one, so return false. return false; } }, getPreviousVisibleAsset: { value: function(currAsset) { var arrAssets = document.querySelectorAll("#pp-container-assets .pp-col-files div"), arrAssetsLength = arrAssets.length, i =0, cssProp = "", boolContinue = false; for (i = arrAssetsLength-1; i >-1 ; i--) { if (!boolContinue) { if (arrAssets[i].isSameNode(currAsset)) { boolContinue = true; } } else { cssProp = window.getComputedStyle(arrAssets[i],null).getPropertyValue("display"); if (cssProp == "block") { return arrAssets[i]; } } } // If we've got this far, there isn't one, so return false. return false; } }, hilightAssetRow: { value: function(ptrElement) { if (ptrElement.classList.contains("focused")) { return; } var arrFiles = document.querySelectorAll("#pp-view-assets .pp-col-files div"), arrFilesLength = arrFiles.length, arrSizes = document.querySelectorAll("#pp-view-assets .pp-col-size div"), arrSizesLength = arrSizes.length, arrDates = document.querySelectorAll("#pp-view-assets .pp-col-date div"), arrDatesLength = arrDates.length, arrTypes = document.querySelectorAll("#pp-view-assets .pp-col-type div"), arrTypesLength = arrTypes.length, inlineEditor = document.querySelector("#pp-view-assets input.inline-editor"), mySpan = ptrElement.querySelector("span"), currIndex, i = 0; ptrParent = nj.queryParentSelector(ptrElement, ".pp-asset-col"); if ((inlineEditor !== null) && (ptrElement.classList.contains("nj-skinned"))) { // An inline edit is currently happening // (sometimes the click event listeners might get fired in that process) // So do nothing return; } if (ptrParent.classList.contains("pp-col-files")) { for (i = 0; i < arrFilesLength; i++) { if(arrFiles[i].isSameNode(ptrElement)) { currIndex = i; i = arrFilesLength; } } } else if (ptrParent.classList.contains("pp-col-size")) { // A size element was passed in for (i = 0; i < arrSizesLength; i++) { if(arrSizes[i].isSameNode(ptrElement)) { currIndex = i; i = arrSizesLength; } } } else if (ptrParent.classList.contains("pp-col-type")) { // A type element was passed in for (i = 0; i < arrTypesLength; i++) { if(arrTypes[i].isSameNode(ptrElement)) { currIndex = i; i = arrTypesLength; } } } else if (ptrParent.classList.contains("pp-col-date")) { // A date element was passed in for (i = 0; i < arrDatesLength; i++) { if(arrDates[i].isSameNode(ptrElement)) { currIndex = i; i = arrDatesLength; } } } this.clearAssetFocus(); arrDates[currIndex].classList.add("focused"); arrFiles[currIndex].classList.add("focused"); arrSizes[currIndex].classList.add("focused"); arrTypes[currIndex].classList.add("focused"); // Turn the file name in into an inline editable element // To avoid getting caught in the current click event, we'll delay the // component initialization for a few milliseconds. var that = this; setTimeout(function() { that.activeInlineEditor = InlineEditor.create(); that.activeInlineEditor.element = arrFiles[currIndex]; that.activeInlineEditor.onChange = function() { that.updateTree = true; that.isSortActive = true; that.needsDraw = true; } that.activeInlineEditor.init(); that.isInlineEditorActive = true; // Bind the editor to the property in the data structure, so that when the change happens // it will propagate. Object.defineBinding(that.activeInlineEditor, "value", { boundObject: that.activeProject, boundObjectPropertyPath: mySpan.dataset.bindpath + ".name" }) }, 200); } }, clearAssetFocus: { value: function() { var arrCurrFocused = document.querySelectorAll("#pp-view-assets .focused"), arrCurrFocusedLength = arrCurrFocused.length, inlineEditor = document.querySelector("#pp-view-assets input.inline-editor"), i = 0; if (inlineEditor !== null ) { // an edit is happening, so we don't actually want to do anything. //return; } for (i = 0; i < arrCurrFocusedLength; i++) { arrCurrFocused[i].classList.remove("focused"); if (this.isInlineEditorActive !== false) { // TODO: A more bulletproof method for deleting this binding. This fails frequently and seemingly arbitrarily. //Object.deleteBinding(this.activeInlineEditor, "value"); this.activeInlineEditor.destroy(); this.isInlineEditorActive = false; } } } }, /* Begin: Draw Cycle */ /* First time draw: True if this is the first time the component has been drawn */ _firstTimeDraw: { value: true }, firstTimeDraw: { get: function() { return this._firstTimeDraw; }, set: function(value) { this._firstTimeDraw = value; } }, willDraw: { enumerable: false, value: function() { //this.log(newErr, "Test message " + newErr) //this.log("willDraw: hasActiveProject: " + this.hasActiveProject + "\nthis.swapProject: " + this.swapProject + "\nthis.firstTimeDraw: " + this.firstTimeDraw); var projectTree, testDirectory, treeContainer, scroller = document.getElementById("pp-col-files"), panelContainer = document.getElementById("pp-container"), arrButtons = document.querySelectorAll("#pp-col-buttons .pp-button"), listContainer = document.querySelector("#pp-container-list .pp-scroll-linked"), assetContainer = document.querySelector("#pp-container-assets .pp-scroll-linked"), arrButtonsLength = arrButtons.length, arrHeaders = document.querySelectorAll("#pp-view-assets .pp-header"), arrHeadersLength = arrHeaders.length, arrAllHeaders = document.querySelectorAll("#pp-col-files .pp-header"), arrAllHeadersLength = arrAllHeaders.length, tempResizer, arrSortArrows = document.querySelectorAll("#pp-view-assets .pp-sort-arrow"), arrSortArrowsLength = arrSortArrows.length, arrLinkedScrollers = document.querySelectorAll(".pp-scroll-main"), arrLinkedScrollersLength = arrLinkedScrollers.length, i = 0, that = this; /* if (this.firstTimeDraw) { this.hasActiveProject="large"; } */ if (!this.hasActiveProject) { var myContainer = document.getElementById("pp-container"); myContainer.classList.add("pp-disabled"); document.getElementById("pp-search-files").disabled=true; return; } else { var myContainer = document.getElementById("pp-container"); myContainer.classList.remove("pp-disabled"); document.getElementById("pp-search-files").disabled=false; } if (this.firstTimeDraw) { // Make headers resizable. for (i = 0; i < arrAllHeadersLength; i++) { tempResizer = ResizerControl.create(); tempResizer.element = arrAllHeaders[i].querySelector(".pp-resize-grip"); tempResizer.panel = arrAllHeaders[i]; tempResizer.isPanel = false; tempResizer.isInversed = false; this.eventManager.addEventListener("panelResizing", function() { that.checkForResize(); }); this.eventManager.addEventListener("panelResizedEnd", function() { that.checkForResize(); that.savePanelState(); }) /* tempResizer.onResize = function() { that.checkForResize(); } tempResizer.onResizeEnd = function() { setTimeout(function() { that.checkForResize(); that.savePanelState(); }, 100) } */ tempResizer.needsDraw = true; } // Add event handlers to buttons for (i = 0; i < arrButtonsLength; i++) { arrButtons[i].identifier="assetButton"; arrButtons[i].addEventListener("click", this, false); arrButtons[i].addEventListener("keydown", this, false); arrButtons[i].addEventListener("keyup", this, false); } // Add the click event listeners to the Asset View headers so they can be sorted for (i = 0; i < arrHeadersLength; i++) { arrHeaders[i].identifier="assetHeader"; arrHeaders[i].addEventListener("click", this, false); } for (i = 0; i < arrSortArrowsLength; i++) { arrSortArrows[i].identifier="assetHeader"; arrSortArrows[i].addEventListener("click", this, false); } // Add the event listener to the filter input so that when the user starts typing // we will start filtering the list var mySearch = document.getElementById("pp-search-files"), mySearchContainer = document.getElementById("pp-search"); mySearch.identifier = "filter"; mySearch.addEventListener("keyup", this, false); mySearchContainer.identifier = "searchContainer"; mySearchContainer.addEventListener("mousedown", this, false); mySearchContainer.addEventListener("keydown", this, false); mySearchContainer.addEventListener("keyup", this, false); // FYI when a search field is cleared using the built-in clearing method it fires a search event? mySearch.addEventListener("search", this, false); // Add keyboard event listeners for the asset container assetContainer.identifier = "assetContainer"; assetContainer.addEventListener("keydown", this, false); assetContainer.addEventListener("mousedown", this, false); assetContainer.addEventListener("keyup", this, false); // Add scroller for (i = 0; i < arrLinkedScrollersLength; i++) { arrLinkedScrollers[i].identifier = "linkedScroller"; arrLinkedScrollers[i].addEventListener("scroll", this, false); } // Add treeClickEvent handler document.addEventListener("treeClickEvent", function() { var arrDirs = document.querySelectorAll("#pp-view-project li.directory.open"), arrDirsLength = arrDirs.length, i = 0, arrUris = []; for (i = 0; i < arrDirsLength; i++) { arrUris.push(arrDirs[i].dataset.uri); } that.panelState.openFolders = arrUris; that.savePanelState(); }); } if (this.swapProject) { var arrCurrIcons = document.querySelectorAll(".pp-button.active"), arrCurrIconsLength = arrCurrIcons.length, i = 0; // TODO: real project fetching. if (this.hasActiveProject === "large") { testDirectory = this.getDirectoryData(false); } else { testDirectory = this.getDirectoryData(true); } // Clear the buttons. for (i = 0; i < arrCurrIconsLength; i++) { arrCurrIcons[i].classList.toggle("active"); } document.getElementById("pp-container-assets").removeAttribute("class"); // Set default view if (this.panelState.activeView === "project") { document.querySelector("#pp-view-assets").style.display = "none"; document.querySelector("#pp-view-project").style.display = "block" } else { document.querySelector("#pp-view-project").style.display = "none" document.querySelector("#pp-view-assets").style.display = "block"; } // Now build the asset view. First, get the flattened directory array this.getFlatDirectory(); // Set for active sort so that the view gets drawn this.isSortActive = true; // Set the tree update flag this.updateTree = true; } if (this.updateTree) { var myTree = document.getElementById("pp-container-tree"); // TODO: Make this better. if (myTree !== null) { var myGetme = document.getElementById("getme"); myGetme.removeChild(myTree); } // Insert the base element for the tree. treeContainer = document.createElement("ul"); treeContainer.setAttribute("id", "tree"); listContainer.appendChild(treeContainer); // Create the tree using the TreeControl projectTree = TreeControl.create(); projectTree.element = treeContainer; projectTree.jsonData = this.activeProject; projectTree.needsDraw = true; } } }, draw: { enumerable: false, value: function() { //this.log("draw: hasActiveProject: " + this.hasActiveProject + "\nthis.swapProject: " + this.swapProject + "\nthis.firstTimeDraw: " + this.firstTimeDraw); var arrToChange, arrToChangeLength, arrHeaders, arrHeadersLength, containerList, containerListLength, strSelector, intAdjust = 17, intTotalWidth = 0, errorMessage = document.querySelector("#pp-container-assets h3"), myAssetCol = document.querySelector("#pp-container-assets .pp-col-files"), filter = document.getElementById("pp-search-files"), filterValue = filter.value, i = 0, j=0, that = this; // Okay, so...what do we need to change? // Do we maybe need to resize the columns in a view? if (!this.firstTimeDraw) { if (this.activeColumn !== false) { this.resizeColumn("#pp-view-" + this.panelState.activeView); this.activeColumn = false; } } // Is there a sort event active? if (this.isSortActive) { // A sort is active, so we need to rebuild the asset view. var aFileCol = document.querySelector("#pp-view-assets .pp-col-files"), aSizeCol = document.querySelector("#pp-view-assets .pp-col-size"), aDateCol = document.querySelector("#pp-view-assets .pp-col-date"), aTypeCol = document.querySelector("#pp-view-assets .pp-col-type"), sortCol = document.querySelector("#pp-view-assets .pp-sort"), sortDirection = sortCol.dataset.direction, sortTarget = "", myColNumber = parseInt(sortCol.dataset.column), myFiles = this.arrFiles, myFilesLength = myFiles.length, i = 0, newFile, newFileContent, newSize, newSizeContent, newDate, newDateContent, newType, newTypeDiv, newTypeDivContent, newClass = "pp-type-other", typeScript = "css,scss,sass,htm,html,xhtm,xhtml,js,jscript,php", typeVideo = "mpeg,avi,qt,wmv", typeAudio = "mp3,mp4,wav", typeImage = "jpeg,jpg,png,gif,ps", typeFlash = "fla,swf", sortHandler = function(thisObject, thatObject) { var returnMultiplier = 1, thisThing, thatThing; // Ascending or Descending sort? if (sortDirection === "descending") { returnMultiplier = -1; } // Targets of size and modifiedDate need to be compared as integers, // otherwise we're doing string compares. if ((sortTarget === "size") || (sortTarget === "modifiedDate")) { thisThing = parseInt(thisObject[sortTarget]); thatThing = parseInt(thatObject[sortTarget]); } else if (sortTarget === "type"){ thisThing = thisObject.name.split(".").pop(); thatThing = thatObject.name.split(".").pop(); } else { thisThing = thisObject[sortTarget]; thatThing = thatObject[sortTarget]; } // Run the comparison. if (thisThing > thatThing) { return (1 * returnMultiplier); } else if (thisThing < thatThing) { return (-1 * returnMultiplier); } else { return 0; } }, makeFriendlySize = function(intSize) { var strSize = false, intRoundedSize = Math.round(intSize/1000); strSize = intRoundedSize + " K"; return strSize; }, makeFriendlyDate = function(intSeconds) { // TODO: Localization. var myDate = new Date(intSeconds), strDate = ""; strDate = (myDate.getMonth() + 1) + "/" + myDate.getDate() + "/" + myDate.getFullYear() + " " + myDate.toLocaleTimeString(); return strDate; }; // Set the sort target if (myColNumber === 0) { sortTarget = "name"; } else if (myColNumber === 1) { sortTarget = "modifiedDate"; } else if (myColNumber === 2) { sortTarget = "size"; } else if (myColNumber === 3) { sortTarget = "type"; } else { return; } // Sort the files object myFiles.sort(sortHandler); // Clear the columns and rebuild nj.empty(aFileCol); nj.empty(aSizeCol); nj.empty(aDateCol); nj.empty(aTypeCol); for (i = 0; i < myFilesLength; i ++) { newSpan = document.createElement("span"), newSpanContent = document.createTextNode(myFiles[i].name), newFile = document.createElement("div"), newSize = document.createElement("div"), newSizeContent = document.createTextNode(makeFriendlySize(parseInt(myFiles[i].size))), newDate = document.createElement("div"), newDateContent = document.createTextNode(makeFriendlyDate(parseInt(myFiles[i].modifiedDate))), newType = myFiles[i].name.split(".").pop().toLowerCase(), newTypeDiv = document.createElement("div"), newTypeDivContent = document.createTextNode(newType); newClass = "pp-type-other"; if (typeScript.indexOf(newType) > -1) { newClass = "pp-type-script"; } else if (typeVideo.indexOf(newType) > -1) { newClass = "pp-type-video"; } else if (typeAudio.indexOf(newType) > -1) { newClass="pp-type-audio"; } else if (typeImage.indexOf(newType) > -1) { newClass = "pp-type-image"; } else if (typeFlash.indexOf(newType) > -1) { newClass = "pp-type-flash"; } newSpan.setAttribute("class", "inline-editable"); newSpan.setAttribute("data-bindpath", myFiles[i].bindPath); newSpan.appendChild(newSpanContent); newFile.setAttribute("class", newClass); newFile.setAttribute("tabindex", 0); newSize.setAttribute("class", newClass); newDate.setAttribute("class", newClass); newTypeDiv.setAttribute("class", newClass); newFile.appendChild(newSpan); newSize.appendChild(newSizeContent); newDate.appendChild(newDateContent); newTypeDiv.appendChild(newTypeDivContent); aFileCol.appendChild(newFile); aSizeCol.appendChild(newSize); aDateCol.appendChild(newDate); aTypeCol.appendChild(newTypeDiv); } this.isSortActive = false; // Is there a filter we need to apply? if (filterValue != "") { this.filteredAssets = this.filterAssets(filterValue); this.isFilterActive = true; } } // Is there a filter event active? if (this.isFilterActive) { var arrAllAssets = document.querySelectorAll("#pp-container-assets .pp-asset-col div"), arrAllAssetsLength = arrAllAssets.length, arrFiles = document.querySelectorAll("#pp-container-assets .pp-col-files div"), arrSizes = document.querySelectorAll("#pp-container-assets .pp-col-size div"), arrDates = document.querySelectorAll("#pp-container-assets .pp-col-date div"), arrTypes = document.querySelectorAll("#pp-container-assets .pp-col-type div"), i = 0, filteredAssets = this.filteredAssets, filteredAssetsLength = filteredAssets.length; // First, hide everything. for (i = 0; i < arrAllAssetsLength; i++) { arrAllAssets[i].classList.add("pp-filter-hidden"); } // Then, show only what is needed. for (i = 0; i < filteredAssetsLength; i++) { var currentIndex = filteredAssets[i]; arrFiles[currentIndex].classList.remove("pp-filter-hidden"); arrSizes[currentIndex].classList.remove("pp-filter-hidden"); arrDates[currentIndex].classList.remove("pp-filter-hidden"); arrTypes[currentIndex].classList.remove("pp-filter-hidden"); } this.isFilterActive = false; } // Finally, now that all sorting and filtering is done, are we even showing anything in the asset view? if (this.panelState.activeView === "assets") { if (myAssetCol.offsetHeight < 5) { // We're not showing anything. errorMessage.style.display = "block"; } else { errorMessage.style.display = "none"; } } } }, didDraw: { enumerable: false, value: function() { var arrHeaders = document.querySelectorAll("#pp-view-assets .pp-header"), arrHeadersLength = arrHeaders.length, arrHeaderContainers = document.querySelectorAll(".pp-header-container"), arrHeaderContainersLength = arrHeaderContainers.length, i = 0, arrOpenFolders = [], arrOpenFoldersLength = 0, strSelector, myFolder, that = this, treeClickEvent = document.createEvent("UIEvents"); //this.log("didDraw: hasActiveProject: " + this.hasActiveProject + "\nthis.swapProject: " + this.swapProject + "\nthis.firstTimeDraw: " + this.firstTimeDraw); if (this.hasActiveProject) { for (i = 0; i < arrHeaderContainersLength; i++) { //this.log("showing headers"); arrHeaderContainers[i].style.display = "block"; } } else { for (i = 0; i < arrHeaderContainersLength; i++) { //this.log("hiding headers and ending draw cycle."); arrHeaderContainers[i].style.display = "none"; } return; } if (!this.firstTimeDraw) { if (!this.swapProject && !this.updateTree) { return; } } // On first draw or project swap we need to copy over the UI settings stored in panelState // First, load the panel state from storage, but only on first draw or swap. if (this.swapProject || this.firstDraw) { this.loadPanelState(); } arrOpenFolders = this.panelState.openFolders; arrOpenFoldersLength = arrOpenFolders.length; // Set up the project view. // Expand the folders var arrDefaultFolders = document.querySelectorAll("#pp-view-project li.directory.open"), arrDefaultFoldersLength = arrDefaultFolders.length; for (i = 0; i < arrDefaultFoldersLength; i ++) { arrDefaultFolders[i].classList.remove("open"); arrDefaultFolders[i].classList.add("closed"); } if (arrOpenFolders[0] === "none") { var arrFoldersToOpen = document.querySelectorAll(".level1"), arrFoldersToOpenLength = arrFoldersToOpen.length; for (i = 0; i < arrFoldersToOpenLength; i++) { arrFoldersToOpen[i].classList.remove("closed"); arrFoldersToOpen[i].classList.add("open"); } } else { for (i = 0; i < arrOpenFoldersLength; i++) { strSelector = "li[data-uri='" +arrOpenFolders[i]+ "'].directory"; myFolder = document.querySelector(strSelector); myFolder.classList.remove("closed"); myFolder.classList.add("open"); } } treeClickEvent.initEvent("treeClickEvent", false, false); document.dispatchEvent(treeClickEvent); // Set up the views if we are swapping projects. if (this.swapProject) { if (this.panelState.activeView === "assets") { var i =0, arrFilters = this.panelState.activeFilters, arrFiltersLength = arrFilters.length, myEvent = document.createEvent("MouseEvents"), arrHeaders = document.querySelectorAll("#pp-view-assets .pp-header"), arrHeadersLength = arrHeaders.length, currSort; for (i = 0; i < arrFiltersLength; i++) { // We will make the switch by displatching a click event through the showall button. myEvent.initMouseEvent("click", false, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); myTarget = document.querySelector(arrFilters[i]); myTarget.dispatchEvent(myEvent); } // Next, set the sort information. currSort = document.querySelector("#pp-view-assets .pp-sort"); currSort.classList.remove("pp-sort"); currSort.classList.remove("sort-ascending"); currSort.classList.remove("sort-descending"); arrHeaders(this.panelState.sortColumn).classList.add("pp-sort"); arrHeaders(this.panelState.sortColumn).classList.add("sort-" + this.panelState.sortDirection); this.isSortActive = true } else { var myEvent = document.createEvent("MouseEvents"); if (this.swapProject) { //this.log('clicking project button') myEvent.initMouseEvent("click", false, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); myTarget = document.querySelector("#pp-col-buttons .button-project"); myTarget.dispatchEvent(myEvent); } } } // Resize columns to match headers in assets view. arrHeaders = document.querySelectorAll("#pp-view-assets .pp-header"); arrHeadersLength = arrHeaders.length; for (i = 0; i < arrHeadersLength; i++) { arrHeaders[i].style.width = (this.panelState.assetColumnWidths[i] - 7) + "px"; } for (i = 0; i < this.panelState.assetColumnWidths.length; i++) { this.activeColumn = i; this.resizeColumn("#pp-view-assets"); } // Resize columns to match headers in project view. arrHeaders = document.querySelectorAll("#pp-view-project .pp-header"); arrHeadersLength = arrHeaders.length; for (i = 0; i < arrHeadersLength; i++) { arrHeaders[i].style.width = (this.panelState.projectColumnWidths[i] -7) + "px"; } setTimeout(function() { for (i = 0; i < that.panelState.projectColumnWidths.length; i++) { that.activeColumn = i; that.resizeColumn("#pp-view-project"); } that.activeColumn = false; }, 300) // If this is a first time draw or a draw because of a project swap, // we need to set the state of the model and redraw. this.firstTimeDraw = false; this.swapProject = false; this.updateTree = false; this.needsDraw = true; } }, /* End: Draw Cycle */ /* Begin: Event handlers */ handleLinkedScrollerScroll: { value: function(event) { var myParent = nj.queryParentSelector(event.target, ".pp-view"), myTarget = myParent.querySelector(".pp-header-container.pp-scroll-linked"), scrollOffset = event.target.scrollLeft; myTarget.style.left = (0 - scrollOffset) + "px"; } }, handleAssetContainerMousedown: { value: function(event) { var arrFiles = document.querySelectorAll("#pp-view-assets .pp-col-files div"), arrFilesLength = arrFiles.length, arrSizes = document.querySelectorAll("#pp-view-assets .pp-col-size div"), arrSizesLength = arrSizes.length, arrDates = document.querySelectorAll("#pp-view-assets .pp-col-date div"), arrDatesLength = arrDates.length, arrTypes = document.querySelectorAll("#pp-view-assets .pp-col-type div"), arrTypesLength = arrTypes.length, currIndex, i = 0, ptrElement = event.target, ptrParent = nj.queryParentSelector(ptrElement, ".pp-asset-col"); // Shift focus this.hasFocus = "assets"; if (ptrParent.classList.contains("pp-col-files")) { // highlight the entire row based on the file element that has focus. if (event.target.classList.contains("inline-editable")){ this.hilightAssetRow(event.target.parentNode); } else { this.hilightAssetRow(event.target); } return; } else if (ptrParent.classList.contains("pp-col-size")) { // A size element was passed in for (i = 0; i < arrSizesLength; i++) { if(arrSizes[i].isSameNode(ptrElement)) { currIndex = i; i = arrSizesLength; } } } else if (ptrParent.classList.contains("pp-col-type")) { // A type element was passed in for (i = 0; i < arrTypesLength; i++) { if(arrTypes[i].isSameNode(ptrElement)) { currIndex = i; i = arrTypesLength; } } } else if (ptrParent.classList.contains("pp-col-date")) { // A date element was passed in for (i = 0; i < arrDatesLength; i++) { if(arrDates[i].isSameNode(ptrElement)) { currIndex = i; i = arrDatesLength; } } } // Focus the element in arrFiles and then call the hilightAssetRow method, // which will highlight the entire row based on the file element that has focus. arrFiles[currIndex].focus(); this.hilightAssetRow(document.activeElement); } }, handleAssetContainerKeydown: { value: function(event) { var nextElement, currentFocusElement = event.currentTarget.querySelector(":focus"); // Down Arrow if (event.keyCode === 40) { // Prevent scroll. event.preventDefault(); if (!this.activeInlineEditor.isActive) { nextElement = this.getNextVisibleAsset(currentFocusElement); if (nextElement) { nextElement.focus(); this.hilightAssetRow(nextElement); } else { return; } } } // Up Arrow if (event.keyCode === 38) { // Prevent scroll. event.preventDefault(); if (!this.activeInlineEditor.isActive) { nextElement = this.getPreviousVisibleAsset(currentFocusElement); if (nextElement) { nextElement.focus(); this.hilightAssetRow(nextElement); } else { return; } } } // Left Arrow if (event.keyCode === 37) { if (!this.activeInlineEditor.isActive) { // Prevent scroll. event.preventDefault(); nextElement = document.querySelector("#projectPanel .button-project"); this.clearAssetFocus(); nextElement.focus(); } } // Right Arrow if (event.keyCode === 39) { if (!this.activeInlineEditor.isActive) { // Prevent scroll. event.preventDefault(); } } // Return Key if (event.keyCode === 13) { event.preventDefault(); } // Tab Key if (event.keyCode === 9) { if (!this.activeInlineEditor.isActive) { if (!this.isShiftKeyDown) { nextElement = this.getNextVisibleAsset(currentFocusElement); // Are we about to tab off the asset panel and into the search field? If so, nextElement will be false. if (!nextElement) { // We are leaving. this.clearAssetFocus(); // Shift focus this.hasFocus = "search"; } else { // We are staying. this.hilightAssetRow(nextElement); this.hasFocus = "assets"; } } else { nextElement = this.getPreviousVisibleAsset(currentFocusElement); // Are we about to tab off the asset panel and into the buttons? If so, nextElement will be false. if (!nextElement) { // We are leaving. this.clearAssetFocus(); this.hasFocus = "buttons"; } else { // We are staying. this.hilightAssetRow(nextElement); this.hasFocus = "assets"; } } } else { event.preventDefault(); } } // Shift key has been pressed. if (event.keyCode === 16) { this.isShiftKeyDown = true; } } }, handleAssetContainerKeyup : { value: function(event) { if (event.keyCode === 16) { this.isShiftKeyDown = false; } } }, /* handleFilterKeyup handles keyup events in the search box. */ handleFilterKeyup: { value: function(event) { if (!this.hasActiveProject) { return; } var myEvent, myTarget, strFilter; // Activate the filtering mechanism this.isFilterActive = true; // If we are not showing the Assets view already, we need to. if (document.querySelector("#pp-view-project").style.display === "block") { // We will make the switch by displatching a click event through the showall button. myEvent = document.createEvent("MouseEvents"); myEvent.initMouseEvent("click", false, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); myTarget = document.querySelector("#pp-col-buttons .button-showall"); myTarget.dispatchEvent(myEvent); } // Next, we need to filter using the delegate. strFilter = event.target.value; this.filteredAssets = this.filterAssets(strFilter); this.needsDraw = true; } }, handleFilterSearch: { value: function(event) { // The filter has been cleared by the user clicking on the clear icon in the input field. // Sometimes fired manually. if (event.target.value !== "") { // This event also fires when return is pressed in the search box // If that's the case, we don't want to do anything. return; } this.filteredAssets = this.filterAssets(""); this.isFilterActive = true; this.needsDraw = true; } }, handleSearchContainerKeydown: { value: function(event) { // Tab key if (event.keyCode === 9) { // Tabbing through the ui. Focus between search widget and asset container happens on the input field. if ((this.isShiftKeyDown) && (event.target.classList.contains("nj-skinned"))) { // We are leaving this.hasFocus = "assets"; var nextButton = this.getLastVisibleAsset(); this.hilightAssetRow(nextButton); } else if ((event.target.classList.contains("nj-skinned")) && (!this.isShiftKeyDown)){ this.hasFocus = "search"; } } // Shift key has been pressed. if (event.keyCode === 16) { this.isShiftKeyDown = true; } } }, handleSearchContainerKeyup: { value: function(event) { if (event.keyCode === 16) { this.isShiftKeyDown = false; } } }, handleSearchContainerMousedown: { value: function(event) { } }, handleAssetHeaderClick: { value: function(event) { var myTarget = event.currentTarget, myColNumber = parseInt(myTarget.dataset.column), arrHeaders = document.querySelectorAll("#pp-view-assets .pp-header"), arrHeadersLength = arrHeaders.length, i = 0, sortTarget = "", currentSortDirection = myTarget.dataset.direction, newSortDirection = "", prevColNumber = 0, sortHandler = function(thisObject, thatObject) { var returnMultiplier = 1; if (sortDirection === "descending") { returnMultiplier = -1; } if (thisObject[sortTarget] > thatObject[sortTarget]) { return (1 * returnMultiplier); } else if (thisObject[sortTarget] < thatObject[sortTarget]) { return (-1 * returnMultiplier); } else { return 0; } }; // Set the sort target if (myColNumber === 0) { sortTarget = "name"; } else if (myColNumber === 1) { sortTarget = "modifiedDate"; } else if (myColNumber === 2) { sortTarget = "size"; } else if (myColNumber === 3) { sortTarget = "type"; } else { return; } // Get the previous active sort for (i = 0; i < arrHeadersLength; i++) { if (arrHeaders[i].classList.contains("pp-sort")) { prevColNumber = i; } } // Click on same column as was previously active, or different column? if (prevColNumber === myColNumber) { // Same column, so we need to change sort direction and redraw. if (currentSortDirection === "ascending") { newSortDirection = "descending"; } else { newSortDirection = "ascending"; } myTarget.classList.remove("sort-" + currentSortDirection); myTarget.classList.add("sort-" + newSortDirection); myTarget.dataset.direction = newSortDirection; this.panelState.sortDirection = newSortDirection; } else { // Different column, so need to move classes. arrHeaders[prevColNumber].classList.remove("pp-sort"); arrHeaders[prevColNumber].classList.remove("sort-ascending"); arrHeaders[prevColNumber].classList.remove("sort-descending"); myTarget.classList.add("pp-sort"); myTarget.classList.add("sort-" + currentSortDirection); this.panelState.sortDirection = currentSortDirection; } this.panelState.sortColumn = myColNumber; this.isSortActive = true; this.savePanelState(); } }, handleAssetButtonKeydown: { value: function(event) { var myTarget = event.currentTarget, myColumn = document.getElementById("pp-col-buttons"), fileColumn = document.getElementById("pp-col-files"), assetView = document.getElementById("pp-view-assets"), projectView = document.getElementById("pp-view-project"), arrCurrIcons = myColumn.querySelectorAll(".pp-button.active"), arrCurrIconsLength = arrCurrIcons.length, nextButton = "", recursionBreak = 0, getNextElement = function(targetDiv) { // Convenience function to walk the nextSiblings and return the first // that is a real DOM element, as opposed to a fake sibling representing the // space between tags. var tempDiv; tempDiv = targetDiv.nextSibling; if (typeof(tempDiv.tagName) !== "undefined") { return tempDiv; } else { if (recursionBreak < 10) { recursionBreak = recursionBreak + 1; return getNextElement(tempDiv); } else { return false; } } }, getPreviousElement = function(targetDiv) { // Convenience function to walk the previousSiblings and return the first // that is a real DOM element, as opposed to a fake sibling representing the // space between tags. var tempDiv; tempDiv = targetDiv.previousSibling; if (typeof(tempDiv.tagName) !== "undefined") { return tempDiv; } else { if (recursionBreak < 10) { recursionBreak = recursionBreak + 1; return getPreviousElement(tempDiv); } else { return false; } } }; // Return key if (event.keyCode === 13) { this.handleAssetButtonClick(event); myTarget.focus(); } // Down Arrow if (event.keyCode === 40) { // Prevent scroll. event.preventDefault(); if (myTarget.classList.contains("button-showall")) { nextButton = myColumn.querySelector(".button-project"); } else { recursionBreak = 0; nextButton = getNextElement(myTarget); } if (nextButton.classList.contains("nj-divider")) { recursionBreak = 0; nextButton = getNextElement(nextButton); } nextButton.focus(); } // Up Arrow if (event.keyCode === 38) { // Prevent scroll. event.preventDefault(); if (myTarget.classList.contains("button-project")) { nextButton = myColumn.querySelector(".button-showall"); } else { recursionBreak = 0; nextButton = getPreviousElement(myTarget); } if (nextButton.classList.contains("nj-divider")) { nextButton = getPreviousElement(nextButton); } nextButton.focus(); } // Left Arrow if (event.keyCode === 37) { // Prevent scroll. event.preventDefault(); } // Right Arrow if (event.keyCode === 39) { // Prevent scroll. event.preventDefault(); if (projectView.style.display === "block") { nextButton = fileColumn.querySelector(".pp-span-all"); } else { nextButton = this.getFirstVisibleAsset(); this.hilightAssetRow(nextButton); } nextButton.focus(); } // Tab key if (event.keyCode === 9) { // Tabbing through the buttons. Focus between button column and asset container happens on the show all button. if ((myTarget.classList.contains("button-showall")) && (this.isShiftKeyDown)) { this.hasFocus = "buttons"; } else if ((myTarget.classList.contains("button-showall")) && (!this.isShiftKeyDown)){ this.hasFocus = "assets"; nextButton = this.getFirstVisibleAsset(); this.hilightAssetRow(nextButton); } } // Shift key has been pressed. if (event.keyCode === 16) { this.isShiftKeyDown = true; } } }, handleAssetButtonKeyup : { value: function(event) { if (event.keyCode === 16) { this.isShiftKeyDown = false; } } }, handleAssetButtonClick: { value: function(event) { if (!this.hasActiveProject) { return; } var myTarget = event.currentTarget, myColumn = document.getElementById("pp-col-buttons"), fileColumn = document.getElementById("pp-col-files"), viewProject = document.getElementById("pp-view-project"), viewAssets = document.getElementById("pp-view-assets"), containerAssets = document.getElementById("pp-container-assets"), arrCurrIcons = myColumn.querySelectorAll(".pp-button.active"), arrCurrIconsLength = arrCurrIcons.length, searchInput = document.getElementById("pp-search-files"); i = 0, arrButtons = []; // Shift focus this.hasFocus = "buttons"; // If we are in Asset View and there is currently a filter active, // we need to clear it. if (viewAssets.style.display === "block") { if ((searchInput.value != "") && (!this.isFilterActive)) { searchInput.value = ""; var myEvent = {}; myEvent.target = {}; myEvent.target.value = ""; this.handleFilterSearch(myEvent); } } if ((myTarget.classList.contains("button-showall")) || (myTarget.classList.contains("button-project"))) { if (myTarget.classList.contains ("active")) { // The user has clicked on an already-active icon, so do nothing. return; } for (var i = 0; i < arrCurrIconsLength; i++) { arrCurrIcons[i].classList.toggle("active"); } } else { for (i = 0; i < arrCurrIconsLength; i++) { if ((arrCurrIcons[i].classList.contains("button-showall")) || (arrCurrIcons[i].classList.contains("button-project"))) { arrCurrIcons[i].classList.toggle("active"); if (containerAssets.classList.contains("pp-show-all")) { containerAssets.classList.toggle("pp-show-all"); } } } if ((myTarget.classList.contains("active")) && (arrCurrIconsLength === 1)) { // We're clicking on the last active button in the asset view. We can't deactivate that one, so return. return; } } myTarget.classList.toggle("active"); //myTarget.blur(); arrCurrIcons = myColumn.querySelectorAll(".pp-button.active"); arrCurrIconsLength = arrCurrIcons.length; containerAssets.setAttribute("class", "pp-scroll-main"); for (i = 0; i < arrCurrIconsLength; i++) { if (arrCurrIcons[i].classList.contains("button-component")) { containerAssets.classList.add("pp-show-components"); arrButtons.push("#pp-col-buttons .button-component"); } if (arrCurrIcons[i].classList.contains("button-script")) { containerAssets.classList.add("pp-show-scripts"); arrButtons.push("#pp-col-buttons .button-script"); } if (arrCurrIcons[i].classList.contains("button-video")) { containerAssets.classList.add("pp-show-videos"); arrButtons.push("#pp-col-buttons .button-video"); } if (arrCurrIcons[i].classList.contains("button-audio")) { containerAssets.classList.add("pp-show-audio"); arrButtons.push("#pp-col-buttons .button-audio"); } if (arrCurrIcons[i].classList.contains("button-image")) { containerAssets.classList.add("pp-show-images"); arrButtons.push("#pp-col-buttons .button-image"); } if (arrCurrIcons[i].classList.contains("button-tag")) { containerAssets.classList.add("pp-show-tags"); arrButtons.push("#pp-col-buttons .button-tag"); } if (arrCurrIcons[i].classList.contains("button-flash")) { containerAssets.classList.add("pp-show-flash"); arrButtons.push("#pp-col-buttons .button-flash"); } } if (myTarget.classList.contains("button-showall")) { containerAssets.classList.add("pp-show-all"); arrButtons.push("#pp-col-buttons .button-showall"); } this.panelState.activeFilters = arrButtons; if (myTarget.classList.contains("button-project")) { // show the Project View viewProject.style.display = "block"; viewAssets.style.display = "none"; this.panelState.activeView = "project"; } else { // show the Asset View viewAssets.style.display = "block"; viewProject.style.display = "none"; this.needsDraw = true; this.panelState.activeView = "assets"; } // Store the current state. this.savePanelState(); } }, /* End: Interaction event handlers */ /* Begin: file handlers */ /* arrFiles: The flattened files array representing all the files in the project */ _arrFiles: { value: [] }, arrFiles: { get: function() { return this._arrFiles; }, set: function(arrFiles) { this._arrFiles = arrFiles; } }, /* Panel State: the stored values of the panel UI state. */ _panelState: { value: false }, panelState: { get: function() { return this._panelState; }, set: function(value) { this._panelState = value; } }, loadPanelState: { value: function() { var strState = localStorage.getItem("panelState"), objState, tempState, intState = 0; if (this.hasActiveProject === "small") { intState = 1; } if (strState === null) { objState = { "activeView" : "project", "sortColumn" : 0, "sortDirection" : "descending", "assetColumnWidths" : [167, 127, 57, 57], "projectColumnWidths" : [167, 127, 57], "activeFilters" : ["#pp-col-buttons .button-project"], "openFolders" : ["none"] } } else { tempState = JSON.parse(strState); if (intState >= tempState.length) { objState = { "activeView" : "project", "sortColumn" : 0, "sortDirection" : "descending", "assetColumnWidths" : [167, 127, 57, 57], "projectColumnWidths" : [167, 127, 57], "activeFilters" : ["#pp-col-buttons .button-project"], "openFolders" : ["none"] } } else { objState = tempState[intState]; //this.log("objstate is " + JSON.stringify(objState) + "\n\n") } } // After we go through all of that, it's possible we might still have a null objState. if (objState === null) { objState = { "activeView" : "project", "sortColumn" : 0, "sortDirection" : "descending", "assetColumnWidths" : [167, 127, 57, 57], "projectColumnWidths" : [167, 127, 57], "activeFilters" : ["#pp-col-buttons .button-project"], "openFolders" : ["none"] } } this.panelState = objState; } }, savePanelState: { value: function() { this.log('called') var strState = localStorage.getItem("panelState"), arrStates, intState = 0; if (this.hasActiveProject === "small") { intState = 1; } if (strState === null) { arrStates = []; } else { arrStates = JSON.parse(strState); } this.log("setting arrStates[" + intState + "] = " + JSON.stringify(this.panelState) + "\n\n"); arrStates[intState] = this.panelState; localStorage.setItem("panelState", JSON.stringify(arrStates)); } }, /* getFlatDirectory: Fill arrFiles from the data source */ getFlatDirectory: { value: function() { var myFiles = [], directory = this.getDirectoryData(false), strPath = "", flattenJson = function(jsonObject, intCounter) { if (intCounter !== false) { // strPath = strPath + "" + "children[" + intCounter+ "]"; strPath = strPath + "" + "children." + intCounter; } if (jsonObject.type === "file") { //jsonObject.type = jsonObject.name.split(".").pop(); jsonObject.extension = jsonObject.name.split(".").pop(); if (intCounter !== false) { jsonObject.bindPath = strPath; } myFiles.push(jsonObject); } else { if (jsonObject.children != null) { var oldPath = strPath; for (var i = 0; i < jsonObject.children.length; i++) { if (strPath !== "") { strPath = strPath + "."; } flattenJson(jsonObject.children[i], i) strPath = oldPath; } } } }; if (this.hasActiveProject === "small") { directory = this.getDirectoryData(true); } flattenJson(this.activeProject, false); this.arrFiles = myFiles; } }, getDirectoryData: { value: function(isSmall) { var ptrSearch = document.getElementById("pp-search-files"); ptrSearch.value = ""; if (isSmall) { this.activeProject = this.getSmallDirectory; } else { this.activeProject = this.getDirectory; } /* var file = {uri: ShellApi.openShellDialog({type: 'file', action: 'new'})}, type; var check = ShellApi.fileExists(file); */ return this.activeProject; } }, getSmallDirectory: { value: { "type":"directory", "name":"My Small Project", "uri":"C:/My Projects", "children":[ { "type":"file", "name":"My Test.html", "uri":"C:/My Projects/My Test.html", "size":"54", "creationDate":"1311732965939", "modifiedDate":"1311732965941" }, { "type":"directory", "name":"new-directory", "uri":"C:/My Projects/new-directory", "size":"120", "creationDate":"1311819825829", "modifiedDate":"1311819825899", "children": [ { "type":"file", "name":"test.mpeg", "uri":"C:/My Projects/Win/test.mp3g", "size":"213022", "creationDate":"1311901492048", "modifiedDate":"1310613500131" }, { "type":"file", "name":"test2.mp3", "uri":"C:/My Projects/Win/test2.mp3", "size":"134035", "creationDate":"1311901492054", "modifiedDate":"1310613500112" } ] }] } }, /* getDirectory: Get the directory information from the data source */ getDirectory: { value: { "type":"directory", "name":"My Large Project", "uri":"C:/My Projects", "children":[ { "type":"file", "name":"Test.html", "uri":"C:/My Projects/Test.html", "size":"54", "creationDate":"1311732965939", "modifiedDate":"1311732965941" }, { "type":"file", "name":"New File.html", "uri":"C:/My Projects/New File.html", "size":"120", "creationDate":"1311819825829", "modifiedDate":"1311819825899" }, { "type":"file", "name":"new.html", "uri":"C:/My Projects/new.html", "size":"120", "creationDate":"1311819641255", "modifiedDate":"1311819888049" } ] } }, /* End: file handlers */ /* Begin: Logging routines */ _boolDebug: { enumerable: false, value: false // set to true to enable debugging to console; false for turning off all debugging. }, boolDebug: { get: function() { return this._boolDebug; }, set: function(boolDebugSwitch) { this._boolDebug = boolDebugSwitch; } }, log: { value: function(strMessage) { if (this.boolDebug) { console.log(this.getLineNumber() + ": " + strMessage); } } }, getLineNumber: { value: function() { try { throw new Error('bazinga') }catch(e){ return e.stack.split("at")[3].split(":")[2]; } } } /* End: Logging routines */ });