11/*
2- * Copyright (c) 2012 - present Adobe Systems Incorporated. All rights reserved.
2+ * Copyright (c) 2021 - present core.ai . All rights reserved.
3+ * Copyright (c) 2012 - 2021 Adobe Systems Incorporated. All rights reserved.
34 *
45 * Permission is hereby granted, free of charge, to any person obtaining a
56 * copy of this software and associated documentation files (the "Software"),
2930 * "loadFailed" - when an extension load is unsuccessful. The second argument is the file path to the
3031 * extension root.
3132 */
33+ // jshint ignore: start
34+ /*global fs, Phoenix*/
35+ /*eslint-env es6*/
36+ /*eslint no-console: 0*/
37+ /*eslint strict: ["error", "global"]*/
3238
3339define ( function ( require , exports , module ) {
3440
@@ -58,6 +64,8 @@ define(function (require, exports, module) {
5864 */
5965 var contexts = { } ;
6066
67+ var pathLib = Phoenix . VFS . path ;
68+
6169 // The native directory path ends with either "test" or "src". We need "src" to
6270 // load the text and i18n modules.
6371 srcPath = srcPath . replace ( / \/ t e s t $ / , "/src" ) ; // convert from "test" to "src"
@@ -72,10 +80,17 @@ define(function (require, exports, module) {
7280 } ) ;
7381
7482 /**
75- * Returns the full path to the default extensions directory.
83+ * Returns the path to the default extensions directory relative to window.location.href
7684 */
7785 function getDefaultExtensionPath ( ) {
78- return FileUtils . getNativeBracketsDirectoryPath ( ) + "/extensions/default" ;
86+ return pathLib . normalize ( "/extensions/default" ) ;
87+ }
88+
89+ /**
90+ * Returns the full path to the development extensions directory.
91+ */
92+ function getDevExtensionPath ( ) {
93+ return pathLib . normalize ( brackets . app . getApplicationSupportDirectory ( ) + "/extensions/dev" ) ;
7994 }
8095
8196 /**
@@ -86,7 +101,7 @@ define(function (require, exports, module) {
86101 */
87102 function getUserExtensionPath ( ) {
88103 if ( brackets . app . getApplicationSupportDirectory ) {
89- return brackets . app . getApplicationSupportDirectory ( ) + "/extensions/user" ;
104+ return pathLib . normalize ( brackets . app . getApplicationSupportDirectory ( ) + "/extensions/user" ) ;
90105 }
91106
92107 return null ;
@@ -121,13 +136,48 @@ define(function (require, exports, module) {
121136 _initExtensionTimeout = value ;
122137 }
123138
139+ /**
140+ * @private
141+ * Loads optional requirejs-config.json file for an extension
142+ * @param {Object } baseConfig
143+ * @return {$.Promise }
144+ */
145+ function _mergeConfigFromURL ( baseConfig ) {
146+ var deferred = new $ . Deferred ( ) ,
147+ extensionConfigFile = baseConfig . baseUrl + "/requirejs-config.json" ;
148+
149+ // Optional JSON config for require.js
150+ $ . get ( extensionConfigFile ) . done ( function ( extensionConfig ) {
151+ try {
152+ // baseConfig.paths properties will override any extension config paths
153+ _ . extend ( extensionConfig . paths , baseConfig . paths ) ;
154+
155+ // Overwrite baseUrl, context, locale (paths is already merged above)
156+ _ . extend ( extensionConfig , _ . omit ( baseConfig , "paths" ) ) ;
157+
158+ deferred . resolve ( extensionConfig ) ;
159+ } catch ( err ) {
160+ // Failed to parse requirejs-config.json
161+ deferred . reject ( "failed to parse requirejs-config.json" ) ;
162+ }
163+ } ) . fail ( function ( ) {
164+ // If requirejs-config.json isn't specified, resolve with the baseConfig only
165+ deferred . resolve ( baseConfig ) ;
166+ } ) ;
167+
168+ return deferred . promise ( ) ;
169+ }
170+
124171 /**
125172 * @private
126173 * Loads optional requirejs-config.json file for an extension
127174 * @param {Object } baseConfig
128175 * @return {$.Promise }
129176 */
130177 function _mergeConfig ( baseConfig ) {
178+ if ( baseConfig . baseUrl . startsWith ( "http://" ) || baseConfig . baseUrl . startsWith ( "https://" ) ) {
179+ return _mergeConfigFromURL ( baseConfig ) ;
180+ }
131181 var deferred = new $ . Deferred ( ) ,
132182 extensionConfigFile = FileSystem . getFileForPath ( baseConfig . baseUrl + "/requirejs-config.json" ) ;
133183
@@ -249,7 +299,7 @@ define(function (require, exports, module) {
249299 var promise = new $ . Deferred ( ) ;
250300
251301 // Try to load the package.json to figure out if we are loading a theme.
252- ExtensionUtils . loadMetadata ( config . baseUrl ) . always ( promise . resolve ) ;
302+ ExtensionUtils . loadMetadata ( config . baseUrl , name ) . always ( promise . resolve ) ;
253303
254304 return promise
255305 . then ( function ( metadata ) {
@@ -358,6 +408,40 @@ define(function (require, exports, module) {
358408 return result . promise ( ) ;
359409 }
360410
411+ /**
412+ * Loads All brackets default extensions from brackets base https URL.
413+ *
414+ * @return {!$.Promise } A promise object that is resolved when all extensions complete loading.
415+ */
416+ function loadAllDefaultExtensions ( ) {
417+ const extensionPath = getDefaultExtensionPath ( ) ;
418+ const href = window . location . href ;
419+ const baseUrl = href . substring ( 0 , href . lastIndexOf ( "/" ) ) ;
420+ const extensionsToLoadURL = baseUrl + extensionPath + "/DefaultExtensions.json" ;
421+ var result = new $ . Deferred ( ) ;
422+
423+ $ . get ( extensionsToLoadURL ) . done ( function ( extensionNames ) {
424+ Async . doInParallel ( extensionNames , function ( extensionName ) {
425+ console . log ( "loading default extension: " , extensionName ) ;
426+ var extConfig = {
427+ baseUrl : baseUrl + extensionPath + "/" + extensionName
428+ } ;
429+ return loadExtension ( extensionName , extConfig , 'main' ) ;
430+ } ) . always ( function ( ) {
431+ // Always resolve the promise even if some extensions had errors
432+ result . resolve ( ) ;
433+ } ) ;
434+
435+ } )
436+ . fail ( function ( err ) {
437+ console . error ( "[Extension] Error -- could not read default extension list from" + extensionsToLoadURL ) ;
438+ result . reject ( ) ;
439+ } ) ;
440+
441+ return result . promise ( ) ;
442+
443+ }
444+
361445 /**
362446 * Loads the extension that lives at baseUrl into its own Require.js context
363447 *
@@ -409,13 +493,10 @@ define(function (require, exports, module) {
409493 if ( ! paths ) {
410494 params . parse ( ) ;
411495
412- if ( params . get ( "reloadWithoutUserExts" ) === "true" ) {
413- paths = [ "default" ] ;
414- } else {
496+ if ( params . get ( "reloadWithoutUserExts" ) !== "true" ) {
415497 paths = [
416- getDefaultExtensionPath ( ) ,
417- "dev" ,
418- getUserExtensionPath ( )
498+ getUserExtensionPath ( ) ,
499+ getDevExtensionPath ( )
419500 ] ;
420501 }
421502 }
@@ -431,20 +512,15 @@ define(function (require, exports, module) {
431512 // during extension loading.
432513 var extensionPath = getUserExtensionPath ( ) ;
433514 FileSystem . getDirectoryForPath ( extensionPath ) . create ( ) ;
515+ FileSystem . getDirectoryForPath ( getDevExtensionPath ( ) ) . create ( ) ;
434516
435517 // Create the extensions/disabled directory, too.
436518 var disabledExtensionPath = extensionPath . replace ( / \/ u s e r $ / , "/disabled" ) ;
437519 FileSystem . getDirectoryForPath ( disabledExtensionPath ) . create ( ) ;
438520
439- var promise = Async . doSequentially ( paths , function ( item ) {
440- var extensionPath = item ;
441-
442- // If the item has "/" in it, assume it is a full path. Otherwise, load
443- // from our source path + "/extensions/".
444- if ( item . indexOf ( "/" ) === - 1 ) {
445- extensionPath = FileUtils . getNativeBracketsDirectoryPath ( ) + "/extensions/" + item ;
446- }
521+ loadAllDefaultExtensions ( ) ;
447522
523+ var promise = Async . doSequentially ( paths , function ( extensionPath ) {
448524 return loadAllExtensionsInNativeDirectory ( extensionPath ) ;
449525 } , false ) ;
450526
0 commit comments