@@ -10,6 +10,7 @@ import (
1010 "path"
1111 "path/filepath"
1212 "regexp"
13+ "runtime"
1314 "strconv"
1415 "strings"
1516
@@ -60,8 +61,7 @@ func readLocalCssMap(cssTranslationMap *map[string]string) error {
6061 return nil
6162}
6263
63- // Start preprocessing apps assets in extractedAppPath
64- func Start (version string , extractedAppsPath string , flags Flag ) {
64+ func Start (version string , spotifyBasePath string , extractedAppsPath string , flags Flag ) {
6565 appPath := filepath .Join (extractedAppsPath , "xpui" )
6666 var cssTranslationMap = make (map [string ]string )
6767 // readSourceMapAndGenerateCSSMap(appPath)
@@ -95,14 +95,66 @@ func Start(version string, extractedAppsPath string, flags Flag) {
9595 spotifyPatch , _ = strconv .Atoi (verParts [2 ])
9696 }
9797
98+ frameworkResourcesPath := ""
99+ switch runtime .GOOS {
100+ case "darwin" :
101+ frameworkResourcesPath = filepath .Join (spotifyBasePath , "Contents" , "Frameworks" , "Chromium Embedded Framework.framework" , "Resources" )
102+ case "windows" :
103+ frameworkResourcesPath = spotifyBasePath
104+ case "linux" :
105+ frameworkResourcesPath = spotifyBasePath
106+ default :
107+ utils .PrintWarning ("Unsupported OS for V8 snapshot finding: " + runtime .GOOS )
108+ }
109+
110+ if frameworkResourcesPath != "" {
111+ files , err := os .ReadDir (frameworkResourcesPath )
112+ if err != nil {
113+ utils .PrintWarning (fmt .Sprintf ("Could not read directory %s for V8 snapshots: %v" , frameworkResourcesPath , err ))
114+ } else {
115+ for _ , file := range files {
116+ if ! file .IsDir () && strings .HasPrefix (file .Name (), "v8_context_snapshot" ) && strings .HasSuffix (file .Name (), ".bin" ) {
117+ binFilePath := filepath .Join (frameworkResourcesPath , file .Name ())
118+ utils .PrintInfo ("Processing V8 snapshot file: " + binFilePath )
119+
120+ startMarker := []byte ("var __webpack_modules__={" )
121+ endMarker := []byte ("xpui-modules.js.map" )
122+
123+ embeddedString , _ , _ , err := utils .ReadStringFromUTF16Binary (binFilePath , startMarker , endMarker )
124+ if err != nil {
125+ utils .PrintWarning (fmt .Sprintf ("Could not process %s: %v" , binFilePath , err ))
126+ utils .PrintInfo ("You can ignore this warning if you're on a Spotify version that didn't yet add xpui modules to the V8 snapshot" )
127+ continue
128+ }
129+
130+ err = utils .CreateFile (filepath .Join (appPath , "xpui-modules.js" ), embeddedString )
131+ if err != nil {
132+ utils .PrintWarning (fmt .Sprintf ("Could not create xpui-modules.js: %v" , err ))
133+ continue
134+ } else {
135+ utils .PrintInfo ("Extracted V8 snapshot blob (remaining xpui) to xpui-modules.js" )
136+ }
137+ }
138+ }
139+ }
140+ }
141+
98142 filepath .Walk (appPath , func (path string , info os.FileInfo , err error ) error {
143+ if err != nil {
144+ fmt .Printf ("Error accessing path %q: %v\n " , path , err )
145+ return err
146+ }
147+ if info .IsDir () {
148+ return nil
149+ }
150+
99151 fileName := info .Name ()
100152 extension := filepath .Ext (fileName )
101153
102154 switch extension {
103155 case ".js" :
104156 utils .ModifyFile (path , func (content string ) string {
105- if flags .DisableSentry && fileName == "xpui.js" {
157+ if flags .DisableSentry && ( fileName == "xpui.js" || fileName == "xpui-snapshot.js" ) {
106158 content = disableSentry (content )
107159 }
108160
@@ -112,6 +164,9 @@ func Start(version string, extractedAppsPath string, flags Flag) {
112164
113165 if flags .ExposeAPIs {
114166 switch fileName {
167+ case "xpui-modules.js" , "xpui-snapshot.js" :
168+ content = exposeAPIs_main (content )
169+ content = exposeAPIs_vendor (content )
115170 case "xpui.js" :
116171 content = exposeAPIs_main (content )
117172 if spotifyMajor >= 1 && spotifyMinor >= 2 && spotifyPatch >= 57 {
@@ -576,7 +631,6 @@ func exposeAPIs_main(input string) string {
576631 & input ,
577632 `(;const [\w\d]+=)((?:\(0,[\w\d]+\.memo\))[\(\d,\w\.\){:}=]+\=[\d\w]+\.[\d\w]+\.getLocaleForURLPath\(\))` ,
578633 func (submatches ... string ) string {
579- fmt .Println (submatches )
580634 return fmt .Sprintf ("%sSpicetify.ReactComponent.Navigation=%s" , submatches [1 ], submatches [2 ])
581635 })
582636
@@ -585,7 +639,12 @@ func exposeAPIs_main(input string) string {
585639 return fmt .Sprintf ("%s[Spicetify.ContextMenuV2.renderItems(),%s].flat()" , submatches [1 ], submatches [2 ])
586640 })
587641
588- croppedInput := utils .FindFirstMatch (input , `.*value:"contextmenu"` )[0 ]
642+ inputContextMenu := utils .FindFirstMatch (input , `.*value:"contextmenu"` )
643+ if len (inputContextMenu ) == 0 {
644+ return input
645+ }
646+
647+ croppedInput := inputContextMenu [0 ]
589648 react := utils .FindLastMatch (croppedInput , `([a-zA-Z_\$][\w\$]*)\.useRef` )[1 ]
590649 candicates := utils .FindLastMatch (croppedInput , `\(\{[^}]*menu:([a-zA-Z_\$][\w\$]*),[^}]*trigger:([a-zA-Z_\$][\w\$]*),[^}]*triggerRef:([a-zA-Z_\$][\w\$]*)` )
591650 oldCandicates := utils .FindLastMatch (croppedInput , `([a-zA-Z_\$][\w\$]*)=[\w_$]+\.menu[^}]*,([a-zA-Z_\$][\w\$]*)=[\w_$]+\.trigger[^}]*,([a-zA-Z_\$][\w\$]*)=[\w_$]+\.triggerRef` )
0 commit comments