@@ -74,6 +74,24 @@ ScratchTools.Storage = {};
74
74
ScratchTools . Resources = { } ;
75
75
ste . console . log ( "ScratchTools API Created" , "ste-main" ) ;
76
76
77
+ ScratchTools . cssFiles = [ ] ;
78
+ async function updateCSSFiles ( ) {
79
+ let activeCSSFiles = Array . from ( document . styleSheets )
80
+ . filter ( ( sheet ) => sheet . href )
81
+ . map ( ( sheet ) => sheet . href )
82
+ . filter ( ( el ) => new URL ( el ) . host === "scratch.mit.edu" ) ;
83
+ activeCSSFiles = activeCSSFiles . filter (
84
+ ( el ) => ! ScratchTools . cssFiles . find ( ( e ) => e . url === el )
85
+ ) ;
86
+
87
+ for ( var i in activeCSSFiles ) {
88
+ ScratchTools . cssFiles . push ( {
89
+ url : activeCSSFiles [ i ] ,
90
+ data : await ( await fetch ( activeCSSFiles [ i ] ) ) . text ( ) ,
91
+ } ) ;
92
+ }
93
+ }
94
+
77
95
if (
78
96
window . location . href . startsWith ( "https://scratch.mit.edu/projects/" ) &&
79
97
window . location . href . includes ( "/editor" )
@@ -159,6 +177,7 @@ function enableScratchToolsSelectorsMutationObserver() {
159
177
enableScratchToolsSelectorsMutationObserver ( ) ;
160
178
161
179
function returnScratchToolsSelectorsMutationObserverCallbacks ( ) {
180
+ updateCSSFiles ( )
162
181
Object . keys ( allWaitInstances ) . forEach ( function ( key ) {
163
182
var waitInstance = allWaitInstances [ key ] ;
164
183
if ( ! waitInstance . removed ) {
@@ -340,6 +359,39 @@ ScratchTools.styles = {
340
359
} ,
341
360
} ;
342
361
362
+ function scratchClass ( name ) {
363
+ let element = document . querySelector ( `[class*='${ name } ']` ) ;
364
+ if ( element ) {
365
+ let classes = [ ...element . classList ] ;
366
+ return classes . find ( ( el ) => el . includes ( name ) ) ;
367
+ } else {
368
+ let text = [ ]
369
+
370
+ for ( var i in ScratchTools . cssFiles ) {
371
+ text . push ( ScratchTools . cssFiles [ i ] . data )
372
+ }
373
+
374
+ text = text . join ( "\n\n" )
375
+ let classes = getClassNamesFromCSSText ( text )
376
+
377
+ let relClass = classes . find ( ( el ) => el . includes ( name ) )
378
+ return relClass
379
+ }
380
+ }
381
+
382
+ ScratchTools . getClassNamesFromCSSText = function ( cssText ) {
383
+ const classNames = new Set ( ) ;
384
+
385
+ const classRegex = / \. ( [ a - z A - Z 0 - 9 _ - ] + ) \b / g;
386
+
387
+ let match ;
388
+ while ( ( match = classRegex . exec ( cssText ) ) !== null ) {
389
+ classNames . add ( match [ 1 ] ) ;
390
+ }
391
+
392
+ return Array . from ( classNames ) ;
393
+ }
394
+
343
395
ScratchTools . waitForElements (
344
396
"ul[class*='menu_menu_'][class*='menu_right_']" ,
345
397
function ( ul ) {
@@ -351,7 +403,10 @@ ScratchTools.waitForElements(
351
403
if ( ! ul . querySelector ( ".ste-menu-full-settings" ) ) {
352
404
var li = document . createElement ( "li" ) ;
353
405
li . className =
354
- "ste-menu-full-settings menu_menu-item_3EwYA menu_hoverable_3u9dt" ;
406
+ "ste-menu-full-settings " +
407
+ scratchClass ( "menu_menu-item_" ) +
408
+ " " +
409
+ scratchClass ( "menu_hoverable_" ) ;
355
410
356
411
var div = document . createElement ( "div" ) ;
357
412
div . className = "settings-menu_option_3rMur" ;
@@ -391,6 +446,8 @@ async function blockliveDetection() {
391
446
Object . keys ( app ) . find ( ( key ) => key . startsWith ( "__reactContainer" ) )
392
447
] . child . stateNode . store . getState ( ) ?. scratchGui ;
393
448
if ( ! gui ?. projectState ) return ;
394
- let detectBlocklive = await import ( "./blocklive-detection/blocklive-detect.js" ) ;
449
+ let detectBlocklive = await import (
450
+ "./blocklive-detection/blocklive-detect.js"
451
+ ) ;
395
452
detectBlocklive . default ( ) ;
396
- }
453
+ }
0 commit comments