@@ -75,6 +75,8 @@ define(function LiveDevelopment(require, exports, module) {
7575 var STATUS_SYNC_ERROR = exports . STATUS_SYNC_ERROR = 5 ;
7676
7777 var Async = require ( "utils/Async" ) ,
78+ CollectionUtils = require ( "utils/CollectionUtils" ) ,
79+ FileIndexManager = require ( "project/FileIndexManager" ) ,
7880 Dialogs = require ( "widgets/Dialogs" ) ,
7981 DefaultDialogs = require ( "widgets/DefaultDialogs" ) ,
8082 DocumentManager = require ( "document/DocumentManager" ) ,
@@ -566,7 +568,7 @@ define(function LiveDevelopment(require, exports, module) {
566568 // After (1) the interstitial page loads, (2) then browser navigation
567569 // to the base URL is completed, and (3) the agents finish loading
568570 // gather related documents and finally set status to STATUS_ACTIVE.
569- var doc = _getCurrentDocument ( ) ;
571+ var doc = _getCurrentDocument ( ) ; // TODO: probably wrong...
570572
571573 if ( doc ) {
572574 var status = STATUS_ACTIVE ,
@@ -611,6 +613,124 @@ define(function LiveDevelopment(require, exports, module) {
611613 return result . promise ( ) ;
612614 }
613615
616+ /**
617+ * @private
618+ * Determine an index file that can be used to start Live Development.
619+ * This function will inspect all files in a project to find the closest index file
620+ * available for currently opened document. We are searching for these files:
621+ * - index.html
622+ * - index.htm
623+ *
624+ * If the project is configured with a custom base url for live developmment, then
625+ * the list of possible index files is extended to contain these index files too:
626+ * - index.php
627+ * - index.php3
628+ * - index.php4
629+ * - index.php5
630+ * - index.phtm
631+ * - index.phtml
632+ * - index.cfm
633+ * - index.cfml
634+ * - index.asp
635+ * - index.aspx
636+ * - index.jsp
637+ * - index.jspx
638+ * - index.shm
639+ * - index.shml
640+ *
641+ * If a file was found, the promise will be resolved with the full path to this file. If no file
642+ * was found in the whole project tree, the promise will be resolved with null.
643+ *
644+ * @return {jQuery.Promise } A promise that is resolved with a full path
645+ * to a file if one could been determined, or null if there was no suitable index
646+ * file.
647+ */
648+ function _getInitialDocFromCurrent ( ) {
649+ var doc = _getCurrentDocument ( ) ,
650+ refPath ,
651+ i ;
652+
653+ // TODO: FileUtils.getParentFolder()
654+ function getParentFolder ( path ) {
655+ return path . substring ( 0 , path . lastIndexOf ( '/' , path . length - 2 ) + 1 ) ;
656+ }
657+
658+ function getFilenameWithoutExtension ( filename ) {
659+ var index = filename . lastIndexOf ( "." ) ;
660+ return index === - 1 ? filename : filename . slice ( 0 , index ) ;
661+ }
662+
663+ // Is the currently opened document already a file we can use for Live Development?
664+ if ( doc ) {
665+ refPath = doc . file . fullPath ;
666+ if ( FileUtils . isStaticHtmlFileExt ( refPath ) || FileUtils . isServerHtmlFileExt ( refPath ) ) {
667+ return new $ . Deferred ( ) . resolve ( doc ) ;
668+ }
669+ }
670+
671+ var result = new $ . Deferred ( ) ;
672+
673+ var baseUrl = ProjectManager . getBaseUrl ( ) ,
674+ hasOwnServerForLiveDevelopment = ( baseUrl && baseUrl . length ) ;
675+
676+ FileIndexManager . getFileInfoList ( "all" ) . done ( function ( allFiles ) {
677+ if ( refPath ) {
678+ var projectRoot = ProjectManager . getProjectRoot ( ) . fullPath ,
679+ containingFolder = FileUtils . getDirectoryPath ( refPath ) ,
680+ indexFileFound = false ,
681+ stillInProjectTree = true ;
682+
683+ var filteredFiltered = allFiles . filter ( function ( item ) {
684+ var parent = getParentFolder ( item . fullPath ) ;
685+
686+ return ( containingFolder . indexOf ( parent ) === 0 ) ;
687+ } ) ;
688+
689+ var filterIndexFile = function ( fileInfo ) {
690+ if ( fileInfo . fullPath . indexOf ( containingFolder ) === 0 ) {
691+ if ( getFilenameWithoutExtension ( fileInfo . name ) === "index" ) {
692+ if ( hasOwnServerForLiveDevelopment ) {
693+ if ( ( FileUtils . isServerHtmlFileExt ( fileInfo . name ) ) ||
694+ ( FileUtils . isStaticHtmlFileExt ( fileInfo . name ) ) ) {
695+ return true ;
696+ }
697+ } else if ( FileUtils . isStaticHtmlFileExt ( fileInfo . name ) ) {
698+ return true ;
699+ }
700+ } else {
701+ return false ;
702+ }
703+ }
704+ } ;
705+
706+ while ( ! indexFileFound && stillInProjectTree ) {
707+ i = CollectionUtils . indexOf ( filteredFiltered , filterIndexFile ) ;
708+
709+ // We found no good match
710+ if ( i === - 1 ) {
711+ // traverse the directory tree up one level
712+ containingFolder = getParentFolder ( containingFolder ) ;
713+ // Are we still inside the project?
714+ if ( containingFolder . indexOf ( projectRoot ) === - 1 ) {
715+ stillInProjectTree = false ;
716+ }
717+ } else {
718+ indexFileFound = true ;
719+ }
720+ }
721+
722+ if ( i !== - 1 ) {
723+ DocumentManager . getDocumentForPath ( filteredFiltered [ i ] . fullPath ) . then ( result . resolve , result . resolve ) ;
724+ return ;
725+ }
726+ }
727+
728+ result . resolve ( null ) ;
729+ } ) ;
730+
731+ return result . promise ( ) ;
732+ }
733+
614734 /**
615735 * @private
616736 * While still connected to the Inspector, do cleanup for agents,
@@ -819,17 +939,18 @@ define(function LiveDevelopment(require, exports, module) {
819939 // parallel.
820940 loadAgents ( ) ;
821941
822- var doc = _getCurrentDocument ( ) ;
823- if ( doc ) {
824- // Navigate from interstitial to the document
825- // Fires a frameNavigated event
826- Inspector . Page . navigate ( doc . url ) ;
827- } else {
828- // Unlikely that we would get to this state where
829- // a connection is in process but there is no current
830- // document
831- close ( ) ;
832- }
942+ _getInitialDocFromCurrent ( ) . done ( function ( doc ) {
943+ if ( doc ) {
944+ // Navigate from interstitial to the document
945+ // Fires a frameNavigated event
946+ Inspector . Page . navigate ( doc . url ) ;
947+ } else {
948+ // Unlikely that we would get to this state where
949+ // a connection is in process but there is no current
950+ // document
951+ close ( ) ;
952+ }
953+ } ) ;
833954 } ) ;
834955 }
835956
@@ -974,12 +1095,13 @@ define(function LiveDevelopment(require, exports, module) {
9741095
9751096 // helper function that actually does the launch once we are sure we have
9761097 // a doc and the server for that doc is up and running.
977- function _doLaunchAfterServerReady ( doc ) {
1098+ function _doLaunchAfterServerReady ( initialDoc ) {
9781099 // update status
9791100 _setStatus ( STATUS_CONNECTING ) ;
9801101
9811102 // create live document
982- _liveDocument = _createDocument ( doc , EditorManager . getCurrentFullEditor ( ) ) ;
1103+ initialDoc . _ensureMasterEditor ( ) ;
1104+ _liveDocument = _createDocument ( initialDoc , initialDoc . _masterEditor ) ;
9831105
9841106 // start listening for requests
9851107 _server . add ( _liveDocument ) ;
@@ -1037,18 +1159,25 @@ define(function LiveDevelopment(require, exports, module) {
10371159 /** Open the Connection and go live */
10381160 function open ( ) {
10391161 _openDeferred = new $ . Deferred ( ) ;
1040-
1041- var doc = _getCurrentDocument ( ) ,
1042- prepareServerPromise = ( doc && _prepareServer ( doc ) ) || new $ . Deferred ( ) . reject ( ) ;
10431162
1044- // wait for server (StaticServer, Base URL or file:)
1045- prepareServerPromise . done ( function ( result ) {
1046- _doLaunchAfterServerReady ( doc ) ;
1047- } ) ;
1048-
1049- prepareServerPromise . fail ( function ( ) {
1050- _showWrongDocError ( ) ;
1051- _openDeferred . reject ( ) ;
1163+ // TODO: need to run _onDocumentChange() after load if doc != currentDocument here? Maybe not, since activeEditorChange
1164+ // doesn't trigger it, while inline editors can still cause edits in doc other than currentDoc...
1165+ _getInitialDocFromCurrent ( ) . done ( function ( doc ) {
1166+ var prepareServerPromise = ( doc && _prepareServer ( doc ) ) || new $ . Deferred ( ) . reject ( ) ;
1167+
1168+ if ( doc && ! doc . _masterEditor ) {
1169+ DocumentManager . addToWorkingSet ( doc . file ) ;
1170+ }
1171+
1172+ // wait for server (StaticServer, Base URL or file:)
1173+ prepareServerPromise
1174+ . done ( function ( ) {
1175+ _doLaunchAfterServerReady ( doc ) ;
1176+ } )
1177+ . fail ( function ( ) {
1178+ _showWrongDocError ( ) ;
1179+ _openDeferred . reject ( ) ;
1180+ } ) ;
10521181 } ) ;
10531182
10541183 return _openDeferred . promise ( ) ;
@@ -1181,8 +1310,9 @@ define(function LiveDevelopment(require, exports, module) {
11811310 }
11821311
11831312 // For unit testing
1184- exports . launcherUrl = launcherUrl ;
1185- exports . _getServer = _getServer ;
1313+ exports . launcherUrl = launcherUrl ;
1314+ exports . _getServer = _getServer ;
1315+ exports . _getInitialDocFromCurrent = _getInitialDocFromCurrent ;
11861316
11871317 // Export public functions
11881318 exports . agents = agents ;
0 commit comments