11/* global __resourceQuery, __webpack_hash__ */ 
22/// <reference types="webpack/module" /> 
33import  webpackHotLog  from  "webpack/hot/log.js" ; 
4- import  parseURL  from  "./utils/parseURL.js" ; 
54import  socket  from  "./socket.js" ; 
65import  {  formatProblem ,  createOverlay  }  from  "./overlay.js" ; 
7- import  {  log ,  logEnabledFeatures ,   setLogLevel  }  from  "./utils/log.js" ; 
6+ import  {  log ,  setLogLevel  }  from  "./utils/log.js" ; 
87import  sendMessage  from  "./utils/sendMessage.js" ; 
98import  reloadApp  from  "./utils/reloadApp.js" ; 
109import  {  isProgressSupported ,  defineProgressElement  }  from  "./progress.js" ; 
@@ -46,13 +45,11 @@ const decodeOverlayOptions = (overlayOptions) => {
4645        ) ; 
4746
4847        // eslint-disable-next-line no-new-func 
49-         const   overlayFilterFunction  =  new  Function ( 
48+         overlayOptions [ property ]  =  new  Function ( 
5049          "message" , 
5150          `var callback = ${ overlayFilterFunctionString }  
5251        return callback(message)` , 
5352        ) ; 
54- 
55-         overlayOptions [ property ]  =  overlayFilterFunction ; 
5653      } 
5754    } ) ; 
5855  } 
@@ -67,13 +64,75 @@ const status = {
6764  currentHash : __webpack_hash__ , 
6865} ; 
6966
70- /** @type  {Options } */ 
71- const  options  =  { 
72-   hot : false , 
73-   liveReload : false , 
74-   progress : false , 
75-   overlay : false , 
67+ /** 
68+  * @returns  {string } 
69+  */ 
70+ const  getCurrentScriptSource  =  ( )  =>  { 
71+   // `document.currentScript` is the most accurate way to find the current script, 
72+   // but is not supported in all browsers. 
73+   if  ( document . currentScript )  { 
74+     return  document . currentScript . getAttribute ( "src" ) ; 
75+   } 
76+ 
77+   // Fallback to getting all scripts running in the document. 
78+   const  scriptElements  =  document . scripts  ||  [ ] ; 
79+   const  scriptElementsWithSrc  =  Array . prototype . filter . call ( 
80+     scriptElements , 
81+     ( element )  =>  element . getAttribute ( "src" ) , 
82+   ) ; 
83+ 
84+   if  ( scriptElementsWithSrc . length  >  0 )  { 
85+     const  currentScript  = 
86+       scriptElementsWithSrc [ scriptElementsWithSrc . length  -  1 ] ; 
87+ 
88+     return  currentScript . getAttribute ( "src" ) ; 
89+   } 
90+ 
91+   // Fail as there was no script to use. 
92+   throw  new  Error ( "[webpack-dev-server] Failed to get current script source." ) ; 
93+ } ; 
94+ 
95+ /** 
96+  * @param  {string } resourceQuery 
97+  * @returns  {{ [key: string]: string | boolean } } 
98+  */ 
99+ const  parseURL  =  ( resourceQuery )  =>  { 
100+   /** @type  {{ [key: string]: string } } */ 
101+   let  result  =  { } ; 
102+ 
103+   if  ( typeof  resourceQuery  ===  "string"  &&  resourceQuery  !==  "" )  { 
104+     const  searchParams  =  resourceQuery . slice ( 1 ) . split ( "&" ) ; 
105+ 
106+     for  ( let  i  =  0 ;  i  <  searchParams . length ;  i ++ )  { 
107+       const  pair  =  searchParams [ i ] . split ( "=" ) ; 
108+ 
109+       result [ pair [ 0 ] ]  =  decodeURIComponent ( pair [ 1 ] ) ; 
110+     } 
111+   }  else  { 
112+     // Else, get the url from the <script> this file was called with. 
113+     const  scriptSource  =  getCurrentScriptSource ( ) ; 
114+ 
115+     let  scriptSourceURL ; 
116+ 
117+     try  { 
118+       // The placeholder `baseURL` with `window.location.href`, 
119+       // is to allow parsing of path-relative or protocol-relative URLs, 
120+       // and will have no effect if `scriptSource` is a fully valid URL. 
121+       scriptSourceURL  =  new  URL ( scriptSource ,  self . location . href ) ; 
122+     }  catch  ( error )  { 
123+       // URL parsing failed, do nothing. 
124+       // We will still proceed to see if we can recover using `resourceQuery` 
125+     } 
126+ 
127+     if  ( scriptSourceURL )  { 
128+       result  =  scriptSourceURL ; 
129+       result . fromCurrentScript  =  true ; 
130+     } 
131+   } 
132+ 
133+   return  result ; 
76134} ; 
135+ 
77136const  parsedResourceQuery  =  parseURL ( __resourceQuery ) ; 
78137
79138const  enabledFeatures  =  { 
@@ -83,6 +142,14 @@ const enabledFeatures = {
83142  Overlay : false , 
84143} ; 
85144
145+ /** @type  {Options } */ 
146+ const  options  =  { 
147+   hot : false , 
148+   liveReload : false , 
149+   progress : false , 
150+   overlay : false , 
151+ } ; 
152+ 
86153if  ( parsedResourceQuery . hot  ===  "true" )  { 
87154  options . hot  =  true ; 
88155  enabledFeatures [ "Hot Module Replacement" ]  =  true ; 
@@ -130,18 +197,37 @@ if (typeof parsedResourceQuery.reconnect !== "undefined") {
130197/** 
131198 * @param  {string } level 
132199 */ 
133- function  setAllLogLevel ( level )  { 
200+ const  setAllLogLevel   =   ( level )   =>  { 
134201  // This is needed because the HMR logger operate separately from dev server logger 
135202  webpackHotLog . setLogLevel ( 
136203    level  ===  "verbose"  ||  level  ===  "log"  ? "info"  : level , 
137204  ) ; 
138205  setLogLevel ( level ) ; 
139- } 
206+ } ; 
140207
141208if  ( options . logging )  { 
142209  setAllLogLevel ( options . logging ) ; 
143210} 
144211
212+ const  logEnabledFeatures  =  ( features )  =>  { 
213+   const  listEnabledFeatures  =  Object . keys ( features ) ; 
214+   if  ( ! features  ||  listEnabledFeatures . length  ===  0 )  { 
215+     return ; 
216+   } 
217+ 
218+   let  logString  =  "Server started:" ; 
219+ 
220+   // Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled. 
221+   for  ( let  i  =  0 ;  i  <  listEnabledFeatures . length ;  i ++ )  { 
222+     const  key  =  listEnabledFeatures [ i ] ; 
223+     logString  +=  ` ${ key } ${ features [ key ]  ? "enabled"  : "disabled" }  ; 
224+   } 
225+   // replace last comma with a period 
226+   logString  =  logString . slice ( 0 ,  - 1 ) . concat ( "." ) ; 
227+ 
228+   log . info ( logString ) ; 
229+ } ; 
230+ 
145231logEnabledFeatures ( enabledFeatures ) ; 
146232
147233self . addEventListener ( "beforeunload" ,  ( )  =>  { 
0 commit comments