@@ -515,9 +515,82 @@ define(function (require, exports, module) {
515515 this . _viewListAddedOrder = [ ] ;
516516 this . _views = { } ;
517517 this . _currentView = null ;
518+ this . _pinnedPaths = new Set ( ) ;
518519 this . showInterstitial ( true ) ;
519520 } ;
520521
522+ /**
523+ * this pins a file path
524+ * @param {string } path - the full path of the file to pin
525+ * @return {boolean } true if the file was pinned, false if it was already pinned or not in the view list
526+ */
527+ Pane . prototype . pinPath = function ( path ) {
528+ // check if already pinned, if it is then ignore
529+ if ( this . isPathPinned ( path ) ) {
530+ return false ;
531+ }
532+
533+ // check if the file is present in the open view list, if not then also ignore
534+ const index = this . findInViewList ( path ) ;
535+ if ( index === - 1 ) {
536+ return false ;
537+ }
538+
539+ // add the file path to the pinned paths set
540+ // we also reorder the view list as pinned files should appear before regular files
541+ this . _pinnedPaths . add ( path ) ;
542+ this . _reorderViewListForPinning ( ) ;
543+ return true ;
544+ } ;
545+
546+ /**
547+ * this unpins a file path.
548+ * @param {string } path - the full path of the file to unpin
549+ * @return {boolean } true if the file was unpinned, false if it wasn't pinned
550+ */
551+ Pane . prototype . unpinPath = function ( path ) {
552+ // if the file is already unpinned, we just ignore
553+ if ( ! this . isPathPinned ( path ) ) {
554+ return false ;
555+ }
556+
557+ // we just remove the file path from the pinned paths set
558+ // here we don't need to reorder the view list, the file can stay in its current position
559+ this . _pinnedPaths . delete ( path ) ;
560+ return true ;
561+ } ;
562+
563+ /**
564+ * checks if a file path is pinned
565+ * @param {string } path - the full path of the file
566+ * @return {boolean } true if the file is pinned false otherwise
567+ */
568+ Pane . prototype . isPathPinned = function ( path ) {
569+ return this . _pinnedPaths . has ( path ) ;
570+ } ;
571+
572+ /**
573+ * this function is responsible to reorder the view list such that pinned files appear first
574+ * the pinned files and regular files both maintain their relative order
575+ * @private
576+ */
577+ Pane . prototype . _reorderViewListForPinning = function ( ) {
578+ const self = this ;
579+
580+ this . _viewList . sort ( function ( a , b ) {
581+ // just the regular comparison sorting logic based on whether the files are pinned or not
582+ const aPinned = self . _pinnedPaths . has ( a . fullPath ) ;
583+ const bPinned = self . _pinnedPaths . has ( b . fullPath ) ;
584+ if ( aPinned && ! bPinned ) {
585+ return - 1 ;
586+ }
587+ if ( ! aPinned && bPinned ) {
588+ return 1 ;
589+ }
590+ return 0 ;
591+ } ) ;
592+ } ;
593+
521594 /**
522595 * Creates a pane event namespaced to this pane
523596 * (pass an empty string to generate just the namespace key to pass to jQuery to turn off all events handled by this pane)
@@ -948,6 +1021,8 @@ define(function (require, exports, module) {
9481021 this . _viewList . splice ( index , 1 ) ;
9491022 this . _viewListMRUOrder . splice ( this . findInViewListMRUOrder ( file . fullPath ) , 1 ) ;
9501023 this . _viewListAddedOrder . splice ( this . findInViewListAddedOrder ( file . fullPath ) , 1 ) ;
1024+ // also remove from pinned paths if it was pinned
1025+ this . _pinnedPaths . delete ( file . fullPath ) ;
9511026 }
9521027
9531028 // Destroy the view
@@ -1514,6 +1589,7 @@ define(function (require, exports, module) {
15141589 Pane . prototype . loadState = function ( state ) {
15151590 var filesToAdd = [ ] ,
15161591 viewStates = { } ,
1592+ pinnedPaths = [ ] ,
15171593 activeFile ,
15181594 data ,
15191595 self = this ;
@@ -1530,10 +1606,22 @@ define(function (require, exports, module) {
15301606 if ( entry . viewState ) {
15311607 viewStates [ entry . file ] = entry . viewState ;
15321608 }
1609+ if ( entry . pinned ) {
1610+ pinnedPaths . push ( entry . file ) ;
1611+ }
15331612 } ) ;
15341613
15351614 this . addListToViewList ( filesToAdd ) ;
15361615
1616+ // restore pinned state
1617+ pinnedPaths . forEach ( function ( path ) {
1618+ self . _pinnedPaths . add ( path ) ;
1619+ } ) ;
1620+ // reorder to put pinned files first
1621+ if ( pinnedPaths . length > 0 ) {
1622+ this . _reorderViewListForPinning ( ) ;
1623+ }
1624+
15371625 ViewStateManager . addViewStates ( viewStates ) ;
15381626
15391627 activeFile = activeFile || getInitialViewFilePath ( ) ;
@@ -1551,6 +1639,7 @@ define(function (require, exports, module) {
15511639 */
15521640 Pane . prototype . saveState = function ( ) {
15531641 var result = [ ] ,
1642+ self = this ,
15541643 currentlyViewedPath = this . getCurrentlyViewedPath ( ) ;
15551644
15561645 // Save the current view state first
@@ -1570,7 +1659,8 @@ define(function (require, exports, module) {
15701659 result . push ( {
15711660 file : file . fullPath ,
15721661 active : ( file . fullPath === currentlyViewedPath ) ,
1573- viewState : ViewStateManager . getViewState ( file )
1662+ viewState : ViewStateManager . getViewState ( file ) ,
1663+ pinned : self . _pinnedPaths . has ( file . fullPath )
15741664 } ) ;
15751665 }
15761666 } ) ;
0 commit comments